Skip to content

Deep Squad Integration: SquadSessionProvider via ISessionProvider Plugin System #436

@PureWeen

Description

@PureWeen

Overview

This issue captures a deep analysis of how PolyPilot should integrate with Brady Gaster's Squad — the AI team runtime for GitHub Copilot. The research included a thorough study of Squad's architecture, running squad init hands-on in the PP worktree (Squad CLI v0.9.1), and reviewing PP's existing ISessionProvider plugin architecture.

TL;DR: PP already has the right plugin infrastructure. A SquadSessionProvider implementing ISessionProvider is the natural, philosophy-correct integration point — Squad does its thing, PP is a beautiful native UI over it.


What Squad Actually Is

Squad is not just a config format — it's a full AI team runtime:

  • Coordinator agent (.github/agents/squad.agent.md) — runs in VS Code Copilot Chat, orchestrates workers
  • 29 skills installed into .copilot/skills/ — instruction files teaching agents conventions, model selection, git workflow, etc.
  • RemoteBridge WebSocket server — Squad's own protocol for external UIs to observe and control sessions
  • Ralph — autonomous GitHub Issues triage agent
  • Cross-squad meshmanifest.json + upstream.json for squad-to-squad discovery and delegation
  • Casting system — thematic character names (Futurama, etc.) persisted across sessions
  • Context hygiene (squad nap) — compress/prune agent history

Current PP Integration — What's Wrong

PP today treats Squad as a config format only: it reads team.md + agents/{name}/charter.md → builds a GroupPreset → creates PP's own multi-agent system. This discards ~80% of Squad: the coordinator persona, agent history, casting, event bus, Ralph, skill handlers, marketplace, upstream registry.

The Surprise: PP Already Works With Squad (Partially)

After running squad init --no-workflows, we found:

  • DiscoverAvailableSkills() already scans .copilot/skills/ — all 29 Squad skills are immediately active in PP sessions pointing at the repo. Nothing to add.
  • DiscoverAvailableAgents() already scans .github/agents/ — the Squad coordinator shows up as a discoverable agent.
  • Squad's session-recovery skill queries the Copilot CLI's session_store SQLite DB (~/.copilot/session-store.db) via the sql tool. This is a Copilot CLI feature (not PP-specific) — but since PP sessions run on the same CLI, Squad agents naturally have access to PP's full session history. Squad and PP are siblings sharing the same Copilot CLI infrastructure.

The plumbing is there. What's missing is surfacing, setup assistance, and deeper RemoteBridge integration.


Primary Recommendation: SquadSessionProvider via ISessionProvider

PP already has ISessionProvider / ISessionProviderFactory / PluginLoader — a full plugin system with SHA-256 hash verification, user approval, and isolated AssemblyLoadContext. CopilotService.Providers.cs already wires providers into the session model with full streaming event support.

A SquadSessionProvider implementing ISessionProvider maps almost perfectly to Squad's RemoteBridge:

ISessionProvider Squad RemoteBridge
InitializeAsync() Connect WS, acquire one-time ticket, authenticate
GetMembers() RCAgentsEvent — one ProviderMember per Squad agent
SendMessageAsync() Send prompt RC command to coordinator
OnContentReceived RCDeltaEvent streaming chunks
OnTurnStart / OnTurnEnd RCCompleteEvent
OnToolStarted/Completed RCToolCallEvent (running/completed/error)
GetActions() squad nap, squad status, squad doctor, ceremony triggers
ShutdownAsync() Close WS connection

What this gets for free from CopilotService.Providers.cs:

  • Full streaming event wiring (IsProcessing, ProcessingPhase, ToolCallCount, history flushing)
  • Member session management (OnMemberContentReceived, OnMemberTurnStart/End)
  • Group creation and session group management
  • Thread-safe InvokeOnUI marshaling for all events

Four Design Challenges

1. Permission Flow Gap

ISessionProvider has no permission approval concept, but Squad's RCPermissionEvent (agent requests tool approval) needs UI support. Proposed fix: Add IPermissionAwareProvider as an optional extension interface:

public interface IPermissionAwareProvider : ISessionProvider
{
    event Action<ProviderPermissionRequest>? OnPermissionRequested;
    Task ApprovePermissionAsync(string permissionId);
    Task DenyPermissionAsync(string permissionId);
}

PP checks provider is IPermissionAwareProvider and shows a dedicated permission modal. Backward-compatible.

2. Coordinator Topology

Squad's coordinator routes work to workers but doesn't generate content directly — it doesn't cleanly map to LeaderSession. Options: (a) make the leader transparent/invisible, showing coordinator routing in a "Squad Console" view, or (b) use the leader session as a command console showing orchestration-log entries.

3. .copilot/skills/ Namespace

