cofluxd 0.15.0 → 1.0.0

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: coflux
3
- description: When you run inside a coflux terminal, this skill documents the local cofluxd commands that open terminals the user can watch and take over from the coflux web/mobile app, report progress, call the user and hand out preview URLs, plus the center MCP for reaching other workspaces and devices. Your coordinates (device / project / workspace / terminal) arrive in a <coflux-session> block at session start, or via the COFLUX_* environment variables. For the workspace your cwd is in always use the zero-credential local cofluxd commands (open, read, wait, send, report progress, call the user, get preview URLs); use the center's coflux MCP only to reach beyond it (child workspaces, other workspaces or devices). Use when the user should be able to watch, step into or stop a command (interactive steps, dev servers, a job they are waiting on), when the user has to decide something, when you want to hand the user a clickable preview URL, or when you need an isolated child workspace for parallel work.
3
+ description: Use coflux to open visible terminals, read, wait, type, report progress, notify the user and obtain preview URLs. Prefer zero-credential local commands in the current workspace; use the account CLI across workspaces and devices. Coordinates arrive through coflux-session or COFLUX_* variables.
4
4
  ---
5
5
 
6
6
  # Working inside coflux
@@ -10,13 +10,12 @@ machines from a browser or a phone and take over at any time. This skill gives y
10
10
  user can see and take over, a progress line and a call button on the workspace card, preview URLs,
11
11
  and a way to operate the other workspaces and devices under the account when you need to.
12
12
 
13
- Two tracks, one rule: **whatever closes locally uses local commands; only reaching beyond the
14
- workspace you are in goes through MCP.**
13
+ **Use local commands in this workspace and account CLI commands across workspaces and devices.**
15
14
 
16
15
  | Track | Credentials | Reach | Use for |
17
16
  |---|---|---|---|
18
- | Local commands `cofluxd terminal/progress/notify/ports` | none (the daemon identifies you by process tree) | **the workspace your cwd is in** | open, read, wait, send, report progress, call the user, preview URLs: the default, fastest, no network dependency |
19
- | Center MCP `coflux` | one OAuth authorization by the user in the host | **the whole account**: every device, project, workspace and terminal | child workspaces (git worktrees), cross-workspace / cross-device access, joining from outside coflux |
17
+ | Local commands `coflux terminal/progress/notify/ports` | none (the daemon identifies you by process tree) | **the workspace your cwd is in** | open, read, wait, send, report progress, call the user, preview URLs: the default, fastest, no network dependency |
18
+ | Account CLI | app login or `coflux login` | all devices and workspaces in the account | child workspaces and remote terminals; JSON output |
20
19
 
21
20
  Of the local commands, `send`/`read`/`wait`/`notify`/`progress` complete entirely inside the
22
21
  local daemon and never touch the center; `new`/`list`/`ports` are relayed to the center by the
@@ -36,22 +35,19 @@ env | grep '^COFLUX_'
36
35
 
37
36
  - **`COFLUX_WORKSPACE_ID` is non-empty** (or the `<coflux-session>` block is present) → you are in
38
37
  a coflux terminal with an up-to-date daemon. The variables below are your coordinates; pass
39
- these ids to MCP tools directly instead of guessing from `list_*`:
38
+ these ids to account CLI commands directly instead of guessing from `list_*`:
40
39
 
41
40
  | Variable | Meaning |
42
41
  |---|---|
43
42
  | `COFLUX_DEVICE_ID` | id of the device you run on (the id in `list_devices`) |
44
43
  | `COFLUX_PROJECT_ID` | owning project id; empty string for a directory workspace without a repository |
45
- | `COFLUX_WORKSPACE_ID` | the workspace this terminal was **opened** in (the id in `list_workspaces`). The variable is frozen when the terminal starts; the workspace the terminal *belongs to* can still change — see below. `cofluxd workspace` is the authority |
44
+ | `COFLUX_WORKSPACE_ID` | the workspace this terminal was **opened** in (the id in `list_workspaces`). The variable is frozen when the terminal starts; the workspace the terminal *belongs to* can still change — see below. `coflux workspace` is the authority |
46
45
  | `COFLUX_TASK_ID` | id of this terminal (the taskId / terminalId used by local commands and `read_terminal`) |
47
46
  | `COFLUX_SESSION_ID` | id of this PTY session |
48
- | `COFLUX_MCP_URL` | the center's MCP URL; the user configures MCP with it |
49
47
 
