@libtmux/workspace-cli 0.1.0-alpha.11 → 0.1.0-alpha.13

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
@@ -1,24 +1,71 @@
1
+ <!-- libtmux-logo -->
2
+ <div align="center">
3
+ <picture>
4
+ <source srcset="https://raw.githubusercontent.com/libtmux/libtmux-ts/HEAD/packages/workspace-cli/assets/logo.svg" type="image/svg+xml">
5
+ <img src="https://raw.githubusercontent.com/libtmux/libtmux-ts/HEAD/packages/workspace-cli/assets/logo.png" width="128" height="128" alt="libtmux for TypeScript workspace">
6
+ </picture>
7
+ </div>
8
+ <!-- /libtmux-logo -->
9
+
10
+ <div align="center">
11
+
1
12
  # Workspace CLI
2
13
 
3
14
  Manage tmux workspaces from YAML and JSON with Node.js 22.12+ or Bun 1.3.14+.
4
- This local implementation is in development.
15
+ `tmux-workspace` loads, captures, converts and imports tmuxp workspace files.
16
+ This implementation is in development.
5
17
 
6
- ## Build
18
+ </div>
7
19
 
8
- Run from the repository root:
20
+ ## Install
21
+
22
+ Run the command without installing it. With Node:
9
23
 
10
24
  ```console
11
- $ bun run --cwd packages/libtmux build
25
+ $ npx -y @libtmux/workspace-cli@0.1.0-alpha.13 --help
12
26
  ```
13
27
 
28
+ With Bun. The command names `node` in its shebang, so `bunx` runs it on Node
29
+ when Node is installed; `--bun` runs it on Bun:
30
+
14
31
  ```console
15
- $ bun run --cwd packages/workspace-cli build
32
+ $ bunx --bun @libtmux/workspace-cli@0.1.0-alpha.13 --help
16
33
  ```
17
34
 
35
+ With pnpm:
36
+
18
37
  ```console
19
- $ node packages/workspace-cli/dist/main.js --help
38
+ $ pnpm dlx @libtmux/workspace-cli@0.1.0-alpha.13 --help
39
+ ```
40
+
41
+ With Yarn. Yarn refuses a release younger than its `npmMinimalAgeGate`, one
42
+ day by default:
43
+
44
+ ```console
45
+ $ yarn dlx @libtmux/workspace-cli@0.1.0-alpha.13 --help
46
+ ```
47
+
48
+ Or install it globally, which puts `tmux-workspace` on `PATH`. With npm:
49
+
50
+ ```console
51
+ $ npm install --global @libtmux/workspace-cli@0.1.0-alpha.13
20
52
  ```
21
53
 
54
+ With pnpm:
55
+
56
+ ```console
57
+ $ pnpm add --global @libtmux/workspace-cli@0.1.0-alpha.13
58
+ ```
59
+
60
+ With Bun:
61
+
62
+ ```console
63
+ $ bun add --global @libtmux/workspace-cli@0.1.0-alpha.13
64
+ ```
65
+
66
+ The rest of this page runs the installed `tmux-workspace`. A runner passes
67
+ the same arguments to the command when they follow the package name.
68
+
22
69
  ## Load and capture
23
70
 
24
71
  Save this document as `workspace.yaml`:
@@ -36,7 +83,7 @@ windows:
36
83
  Load on a separate tmux socket:
37
84
 
38
85
  ```console
39
- $ node packages/workspace-cli/dist/main.js load ./workspace.yaml \
86
+ $ tmux-workspace load ./workspace.yaml \
40
87
  -L workspace-cli-demo \
41
88
  -d \
42
89
  --json
@@ -45,7 +92,7 @@ $ node packages/workspace-cli/dist/main.js load ./workspace.yaml \
45
92
  Capture its live topology:
46
93
 
47
94
  ```console
48
- $ node packages/workspace-cli/dist/main.js freeze dev \
95
+ $ tmux-workspace freeze dev \
49
96
  -L workspace-cli-demo \
50
97
  --json
51
98
  ```
@@ -126,17 +173,22 @@ lists and blank builder names still use native validation.
126
173
  ## Inspect a workspace through MCP
127
174
 
128
175
  The separate [MCP server](../mcp/README.md) inspects loaded workspaces on the
129
- same tmux socket. Build it from the repository root:
130
-
131
- ```console
132
- $ bun run --cwd packages/mcp build
176
+ same tmux socket. After the detached load above, add it to your MCP client with
177
+ that socket and the `inspect` toolset:
178
+
179
+ ```json
180
+ {
181
+ "mcpServers": {
182
+ "tmux": {
183
+ "command": "npx",
184
+ "args": ["-y", "@libtmux/mcp@0.1.0-alpha.13"],
185
+ "env": { "LIBTMUX_SOCKET": "workspace-cli-demo", "LIBTMUX_TOOLSETS": "inspect" }
186
+ }
187
+ }
188
+ }
133
189
  ```
