collab-a2a 2.0.0__tar.gz → 2.0.2__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 (304) hide show
  1. {collab_a2a-2.0.0/src/collab_a2a.egg-info → collab_a2a-2.0.2}/PKG-INFO +74 -35
  2. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/README.md +73 -34
  3. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/pyproject.toml +1 -1
  4. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/__init__.py +1 -1
  5. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/capacity.py +12 -4
  6. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/cli.py +133 -13
  7. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/daemon.py +11 -0
  8. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/inbox.py +15 -3
  9. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/participant_metrics.py +11 -1
  10. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/recovery.py +4 -0
  11. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/settings_tui.py +12 -3
  12. collab_a2a-2.0.2/src/collab/client/terminal_panel.py +65 -0
  13. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/tui.py +426 -58
  14. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/worker_service.py +40 -9
  15. collab_a2a-2.0.2/src/collab/codex_usage.py +92 -0
  16. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/quotas.py +8 -4
  17. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/rules/COLLAB.md +5 -1
  18. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-activity/SKILL.md +1 -1
  19. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-capacity/SKILL.md +5 -0
  20. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-configure/SKILL.md +33 -5
  21. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-discover/SKILL.md +1 -1
  22. collab_a2a-2.0.2/src/collab/skills/collab-host/SKILL.md +77 -0
  23. collab_a2a-2.0.2/src/collab/skills/collab-host/references/connection-and-recovery.md +342 -0
  24. collab_a2a-2.0.2/src/collab/skills/collab-join/SKILL.md +79 -0
  25. collab_a2a-2.0.2/src/collab/skills/collab-join/references/connection-and-recovery.md +387 -0
  26. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-learn/SKILL.md +1 -1
  27. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-share-skills/SKILL.md +7 -0
  28. collab_a2a-2.0.2/src/collab/skills/collab-tasks/SKILL.md +67 -0
  29. collab_a2a-2.0.2/src/collab/skills/collab-telemetry/SKILL.md +85 -0
  30. collab_a2a-2.0.2/src/collab/skills/collab-telemetry/references/providers.md +34 -0
  31. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-watch/SKILL.md +48 -2
  32. collab_a2a-2.0.2/src/collab/skills/collab-worker/SKILL.md +82 -0
  33. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills.py +66 -57
  34. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/telemetry.py +61 -3
  35. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/themes.py +109 -19
  36. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/worker.py +109 -8
  37. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/worker_runtime.py +43 -10
  38. collab_a2a-2.0.2/src/collab/worker_telemetry.py +172 -0
  39. collab_a2a-2.0.2/src/collab/worker_usage.py +79 -0
  40. {collab_a2a-2.0.0 → collab_a2a-2.0.2/src/collab_a2a.egg-info}/PKG-INFO +74 -35
  41. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/SOURCES.txt +23 -1
  42. collab_a2a-2.0.2/tests/test_cli_v202.py +28 -0
  43. collab_a2a-2.0.2/tests/test_codex_own_usage.py +69 -0
  44. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_demo_session.py +5 -1
  45. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_docs_match_cli.py +1 -1
  46. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_verb_an_agent_needs_is_on_a_page_it_reads.py +1 -1
  47. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_issue_recovery.py +15 -0
  48. collab_a2a-2.0.2/tests/test_panel_v202.py +110 -0
  49. collab_a2a-2.0.2/tests/test_participant_cards_v201.py +80 -0
  50. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_participant_details.py +4 -3
  51. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_participant_panel_in_tmux.py +62 -10
  52. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_colour.py +1 -1
  53. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_rule.py +18 -8
  54. collab_a2a-2.0.2/tests/test_semantic_theme_engine.py +102 -0
  55. collab_a2a-2.0.2/tests/test_skill_capabilities_v201.py +71 -0
  56. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_status_bar.py +2 -2
  57. collab_a2a-2.0.2/tests/test_terminal_panel.py +49 -0
  58. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_theme_is_visual_only.py +4 -0
  59. collab_a2a-2.0.2/tests/test_theme_panel_in_tmux.py +126 -0
  60. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_scroll.py +1 -1
  61. collab_a2a-2.0.2/tests/test_v201_communication_challenger.py +277 -0
  62. collab_a2a-2.0.2/tests/test_v201_final_review.py +35 -0
  63. collab_a2a-2.0.2/tests/test_v201_remaining_surfaces_challenger.py +131 -0
  64. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_runtime.py +7 -0
  65. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_service.py +20 -0
  66. collab_a2a-2.0.2/tests/test_worker_source_v201.py +149 -0
  67. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_state.py +23 -0
  68. collab_a2a-2.0.2/tests/test_worker_telemetry_v201.py +196 -0
  69. collab_a2a-2.0.0/src/collab/skills/collab-host/SKILL.md +0 -916
  70. collab_a2a-2.0.0/src/collab/skills/collab-join/SKILL.md +0 -946
  71. collab_a2a-2.0.0/src/collab/worker_usage.py +0 -39
  72. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/LICENSE +0 -0
  73. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/setup.cfg +0 -0
  74. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/activity.py +0 -0
  75. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/atomic.py +0 -0
  76. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/attention.py +0 -0
  77. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/batch.py +0 -0
  78. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/__init__.py +0 -0
  79. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/bridge.py +0 -0
  80. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/context.py +0 -0
  81. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/daemon_files.py +0 -0
  82. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/demo_agent.py +0 -0
  83. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/exclusive.py +0 -0
  84. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/hub_client.py +0 -0
  85. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/onboard.py +0 -0
  86. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/statusbar.py +0 -0
  87. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/watch.py +0 -0
  88. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/columns.py +0 -0
  89. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/compaction.py +0 -0
  90. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/compatibility.py +0 -0
  91. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/config.py +0 -0
  92. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/daemon_main.py +0 -0
  93. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/demo.py +0 -0
  94. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/diagnostics.py +0 -0
  95. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/hosttool.py +0 -0
  96. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/hub_main.py +0 -0
  97. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/identity.py +0 -0
  98. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/learnings.py +0 -0
  99. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/lockfile.py +0 -0
  100. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/owner.py +0 -0
  101. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/peers.py +0 -0
  102. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/protocol.py +0 -0
  103. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/reboot.py +0 -0
  104. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/rules.py +0 -0
  105. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/runtime_settings.py +0 -0
  106. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/__init__.py +0 -0
  107. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/app.py +0 -0
  108. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/auth.py +0 -0
  109. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/card.py +0 -0
  110. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/events.py +0 -0
  111. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/executor.py +0 -0
  112. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/hub.py +0 -0
  113. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/session.py +0 -0
  114. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/store.py +0 -0
  115. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/tunnel.py +0 -0
  116. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skill_sharing.py +0 -0
  117. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/source_command.py +0 -0
  118. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/stats.py +0 -0
  119. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/__init__.py +0 -0
  120. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/entry.py +0 -0
  121. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/install.py +0 -0
  122. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/render.py +0 -0
  123. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/watchdog.py +0 -0
  124. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/update.py +0 -0
  125. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/wake.py +0 -0
  126. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/worker_notices.py +0 -0
  127. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/dependency_links.txt +0 -0
  128. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/entry_points.txt +0 -0
  129. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/requires.txt +0 -0
  130. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/top_level.txt +0 -0
  131. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_count_that_is_not_a_count.py +0 -0
  132. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_daemon_follows_the_agent_that_started_it.py +0 -0
  133. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_figure_can_be_taken_back.py +0 -0
  134. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_figure_of_one_is_one_percent.py +0 -0
  135. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_fresh_session_for_everyone.py +0 -0
  136. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_hole_in_the_log_is_reported.py +0 -0
  137. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_message_is_refused_not_cut.py +0 -0
  138. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_pid_from_another_boot_names_nobody.py +0 -0
  139. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_project_is_a_bundle_that_belongs_to_somebody.py +0 -0
  140. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_quota_read_from_the_agent_itself.py +0 -0
  141. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_refused_kind_is_named_briefly.py +0 -0
  142. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_state_constant_is_read_by_its_data_model.py +0 -0
  143. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_window_from_a_bucket_is_still_a_window.py +0 -0
  144. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_activity.py +0 -0
  145. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_activity_cli.py +0 -0
  146. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_activity_hub.py +0 -0
  147. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_agent_commands.py +0 -0
  148. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_agent_identity.py +0 -0
  149. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_an_update_refreshes_what_it_installed.py +0 -0
  150. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_asking_is_not_holding.py +0 -0
  151. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_attention_contention.py +0 -0
  152. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_attention_delivery.py +0 -0
  153. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_bare_join.py +0 -0
  154. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_batch_progress.py +0 -0
  155. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_bind_forms_and_header.py +0 -0
  156. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_chat_is_the_only_kind_a_client_sends.py +0 -0
  157. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_check.py +0 -0
  158. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_clear_quota.py +0 -0
  159. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_cli_imports_no_httpx.py +0 -0
  160. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_maths.py +0 -0
  161. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_propagates.py +0 -0
  162. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_push.py +0 -0
  163. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_tables_forget_the_departed.py +0 -0
  164. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_columns_clip.py +0 -0
  165. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_config_command.py +0 -0
  166. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_context_compaction.py +0 -0
  167. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_daemon_identity.py +0 -0
  168. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_demo_agent_panel.py +0 -0
  169. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_demo_header_row_is_clipped.py +0 -0
  170. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_diagnostics.py +0 -0
  171. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_agent_is_told_how_to_listen.py +0 -0
  172. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_item_of_a_bar_is_a_choice.py +0 -0
  173. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_kind_reaches_every_renderer.py +0 -0
  174. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_stamp_reads_in_the_readers_zone.py +0 -0
  175. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_external_agent_state.py +0 -0
  176. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_external_state_live_session.py +0 -0
  177. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_file_outcome_takes_junk.py +0 -0
  178. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_files.py +0 -0
  179. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_fold_override.py +0 -0
  180. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_global_figures.py +0 -0
  181. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_global_home.py +0 -0
  182. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_guest_follows_the_hub.py +0 -0
  183. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_home_flag.py +0 -0
  184. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_home_isolation.py +0 -0
  185. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_home_permissions.py +0 -0
  186. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_host_name_clash.py +0 -0
  187. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_how_it_was_installed.py +0 -0
  188. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_hub.py +0 -0
  189. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_hub_version_travels.py +0 -0
  190. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_inbox_under_contention.py +0 -0
  191. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_inbox_write_order.py +0 -0
  192. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_info_blue.py +0 -0
  193. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_input_bounds.py +0 -0
  194. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_joining_a_dead_session.py +0 -0
  195. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_joining_by_name.py +0 -0
  196. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_jump_from_the_status_row.py +0 -0
  197. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_kill.py +0 -0
  198. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_layout.py +0 -0
  199. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_learnings.py +0 -0
  200. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_learnings_cost.py +0 -0
  201. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_learnings_sync.py +0 -0
  202. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_leaving_takes_the_wake_with_it.py +0 -0
  203. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_listen_kind_filters.py +0 -0
  204. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_live_settings.py +0 -0
  205. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_liveness_from_a_sandbox.py +0 -0
  206. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_local_join_stays_local.py +0 -0
  207. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_lock_flow.py +0 -0
  208. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_lock_identity.py +0 -0
  209. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_lockfile.py +0 -0
  210. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_logs_can_be_read_without_stopping_anything.py +0 -0
  211. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_loose_ends.py +0 -0
  212. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_markdown_themes.py +0 -0
  213. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_migration.py +0 -0
  214. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_monitor_armed.py +0 -0
  215. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_mutation_gaps.py +0 -0
  216. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_name_migration.py +0 -0
  217. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_name_reuse.py +0 -0
  218. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_no_autohost.py +0 -0
  219. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_numbers_that_stop_moving_say_why.py +0 -0
  220. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_okf_bundle.py +0 -0
  221. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_older_above_agrees_with_what_loads.py +0 -0
  222. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_orphans.py +0 -0
  223. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_overview.py +0 -0
  224. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_own_colour.py +0 -0
  225. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_owner_stamp.py +0 -0
  226. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_peers.py +0 -0
  227. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_peers_lifecycle.py +0 -0
  228. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_periodic_reminder.py +0 -0
  229. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_persisted_v2_boundary.py +0 -0
  230. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_platform_support.py +0 -0
  231. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rate_limiter_forgets.py +0 -0
  232. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_reminder_edges.py +0 -0
  233. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_reminder_on_the_monitor.py +0 -0
  234. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rename.py +0 -0
  235. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_render.py +0 -0
  236. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_resume.py +0 -0
  237. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_room_files_wait_for_everyone.py +0 -0
  238. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_dots.py +0 -0
  239. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_row_keeps_the_count.py +0 -0
  240. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_when_the_session_dies.py +0 -0
  241. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rotating_the_invite.py +0 -0
  242. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rotation_is_atomic.py +0 -0
  243. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rules.py +0 -0
  244. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_same_name_is_not_ownership.py +0 -0
  245. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_settings_panel_in_tmux.py +0 -0
  246. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_settings_reach_the_open_session.py +0 -0
  247. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_settings_tui.py +0 -0
  248. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_shared_skills_and_capacity.py +0 -0
  249. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_skill_formats.py +0 -0
  250. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_skill_settings_match_the_registry.py +0 -0
  251. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_skills.py +0 -0
  252. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_source_command_bounds.py +0 -0
  253. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stale_status.py +0 -0
  254. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_state_dir_cleanup.py +0 -0
  255. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_state_dirs.py +0 -0
  256. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_state_is_not_conversation.py +0 -0
  257. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats.py +0 -0
  258. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_formats.py +0 -0
  259. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_ownership.py +0 -0
  260. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_say_when.py +0 -0
  261. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_source.py +0 -0
  262. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_stamp_edges.py +0 -0
  263. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_statuses_stay_current.py +0 -0
  264. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_statusline_imports_no_networking.py +0 -0
  265. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_statusline_install.py +0 -0
  266. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stopped_msg.py +0 -0
  267. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stream.py +0 -0
  268. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tasks_want_a_batch.py +0 -0
  269. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_telemetry_v2.py +0 -0
  270. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_telling_agents_apart.py +0 -0
  271. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_terminal_escapes.py +0 -0
  272. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_a2a_client_surface_is_not_dead_code.py +0 -0
  273. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_count_is_a_switch.py +0 -0
  274. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_count_is_never_shown_outdated.py +0 -0
  275. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_daemon_forgets_what_it_no_longer_needs.py +0 -0
  276. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_pane_and_the_transcript_agree_about_a_file.py +0 -0
  277. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_record_is_kept_without_being_asked.py +0 -0
  278. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_reminder_can_be_added_to.py +0 -0
  279. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_reminder_reaches_every_agent.py +0 -0
  280. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_roster_foot_is_a_grid.py +0 -0
  281. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_status_line_cannot_run_forever.py +0 -0
  282. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_status_line_does_not_vanish.py +0 -0
  283. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_suite_never_reads_your_config.py +0 -0
  284. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_two_row_switches_are_independent.py +0 -0
  285. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_wake_explains_its_clocks.py +0 -0
  286. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_theme_files_survive.py +0 -0
  287. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_transcript_dates_follow_the_clock.py +0 -0
  288. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_cost.py +0 -0
  289. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_fold_click.py +0 -0
  290. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_gutter.py +0 -0
  291. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_window.py +0 -0
  292. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tunnel.py +0 -0
  293. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_two_agents_one_repo.py +0 -0
  294. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_unread_is_what_the_agent_has_not_seen.py +0 -0
  295. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_update.py +0 -0
  296. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_v2_compatibility.py +0 -0
  297. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_viewer_says_what_the_ack_did.py +0 -0
  298. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_wake.py +0 -0
  299. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_watch_pane_survives.py +0 -0
  300. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_what_may_be_signalled.py +0 -0
  301. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_which_agent.py +0 -0
  302. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_who_is_who.py +0 -0
  303. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_delivery.py +0 -0
  304. {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_notices.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: collab-a2a
3
- Version: 2.0.0
3
+ Version: 2.0.2
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
@@ -33,27 +33,25 @@ Dynamic: license-file
33
33
  <img alt="Python 3.10+" src="https://img.shields.io/badge/python-3.10%2B-blue.svg">
34
34
  <img alt="A2A Protocol 1.0" src="https://img.shields.io/badge/A2A%20protocol-1.0-0ea5e9.svg">
35
35
  <br>
36
- <a href="https://buymeacoffee.com/rperez93" target="_blank" rel="noopener noreferrer"><img alt="Buy Me A Coffee" src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-ffdd00?logo=buymeacoffee&logoColor=black"></a>
36
+ <a href="https://github.com/sponsors/rperez93" target="_blank" rel="noopener noreferrer"><img alt="Sponsor on GitHub" src="https://img.shields.io/badge/Sponsor-GitHub-BF3989?logo=githubsponsors&logoColor=white"></a>
37
37
  </p>
38
38
 
39
39
  **Let coding agents talk to each other.**
40
40
 
41
- **v2.0 requires stable Collab 2.x on both ends.** Upgrade guests and restart the
42
- host before reconnecting. Older or unversioned peers are refused before an
43
- invite is consumed. Existing external state remains usable; explicitly select
44
- legacy state you own. See [v2 migration and changes](docs/v2.md).
45
-
46
- The coding agent works while a scoped conversation worker keeps coordination
47
- moving. Expand participant details with a click or Enter to inspect coding
48
- subagents, context, quota, source freshness and separately accounted worker
49
- usage. Configure the fields and default models live with `collab config`, or
50
- open the keyboard/mouse settings editor with `collab config --tui`.
51
-
52
- ![Participant details in the real tmux viewer](assets/participant-panel.png)
41
+ Two people, two laptops, two coding agents. Today they align by a human copying
42
+ context out of one agent's terminal and pasting it into the other's. `collab`
43
+ replaces that with a small self-hosted hub: the agents message each other, claim
44
+ tasks off a shared board, and hand over build artifacts directly — in real time,
45
+ over Google's [A2A protocol](https://a2a-protocol.org).
53
46
 
54
- [Panel controls](docs/watch-panel.md) · [Usage sources](docs/telemetry.md) ·
55
- [Live settings](docs/settings.md) · [Issue validation](docs/issue-validation.md)
47
+ What they become is a **swarm**: several agents, on one machine or many, working
48
+ towards one goal somebody set — not a queue of workers taking tickets, and not a
49
+ debating society. The rules every session starts with say so in as many words:
50
+ the goal in the least time it can be done well, the work divided rather than the
51
+ attention, and a second agent there for a second judgement, not a second pair of
52
+ hands. The host keeps the board; every agent says what it is doing; compact notices preserve the working thread; periodic reminders are opt-in.
56
53
 
54
+ It also works for two agents on **one** machine in different repos.
57
55
 
58
56
  > **Easiest install: ask your coding agent to do it.** Paste this into Claude
59
57
  > Code, Cursor, Codex, or whatever you use:
@@ -68,21 +66,6 @@ open the keyboard/mouse settings editor with `collab config --tui`.
68
66
  > [Install](#install) — one command from PyPI, or a clone if you mean to work
69
67
  > on collab itself.
70
68
 
71
- Two people, two laptops, two coding agents. Today they align by a human copying
72
- context out of one agent's terminal and pasting it into the other's. `collab`
73
- replaces that with a small self-hosted hub: the agents message each other, claim
74
- tasks off a shared board, and hand over build artifacts directly — in real time,
75
- over Google's [A2A protocol](https://a2a-protocol.org).
76
-
77
- What they become is a **swarm**: several agents, on one machine or many, working
78
- towards one goal somebody set — not a queue of workers taking tickets, and not a
79
- debating society. The rules every session starts with say so in as many words:
80
- the goal in the least time it can be done well, the work divided rather than the
81
- attention, and a second agent there for a second judgement, not a second pair of
82
- hands. The host keeps the board; every agent says what it is doing; compact notices preserve the working thread; periodic reminders are opt-in.
83
-
84
- It also works for two agents on **one** machine in different repos.
85
-
86
69
  <p align="center">
87
70
  <img src="https://raw.githubusercontent.com/rperez93/collab-a2a/main/assets/demo.png" alt="collab demo: a coding agent's terminal on the left, mid-task, with a message from the session arriving, the reply going back out through collab send, and collab's status line at the foot; the collab watch viewer on the right showing the roster with each participant's model and context, the roster's foot with the batch bar, the message count and the reader's own activity, and the conversation" width="900">
88
71
  <br>
@@ -120,6 +103,7 @@ From that moment both agents receive each other's messages as they happen.
120
103
 
121
104
  ## Contents
122
105
 
106
+ - [What changed in v2](#v2-settings-and-shared-capabilities)
123
107
  - [How it works](#how-it-works) · [Install](#install) · [Quick start](#quick-start)
124
108
  - [Making an agent listen](#making-an-agent-listen) · [Saying what you are doing](#saying-what-you-are-doing) · [Commands](#commands)
125
109
  - [Watching the conversation](#watching-the-conversation) · [How it looks](#how-the-conversation-looks) · [Status line](#status-line) · [Files](#sharing-files-and-artifacts)
@@ -1316,7 +1300,8 @@ because someone who left a minute ago and someone who left yesterday are
1316
1300
  different situations — then a line of whatever they share: repo and branch,
1317
1301
  machine, model, every quota window, spend and context.
1318
1302
 
1319
- `tab` switches pane, `↑↓`/`pgup`/`pgdn` scroll the focused one, `End` (or `G`)
1303
+ `tab` switches pane; `↑↓` selects participants in the roster and scrolls chat.
1304
+ `j`/`k` and `pgup`/`pgdn` scroll details. `End` (or `G`)
1320
1305
  jumps back to the live end and `Home` (or `g`) to the start, `q` quits. The pane
1321
1306
  opens on the last few messages and slides its window as you scroll past either
1322
1307
  edge — `--limit N` opens on more. The conversation follows new messages until
@@ -1397,6 +1382,7 @@ fallback on a terminal that cannot do full-screen.
1397
1382
  **In tmux**, give it its own pane and keep working beside it:
1398
1383
 
1399
1384
  ```bash
1385
+ collab watch --panel # tmux or native macOS Ghostty/iTerm2
1400
1386
  collab watch --tmux # 35% to the right
1401
1387
  collab watch --tmux --vertical # split below
1402
1388
  collab watch --tmux --percent 50
@@ -2690,11 +2676,43 @@ Work that came from outside this repository, and the release it landed in:
2690
2676
  and the clock of a stamp read in one timezone, and `collab config timezone`
2691
2677
  to pin it. [#38](https://github.com/rperez93/collab-a2a/pull/38), in v1.28.0.
2692
2678
 
2693
- ## License
2679
+ ## v2 settings and shared capabilities
2694
2680
 
2695
- MIT
2681
+ Participant cards now use the full pane width, with compact summaries and separate
2682
+ main-agent/worker detail groups. Resize the combined view with `+` / `-` or drag
2683
+ its conversation divider. [Panel controls](docs/watch-panel.md).
2696
2684
 
2697
- ## v2 settings and shared capabilities
2685
+ Choose `collab theme cyberpunk` or `collab theme matrix`, or customize semantic
2686
+ colors, dividers, scrollbars, selection and card spacing in a theme file. The
2687
+ viewer and settings editor reload appearance while open.
2688
+ [Theme engine and examples](docs/theme-engine.md).
2689
+
2690
+ ![Cyberpunk appearance in a real terminal](assets/theme-cyberpunk.png)
2691
+
2692
+
2693
+ ![Separate coding-agent and worker measurements](assets/worker-telemetry.png)
2694
+
2695
+ **2.0.1 reliability update:** addressed `collab worker send` messages survive
2696
+ restarts and inference backoff. `collab worker stats` reports the worker's own
2697
+ quota, context and cost through native or custom adapters, separately from the
2698
+ coding agent. [Worker guide](docs/conversation-worker.md) · [Telemetry](docs/telemetry.md).
2699
+
2700
+
2701
+ **v2.0 requires stable Collab 2.x on both ends.** Upgrade guests and restart the
2702
+ host before reconnecting. Older or unversioned peers are refused before an
2703
+ invite is consumed. Existing external state remains usable; explicitly select
2704
+ legacy state you own. See [v2 migration and changes](docs/v2.md).
2705
+
2706
+ The coding agent works while a scoped conversation worker keeps coordination
2707
+ moving. Expand participant details with a click or Enter to inspect coding
2708
+ subagents, context, quota, source freshness and separately accounted worker
2709
+ usage. Configure the fields and default models live with `collab config`, or
2710
+ open the keyboard/mouse settings editor with `collab config --tui`.
2711
+
2712
+ ![Participant details in the real tmux viewer](assets/participant-panel.png)
2713
+
2714
+ [Panel controls](docs/watch-panel.md) · [Usage sources](docs/telemetry.md) ·
2715
+ [Live settings](docs/settings.md) · [Issue validation](docs/issue-validation.md)
2698
2716
 
2699
2717
  ![Keyboard and mouse settings editor](assets/settings-panel.png)
2700
2718
 
@@ -2703,6 +2721,11 @@ provider model defaults, worker budgets, participant fields and explicit model
2703
2721
  prices. Edits are staged and validated; external changes reload without silently
2704
2722
  overwriting a draft. [Editor guide](docs/settings-panel.md).
2705
2723
 
2724
+ Twelve bundled skills cover hosting, joining, discovery, watching, activity,
2725
+ learnings, settings, skill sharing, capacity, workers, telemetry and tasks.
2726
+ `collab skills status --json` publishes the local capability catalog; focused
2727
+ guides load the workflow an agent needs. Install them with `collab skills install`.
2728
+
2706
2729
  Agents can publish selected skills with `collab skills publish PATH`, discover
2707
2730
  metadata with `collab skills shared`, inspect with `collab skills show ID`, and
2708
2731
  withdraw their own entry. Shared text is never installed or executed automatically.
@@ -2713,3 +2736,19 @@ concurrency, active count, fresh quota and per-task budget are known.
2713
2736
  For full transcript consumers, `collab listen --delivery full --no-activity` or
2714
2737
  repeated `--kind` options select useful events. Compact notices remain the default.
2715
2738
  See [resource measurements](docs/performance.md) for CPU/RAM and leak-check limits.
2739
+
2740
+ ## License
2741
+
2742
+ MIT
2743
+
2744
+ In v2.0.2, collapsed participants use one padded coloured row with main and
2745
+ worker models and activity duration. Up/Down selects participants; Page Up/Down
2746
+ and the wheel scroll details. Stats remain available for a solo participant.
2747
+ See [panel controls and terminal support](docs/watch-panel.md). The Codex probe
2748
+ refreshes own-thread model/context/tokens alongside independently dated quota.
2749
+ Worker facts survive summary changes within a bounded retained-context history.
2750
+
2751
+ In the combined viewer, Tab or Shift+Tab switches panes; `1` focuses
2752
+ Participants and `2` focuses Conversation without moving either scroll position.
2753
+ The footer shows keys for the focused pane. Expanded participant details have
2754
+ left padding and pack short facts and their observation ages onto shared rows.
@@ -12,27 +12,25 @@
12
12
  <img alt="Python 3.10+" src="https://img.shields.io/badge/python-3.10%2B-blue.svg">
13
13
  <img alt="A2A Protocol 1.0" src="https://img.shields.io/badge/A2A%20protocol-1.0-0ea5e9.svg">
14
14
  <br>
15
- <a href="https://buymeacoffee.com/rperez93" target="_blank" rel="noopener noreferrer"><img alt="Buy Me A Coffee" src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-ffdd00?logo=buymeacoffee&logoColor=black"></a>
15
+ <a href="https://github.com/sponsors/rperez93" target="_blank" rel="noopener noreferrer"><img alt="Sponsor on GitHub" src="https://img.shields.io/badge/Sponsor-GitHub-BF3989?logo=githubsponsors&logoColor=white"></a>
16
16
  </p>
17
17
 
18
18
  **Let coding agents talk to each other.**
19
19
 
20
- **v2.0 requires stable Collab 2.x on both ends.** Upgrade guests and restart the
21
- host before reconnecting. Older or unversioned peers are refused before an
22
- invite is consumed. Existing external state remains usable; explicitly select
23
- legacy state you own. See [v2 migration and changes](docs/v2.md).
24
-
25
- The coding agent works while a scoped conversation worker keeps coordination
26
- moving. Expand participant details with a click or Enter to inspect coding
27
- subagents, context, quota, source freshness and separately accounted worker
28
- usage. Configure the fields and default models live with `collab config`, or
29
- open the keyboard/mouse settings editor with `collab config --tui`.
30
-
31
- ![Participant details in the real tmux viewer](assets/participant-panel.png)
20
+ Two people, two laptops, two coding agents. Today they align by a human copying
21
+ context out of one agent's terminal and pasting it into the other's. `collab`
22
+ replaces that with a small self-hosted hub: the agents message each other, claim
23
+ tasks off a shared board, and hand over build artifacts directly — in real time,
24
+ over Google's [A2A protocol](https://a2a-protocol.org).
32
25
 
33
- [Panel controls](docs/watch-panel.md) · [Usage sources](docs/telemetry.md) ·
34
- [Live settings](docs/settings.md) · [Issue validation](docs/issue-validation.md)
26
+ What they become is a **swarm**: several agents, on one machine or many, working
27
+ towards one goal somebody set — not a queue of workers taking tickets, and not a
28
+ debating society. The rules every session starts with say so in as many words:
29
+ the goal in the least time it can be done well, the work divided rather than the
30
+ attention, and a second agent there for a second judgement, not a second pair of
31
+ hands. The host keeps the board; every agent says what it is doing; compact notices preserve the working thread; periodic reminders are opt-in.
35
32
 
33
+ It also works for two agents on **one** machine in different repos.
36
34
 
37
35
  > **Easiest install: ask your coding agent to do it.** Paste this into Claude
38
36
  > Code, Cursor, Codex, or whatever you use:
@@ -47,21 +45,6 @@ open the keyboard/mouse settings editor with `collab config --tui`.
47
45
  > [Install](#install) — one command from PyPI, or a clone if you mean to work
48
46
  > on collab itself.
49
47
 
50
- Two people, two laptops, two coding agents. Today they align by a human copying
51
- context out of one agent's terminal and pasting it into the other's. `collab`
52
- replaces that with a small self-hosted hub: the agents message each other, claim
53
- tasks off a shared board, and hand over build artifacts directly — in real time,
54
- over Google's [A2A protocol](https://a2a-protocol.org).
55
-
56
- What they become is a **swarm**: several agents, on one machine or many, working
57
- towards one goal somebody set — not a queue of workers taking tickets, and not a
58
- debating society. The rules every session starts with say so in as many words:
59
- the goal in the least time it can be done well, the work divided rather than the
60
- attention, and a second agent there for a second judgement, not a second pair of
61
- hands. The host keeps the board; every agent says what it is doing; compact notices preserve the working thread; periodic reminders are opt-in.
62
-
63
- It also works for two agents on **one** machine in different repos.
64
-
65
48
  <p align="center">
66
49
  <img src="https://raw.githubusercontent.com/rperez93/collab-a2a/main/assets/demo.png" alt="collab demo: a coding agent's terminal on the left, mid-task, with a message from the session arriving, the reply going back out through collab send, and collab's status line at the foot; the collab watch viewer on the right showing the roster with each participant's model and context, the roster's foot with the batch bar, the message count and the reader's own activity, and the conversation" width="900">
67
50
  <br>
@@ -99,6 +82,7 @@ From that moment both agents receive each other's messages as they happen.
99
82
 
100
83
  ## Contents
101
84
 
85
+ - [What changed in v2](#v2-settings-and-shared-capabilities)
102
86
  - [How it works](#how-it-works) · [Install](#install) · [Quick start](#quick-start)
103
87
  - [Making an agent listen](#making-an-agent-listen) · [Saying what you are doing](#saying-what-you-are-doing) · [Commands](#commands)
104
88
  - [Watching the conversation](#watching-the-conversation) · [How it looks](#how-the-conversation-looks) · [Status line](#status-line) · [Files](#sharing-files-and-artifacts)
@@ -1295,7 +1279,8 @@ because someone who left a minute ago and someone who left yesterday are
1295
1279
  different situations — then a line of whatever they share: repo and branch,
1296
1280
  machine, model, every quota window, spend and context.
1297
1281
 
1298
- `tab` switches pane, `↑↓`/`pgup`/`pgdn` scroll the focused one, `End` (or `G`)
1282
+ `tab` switches pane; `↑↓` selects participants in the roster and scrolls chat.
1283
+ `j`/`k` and `pgup`/`pgdn` scroll details. `End` (or `G`)
1299
1284
  jumps back to the live end and `Home` (or `g`) to the start, `q` quits. The pane
1300
1285
  opens on the last few messages and slides its window as you scroll past either
1301
1286
  edge — `--limit N` opens on more. The conversation follows new messages until
@@ -1376,6 +1361,7 @@ fallback on a terminal that cannot do full-screen.
1376
1361
  **In tmux**, give it its own pane and keep working beside it:
1377
1362
 
1378
1363
  ```bash
1364
+ collab watch --panel # tmux or native macOS Ghostty/iTerm2
1379
1365
  collab watch --tmux # 35% to the right
1380
1366
  collab watch --tmux --vertical # split below
1381
1367
  collab watch --tmux --percent 50
@@ -2669,11 +2655,43 @@ Work that came from outside this repository, and the release it landed in:
2669
2655
  and the clock of a stamp read in one timezone, and `collab config timezone`
2670
2656
  to pin it. [#38](https://github.com/rperez93/collab-a2a/pull/38), in v1.28.0.
2671
2657
 
2672
- ## License
2658
+ ## v2 settings and shared capabilities
2673
2659
 
2674
- MIT
2660
+ Participant cards now use the full pane width, with compact summaries and separate
2661
+ main-agent/worker detail groups. Resize the combined view with `+` / `-` or drag
2662
+ its conversation divider. [Panel controls](docs/watch-panel.md).
2675
2663
 
2676
- ## v2 settings and shared capabilities
2664
+ Choose `collab theme cyberpunk` or `collab theme matrix`, or customize semantic
2665
+ colors, dividers, scrollbars, selection and card spacing in a theme file. The
2666
+ viewer and settings editor reload appearance while open.
2667
+ [Theme engine and examples](docs/theme-engine.md).
2668
+
2669
+ ![Cyberpunk appearance in a real terminal](assets/theme-cyberpunk.png)
2670
+
2671
+
2672
+ ![Separate coding-agent and worker measurements](assets/worker-telemetry.png)
2673
+
2674
+ **2.0.1 reliability update:** addressed `collab worker send` messages survive
2675
+ restarts and inference backoff. `collab worker stats` reports the worker's own
2676
+ quota, context and cost through native or custom adapters, separately from the
2677
+ coding agent. [Worker guide](docs/conversation-worker.md) · [Telemetry](docs/telemetry.md).
2678
+
2679
+
2680
+ **v2.0 requires stable Collab 2.x on both ends.** Upgrade guests and restart the
2681
+ host before reconnecting. Older or unversioned peers are refused before an
2682
+ invite is consumed. Existing external state remains usable; explicitly select
2683
+ legacy state you own. See [v2 migration and changes](docs/v2.md).
2684
+
2685
+ The coding agent works while a scoped conversation worker keeps coordination
2686
+ moving. Expand participant details with a click or Enter to inspect coding
2687
+ subagents, context, quota, source freshness and separately accounted worker
2688
+ usage. Configure the fields and default models live with `collab config`, or
2689
+ open the keyboard/mouse settings editor with `collab config --tui`.
2690
+
2691
+ ![Participant details in the real tmux viewer](assets/participant-panel.png)
2692
+
2693
+ [Panel controls](docs/watch-panel.md) · [Usage sources](docs/telemetry.md) ·
2694
+ [Live settings](docs/settings.md) · [Issue validation](docs/issue-validation.md)
2677
2695
 
2678
2696
  ![Keyboard and mouse settings editor](assets/settings-panel.png)
2679
2697
 
@@ -2682,6 +2700,11 @@ provider model defaults, worker budgets, participant fields and explicit model
2682
2700
  prices. Edits are staged and validated; external changes reload without silently
2683
2701
  overwriting a draft. [Editor guide](docs/settings-panel.md).
2684
2702
 
2703
+ Twelve bundled skills cover hosting, joining, discovery, watching, activity,
2704
+ learnings, settings, skill sharing, capacity, workers, telemetry and tasks.
2705
+ `collab skills status --json` publishes the local capability catalog; focused
2706
+ guides load the workflow an agent needs. Install them with `collab skills install`.
2707
+
2685
2708
  Agents can publish selected skills with `collab skills publish PATH`, discover
2686
2709
  metadata with `collab skills shared`, inspect with `collab skills show ID`, and
2687
2710
  withdraw their own entry. Shared text is never installed or executed automatically.
@@ -2692,3 +2715,19 @@ concurrency, active count, fresh quota and per-task budget are known.
2692
2715
  For full transcript consumers, `collab listen --delivery full --no-activity` or
2693
2716
  repeated `--kind` options select useful events. Compact notices remain the default.
2694
2717
  See [resource measurements](docs/performance.md) for CPU/RAM and leak-check limits.
2718
+
2719
+ ## License
2720
+
2721
+ MIT
2722
+
2723
+ In v2.0.2, collapsed participants use one padded coloured row with main and
2724
+ worker models and activity duration. Up/Down selects participants; Page Up/Down
2725
+ and the wheel scroll details. Stats remain available for a solo participant.
2726
+ See [panel controls and terminal support](docs/watch-panel.md). The Codex probe
2727
+ refreshes own-thread model/context/tokens alongside independently dated quota.
2728
+ Worker facts survive summary changes within a bounded retained-context history.
2729
+
2730
+ In the combined viewer, Tab or Shift+Tab switches panes; `1` focuses
2731
+ Participants and `2` focuses Conversation without moving either scroll position.
2732
+ The footer shows keys for the focused pane. Expanded participant details have
2733
+ left padding and pack short facts and their observation ages onto shared rows.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "collab-a2a"
7
- version = "2.0.0"
7
+ version = "2.0.2"
8
8
  description = "An A2A hub that lets coding agents on different machines talk, align on tasks, and discuss work in real time."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """collab — an A2A hub for coding agents."""
2
2
 
3
- __version__ = "2.0.0"
3
+ __version__ = "2.0.2"
@@ -13,7 +13,7 @@ def _number(value: Any) -> float | None:
13
13
  try:
14
14
  number = float(value)
15
15
  return number if math.isfinite(number) else None
16
- except (ValueError, TypeError):
16
+ except (ValueError, TypeError, OverflowError):
17
17
  return None
18
18
 
19
19
 
@@ -125,9 +125,16 @@ def estimate_capacity(stats: dict[str, Any], *, concurrency_limit: int | None =
125
125
  return result
126
126
  per_child = _number(cost.get(name)) if isinstance(cost, dict) else _number(cost)
127
127
  row['per_child_percent'] = per_child
128
- if per_child is None or active_children is None:
128
+ if per_child is None or active_children is None or concurrency_limit is None:
129
129
  continue
130
- count = max(0, math.floor((available + 1e-10) / per_child) - active_children)
130
+ # A valid tiny calibration (for example 1e-320 percentage points)
131
+ # makes floating-point division infinite. Compare against the finite
132
+ # native ceiling first; beyond it extra quota cannot add children.
133
+ # When division is needed, this comparison bounds its ratio to 10,000.
134
+ if available + 1e-10 >= per_child * concurrency_limit:
135
+ count = available_slots
136
+ else:
137
+ count = max(0, math.floor((available + 1e-10) / per_child) - active_children)
131
138
  row['maximum_additional_children'] = count
132
139
  capacities.append((count, name))
133
140
  if unavailable:
@@ -136,7 +143,8 @@ def estimate_capacity(stats: dict[str, Any], *, concurrency_limit: int | None =
136
143
  result['reasons'].append('native concurrency limit is unknown; supply it explicitly')
137
144
  if active_children is None:
138
145
  result['reasons'].append('current active native-child count is unknown')
139
- if len(capacities) != len(quota) and not unavailable:
146
+ if (len(capacities) != len(quota) and not unavailable
147
+ and concurrency_limit is not None and active_children is not None):
140
148
  result['reasons'].append('a calibrated child cost or explicit task budget is missing for a quota window')
141
149
  if result['reasons']:
142
150
  return result