50
- - **Variables empty or absent** → treat yourself as outside coflux: forget this skill and use your
51
- own tools as usual (if the user configured the coflux MCP in the host, the MCP tools still work;
52
- you just have no "where am I" coordinates). If the user insists you are inside a coflux terminal,
53
- this machine's daemon has not been upgraded: tell the user to run `cofluxd update && cofluxd restart`;
54
- after reopening the terminal the variables and the local commands are there.
48
+ - **Variables empty or absent**: there is no local terminal context. Use `coflux whoami` to check
49
+ account access and the account CLI to discover workspaces. Ask the user to log in when needed;
50
+ never fabricate COFLUX_* coordinates.
55
51
 
56
52
  ### Two workspaces to keep apart: owning and effective
57
53
 
@@ -66,11 +62,11 @@ conversation, no restart — and a coflux child workspace is a normal registered
66
62
  session whose terminal belongs to workspace A can end up working inside workspace B. From that
67
63
  moment, in B:
68
64
 
69
- - `cofluxd terminal new` opens the terminal **in B**, under B in the user's sidebar, running in B's
65
+ - `coflux terminal new` opens the terminal **in B**, under B in the user's sidebar, running in B's
70
66
  directory, counting against B's terminal cap;
71
- - `cofluxd terminal list` lists B's terminals, and A's terminals answer `read` / `wait` / `send`
67
+ - `coflux terminal list` lists B's terminals, and A's terminals answer `read` / `wait` / `send`
72
68
  with "not in this workspace or does not exist" (`cd` back to A to reach them again);
73
- - MCP calls need **B's** id as `workspaceId`;
69
+ - Account CLI calls need **B's** id as `workspaceId`;
74
70
  - the terminal itself stays under A, and `progress`, `notify` and `ports` still belong to it,
75
71
  whatever your cwd is; `COFLUX_TASK_ID` and `COFLUX_SESSION_ID` never change.
76
72
 
@@ -93,8 +89,8 @@ lives. When Claude Code cleans up its own worktree on exit, that workspace's ter
93
89
  the project's main workspace and the record disappears by itself.
94
90
 
95
91
  So, after entering or leaving a worktree, owning **and** effective are both the new workspace: pass
96
- its id to MCP tools and everything local already acts on it. The plugin drops the new id next to the
97
- tool result, and `cofluxd workspace` always tells you. Two things stay behind on purpose:
92
+ its id to account CLI commands and everything local already acts on it. The plugin drops the new id next to the
93
+ tool result, and `coflux workspace` always tells you. Two things stay behind on purpose:
98
94
 
99
95
  - `COFLUX_WORKSPACE_ID` (and the id in the `<coflux-session>` block from earlier in this session)
100
96
  still names where the terminal was *opened*; it is frozen when the PTY starts and cannot be
@@ -109,15 +105,15 @@ a daemon that is down or too old — the session just carries on with the owners
109
105
  ### Ask where you are
110
106
 
111
107
  ```sh
112
- cofluxd workspace
108
+ coflux workspace
113
109
  {"workspaceId":"ws-b","path":"/Users/me/.coflux/worktrees/ws-b","owningWorkspaceId":"ws-a","moved":true}
114
110
  ```
115
111
 
116
112
  One line of JSON: `workspaceId` (+ `path`) is the **effective** workspace, `owningWorkspaceId` is the
117
113
  workspace this terminal belongs to right now, and `moved` says whether they differ. With the plugin
118
114
  installed you also get a `<coflux-session-moved>` block at the start of every prompt while the two
119
- differ — but that block only arrives with the **next** user prompt. **About to call an MCP tool right
120
- after a `cd`? Run `cofluxd workspace` first** and use the `workspaceId` it prints; do not reuse
115
+ differ — but that block only arrives with the **next** user prompt. **About to call an account command right
116
+ after a `cd`? Run `coflux workspace` first** and use the `workspaceId` it prints; do not reuse
121
117
  `COFLUX_WORKSPACE_ID`.
122
118
 
123
119
  ## When to open a terminal
@@ -143,8 +139,8 @@ own tools are faster, and a pile of one-second terminals is just noise to the us
143
139
  There are two kinds, told apart by one single thing: **whether you pass a command**.
144
140
 
145
141
  ```sh
146
- cofluxd terminal new --title="Run unit tests" --cmd="pnpm -C tests test" # job terminal
147
- cofluxd terminal new --title="Debug shell" # session terminal
142
+ coflux terminal new --title="Run unit tests" --cmd="pnpm -C tests test" # job terminal
143
+ coflux terminal new --title="Debug shell" # session terminal
148
144
  ```
