xmux-bridge 1.0.40 → 1.0.41

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
@@ -24,11 +24,6 @@ brew tap DwvN-Lee/xmux
24
24
  brew install xmux
25
25
  ```
26
26
 
27
- Homebrew owns the stable runtime under `$(brew --prefix)/opt/xmux/libexec`.
28
- The installed `xmux` command exports that path as `XMUX_INSTALL_DIR` and then
29
- execs the runtime wrapper in `libexec/bin/xmux`. Ad hoc local directories, npx
30
- caches, and zsh plugin directories are not part of the normal runtime path.
31
-
32
27
  Configure Codex integration explicitly:
33
28
 
34
29
  ```bash
@@ -36,21 +31,8 @@ xmux setup-codex
36
31
  xmux doctor-codex
37
32
  ```
38
33
 
39
- Homebrew installs the XMux CLI/runtime only. `xmux setup-codex` is the command
40
- that mutates `~/.codex`: it registers the `xmux_lead` MCP server through the
41
- versioned npm package, points that MCP runtime back at Homebrew with
42
- `XMUX_INSTALL_DIR`, adds the installed `xmux` path to Codex shell policy,
43
- installs the scoped XMux command rule, and refreshes available XMux skills
44
- under `~/.codex/skills`. Runtime-only installs do not include skill source
45
- files, so pass an external skill source when refreshing skills:
46
-
47
- ```bash
48
- xmux setup-codex --skills-dir /path/to/xmux-skills
49
- ```
50
-
51
- `XMUX_CODEX_SKILLS_DIR` provides the same source path for automation. Without
52
- `--skills-dir` or `XMUX_CODEX_SKILLS_DIR`, `setup-codex` skips skill refresh
53
- and leaves existing user-owned skills untouched.
34
+ `xmux setup-codex` registers XMux with Codex, and `xmux doctor-codex` checks
35
+ that the integration is ready.
54
36
 
55
37
  Start the Codex lead from the target project directory:
56
38
 
@@ -148,7 +130,7 @@ Runtime state is project-local:
148
130
  Runtime path environment names are now split by responsibility:
149
131
 
150
132
  ```text
151
- XMUX_INSTALL_DIR # XMux source/install directory
133
+ XMUX_INSTALL_DIR # XMux install root
152
134
  XMUX_PROJECT_DIR # project root where Codex is working
153
135
  XMUX_STATE_DIR # project-local runtime state, usually $XMUX_PROJECT_DIR/.codex/xmux
154
136
  ```
@@ -156,36 +138,25 @@ XMUX_STATE_DIR # project-local runtime state, usually $XMUX_PROJECT_DIR/.code
156
138
  Codex uses the normal user runtime under `~/.codex`. XMux does not create an
157
139
  isolated Codex home for a team, and Codex teammate mode is unsupported.
158
140
 
159
- Agent automation uses `xmux` from the Codex shell policy PATH that
160
- `xmux setup-codex` writes to `~/.codex/config.toml`. If that wrapper is
161
- unavailable, it falls back to the explicit XMux executable. The user-facing
162
- bootstrap command remains `xmux -n <session>` after setup; ad hoc local paths
163
- and shell-loading details are not part of the agent contract.
141
+ Agent automation uses the installed `xmux` command that `xmux setup-codex`
142
+ makes available to Codex. The user-facing bootstrap command remains
143
+ `xmux -n <session>` after setup.
164
144
 
165
145
  The Codex lead MCP server is `xmux_lead`. `xmux setup-codex` configures it so
166
146
  Codex can route requests, wait for teammate responses, read events, and inspect
167
147
  team status.
168
- The global MCP config is install-scoped: the MCP command is a versioned npm
169
- entrypoint launched with a project-neutral `npx --prefix`, while
170
- `XMUX_INSTALL_DIR` points at the Homebrew runtime that owns wrapper scripts,
171
- state discovery, and lifecycle. It does not pin
172
- `XMUX_PROJECT_DIR`/`XMUX_STATE_DIR`; those values come from the active
173
- `xmux -n <session>` lead runtime.
174
-
175
- Provider teammates write responses through `bridge-mcp-server.js`, using the
176
- team runtime environment prepared by XMux. The bridge and mailbox paths are
148
+ The installed `xmux` command owns the tmux runtime. The `xmux_lead` MCP server
149
+ is delivered as a versioned npm entrypoint, and Codex skills are optional
150
+ shortcuts for orchestrating that runtime. The MCP command is install-scoped and
151
+ does not pin `XMUX_PROJECT_DIR`/`XMUX_STATE_DIR`; those values come from the
152
+ active `xmux -n <session>` lead runtime.
153
+
154
+ Provider teammates write responses through `mcp/servers/bridge.js`, using the
155
+ team runtime environment prepared by XMux. The MCP and mailbox paths are
177
156
  implementation details behind Codex-led teammate orchestration.
178
157
 
179
- The explicit Codex setup installs available XMux skills under
180
- `~/.codex/skills` only from `--skills-dir` or `XMUX_CODEX_SKILLS_DIR`.
181
- Homebrew does not install Codex skills or repo-local plugin files; normal
182
- runtime operation depends on the installed `xmux` command and
183
- `XMUX_INSTALL_DIR`, not a checkout path.
184
-
185
- The plugin skill source of truth is `plugins/xmux/skills`; the top-level
186
- `skills/` directory is a mirrored distribution copy for explicit skill refresh
187
- workflows. Users explicitly invoke Codex skills with `$`, for example
188
- `$xmux-teams`. The official XMux skills cover agent-facing orchestration flows:
158
+ Users can ask for teammate work in natural language. When XMux skills are
159
+ available in Codex, the official skill shortcuts are:
189
160
 
190
161
  ```text
191
162
  $xmux-teams
@@ -196,22 +167,14 @@ $xmux-diagnosis
196
167
  $xmux-send-pane
197
168
  ```
198
169
 
199
- Development verification for agent/runtime changes:
200
-
201
- ```bash
202
- zsh -n xmux.zsh
203
- zsh -n xmux-bridge.zsh
204
- node --check scripts/setup_xmux_codex_mcp.js
205
- git diff --check
206
- ```
207
-
208
- Homebrew distribution notes live in [Homebrew distribution](docs/operations/homebrew.md).
170
+ Homebrew installation details live in [Homebrew installation](docs/operations/homebrew.md).
209
171
 
210
172
  ## Docs
211
173
 
212
174
  - [Documentation index](docs/README.md)
175
+ - [Repository layout](docs/runtime/repository-layout.md)
213
176
  - [Codex lead runtime](docs/runtime/codex-lead.md)
214
- - [Homebrew distribution](docs/operations/homebrew.md)
177
+ - [Homebrew installation](docs/operations/homebrew.md)
215
178
  - [Wrapper-first debugging](docs/operations/debugging.md)
216
179
  - [Claude teammate](docs/teammates/claude.md)
217
180
  - [Gemini teammate](docs/teammates/gemini.md)
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * bridge-mcp-server.js
3
+ * mcp/servers/bridge.js
4
4
  * Minimal MCP server for xmux.
5
5
  * Exposes write_to_lead(text, summary?) so Claude, Gemini, and Copilot
6
6
  * teammates can write directly to the XMux lead inbox.
@@ -140,7 +140,11 @@ function trimToCap(msgs, cap) {
140
140
  function mailboxInstallBases() {
141
141
  const seen = new Set();
142
142
  const bases = [];
143
- for (const candidate of [XMUX_INSTALL_DIR, __dirname]) {
143
+ const packageRoot = path.basename(__dirname) === 'servers'
144
+ && path.basename(path.dirname(__dirname)) === 'mcp'
145
+ ? path.dirname(path.dirname(__dirname))
146
+ : __dirname;
147
+ for (const candidate of [XMUX_INSTALL_DIR, packageRoot, __dirname]) {
144
148
  if (!candidate) continue;
145
149
  const resolved = path.resolve(candidate);
146
150
  if (seen.has(resolved)) continue;
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * xmux-lead-mcp-server.js
3
+ * mcp/servers/lead.js
4
4
  * Stdio-only MCP server exposing XMux lead/team mailbox tools.
5
5
  *
6
6
  * Mailbox persistence is delegated to the Node mailbox CLI.
@@ -138,7 +138,11 @@ function parseJsonOutput(stdout) {
138
138
  function mailboxInstallBases() {
139
139
  const seen = new Set();
140
140
  const bases = [];
141
- for (const candidate of [XMUX_INSTALL_DIR, __dirname]) {
141
+ const packageRoot = path.basename(__dirname) === 'servers'
142
+ && path.basename(path.dirname(__dirname)) === 'mcp'
143
+ ? path.dirname(path.dirname(__dirname))
144
+ : __dirname;
145
+ for (const candidate of [XMUX_INSTALL_DIR, packageRoot, __dirname]) {
142
146
  if (!candidate) continue;
143
147
  const resolved = path.resolve(candidate);
144
148
  if (seen.has(resolved)) continue;
@@ -28,7 +28,7 @@ function stableHomebrewXmuxInstallDir(installDir) {
28
28
 
29
29
  const prefix = resolved.split(marker, 1)[0];
30
30
  const candidate = path.join(prefix, "opt", "xmux", "libexec");
31
- if (fs.existsSync(path.join(candidate, "xmux.zsh"))) {
31
+ if (fs.existsSync(path.join(candidate, "runtime", "shell", "xmux.zsh")) || fs.existsSync(path.join(candidate, "xmux.zsh"))) {
32
32
  return candidate;
33
33
  }
34
34
  return resolved;
@@ -36,13 +36,14 @@ function stableHomebrewXmuxInstallDir(installDir) {
36
36
 
37
37
  function stableHomebrewXmuxFilePath(filePath) {
38
38
  const resolved = absolute(filePath);
39
- const installDir = path.dirname(resolved);
40
- const stableInstallDir = stableHomebrewXmuxInstallDir(installDir);
41
- if (stableInstallDir === installDir) {
42
- return resolved;
43
- }
44
-
45
- const candidate = path.join(stableInstallDir, path.basename(resolved));
39
+ const marker = `${path.sep}Cellar${path.sep}xmux${path.sep}`;
40
+ const libexecSegment = `${path.sep}libexec${path.sep}`;
41
+ const libexecIndex = resolved.indexOf(libexecSegment);
42
+ if (!resolved.includes(marker) || libexecIndex < 0) return resolved;
43
+ const prefix = resolved.split(marker, 1)[0];
44
+ const optDir = path.join(prefix, "opt", "xmux", "libexec");
45
+ const relativePath = resolved.slice(libexecIndex + libexecSegment.length);
46
+ const candidate = path.join(optDir, relativePath);
46
47
  if (fs.existsSync(candidate)) {
47
48
  return candidate;
48
49
  }
@@ -72,7 +73,7 @@ function atomicWriteJson(filePath, data) {
72
73
 
73
74
  function usage() {
74
75
  process.stderr.write(
75
- "usage: setup_claude_mcp.js <bridge_js> <project_dir> <outbox> <agent> <team> <state_dir> <install_dir>\n",
76
+ "usage: claude.js <bridge_js> <project_dir> <outbox> <agent> <team> <state_dir> <install_dir>\n",
76
77
  );
77
78
  }
78
79
 
@@ -32,26 +32,39 @@ function abs(value) {
32
32
  return path.resolve(expandUser(value));
33
33
  }
34
34
 
35
+ function xmux_runtime_shell_path(installDir) {
36
+ return path.join(abs(installDir), "runtime", "shell", "xmux.zsh");
37
+ }
38
+
39
+ function has_xmux_runtime(installDir) {
40
+ const root = abs(installDir);
41
+ return fs.existsSync(xmux_runtime_shell_path(root)) || fs.existsSync(path.join(root, "xmux.zsh"));
42
+ }
43
+
35
44
  function stable_homebrew_xmux_install_dir(xmuxInstallDir) {
36
45
  const installDir = abs(xmuxInstallDir);
37
46
  const marker = `${path.sep}Cellar${path.sep}xmux${path.sep}`;
38
47
  if (!installDir.includes(marker) || !installDir.endsWith(`${path.sep}libexec`)) {
39
48
  return installDir;
40
49
  }
41
- if (!fs.existsSync(path.join(installDir, "xmux.zsh"))) {
50
+ if (!has_xmux_runtime(installDir)) {
42
51
  return installDir;
43
52
  }
44
53
  const prefix = installDir.split(marker, 1)[0];
45
54
  const candidate = path.join(prefix, "opt", "xmux", "libexec");
46
- return fs.existsSync(path.join(candidate, "xmux.zsh")) ? candidate : installDir;
55
+ return has_xmux_runtime(candidate) ? candidate : installDir;
47
56
  }
48
57
 
49
58
  function stable_homebrew_xmux_file_path(inputPath) {
50
59
  const resolved = abs(inputPath);
51
- const installDir = path.dirname(resolved);
52
- const stableInstallDir = stable_homebrew_xmux_install_dir(installDir);
53
- if (stableInstallDir === installDir) return resolved;
54
- const candidate = path.join(stableInstallDir, path.basename(resolved));
60
+ const marker = `${path.sep}Cellar${path.sep}xmux${path.sep}`;
61
+ const libexecSegment = `${path.sep}libexec${path.sep}`;
62
+ const libexecIndex = resolved.indexOf(libexecSegment);
63
+ if (!resolved.includes(marker) || libexecIndex < 0) return resolved;
64
+ const prefix = resolved.split(marker, 1)[0];
65
+ const optDir = path.join(prefix, "opt", "xmux", "libexec");
66
+ const relativePath = resolved.slice(libexecIndex + libexecSegment.length);
67
+ const candidate = path.join(optDir, relativePath);
55
68
  return fs.existsSync(candidate) ? candidate : resolved;
56
69
  }
57
70
 
@@ -139,14 +152,15 @@ function package_spec_has_version(packageSpec) {
139
152
  }
140
153
 
141
154
  function xmux_version_from_install_dir(xmuxInstallDir) {
142
- const content = read_text(path.join(abs(xmuxInstallDir), "xmux.zsh"));
155
+ const root = abs(xmuxInstallDir);
156
+ const content = read_text(xmux_runtime_shell_path(root)) || read_text(path.join(root, "xmux.zsh"));
143
157
  const match = content.match(/^XMUX_VERSION=["']([^"']+)["']/m);
144
158
  return match ? match[1] : "";
145
159
  }
146
160
 
147
161
  function default_mcp_package_spec(xmuxInstallDir, packageName = "", packageVersion = "") {
148
162
  const installPackage = read_json(path.join(abs(xmuxInstallDir), "package.json")) || {};
149
- const scriptPackage = read_json(path.join(path.dirname(path.dirname(abs(__filename))), "package.json")) || {};
163
+ const scriptPackage = read_json(path.join(path.dirname(path.dirname(path.dirname(abs(__filename)))), "package.json")) || {};
150
164
  const name = packageName
151
165
  || process.env.XMUX_MCP_NPM_PACKAGE
152
166
  || installPackage.name
@@ -272,7 +286,7 @@ function is_xmux_runtime_bin_path(candidatePath, currentXmuxBin) {
272
286
  if (expanded === abs(currentXmuxBin)) return true;
273
287
  if (path.basename(expanded) !== "bin") return false;
274
288
  const installDir = path.dirname(expanded);
275
- if (fs.existsSync(path.join(installDir, "xmux.zsh")) && fs.existsSync(path.join(expanded, "xmux"))) {
289
+ if (has_xmux_runtime(installDir) && fs.existsSync(path.join(expanded, "xmux"))) {
276
290
  return true;
277
291
  }
278
292
  if (path.basename(installDir) !== "libexec") return false;
@@ -419,7 +433,7 @@ function install_xmux_command_rule(configPath) {
419
433
  let content = remove_marker_block(read_text(filePath), RULE_BEGIN, RULE_END);
420
434
  const block = [
421
435
  RULE_BEGIN,
422
- "# Allow the scoped XMux wrapper command; XMux skills still control operation scope.",
436
+ "# Allow the scoped XMux wrapper command; user intent and XMux wrappers control operation scope.",
423
437
  'prefix_rule(pattern=["xmux"], decision="allow")',
424
438
  RULE_END,
425
439
  ].join("\n");
@@ -568,12 +582,12 @@ function _xmux_lead_mcp_processes_from_ps(psOutput) {
568
582
  const processes = [];
569
583
  for (const rawLine of String(psOutput || "").split(/\r?\n/)) {
570
584
  const stripped = rawLine.trim();
571
- if (!stripped.includes("xmux-lead-mcp-server.js")) continue;
585
+ if (!stripped.includes("mcp/servers/lead.js") && !stripped.includes("xmux-lead-mcp-server.js")) continue;
572
586
  const match = stripped.match(/^(\d+)\s+(.*)$/);
573
587
  if (!match) continue;
574
588
  const [, pid, command] = match;
575
589
  const tokens = splitShellWords(command.trim());
576
- const serverPath = tokens.find((token) => token.endsWith("xmux-lead-mcp-server.js")) || "";
590
+ const serverPath = tokens.find((token) => token.endsWith("mcp/servers/lead.js") || token.endsWith("xmux-lead-mcp-server.js")) || "";
577
591
  if (!serverPath) continue;
578
592
  processes.push({ pid, command: command.trim(), server_path: abs(serverPath) });
579
593
  }
@@ -591,7 +605,7 @@ function running_xmux_lead_mcp_processes() {
591
605
 
592
606
  function _is_homebrew_xmux_mcp_server(serverPath) {
593
607
  const normalized = abs(serverPath);
594
- return normalized.endsWith("xmux-lead-mcp-server.js")
608
+ return (normalized.endsWith(`${path.sep}mcp${path.sep}servers${path.sep}lead.js`) || normalized.endsWith("xmux-lead-mcp-server.js"))
595
609
  && normalized.includes(`${path.sep}Cellar${path.sep}xmux${path.sep}`)
596
610
  && normalized.includes(`${path.sep}libexec${path.sep}`);
597
611
  }
@@ -636,7 +650,7 @@ function doctor_codex(configPath, xmuxInstallDir, mcpConfigOrServerPath, skillsD
636
650
  } else if (installedNames.size) {
637
651
  notes.push(["OK", `XMux Codex skills installed under ${skills_root(configPath)}`]);
638
652
  } else {
639
- notes.push(["WARN", "no XMux skill source directory found; pass --skills-dir or set XMUX_CODEX_SKILLS_DIR"]);
653
+ notes.push(["OK", "optional XMux skills are not configured"]);
640
654
  }
641
655
 
642
656
  if (fs.existsSync(plugin_cache_path(configPath))) {
@@ -748,7 +762,7 @@ function main(argv = process.argv.slice(2)) {
748
762
  const opts = parse_args(argv);
749
763
  const configPath = resolve_config_path(opts);
750
764
  opts.mcp_npx_prefix = abs(opts.mcp_npx_prefix || process.env.XMUX_MCP_NPX_PREFIX || default_mcp_npx_prefix(configPath));
751
- const scriptInstallDir = path.dirname(path.dirname(abs(__filename)));
765
+ const scriptInstallDir = path.dirname(path.dirname(path.dirname(abs(__filename))));
752
766
  const rawInstallDir = abs(opts.xmux_install_dir || scriptInstallDir);
753
767
  const xmuxInstallDir = stable_homebrew_xmux_install_dir(rawInstallDir);
754
768
  const xmuxProjectDir = abs(opts.xmux_project_dir || default_xmux_project_dir());
@@ -795,7 +809,9 @@ function main(argv = process.argv.slice(2)) {
795
809
  console.log(" xmux_project_dir: inherited from xmux-launched Codex runtime");
796
810
  console.log(" xmux_state_dir: inherited from xmux-launched Codex runtime");
797
811
  if (installedSkills.length) console.log(` skills: ${installedSkills.join(", ")}`);
798
- else if (opts.install_skills) console.log(" skills: skipped; pass --skills-dir or set XMUX_CODEX_SKILLS_DIR");
812
+ else if (opts.install_skills && (opts.skills_dir || process.env.XMUX_CODEX_SKILLS_DIR)) {
813
+ console.log(" skills: no importable XMux skills found");
814
+ }
799
815
  console.log(" plugin_cache: disabled; stale XMux plugin cache removed if present");
800
816
  return 0;
801
817
  }
@@ -18,16 +18,15 @@ const TOOLS = ["write_to_lead"];
18
18
 
19
19
  function stableHomebrewXmuxFilePath(inputPath) {
20
20
  const resolved = path.resolve(inputPath.replace(/^~(?=$|\/)/, os.homedir()));
21
- const installDir = path.dirname(resolved);
22
21
  const marker = `${path.sep}Cellar${path.sep}xmux${path.sep}`;
23
- if (!installDir.includes(marker) || !installDir.endsWith(`${path.sep}libexec`)) {
24
- return resolved;
25
- }
26
-
27
- const prefix = installDir.split(marker, 1)[0];
22
+ const libexecSegment = `${path.sep}libexec${path.sep}`;
23
+ const libexecIndex = resolved.indexOf(libexecSegment);
24
+ if (!resolved.includes(marker) || libexecIndex < 0) return resolved;
25
+ const prefix = resolved.split(marker, 1)[0];
28
26
  const optDir = path.join(prefix, "opt", "xmux", "libexec");
29
- const candidate = path.join(optDir, path.basename(resolved));
30
- if (fs.existsSync(path.join(optDir, "xmux.zsh")) && fs.existsSync(candidate)) {
27
+ const relativePath = resolved.slice(libexecIndex + libexecSegment.length);
28
+ const candidate = path.join(optDir, relativePath);
29
+ if ((fs.existsSync(path.join(optDir, "runtime", "shell", "xmux.zsh")) || fs.existsSync(path.join(optDir, "xmux.zsh"))) && fs.existsSync(candidate)) {
31
30
  return candidate;
32
31
  }
33
32
  return resolved;
@@ -18,16 +18,15 @@ const NPM_PIN = "xmux-bridge@^1.3.0";
18
18
 
19
19
  function stableHomebrewXmuxFilePath(inputPath) {
20
20
  const resolved = path.resolve(inputPath.replace(/^~(?=$|\/)/, os.homedir()));
21
- const installDir = path.dirname(resolved);
22
21
  const marker = `${path.sep}Cellar${path.sep}xmux${path.sep}`;
23
- if (!installDir.includes(marker) || !installDir.endsWith(`${path.sep}libexec`)) {
24
- return resolved;
25
- }
26
-
27
- const prefix = installDir.split(marker, 1)[0];
22
+ const libexecSegment = `${path.sep}libexec${path.sep}`;
23
+ const libexecIndex = resolved.indexOf(libexecSegment);
24
+ if (!resolved.includes(marker) || libexecIndex < 0) return resolved;
25
+ const prefix = resolved.split(marker, 1)[0];
28
26
  const optDir = path.join(prefix, "opt", "xmux", "libexec");
29
- const candidate = path.join(optDir, path.basename(resolved));
30
- if (fs.existsSync(path.join(optDir, "xmux.zsh")) && fs.existsSync(candidate)) {
27
+ const relativePath = resolved.slice(libexecIndex + libexecSegment.length);
28
+ const candidate = path.join(optDir, relativePath);
29
+ if ((fs.existsSync(path.join(optDir, "runtime", "shell", "xmux.zsh")) || fs.existsSync(path.join(optDir, "xmux.zsh"))) && fs.existsSync(candidate)) {
31
30
  return candidate;
32
31
  }
33
32
  return resolved;
package/package.json CHANGED
@@ -1,21 +1,15 @@
1
1
  {
2
2
  "name": "xmux-bridge",
3
- "version": "1.0.40",
4
- "description": "MCP stdio server for XMux teammate responses",
3
+ "version": "1.0.41",
4
+ "description": "MCP bridge and lead server package for XMux",
5
5
  "bin": {
6
- "xmux-bridge": "./bridge-mcp-server.js",
7
- "xmux-lead-mcp": "./xmux-lead-mcp-server.js",
8
- "xmux-mailbox": "./dist/bin/xmux-mailbox.js",
9
- "xmux": "./bin/xmux",
10
- "xmux-bridge-relay": "./xmux-bridge.zsh"
6
+ "xmux-lead-mcp": "./mcp/servers/lead.js",
7
+ "xmux-bridge": "./mcp/servers/bridge.js",
8
+ "xmux-mailbox": "./dist/bin/xmux-mailbox.js"
11
9
  },
12
10
  "files": [
13
- "bridge-mcp-server.js",
14
- "xmux-lead-mcp-server.js",
15
- "xmux-bridge.zsh",
16
- "bin/xmux",
17
- "xmux.zsh",
18
- "scripts/*.js",
11
+ "mcp/servers",
12
+ "mcp/setup",
19
13
  "dist/bin/xmux-mailbox.js",
20
14
  "dist/mailbox",
21
15
  "src/runtime",
package/bin/xmux DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env zsh
2
- set -euo pipefail
3
-
4
- script_path="${0:A}"
5
- script_dir="${script_path:h}"
6
- install_dir="${script_dir:h}"
7
-
8
- source "$install_dir/xmux.zsh"
9
- xmux "$@"
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- const fs = require("node:fs");
5
- const os = require("node:os");
6
- const path = require("node:path");
7
-
8
- const TOML_PATH = path.join(os.homedir(), ".codex", "config.toml");
9
-
10
- function usage() {
11
- process.stderr.write("usage: trust_codex_project.js <path>\n");
12
- }
13
-
14
- function main(argv = process.argv.slice(2)) {
15
- if (argv.length !== 1) {
16
- usage();
17
- return 1;
18
- }
19
-
20
- const projectPath = fs.realpathSync(path.resolve(argv[0]));
21
- const section = `[projects."${projectPath}"]`;
22
- let content = "";
23
- if (fs.existsSync(TOML_PATH)) {
24
- content = fs.readFileSync(TOML_PATH, "utf-8");
25
- }
26
-
27
- if (content.includes(section)) {
28
- return 0;
29
- }
30
-
31
- const entry = `${section}\ntrust_level = "trusted"\n`;
32
- fs.mkdirSync(path.dirname(TOML_PATH), { recursive: true });
33
- if (content && !content.endsWith("\n")) {
34
- content += "\n";
35
- }
36
- fs.writeFileSync(TOML_PATH, `${content}\n${entry}`, "utf-8");
37
- return 0;
38
- }
39
-
40
- if (require.main === module) {
41
- process.exitCode = main();
42
- }
43
-
44
- module.exports = { main };
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- const fs = require("node:fs");
5
- const os = require("node:os");
6
- const path = require("node:path");
7
-
8
- const FILE_PATH = path.join(os.homedir(), ".copilot", "config.json");
9
-
10
- function usage() {
11
- process.stderr.write("usage: trust_copilot_project.js <path>\n");
12
- }
13
-
14
- function main(argv = process.argv.slice(2)) {
15
- if (argv.length !== 1) {
16
- usage();
17
- return 1;
18
- }
19
-
20
- const projectPath = fs.realpathSync(path.resolve(argv[0]));
21
- let data = {};
22
- if (fs.existsSync(FILE_PATH)) {
23
- try {
24
- const parsed = JSON.parse(fs.readFileSync(FILE_PATH, "utf-8"));
25
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
26
- data = parsed;
27
- }
28
- } catch {
29
- data = {};
30
- }
31
- }
32
-
33
- const folders = Array.isArray(data.trusted_folders) ? data.trusted_folders : [];
34
- if (folders.includes(projectPath)) {
35
- return 0;
36
- }
37
-
38
- folders.push(projectPath);
39
- data.trusted_folders = folders;
40
- fs.mkdirSync(path.dirname(FILE_PATH), { recursive: true });
41
- fs.writeFileSync(FILE_PATH, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
42
- return 0;
43
- }
44
-
45
- if (require.main === module) {
46
- process.exitCode = main();
47
- }
48
-
49
- module.exports = { main };
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- const fs = require("node:fs");
5
- const os = require("node:os");
6
- const path = require("node:path");
7
-
8
- const FILE_PATH = path.join(os.homedir(), ".gemini", "trustedFolders.json");
9
-
10
- function usage() {
11
- process.stderr.write("usage: trust_gemini_project.js <path>\n");
12
- }
13
-
14
- function main(argv = process.argv.slice(2)) {
15
- if (argv.length !== 1) {
16
- usage();
17
- return 1;
18
- }
19
-
20
- const projectPath = fs.realpathSync(path.resolve(argv[0]));
21
- let data = {};
22
- if (fs.existsSync(FILE_PATH)) {
23
- try {
24
- const parsed = JSON.parse(fs.readFileSync(FILE_PATH, "utf-8"));
25
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
26
- data = parsed;
27
- }
28
- } catch {
29
- data = {};
30
- }
31
- }
32
-
33
- if (data[projectPath] === "TRUST_FOLDER") {
34
- return 0;
35
- }
36
-
37
- data[projectPath] = "TRUST_FOLDER";
38
- fs.mkdirSync(path.dirname(FILE_PATH), { recursive: true });
39
- fs.writeFileSync(FILE_PATH, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
40
- return 0;
41
- }
42
-
43
- if (require.main === module) {
44
- process.exitCode = main();
45
- }
46
-
47
- module.exports = { main };