@hanamorilabs/tab 0.1.4 → 0.1.5
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 +12 -12
- package/dist/cli.js +46 -27
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,8 +45,8 @@ kill switch stay on flocktab.com. It is one small Rust binary. `tab up` asks
|
|
|
45
45
|
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
|
-
`tab down` stops it; `tab update`
|
|
49
|
-
`tab claude` starts it when it is down. No Docker, no Rust, no checkout: the
|
|
48
|
+
`tab down` stops it; `tab update` installs the newest tab, which brings the
|
|
49
|
+
newest proxy, and restarts it; `tab claude` starts it when it is down. No Docker, no Rust, no checkout: the
|
|
50
50
|
binary comes with `tab` as the `@hanamorilabs/flocktab-proxy-<platform>`
|
|
51
51
|
package for your machine. Then
|
|
52
52
|
`tab login`, pick **2 Self-hosted**: the proxy says which console it settles
|
|
@@ -64,7 +64,7 @@ tab alias remove <name>... undo that; `tab alias list` shows them
|
|
|
64
64
|
tab status flock, folder Agent, proxy health, provider key state
|
|
65
65
|
tab version tab and proxy versions
|
|
66
66
|
tab up | down self-hosted: start or stop the local proxy
|
|
67
|
-
tab update
|
|
67
|
+
tab update the newest tab and proxy from npm; restarts a running local proxy
|
|
68
68
|
tab logout forget the session and keys on this machine
|
|
69
69
|
tab help this list
|
|
70
70
|
```
|
|
@@ -77,19 +77,19 @@ this folder's Agent. Every read takes `--json`.
|
|
|
77
77
|
|
|
78
78
|
```
|
|
79
79
|
tab list every Agent: state, spent of cap, window, project
|
|
80
|
-
tab close
|
|
81
|
-
tab cap
|
|
82
|
-
tab rename
|
|
83
|
-
tab policy
|
|
84
|
-
tab project
|
|
80
|
+
tab close my-project tab open my-project the kill switch (402 tab_closed on the next call)
|
|
81
|
+
tab cap my-project 25 --window week cap in dollars, and the window
|
|
82
|
+
tab rename my-project "My project (nightly)" the slug stays
|
|
83
|
+
tab policy my-project --velocity 60 --models gpt-5,claude-sonnet-5 --allow email.send
|
|
84
|
+
tab project my-project Foley --create attribute to a project (--repo owner/name; none clears)
|
|
85
85
|
tab projects add Foley projects
|
|
86
|
-
tab key rotate
|
|
87
|
-
tab archive
|
|
88
|
-
tab ledger [
|
|
86
|
+
tab key rotate my-project [--show] new key, kept on this machine; --show prints it once
|
|
87
|
+
tab archive my-project closes for good, leaves the bill (asks first; -y skips)
|
|
88
|
+
tab ledger [my-project] --limit 20 --blocked one row per call: settled of held, status, reason
|
|
89
89
|
tab spend [agent|project|day] --since 7d meter and outside spend, the console's numbers
|
|
90
90
|
tab outside connections, per-project outside spend, unattributed
|
|
91
91
|
tab live --watch 4 who is working now, refreshed every 4 seconds
|
|
92
|
-
tab web [
|
|
92
|
+
tab web [my-project] the Agent's console page in the browser
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
## Aliases: plain `codex` on the tab
|
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* tab alias remove codex undo that; `tab alias list` shows them
|
|
12
12
|
* tab status which flock, which Agent here, is the proxy up
|
|
13
13
|
* tab version tab and proxy versions
|
|
14
|
-
* tab up | down
|
|
14
|
+
* tab up | down self-hosted: start or stop the local proxy
|
|
15
|
+
* tab update the newest tab and proxy from npm
|
|
15
16
|
* tab logout forget the session and keys
|
|
16
17
|
*
|
|
17
18
|
* Login is per machine. The Agent is per folder: the first `tab claude` in
|
|
@@ -73,7 +74,7 @@ function usage() {
|
|
|
73
74
|
cmd("... --json", "every read command as JSON, for scripts and agents"),
|
|
74
75
|
cmd("up", "self-hosted: start the local proxy (fetches it the first time)"),
|
|
75
76
|
cmd("down", "self-hosted: stop the local proxy"),
|
|
76
|
-
cmd("update", "
|
|
77
|
+
cmd("update", "the newest tab (and proxy) from npm; restarts a running local proxy"),
|
|
77
78
|
cmd("logout", "forget the session and keys"),
|
|
78
79
|
].map(([k, v]) => [cyan(k), v])));
|
|
79
80
|
say(`
|
|
@@ -621,6 +622,48 @@ async function collectProviderKeys() {
|
|
|
621
622
|
ok(`Saved to ${dim(file)} ${dim("(owner-only)")}`);
|
|
622
623
|
return true;
|
|
623
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* `tab update`: the newest tab from npm, which carries the newest proxy as
|
|
627
|
+
* its platform package. A self-hosted proxy that was running is restarted
|
|
628
|
+
* on the new binary; a hosted machine just gets the new tab.
|
|
629
|
+
*/
|
|
630
|
+
async function update() {
|
|
631
|
+
const config = await loadConfig();
|
|
632
|
+
const wasUp = config?.mode === "self-hosted" && (await proxyHealth(config.proxyUrl)).ok;
|
|
633
|
+
say(dim(`tab ${TAB_VERSION} now; asking npm for the newest.`));
|
|
634
|
+
const code = await new Promise((resolve) => {
|
|
635
|
+
const child = spawn(process.platform === "win32" ? "npm.cmd" : "npm", ["i", "-g", "@hanamorilabs/tab@latest"], {
|
|
636
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
637
|
+
shell: process.platform === "win32",
|
|
638
|
+
});
|
|
639
|
+
child.on("error", () => resolve(1));
|
|
640
|
+
child.on("close", (c) => resolve(c ?? 1));
|
|
641
|
+
});
|
|
642
|
+
if (code !== 0) {
|
|
643
|
+
fail(`npm could not update tab. Try: ${bold("npm i -g @hanamorilabs/tab@latest")}`);
|
|
644
|
+
return 1;
|
|
645
|
+
}
|
|
646
|
+
// The version now on PATH is the new install's, not this process's.
|
|
647
|
+
const installed = await new Promise((resolve) => {
|
|
648
|
+
const child = spawn(process.platform === "win32" ? "tab.cmd" : "tab", ["version"], { shell: process.platform === "win32" });
|
|
649
|
+
let text = "";
|
|
650
|
+
child.stdout?.on("data", (d) => (text += d.toString()));
|
|
651
|
+
child.stderr?.on("data", (d) => (text += d.toString()));
|
|
652
|
+
child.on("close", () => resolve(text.trim()));
|
|
653
|
+
child.on("error", () => resolve(""));
|
|
654
|
+
});
|
|
655
|
+
ok(installed ? `Updated.
|
|
656
|
+
${installed}` : "Updated.");
|
|
657
|
+
if (!wasUp) {
|
|
658
|
+
if (!packagedBinPath() && config?.mode === "self-hosted") {
|
|
659
|
+
const fetched = await downloadProxy((t) => say(dim(t)));
|
|
660
|
+
(fetched.ok ? ok : fail)(fetched.ok ? `Fetched flocktab-proxy ${PROXY_VERSION}.` : fetched.message);
|
|
661
|
+
}
|
|
662
|
+
return 0;
|
|
663
|
+
}
|
|
664
|
+
await stopProxy();
|
|
665
|
+
return (await bringUp(config.proxyUrl)) ? 0 : 1;
|
|
666
|
+
}
|
|
624
667
|
async function selfHosted(action) {
|
|
625
668
|
const config = await loadConfig();
|
|
626
669
|
const proxyUrl = config?.mode === "self-hosted" ? config.proxyUrl : LOCAL_PROXY;
|
|
@@ -629,30 +672,6 @@ async function selfHosted(action) {
|
|
|
629
672
|
(stopped ? ok : warn)(stopped ? "Proxy stopped." : "Proxy was not running.");
|
|
630
673
|
return 0;
|
|
631
674
|
}
|
|
632
|
-
if (action === "update") {
|
|
633
|
-
await stopProxy();
|
|
634
|
-
if (packagedBinPath()) {
|
|
635
|
-
// The binary is part of the npm install; the newest one comes with the newest tab.
|
|
636
|
-
say(`The proxy ships with tab. Updating tab updates it: ${bold("npm i -g @hanamorilabs/tab@latest")}`);
|
|
637
|
-
const code = await new Promise((resolve) => {
|
|
638
|
-
const child = spawn(process.platform === "win32" ? "npm.cmd" : "npm", ["i", "-g", "@hanamorilabs/tab@latest"], { stdio: "inherit" });
|
|
639
|
-
child.on("error", () => resolve(1));
|
|
640
|
-
child.on("close", (c) => resolve(c ?? 1));
|
|
641
|
-
});
|
|
642
|
-
if (code !== 0) {
|
|
643
|
-
fail("npm could not update tab.");
|
|
644
|
-
return 1;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
else {
|
|
648
|
-
const fetched = await downloadProxy((t) => say(dim(t)));
|
|
649
|
-
if (!fetched.ok) {
|
|
650
|
-
fail(fetched.message);
|
|
651
|
-
return 1;
|
|
652
|
-
}
|
|
653
|
-
ok(`Fetched flocktab-proxy ${PROXY_VERSION}.`);
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
675
|
if (!(await hasProxyEnv())) {
|
|
657
676
|
const written = await collectProviderKeys();
|
|
658
677
|
if (!written)
|
|
@@ -759,7 +778,7 @@ async function main(argv) {
|
|
|
759
778
|
case "down":
|
|
760
779
|
return selfHosted("down");
|
|
761
780
|
case "update":
|
|
762
|
-
return
|
|
781
|
+
return update();
|
|
763
782
|
default:
|
|
764
783
|
return runAgent(command, rest);
|
|
765
784
|
}
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Written by scripts/write-version.mjs from package.json at build; `tab version` prints it. */
|
|
2
|
-
export const TAB_VERSION = "0.1.
|
|
2
|
+
export const TAB_VERSION = "0.1.5";
|