149
145
 
150
146
  `--title` is the name the user sees in the sidebar; **name it properly**: "Run unit tests",
@@ -173,14 +169,14 @@ from what is on screen, and `wait` is only meaningful after you have sent `exit`
173
169
 
174
170
  Driving a session terminal:
175
171
 
176
- 1. `cofluxd terminal new --title="Debug shell"` → prints a taskId.
177
- 2. `cofluxd terminal read <taskId>` until you see the shell prompt. The shell needs a moment to
172
+ 1. `coflux terminal new --title="Debug shell"` → prints a taskId.
173
+ 2. `coflux terminal read <taskId>` until you see the shell prompt. The shell needs a moment to
178
174
  start and the first read can come back empty — **never `send` before you have seen a prompt**.
179
- 3. `cofluxd terminal send <taskId> --text="pnpm build" --enter`, then `read` again to see what
175
+ 3. `coflux terminal send <taskId> --text="pnpm build" --enter`, then `read` again to see what
180
176
  happened. One send per command; nothing signals you when a command finished, so read until the
181
177
  prompt is back. To make that unambiguous, end the command with a marker of your own
182
178
  (`pnpm build; echo DONE-$?`) and read until the marker shows up.
183
- 4. `cofluxd terminal send <taskId> --text="exit" --enter` when you are done; the terminal then
179
+ 4. `coflux terminal send <taskId> --text="exit" --enter` when you are done; the terminal then
184
180
  becomes `exited` with the shell's exit code.
185
181
 
186
182
  The new terminal has the same `COFLUX_*` variables (pointing at its own task/session ids, same
@@ -189,9 +185,9 @@ workspace as you).
189
185
  ### See how far it got
190
186
 
191
187
  ```sh
192
- cofluxd terminal list # every terminal in the workspace your cwd is in: id, state, exit code, title
193
- cofluxd terminal read <taskId> # a terminal's content (plain text, last 200 lines by default)
194
- cofluxd terminal read <taskId> --lines 50
188
+ coflux terminal list # every terminal in the workspace your cwd is in: id, state, exit code, title
189
+ coflux terminal read <taskId> # a terminal's content (plain text, last 200 lines by default)
190
+ coflux terminal read <taskId> --lines 50
195
191
  ```
196
192
 
197
193
  `list` states are `running` / `exited` / `idle`; `exited` carries `exit=<code>`.
@@ -203,8 +199,8 @@ history, and empty for the first moments after opening. Both are immediate.
203
199
  ### Wait for a command to finish
204
200
 
205
201
  ```sh
206
- cofluxd terminal wait <taskId> # block until that terminal exits and print the exit code (default cap 30 minutes)
207
- cofluxd terminal wait <taskId> --timeout 300 # custom timeout in seconds; a timeout fails loudly with a non-zero exit
202
+ coflux terminal wait <taskId> # block until that terminal exits and print the exit code (default cap 30 minutes)
203
+ coflux terminal wait <taskId> --timeout 300 # custom timeout in seconds; a timeout fails loudly with a non-zero exit
208
204
  ```
209
205
 
210
206
  To wait for a command use `wait`; **do not write your own polling loop**. One command blocks
@@ -223,10 +219,10 @@ not any command's: check what a command did by reading the screen.
223
219
  **Keep working, and be woken up when it finishes.** `wait` blocks, so run it as a backgrounded Bash
224
220
  call of your own:
225
221
 
226
- 1. `cofluxd terminal new --title="Run the test suite" --cmd="pnpm -C tests test"` → prints a taskId.
227
- 2. Run `cofluxd terminal wait <taskId>` as a backgrounded Bash call, then go do something else.
222
+ 1. `coflux terminal new --title="Run the test suite" --cmd="pnpm -C tests test"` → prints a taskId.
223
+ 2. Run `coflux terminal wait <taskId>` as a backgrounded Bash call, then go do something else.
228
224
  3. The host wakes you when that call exits. Check its output for `# exited exit=<code>`, then
229
- `cofluxd terminal read <taskId>` to see what actually happened.
225
+ `coflux terminal read <taskId>` to see what actually happened.
230
226
 
231
227
  That gets you both halves at once: the user watches (and can take over) a real terminal, and you are
232
228
  still told the moment it is over, instead of blocking or polling for it.
@@ -234,8 +230,8 @@ still told the moment it is over, instead of blocking or polling for it.
234
230
  ### Type into a terminal
