collab-a2a 2.1.2__tar.gz → 2.2.0__tar.gz

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 (423) hide show
  1. {collab_a2a-2.1.2/src/collab_a2a.egg-info → collab_a2a-2.2.0}/PKG-INFO +234 -23
  2. collab_a2a-2.1.2/PKG-INFO → collab_a2a-2.2.0/README.md +230 -43
  3. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/pyproject.toml +13 -3
  4. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/__init__.py +1 -1
  5. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/activity.py +15 -1
  6. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/attention.py +17 -2
  7. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/batch.py +254 -3
  8. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/cli.py +1702 -77
  9. collab_a2a-2.2.0/src/collab/client/approval.py +569 -0
  10. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/bridge.py +29 -9
  11. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/context.py +4 -4
  12. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/daemon.py +439 -168
  13. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/daemon_files.py +186 -31
  14. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/demo_agent.py +1 -1
  15. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/exclusive.py +18 -9
  16. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/hub_client.py +73 -14
  17. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/inbox.py +7 -4
  18. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/onboard.py +55 -3
  19. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/participant_metrics.py +52 -1
  20. collab_a2a-2.2.0/src/collab/client/passkey.py +643 -0
  21. collab_a2a-2.2.0/src/collab/client/passkey_adapter.py +507 -0
  22. collab_a2a-2.2.0/src/collab/client/passkey_assets/enrol.html +34 -0
  23. collab_a2a-2.2.0/src/collab/client/passkey_assets/enrol.js +203 -0
  24. collab_a2a-2.2.0/src/collab/client/passkey_assets/index.html +52 -0
  25. collab_a2a-2.2.0/src/collab/client/passkey_assets/passkey.css +24 -0
  26. collab_a2a-2.2.0/src/collab/client/passkey_assets/passkey.js +366 -0
  27. collab_a2a-2.2.0/src/collab/client/passkey_dispatch.py +316 -0
  28. collab_a2a-2.2.0/src/collab/client/passkey_enrol.py +352 -0
  29. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/settings_tui.py +25 -6
  30. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/statusbar.py +25 -5
  31. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/tui.py +39 -16
  32. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/watch.py +21 -15
  33. collab_a2a-2.2.0/src/collab/client/worker_service.py +1036 -0
  34. collab_a2a-2.2.0/src/collab/codex_usage.py +140 -0
  35. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/config.py +586 -36
  36. collab_a2a-2.2.0/src/collab/consent_hello.py +795 -0
  37. collab_a2a-2.2.0/src/collab/daemon_main.py +50 -0
  38. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/demo.py +41 -18
  39. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/hosttool.py +47 -5
  40. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/hub_main.py +82 -15
  41. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/learnings.py +52 -5
  42. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/lockfile.py +1 -0
  43. collab_a2a-2.2.0/src/collab/logcap.py +1047 -0
  44. collab_a2a-2.2.0/src/collab/logpipe.py +46 -0
  45. collab_a2a-2.2.0/src/collab/names.py +90 -0
  46. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/owner.py +76 -5
  47. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/peers.py +119 -23
  48. collab_a2a-2.2.0/src/collab/privacy.py +57 -0
  49. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/protocol.py +111 -6
  50. collab_a2a-2.2.0/src/collab/proxy.py +457 -0
  51. collab_a2a-2.2.0/src/collab/proxy_host.py +154 -0
  52. collab_a2a-2.2.0/src/collab/proxy_main.py +290 -0
  53. collab_a2a-2.2.0/src/collab/quota_sources.py +138 -0
  54. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/quotas.py +10 -2
  55. collab_a2a-2.2.0/src/collab/roster_clocks.py +54 -0
  56. collab_a2a-2.2.0/src/collab/routes.py +381 -0
  57. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/rules/COLLAB.md +67 -15
  58. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/runtime_settings.py +8 -5
  59. collab_a2a-2.2.0/src/collab/saved_sessions.py +56 -0
  60. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/app.py +308 -57
  61. collab_a2a-2.2.0/src/collab/server/approval_alarms.py +202 -0
  62. collab_a2a-2.2.0/src/collab/server/approval_challenge.py +143 -0
  63. collab_a2a-2.2.0/src/collab/server/approval_crypto.py +191 -0
  64. collab_a2a-2.2.0/src/collab/server/approval_keys.py +207 -0
  65. collab_a2a-2.2.0/src/collab/server/approval_routes.py +199 -0
  66. collab_a2a-2.2.0/src/collab/server/approval_skills.py +180 -0
  67. collab_a2a-2.2.0/src/collab/server/approval_store.py +528 -0
  68. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/executor.py +83 -1
  69. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/hub.py +74 -11
  70. collab_a2a-2.2.0/src/collab/server/local_tls.py +326 -0
  71. collab_a2a-2.2.0/src/collab/server/roster_transport.py +152 -0
  72. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/session.py +97 -2
  73. collab_a2a-2.2.0/src/collab/server/skill_approval_policy.py +147 -0
  74. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/store.py +186 -58
  75. collab_a2a-2.2.0/src/collab/server/tunnel.py +454 -0
  76. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skill_sharing.py +46 -0
  77. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-activity/SKILL.md +8 -4
  78. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-configure/SKILL.md +16 -10
  79. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-discover/SKILL.md +37 -2
  80. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-host/SKILL.md +31 -2
  81. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-host/references/connection-and-recovery.md +8 -3
  82. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-join/SKILL.md +14 -1
  83. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-join/references/connection-and-recovery.md +4 -0
  84. collab_a2a-2.2.0/src/collab/skills/collab-share-skills/SKILL.md +97 -0
  85. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-tasks/SKILL.md +21 -6
  86. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-telemetry/SKILL.md +31 -3
  87. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-worker/SKILL.md +57 -8
  88. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills.py +26 -1
  89. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/source_command.py +7 -5
  90. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/stats.py +162 -30
  91. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/statusline/render.py +34 -15
  92. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/task_pickup.py +88 -13
  93. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/telemetry.py +11 -4
  94. collab_a2a-2.2.0/src/collab/telemetry_setup.py +131 -0
  95. collab_a2a-2.2.0/src/collab/terminal_text.py +69 -0
  96. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/wake.py +135 -12
  97. collab_a2a-2.2.0/src/collab/worker.py +1020 -0
  98. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/worker_notices.py +59 -11
  99. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/worker_runtime.py +118 -3
  100. collab_a2a-2.1.2/README.md → collab_a2a-2.2.0/src/collab_a2a.egg-info/PKG-INFO +254 -21
  101. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab_a2a.egg-info/SOURCES.txt +101 -0
  102. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab_a2a.egg-info/requires.txt +3 -1
  103. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_daemon_follows_the_agent_that_started_it.py +54 -1
  104. collab_a2a-2.2.0/tests/test_a_refused_tunnel_says_why.py +1073 -0
  105. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_agent_identity.py +3 -2
  106. collab_a2a-2.2.0/tests/test_approval_alarms.py +214 -0
  107. collab_a2a-2.2.0/tests/test_approval_challenge.py +82 -0
  108. collab_a2a-2.2.0/tests/test_approval_crypto.py +202 -0
  109. collab_a2a-2.2.0/tests/test_approval_key_changes.py +267 -0
  110. collab_a2a-2.2.0/tests/test_approval_routes.py +320 -0
  111. collab_a2a-2.2.0/tests/test_approval_security_wakes.py +288 -0
  112. collab_a2a-2.2.0/tests/test_approval_skills.py +332 -0
  113. collab_a2a-2.2.0/tests/test_approval_store.py +524 -0
  114. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_automatic_telemetry.py +11 -3
  115. collab_a2a-2.2.0/tests/test_batch_pace.py +540 -0
  116. collab_a2a-2.2.0/tests/test_bridge_delivery_is_bounded.py +79 -0
  117. collab_a2a-2.2.0/tests/test_codex_own_usage.py +149 -0
  118. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_colour_propagates.py +2 -2
  119. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_config_command.py +6 -3
  120. collab_a2a-2.2.0/tests/test_consent_hello.py +702 -0
  121. collab_a2a-2.2.0/tests/test_dashboard.py +360 -0
  122. collab_a2a-2.2.0/tests/test_default_name_identifies_nobody.py +216 -0
  123. collab_a2a-2.2.0/tests/test_every_agent_has_a_quota_route.py +367 -0
  124. collab_a2a-2.2.0/tests/test_every_source_parses_on_the_oldest_supported_python.py +77 -0
  125. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_external_state_live_session.py +8 -0
  126. collab_a2a-2.2.0/tests/test_file_identity_authorization.py +186 -0
  127. collab_a2a-2.2.0/tests/test_file_list_all.py +115 -0
  128. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_guest_follows_the_hub.py +9 -3
  129. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_home_isolation.py +63 -10
  130. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_hub.py +59 -7
  131. collab_a2a-2.2.0/tests/test_hub_alarm_rendering_in_tmux.py +76 -0
  132. collab_a2a-2.2.0/tests/test_hub_alarms_have_reserved_rendering.py +111 -0
  133. collab_a2a-2.2.0/tests/test_identity_authorization.py +171 -0
  134. collab_a2a-2.2.0/tests/test_identity_migration_provenance.py +107 -0
  135. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_input_bounds.py +5 -3
  136. collab_a2a-2.2.0/tests/test_keep_process_lifecycle.py +122 -0
  137. collab_a2a-2.2.0/tests/test_legacy_answer_migration.py +105 -0
  138. collab_a2a-2.2.0/tests/test_local_tls.py +442 -0
  139. collab_a2a-2.2.0/tests/test_logs_stay_capped.py +1517 -0
  140. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_migration.py +6 -4
  141. collab_a2a-2.2.0/tests/test_models_are_published_with_when_they_changed.py +177 -0
  142. collab_a2a-2.2.0/tests/test_ngrok_and_status_hints.py +78 -0
  143. collab_a2a-2.2.0/tests/test_no_host_identity_reaches_peers.py +728 -0
  144. collab_a2a-2.2.0/tests/test_one_proxy_serves_every_session.py +679 -0
  145. collab_a2a-2.2.0/tests/test_owner_table_bounds.py +125 -0
  146. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_panel_v202.py +9 -0
  147. collab_a2a-2.2.0/tests/test_passkey_adapter.py +559 -0
  148. collab_a2a-2.2.0/tests/test_passkey_dispatch.py +420 -0
  149. collab_a2a-2.2.0/tests/test_passkey_dispatch_integration.py +144 -0
  150. collab_a2a-2.2.0/tests/test_passkey_dispatch_resources.py +69 -0
  151. collab_a2a-2.2.0/tests/test_passkey_enrol.py +446 -0
  152. collab_a2a-2.2.0/tests/test_passkey_enrol_js.py +205 -0
  153. collab_a2a-2.2.0/tests/test_passkey_enrol_resources.py +141 -0
  154. collab_a2a-2.2.0/tests/test_passkey_frontend.py +408 -0
  155. collab_a2a-2.2.0/tests/test_passkey_frontend_js.py +406 -0
  156. collab_a2a-2.2.0/tests/test_passkey_frontend_resources.py +121 -0
  157. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_peers.py +9 -5
  158. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_periodic_reminder.py +6 -2
  159. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_platform_support.py +54 -1
  160. collab_a2a-2.2.0/tests/test_pr127_generation_probe.py +18 -0
  161. collab_a2a-2.2.0/tests/test_private_answer_binding.py +190 -0
  162. collab_a2a-2.2.0/tests/test_proxy_host.py +506 -0
  163. collab_a2a-2.2.0/tests/test_quarantine_recovery_cli.py +74 -0
  164. collab_a2a-2.2.0/tests/test_renamed_answer.py +393 -0
  165. collab_a2a-2.2.0/tests/test_reserved_hub_identity.py +74 -0
  166. collab_a2a-2.2.0/tests/test_reset_epoch.py +88 -0
  167. collab_a2a-2.2.0/tests/test_roster_pace_clocks.py +160 -0
  168. collab_a2a-2.2.0/tests/test_roster_requests_are_coalesced.py +191 -0
  169. collab_a2a-2.2.0/tests/test_roster_transport.py +358 -0
  170. collab_a2a-2.2.0/tests/test_route_owner_trust_regressions.py +101 -0
  171. collab_a2a-2.2.0/tests/test_route_trust_boundaries.py +391 -0
  172. collab_a2a-2.2.0/tests/test_routes_keep_their_authority.py +276 -0
  173. collab_a2a-2.2.0/tests/test_saved_sessions.py +531 -0
  174. collab_a2a-2.2.0/tests/test_security_gate_survivors.py +95 -0
  175. collab_a2a-2.2.0/tests/test_security_wake_resources.py +85 -0
  176. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_settings_panel_in_tmux.py +14 -6
  177. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_settings_reach_the_open_session.py +4 -3
  178. collab_a2a-2.2.0/tests/test_settings_scope.py +580 -0
  179. collab_a2a-2.2.0/tests/test_skill_approval_policy.py +173 -0
  180. collab_a2a-2.2.0/tests/test_skill_lists_and_requests.py +281 -0
  181. collab_a2a-2.2.0/tests/test_skills_exchange_budget.py +83 -0
  182. collab_a2a-2.2.0/tests/test_source_command_bounds.py +61 -0
  183. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stats.py +18 -7
  184. collab_a2a-2.2.0/tests/test_strong_approval_client.py +822 -0
  185. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_task_pickup.py +212 -0
  186. collab_a2a-2.2.0/tests/test_task_release_handoff.py +105 -0
  187. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_telemetry_v2.py +4 -2
  188. collab_a2a-2.2.0/tests/test_the_demo_draws_what_shipped.py +109 -0
  189. collab_a2a-2.2.0/tests/test_the_hub_and_daemon_stay_cheap_under_load.py +350 -0
  190. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_record_is_kept_without_being_asked.py +83 -12
  191. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_reminder_can_be_added_to.py +3 -3
  192. collab_a2a-2.2.0/tests/test_tls_keepalive.py +190 -0
  193. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tunnel.py +3 -5
  194. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_v201_communication_challenger.py +13 -6
  195. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_v201_final_review.py +1 -1
  196. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_worker_default.py +115 -0
  197. collab_a2a-2.2.0/tests/test_worker_delivery.py +188 -0
  198. collab_a2a-2.2.0/tests/test_worker_identity_routing.py +507 -0
  199. collab_a2a-2.2.0/tests/test_worker_notices.py +408 -0
  200. collab_a2a-2.2.0/tests/test_worker_own_context.py +388 -0
  201. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_worker_runtime.py +170 -1
  202. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_worker_service.py +356 -4
  203. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_worker_source_v201.py +7 -6
  204. collab_a2a-2.2.0/tests/test_worker_state.py +578 -0
  205. collab_a2a-2.1.2/src/collab/client/worker_service.py +0 -336
  206. collab_a2a-2.1.2/src/collab/codex_usage.py +0 -92
  207. collab_a2a-2.1.2/src/collab/daemon_main.py +0 -30
  208. collab_a2a-2.1.2/src/collab/server/tunnel.py +0 -259
  209. collab_a2a-2.1.2/src/collab/skills/collab-share-skills/SKILL.md +0 -33
  210. collab_a2a-2.1.2/src/collab/telemetry_setup.py +0 -73
  211. collab_a2a-2.1.2/src/collab/worker.py +0 -480
  212. collab_a2a-2.1.2/tests/test_codex_own_usage.py +0 -69
  213. collab_a2a-2.1.2/tests/test_source_command_bounds.py +0 -29
  214. collab_a2a-2.1.2/tests/test_worker_delivery.py +0 -32
  215. collab_a2a-2.1.2/tests/test_worker_notices.py +0 -177
  216. collab_a2a-2.1.2/tests/test_worker_state.py +0 -317
  217. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/LICENSE +0 -0
  218. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/setup.cfg +0 -0
  219. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/atomic.py +0 -0
  220. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/capacity.py +0 -0
  221. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/__init__.py +0 -0
  222. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/background.py +0 -0
  223. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/recovery.py +0 -0
  224. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/client/terminal_panel.py +0 -0
  225. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/columns.py +0 -0
  226. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/compaction.py +0 -0
  227. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/compatibility.py +0 -0
  228. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/diagnostics.py +0 -0
  229. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/identity.py +0 -0
  230. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/reboot.py +0 -0
  231. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/rules.py +0 -0
  232. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/__init__.py +0 -0
  233. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/auth.py +0 -0
  234. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/card.py +0 -0
  235. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/server/events.py +0 -0
  236. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/setting_edit.py +0 -0
  237. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-capacity/SKILL.md +0 -0
  238. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-learn/SKILL.md +0 -0
  239. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-telemetry/references/providers.md +0 -0
  240. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/skills/collab-watch/SKILL.md +0 -0
  241. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/statusline/__init__.py +0 -0
  242. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/statusline/entry.py +0 -0
  243. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/statusline/install.py +0 -0
  244. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/statusline/watchdog.py +0 -0
  245. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/themes.py +0 -0
  246. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/update.py +0 -0
  247. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/worker_telemetry.py +0 -0
  248. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab/worker_usage.py +0 -0
  249. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab_a2a.egg-info/dependency_links.txt +0 -0
  250. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab_a2a.egg-info/entry_points.txt +0 -0
  251. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/src/collab_a2a.egg-info/top_level.txt +0 -0
  252. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_count_that_is_not_a_count.py +0 -0
  253. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_figure_can_be_taken_back.py +0 -0
  254. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_figure_of_one_is_one_percent.py +0 -0
  255. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_fresh_session_for_everyone.py +0 -0
  256. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_hole_in_the_log_is_reported.py +0 -0
  257. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_message_is_refused_not_cut.py +0 -0
  258. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_pid_from_another_boot_names_nobody.py +0 -0
  259. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_project_is_a_bundle_that_belongs_to_somebody.py +0 -0
  260. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_quota_read_from_the_agent_itself.py +0 -0
  261. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_refused_kind_is_named_briefly.py +0 -0
  262. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_state_constant_is_read_by_its_data_model.py +0 -0
  263. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_a_window_from_a_bucket_is_still_a_window.py +0 -0
  264. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_activity.py +0 -0
  265. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_activity_cli.py +0 -0
  266. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_activity_hub.py +0 -0
  267. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_agent_commands.py +0 -0
  268. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_an_update_refreshes_what_it_installed.py +0 -0
  269. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_asking_is_not_holding.py +0 -0
  270. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_attention_contention.py +0 -0
  271. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_attention_delivery.py +0 -0
  272. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_bare_join.py +0 -0
  273. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_batch_progress.py +0 -0
  274. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_bind_forms_and_header.py +0 -0
  275. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_chat_is_the_only_kind_a_client_sends.py +0 -0
  276. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_check.py +0 -0
  277. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_clear_quota.py +0 -0
  278. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_cli_imports_no_httpx.py +0 -0
  279. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_cli_v202.py +0 -0
  280. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_colour_maths.py +0 -0
  281. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_colour_push.py +0 -0
  282. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_colour_tables_forget_the_departed.py +0 -0
  283. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_columns_clip.py +0 -0
  284. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_context_compaction.py +0 -0
  285. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_daemon_identity.py +0 -0
  286. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_demo_agent_panel.py +0 -0
  287. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_demo_header_row_is_clipped.py +0 -0
  288. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_demo_session.py +0 -0
  289. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_diagnostics.py +0 -0
  290. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_docs_match_cli.py +0 -0
  291. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_every_agent_is_told_how_to_listen.py +0 -0
  292. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_every_item_of_a_bar_is_a_choice.py +0 -0
  293. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_every_kind_reaches_every_renderer.py +0 -0
  294. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_every_stamp_reads_in_the_readers_zone.py +0 -0
  295. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_every_verb_an_agent_needs_is_on_a_page_it_reads.py +0 -0
  296. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_external_agent_state.py +0 -0
  297. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_file_outcome_takes_junk.py +0 -0
  298. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_files.py +0 -0
  299. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_fold_override.py +0 -0
  300. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_global_figures.py +0 -0
  301. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_global_home.py +0 -0
  302. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_home_flag.py +0 -0
  303. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_home_permissions.py +0 -0
  304. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_host_name_clash.py +0 -0
  305. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_how_it_was_installed.py +0 -0
  306. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_hub_version_travels.py +0 -0
  307. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_inbox_under_contention.py +0 -0
  308. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_inbox_write_order.py +0 -0
  309. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_info_blue.py +0 -0
  310. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_issue_recovery.py +0 -0
  311. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_joining_a_dead_session.py +0 -0
  312. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_joining_by_name.py +0 -0
  313. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_jump_from_the_status_row.py +0 -0
  314. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_kill.py +0 -0
  315. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_layout.py +0 -0
  316. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_learnings.py +0 -0
  317. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_learnings_cost.py +0 -0
  318. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_learnings_sync.py +0 -0
  319. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_leaving_takes_the_wake_with_it.py +0 -0
  320. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_listen_kind_filters.py +0 -0
  321. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_live_settings.py +0 -0
  322. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_liveness_from_a_sandbox.py +0 -0
  323. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_local_join_stays_local.py +0 -0
  324. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_lock_flow.py +0 -0
  325. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_lock_identity.py +0 -0
  326. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_lockfile.py +0 -0
  327. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_logs_can_be_read_without_stopping_anything.py +0 -0
  328. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_loose_ends.py +0 -0
  329. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_markdown_themes.py +0 -0
  330. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_monitor_armed.py +0 -0
  331. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_mutation_gaps.py +0 -0
  332. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_name_migration.py +0 -0
  333. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_name_reuse.py +0 -0
  334. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_no_autohost.py +0 -0
  335. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_numbers_that_stop_moving_say_why.py +0 -0
  336. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_okf_bundle.py +0 -0
  337. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_older_above_agrees_with_what_loads.py +0 -0
  338. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_orphans.py +0 -0
  339. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_overview.py +0 -0
  340. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_own_colour.py +0 -0
  341. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_owner_stamp.py +0 -0
  342. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_panel_background.py +0 -0
  343. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_participant_cards_v201.py +0 -0
  344. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_participant_details.py +0 -0
  345. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_participant_panel_in_tmux.py +0 -0
  346. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_peers_lifecycle.py +0 -0
  347. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_persisted_v2_boundary.py +0 -0
  348. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_rate_limiter_forgets.py +0 -0
  349. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_reminder_edges.py +0 -0
  350. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_reminder_on_the_monitor.py +0 -0
  351. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_rename.py +0 -0
  352. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_render.py +0 -0
  353. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_resume.py +0 -0
  354. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_room_files_wait_for_everyone.py +0 -0
  355. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_roster_colour.py +0 -0
  356. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_roster_dots.py +0 -0
  357. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_roster_row_keeps_the_count.py +0 -0
  358. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_roster_rule.py +0 -0
  359. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_roster_when_the_session_dies.py +0 -0
  360. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_rotating_the_invite.py +0 -0
  361. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_rotation_is_atomic.py +0 -0
  362. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_rules.py +0 -0
  363. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_same_name_is_not_ownership.py +0 -0
  364. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_semantic_theme_engine.py +0 -0
  365. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_setting_edit.py +0 -0
  366. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_settings_tui.py +0 -0
  367. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_shared_skills_and_capacity.py +0 -0
  368. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_skill_capabilities_v201.py +0 -0
  369. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_skill_formats.py +0 -0
  370. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_skill_settings_match_the_registry.py +0 -0
  371. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_skills.py +0 -0
  372. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stale_status.py +0 -0
  373. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_state_dir_cleanup.py +0 -0
  374. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_state_dirs.py +0 -0
  375. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_state_is_not_conversation.py +0 -0
  376. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stats_formats.py +0 -0
  377. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stats_ownership.py +0 -0
  378. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stats_say_when.py +0 -0
  379. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stats_source.py +0 -0
  380. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stats_stamp_edges.py +0 -0
  381. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_status_bar.py +0 -0
  382. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_statuses_stay_current.py +0 -0
  383. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_statusline_imports_no_networking.py +0 -0
  384. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_statusline_install.py +0 -0
  385. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stopped_msg.py +0 -0
  386. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_stream.py +0 -0
  387. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tasks_want_a_batch.py +0 -0
  388. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_telling_agents_apart.py +0 -0
  389. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_terminal_escapes.py +0 -0
  390. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_terminal_panel.py +0 -0
  391. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_a2a_client_surface_is_not_dead_code.py +0 -0
  392. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_count_is_a_switch.py +0 -0
  393. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_count_is_never_shown_outdated.py +0 -0
  394. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_daemon_forgets_what_it_no_longer_needs.py +0 -0
  395. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_pane_and_the_transcript_agree_about_a_file.py +0 -0
  396. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_reminder_reaches_every_agent.py +0 -0
  397. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_roster_foot_is_a_grid.py +0 -0
  398. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_status_line_cannot_run_forever.py +0 -0
  399. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_status_line_does_not_vanish.py +0 -0
  400. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_suite_never_reads_your_config.py +0 -0
  401. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_two_row_switches_are_independent.py +0 -0
  402. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_the_wake_explains_its_clocks.py +0 -0
  403. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_theme_files_survive.py +0 -0
  404. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_theme_is_visual_only.py +0 -0
  405. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_theme_panel_in_tmux.py +0 -0
  406. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_transcript_dates_follow_the_clock.py +0 -0
  407. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tui_cost.py +0 -0
  408. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tui_fold_click.py +0 -0
  409. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tui_gutter.py +0 -0
  410. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tui_scroll.py +0 -0
  411. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_tui_window.py +0 -0
  412. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_two_agents_one_repo.py +0 -0
  413. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_unread_is_what_the_agent_has_not_seen.py +0 -0
  414. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_update.py +0 -0
  415. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_v201_remaining_surfaces_challenger.py +0 -0
  416. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_v2_compatibility.py +0 -0
  417. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_viewer_says_what_the_ack_did.py +0 -0
  418. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_wake.py +0 -0
  419. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_watch_pane_survives.py +0 -0
  420. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_what_may_be_signalled.py +0 -0
  421. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_which_agent.py +0 -0
  422. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_who_is_who.py +0 -0
  423. {collab_a2a-2.1.2 → collab_a2a-2.2.0}/tests/test_worker_telemetry_v201.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: collab-a2a
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: An A2A hub that lets coding agents on different machines talk, align on tasks, and discuss work in real time.
5
5
  License: MIT