134
190
 
135
- After the detached load above, configure your MCP client to launch `node` with
136
- the built `packages/mcp/dist/server.js` as its argument. Use an absolute program
137
- path if the client starts outside this repository. Set `LIBTMUX_SOCKET` to
138
- `workspace-cli-demo` and `LIBTMUX_TOOLSETS` to `inspect` in that subprocess's
139
- environment. The socket is selected when the MCP server starts.
191
+ The socket is selected when the MCP server starts.
140
192
 
141
193
  For a workspace loaded with `-S`, set `LIBTMUX_SOCKET_PATH` to the same absolute
142
194
  socket path instead of `LIBTMUX_SOCKET`. If the CLI uses `TMUX_BIN`, select that
@@ -287,7 +339,7 @@ their completion scope.
287
339
  Completion is tested on Linux with Bash 5.2, Zsh 5.9, and fish 4.8. Bash 3.2 is
288
340
  a syntax target; older shells and filenames containing newlines remain unverified.
289
341
 
290
- After installing the local package, load the script for your shell. Bash:
342
+ With `tmux-workspace` on `PATH`, load the script for your shell. Bash:
291
343
 
292
344
  ```console
293
345
  $ source <(tmux-workspace completion bash)
@@ -307,6 +359,22 @@ $ tmux-workspace completion fish | source
307
359
 
308
360
  For automation, `--json` and `--ndjson` wrap the script in a structured result.
309
361
 
362
+ ## Build from source
363
+
364
+ Run from the repository root:
365
+
366
+ ```console
367
+ $ bun run --cwd packages/libtmux build
368
+ ```
369
+
370
+ ```console
371
+ $ bun run --cwd packages/workspace-cli build
372
+ ```
373
+
374
+ ```console
375
+ $ node packages/workspace-cli/dist/main.js --help
376
+ ```
377
+
310
378
  ## Development status
311
379
 
312
380
  Native discovery, conversion, imports, common searches, detached load, append,
@@ -4,14 +4,14 @@
4
4
  into `dist/` and their license terms are reproduced here in full, as those
5
5
  terms require. `libtmux` is not bundled and carries its own notice.
6
6
 
7
- ## ansi-regex 5.0.1
7
+ ## ansi-regex 6.4.0
8
8
 
9
9
  License: MIT
10
10
 
11
11
  ```text
12
12
  MIT License
13
13
 
14
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
14
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
15
15
 
16
16
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
17
17
 
@@ -81,7 +81,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
81
81
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
82
82
  ```
83
83
 
84
- ## get-east-asian-width 1.6.0
84
+ ## get-east-asian-width 1.7.0
85
85
 
86
86
  License: MIT
87
87
 
@@ -113,7 +113,7 @@ The above copyright notice and this permission notice shall be included in all c
113
113
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
114
114
  ```
115
115
 
116
- ## slice-ansi 9.0.0
116
+ ## slice-ansi 9.0.1
117
117
 
118
118
  License: MIT
119
119
 
@@ -130,7 +130,7 @@ The above copyright notice and this permission notice shall be included in all c
130
130
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
131
131
  ```
132
132
 
133
- ## string-width 8.2.2
133
+ ## string-width 8.3.0
134
134
 
135
135
  License: MIT
136
136
 
@@ -162,7 +162,7 @@ The above copyright notice and this permission notice shall be included in all c
162
162
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
163
163
  ```
164
164
 
165
- ## yaml 2.9.0
165
+ ## yaml 2.9.1
166
166
 
167
167
  License: ISC
168
168
 