235
231
 
236
232
  ```sh
237
- cofluxd terminal send <taskId> --text "y" --enter # type a line and press Enter
238
- cofluxd terminal send <taskId> --enter # just press Enter
233
+ coflux terminal send <taskId> --text "y" --enter # type a line and press Enter
234
+ coflux terminal send <taskId> --enter # just press Enter
239
235
  ```
240
236
 
241
237
  For interactive confirmations (y/N, menus), or to add a command in the same shell after the
@@ -252,7 +248,7 @@ previous one finished. Discipline:
252
248
  ### Report progress
253
249
 
254
250
  ```sh
255
- cofluxd progress "Reproduced; narrowing down the relay reconnect timing"
251
+ coflux progress "Reproduced; narrowing down the relay reconnect timing"
256
252
  ```
257
253
 
258
254
  One sentence telling the user how far you are, shown on the workspace card and replaced by the
@@ -267,7 +263,7 @@ If unsure: when the user does not have to do anything, use `progress`.
267
263
  ### Call the user
268
264
 
269
265
  ```sh
270
- cofluxd notify "Both approaches work; I need you to pick one"
266
+ coflux notify "Both approaches work; I need you to pick one"
271
267
  ```
272
268
 
273
269
  The user's sidebar switches this workspace to "waiting for interaction" and shows this sentence;
@@ -281,7 +277,7 @@ extra notify. This is for "what you have to say cannot be guessed from the statu
281
277
  ### Hand the user a clickable preview
282
278
 
283
279
  ```sh
284
- cofluxd ports
280
+ coflux ports
285
281
  ```
286
282
 
287
283
  Lists every listening port in this workspace with its public preview URL. After starting a dev
@@ -292,79 +288,55 @@ server, use it to get the URL and tell the user directly; they click it and nobo
292
288
  Errors are one readable sentence; do what they say: "not inside a coflux terminal" = you are not
293
289
  in a coflux session; "terminal is not in this workspace or does not exist" = check the id with
294
290
  `list`, and if you moved into another workspace that is exactly what a terminal of the other one
295
- looks like (`cofluxd workspace` to confirm, `cd` back to reach it); "predates the daemon upgrade" =
291
+ looks like (`coflux workspace` to confirm, `cd` back to reach it); "predates the daemon upgrade" =
296
292
  that terminal was opened before the daemon upgrade, open a new one; a `new` without `--cmd` refused for a missing command = this machine's daemon is older
297
293
  than session terminals, tell the user to run `cofluxd update && cofluxd restart` (or pass a command
298
294
  and use a job terminal); "daemon is not connected to the center" only appears on
299
295
  `new`/`list`/`ports`, retry once it reconnects.
300
296
 
301
- ## Center MCP: leaving this workspace
297
+ ## Account CLI: across workspaces and devices
302
298
 
303
- Local commands only see the workspace your cwd is in. Use the MCP server named `coflux` in the
304
- host **only** for these:
305
-
306
- - **Open an isolated child workspace to work in parallel**: `create_workspace` (project id from
307
- `$COFLUX_PROJECT_ID`) really runs `git worktree add` on the device; then `create_terminal` runs
308
- commands there. The same two kinds apply: `create_terminal` with a `command` opens a
309
- job terminal, without one it opens a session terminal.
310
- - **Look at or operate terminals in other workspaces or on other devices**: `list_*` →
311
- `read_terminal` / `send_terminal_input`.
312
- - **Join everything under the account when you are not inside a coflux terminal** (for example
313
- Claude Code the user started on their own machine).
314
- - **Deleting a workspace**: `remove_workspace` (it closes that workspace's terminals first, then
315
- removes the worktree and the record). Inside a coflux project the plugin blocks
316
- `git worktree remove|move` run by hand, because that leaves an orphan workspace record in the user's
317
- sidebar. Creating a worktree is *not* blocked — coflux follows you into it (see above) — and Claude
318
- Code's own worktrees need no cleanup from you at all.
319
-
320
- Do not detour through MCP for work inside the workspace you are in — including one you moved into
321
- with `cd` or EnterWorktree, where the local commands follow you: that is an extra round trip to the
322
- center, while a local command does it in one step.
323
-
324
- ### When MCP is not configured
325
-
326
- Run `claude mcp list` (Codex: `codex mcp list`) to see whether `coflux` is there. If not, give
327
- the user the one-line setup, with the URL from `$COFLUX_MCP_URL` (it is the center's public URL
328
- + `/mcp`):
299
+ The bundled CLI can use the desktop app's login without receiving its token. For a standalone CLI,
300
+ use `coflux login --username <account> --password-stdin`; the user supplies the password safely,
301
+ never as a command argument. Account commands return JSON. A workspace ID identifies its device.
329
302
 
