@hanamorilabs/tab 0.1.0 → 0.1.1

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,6 +1,6 @@
1
1
  # tab
2
2
 
3
- Run any AI agent on a FlockTab tab.
3
+ Run any AI agent on a FlockTab tab. Needs Node 22 or newer; nothing else.
4
4
 
5
5
  ```
6
6
  npm i -g @hanamorilabs/tab
@@ -46,11 +46,27 @@ for the keys once (typed without echo, saved owner-only to
46
46
  `~/.flocktab/proxy.env`), fetches `flocktab-proxy` for this machine into
47
47
  `~/.flocktab/bin`, and starts it in the background (log: `~/.flocktab/proxy.log`).
48
48
  `tab down` stops it; `tab update` fetches the newest proxy and restarts;
49
- `tab claude` starts it when it is down. No Docker, no checkout. Then
49
+ `tab claude` starts it when it is down. No Docker, no Rust, no checkout: the
50
+ binary comes with `tab` as the `@hanamorilabs/flocktab-proxy-<platform>`
51
+ package for your machine. Then
50
52
  `tab login`, pick **2 Self-hosted**: the proxy says which console it settles
51
53
  through, so the device code lands on flocktab.com. No unlock in this mode;
52
54
  Codex shows `FlockTab - Self-hosted` as its provider.
53
55
 
56
+ ## Commands
57
+
58
+ ```
59
+ tab login approve this machine in the console, once
60
+ tab <agent> [args] claude, codex, grok, kimi, gemini, or any command, on the tab
61
+ tab use pick or change the Agent this folder runs as (.flocktab)
62
+ tab status flock, folder Agent, proxy health, provider key state
63
+ tab version tab and proxy versions
64
+ tab up | down self-hosted: start or stop the local proxy
65
+ tab update self-hosted: newest proxy (npm i -g @hanamorilabs/tab@latest)
66
+ tab logout forget the session and keys on this machine
67
+ tab help this list
68
+ ```
69
+
54
70
  ## Secrets and colour
55
71
 
56
72
  The unlock and provider keys are typed with echo off (raw mode); the unlock is checked against the proxy before saving; a wrong unlock is refused, and `tab status` says `unlock ok` or `unlock is WRONG`. The check is `GET /v1/whoami` with the unlock, which decrypts the envelope in memory and answers `ok`/`wrong`, never the key. Output is coloured on a terminal; `NO_COLOR` turns it off, `FORCE_COLOR` turns it on for pipes.
package/dist/cli.js CHANGED
@@ -8,6 +8,7 @@
8
8
  * tab <cmd> [...args] anything else, both APIs pointed at the tab
9
9
  * tab use pick (or change) the Agent this folder runs as
10
10
  * tab status which flock, which Agent here, is the proxy up
11
+ * tab version tab and proxy versions
11
12
  * tab up | down | update self-hosted: start, stop, or fetch the newest proxy
12
13
  * tab logout forget the session and keys
13
14
  *
@@ -28,8 +29,9 @@ import { consoleUrlFor, DeviceLoginError, startDeviceLogin, waitForApproval } fr
28
29
  import { clearConfig, configDir, configPath, HOSTED_PROXY, isLocalProxy, loadConfig, LOCAL_PROXY, normalizeProxyUrl, presentedKey, saveConfig, } from "./config.js";
29
30
  import { reportFolder } from "./folder.js";
30
31
  import { agentNameFor, projectRoot, readProject, writeProject } from "./project.js";
31
- import { downloadProxy, hasProxyEnv, packagedBinPath, proxyBinPath, proxyEnvPath, proxyLogPath, PROXY_VERSION, startProxy, stopProxy, tailProxyLog, writeProxyEnv, } from "./proxy-bin.js";
32
+ import { downloadProxy, hasProxyEnv, packagedBinPath, proxyBinPath, proxyEnvPath, proxyInstalled, proxyLogPath, PROXY_VERSION, startProxy, stopProxy, tailProxyLog, writeProxyEnv, } from "./proxy-bin.js";
32
33
  import { proxyHealth, waitHealthy } from "./selfhost.js";
34
+ import { TAB_VERSION } from "./version.js";
33
35
  const say = (text) => console.error(text);
34
36
  const ok = (text) => say(line("ok", text));
35
37
  const warn = (text) => say(line("warn", text));
@@ -47,6 +49,7 @@ function usage() {
47
49
  cmd("<command> [args]", "any other agent, both APIs pointed at the tab"),
48
50
  cmd("use", "pick or change the Agent this folder runs as (.flocktab)"),
49
51
  cmd("status", "which flock, which Agent here, is the proxy up"),
52
+ cmd("version", "tab and proxy versions"),
50
53
  cmd("up", "self-hosted: start the local proxy (fetches it the first time)"),
51
54
  cmd("down", "self-hosted: stop the local proxy"),
52
55
  cmd("update", "self-hosted: fetch the newest proxy and restart it"),
@@ -423,6 +426,15 @@ async function resolveAgent(config, opts = {}) {
423
426
  ok(`This folder runs as ${bold(issued.agent.name)} ${dim(`(${file})`)}`);
424
427
  return login;
425
428
  }
429
+ /** `tab version`: this CLI, and the proxy it would run (packaged, downloaded, or neither). */
430
+ async function version() {
431
+ const packaged = packagedBinPath();
432
+ const bin = proxyBinPath();
433
+ const installed = await proxyInstalled();
434
+ const where = packaged ? `packaged, ${packaged}` : installed ? `downloaded, ${bin}` : "not installed; tab up fetches it";
435
+ say(rows([["tab", TAB_VERSION], ["proxy", `${PROXY_VERSION} ${dim(`(${where})`)}`]], 0));
436
+ return 0;
437
+ }
426
438
  async function status() {
427
439
  const config = await loadConfig();
428
440
  if (!config) {
@@ -488,6 +500,8 @@ async function runAgent(name, args) {
488
500
  child.on("error", (err) => {
489
501
  if (err.code === "ENOENT") {
490
502
  fail(`${spec.label} is not installed (${spec.command} not on PATH). ${dim(spec.install)}`);
503
+ if (!knownClients().includes(name))
504
+ say(dim(`Not a tab command either; see ${bold("tab help")}.`));
491
505
  resolve(127);
492
506
  return;
493
507
  }
@@ -591,6 +605,10 @@ async function main(argv) {
591
605
  return 0;
592
606
  case "use":
593
607
  return use();
608
+ case "version":
609
+ case "--version":
610
+ case "-v":
611
+ return version();
594
612
  case "status":
595
613
  return status();
596
614
  case "up":
@@ -0,0 +1,2 @@
1
+ /** Written by scripts/write-version.mjs from package.json at build; `tab version` prints it. */
2
+ export const TAB_VERSION = "0.1.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanamorilabs/tab",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Run any AI agent on a FlockTab tab: tab claude, tab codex, tab <command>.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  "node": ">=22"
16
16
  },
17
17
  "scripts": {
18
- "build": "tsc -p tsconfig.build.json && chmod +x dist/cli.js",
18
+ "build": "node scripts/write-version.mjs && tsc -p tsconfig.build.json && chmod +x dist/cli.js",
19
19
  "dev": "tsx src/cli.ts",
20
20
  "test": "vitest run",
21
21
  "typecheck": "tsc --noEmit",