6
6
  Requires-Python: >=3.10
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
- Requires-Dist: a2a-sdk[fastapi]>=1.1.2
9
+ Requires-Dist: cryptography>=46
10
+ Requires-Dist: a2a-sdk[fastapi]<1.2,>=1.1.2
10
11
  Requires-Dist: uvicorn>=0.30
11
12
  Requires-Dist: httpx>=0.28.1
12
13
  Requires-Dist: httpx-sse>=0.4
@@ -15,6 +16,7 @@ Requires-Dist: Pillow>=12.1.1
15
16
  Requires-Dist: python-multipart>=0.0.18
16
17
  Requires-Dist: websockets>=14
17
18
  Requires-Dist: tzdata; platform_system == "Windows"
19
+ Requires-Dist: cryptography>=42
18
20
  Provides-Extra: dev
19
21
  Requires-Dist: pytest>=8; extra == "dev"
20
22
  Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
@@ -90,6 +92,7 @@ To receive messages in real time, arm a Monitor on one of these:
90
92
  ```
91
93
  $ collab join https://a1b2c3.ngrok.app#FDfw... --focus "the client side"
92
94
  [ok] joined s_bb9c59a3 as bob (host: alice)
95
+ [ok] using route https://a1b2c3.ngrok.app
93
96
  [ok] listening
94
97
  [ok] announced your focus: the client side
95
98
 
@@ -104,7 +107,7 @@ From that moment both agents receive each other's messages as they happen.
104
107
 
105
108
  ## Contents
106
109
 
107
- - [What changed in v2](#v2-settings-and-shared-capabilities)
110
+ - [In 2.2.0](#in-220) · [What changed in v2](#v2-settings-and-shared-capabilities)
108
111
  - [How it works](#how-it-works) · [Install](#install) · [Quick start](#quick-start)
109
112
  - [Making an agent listen](#making-an-agent-listen) · [Saying what you are doing](#saying-what-you-are-doing) · [Commands](#commands)
110
113
  - [Watching the conversation](#watching-the-conversation) · [How it looks](#how-the-conversation-looks) · [Status line](#status-line) · [Files](#sharing-files-and-artifacts)
@@ -114,6 +117,106 @@ From that moment both agents receive each other's messages as they happen.
114
117
 
115
118
  ---
116
119
 
120
+ ## In 2.2.0
121
+
122
+ What 2.2.0 adds since 2.1.2.
123
+
124
+ - **Upgrade note: offline names are reserved.** A participant who goes offline
125
+ keeps their name: only the collab state that joined as them, presenting its
126
+ saved token, can rejoin under it, and an invite alone is refused. Clients
127
+ older than 2.2.0 do not send that token, so after going offline they cannot
128
+ rejoin under their own name until they upgrade; they can join under another
129
+ name meanwhile (#150).
130
+ - **Reserved names and hub alarms.** `collab` and look-alikes are refused as
131
+ participant names, hub alarms show in a reserved banner, and security
132
+ alarms wake the agent (#168).
133
+ - **Hand work over.** `collab task release --id T_xxx` gives up a claim, and
134
+ `collab task handoff --id T_xxx --to NAME` offers a task to one participant,
135
+ who accepts with `collab task claim`; the host may release a claim held by
136
+ someone offline. The people an ownership change concerns are told directly
137
+ (#177).
138
+ - **Peers see less about you.** The metadata collab sends on its own (join
139
+ handshake, stats, activity) no longer carries your hostname, OS account,
140
+ working directory or git remote; a `machine-…` label says only whether two
141
+ agents share a machine, and `collab stats --json` no longer carries `user`
142
+ (#178). What you write in chat is still sent as written. Records a hub
143
+ stored before 2.2.0 are cleaned when served, not rewritten. Upgrade note: the machine identity is now random, generated once, so
144
+ each machine shows a new `machine-…` label the first time it runs 2.2.0.
145
+ - **Strong approval is live with Windows Hello.** A skill request asked with
146
+ `--strong` opens collab's approval window; passkey approval is not in this
147
+ release (#181).
148
+ - **One proxy for every session, by default.** `collab host` attaches to the
149
+ machine's shared proxy (`proxy` = `auto`) and a session's address becomes
150
+ `/s/<id>`; a session that served the bare domain with its own tunnel before
151
+ keeps it, so its old links still work. `collab config proxy off` or
152
+ `--tunnel own` opts out (#182).
153
+ - **A batch says when it will be done.** `collab batch status` adds the elapsed
154
+ time and an ETA taken from the completions the hub recorded — «≥» once the
155
+ task in flight is past its turn, «done in» and «closed after» at the end.
156
+ The status line and `collab watch` show it beside the bar.
157
+ - **The conversation worker follows the coding agent** and speaks for the main
158
+ agent while it is enabled: an automatic worker uses the provider of the agent
159
+ running collab (`worker_agent` `auto`) and realigns on the next join; the main
160
+ agent's messages, comments and file sends go through its durable outbox; and
161
+ it paces itself once half its budget is spent. A provider failure is classed (`auth`, `model`,
162
+ `rate_limit`, `network`, `other`): a rate limit waits 15 minutes to an hour,
163
+ an auth or model failure becomes one decision for the main agent and is
164
+ rechecked hourly, and the rest retry at the normal delay. Answers to a peer close the chain:
165
+ `collab worker reply ID TEXT --verbatim` sends your words as written,
166
+ `--instruct` lets the worker word them, and `--awaiting-human` tells the peer
167
+ your human is deciding.
168
+ - **`collab dashboard`** — everyone's quota, reset times and shared skills in one
169
+ table, kept current by the daemon. Quota resets are read by one explicit
170
+ policy, and a figure that is not a percentage is left out.
171
+ - **Skills on request.** `collab skills peers` lists what each participant
172
+ shares; `collab skills ask NAME --to PEER` asks one to run a skill, and
173
+ consent is the asked side's: on a terminal its human answers y/N, and an
174
+ agent may accept only with `--human-approved`, its statement that its human
175
+ agreed (`collab skills accept|decline ID`). A request asked with `--strong`
176
+ needs more, and is live in 2.2.0: a Windows Hello gesture in collab's
177
+ approval window, verified by the hub against a key the human enrolled
178
+ themselves (`collab consent enrol`); no flag or typed answer accepts it.
179
+ Passkey approval on other systems is not in this release. It holds only
180
+ between clients that have it (2.2.0 or later): an older asked side can still
181
+ accept the ordinary way,
182
+ which the asking side never counts as accepted.
183
+ - **A quota and model route for every coding agent collab recognises.** Claude
184
+ Code (its status line) and Codex (its app-server and turn record) report
185
+ them; the others are recorded as unknown, with the reason — an unknown quota
186
+ stays unknown rather than reading as zero, and nested tools are not credited
187
+ to the outer one.
188
+ - **Settings per agent.** An agent's own settings — its name, colour,
189
+ reporting and worker — stay with that agent, while machine settings such as
190
+ the theme stay shared, and a machine-wide telemetry opt-out still applies;
191
+ `collab config KEY VALUE --machine` makes it every agent's default here, and
192
+ `--kind` keeps it for every conversation of one agent kind.
193
+ - **Work offers.** Joining a session, or finishing a task, offers available
194
+ batch work — and stays quiet when there is none.
195
+ - **Sessions and resume.** `collab sessions` lists saved host and guest sessions
196
+ and `collab resume` reopens one in its original working path. Resuming an
197
+ identity another live agent holds is refused, naming what to do: close that
198
+ agent's terminal (its PID is printed), or use `--home` for a deliberate second
199
+ identity. `collab host --keep` and `collab resume --keep` keep a session after
200
+ the coding agent exits.
201
+ - **Local and public routes** for one session: agents on the host's machine
202
+ join over loopback, a TLS entrance can serve a LAN, and the public tunnel
203
+ keeps working beside them ([local routes](docs/local-routes.md)).
204
+ - **Tunnel refusals say why.** When ngrok refuses to start, `collab host`
205
+ prints its reason and the remedy; `collab config ngrok_domain NAME` sets a
206
+ reserved domain every new session uses.
207
+ - **Identity, not names.** Private messages, files and queued worker replies
208
+ are bound to stable participant ids, so a rename cannot redirect them, and a
209
+ worker notice is re-checked just before it is delivered.
210
+ - **`collab file list`** counts files that already ended, and `--all` shows
211
+ each with why — collected, expired or withdrawn.
212
+ - **Roster efficiency.** Roster reads are coalesced and conditional, so an
213
+ unchanged roster is not sent again.
214
+ - **Logs capped at 10 MB** each, at write time — `daemon.log`, `hub.log`,
215
+ `ngrok.log` and the new `worker.log`, one content-free line per worker attempt
216
+ ([state storage](docs/state-storage.md)).
217
+
218
+ ---
219
+
117
220
  ## Documentation
118
221
 
119
222
  This page is the tour. Two directories go further, and they are for different
@@ -190,6 +293,14 @@ the SSE `id:`. A reconnecting daemon sends `Last-Event-ID: 412` and the hub
190
293
  replays from the log. Kill the hub with `-9`, restart it: the feed resumes with
191
294
  no gap.
192
295
 
296
+ One session remains reachable locally and through its public tunnel. A join
297
+ can use verified private same-machine discovery. After an authenticated join,
298
+ a client can select the host's advertised pinned TLS entrance on a reachable
299
+ private network, then fall back publicly without changing membership. A link
300
+ alone cannot authorize that LAN destination. Older links and clients retain
301
+ their public route. [Route selection and recovery](docs/local-routes.md)
302
+ describe trust checks, optional OpenSSL setup and measured local/tunnel costs.
303
+
193
304
  ## Install
194
305
 
195
306
  Two ways in. Take the first unless you intend to change collab itself.
@@ -305,8 +416,17 @@ current link. To keep one address across restarts, pin a reserved domain:
305
416
 
306
417
  ```bash
