tabctl 0.5.3 → 0.6.0-alpha.10
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 +135 -35
- package/dist/extension/background.js +179 -3155
- package/dist/extension/lib/content.js +0 -115
- package/dist/extension/lib/screenshot.js +0 -93
- package/dist/extension/manifest.json +2 -2
- package/package.json +13 -5
- package/dist/cli/lib/args.js +0 -141
- package/dist/cli/lib/client.js +0 -83
- package/dist/cli/lib/commands/doctor.js +0 -134
- package/dist/cli/lib/commands/index.js +0 -51
- package/dist/cli/lib/commands/list.js +0 -159
- package/dist/cli/lib/commands/meta.js +0 -229
- package/dist/cli/lib/commands/params-groups.js +0 -48
- package/dist/cli/lib/commands/params-move.js +0 -44
- package/dist/cli/lib/commands/params.js +0 -314
- package/dist/cli/lib/commands/profile.js +0 -91
- package/dist/cli/lib/commands/setup.js +0 -294
- package/dist/cli/lib/constants.js +0 -30
- package/dist/cli/lib/help.js +0 -205
- package/dist/cli/lib/options-commands.js +0 -274
- package/dist/cli/lib/options-groups.js +0 -41
- package/dist/cli/lib/options.js +0 -125
- package/dist/cli/lib/output.js +0 -147
- package/dist/cli/lib/pagination.js +0 -55
- package/dist/cli/lib/policy-filter.js +0 -202
- package/dist/cli/lib/policy.js +0 -91
- package/dist/cli/lib/report.js +0 -61
- package/dist/cli/lib/response.js +0 -235
- package/dist/cli/lib/scope.js +0 -250
- package/dist/cli/lib/snapshot.js +0 -216
- package/dist/cli/lib/types.js +0 -2
- package/dist/cli/tabctl.js +0 -475
- package/dist/extension/lib/archive.js +0 -444
- package/dist/extension/lib/deps.js +0 -4
- package/dist/extension/lib/groups.js +0 -529
- package/dist/extension/lib/inspect.js +0 -252
- package/dist/extension/lib/move.js +0 -342
- package/dist/extension/lib/tabs.js +0 -456
- package/dist/extension/lib/undo-handlers.js +0 -447
- package/dist/host/host.bundle.js +0 -670
- package/dist/host/host.js +0 -143
- package/dist/host/host.sh +0 -5
- package/dist/host/launcher/go.mod +0 -3
- package/dist/host/launcher/main.go +0 -109
- package/dist/host/lib/handlers.js +0 -327
- package/dist/host/lib/undo.js +0 -60
- package/dist/shared/config.js +0 -134
- package/dist/shared/extension-sync.js +0 -170
- package/dist/shared/profiles.js +0 -78
- package/dist/shared/version.js +0 -8
- package/dist/shared/wrapper-health.js +0 -132
package/README.md
CHANGED
|
@@ -7,13 +7,21 @@ A command-line instrument for browser tab orchestration — list, search, group,
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
11
|
-
tabctl setup --browser chrome
|
|
12
|
-
# Load the extension:
|
|
10
|
+
mise use -g github:ekroon/tabctl # install the tabctl binary
|
|
11
|
+
tabctl setup --browser edge --extension-id <id> # or: --browser chrome --extension-id <id>
|
|
12
|
+
# Load the extension: edge://extensions → Developer mode → Load unpacked → paste: ~/.local/state/tabctl/extension/
|
|
13
13
|
tabctl ping
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
If it pings back, the wire is live. You're connected.
|
|
16
|
+
Setup writes the wrapper script, native messaging manifest, and registers the profile in one step. Works on macOS, Linux, and Windows. If it pings back, the wire is live. You're connected.
|
|
17
|
+
|
|
18
|
+
### Alternative: build from source
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cargo install --path rust/crates/tabctl
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> **Legacy:** `npm install -g tabctl` still works for the Node.js-based distribution but is no longer the primary install method. No Node.js or Go is required at runtime — the single `tabctl` binary handles everything.
|
|
17
25
|
|
|
18
26
|
## Agent Skill
|
|
19
27
|
|
|
@@ -54,28 +62,44 @@ When tabctl is installed as a skill, your agent sees what you see. Just talk to
|
|
|
54
62
|
|
|
55
63
|
---
|
|
56
64
|
|
|
57
|
-
`tabctl`
|
|
65
|
+
`tabctl` is a single Rust binary that serves as both the CLI and the native messaging host. The CLI sends commands over a Unix socket (or named pipe on Windows) to the host, which proxies them to the browser extension via native messaging. The `tabctl host` subcommand is the native messaging entry point — invoked automatically by the browser, not manually.
|
|
58
66
|
|
|
59
67
|
This repo contains:
|
|
60
|
-
- Chrome/Edge extension (
|
|
61
|
-
-
|
|
62
|
-
-
|
|
68
|
+
- Chrome/Edge extension (`src/extension/`, the only TypeScript component)
|
|
69
|
+
- Rust workspace (`rust/crates/*`) — single `tabctl` binary for CLI + host + shared runtime
|
|
70
|
+
- Node packaging/build scripts for distribution (legacy)
|
|
63
71
|
|
|
64
72
|
## Quick Start
|
|
65
73
|
|
|
66
74
|
### 1. Build and install
|
|
67
75
|
|
|
76
|
+
```bash
|
|
77
|
+
cargo install --path rust/crates/tabctl # puts tabctl on your PATH
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For development with the full build pipeline (extension + Rust):
|
|
81
|
+
|
|
68
82
|
```bash
|
|
69
83
|
npm install
|
|
70
84
|
npm run build
|
|
71
|
-
npm link # puts tabctl on your PATH
|
|
72
85
|
```
|
|
73
86
|
|
|
74
|
-
|
|
87
|
+
Local development shortcuts are available via `Makefile`:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
make dev-up BROWSER=edge PROFILE=edge
|
|
91
|
+
make dev-run PROFILE=edge CMD="list --all --json"
|
|
92
|
+
make dev-run-release-like PROFILE=edge CMD="list --all --json"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
If `npm` is not on PATH in your shell, override it per command:
|
|
96
|
+
```bash
|
|
97
|
+
make dev-build NPM=~/.local/share/mise/shims/npm
|
|
98
|
+
```
|
|
75
99
|
|
|
76
100
|
### 2. Set up your browser
|
|
77
101
|
|
|
78
|
-
Run setup
|
|
102
|
+
Run setup to write the manifest, wrapper script, and profile registration:
|
|
79
103
|
|
|
80
104
|
<!-- test: "setup explicit --extension-id overrides auto-derived ID" -->
|
|
81
105
|
```bash
|
|
@@ -83,25 +107,32 @@ tabctl setup --browser chrome
|
|
|
83
107
|
```
|
|
84
108
|
|
|
85
109
|
This will:
|
|
86
|
-
1.
|
|
87
|
-
2.
|
|
88
|
-
3.
|
|
89
|
-
4.
|
|
110
|
+
1. Write the native messaging manifest and wrapper script
|
|
111
|
+
2. Register the browser profile in `profiles.json`
|
|
112
|
+
3. Download the version-pinned release extension asset (`tabctl-extension.zip` + `.sha256`) into the tabctl data directory
|
|
113
|
+
4. Sync the managed unpacked extension directory to the tabctl version (`~/.local/state/tabctl/extension/`)
|
|
114
|
+
5. Derive the extension ID from the managed extension path (or use explicit `--extension-id`)
|
|
115
|
+
6. Print the path for loading as an unpacked extension in `chrome://extensions`
|
|
116
|
+
|
|
117
|
+
For local dev builds (no GitHub download), point setup at an unpacked directory:
|
|
118
|
+
```bash
|
|
119
|
+
tabctl setup --browser chrome --extension-dir dist/extension
|
|
120
|
+
```
|
|
90
121
|
|
|
91
122
|
> **Edge?** Use `--browser edge` and load from `edge://extensions` instead.
|
|
123
|
+
>
|
|
124
|
+
> **Cross-platform:** setup works on macOS, Linux, and Windows. On Windows, setup verifies connectivity after writing setup artifacts and checks the runtime extension ID reported by the browser. Connectivity failures and runtime extension ID mismatches exit non-zero and print manual recovery steps (including expected vs runtime IDs).
|
|
92
125
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
tabctl setup --browser chrome --extension-id <your-extension-id>
|
|
98
|
-
```
|
|
126
|
+
Optional setup release overrides:
|
|
127
|
+
- Flags: `--extension-dir`, `--release-repo`, `--release-tag` (or `--release-version`), `--release-asset`, `--skip-extension-download`
|
|
128
|
+
- Env vars: `TABCTL_SETUP_EXTENSION_DIR`, `TABCTL_RELEASE_REPO`, `TABCTL_RELEASE_TAG`, `TABCTL_RELEASE_ASSET`, `TABCTL_SETUP_FETCH_EXTENSION=0`
|
|
129
|
+
- Precedence: flags override env vars, then built-in defaults; if download fails, setup continues and includes warning details in setup output.
|
|
99
130
|
|
|
100
131
|
### 3. Verify and explore
|
|
101
132
|
|
|
102
133
|
<!-- test: "ping sends ping action", "list sends list action" -->
|
|
103
134
|
```bash
|
|
104
|
-
tabctl ping # check
|
|
135
|
+
tabctl ping # check connection + runtime version sync
|
|
105
136
|
tabctl list # see your open tabs
|
|
106
137
|
```
|
|
107
138
|
|
|
@@ -209,6 +240,46 @@ See [CLI.md](CLI.md#configuration) for full details.
|
|
|
209
240
|
- Socket: `<dataDir>/tabctl.sock` (default: `~/.local/state/tabctl/tabctl.sock`)
|
|
210
241
|
- Undo log: `<dataDir>/undo.jsonl` (default: `~/.local/state/tabctl/undo.jsonl`)
|
|
211
242
|
- Profile registry: `<configDir>/profiles.json`
|
|
243
|
+
- WSL TCP port file: `<dataDir>/tcp-port` (written by the Windows host)
|
|
244
|
+
|
|
245
|
+
## Windows + WSL transport
|
|
246
|
+
|
|
247
|
+
On Windows, the host exposes a dual endpoint model:
|
|
248
|
+
- Windows native clients use a named pipe endpoint (`\\.\pipe\tabctl-<hash>`).
|
|
249
|
+
- WSL/Linux clients use `tcp://127.0.0.1:<port>`, with the host writing `<dataDir>/tcp-port`.
|
|
250
|
+
|
|
251
|
+
WSL endpoint discovery (CLI):
|
|
252
|
+
1. `TABCTL_SOCKET` (explicit endpoint); if this is a pipe endpoint in WSL, CLI still prefers discovered TCP.
|
|
253
|
+
2. `TABCTL_TCP_PORT` (forces `127.0.0.1:<port>`).
|
|
254
|
+
3. `tcp-port` file discovery from resolved data dir (and equivalent `/mnt/c/Users/*/.../tabctl/.../tcp-port` locations).
|
|
255
|
+
4. Fallback: `tcp://127.0.0.1:38000`.
|
|
256
|
+
|
|
257
|
+
Relevant knobs: `TABCTL_SOCKET`, `TABCTL_TCP_PORT`, `TABCTL_PROFILE`, `TABCTL_DATA_DIR`, `TABCTL_STATE_DIR`, `TABCTL_CONFIG_DIR`.
|
|
258
|
+
|
|
259
|
+
## Troubleshooting (setup/ping on Windows + WSL)
|
|
260
|
+
|
|
261
|
+
- `tabctl setup` fails with `Windows setup verification failed`: check `data.verification.reason` in JSON output (`ping-timeout`, `socket-not-found`, `socket-refused`, `ping-not-ok`, `extension-id-mismatch`), then follow printed manual steps.
|
|
262
|
+
- Runtime ID mismatch (`extension-id-mismatch`): compare expected vs runtime IDs from setup output, then rerun setup with the runtime ID shown by `edge://extensions` / `chrome://extensions`:
|
|
263
|
+
- `tabctl setup --browser <edge|chrome> --extension-id <runtime-id>`
|
|
264
|
+
- Runtime command runs can auto-sync extension files when host/extension versions drift; rerun `tabctl reload` if the browser does not pick up changes immediately.
|
|
265
|
+
- For local release-like testing while developing, force runtime sync behavior with `TABCTL_AUTO_SYNC_MODE=release-like`.
|
|
266
|
+
- Disable runtime sync entirely with `TABCTL_AUTO_SYNC_MODE=off`.
|
|
267
|
+
- `tabctl ping --json` is the canonical runtime version check (`versionsInSync`, `hostBaseVersion`, `baseVersion`).
|
|
268
|
+
- Version metadata is intentionally health-only: regular command payloads (`open`, `list`, etc.) do not include version fields.
|
|
269
|
+
- `tabctl ping` returns connect errors (`ENOENT`, `ECONNREFUSED`, timeout): ensure extension is loaded and active, rerun `tabctl setup`, and in WSL verify `TABCTL_TCP_PORT` or `<dataDir>/tcp-port` matches a listening localhost port.
|
|
270
|
+
- `tabctl doctor --fix --json` includes per-profile connectivity diagnostics in `data.profiles[].connectivity`; if ping remains unhealthy after local repairs, follow `manualSteps`.
|
|
271
|
+
|
|
272
|
+
Local release-like sync test recipe:
|
|
273
|
+
```bash
|
|
274
|
+
# 1) Install an older extension release into managed extension path
|
|
275
|
+
tabctl setup --browser edge --extension-id <extension-id> --release-tag v0.5.2
|
|
276
|
+
|
|
277
|
+
# 2) Run the current binary with forced release-like auto-sync
|
|
278
|
+
TABCTL_AUTO_SYNC_MODE=release-like cargo run --manifest-path rust/Cargo.toml -p tabctl -- list --all
|
|
279
|
+
|
|
280
|
+
# 3) Verify host/extension base versions are back in sync
|
|
281
|
+
tabctl ping --json
|
|
282
|
+
```
|
|
212
283
|
|
|
213
284
|
## Multi-Browser Setup
|
|
214
285
|
|
|
@@ -219,10 +290,10 @@ tabctl supports multiple browser profiles. Each profile connects to a different
|
|
|
219
290
|
<!-- test: "setup writes native host manifest", "setup writes native host manifest for chrome", "setup --name creates custom-named profile", "profile-list with multiple profiles shows all", "profile-switch success updates default", "--profile flag overrides active profile" -->
|
|
220
291
|
```bash
|
|
221
292
|
# Setup for Edge
|
|
222
|
-
tabctl setup --browser edge
|
|
293
|
+
tabctl setup --browser edge --extension-id <edge-extension-id>
|
|
223
294
|
|
|
224
295
|
# Setup for Chrome (with custom name)
|
|
225
|
-
tabctl setup --browser chrome --name chrome-work
|
|
296
|
+
tabctl setup --browser chrome --name chrome-work --extension-id <chrome-extension-id>
|
|
226
297
|
|
|
227
298
|
# List profiles
|
|
228
299
|
tabctl profile-list
|
|
@@ -258,24 +329,34 @@ Policy is shared across all profiles.
|
|
|
258
329
|
## Security
|
|
259
330
|
- The native host is locked to your extension ID.
|
|
260
331
|
- All data stays local; no external API keys are used.
|
|
332
|
+
- TCP connections (used for WSL ↔ Windows communication) are secured with a per-session auth token. The host generates a random token on startup; the CLI reads it automatically. See [CLI.md](CLI.md) for details.
|
|
333
|
+
- TCP transport is available on all platforms via `TABCTL_HOST_TCP=1` (host) and `TABCTL_TRANSPORT=tcp` (CLI). All TCP connections are authenticated. See [CLI.md](CLI.md) for details.
|
|
261
334
|
|
|
262
335
|
## Development
|
|
263
336
|
|
|
264
|
-
###
|
|
265
|
-
|
|
266
|
-
- `src/extension/background.ts` -> `extension/background.js`
|
|
267
|
-
- `src/host/host.ts` -> `host/host.js`
|
|
268
|
-
- `src/cli/tabctl.ts` -> `cli/tabctl.js`
|
|
269
|
-
- `src/tests/unit/*.ts` -> `tests/unit/*.js`
|
|
337
|
+
### Build workflow
|
|
338
|
+
The single `tabctl` binary is built from the Rust workspace (`rust/`). TypeScript is limited to the browser extension boundary (`src/extension/`). No Node.js or Go is required at runtime.
|
|
270
339
|
|
|
271
|
-
Build and
|
|
340
|
+
Build and verify:
|
|
272
341
|
|
|
273
342
|
```bash
|
|
274
|
-
|
|
275
|
-
npm run build
|
|
276
|
-
npm test
|
|
343
|
+
cargo build --release -p tabctl # build the binary
|
|
344
|
+
npm install && npm run build # full pipeline (extension + Rust)
|
|
345
|
+
npm test # unit tests
|
|
277
346
|
```
|
|
278
347
|
|
|
348
|
+
Rust-only validation:
|
|
349
|
+
```bash
|
|
350
|
+
npm run rust:verify
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Browser-backed integration harness (requires built dist artifacts and Chrome):
|
|
354
|
+
```bash
|
|
355
|
+
npm run test:integration
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
WSL CI validates the WSL->Windows invocation bridge (`test.yml` `wsl` job) with phases: `prerequisites`, `diagnostics`, `build_and_unit`, `setup_validation`, `windows_invocation`, `integration`. Runtime/build execution is delegated to Windows commands (`cmd.exe`/`powershell.exe`), so WSL-local Rust compilation is not required.
|
|
359
|
+
|
|
279
360
|
### Versioning
|
|
280
361
|
The base version lives in `package.json` and is embedded into the CLI, host, and extension at build time.
|
|
281
362
|
|
|
@@ -284,6 +365,25 @@ Commands:
|
|
|
284
365
|
npm run bump:patch
|
|
285
366
|
npm run bump:minor
|
|
286
367
|
npm run bump:major
|
|
368
|
+
npm run bump:alpha
|
|
369
|
+
npm run bump:rc
|
|
370
|
+
npm run bump:stable
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Pre-release staging flow:
|
|
374
|
+
- `bump:alpha` creates/increments `x.y.z-alpha.N`
|
|
375
|
+
- `bump:rc` promotes alpha to `x.y.z-rc.1` (or increments RC)
|
|
376
|
+
- `bump:stable` drops the prerelease suffix for final stable publish
|
|
377
|
+
|
|
378
|
+
Release publishing (`.github/workflows/publish.yml`) enforces:
|
|
379
|
+
- Git tag must match `package.json` version (`v<version>`)
|
|
380
|
+
- prerelease tags publish to `alpha`/`rc`; stable publishes to `latest`
|
|
381
|
+
- `npm run build` and `npm test` must pass before publish
|
|
382
|
+
- release assets include `tabctl-extension.zip` plus `tabctl-extension.zip.sha256`
|
|
383
|
+
|
|
384
|
+
Fetch the extension asset from a release with:
|
|
385
|
+
```bash
|
|
386
|
+
tabctl extension-fetch --version 0.5.3
|
|
287
387
|
```
|
|
288
388
|
|
|
289
389
|
Local builds default to a dev version when a `.git` directory is present, appending the short SHA.
|
|
@@ -309,5 +409,5 @@ Notes:
|
|
|
309
409
|
- Selector `attr` supports `href-url`/`src-url` to return absolute http(s) URLs.
|
|
310
410
|
- `screenshot --out` writes per-tab folders into the target directory.
|
|
311
411
|
- `tabctl undo` accepts a positional txid, `--txid`, or `--latest`.
|
|
312
|
-
- `tabctl history --json` returns a JSON array
|
|
412
|
+
- `tabctl history --json` returns a top-level JSON array.
|
|
313
413
|
- `--format` is only supported by `report` (use `--json` elsewhere).
|