@cabane/cli 0.1.0
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 +182 -0
- package/dist/cli.js +1939 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# cabane CLI
|
|
2
|
+
|
|
3
|
+
Run a self-hosted Cabane on your own machine — **no docker, no repo**. `@cabane/cli`
|
|
4
|
+
is a thin public supervisor/installer (no product source): it fetches the built
|
|
5
|
+
server artifact, runs the whole stack, and keeps it updated.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i -g @cabane/cli # install the CLI (bin: `cabane`)
|
|
9
|
+
cabane init # first-run wizard: data location, port, executor key
|
|
10
|
+
cabane install --token cabdist_… # fetch + sha256-verify + unpack the gated server artifact
|
|
11
|
+
cabane up --daemon # supervise Postgres + server + house bridge (no flags — uses your config)
|
|
12
|
+
# open http://localhost:3000, sign up
|
|
13
|
+
cabane setup-agent # register the house bridge + put your agent on it (prompts for a cab_… token)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`cabane init` is the interactive first-run wizard: it asks where your data lives
|
|
17
|
+
(and **shows the resolved paths** — `data/storage` for uploads, `data/pg` for the
|
|
18
|
+
database), the port, an optional public URL, and your executor credential entered
|
|
19
|
+
**password-style**. It persists everything to config, so a later `cabane up` needs
|
|
20
|
+
no flags. Re-run it any time to reconfigure. You can still skip it and pass flags
|
|
21
|
+
directly if you prefer.
|
|
22
|
+
|
|
23
|
+
Every secret is entered at a hidden prompt, never on the command line — the
|
|
24
|
+
`cabdist_…` distribution grant (`cabane install`), the executor key (`cabane init`
|
|
25
|
+
/ `cabane set-env KEY`), and the `cab_…` access token (`cabane setup-agent`) — so
|
|
26
|
+
none of them land in your shell history or on screen.
|
|
27
|
+
|
|
28
|
+
The house bridge runs whatever executor you have (Claude Code, or another
|
|
29
|
+
supported harness) — see [Credentials](#credentials) for making its login
|
|
30
|
+
reachable. On a Claude subscription there's nothing to do; on API-key billing,
|
|
31
|
+
export or persist your key.
|
|
32
|
+
|
|
33
|
+
## What it supervises
|
|
34
|
+
|
|
35
|
+
`cabane up` runs three children in order, with a clean SIGTERM teardown:
|
|
36
|
+
|
|
37
|
+
1. **Embedded Postgres** — the `embedded-postgres` binaries (pinned pg 16.14) run
|
|
38
|
+
as a child on a local off-5432 port; data in `<CABANE_HOME>/data/pg`. No system
|
|
39
|
+
Postgres, no download at runtime (the binaries ship in the npm package).
|
|
40
|
+
2. **The server** — the artifact's single-process API+SPA (`server.js`, filesystem
|
|
41
|
+
storage, the bundled SPA served via `WEB_DIST`), env composed automatically
|
|
42
|
+
(`NODE_ENV=production`, `http://localhost:<port>`, generated-once vision
|
|
43
|
+
secret). Migrations apply on boot.
|
|
44
|
+
3. **The house bridge** — bundled inside the server artifact from the same commit
|
|
45
|
+
(`<appDir>/bridge`), run as the house executor so your agents answer, always in
|
|
46
|
+
version lockstep with the server. Configured by `cabane setup-agent`.
|
|
47
|
+
|
|
48
|
+
## Layout (`~/.cabane-selfhost/`)
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
config.json the CLI's config (token, port, versions, house ids)
|
|
52
|
+
app/<version>/ each installed artifact tree
|
|
53
|
+
data/pg/ Postgres data dir
|
|
54
|
+
data/storage/ file bytes (filesystem storage backend)
|
|
55
|
+
bridge/ the house bridge's isolated HOME
|
|
56
|
+
logs/ server.log · bridge.log
|
|
57
|
+
run/ supervisor.pid · state.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The root defaults to **`~/.cabane-selfhost/`** — deliberately _not_ `~/.cabane`,
|
|
61
|
+
which a standalone `@cabane/bridge` user bridge already keys off, so a self-host
|
|
62
|
+
install can never clobber a bridge's device pairing on a shared box. Override the
|
|
63
|
+
whole root with the **`CABANE_HOME`** env var (the multi-instance lever); a
|
|
64
|
+
pre-existing self-host install still living at `~/.cabane` is adopted in place, so
|
|
65
|
+
no data moves. A `cabane install` / `set-env` pointed (via `CABANE_HOME`) at a
|
|
66
|
+
directory that holds a bridge config refuses rather than overwrite it.
|
|
67
|
+
|
|
68
|
+
**Relocating just the data.** `cabane init` can point the **data** leg (pg +
|
|
69
|
+
storage) at any path you choose while `config.json` + `app/` stay under the root —
|
|
70
|
+
handy for putting bulky uploads on a bigger disk. The default is still
|
|
71
|
+
`<root>/data`; the chosen location persists in config, so `up` finds it with no
|
|
72
|
+
env var or flag.
|
|
73
|
+
|
|
74
|
+
**Your data is safe across upgrades.** `data/` (pg + storage) sits apart from the
|
|
75
|
+
versioned `app/<version>/` tree, so `cabane install`, `cabane update`, and a
|
|
76
|
+
same-version reinstall only ever touch the app tree — your account, files, and
|
|
77
|
+
conversations persist untouched. `cabane status` prints the `home` + `data`
|
|
78
|
+
paths so you can see it.
|
|
79
|
+
|
|
80
|
+
## Commands
|
|
81
|
+
|
|
82
|
+
| Command | What it does |
|
|
83
|
+
| -------------------- | --------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `cabane init` | interactive first-run wizard: data location, port, public URL, executor credential |
|
|
85
|
+
| `cabane install` | fetch (token → gated artifact) or `--from` a local tarball; unpack + `npm install --omit=dev` |
|
|
86
|
+
| `cabane up` | start + supervise the stack (`--daemon` for background) |
|
|
87
|
+
| `cabane setup-agent` | after signup: register the house bridge, assign your agent |
|
|
88
|
+
| `cabane update` | install a newer published artifact (keeps N-1 for rollback) |
|
|
89
|
+
| `cabane set-env` | persist `KEY=VALUE` credentials forwarded to the house bridge (`--list` / `--unset`) |
|
|
90
|
+
| `cabane down` | stop a running stack |
|
|
91
|
+
| `cabane status` | what's installed + running |
|
|
92
|
+
| `cabane logs` | tail the server + bridge logs |
|
|
93
|
+
| `cabane doctor` | preflight: diagnose common self-host failure classes (runs with the stack down) |
|
|
94
|
+
|
|
95
|
+
## Troubleshooting — `cabane doctor`
|
|
96
|
+
|
|
97
|
+
When something won't start, run `cabane doctor` **first**. It's a standalone
|
|
98
|
+
preflight (no server needed — it's what you reach for precisely when things are
|
|
99
|
+
broken) that checks the common self-host failure classes and prints a legible
|
|
100
|
+
pass/fail/warn report, each with a one-line fix, then exits non-zero if any hard
|
|
101
|
+
check fails. It's strictly local — nothing phones home. v1 checks:
|
|
102
|
+
|
|
103
|
+
- **Node** ≥ the required version.
|
|
104
|
+
- **Executor** — Claude Code present on PATH, and a credential reachable by the
|
|
105
|
+
house bridge (subscription login, an `ANTHROPIC_*` env/persisted key, or a
|
|
106
|
+
managed-policy that would refuse your key — named specifically). Reachability
|
|
107
|
+
only; it never calls the provider.
|
|
108
|
+
- **Port** free (or held by a running cabane).
|
|
109
|
+
- **Embedded Postgres** — platform binaries present + data dir healthy.
|
|
110
|
+
- **Storage root** — writable, and where it is.
|
|
111
|
+
- **Bridge/server version** — the bridge bundled in the installed artifact
|
|
112
|
+
matches the server it ships with (a version skew from a mismatched install is
|
|
113
|
+
flagged).
|
|
114
|
+
- **Disk space** for the data dir.
|
|
115
|
+
- **macOS Gatekeeper** — quarantine on the Postgres binaries (macOS only).
|
|
116
|
+
|
|
117
|
+
## Requirements
|
|
118
|
+
|
|
119
|
+
- **Node ≥ 22.**
|
|
120
|
+
- **An executor the house bridge can run** — e.g. Claude Code, or another
|
|
121
|
+
supported harness — with its credentials reachable (see [Credentials](#credentials)).
|
|
122
|
+
Cabane ships no model of its own and requires no particular provider; the house
|
|
123
|
+
bridge runs whatever executor you have.
|
|
124
|
+
|
|
125
|
+
## Credentials
|
|
126
|
+
|
|
127
|
+
The house bridge inherits the environment `cabane up` runs under, so your
|
|
128
|
+
executor's credentials reach it — no provider is special-cased:
|
|
129
|
+
|
|
130
|
+
- **Claude subscription** — a logged-in Claude Code just works; its OAuth creds
|
|
131
|
+
live on disk under `~/.claude` (pointed at by `CLAUDE_CONFIG_DIR`), so there's
|
|
132
|
+
nothing to export.
|
|
133
|
+
- **API-key billing (or any executor keyed by an env var)** — the key lives in
|
|
134
|
+
your environment, not on disk, so make it reachable one of two ways:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
# the wizard — `cabane init` prompts for it password-style and persists it
|
|
138
|
+
cabane init
|
|
139
|
+
|
|
140
|
+
# persisted, on its own — save once; every future `up` (fresh shell, reboot) picks it up.
|
|
141
|
+
# A bare KEY prompts for the value (hidden); `KEY=VALUE` still works for scripting.
|
|
142
|
+
cabane set-env ANTHROPIC_API_KEY
|
|
143
|
+
cabane up --daemon
|
|
144
|
+
|
|
145
|
+
# ambient — export in the shell you launch from
|
|
146
|
+
export ANTHROPIC_API_KEY=sk-ant-…
|
|
147
|
+
cabane up --daemon
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`set-env` stores generic `KEY=VALUE` pairs in `<CABANE_HOME>/config.json` and composes
|
|
151
|
+
them into the bridge on every `up`, so it serves any executor's credentials (a
|
|
152
|
+
proxy `ANTHROPIC_BASE_URL`, an `ANTHROPIC_AUTH_TOKEN`, a future harness's key) —
|
|
153
|
+
not just Anthropic. A bare `cabane set-env KEY` (no `=value`) prompts for the value
|
|
154
|
+
without echoing, so a secret never lands on the command line. Inspect with `cabane
|
|
155
|
+
set-env --list` (values masked), remove with `cabane set-env --unset KEY`. A live shell export takes precedence over a
|
|
156
|
+
persisted value; the house-class isolation vars (`HOME`, `CLAUDE_CONFIG_DIR`,
|
|
157
|
+
class) always win over both. Apply a change to an already-running stack with
|
|
158
|
+
`cabane down && cabane up`.
|
|
159
|
+
|
|
160
|
+
## Notes
|
|
161
|
+
|
|
162
|
+
- **macOS Gatekeeper** on the unsigned Postgres binaries is a known open question
|
|
163
|
+
(CT453) — documented, not yet solved. If pg fails to exec on first run, clear
|
|
164
|
+
the quarantine xattr and retry.
|
|
165
|
+
- **Before it's published to npm**, install the CLI from a local tarball: `pnpm
|
|
166
|
+
--filter @cabane/cli build && cd apps/cli && npm pack`, then `npm i -g
|
|
167
|
+
./cabane-cli-<version>.tgz`. You can also install the _server_ artifact from a
|
|
168
|
+
local build with `cabane install --from <artifact.tgz>` instead of a token.
|
|
169
|
+
|
|
170
|
+
## Publishing (maintainers)
|
|
171
|
+
|
|
172
|
+
The package is publish-ready and source-free — it carries no product source, only
|
|
173
|
+
the bundled supervisor. Verify the tarball first, then publish:
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
pnpm cli:publish:dry # builds, then `npm publish --dry-run` — lists only dist/ + README
|
|
177
|
+
pnpm cli:publish # builds (prepublishOnly) + `npm publish --access public`
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`cli:publish:dry` should list exactly `dist/cli.js`, `package.json`, and
|
|
181
|
+
`README.md` — no `.ts`. Bump `version` in `apps/cli/package.json` before a real
|
|
182
|
+
publish (npm refuses to overwrite a published version).
|