307
418
  collab host --domain your-name.ngrok-free.app
419
+ collab config ngrok_domain your-name.ngrok-free.app # or once, for every session
308
420
  ```
309
421
 
422
+ The order is `--domain`; then a domain you gave this session with `--domain`
423
+ before, which it keeps; then the `ngrok_domain` setting, which also moves
424
+ sessions that only ever had the default — so correcting or clearing the
425
+ setting takes effect at the next `collab host`. One domain serves one session at a time. If ngrok refuses to
426
+ start — for example because that endpoint is already online in another ngrok
427
+ process (`ERR_NGROK_334`) — `collab host` prints ngrok's own reason and the
428
+ remedy, and the session stays usable on this machine.
429
+
310
430
  The link is the only credential for joining, so anyone holding it can get in. If
311
431
  it leaks, or you shared it more widely than you meant to, replace it:
312
432
 
@@ -368,7 +488,8 @@ told to arm a monitor it does not have arms nothing and stops looking.
368
488
  `collab check`'s `watching` line says the same thing whenever nothing is
369
489
  reading.
370
490
 
371
- Host and join enable a Codex/Luna conversation worker by default. Customize
491
+ Host and join enable a conversation worker by default, on the coding agent's
492
+ own provider and its lower-tier model (Claude Code → Haiku, Codex → Luna). Customize
372
493
  its provider and scope and supply current task facts:
373
494
 
374
495
  ```bash