squad init installs 29 generic skills into .copilot/skills/, the same directory PP scans. First-seen deduplication in ScanSkillDirectory means project-specific skills should be added after squad init to take precedence by name. User guidance needed in PP's UI.

4. Coordinator Agent is VS Code-Specific

squad.agent.md uses task tool, ask_user, and @squad mentions — VS Code Copilot Chat patterns not available in the Copilot CLI. The coordinator is not usable verbatim in PP. Worker charters and skills ARE compatible. PP's multi-agent orchestrator replaces the VS Code coordinator role.


Immediate Near-Term Wins (No Breaking Changes)

  1. Fix project-level MCP config: LoadMcpServers() reads ~/.copilot/mcp-config.json (global) but misses Squad's project-local .copilot/mcp-config.json. Merging this gives Squad's MCP tools to PP sessions automatically.
  2. Stop flattening Squad: When PP discovers .squad/, surface manifest.json, upstream.json, identity/now.md, and decisions.md in the group UI — don't pretend PP IS Squad.
  3. "Squad initialized" badge: Surface when a repo has Squad set up (detect .squad/team.md + .copilot/skills/ count).
  4. "Set up Squad" button: Run squad init --no-workflows on behalf of the user from the repo panel.
  5. Skills source labels: In the skills discovery UI, tag which skills are Squad-provided vs project-specific.

Phased Roadmap

Phase 1 — Respect Squad's Runtime (low risk)

  • Stop treating .squad/ as a config-only format — read manifest.json, upstream.json, identity/now.md, decisions.md and surface them in the group UI
  • Project-level .copilot/mcp-config.json merge into LoadMcpServers()
  • Squad-initialized detection + badge in repo panel
  • Skills source labeling (Squad-owned vs project-owned)
  • "Set up Squad" button wrapping squad init

Phase 2 — Marketplace & Skills UI (high value)

  • Squad marketplace browser (plugin sources, browse, install via squad plugin marketplace add)
  • Jon Dick's skill handler configurator (pick backend for tasks/decisions/memories)
  • Upstream squad registry UI (upstream.json visualization)
  • Machine capabilities viewer

Phase 3 — RemoteBridge via ISessionProvider (transformative)

  • SquadSessionProvider plugin that connects to Squad's RemoteBridge WS (squad start --port 4242)
  • IPermissionAwareProvider extension interface in PolyPilot.Provider.Abstractions
  • Permission approval modal in Dashboard — native card UI when an agent requests tool approval
  • Mobile permission approval: Squad runs squad start --tunnel, PP scans the QR code (PP already has DevTunnelService + QrScannerPage), and permission requests pop as actionable cards on your phone. This is the wow moment.
  • Squad runs Squad. PP is the beautiful native companion UI over it.

Risks & Open Questions

Protocol Stability

Squad is at 0.9.1 (pre-1.0). The RemoteBridge RC_PROTOCOL_VERSION = '1.0' is just the wire format version, not a stability guarantee. Breaking changes to RCDeltaEvent, RCPermissionEvent, or RCAgentsEvent shapes before Squad 1.0 would break the PP plugin. Mitigation: Keep the Squad provider as a separate plugin DLL (not compiled into PP core) so it can version independently. Add a protocol version check on connect.

Lifecycle: Who Starts Squad?

The SquadSessionProvider connects to a running RemoteBridge — someone must start squad start or squad rc first. PP should NOT try to manage Squad's lifecycle initially (that doubles the bug surface area for process management). Start with "user runs Squad separately, PP connects" and explore PP-managed lifecycle later.

squad.config.ts and SquadWriter Safety

Squad has a programmatic squad.config.ts builder API. Running squad build regenerates .squad/*.md from this config, potentially overwriting changes PP's SquadWriter.cs makes. PP should check for squad.config.ts before writing to .squad/ and warn the user that their edits may be lost on next squad build.

ACP Passthrough (Alternative Path)

Squad's rc.ts has setPassthrough() / passthroughFromAgent() APIs that relay raw ACP JSON-RPC between WebSocket clients and copilot --acp. This means Squad's bridge can act as a transparent Copilot relay. PP could potentially connect via its existing ACP protocol instead of the RC protocol — simpler but loses Squad-specific events (agent roster, permissions, casting). Worth exploring as a complementary path.


References

  • Squad repo: https://github.com/bradygaster/squad
  • Squad CLI install: npm install -g @bradygaster/squad-cli
  • Research session: full analysis in PP session plan (Copilot session 5d6bd68c)
  • Squad RemoteBridge protocol: packages/squad-sdk/src/remote/protocol.ts
  • Squad's skill system: packages/squad-sdk/src/skills/ (includes Jon Dick's SkillScriptLoader)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions