feat: implement agent socket api, client and cli (#20758)

closes: https://github.com/coder/coder/issues/10352
closes: https://github.com/coder/internal/issues/1094
closes: https://github.com/coder/internal/issues/1095

In this pull request, we enable a new set of experimental cli commands
grouped under `coder exp sync`.
These commands allow any process acting within a coder workspace to
inform the coder agent of its requirements and execution progress. The
coder agent will then relay this information to other processes that
have subscribed.

These commands are:
```
# Check if this feature is enabled in your environment 
coder exp sync ping

# express that your unit depends on another
coder exp sync want <unit> <dependency_unit> 

# express that your unit intends to start a portion of the script that requires 
# other units to have completed first. This command blocks until all dependencies have been met
coder exp sync start <unit> 

# express that your unit has completes its work, allowing dependent units to begin their execution
coder exp sync complete <unit>
```

Example:

In order to automatically run claude code in a new workspace, it must
first have a git repository cloned. The scripts responsible for cloning
the repository and for running claude code would coordinate in the
following way:

```bash
# Script A: Claude code

# Inform the agent that the claude script wants the git script.
# That is, the git script must have completed before the claude script can begin its execution
coder exp sync want claude git

# Inform the agent that we would now like to begin execution of claude.
# This command will block until the git script (and any other defined dependencies)
# have completed
coder exp sync start claude

# Now we run claude code and any other commands we need
claude ...

# Once our script has completed, we inform the agent, so that any scripts that depend on this one
# may begin their execution

coder exp sync complete claude
```

```bash
# Script B: Git

# Because the git script does not have any dependencies, we can simply inform the agent that we 
# intend to start
coder exp sync start git

git clone ssh://git@github.com/coder/coder

# Once the repository have been cloned, we inform the agent that this script is complete, so that
# scripts that depend on it may begin their execution.
coder exp sync complete git
```

Notes:
* Unit names (ie. `claude` and `git`) given as input to the sync
commands are arbitrary strings. You do not have to conform to specific
identifiers. We recommend naming your scripts descriptively, but
succinctly.
* Scripts unit names should be well documented. Other scripts will need
to know the names you've chosen in order to depend on yours. Therefore,
you

---------

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
This commit is contained in:
Sas Swart
2025-11-28 08:33:50 +02:00
committed by GitHub
co-authored by Mathias Fredriksson
parent ee58f40cad
commit ce627bf23f
37 changed files with 1313 additions and 276 deletions
@@ -0,0 +1 @@
Success
@@ -0,0 +1 @@
Success
@@ -0,0 +1 @@
Success
@@ -0,0 +1,2 @@
Waiting for dependencies of unit 'test-unit' to be satisfied...
Success
@@ -0,0 +1,6 @@
Unit: test-unit
Status: completed
Ready: true
Dependencies:
No dependencies found
@@ -0,0 +1,13 @@
{
"unit_name": "test-unit",
"status": "pending",
"is_ready": true,
"dependencies": [
{
"depends_on": "dep-unit",
"required_status": "completed",
"current_status": "completed",
"is_satisfied": true
}
]
}
@@ -0,0 +1,7 @@
Unit: test-unit
Status: pending
Ready: false
Dependencies:
DEPENDS ON REQUIRED STATUS CURRENT STATUS SATISFIED
dep-unit completed not registered false
@@ -0,0 +1,6 @@
Unit: test-unit
Status: started
Ready: true
Dependencies:
No dependencies found
@@ -0,0 +1,8 @@
Unit: test-unit
Status: pending
Ready: false
Dependencies:
DEPENDS ON REQUIRED STATUS CURRENT STATUS SATISFIED
dep-1 completed completed true
dep-2 completed not registered false
@@ -0,0 +1 @@
Success
+6
View File
@@ -67,6 +67,12 @@ OPTIONS:
--script-data-dir string, $CODER_AGENT_SCRIPT_DATA_DIR (default: /tmp)
Specify the location for storing script data.
--socket-path string, $CODER_AGENT_SOCKET_PATH
Specify the path for the agent socket.
--socket-server-enabled bool, $CODER_AGENT_SOCKET_SERVER_ENABLED (default: false)
Enable the agent socket server.
--ssh-max-timeout duration, $CODER_AGENT_SSH_MAX_TIMEOUT (default: 72h)
Specify the max timeout for a SSH connection, it is advisable to set
it to a minimum of 60s, but no more than 72h.
+27
View File
@@ -0,0 +1,27 @@
coder v0.0.0-devel
USAGE:
coder exp sync [flags]
Manage unit dependencies for coordinated startup
Commands for orchestrating unit startup order in workspaces. Units are most
commonly coder scripts. Use these commands to declare dependencies between
units, coordinate their startup sequence, and ensure units start only after
their dependencies are ready. This helps prevent race conditions and startup
failures.
SUBCOMMANDS:
complete Mark a unit as complete
ping Test agent socket connectivity and health
start Wait until all unit dependencies are satisfied
status Show unit status and dependency state
want Declare that a unit depends on another unit completing before it
can start
OPTIONS:
--socket-path string, $CODER_AGENT_SOCKET_PATH
Specify the path for the agent socket.
———
Run `coder --help` for a list of global options.
+12
View File
@@ -0,0 +1,12 @@
coder v0.0.0-devel
USAGE:
coder exp sync complete <unit>
Mark a unit as complete
Mark a unit as complete. Indicating to other units that it has completed its
work. This allows units that depend on it to proceed with their startup.
———
Run `coder --help` for a list of global options.
+13
View File
@@ -0,0 +1,13 @@
coder v0.0.0-devel
USAGE:
coder exp sync ping
Test agent socket connectivity and health
Test connectivity to the local Coder agent socket to verify the agent is
running and responsive. Useful for troubleshooting startup issues or verifying
the agent is accessible before running other sync commands.
———
Run `coder --help` for a list of global options.
+17
View File
@@ -0,0 +1,17 @@
coder v0.0.0-devel
USAGE:
coder exp sync start [flags] <unit>
Wait until all unit dependencies are satisfied
Wait until all dependencies are satisfied, consider the unit to have started,
then allow it to proceed. This command polls until dependencies are ready,
then marks the unit as started.
OPTIONS:
--timeout duration (default: 5m)
Maximum time to wait for dependencies (e.g., 30s, 5m). 5m by default.
———
Run `coder --help` for a list of global options.
+20
View File
@@ -0,0 +1,20 @@
coder v0.0.0-devel
USAGE:
coder exp sync status [flags] <unit>
Show unit status and dependency state
Show the current status of a unit, whether it is ready to start, and lists its
dependencies. Shows which dependencies are satisfied and which are still
pending. Supports multiple output formats.
OPTIONS:
-c, --column [depends on|required status|current status|satisfied] (default: depends on,required status,current status,satisfied)
Columns to display in table output.
-o, --output table|json (default: table)
Output format.
———
Run `coder --help` for a list of global options.
+13
View File
@@ -0,0 +1,13 @@
coder v0.0.0-devel
USAGE:
coder exp sync want <unit> <depends-on>
Declare that a unit depends on another unit completing before it can start
Declare that a unit depends on another unit completing before it can start.
The unit specified first will not start until the second has signaled that it
has completed.
———
Run `coder --help` for a list of global options.