@@ -387,15 +508,20 @@ escalation; it must not imply that a decision has already been made. The usual
387
508
  scope and supplied-facts limits still apply.
388
509
 
389
510
  The worker keeps answering peers while the main agent works. Keep the usual
390
- monitor or wake armed: it now carries worker decisions and recovery alerts.
511
+ monitor or wake armed: it carries worker decisions, recovery alerts and hub
512
+ approval-security alarms.
391
513
  Answers return to the worker and then to the waiting peer. Choose its provider
392
514
  independently of the coding host: Codex, Claude, OpenCode, Cursor, or a custom
393
- adapter. The defaults are Luna for Codex and Haiku 4.5 for Claude; OpenCode and
394
- Cursor require explicit models. Model failures never switch to a premium model.
515
+ adapter. The defaults are Luna for Codex and Haiku 5.5 for Claude; OpenCode and
516
+ Cursor require explicit models. Model failures never switch to a premium model;
517
+ rate limits wait (at most an hour), and login or model errors become one pending
518
+ decision and are rechecked only hourly instead of every retry.
395
519
  See [conversation workers](docs/conversation-worker.md) for setup, authentication,
396
520
  scope, limits, and the return path. Use `collab worker off` to disable it for
397
521
  this session, or `collab config worker_auto_start false` before setup to opt out.
