@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 +18 -2
- package/dist/cli.js +19 -1
- package/dist/version.js +2 -0
- package/package.json +2 -2
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
|
|
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":
|
package/dist/version.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanamorilabs/tab",
|
|
3
|
-
"version": "0.1.
|
|
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",
|