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.
- package/README.md +34 -67
- package/account-client.mjs +101 -0
- package/coflux.mjs +399 -0
- package/cofluxd.mjs +9 -362
- package/package.json +6 -3
- package/skills/coflux/SKILL.md +63 -91
package/skills/coflux/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: coflux
|
|
3
|
-
description:
|
|
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
|
-
|
|
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 `
|
|
19
|
-
|
|
|
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
|
|
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. `
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
- `
|
|
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
|
-
- `
|
|
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
|
-
-
|
|
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
|
|
97
|
-
tool result, and `
|
|
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
|
-
|
|
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
|
|
120
|
-
after a `cd`? Run `
|
|
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
|
-
|
|
147
|
-
|
|
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. `
|
|
177
|
-
2. `
|
|
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. `
|
|
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. `
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
207
|
-
|
|
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. `
|
|
227
|
-
2. Run `
|
|
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
|
-
`
|
|
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
|
-
|
|
238
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (`
|
|
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
|
-
##
|
|
297
|
+
## Account CLI: across workspaces and devices
|
|
302
298
|
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
332
|
-
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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** (`
|
|
359
|
-
|
|
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
|
|
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
|
-
`
|
|
342
|
+
`coflux workspace`.
|