398
- `collab config worker_agent claude` selects Claude/Haiku 4.5 for unconfigured sessions.
522
+ Automatic setup follows the coding agent (Claude Code gets a Claude worker, Codex a
523
+ Codex one); `collab config worker_agent codex|claude` pins a provider instead. While
524
+ the worker is on, `collab send` is queued through it rather than posted directly.
399
525
  Explicit off and provider choices survive reconnects.
400
526
 
401
527
  Without a worker, automatic delivery is a compact inbox notice, with no peer message text. One
@@ -1167,12 +1293,14 @@ collab 1.7.0 — let coding agents talk to each other
1167
1293
  | `collab listen --follow` | stream events as lines (what a Monitor watches) |
1168
1294
  | `collab recv --wait N` | drain unread, optionally waiting |
1169
1295
  | `collab watch` | a full-screen live view: roster, usage and conversation |
1170
- | `collab sessions` | sessions this repo has hosted before |
1296
+ | `collab sessions` | saved host and guest sessions for this participant |
1297
+ | `collab resume <id>` | resume a saved session in its original working path |
1171
1298
  | `collab kill` | end a session (its data is kept unless `--purge`) |
1172
1299
  | `collab join` | join the session running on this machine — no link needed |
1173
1300
  | `collab discover` | collab sessions running on this machine |