330
303
  ```sh
331
- claude mcp add --transport http coflux "$COFLUX_MCP_URL" # Claude Code
332
- codex mcp add coflux --url "$COFLUX_MCP_URL" # Codex
304
+ coflux device list
305
+ coflux project list --device <deviceId>
306
+ coflux workspace list --device <deviceId>
307
+ coflux workspace new --project <projectId> --branch <branch>
308
+ coflux terminal new --workspace <workspaceId> --title <title> [--cmd <command>]
309
+ coflux terminal list --workspace <workspaceId>
310
+ coflux terminal read <terminalId> --remote
311
+ coflux terminal send <terminalId> --remote --text <text> [--enter]
312
+ coflux terminal wait <terminalId> --remote --timeout 30
313
+ coflux terminal stop <terminalId> --remote
314
+ coflux terminal remove <terminalId> --remote
315
+ coflux workspace rename <workspaceId> --name <name>
316
+ coflux workspace remove <workspaceId>
317
+ coflux ports --remote --device <deviceId>
333
318
  ```
334
319
 
335
- The host then guides the user through a one-time OAuth authorization in the browser (`/mcp` in
336
- Claude Code). Authorization is the user's job; you only hand over the URL and the command. Until
337
- it is set up, keep doing the work inside this workspace with local commands.
338
-
339
- ### Using the tools
340
-
341
- The tool list and each tool's contract (parameters, limits, what an error means) come from the
342
- MCP server itself: read the tool descriptions in the host, they are the source of truth and this
343
- file does not repeat them. Take ids from the `COFLUX_*` variables first — except the workspace id
344
- after you moved, which comes from `cofluxd workspace` (or the `<coflux-session-moved>` block); for
345
- anything outside the workspace you are in, find ids with the `list_*` tools.
346
-
347
- The local-command disciplines apply to MCP just the same: `read_terminal` before
348
- `send_terminal_input`, stop when refused because the user is taking over (communicate with
349
- `cofluxd notify` instead of retrying), `wait_terminal` instead of a polling loop around
350
- `read_terminal`, and stop on "needs upgrade" (tell the user to run
351
- `cofluxd update && cofluxd restart` on that device; do not retry or work around it).
320
+ `--remote` selects account access, including other workspaces on this machine. Read before sending;
321
+ stop immediately when the user takes over. If a write times out, inspect the result before retrying.
322
+ Exiting the CLI does not stop its terminals. Delete workspaces through `coflux workspace remove`
323
+ so the filesystem and workspace records stay consistent.
352
324
 
353
325
  ## Boundaries
354
326
 
355
327
  - You can open, read, wait and type, but **typing is a restricted write with humans first**: you
356
328
  cannot write into a terminal the user is taking over (you are refused explicitly), and the user
357
329
  taking over at any time displaces you. Do not fight a human for a terminal.
358
- - Local commands only see **the workspace your cwd is in** (`cofluxd workspace` says which one);
359
- other workspaces and other machines go through MCP and are limited to the same account.
330
+ - Local commands only see **the workspace your cwd is in** (`coflux workspace` says which one);
331
+ use the account CLI for other workspaces and machines in the same account.
360
332
  - A workspace has a cap on concurrently live terminals (default 8, including the user's own).
361
333
  On hitting the cap, `list` first: usually some finished terminals were never collected. If the
362
334
  user really filled it up, `notify` them instead of forcing it.
363
- - `new`/`list`/`ports` and every MCP tool need the daemon connected to the center; "letting the
335
+ - `new`/`list`/`ports` and account commands need the daemon connected to the center; "letting the
364
336
  user see" is their whole point. `send`/`read`/`wait`/`notify`/`progress` do not depend on the
365
337
  center. When disconnected they fail loudly rather than degrade silently.
366
338
  - `COFLUX_*` variables exist only in PTYs opened by coflux; exporting or changing them yourself
367
339
  has no effect, the center only trusts the ids it issued. `COFLUX_WORKSPACE_ID` always means the
368
340
  workspace this terminal was **opened** in and goes stale the moment coflux follows you into a
369
341
  worktree; both "where does this terminal belong now" and "where am I acting" come from
370
- `cofluxd workspace`.
342
+ `coflux workspace`.