cofluxd 0.14.0 → 0.15.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/cofluxd.mjs +88 -3
- package/package.json +1 -1
- package/skills/coflux/SKILL.md +97 -21
package/cofluxd.mjs
CHANGED
|
@@ -945,10 +945,14 @@ async function cmdHook() {
|
|
|
945
945
|
// 不需要任何凭证:daemon 用调用方 pid 反查进程树确认它属于哪个会话,树外一律拒。
|
|
946
946
|
// local-first(plan 094):send/read/wait/notify/progress 在 daemon 本地闭环,不经中心;只有
|
|
947
947
|
// new/list/ports 由 daemon 代问中心(Task 要落库广播、预览 URL 由中心生成)。
|
|
948
|
+
// 跟随 cwd(plan 102):请求都带 process.cwd(),agent 挪进同设备另一个 coflux 工作区后,这些
|
|
949
|
+
// 命令就对那个工作区办事(notify/progress/ports 除外,它们挂在本会话上,与工作区无关)。
|
|
948
950
|
// 与 `hook` 子命令的约定**相反**:这些命令必须写 stdout——输出就是给 agent 读的返回值。
|
|
949
951
|
// 也刻意不做自动重试:terminal new 有副作用,重试会开出两个终端,失败就把错误交给 agent。
|
|
950
952
|
|
|
951
953
|
const AGENT_TIMEOUT_MS = 30_000;
|
|
954
|
+
/** 调用方能收窄单次 `/agent` 等待的下限;再低就只够覆盖 node 自己的启动,等于必然超时。 */
|
|
955
|
+
const MIN_AGENT_TIMEOUT_MS = 200;
|
|
952
956
|
const DEFAULT_READ_LINES = 200;
|
|
953
957
|
// wait 的循环必须在 CLI 侧:单次 agentPost 有 25 秒的 loopback 应答上限。默认 30 分钟——编码任务
|
|
954
958
|
// 常跑很久;轮询走 terminal.status(daemon 本地账本直接答,不经中心),3 秒一次对本机 loopback
|
|
@@ -956,6 +960,24 @@ const DEFAULT_READ_LINES = 200;
|
|
|
956
960
|
const DEFAULT_WAIT_TIMEOUT_S = 1800;
|
|
957
961
|
const WAIT_POLL_MS = 3000;
|
|
958
962
|
|
|
963
|
+
// 每条请求都带调用方 cwd(plan 102):agent 可以经 `/cd` 或 EnterWorktree 把活着的会话挪进同
|
|
964
|
+
// 设备的另一个 coflux 工作区,daemon 据此把本次请求的**目标**解析到 cwd 所在的工作区(会话的
|
|
965
|
+
// 归属工作区不变)。目录被删掉时 process.cwd() 会抛,按"报不出来"处理,daemon 退回归属工作区。
|
|
966
|
+
function callerCwd() {
|
|
967
|
+
try { return process.cwd(); } catch { return ""; }
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// 调用方可以用 COFLUX_AGENT_TIMEOUT_MS 收窄单次请求的等待上限(plan 104)。默认 30 秒是为
|
|
971
|
+
// agent 定的——它等得起;hook 脚本等不起:宿主按秒杀 hook(SessionStart 只给几秒),而经中心的
|
|
972
|
+
// 动作最坏要等 daemon 的 20 秒中心超时。被宿主杀在半路比拿不到答案坏得多(连坐标块都印不出来),
|
|
973
|
+
// 所以这类调用方自报一个更小的预算,到点干净失败、让脚本走回退。
|
|
974
|
+
// 只允许收窄不允许放宽:上限仍是 AGENT_TIMEOUT_MS,畸形值一律按默认处理。
|
|
975
|
+
function agentTimeoutMs() {
|
|
976
|
+
const raw = Number(process.env.COFLUX_AGENT_TIMEOUT_MS);
|
|
977
|
+
if (!Number.isFinite(raw) || raw <= 0) return AGENT_TIMEOUT_MS;
|
|
978
|
+
return Math.min(Math.max(Math.floor(raw), MIN_AGENT_TIMEOUT_MS), AGENT_TIMEOUT_MS);
|
|
979
|
+
}
|
|
980
|
+
|
|
959
981
|
async function agentPost(body) {
|
|
960
982
|
const portResult = localGatewayPort();
|
|
961
983
|
if (!portResult.ok) die(portResult.error);
|
|
@@ -964,8 +986,8 @@ async function agentPost(body) {
|
|
|
964
986
|
res = await fetch(`http://127.0.0.1:${portResult.port}/agent`, {
|
|
965
987
|
method: "POST",
|
|
966
988
|
headers: { "content-type": "application/json" },
|
|
967
|
-
body: JSON.stringify({ ...body, pid: process.pid, ppid: process.ppid }),
|
|
968
|
-
signal: AbortSignal.timeout(
|
|
989
|
+
body: JSON.stringify({ ...body, pid: process.pid, ppid: process.ppid, cwd: callerCwd() }),
|
|
990
|
+
signal: AbortSignal.timeout(agentTimeoutMs()),
|
|
969
991
|
});
|
|
970
992
|
} catch (error) {
|
|
971
993
|
die(`连不上本机 daemon:${error?.message || error}(daemon 没在跑?先看 cofluxd status)`);
|
|
@@ -1071,6 +1093,55 @@ async function cmdProgress() {
|
|
|
1071
1093
|
console.log("已更新进度(显示在工作区卡片上,被下一条覆盖)");
|
|
1072
1094
|
}
|
|
1073
1095
|
|
|
1096
|
+
// 「我在哪」与「跟着我搬」(plan 102 / 103)。三条都打一行 JSON,字段稳定——插件脚本按它比对,
|
|
1097
|
+
// agent 也直接读。
|
|
1098
|
+
//
|
|
1099
|
+
// cofluxd workspace 只读:cwd 所在的有效工作区 + 本终端的归属工作区
|
|
1100
|
+
// cofluxd workspace locate [path] 把本终端的**归属**搬到 path 所属的工作区(未登记先登记)
|
|
1101
|
+
// cofluxd workspace forget <path> 该 worktree 已被删掉:其下终端搬回主工作区、记录消失
|
|
1102
|
+
//
|
|
1103
|
+
// locate/forget 是插件在 SessionStart / PostToolUse(EnterWorktree|ExitWorktree) / WorktreeRemove
|
|
1104
|
+
// 上调的,同样零凭证(daemon 按进程树认身份)。daemon 旧到不认识这两个动作时它会回
|
|
1105
|
+
// 「未知 action …」,agentPost 原样报错并非零退出——脚本据此静默放弃,不干扰会话。
|
|
1106
|
+
async function cmdWorkspace() {
|
|
1107
|
+
const sub = positionals[1];
|
|
1108
|
+
if (!sub) {
|
|
1109
|
+
const result = await agentPost({ action: "workspace.current" });
|
|
1110
|
+
return void console.log(JSON.stringify({
|
|
1111
|
+
workspaceId: result.workspaceId,
|
|
1112
|
+
path: result.path,
|
|
1113
|
+
owningWorkspaceId: result.owningWorkspaceId,
|
|
1114
|
+
moved: Boolean(result.moved),
|
|
1115
|
+
}));
|
|
1116
|
+
}
|
|
1117
|
+
if (sub === "locate") {
|
|
1118
|
+
// 路径缺省取调用方 cwd;插件脚本一律显式传 hook 载荷里的 cwd(hook 在会话当前目录执行,
|
|
1119
|
+
// 与载荷里的 cwd 未必相同)。
|
|
1120
|
+
const path = positionals[2] || callerCwd();
|
|
1121
|
+
if (!path) die("workspace locate 需要 <path>(取不到当前目录)");
|
|
1122
|
+
const result = await agentPost({ action: "workspace.locate", path });
|
|
1123
|
+
return void console.log(JSON.stringify({
|
|
1124
|
+
workspaceId: result.workspaceId,
|
|
1125
|
+
path: result.path,
|
|
1126
|
+
branch: result.branch,
|
|
1127
|
+
created: Boolean(result.created),
|
|
1128
|
+
moved: Boolean(result.moved),
|
|
1129
|
+
}));
|
|
1130
|
+
}
|
|
1131
|
+
if (sub === "forget") {
|
|
1132
|
+
const path = positionals[2];
|
|
1133
|
+
if (!path) die("workspace forget 需要 <path>(被删掉的 worktree 目录)");
|
|
1134
|
+
const result = await agentPost({ action: "workspace.forget", path });
|
|
1135
|
+
return void console.log(JSON.stringify({
|
|
1136
|
+
workspaceId: result.workspaceId,
|
|
1137
|
+
fallbackWorkspaceId: result.fallbackWorkspaceId,
|
|
1138
|
+
movedTerminals: result.movedTerminals ?? 0,
|
|
1139
|
+
removed: Boolean(result.removed),
|
|
1140
|
+
}));
|
|
1141
|
+
}
|
|
1142
|
+
die(`workspace 的子命令只有 locate | forget(不带子命令 = 报出我在哪)`);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1074
1145
|
async function cmdPorts() {
|
|
1075
1146
|
const { ports } = await agentPost({ action: "ports" });
|
|
1076
1147
|
if (!ports.length) return void console.log("本工作区暂无监听端口");
|
|
@@ -1110,6 +1181,20 @@ const HELP = `cofluxd —— coflux daemon 管理
|
|
|
1110
1181
|
cofluxd notify "<一句话>" 叫人:工作区在侧栏转为「等待交互」并显示这句话
|
|
1111
1182
|
cofluxd progress "<一句话>" 播报进度:显示在工作区卡片上,被下一条覆盖(不打扰用户)
|
|
1112
1183
|
cofluxd ports 列出本工作区的监听端口及可直接打开的预览 URL
|
|
1184
|
+
cofluxd workspace 一行 JSON 报出「我在哪」:workspaceId(cwd 所在的有效工作区,本地命令
|
|
1185
|
+
都落在它上面)、path、owningWorkspaceId(本终端此刻归属哪个工作区)、
|
|
1186
|
+
moved。用 /cd 挪进另一个 coflux 工作区后用它确认目标,调 MCP 时也传这个
|
|
1187
|
+
workspaceId
|
|
1188
|
+
cofluxd workspace locate [path]
|
|
1189
|
+
把本终端的**归属**搬到 path(缺省=当前目录)所属的工作区:进入/离开
|
|
1190
|
+
worktree 后 coflux 跟着走,未登记的同仓库 worktree 先登记出一个子工作区。
|
|
1191
|
+
插件自动调,一般不用手敲
|
|
1192
|
+
cofluxd workspace forget <path>
|
|
1193
|
+
该 worktree 已被删掉:其下所有终端搬回项目主工作区、工作区记录消失
|
|
1194
|
+
(不执行 git worktree remove)
|
|
1195
|
+
|
|
1196
|
+
agent 命令的环境变量:COFLUX_AGENT_TIMEOUT_MS 收窄单次请求的等待上限(默认 30000,只能调小),
|
|
1197
|
+
供有硬超时的 hook 脚本用——到点干净失败,好过被宿主杀在半路。
|
|
1113
1198
|
|
|
1114
1199
|
up flags: --server <ws://.../daemon> --name <名> --shell <路径>
|
|
1115
1200
|
通用: --version <vX|latest>(不传时 up 沿用已有二进制,update 默认 latest) --bin-dir <dir>(用本地 cargo 产物) --no-start
|
|
@@ -1147,7 +1232,7 @@ let cmd = positionals[0];
|
|
|
1147
1232
|
if (values.help || cmd === "help") { console.log(HELP); process.exit(0); }
|
|
1148
1233
|
if (!cmd) cmd = fs.existsSync(SETTINGS) ? "status" : "up"; // 首次裸跑 → 引导
|
|
1149
1234
|
|
|
1150
|
-
const handlers = { up: cmdUp, update: cmdUpdate, restart: cmdRestart, down: cmdDown, status: cmdStatus, doctor: cmdDoctor, fda: cmdFda, logs: cmdLogs, uninstall: cmdUninstall, hook: cmdHook, terminal: cmdTerminal, notify: cmdNotify, progress: cmdProgress, ports: cmdPorts };
|
|
1235
|
+
const handlers = { up: cmdUp, update: cmdUpdate, restart: cmdRestart, down: cmdDown, status: cmdStatus, doctor: cmdDoctor, fda: cmdFda, logs: cmdLogs, uninstall: cmdUninstall, hook: cmdHook, terminal: cmdTerminal, notify: cmdNotify, progress: cmdProgress, ports: cmdPorts, workspace: cmdWorkspace };
|
|
1151
1236
|
const h = handlers[cmd];
|
|
1152
1237
|
if (!h) die(`未知命令: ${cmd}${MIGRATED[cmd] ? `\n${MIGRATED[cmd]}` : ""}\n\n${HELP}`);
|
|
1153
1238
|
await h(values);
|
package/package.json
CHANGED
package/skills/coflux/SKILL.md
CHANGED
|
@@ -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.
|
|
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.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Working inside coflux
|
|
@@ -10,12 +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
|
|
14
|
-
workspace goes through MCP.**
|
|
13
|
+
Two tracks, one rule: **whatever closes locally uses local commands; only reaching beyond the
|
|
14
|
+
workspace you are in goes through MCP.**
|
|
15
15
|
|
|
16
16
|
| Track | Credentials | Reach | Use for |
|
|
17
17
|
|---|---|---|---|
|
|
18
|
-
| Local commands `cofluxd terminal/progress/notify/ports` | none (the daemon identifies you by process tree) | **the workspace
|
|
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
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 |
|
|
20
20
|
|
|
21
21
|
Of the local commands, `send`/`read`/`wait`/`notify`/`progress` complete entirely inside the
|
|
@@ -42,7 +42,7 @@ env | grep '^COFLUX_'
|
|
|
42
42
|
|---|---|
|
|
43
43
|
| `COFLUX_DEVICE_ID` | id of the device you run on (the id in `list_devices`) |
|
|
44
44
|
| `COFLUX_PROJECT_ID` | owning project id; empty string for a directory workspace without a repository |
|
|
45
|
-
| `COFLUX_WORKSPACE_ID` |
|
|
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 |
|
|
46
46
|
| `COFLUX_TASK_ID` | id of this terminal (the taskId / terminalId used by local commands and `read_terminal`) |
|
|
47
47
|
| `COFLUX_SESSION_ID` | id of this PTY session |
|
|
48
48
|
| `COFLUX_MCP_URL` | the center's MCP URL; the user configures MCP with it |
|
|
@@ -53,6 +53,73 @@ env | grep '^COFLUX_'
|
|
|
53
53
|
this machine's daemon has not been upgraded: tell the user to run `cofluxd update && cofluxd restart`;
|
|
54
54
|
after reopening the terminal the variables and the local commands are there.
|
|
55
55
|
|
|
56
|
+
### Two workspaces to keep apart: owning and effective
|
|
57
|
+
|
|
58
|
+
- **Owning workspace** = the workspace this terminal **belongs to**: what the user's sidebar shows it
|
|
59
|
+
under, what its turn state, branch and diff stats are attributed to. It starts out as
|
|
60
|
+
`COFLUX_WORKSPACE_ID` and moves with you when you enter or leave a git worktree (below).
|
|
61
|
+
- **Effective workspace** = the workspace **your current working directory is inside**. This is what
|
|
62
|
+
every local command acts on.
|
|
63
|
+
|
|
64
|
+
They are the same until your cwd wanders off. A plain `cd <path>` moves a *live* session — same
|
|
65
|
+
conversation, no restart — and a coflux child workspace is a normal registered git worktree, so a
|
|
66
|
+
session whose terminal belongs to workspace A can end up working inside workspace B. From that
|
|
67
|
+
moment, in B:
|
|
68
|
+
|
|
69
|
+
- `cofluxd terminal new` opens the terminal **in B**, under B in the user's sidebar, running in B's
|
|
70
|
+
directory, counting against B's terminal cap;
|
|
71
|
+
- `cofluxd terminal list` lists B's terminals, and A's terminals answer `read` / `wait` / `send`
|
|
72
|
+
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`;
|
|
74
|
+
- the terminal itself stays under A, and `progress`, `notify` and `ports` still belong to it,
|
|
75
|
+
whatever your cwd is; `COFLUX_TASK_ID` and `COFLUX_SESSION_ID` never change.
|
|
76
|
+
|
|
77
|
+
If your cwd is outside every coflux workspace (say `/tmp`), local commands fall back to the owning
|
|
78
|
+
workspace.
|
|
79
|
+
|
|
80
|
+
A terminal opened before the daemon was upgraded is the one case with no owning workspace at all:
|
|
81
|
+
its local commands are refused with "predates the daemon upgrade" whatever your cwd is, because the
|
|
82
|
+
daemon never guesses ownership from a directory. Open a new terminal.
|
|
83
|
+
|
|
84
|
+
### coflux follows you into a git worktree
|
|
85
|
+
|
|
86
|
+
`EnterWorktree` switches this live session into a git worktree (its own, or an existing one you point
|
|
87
|
+
it at), `ExitWorktree` switches back, and resuming a session that had entered one puts you straight
|
|
88
|
+
back in it. **coflux comes along**: the terminal's *owning* workspace moves to the workspace that
|
|
89
|
+
worktree is, and if coflux has never seen that worktree it registers it as a child workspace of this
|
|
90
|
+
project first — a new card appears in the user's sidebar, with its branch and diff stats. Nothing is
|
|
91
|
+
interrupted: same terminal, same PTY, same conversation, and the user keeps watching it where it now
|
|
92
|
+
lives. When Claude Code cleans up its own worktree on exit, that workspace's terminals move back to
|
|
93
|
+
the project's main workspace and the record disappears by itself.
|
|
94
|
+
|
|
95
|
+
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:
|
|
98
|
+
|
|
99
|
+
- `COFLUX_WORKSPACE_ID` (and the id in the `<coflux-session>` block from earlier in this session)
|
|
100
|
+
still names where the terminal was *opened*; it is frozen when the PTY starts and cannot be
|
|
101
|
+
rewritten. Never reuse it after a move.
|
|
102
|
+
- The shell inside this terminal keeps its own directory. That is only about the shell; it does not
|
|
103
|
+
affect where your work is attributed.
|
|
104
|
+
|
|
105
|
+
Nothing happens when coflux cannot follow, and nothing is blocked either: another repository, a
|
|
106
|
+
directory that is not a git repository, a terminal opened in a directory workspace (no project), or
|
|
107
|
+
a daemon that is down or too old — the session just carries on with the ownership it had.
|
|
108
|
+
|
|
109
|
+
### Ask where you are
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
cofluxd workspace
|
|
113
|
+
{"workspaceId":"ws-b","path":"/Users/me/.coflux/worktrees/ws-b","owningWorkspaceId":"ws-a","moved":true}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
One line of JSON: `workspaceId` (+ `path`) is the **effective** workspace, `owningWorkspaceId` is the
|
|
117
|
+
workspace this terminal belongs to right now, and `moved` says whether they differ. With the plugin
|
|
118
|
+
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
|
|
121
|
+
`COFLUX_WORKSPACE_ID`.
|
|
122
|
+
|
|
56
123
|
## When to open a terminal
|
|
57
124
|
|
|
58
125
|
A coflux terminal is a process the user can see: a titled entry in their sidebar that they can
|
|
@@ -81,7 +148,8 @@ cofluxd terminal new --title="Debug shell" # ses
|
|
|
81
148
|
```
|
|
82
149
|
|
|
83
150
|
`--title` is the name the user sees in the sidebar; **name it properly**: "Run unit tests",
|
|
84
|
-
"Start dev server", never "terminal 1". Either kind runs in the
|
|
151
|
+
"Start dev server", never "terminal 1". Either kind runs in the directory of the workspace your cwd
|
|
152
|
+
is in (which is not always the one this terminal was opened in — see "owning and effective").
|
|
85
153
|
|
|
86
154
|
Always write `--cmd=<value>` and `--title=<value>` with the `=`, never separated by a space: a
|
|
87
155
|
value that starts with `-` is otherwise taken for another option and the call fails outright.
|
|
@@ -121,7 +189,7 @@ workspace as you).
|
|
|
121
189
|
### See how far it got
|
|
122
190
|
|
|
123
191
|
```sh
|
|
124
|
-
cofluxd terminal list # every terminal in
|
|
192
|
+
cofluxd terminal list # every terminal in the workspace your cwd is in: id, state, exit code, title
|
|
125
193
|
cofluxd terminal read <taskId> # a terminal's content (plain text, last 200 lines by default)
|
|
126
194
|
cofluxd terminal read <taskId> --lines 50
|
|
127
195
|
```
|
|
@@ -223,16 +291,17 @@ server, use it to get the URL and tell the user directly; they click it and nobo
|
|
|
223
291
|
|
|
224
292
|
Errors are one readable sentence; do what they say: "not inside a coflux terminal" = you are not
|
|
225
293
|
in a coflux session; "terminal is not in this workspace or does not exist" = check the id with
|
|
226
|
-
`list
|
|
227
|
-
|
|
294
|
+
`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" =
|
|
296
|
+
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
|
|
228
297
|
than session terminals, tell the user to run `cofluxd update && cofluxd restart` (or pass a command
|
|
229
298
|
and use a job terminal); "daemon is not connected to the center" only appears on
|
|
230
299
|
`new`/`list`/`ports`, retry once it reconnects.
|
|
231
300
|
|
|
232
301
|
## Center MCP: leaving this workspace
|
|
233
302
|
|
|
234
|
-
Local commands only see the workspace
|
|
235
|
-
**only** for these:
|
|
303
|
+
Local commands only see the workspace your cwd is in. Use the MCP server named `coflux` in the
|
|
304
|
+
host **only** for these:
|
|
236
305
|
|
|
237
306
|
- **Open an isolated child workspace to work in parallel**: `create_workspace` (project id from
|
|
238
307
|
`$COFLUX_PROJECT_ID`) really runs `git worktree add` on the device; then `create_terminal` runs
|
|
@@ -242,11 +311,14 @@ Local commands only see the workspace you are in. Use the MCP server named `cofl
|
|
|
242
311
|
`read_terminal` / `send_terminal_input`.
|
|
243
312
|
- **Join everything under the account when you are not inside a coflux terminal** (for example
|
|
244
313
|
Claude Code the user started on their own machine).
|
|
245
|
-
- **
|
|
246
|
-
|
|
247
|
-
worktree
|
|
248
|
-
|
|
249
|
-
|
|
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
|
|
250
322
|
center, while a local command does it in one step.
|
|
251
323
|
|
|
252
324
|
### When MCP is not configured
|
|
@@ -268,8 +340,9 @@ it is set up, keep doing the work inside this workspace with local commands.
|
|
|
268
340
|
|
|
269
341
|
The tool list and each tool's contract (parameters, limits, what an error means) come from the
|
|
270
342
|
MCP server itself: read the tool descriptions in the host, they are the source of truth and this
|
|
271
|
-
file does not repeat them. Take ids from the `COFLUX_*` variables first
|
|
272
|
-
|
|
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.
|
|
273
346
|
|
|
274
347
|
The local-command disciplines apply to MCP just the same: `read_terminal` before
|
|
275
348
|
`send_terminal_input`, stop when refused because the user is taking over (communicate with
|
|
@@ -282,8 +355,8 @@ The local-command disciplines apply to MCP just the same: `read_terminal` before
|
|
|
282
355
|
- You can open, read, wait and type, but **typing is a restricted write with humans first**: you
|
|
283
356
|
cannot write into a terminal the user is taking over (you are refused explicitly), and the user
|
|
284
357
|
taking over at any time displaces you. Do not fight a human for a terminal.
|
|
285
|
-
- Local commands only see **the workspace
|
|
286
|
-
through MCP and are limited to the same account.
|
|
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.
|
|
287
360
|
- A workspace has a cap on concurrently live terminals (default 8, including the user's own).
|
|
288
361
|
On hitting the cap, `list` first: usually some finished terminals were never collected. If the
|
|
289
362
|
user really filled it up, `notify` them instead of forcing it.
|
|
@@ -291,4 +364,7 @@ The local-command disciplines apply to MCP just the same: `read_terminal` before
|
|
|
291
364
|
user see" is their whole point. `send`/`read`/`wait`/`notify`/`progress` do not depend on the
|
|
292
365
|
center. When disconnected they fail loudly rather than degrade silently.
|
|
293
366
|
- `COFLUX_*` variables exist only in PTYs opened by coflux; exporting or changing them yourself
|
|
294
|
-
has no effect, the center only trusts the ids it issued.
|
|
367
|
+
has no effect, the center only trusts the ids it issued. `COFLUX_WORKSPACE_ID` always means the
|
|
368
|
+
workspace this terminal was **opened** in and goes stale the moment coflux follows you into a
|
|
369
|
+
worktree; both "where does this terminal belong now" and "where am I acting" come from
|
|
370
|
+
`cofluxd workspace`.
|