1174
1301
  | `collab join <id>` | join a particular one, when several are running — the id `discover` prints |
1175
1302
  | `collab stats` | what each agent reports about its usage, and when it reported it |
1303
+ | `collab dashboard` | everyone's quota windows, worker budget and shared skills, kept current by the daemon |
1176
1304
  | `collab rules [--default]` | how to behave in a session — what `host` and `join` print on arrival; `--default` is the shipped file alone, to seed a repo's `COLLAB.md` |
1177
1305
  | `collab update` | check for, and install, a newer collab, then re-run the installers for whatever was already installed |
1178
1306
  | `collab who` | roster: who is here, their repo, branch and focus |
@@ -1612,7 +1740,9 @@ re-sharing is a decision you make each time you resume.
1612
1740
  collab host # resume the most recent (the default)
1613
1741
  collab host --resume <id> # resume a particular one
1614
1742
  collab host --fresh # start an empty session instead
1615
- collab sessions # what this repo has hosted, and what each holds
1743
+ collab sessions # saved host and guest sessions, with working paths
1744
+ collab resume <id> # resume either role in its original working path
1745
+ collab resume <id> --keep # keep it after the coding agent exits
1616
1746
  collab kill # end the current one — data kept, resumable
1617
1747
  collab kill --disarm # and turn off the wake armed on it
1618
1748
  collab kill --all # end every session this repo hosts
@@ -1670,6 +1800,14 @@ collab daemon start --keep
1670
1800
  collab config follow_agent off # never follow, for any session
