Skip to content

feat(cockpit): multi-harness messaging, agents graph, per-agent files + Pi (part A of #243) - #245

Closed
Mystic0112 wants to merge 2 commits into
jacobaraujo7:mainfrom
Mystic0112:feat/multi-harness-agents-pr
Closed

Mystic0112 wants to merge 2 commits into
jacobaraujo7:mainfrom
Mystic0112:feat/multi-harness-agents-pr

Conversation

@Mystic0112

@Mystic0112 Mystic0112 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Part A of #243. As requested in review, the original PR was split. The MCP, desktop-app and Codex-via-MCP work moved to a separate PR (part B), which builds on this one.

What's in it

1. Multi-harness messaging

  • cockpit msg --to <label|tab-id> <text> types [from: <tab> · <harness>] <text> into the target tab, presses Enter after a short delay, and logs the message per workspace. Labels resolve like read-tab (ambiguous = error), and the sender signs with its label or tab id.
  • harness field in list-panes / list-tabs.
  • install-skill also targets Antigravity (~/.gemini/antigravity-cli/skills).
  • Turn status for tabs without hooks: output means working, ~3s of silence means idle. Echo and redraw are filtered, and short blips don't notify.
  • AgentHarness.fromWire no longer maps unknown names to claude.

2. Agents graph (topbar → Visualize agents)

  • Canvas tab with one node per agent. Observed cables come from the message log; defined links are made by dragging between ports, and both agents get an intro.
  • Maestro: one per workspace, auto-linked to every agent.
  • Per-agent colors.
  • Node context menu: Focus, Rename, Make/Remove maestro, Close.
  • New agent dialog: quick start per harness, label, command, cwd, monitor-activity toggle, role and initial task.
  • cockpit peers [--json]. Layout state is saved with the workspace.

3. Files panel: who is touching what

  • cockpit hook forwards edited file paths from PostToolUse. Tabs without hooks are inferred from git at the end of each turn and marked "(inferred)".
  • Agent filter in the Files header: colored dots, a warning when 2+ agents touched the same file, and a list per agent.

Pi as a first-class agent (review feedback)

  • Pi's turn status no longer relies on reading terminal output. PiHookInstallerImpl installs ~/.pi/agent/extensions/cockpit-hook.js; the installer only runs when ~/.pi exists, is idempotent, and never touches a user file with the same name. Pi loads the extension automatically.
  • Inside a Cockpit tab, the extension maps Pi events to cockpit hook --harness pi:
    • session_start → SessionStart
    • agent_start → UserPromptSubmit
    • agent_end → Stop
    • edit/write → PostToolUse with file paths, which feeds the Files panel
    • approval prompts → waiting
  • The first hook event turns off the output heuristic for that process, so a Pi started before the extension existed still gets a status.
  • Detection:
    • The classifier accepts node-wrapped launches.
    • --mode text without -p now counts as the TUI.
    • pi install|remove|update|list are treated as admin commands.
    • The extension renames non-TUI processes to pi-<mode>. Pi overwrites process.title, which hides --mode rpc from /proc, so this keeps rpc runs from being detected as agents.
  • Pi comes first in the New agent quick start. install-skill --agent pi was verified.
  • Tests: test/session/pi_agent_test.dart covers harness pi in list-tabs/peers, the graph node, the intro text, msg delivery (PTY write, delayed Enter, logged) and turn status via both heuristic and hook. test/data/pi_hook_installer_test.dart covers the installer. There are also classifier cases and a Rust test for the hook envelope.

Testing

  • flutter analyze reports no issues. cargo test: 42 + 39 passed.
  • Full suite: only the failures that also fail on a clean main (terminal_view_test textScaler ×2 and the window_menu_bar_test macOS case).
  • Live on Linux with Pi 1.3.0 (@earendil-works/pi-coding-agent): the tab was detected as [pi] and the extension was installed at startup.
    • A cockpit msg reached Pi; the turn went working → idle; Pi's write tool ran.
    • Pi replied with cockpit msg, signed [from: PiTest · Pi].
  • Not tested on macOS. Thanks for checking it there.

🤖 Generated with Claude Code

@tecrodrigocastro

Copy link
Copy Markdown
Contributor

Fala meo @Mystic0112 a primeira coisa a ser feita é quebrar essa PR em outra menores, um exemplo:

  • PR A: mensagens multi-harness (cockpit msg, campo harness), grafo de agentes + Maestro e atribuição por agente no painel de Files (partes 1+2+3).
  • PR B: cockpit mcp, apps desktop como agentes externos, edição de configs MCP de terceiros e Codex via MCP (partes 4+5).
    parte B também traz uma superfície nova que queremos revisar separadamente.

@tecrodrigocastro

Copy link
Copy Markdown
Contributor

O Pi é o alvo principal deste projeto. Garanta que ele funcione como nó no grafo e com o cockpit msg (detecção, ícone, instalação da skill e status de turno), e adicione um teste para isso. Hoje o PR e os testes giram em torno de Claude, Codex e Antigravity.

@tecrodrigocastro

Copy link
Copy Markdown
Contributor
  • O from é aceito como veio, então qualquer agente pode se passar por outro. Adicione o token por sessão citado na nota ponytail: ou documente a limitação com clareza.
  • O fallback para ~/.cockpit/status.sock amplia quem consegue falar com o app. Confirme as permissões do socket (0600, só o dono) e que outros usuários locais não alcançam esse fallback.
  • Edição de configs MCP de outros apps: o fluxo de consentimento + backup + chmod 600 está bom. Adicione também um caminho de "remover/desfazer".

@tecrodrigocastro tecrodrigocastro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verificar os comentarios

@tecrodrigocastro

Copy link
Copy Markdown
Contributor

Pelo que entendi os testes dessa PR foi feito no linux, irei realizar os testes no MacOs e retorno. Ja que a plataforma mais utilizada no cockpit

@Mystic0112

Mystic0112 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor Author

Show, irei particionar o pr e verificar o resto

Mystic0112 and others added 2 commits October 16, 2026 21:04
… files (jacobaraujo7#243)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Mystic0112
Mystic0112 force-pushed the feat/multi-harness-agents-pr branch from 95f9587 to bf3cc9f Compare October 17, 2026 13:13
@Mystic0112 Mystic0112 changed the title feat(cockpit): multi-harness agent graph + desktop agents via MCP feat(cockpit): multi-harness messaging, agents graph, per-agent files + Pi (part A of #243) Oct 17, 2026
@Mystic0112

Copy link
Copy Markdown
Contributor Author

@tecrodrigocastro valeu pela revisão! Respondendo ponto a ponto:

1. Divisão do PR. Feito.

2. Pi como alvo principal.

  • Status de turno: deixou de vir da leitura da saída do terminal. O Cockpit instala uma extensão em ~/.pi/agent/extensions/cockpit-hook.js, só quando ~/.pi existe, idempotente, e sem tocar em arquivo do usuário com o mesmo nome. Ela traduz os eventos do Pi para o cockpit hook --harness pi:
    • session_start, agent_start e agent_end viram início e fim de turno;
    • edit/write mandam o caminho dos arquivos para o painel Files;
    • prompts de aprovação viram "aguardando".
  • Detecção:
    • aceita o Pi lançado via node;
    • pi install/remove/update/list contam como comandos administrativos;
    • o --mode rpc não é confundido com o TUI.
  • Interface: ícone do Pi, Pi primeiro no "New agent", skill em ~/.pi/agent/skills.
  • Testes: test/session/pi_agent_test.dart cobre detecção, nó no grafo, entrega do cockpit msg e status por hook e por heurística. test/data/pi_hook_installer_test.dart cobre o instalador.
  • Teste ao vivo no Linux com o Pi 1.3.0: a aba foi detectada como [pi], recebeu uma mensagem, passou de trabalhando para parado, usou o write e respondeu com cockpit msg.

3. from sem validação (no #253). Implementei o token por sessão. Cada aba do Codex recebe um from_token aleatório de 128 bits na mensagem de conexão. Ele muda a cada nova conexão e é descartado quando a aba fecha. Sem o token certo, o from é recusado, com comparação em tempo constante. O risco que sobra está documentado: um processo local que consiga ler o terminal daquela aba pode descobrir o token.

4. Fallback do socket (no #253). Antes, o socket seguia a umask do processo. Aqui, com umask 0002, a pasta ficava 0775 e o socket srwxrwxr-x: o grupo conseguia conectar, outros usuários não. Agora a pasta ~/.cockpit vira 0700 antes do bind e o socket 0600 antes do listen, nos dois flavors, com teste. O fallback ~/.cockpit/status.sock é o mesmo socket para o qual o COCKPIT_STATUS_SOCK já aponta.

5. Remover/desfazer (no #253). Dá para remover só a entrada cockpit, sempre com backup antes e sem restaurar backup antigo por cima de edições mais novas. Fica em dois lugares:

  • ao remover um nó desktop do canvas;
  • em Settings → Automations → "Desktop app integrations (MCP)".

No Codex, remover desliga uma configuração para o instalador não recolocar a entrada no boot, já que o Codex do terminal usa a mesma entrada.

Fico no aguardo dos testes no macOS. Tudo aqui foi testado no Linux.

@jacobaraujo7

Copy link
Copy Markdown
Owner

Thanks @Mystic0112 for the effort here, and for splitting it. After looking at both parts, here's the scope decision:

Cockpit already has the inter-agent primitive (cockpit send --tab-id --enter + read-tab, plus the hook-based turn status), and we drive orchestration on top of it by convention and scripts. We don't want a second messaging layer (cockpit msg), the agents graph / Maestro, or the MCP hub for desktop apps: that moves Cockpit away from the 2.0 decision (an agent is a process in a terminal) and duplicates the Remote Pi mesh inside the app.

What we do want, as small separate PRs:

  1. Pi hook (cockpit-hook.js installer + turn status + edited paths). Pi is the primary target of this project, so this is the most valuable piece.
  2. harness field in list-tabs --json.
  3. Optionally, per-agent file attribution in the Files panel. This is the one piece of new UI that shows something we're blind to today.

So I'm closing this PR and #253. If you open the smaller PRs above, we'll review them promptly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants