feat: add coder exp sync list command (#26443)

Add a new subcommand to list all registered sync units and their current
statuses. This provides a quick overview of the dependency coordination
state in a workspace without needing to query each unit individually.

The command supports both table (default) and JSON output formats.

```
$ coder exp sync list
UNIT    STATUS     READY
unit-a  started    true
unit-b  completed  true
unit-c  pending    false

$ coder exp sync list --output json
[
  {
    "unit_name": "my-unit",
    "status": "started",
    "is_ready": true
  }
]
```

When no units are registered, the command prints `No units registered`.

<details><summary>Changes across layers</summary>

- `agent/unit`: add `Manager.ListUnits()` method
- `agent/agentsocket/proto`: add `SyncList` RPC, bump API to v1.2
- `agent/agentsocket`: add service and client implementations
- `cli`: add `sync_list.go` command, register in `sync.go`
- Tests: three golden-file test cases (empty list, multiple units, JSON)

</details>

> Generated by Coder Agents on behalf of @SasSwart

---------

Co-authored-by: Cian Johnston <cian@coder.com>
This commit is contained in:
Sas Swart
2026-06-17 13:01:57 +02:00
committed by GitHub
co-authored by Cian Johnston
parent 74a7ad0929
commit 7d95153bf4
18 changed files with 553 additions and 39 deletions
+12
View File
@@ -284,6 +284,18 @@ func (m *Manager) GetUnmetDependencies(unit ID) ([]Dependency, error) {
return unmetDependencies, nil
}
// ListUnits returns a snapshot of all registered units and their current status.
func (m *Manager) ListUnits() []Unit {
m.mu.RLock()
defer m.mu.RUnlock()
units := make([]Unit, 0, len(m.units))
for _, u := range m.units {
units = append(units, u)
}
return units
}
// ExportDOT exports the dependency graph to DOT format for visualization.
func (m *Manager) ExportDOT(name string) (string, error) {
return m.graph.ToDOT(name)