1671
1801
  ```
1672
1802
 
1803
+ `--keep` is remembered for that saved session, including listener restarts and
1804
+ host resume. It also detaches an already-running follower on its next ownership
1805
+ check; it does not need a restart to take effect. The choice is local to this
1806
+ participant's session and does not change another participant's lifecycle or the
1807
+ global `follow_agent` setting. Stop it explicitly with `collab kill` or
1808
+ `collab daemon stop`; a fresh session starts with the normal following policy.
1809
+ Combining `--keep` with `--no-daemon` still records the choice for a later start.
1810
+
1673
1811
  Two minutes rather than at once, because quitting an agent and starting it again
1674
1812
  is common and should cost nothing: the next `collab host` or `collab join` from
1675
1813
  the new agent re-claims the session, and the daemon picks that up on its next
@@ -1857,7 +1995,12 @@ If a session is listed there it is yours to bring back — `collab host`, or
1857
1995
  `collab host --resume <id>` for a particular one — with its history and a fresh
1858
1996
  invite for others to rejoin. There is no need to ask whoever you were talking
1859
1997
  to restart anything. Only when nothing at all is listed is nothing running.
1860
- `collab sessions` lists everything this repo has, running or not.
1998
+ `collab sessions` lists this participant’s saved host and guest sessions, running
1999
+ or not. `collab resume <id>` restores the original working path and identity;
2000
+ use `--home <state-folder>` with either command to select your own saved state
2001
+ from another workspace or coding-agent thread. A guest requires its host to be
2002
+ reachable. A missing working directory or unknown session ID fails without
2003
+ selecting another session. The calling shell’s directory does not change.
1861
2004
 
1862
2005
  A session is registered by its **hub**, so it stays discoverable and joinable
1863
2006
  even if its listener has stopped — the hub is what makes it reachable. Stopping
@@ -1914,11 +2057,22 @@ cannot hold up chat, activity or the participant roster.
1914
2057
  Claude Code and Codex telemetry configure automatically when hosting, joining
1915
2058
  or starting the daemon. `stats_auto_setup` is enabled by default. Routing belongs
1916
2059
  to each participant, so a mixed room keeps Claude and Codex sources separate.
2060
+ Every other agent collab detects (Gemini CLI, opencode, Cursor, Copilot CLI,
2061
+ goose, Amp) is recorded with its quota unknown and the reason, which
2062
+ `collab stats` and `collab check` show. On any switch of tool the previous
2063
+ tool's quota, model and context are withdrawn, and nothing is published in
2064
+ place of a missing figure. Markers are inherited, so a tool started inside
2065
+ another is credited only when every marker's tool is an agent process above
2066
+ it, nearest first; otherwise the quota is «nested tools; cannot attribute».
2067
+ A stale inherited marker therefore reads as unknown – the accepted cost.
1917
2068
  Explicit sources and explicit opt-outs take precedence. Worker usage remains a
1918
2069
  separate observation from its native provider response.
1919
2070
 
1920
- The roster refreshes independently every three seconds and on activity/presence
1921
- events. After 30 seconds without a successful fetch, connectivity becomes
2071
+ The roster refreshes independently every three seconds. Activity/presence
2072
+ invalidations share fixed 100 ms windows, with a trailing read for events that
2073
+ arrive during a fetch. Unchanged rosters use private conditional responses;
2074
+ finite roster JSON negotiates gzip while chat stays on its unbuffered SSE feed.
2075
+ After 30 seconds without a successful fetch or revalidation, connectivity becomes
1922
2076
  unknown, even if chat is live. Working/idle still describes reported activity.
1923
2077
  See [telemetry setup and controls](docs/telemetry.md) and
1924
2078
  [panel refresh behavior](docs/watch-panel.md).
@@ -1931,7 +2085,7 @@ Agents expose different sources:
1931
2085
  | **Antigravity** | automatic — same mechanism, its status line payload is understood too |
1932
2086
  | **Codex CLI** | automatic – setup binds the participant to its exact Codex thread and probes native usage and account limits |
1933
2087
  | **opencode** | `collab stats --report` from a plugin — a shell status line is still an [open request](https://github.com/anomalyco/opencode/issues/30295) |
1934
- | **Gemini CLI** | `collab stats --report` — statusline is an [open request](https://github.com/google-gemini/gemini-cli/issues/8191); `/stats` shows the numbers |
2088
+ | **Gemini CLI** | quota unknown automatically – the CLI keeps it in process memory only; `collab stats --report` — statusline is an [open request](https://github.com/google-gemini/gemini-cli/issues/8191); `/stats` shows the numbers |
1935
2089
  | **anything else** | `collab stats --report` |
1936
2090
 
1937
2091
  ### Keeping them current
@@ -1952,6 +2106,12 @@ It is run and checked immediately, so a typo tells you at once rather than
1952
2106
  silently reporting nothing forever. `collab stats --source ''` clears it and
1953
2107
  persistently opts out of automatic polling. Unset `stats_command` to restore
1954
2108
  automatic routing; disabling `stats_auto_setup` also stops automatic polling.
2109
+ A telemetry opt-out set machine-wide (`collab config stats_auto_setup false
2110
+ --machine`, or an empty `stats_command` there) applies to every agent; a
2111
+ non-empty `stats_command` is per agent. One left in the machine file stops
2112
+ applying, and automatic setup installs nothing until the person adopts it
2113
+ (`collab config stats_command '<probe>'`) or clears it; host and join say so
2114
+ once, and `collab check` warns on every run until then.
1955
2115
 
1956
2116
  **Some agents will only tell a program, not a shell.** Codex has no status line
1957
2117
  and no usage flag, but its CLI ships an app-server that will say what quota is
@@ -2251,6 +2411,11 @@ only with the last of them — or after 30 minutes, whichever comes first.
2251
2411
  Someone who joins later may still fetch it while it lasts, but does not keep it
2252
2412
  alive; someone removed from the session does not hold it up.
2253
2413
 
2414
+ `collab file list` shows files still on the host and says how many have
2415
+ already ended; `collab file list --all` adds those, each marked collected,
2416
+ expired or withdrawn, so a file that left the list is never mistaken for one
2417
+ that was lost.
2418
+
2254
2419
  ## Security
2255
2420
 
2256
2421
  - **Per-participant tokens.** An invite is exchanged once for your own bearer
@@ -2322,9 +2487,30 @@ records, and no amount of scrubbing entitles anybody to publish it unseen. With
2322
2487
  diagnostics off it still writes the header and tells you how to capture a log.
2323
2488
 
2324
2489
  Beside it, `daemon.log` and `hub.log` are the two processes' own output at more
2325
- length. Those have always been kept and are not a record of anything in
2326
- particular; a process rolls one aside when it opens it and finds it past two
2327
- megabytes, keeping one previous generation.
2490
+ length, `ngrok.log` is the tunnel agent's, and `worker.log` has one JSON line per
2491
+ conversation-worker attempt — an opaque random `attempt` id, how far it got
2492
+ (`reserved`, `launched`,
2493
+ `committed`), its outcome (`output`, `no-op`, `invalid`, `failed`, `cancelled`,
2494
+ or `skipped-local` for a counted turn that called no model), what triggered it
2495
+ as counts by kind, the model, tokens and cost, reply and escalation counts, the
2496
+ class of any failure and how long it took — never what anybody said, who said
2497
+ it, or a provider's own error text. Every one of them is capped at 10 MB with its
2498
+ rotated generation — the live file, `<name>.1` and a rotation's `<name>.1.tmp`
2499
+ together — and the cap is applied AT WRITE TIME: whatever collab writes rotates
2500
+ first if it would carry the live file past 3 MiB, so no burst can take the file
2501
+ over its budget. ngrok never writes `ngrok.log` itself; its output goes through a
2502
+ small collector process that writes the file the same way and drops a flood
2503
+ past 256 KB a second, saying how many lines it dropped. A watcher thread
2504
+ remains as a safety net for the one thing that writes around the cap — an
2505
+ interpreter's own traceback on a crash, a few kilobytes once.
2506
+
2507
+ Upgrading from 2.1.2: an older `collab host` started beside a newer hub renames
2508
+ `hub.log` aside to `hub.log.1` when it opens it, as 2.1.2 always did. The newer
2509
+ hub's logging notices the rename and starts a fresh `hub.log`, and the lines
2510
+ from before are in `hub.log.1`. Its raw stderr — a crash traceback — still
2511
+ points at the renamed file, which a later rotation replaces, so such a
2512
+ traceback can be lost; restarting the hub ends that. `collab logs` prints all three of
2513
+ collab's own.
2328
2514
 
2329
2515
  ## Settings
2330
2516
 
@@ -2349,13 +2535,15 @@ collab config --json # the same table, for an agent to read
2349
2535
 
2350
2536
  | Setting | What it does | Also set by | Default |
2351
2537
  |---|---|---|---|
2352
- | `display_name` | the name others see | `collab name <n>` | git `user.name`, else `$USER` |
2538
+ | `display_name` | the name others see | `collab name <n>` | the agent kind and a stable suffix, e.g. `claude-3f2a91c0` (a legacy machine-wide name is adopted by the first agent only) |
2353
2539
  | `color` | the colour others see you in | `collab color <hex>` | dealt from the palette |
2354
2540
  | `editor` | terminal editor command; empty follows VISUAL, EDITOR, then vi | — | empty |
2355
2541
  | `theme` | how the conversation is laid out | `collab theme <name>` | `classic` |
2356
2542
  | `timezone` | the zone dates and times are read in; an IANA name, or `auto` for the computer's own | — | `auto` |
2357
2543
  | `share_stats` | share your usage with the session | `collab stats --share on\|off` | `on` |
2358
2544
  | `rules` | print collab's rules of conduct at `host` and `join`; the pointer to the repo's own `COLLAB.md` always prints | — | `on` |
2545
+ | `ngrok_domain` | reserved ngrok domain `collab host` uses when `--domain` is not given; a session you gave its own `--domain` keeps it | `collab host --domain` | empty |
2546
+ | `proxy` | shared machine tunnel policy: on/auto share one machine tunnel, off gives each hub its own | `collab host --tunnel own\|proxy` | `auto` |
2359
2547
  | `watch_layout` | `split`, `tmux`, `chat` or `roster` | `collab watch --layout <l> --save` | `split` |
2360
2548
  | `watch_roster_size` | how much room the roster gets, in percent | `collab watch --roster-size <n> --save` | `30` |
2361
2549
  | `watch_roster_position` | `top`, `bottom`, `left` or `right` | `collab watch --roster-position <p> --save` | `top` |
@@ -2392,9 +2580,10 @@ asked to display is a worse surprise than the one it would be fixing. If the old
2392
2580
  key is still in your file, `collab config` says so in one line every time you
2393
2581
  list your settings, until you replace it.
2394
2582
 
2395
- `display_name` and `color` here are the machine-wide defaults. Where two agents
2396
- share one checkout each has its own name and colour in its own state directory,
2397
- and `collab name` and `collab color` set those — see
2583
+ `display_name` and `color` are each agent's own, never inherited from the
2584
+ machine file (a value left there is shown as legacy, with how to adopt it).
2585
+ Where two agents share one checkout each has its own name and colour in its own
2586
+ state directory, and `collab name` and `collab color` set those — see
2398
2587
  [Two agents in one checkout](#two-agents-in-one-checkout).
2399
2588
 
2400
2589
  **A change reaches the sessions you already have open.** That is the rule for
@@ -2596,6 +2785,7 @@ retain the same internal layout:
2596
2785
  status.json what the status line reads
2597
2786
  agent_stats.json usage your agent reported, waiting to be shared
2598
2787
  daemon.pid daemon.log the listener; the pid file carries the boot it was written on
2788
+ worker.db worker.log the conversation worker's state, and one line per model turn
2599
2789
  hub.json host only: port, invite and host token (0600)
2600
2790
  hub.db host only: the session's event log
2601
2791
  hub.log ngrok.log host only
@@ -2702,7 +2892,13 @@ Work that came from outside this repository, and the release it landed in:
2702
2892
 
2703
2893
  ## Proactive batch pickup
2704
2894
 
2705
- Proactive pickup is enabled by default. After **five continuous idle minutes**, a
2895
+ Proactive pickup is enabled by default. Joining a batch offers unclaimed work
2896
+ immediately when you own no unfinished task. Completing your current task also
2897
+ prompts you to inspect and claim suitable next work without waiting for the lead.
2898
+ These foreground prompts reserve nothing and add no network requests. Inspect
2899
+ dependencies before claiming, and split large tasks into bounded deliverables.
2900
+
2901
+ After **five continuous idle minutes**, a
2706
2902
  participant with no owned unfinished tasks receives a notice to inspect the
2707
2903
  latest batch. A working participant can also receive one when fresh native
2708
2904
  child counts and an explicitly configured quota/concurrency budget show spare
@@ -2793,7 +2989,11 @@ guides load the workflow an agent needs. Install them with `collab skills instal
2793
2989
  Agents can publish selected skills with `collab skills publish PATH`, discover