Binary file
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 135.46667 135.46666" role="img" aria-label="libtmux for TypeScript — workspace CLI" class="libtmux-logo" data-language="typescript" data-variant="workspace" focusable="false"><title>libtmux for TypeScript — workspace CLI</title><g transform="translate(-210.28959,-409.98108)" data-part="artwork"><path d="m 334.66493,533.88598 v 11.56176 h 3.76501 c 4.04619,2.1e-4 7.32623,-3.28012 7.32632,-7.32631 v -4.23545 z" fill="#333333" data-part="base-edge"></path><g transform="matrix(1.024,0,0,1.024,-5.0469422,-9.8395302)" data-part="primary-tile"><path d="M 227.78906,0 213.98242,3.6992188 V 460.62109 H 241.4082 V 15.564453 Z" transform="matrix(0.26458333,0,0,0.26458333,210.28959,409.98108)" fill="#004687" data-part="primary-edge"></path><path d="m 210.28981,417.13553 v 113.86425 l 60.26885,2.60089 V 409.98109 h -53.11441 c -3.95129,0 -7.15444,3.20315 -7.15444,7.15444 z" fill="#3178C6" data-part="primary"></path></g><g transform="matrix(1.024,0,0,1.024,-5.0469422,-9.8395302)" data-part="lower-tile"><path d="m 486.38086,246.03906 -5.24805,4.99805 v 207.2207 l 5.24805,-0.93164 L 500,465.18945 V 261.60352 Z" transform="matrix(0.26458333,0,0,0.26458333,210.28959,409.98108)" fill="#001E40" data-part="lower-edge"></path><path d="m 278.70874,475.07917 v 64.8875 l 60.26883,-8.98455 v -55.90295 z" fill="#01417D" data-part="lower"></path></g><path d="m 210.28959,533.88598 v 4.23545 c 9e-5,4.04619 3.28012,7.32651 7.32631,7.32631 h 117.12417 c 4.04619,2e-4 7.32621,-3.28012 7.32631,-7.32631 v -4.23545 z" fill="#231F20" data-part="base"></path><g transform="matrix(1.024,0,0,1.024,-5.0469422,-9.8395302)" data-part="upper-tile"><path d="m 459.33984,0 -25.33593,2.1074219 h 21.38281 c 14.93397,0 27.04101,12.1070061 27.04101,27.0410161 l 1.51727,183.649512 2.43542,2.38046 -1.84468,1.91057 15.46424,13.65284 L 500,42.603516 C 499.99913,8.8176763 474.27408,-6.8031496e-4 459.33984,0 Z" transform="matrix(0.26458333,0,0,0.26458333,210.28959,409.98108)" fill="#5A85B8" data-part="upper-side"></path><path d="m 331.82331,409.98109 h -53.11442 v 56.93261 h 60.26885 v -49.77817 c 0,-3.95129 -3.20315,-7.15444 -7.15443,-7.15444 z" fill="#7FB1EC" data-part="upper"></path><path d="m 278.7089,466.9137 h 60.26885 l 3.6035,4.11782 h -60.26932 z" fill="#4973A5" data-part="upper-bottom"></path></g></g></svg>
@@ -1,9 +1,12 @@
1
+ import {
2
+ requireSupportedTmux
3
+ } from "./main-wxsb2mch.js";
1
4
  import {
2
5
  expand,
3
6
  normalize,
4
7
  processRun,
5
8
  tokenize
6
- } from "./main-c8atq2pj.js";
9
+ } from "./main-04s13z6x.js";
7
10
  import {
8
11
  CliError,
9
12
  OperationOutput,
@@ -21,18 +24,19 @@ import {
21
24
  sequence,
22
25
  styled,
23
26
  write
24
- } from "./main-gh3pafqb.js";
27
+ } from "./main-gky86mgf.js";
25
28
  import {
26
29
  CommanderError,
27
30
  createParser,
28
31
  package_default
29
- } from "./main-bfnr2nkj.js";
32
+ } from "./main-fv0q4s30.js";
30
33
  import {
31
34
  __require
32
- } from "./main-1de529jm.js";
35
+ } from "./main-p4mbtvt8.js";
33
36
 
34
37
  // src/app.ts
35
38
  import { basename, dirname, extname, join as join2, resolve as resolve3 } from "node:path";
39
+ import { VersionTooLowError } from "libtmux";
36
40
 
37
41
  // src/imports.ts
38
42
  import { join, resolve } from "node:path";
@@ -319,6 +323,7 @@ async function search(values, context) {
319
323
 
320
324
  // src/commands.ts
321
325
  import { platform, release } from "node:os";
326
+ import { Server } from "libtmux";
322
327
  function tty(context) {
323
328
  return Boolean(context.stdin.isTTY);
324
329
  }
@@ -402,6 +407,10 @@ async function shell(request, context) {
402
407
  throw error;
403
408
  throw new CliError("script_failed", "The Python bridge requires tmuxp 1.74.0; set TMUX_WORKSPACE_PYTHON to its interpreter");
404
409
  }
410
+ await requireSupportedTmux(new Server({
411
+ environment: context.env,
412
+ ...typeof request.values.socket_path === "string" && request.values.socket_path ? { socketPath: request.values.socket_path } : typeof request.values.socket_name === "string" && request.values.socket_name ? { socketName: request.values.socket_name } : {}
413
+ }), context);
405
414
  const args = [
406
415
  python,
407
416
  "-u",
@@ -593,7 +602,7 @@ async function run(argv, context) {
593
602
  return 0;
594
603
  }
595
604
  if (request.command === "load" || request.command === "freeze") {
596
- const operation = (await import("./tmux-wa2zn8z1.js"))[request.command];
605
+ const operation = (await import("./tmux-2bj9awev.js"))[request.command];
597
606
  context.signal?.throwIfAborted();
598
607
  return await operation(request, context);
599
608
  }
@@ -605,8 +614,8 @@ async function run(argv, context) {
605
614
  return await shell(request, context);
606
615
  if (request.command === "completion") {
607
616
  const [{ commandCatalog }, { completionScript }] = await Promise.all([
608
- import("./reference-ebfxh6yp.js"),
609
- import("./completions-2a9fqwq3.js")
617
+ import("./reference-3kbd1xpz.js"),
618
+ import("./completions-n0m971c2.js")
610
619
  ]);
611
620
  const shell2 = request.values.shell;
612
621
  const script = completionScript(commandCatalog(parser), shell2);
@@ -723,7 +732,7 @@ async function run(argv, context) {
723
732
  if (context.signal?.aborted)
724
733
  return 130;
725
734
  const usage = error instanceof CommanderError;
726
- const code = usage ? "usage" : error instanceof CliError ? error.code : "tmux_failed";
735
+ const code = usage ? "usage" : error instanceof CliError ? error.code : error instanceof VersionTooLowError ? "tmux_unsupported" : "tmux_failed";
727
736
  const message = usage ? parserError.trim() || error.message : error instanceof Error ? error.message : String(error);
728
737
  try {
729
738
  await report(code, message);
@@ -1,4 +1,4 @@
1
- import"./main-1de529jm.js";
1
+ import"./main-p4mbtvt8.js";
2
2
 
3
3
  // src/completions.ts
4
4
  var quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
@@ -1,19 +1,23 @@
1
+ import {
2
+ requireSupportedTmux
3
+ } from "./main-wxsb2mch.js";
1
4
  import {
2
5
  expand,
3
6
  normalize,
4
7
  processRun,
5
8
  workspaceName
6
- } from "./main-c8atq2pj.js";
9
+ } from "./main-04s13z6x.js";
7
10
  import {
8
11
  CliError,
9
12
  privatePath,
10
13
  write
11
- } from "./main-gh3pafqb.js";
12
- import"./main-1de529jm.js";
14
+ } from "./main-gky86mgf.js";
15
+ import"./main-p4mbtvt8.js";
13
16
 
14
17
  // src/extensions.ts
15
18
  import {
16
- TmuxCommandError
19
+ TmuxCommandError,
20
+ VersionTooLowError
17
21
  } from "libtmux";
18
22
  import { constants } from "node:fs";
19
23
  import { mkdtemp, open, rm, stat } from "node:fs/promises";
@@ -170,18 +174,21 @@ async function sessionHint(path) {
170
174
  function sameDaemon(left, right) {
171
175
  return left.pid === right.pid && left.startTime === right.startTime;
172
176
  }
173
- async function baseline(server, signal) {
177
+ async function baseline(server, context) {
178
+ const signal = context.signal;
174
179
  try {
175
180
  await server.cmd("list-sessions", [], signal ? { signal } : {});
176
181
  } catch (error) {
177
- if (error instanceof TmuxCommandError && error.exitCode === 1 && !error.stdout.length && error.stderr.length === 1 && /^(?:no server running on .+|error connecting to .+ \((?:No such file or directory|Connection refused)\))$/.test(error.stderr[0]))
182
+ if (error instanceof TmuxCommandError && error.exitCode === 1 && !error.stdout.length && error.stderr.length === 1 && /^(?:no server running on .+|error connecting to .+ \((?:No such file or directory|Connection refused)\))$/.test(error.stderr[0])) {
183
+ await requireSupportedTmux(server, context);
178
184
  return;
185
+ }
179
186
  throw error;
180
187
  }
181
188
  return server.snapshot(signal ? { signal } : {});
182
189
  }
183
190
  async function buildExtension(python, spec, source, server, context, output, result, borrowed) {
184
- const before = await baseline(server, context.signal);
191
+ const before = await baseline(server, context);
185
192
  if (borrowed && (!before || !sameDaemon(borrowed.daemon, before.daemonIdentity) || !before.sessions.toArray().some((session2) => session2.id === borrowed.session.id)))
186
193
  throw new CliError("tmux_failed", "The authenticated append session or daemon changed");
187
194
  const existing = !borrowed && before?.sessions.toArray().find((session2) => session2.name === spec.name);
@@ -250,7 +257,7 @@ async function buildExtension(python, spec, source, server, context, output, res
250
257
  result.session_name = session.name ?? spec.name;
251
258
  } catch (error) {
252
259
  result.observation_error = error instanceof Error ? error.message : String(error);
253
- failed ??= new CliError("tmux_failed", result.observation_error);
260
+ failed ??= new CliError(error instanceof VersionTooLowError ? "tmux_unsupported" : "tmux_failed", result.observation_error);
254
261
  }
255
262
  if (failed !== undefined)
256
263
  throw failed;