worktrust 0.6.0 → 0.6.2

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 CHANGED
@@ -4,7 +4,7 @@ Couple a computer to [WorkTrust](https://worktrust.io) in one command. WorkTrust
4
4
  record of the work you do with AI without anyone reading that work: it receives metadata only.
5
5
 
6
6
  ```
7
- npx worktrust
7
+ npx worktrust@latest
8
8
  ```
9
9
 
10
10
  **The only official package** is `worktrust`, published by the npm account **worktrustio** with
package/log-session.mjs CHANGED
@@ -753,7 +753,7 @@ if (flag("install")) {
753
753
  // Codex has no settings.json to wire; its notify hook is one line in config.toml, added by hand so
754
754
  // this script never rewrites a TOML file it did not create. Without it, Codex rollouts are still
755
755
  // swept whenever the Claude Code hook runs.
756
- if (existsSync(join(homedir(), ".codex"))) console.log(`codex: to have Codex wake this hook too, add to ~/.codex/config.toml:\n notify = ${via ? `["${process.execPath}", "${via}", "hook", "--codex-notify"]` : `["node", "${home}", "--codex-notify"]`}\n (its rollouts are swept on every run either way)`);
756
+ if (existsSync(join(homedir(), ".codex"))) console.log(`codex: to have Codex wake this hook too, add to ~/.codex/config.toml:\n notify = ${via ? `["${process.env.WORKTRUST_NODE || process.execPath}", "${via}", "hook", "--codex-notify"]` : `["node", "${home}", "--codex-notify"]`}\n (its rollouts are swept on every run either way)`);
757
757
  process.exit(0);
758
758
  }
759
759
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktrust",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Couple this computer to WorkTrust: approve a code in your browser, and every AI app here reports what you built. Metadata only, no dependencies.",
5
5
  "type": "module",
6
6
  "bin": {
package/setup-mcp.mjs CHANGED
@@ -43,6 +43,23 @@ function fromClaude() {
43
43
  } catch { return null; }
44
44
  }
45
45
  const discovered = fromClaude();
46
+ /**
47
+ * EVERY DIRECT WORKTRUST ENTRY CLAUDE CODE HOLDS, BY NAME (2026-10-04). A coupling made by hand may
48
+ * carry any name ("worktrust-imac-home") and a key in its header; `npx worktrust` once read it as
49
+ * "already coupled" and left Claude Code on that unbound key. With the bridge, each such entry is
50
+ * taken out and the bridge put in; on removal, they all go. Only entries whose address is a
51
+ * WorkTrust door are touched, user scope here and local scope in the folder that holds it.
52
+ */
53
+ function directClaudeEntries() {
54
+ try {
55
+ const config = JSON.parse(readFileSync(join(homedir(), ".claude.json"), "utf8"));
56
+ const door = (server) => typeof server?.url === "string" && /\/api\/mcp\b/.test(server.url) && /worktrust/i.test(new URL(server.url).host);
57
+ const entries = Object.entries(config.mcpServers ?? {}).filter(([, server]) => door(server)).map(([name]) => ({ name, scope: "user", dir: null }));
58
+ for (const [dir, project] of Object.entries(config.projects ?? {})) for (const [name, server] of Object.entries(project?.mcpServers ?? {})) if (door(server)) entries.push({ name, scope: "local", dir });
59
+ const bridged = Object.values(config.mcpServers ?? {}).some((server) => Array.isArray(server?.args) && server.args.includes(BRIDGE));
60
+ return { entries, bridged };
61
+ } catch { return { entries: [], bridged: false }; }
62
+ }
46
63
  const URL_ = value("url") ?? process.env.WORKTRUST_MCP_URL ?? discovered?.url;
47
64
  const TOKEN = value("token") ?? process.env.WORKTRUST_MCP_TOKEN ?? discovered?.token;
48
65
  if (!URL_ || (!TOKEN && !BRIDGE)) { console.error("no coupling: pass --url and --token (from Sources → Claude (MCP) → Add coupling), or couple Claude Code first"); process.exit(1); }
@@ -75,7 +92,15 @@ for (const client of CLIENTS) {
75
92
  // it when the command is not. User scope, so the coupling holds in every folder on this machine.
76
93
  const claudeArgs = REMOVE ? ["mcp", "remove", "-s", "user", NAME] : BRIDGE ? ["mcp", "add", "-s", "user", NAME, "--", NODE, BRIDGE, "mcp"] : ["mcp", "add", "--transport", "http", "-s", "user", NAME, URL_, "-H", `Authorization: Bearer ${TOKEN}`];
77
94
  const shown = REMOVE ? `claude mcp remove -s user ${NAME}` : BRIDGE ? `claude mcp add -s user ${NAME} -- "${NODE}" "${BRIDGE}" mcp` : `claude mcp add --transport http -s user ${NAME} "${URL_}" -H "Authorization: Bearer <token>"`;
78
- if (!REMOVE && discovered) { console.log(` ✓ ${client.label}: already coupled`); standing += 1; continue; }
95
+ const direct = directClaudeEntries();
96
+ if (!REMOVE && (BRIDGE ? direct.bridged && direct.entries.length === 0 : discovered)) { console.log(` ✓ ${client.label}: already coupled`); standing += 1; continue; }
97
+ // A direct entry under any name is replaced by the bridge, and every one goes on removal.
98
+ if (BRIDGE || REMOVE) for (const entry of direct.entries.filter((one) => !(REMOVE && one.name === NAME && one.scope === "user"))) {
99
+ const verb = `claude mcp remove -s ${entry.scope} ${entry.name}`;
100
+ if (!WRITE) { console.log(` ↻ ${client.label}: the direct entry "${entry.name}" (${entry.scope}) is replaced`); continue; }
101
+ const out = claudeOnPath() ? spawnSync("claude", ["mcp", "remove", "-s", entry.scope, entry.name], { encoding: "utf8", shell: platform() === "win32", ...(entry.dir ? { cwd: entry.dir } : {}) }) : null;
102
+ console.log(out?.status === 0 ? ` – ${client.label}: removed the direct entry "${entry.name}" (${entry.scope})` : ` ! ${client.label}: could not remove "${entry.name}"; run it yourself${entry.dir ? ` in ${entry.dir}` : ""}: ${verb}`);
103
+ }
79
104
  if (WRITE && claudeOnPath()) {
80
105
  const run = spawnSync("claude", claudeArgs, { encoding: "utf8", shell: platform() === "win32" });
81
106
  if (run.status === 0) { console.log(` + ${client.label}: ${REMOVE ? "removed" : "coupled"} through \`claude mcp ${REMOVE ? "remove" : "add"}\` (user scope)`); touched += 1; continue; }