2794
2990
  metadata with `collab skills shared`, inspect with `collab skills show ID`, and
2795
2991
  withdraw their own entry. Shared text is never installed or executed automatically.
2796
- `collab capacity --json` estimates additional native teammates only when the
2992
+ Each participant's installed skill names are shared by default (`collab skills
2993
+ peers`; `collab config share_skill_list false` opts out), and `collab skills ask
2994
+ SKILL --to NAME` requests a run that only the receiver's human can `accept`.
2995
+ Up to two native teammates is the default when independent work exists.
2996
+ `collab capacity --json` estimates additional native teammates beyond that only when the
2797
2997
  concurrency, active count, fresh quota and per-task budget are known.
2798
2998
  [Capability and capacity guide](docs/skills-and-capacity.md).
2799
2999
 
@@ -2828,3 +3028,14 @@ no longer impose a model cooldown; `collab config worker_turn_gap 5` governs
2828
3028
  actual model calls, while existing attempt budgets and retries remain in force.
2829
3029
  Provider call duration still contributes to reply time. See
2830
3030
  [worker behavior](docs/conversation-worker.md) for the delivery model.
3031
+
3032
+ ### Shared public tunnel
3033
+
3034
+ One machine proxy can serve every hosted session through one tunnel: sessions
3035
+ receive `/s/<id>` links under the shared domain. It is the default from 2.2.0
3036
+ (`proxy` = `auto`); `collab config proxy off`, or `collab host --tunnel own`
3037
+ for one session, keeps a hub on its own tunnel. A session that served the bare
3038
+ domain with its own tunnel before keeps it automatically, so the links handed
3039
+ out then still reach it; `collab host --primary` asks for it explicitly, and a
3040
+ session refused it is told. See [proxy hosting
3041
+ and migration](docs/proxy-hosting.md).