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.
- {collab_a2a-2.0.0/src/collab_a2a.egg-info → collab_a2a-2.0.2}/PKG-INFO +74 -35
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/README.md +73 -34
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/pyproject.toml +1 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/__init__.py +1 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/capacity.py +12 -4
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/cli.py +133 -13
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/daemon.py +11 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/inbox.py +15 -3
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/participant_metrics.py +11 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/recovery.py +4 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/settings_tui.py +12 -3
- collab_a2a-2.0.2/src/collab/client/terminal_panel.py +65 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/tui.py +426 -58
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/worker_service.py +40 -9
- collab_a2a-2.0.2/src/collab/codex_usage.py +92 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/quotas.py +8 -4
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/rules/COLLAB.md +5 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-activity/SKILL.md +1 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-capacity/SKILL.md +5 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-configure/SKILL.md +33 -5
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-discover/SKILL.md +1 -1
- collab_a2a-2.0.2/src/collab/skills/collab-host/SKILL.md +77 -0
- collab_a2a-2.0.2/src/collab/skills/collab-host/references/connection-and-recovery.md +342 -0
- collab_a2a-2.0.2/src/collab/skills/collab-join/SKILL.md +79 -0
- collab_a2a-2.0.2/src/collab/skills/collab-join/references/connection-and-recovery.md +387 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-learn/SKILL.md +1 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-share-skills/SKILL.md +7 -0
- collab_a2a-2.0.2/src/collab/skills/collab-tasks/SKILL.md +67 -0
- collab_a2a-2.0.2/src/collab/skills/collab-telemetry/SKILL.md +85 -0
- collab_a2a-2.0.2/src/collab/skills/collab-telemetry/references/providers.md +34 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills/collab-watch/SKILL.md +48 -2
- collab_a2a-2.0.2/src/collab/skills/collab-worker/SKILL.md +82 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skills.py +66 -57
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/telemetry.py +61 -3
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/themes.py +109 -19
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/worker.py +109 -8
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/worker_runtime.py +43 -10
- collab_a2a-2.0.2/src/collab/worker_telemetry.py +172 -0
- collab_a2a-2.0.2/src/collab/worker_usage.py +79 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2/src/collab_a2a.egg-info}/PKG-INFO +74 -35
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/SOURCES.txt +23 -1
- collab_a2a-2.0.2/tests/test_cli_v202.py +28 -0
- collab_a2a-2.0.2/tests/test_codex_own_usage.py +69 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_demo_session.py +5 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_docs_match_cli.py +1 -1
- {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
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_issue_recovery.py +15 -0
- collab_a2a-2.0.2/tests/test_panel_v202.py +110 -0
- collab_a2a-2.0.2/tests/test_participant_cards_v201.py +80 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_participant_details.py +4 -3
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_participant_panel_in_tmux.py +62 -10
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_colour.py +1 -1
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_rule.py +18 -8
- collab_a2a-2.0.2/tests/test_semantic_theme_engine.py +102 -0
- collab_a2a-2.0.2/tests/test_skill_capabilities_v201.py +71 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_status_bar.py +2 -2
- collab_a2a-2.0.2/tests/test_terminal_panel.py +49 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_theme_is_visual_only.py +4 -0
- collab_a2a-2.0.2/tests/test_theme_panel_in_tmux.py +126 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_scroll.py +1 -1
- collab_a2a-2.0.2/tests/test_v201_communication_challenger.py +277 -0
- collab_a2a-2.0.2/tests/test_v201_final_review.py +35 -0
- collab_a2a-2.0.2/tests/test_v201_remaining_surfaces_challenger.py +131 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_runtime.py +7 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_service.py +20 -0
- collab_a2a-2.0.2/tests/test_worker_source_v201.py +149 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_state.py +23 -0
- collab_a2a-2.0.2/tests/test_worker_telemetry_v201.py +196 -0
- collab_a2a-2.0.0/src/collab/skills/collab-host/SKILL.md +0 -916
- collab_a2a-2.0.0/src/collab/skills/collab-join/SKILL.md +0 -946
- collab_a2a-2.0.0/src/collab/worker_usage.py +0 -39
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/LICENSE +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/setup.cfg +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/activity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/atomic.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/attention.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/batch.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/__init__.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/bridge.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/context.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/daemon_files.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/demo_agent.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/exclusive.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/hub_client.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/onboard.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/statusbar.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/client/watch.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/columns.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/compaction.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/compatibility.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/config.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/daemon_main.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/demo.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/diagnostics.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/hosttool.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/hub_main.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/identity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/learnings.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/lockfile.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/owner.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/peers.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/protocol.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/reboot.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/rules.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/runtime_settings.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/__init__.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/app.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/auth.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/card.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/events.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/executor.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/hub.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/session.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/store.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/server/tunnel.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/skill_sharing.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/source_command.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/stats.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/__init__.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/entry.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/install.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/render.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/statusline/watchdog.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/update.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/wake.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab/worker_notices.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/dependency_links.txt +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/entry_points.txt +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/requires.txt +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/src/collab_a2a.egg-info/top_level.txt +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_count_that_is_not_a_count.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_daemon_follows_the_agent_that_started_it.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_figure_can_be_taken_back.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_figure_of_one_is_one_percent.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_fresh_session_for_everyone.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_hole_in_the_log_is_reported.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_message_is_refused_not_cut.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_pid_from_another_boot_names_nobody.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_project_is_a_bundle_that_belongs_to_somebody.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_quota_read_from_the_agent_itself.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_refused_kind_is_named_briefly.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_state_constant_is_read_by_its_data_model.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_a_window_from_a_bucket_is_still_a_window.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_activity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_activity_cli.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_activity_hub.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_agent_commands.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_agent_identity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_an_update_refreshes_what_it_installed.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_asking_is_not_holding.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_attention_contention.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_attention_delivery.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_bare_join.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_batch_progress.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_bind_forms_and_header.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_chat_is_the_only_kind_a_client_sends.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_check.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_clear_quota.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_cli_imports_no_httpx.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_maths.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_propagates.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_push.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_colour_tables_forget_the_departed.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_columns_clip.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_config_command.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_context_compaction.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_daemon_identity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_demo_agent_panel.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_demo_header_row_is_clipped.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_diagnostics.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_agent_is_told_how_to_listen.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_item_of_a_bar_is_a_choice.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_kind_reaches_every_renderer.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_every_stamp_reads_in_the_readers_zone.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_external_agent_state.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_external_state_live_session.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_file_outcome_takes_junk.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_files.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_fold_override.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_global_figures.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_global_home.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_guest_follows_the_hub.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_home_flag.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_home_isolation.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_home_permissions.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_host_name_clash.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_how_it_was_installed.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_hub.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_hub_version_travels.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_inbox_under_contention.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_inbox_write_order.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_info_blue.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_input_bounds.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_joining_a_dead_session.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_joining_by_name.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_jump_from_the_status_row.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_kill.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_layout.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_learnings.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_learnings_cost.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_learnings_sync.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_leaving_takes_the_wake_with_it.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_listen_kind_filters.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_live_settings.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_liveness_from_a_sandbox.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_local_join_stays_local.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_lock_flow.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_lock_identity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_lockfile.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_logs_can_be_read_without_stopping_anything.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_loose_ends.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_markdown_themes.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_migration.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_monitor_armed.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_mutation_gaps.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_name_migration.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_name_reuse.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_no_autohost.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_numbers_that_stop_moving_say_why.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_okf_bundle.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_older_above_agrees_with_what_loads.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_orphans.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_overview.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_own_colour.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_owner_stamp.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_peers.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_peers_lifecycle.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_periodic_reminder.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_persisted_v2_boundary.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_platform_support.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rate_limiter_forgets.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_reminder_edges.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_reminder_on_the_monitor.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rename.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_render.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_resume.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_room_files_wait_for_everyone.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_dots.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_row_keeps_the_count.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_roster_when_the_session_dies.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rotating_the_invite.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rotation_is_atomic.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_rules.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_same_name_is_not_ownership.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_settings_panel_in_tmux.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_settings_reach_the_open_session.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_settings_tui.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_shared_skills_and_capacity.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_skill_formats.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_skill_settings_match_the_registry.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_skills.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_source_command_bounds.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stale_status.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_state_dir_cleanup.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_state_dirs.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_state_is_not_conversation.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_formats.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_ownership.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_say_when.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_source.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stats_stamp_edges.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_statuses_stay_current.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_statusline_imports_no_networking.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_statusline_install.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stopped_msg.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_stream.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tasks_want_a_batch.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_telemetry_v2.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_telling_agents_apart.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_terminal_escapes.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_a2a_client_surface_is_not_dead_code.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_count_is_a_switch.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_count_is_never_shown_outdated.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_daemon_forgets_what_it_no_longer_needs.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_pane_and_the_transcript_agree_about_a_file.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_record_is_kept_without_being_asked.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_reminder_can_be_added_to.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_reminder_reaches_every_agent.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_roster_foot_is_a_grid.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_status_line_cannot_run_forever.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_status_line_does_not_vanish.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_suite_never_reads_your_config.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_two_row_switches_are_independent.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_the_wake_explains_its_clocks.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_theme_files_survive.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_transcript_dates_follow_the_clock.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_cost.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_fold_click.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_gutter.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tui_window.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_tunnel.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_two_agents_one_repo.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_unread_is_what_the_agent_has_not_seen.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_update.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_v2_compatibility.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_viewer_says_what_the_ack_did.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_wake.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_watch_pane_survives.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_what_may_be_signalled.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_which_agent.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_who_is_who.py +0 -0
- {collab_a2a-2.0.0 → collab_a2a-2.0.2}/tests/test_worker_delivery.py +0 -0
- {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.
|
|
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://
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-

|
|
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
|
-
|
|
55
|
-
|
|
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
|
|
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
|
-
##
|
|
2679
|
+
## v2 settings and shared capabilities
|
|
2694
2680
|
|
|
2695
|
-
|
|
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
|
-
|
|
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
|
+

|
|
2691
|
+
|
|
2692
|
+
|
|
2693
|
+

|
|
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
|
+

|
|
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
|

|
|
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://
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-

|
|
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
|
-
|
|
34
|
-
|
|
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
|
|
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
|
-
##
|
|
2658
|
+
## v2 settings and shared capabilities
|
|
2673
2659
|
|
|
2674
|
-
|
|
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
|
-
|
|
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
|
+

|
|
2670
|
+
|
|
2671
|
+
|
|
2672
|
+

|
|
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
|
+

|
|
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
|

|
|
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.
|
|
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"
|
|
@@ -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
|
-
|
|
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
|