@canner-ca/cli 0.5.0 → 0.5.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 +231 -231
- package/package.json +42 -42
- package/src/cli.mjs +2569 -2543
package/README.md
CHANGED
|
@@ -1,231 +1,231 @@
|
|
|
1
|
-
# @canner-ca/cli
|
|
2
|
-
|
|
3
|
-
Deploy to [Canner](https://canner.ca) from any terminal. Works in macOS, Linux, Windows, and Cursor's integrated terminal. No git required.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g @canner-ca/cli
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or run without installing:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npx @canner-ca/cli@latest deploy --follow
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Requires Node.js 20 or later.
|
|
18
|
-
|
|
19
|
-
## Quick start
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
# Sign in once (paste an API token from canner.ca/dashboard/
|
|
23
|
-
canner login
|
|
24
|
-
|
|
25
|
-
# In your project directory, create a Canner project
|
|
26
|
-
canner init
|
|
27
|
-
|
|
28
|
-
# Ship it
|
|
29
|
-
canner deploy --follow
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
`--follow` streams the build log live and exits with the build's success code, so it works as the last step of a CI pipeline.
|
|
33
|
-
|
|
34
|
-
## Commands
|
|
35
|
-
|
|
36
|
-
### Setup
|
|
37
|
-
|
|
38
|
-
| Command | What it does |
|
|
39
|
-
|---|---|
|
|
40
|
-
| `canner login` | Prompt for an API token, store it at `~/.canner/credentials` (mode 0600). |
|
|
41
|
-
| `canner logout` | Delete `~/.canner/credentials` from this machine. |
|
|
42
|
-
| `canner whoami` | Show the email + plan this CLI is signed in as. |
|
|
43
|
-
|
|
44
|
-
### Projects
|
|
45
|
-
|
|
46
|
-
| Command | What it does |
|
|
47
|
-
|---|---|
|
|
48
|
-
| `canner projects` | List your projects. |
|
|
49
|
-
| `canner init [--slug X]` | Create a new Canner project and write `canner.json` in the current directory. |
|
|
50
|
-
| `canner status [--slug X]` | Show one project's state — URL, status, source, last request. |
|
|
51
|
-
| `canner open [--slug X] [--dashboard]` | Open the tenant URL (or the dashboard project page) in your browser. |
|
|
52
|
-
|
|
53
|
-
### Deploys
|
|
54
|
-
|
|
55
|
-
| Command | What it does |
|
|
56
|
-
|---|---|
|
|
57
|
-
| `canner deploy [path] [--slug X] [--follow]` | Tar the directory and upload. Works for any project — GitHub-connected or upload-only. `--follow` streams the build log and exits with the build's success code. |
|
|
58
|
-
| `canner redeploy [--slug X] [--follow]` | Trigger a rebuild from the GitHub repo's `HEAD` without uploading. GitHub-connected projects only. |
|
|
59
|
-
| `canner deployments [--slug X]` | List the project's recent deployments. |
|
|
60
|
-
| `canner deployments <id> [--slug X] [--follow]` | Show one deployment's build log; `--follow` streams if it's still in progress. |
|
|
61
|
-
| `canner cancel [<id>] [--slug X]` | Abort the in-flight build (or a specific one by id). |
|
|
62
|
-
| `canner logs [--slug X] [--lines N] [--follow]` | Stream the running tenant's runtime logs (last 200 lines by default). |
|
|
63
|
-
|
|
64
|
-
### Resources
|
|
65
|
-
|
|
66
|
-
| Command | What it does |
|
|
67
|
-
|---|---|
|
|
68
|
-
| `canner token list` | List your `cnr_` API tokens. |
|
|
69
|
-
| `canner token create <name>` | Mint a new token. The secret is printed once — copy it immediately. |
|
|
70
|
-
| `canner token revoke <id\|name>` | Revoke a token. |
|
|
71
|
-
| `canner env [list] [--reveal] [--slug X]` | List a project's environment variables. Values marked sensitive are redacted (`••••••`, or `null` in `--json`) unless `--reveal` is passed. |
|
|
72
|
-
| `canner env set KEY=VALUE [--env production\|preview] [--sensitive] [--slug X]` | Add an environment variable. |
|
|
73
|
-
| `canner env rm <KEY\|id> [--env ...] [--slug X]` | Delete an environment variable. |
|
|
74
|
-
| `canner domains [list] [--slug X]` | List a project's custom domains. |
|
|
75
|
-
| `canner domains add <hostname> [--slug X]` | Attach a custom domain (starts `pending`). |
|
|
76
|
-
| `canner domains verify <hostname\|id> [--slug X]` | Re-check DNS and provision TLS. |
|
|
77
|
-
| `canner domains rm <hostname\|id> [--slug X]` | Detach a custom domain. |
|
|
78
|
-
|
|
79
|
-
### Databases
|
|
80
|
-
|
|
81
|
-
| Command | What it does |
|
|
82
|
-
|---|---|
|
|
83
|
-
| `canner db [list] [--slug X]` | List the project's databases (the primary is injected as `DATABASE_URL`). |
|
|
84
|
-
| `canner db init [--pg 17\|18]` | Provision the project's primary database. |
|
|
85
|
-
| `canner db create <name> [--pg 17\|18]` | Add another database (paid plans). Injected as `DATABASE_URL_<NAME>`. |
|
|
86
|
-
| `canner db info [<name>] [--reveal]` / `canner db url [<name>]` | Connection details. The password is hidden unless `--reveal` (and is `null` in `--json`). |
|
|
87
|
-
| `canner db export [<name>] [--format custom\|plain] [--out FILE]` | Dump a database and download it. `custom` restores with `pg_restore`, `plain` is gzipped SQL. Every plan. |
|
|
88
|
-
| `canner db import <file> [--to <name>] [--replace]` | Restore a `pg_dump --format=custom` file (max 500 MB). The database must be empty unless `--replace`, which snapshots it first. Atomic: on failure nothing changes. |
|
|
89
|
-
| `canner db migrate-in --from <url>\|--from-env VAR [--to <name>] [--replace]` | Stream a database in from any publicly reachable Postgres server. Nothing is stored; the URL is used once. Use `--from -` to type it instead of putting a password in your shell history. |
|
|
90
|
-
| `canner db migrate-out --to-url <url>\|--to-env VAR [--from <name>] --yes` | Stream a database out to another server. |
|
|
91
|
-
| `canner db copy <from> <to> [--to-project SLUG] [--replace]` | Copy one database into another you own. |
|
|
92
|
-
| `canner db rm <name> --yes` · `canner db pg-version <name> <17\|18> --yes` | Delete an additional database · move it to another Postgres version. |
|
|
93
|
-
| `canner db ops [<id>]` | Recent operations, or one operation's status. |
|
|
94
|
-
| `canner db external [<name>]` | Show external-access status: host, port, allowlist. |
|
|
95
|
-
| `canner db external <name> --enable --allow CIDR [--allow CIDR ...]` | Turn on public access, restricted to the given IPs/CIDRs (repeatable). `--allow-all --yes` opens it to the whole internet — not recommended. |
|
|
96
|
-
| `canner db external <name> --disable` | Turn public access off. Always allowed, even on a downgraded plan. |
|
|
97
|
-
| `canner db rotate <name> --yes` | Rotate the database's password. Redeploy to pick up the new `DATABASE_URL`. |
|
|
98
|
-
|
|
99
|
-
Export, import, migrate and copy run on Canner. The CLI starts the operation and
|
|
100
|
-
shows progress; add `--no-wait` to return immediately and check with `canner db ops <id>`.
|
|
101
|
-
Boolean flags (`--replace`, `--yes`, `--no-wait`) can appear anywhere.
|
|
102
|
-
|
|
103
|
-
## JSON output
|
|
104
|
-
|
|
105
|
-
Add `--json` to any command for machine-readable output — tables and progress lines are suppressed and a single JSON value is printed to stdout, so the result pipes straight into `jq` or an agent. Errors are written to stderr as `{"error":"..."}` with a non-zero exit code. With `--json`, `deploy --follow` does **not** stream the build log (it would corrupt the JSON); poll `canner deployments <id> --json` for the terminal status instead.
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
canner projects --json | jq -r '.[].slug'
|
|
109
|
-
canner deploy --json # → {"deployment_id":"…","status":"queued",…}
|
|
110
|
-
canner env list --slug my-app --json
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
This pairs with the REST API directly: every command wraps an endpoint documented in the [API reference](https://canner.ca/developers) (interactive explorer at <https://api.canner.ca/docs>, OpenAPI spec at <https://api.canner.ca/openapi.json>).
|
|
114
|
-
|
|
115
|
-
## What gets uploaded
|
|
116
|
-
|
|
117
|
-
The CLI tars the current directory into a `.tar.gz`, excludes the "build noise" defaults, and streams it to the same upload endpoint the dashboard's drag-drop uses. The server-side build pipeline detects the framework and runs install / build / deploy just like a `git push`.
|
|
118
|
-
|
|
119
|
-
**Always excluded** (no opt-out): `node_modules/`, `.git/`, `.next/`, `.nuxt/`, `.turbo/`, `.vercel/`, `.svelte-kit/`, `.DS_Store`, `Thumbs.db`. The server-side pipeline rebuilds these from your `package.json` anyway.
|
|
120
|
-
|
|
121
|
-
**Additionally excluded if present**: anything in `.cannerignore`. Format is similar to `.gitignore` but simpler:
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
# comment lines start with #
|
|
125
|
-
build
|
|
126
|
-
coverage/
|
|
127
|
-
*.log
|
|
128
|
-
/dist # leading slash anchors to project root
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Supported: basename matches anywhere in the tree, trailing-slash for directory-only, leading-slash for root-anchored, single-segment `*` glob. No negation.
|
|
132
|
-
|
|
133
|
-
## Per-project config: `canner.json`
|
|
134
|
-
|
|
135
|
-
`canner init` writes this in your project root. Commit it alongside your source so `canner deploy` knows the target slug:
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"slug": "my-app"
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Override the slug per-run with `--slug=other-app` if you maintain multiple environments.
|
|
144
|
-
|
|
145
|
-
## Environment variables
|
|
146
|
-
|
|
147
|
-
| Variable | Purpose |
|
|
148
|
-
|---|---|
|
|
149
|
-
| `CANNER_TOKEN` | Use this token instead of the one in `~/.canner/credentials`. Handy for CI. |
|
|
150
|
-
| `CANNER_API_BASE` | Override the API endpoint. Default `https://api.canner.ca`. |
|
|
151
|
-
|
|
152
|
-
## CI / GitHub Actions
|
|
153
|
-
|
|
154
|
-
```yaml
|
|
155
|
-
- uses: actions/setup-node@v4
|
|
156
|
-
with: { node-version: 22 }
|
|
157
|
-
- run: npx @canner-ca/cli@latest deploy --follow
|
|
158
|
-
env:
|
|
159
|
-
CANNER_TOKEN: ${{ secrets.CANNER_TOKEN }}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
`--follow` exits with the build's success code, so a failed build fails the workflow.
|
|
163
|
-
|
|
164
|
-
## Cursor / AI agents
|
|
165
|
-
|
|
166
|
-
Works in any terminal, including Cursor's integrated terminal. Agents can invoke it as a shell tool — no extension or MCP server required:
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
canner deploy --follow
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Plan size caps
|
|
173
|
-
|
|
174
|
-
The CLI uploads under the same per-tier compressed-archive cap as the dashboard:
|
|
175
|
-
|
|
176
|
-
<!-- BEGIN:GENERATED:cli-caps -->
|
|
177
|
-
- **Starter** — 100 MB
|
|
178
|
-
- **Live** — 500 MB
|
|
179
|
-
- **Dedicated** — 1 GB
|
|
180
|
-
<!-- END:GENERATED:cli-caps -->
|
|
181
|
-
|
|
182
|
-
If your project is bigger than that compressed, drop heavier directories into `.cannerignore` or upgrade your plan. `node_modules` is already excluded; the typical thing that pushes a project over the cap is a `public/` folder full of media.
|
|
183
|
-
|
|
184
|
-
## What this CLI stores and sends
|
|
185
|
-
|
|
186
|
-
**Written to your machine — two files, both plain text you can read:**
|
|
187
|
-
|
|
188
|
-
| Path | Contents | Written by |
|
|
189
|
-
|---|---|---|
|
|
190
|
-
| `~/.canner/credentials` | `{ api_base, token }`, mode `0600` | `canner login` |
|
|
191
|
-
| `./canner.json` | Your project slug, in the project directory | `canner init` |
|
|
192
|
-
|
|
193
|
-
Nothing else is written. No system settings, shell profiles, PATH entries, or
|
|
194
|
-
startup items are modified.
|
|
195
|
-
|
|
196
|
-
**Sent over the network:** requests go only to `https://api.canner.ca` (or
|
|
197
|
-
whatever `CANNER_API_BASE` is set to). `canner deploy` uploads a tar of your
|
|
198
|
-
project directory — minus `node_modules`, `.git`, build output, and anything in
|
|
199
|
-
your `.cannerignore` — so that we can build and host it.
|
|
200
|
-
|
|
201
|
-
**Telemetry: none.** There is no usage tracking, analytics, crash reporting, or
|
|
202
|
-
phone-home of any kind. The CLI makes no network request you didn't ask for by
|
|
203
|
-
running a command.
|
|
204
|
-
|
|
205
|
-
## Removing the CLI
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
canner logout # delete ~/.canner/credentials
|
|
209
|
-
npm uninstall -g @canner-ca/cli # remove the package
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
`canner logout` removes the stored credential from **this machine only**. The
|
|
213
|
-
token itself stays valid — the same token may be in use in CI or on another
|
|
214
|
-
machine, so logging out on your laptop deliberately doesn't kill it. To revoke
|
|
215
|
-
it everywhere, run `canner token revoke <name>` before logging out, or revoke it
|
|
216
|
-
from your dashboard's API tokens page.
|
|
217
|
-
|
|
218
|
-
If you've already uninstalled the package and want to clear the leftover
|
|
219
|
-
credential, delete `~/.canner/credentials` by hand. Removing it affects nothing
|
|
220
|
-
else; `canner.json` in a project directory is just a slug and is safe to keep or
|
|
221
|
-
delete.
|
|
222
|
-
|
|
223
|
-
## Terms
|
|
224
|
-
|
|
225
|
-
Use of the CLI and the Canner service is governed by the
|
|
226
|
-
[Terms of Service](https://canner.ca/terms) and the
|
|
227
|
-
[Privacy Policy](https://canner.ca/privacy).
|
|
228
|
-
|
|
229
|
-
## License
|
|
230
|
-
|
|
231
|
-
MIT.
|
|
1
|
+
# @canner-ca/cli
|
|
2
|
+
|
|
3
|
+
Deploy to [Canner](https://canner.ca) from any terminal. Works in macOS, Linux, Windows, and Cursor's integrated terminal. No git required.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @canner-ca/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run without installing:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @canner-ca/cli@latest deploy --follow
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Requires Node.js 20 or later.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Sign in once (paste an API token from canner.ca/dashboard/identity/api-keys)
|
|
23
|
+
canner login
|
|
24
|
+
|
|
25
|
+
# In your project directory, create a Canner project
|
|
26
|
+
canner init
|
|
27
|
+
|
|
28
|
+
# Ship it
|
|
29
|
+
canner deploy --follow
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`--follow` streams the build log live and exits with the build's success code, so it works as the last step of a CI pipeline.
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
### Setup
|
|
37
|
+
|
|
38
|
+
| Command | What it does |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `canner login` | Prompt for an API token, store it at `~/.canner/credentials` (mode 0600). |
|
|
41
|
+
| `canner logout` | Delete `~/.canner/credentials` from this machine. |
|
|
42
|
+
| `canner whoami` | Show the email + plan this CLI is signed in as. |
|
|
43
|
+
|
|
44
|
+
### Projects
|
|
45
|
+
|
|
46
|
+
| Command | What it does |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `canner projects` | List your projects. |
|
|
49
|
+
| `canner init [--slug X]` | Create a new Canner project and write `canner.json` in the current directory. |
|
|
50
|
+
| `canner status [--slug X]` | Show one project's state — URL, status, source, last request. |
|
|
51
|
+
| `canner open [--slug X] [--dashboard]` | Open the tenant URL (or the dashboard project page) in your browser. |
|
|
52
|
+
|
|
53
|
+
### Deploys
|
|
54
|
+
|
|
55
|
+
| Command | What it does |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `canner deploy [path] [--slug X] [--follow]` | Tar the directory and upload. Works for any project — GitHub-connected or upload-only. `--follow` streams the build log and exits with the build's success code. |
|
|
58
|
+
| `canner redeploy [--slug X] [--follow]` | Trigger a rebuild from the GitHub repo's `HEAD` without uploading. GitHub-connected projects only. |
|
|
59
|
+
| `canner deployments [--slug X]` | List the project's recent deployments. |
|
|
60
|
+
| `canner deployments <id> [--slug X] [--follow]` | Show one deployment's build log; `--follow` streams if it's still in progress. |
|
|
61
|
+
| `canner cancel [<id>] [--slug X]` | Abort the in-flight build (or a specific one by id). |
|
|
62
|
+
| `canner logs [--slug X] [--lines N] [--follow]` | Stream the running tenant's runtime logs (last 200 lines by default). |
|
|
63
|
+
|
|
64
|
+
### Resources
|
|
65
|
+
|
|
66
|
+
| Command | What it does |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `canner token list` | List your `cnr_` API tokens. |
|
|
69
|
+
| `canner token create <name>` | Mint a new token. The secret is printed once — copy it immediately. |
|
|
70
|
+
| `canner token revoke <id\|name>` | Revoke a token. |
|
|
71
|
+
| `canner env [list] [--reveal] [--slug X]` | List a project's environment variables. Values marked sensitive are redacted (`••••••`, or `null` in `--json`) unless `--reveal` is passed. |
|
|
72
|
+
| `canner env set KEY=VALUE [--env production\|preview] [--sensitive] [--slug X]` | Add an environment variable. |
|
|
73
|
+
| `canner env rm <KEY\|id> [--env ...] [--slug X]` | Delete an environment variable. |
|
|
74
|
+
| `canner domains [list] [--slug X]` | List a project's custom domains. |
|
|
75
|
+
| `canner domains add <hostname> [--slug X]` | Attach a custom domain (starts `pending`). |
|
|
76
|
+
| `canner domains verify <hostname\|id> [--slug X]` | Re-check DNS and provision TLS. |
|
|
77
|
+
| `canner domains rm <hostname\|id> [--slug X]` | Detach a custom domain. |
|
|
78
|
+
|
|
79
|
+
### Databases
|
|
80
|
+
|
|
81
|
+
| Command | What it does |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `canner db [list] [--slug X]` | List the project's databases (the primary is injected as `DATABASE_URL`). |
|
|
84
|
+
| `canner db init [--pg 17\|18]` | Provision the project's primary database. |
|
|
85
|
+
| `canner db create <name> [--pg 17\|18]` | Add another database (paid plans). Injected as `DATABASE_URL_<NAME>`. |
|
|
86
|
+
| `canner db info [<name>] [--reveal]` / `canner db url [<name>]` | Connection details. The password is hidden unless `--reveal` (and is `null` in `--json`). |
|
|
87
|
+
| `canner db export [<name>] [--format custom\|plain] [--out FILE]` | Dump a database and download it. `custom` restores with `pg_restore`, `plain` is gzipped SQL. Every plan. |
|
|
88
|
+
| `canner db import <file> [--to <name>] [--replace]` | Restore a `pg_dump --format=custom` file (max 500 MB). The database must be empty unless `--replace`, which snapshots it first. Atomic: on failure nothing changes. |
|
|
89
|
+
| `canner db migrate-in --from <url>\|--from-env VAR [--to <name>] [--replace]` | Stream a database in from any publicly reachable Postgres server. Nothing is stored; the URL is used once. Use `--from -` to type it instead of putting a password in your shell history. |
|
|
90
|
+
| `canner db migrate-out --to-url <url>\|--to-env VAR [--from <name>] --yes` | Stream a database out to another server. |
|
|
91
|
+
| `canner db copy <from> <to> [--to-project SLUG] [--replace]` | Copy one database into another you own. |
|
|
92
|
+
| `canner db rm <name> --yes` · `canner db pg-version <name> <17\|18> --yes` | Delete an additional database · move it to another Postgres version. |
|
|
93
|
+
| `canner db ops [<id>]` | Recent operations, or one operation's status. |
|
|
94
|
+
| `canner db external [<name>]` | Show external-access status: host, port, allowlist. |
|
|
95
|
+
| `canner db external <name> --enable --allow CIDR [--allow CIDR ...]` | Turn on public access, restricted to the given IPs/CIDRs (repeatable). `--allow-all --yes` opens it to the whole internet — not recommended. |
|
|
96
|
+
| `canner db external <name> --disable` | Turn public access off. Always allowed, even on a downgraded plan. |
|
|
97
|
+
| `canner db rotate <name> --yes` | Rotate the database's password. Redeploy to pick up the new `DATABASE_URL`. |
|
|
98
|
+
|
|
99
|
+
Export, import, migrate and copy run on Canner. The CLI starts the operation and
|
|
100
|
+
shows progress; add `--no-wait` to return immediately and check with `canner db ops <id>`.
|
|
101
|
+
Boolean flags (`--replace`, `--yes`, `--no-wait`) can appear anywhere.
|
|
102
|
+
|
|
103
|
+
## JSON output
|
|
104
|
+
|
|
105
|
+
Add `--json` to any command for machine-readable output — tables and progress lines are suppressed and a single JSON value is printed to stdout, so the result pipes straight into `jq` or an agent. Errors are written to stderr as `{"error":"..."}` with a non-zero exit code. With `--json`, `deploy --follow` does **not** stream the build log (it would corrupt the JSON); poll `canner deployments <id> --json` for the terminal status instead.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
canner projects --json | jq -r '.[].slug'
|
|
109
|
+
canner deploy --json # → {"deployment_id":"…","status":"queued",…}
|
|
110
|
+
canner env list --slug my-app --json
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This pairs with the REST API directly: every command wraps an endpoint documented in the [API reference](https://canner.ca/developers) (interactive explorer at <https://api.canner.ca/docs>, OpenAPI spec at <https://api.canner.ca/openapi.json>).
|
|
114
|
+
|
|
115
|
+
## What gets uploaded
|
|
116
|
+
|
|
117
|
+
The CLI tars the current directory into a `.tar.gz`, excludes the "build noise" defaults, and streams it to the same upload endpoint the dashboard's drag-drop uses. The server-side build pipeline detects the framework and runs install / build / deploy just like a `git push`.
|
|
118
|
+
|
|
119
|
+
**Always excluded** (no opt-out): `node_modules/`, `.git/`, `.next/`, `.nuxt/`, `.turbo/`, `.vercel/`, `.svelte-kit/`, `.DS_Store`, `Thumbs.db`. The server-side pipeline rebuilds these from your `package.json` anyway.
|
|
120
|
+
|
|
121
|
+
**Additionally excluded if present**: anything in `.cannerignore`. Format is similar to `.gitignore` but simpler:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
# comment lines start with #
|
|
125
|
+
build
|
|
126
|
+
coverage/
|
|
127
|
+
*.log
|
|
128
|
+
/dist # leading slash anchors to project root
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Supported: basename matches anywhere in the tree, trailing-slash for directory-only, leading-slash for root-anchored, single-segment `*` glob. No negation.
|
|
132
|
+
|
|
133
|
+
## Per-project config: `canner.json`
|
|
134
|
+
|
|
135
|
+
`canner init` writes this in your project root. Commit it alongside your source so `canner deploy` knows the target slug:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"slug": "my-app"
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Override the slug per-run with `--slug=other-app` if you maintain multiple environments.
|
|
144
|
+
|
|
145
|
+
## Environment variables
|
|
146
|
+
|
|
147
|
+
| Variable | Purpose |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `CANNER_TOKEN` | Use this token instead of the one in `~/.canner/credentials`. Handy for CI. |
|
|
150
|
+
| `CANNER_API_BASE` | Override the API endpoint. Default `https://api.canner.ca`. |
|
|
151
|
+
|
|
152
|
+
## CI / GitHub Actions
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
- uses: actions/setup-node@v4
|
|
156
|
+
with: { node-version: 22 }
|
|
157
|
+
- run: npx @canner-ca/cli@latest deploy --follow
|
|
158
|
+
env:
|
|
159
|
+
CANNER_TOKEN: ${{ secrets.CANNER_TOKEN }}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`--follow` exits with the build's success code, so a failed build fails the workflow.
|
|
163
|
+
|
|
164
|
+
## Cursor / AI agents
|
|
165
|
+
|
|
166
|
+
Works in any terminal, including Cursor's integrated terminal. Agents can invoke it as a shell tool — no extension or MCP server required:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
canner deploy --follow
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Plan size caps
|
|
173
|
+
|
|
174
|
+
The CLI uploads under the same per-tier compressed-archive cap as the dashboard:
|
|
175
|
+
|
|
176
|
+
<!-- BEGIN:GENERATED:cli-caps -->
|
|
177
|
+
- **Starter** — 100 MB
|
|
178
|
+
- **Live** — 500 MB
|
|
179
|
+
- **Dedicated** — 1 GB
|
|
180
|
+
<!-- END:GENERATED:cli-caps -->
|
|
181
|
+
|
|
182
|
+
If your project is bigger than that compressed, drop heavier directories into `.cannerignore` or upgrade your plan. `node_modules` is already excluded; the typical thing that pushes a project over the cap is a `public/` folder full of media.
|
|
183
|
+
|
|
184
|
+
## What this CLI stores and sends
|
|
185
|
+
|
|
186
|
+
**Written to your machine — two files, both plain text you can read:**
|
|
187
|
+
|
|
188
|
+
| Path | Contents | Written by |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| `~/.canner/credentials` | `{ api_base, token }`, mode `0600` | `canner login` |
|
|
191
|
+
| `./canner.json` | Your project slug, in the project directory | `canner init` |
|
|
192
|
+
|
|
193
|
+
Nothing else is written. No system settings, shell profiles, PATH entries, or
|
|
194
|
+
startup items are modified.
|
|
195
|
+
|
|
196
|
+
**Sent over the network:** requests go only to `https://api.canner.ca` (or
|
|
197
|
+
whatever `CANNER_API_BASE` is set to). `canner deploy` uploads a tar of your
|
|
198
|
+
project directory — minus `node_modules`, `.git`, build output, and anything in
|
|
199
|
+
your `.cannerignore` — so that we can build and host it.
|
|
200
|
+
|
|
201
|
+
**Telemetry: none.** There is no usage tracking, analytics, crash reporting, or
|
|
202
|
+
phone-home of any kind. The CLI makes no network request you didn't ask for by
|
|
203
|
+
running a command.
|
|
204
|
+
|
|
205
|
+
## Removing the CLI
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
canner logout # delete ~/.canner/credentials
|
|
209
|
+
npm uninstall -g @canner-ca/cli # remove the package
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
`canner logout` removes the stored credential from **this machine only**. The
|
|
213
|
+
token itself stays valid — the same token may be in use in CI or on another
|
|
214
|
+
machine, so logging out on your laptop deliberately doesn't kill it. To revoke
|
|
215
|
+
it everywhere, run `canner token revoke <name>` before logging out, or revoke it
|
|
216
|
+
from your dashboard's API tokens page.
|
|
217
|
+
|
|
218
|
+
If you've already uninstalled the package and want to clear the leftover
|
|
219
|
+
credential, delete `~/.canner/credentials` by hand. Removing it affects nothing
|
|
220
|
+
else; `canner.json` in a project directory is just a slug and is safe to keep or
|
|
221
|
+
delete.
|
|
222
|
+
|
|
223
|
+
## Terms
|
|
224
|
+
|
|
225
|
+
Use of the CLI and the Canner service is governed by the
|
|
226
|
+
[Terms of Service](https://canner.ca/terms) and the
|
|
227
|
+
[Privacy Policy](https://canner.ca/privacy).
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT.
|
package/package.json
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@canner-ca/cli",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "Canner deploy CLI — git push from any terminal, no GitHub required",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"canner": "./src/cli.mjs"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"src/",
|
|
11
|
-
"README.md"
|
|
12
|
-
],
|
|
13
|
-
"scripts": {
|
|
14
|
-
"start": "node src/cli.mjs",
|
|
15
|
-
"test": "node test/run.mjs",
|
|
16
|
-
"prepublishOnly": "node -e \"require('fs').
|
|
17
|
-
},
|
|
18
|
-
"dependencies": {
|
|
19
|
-
"tar": "^7.4.3"
|
|
20
|
-
},
|
|
21
|
-
"engines": {
|
|
22
|
-
"node": ">=20"
|
|
23
|
-
},
|
|
24
|
-
"keywords": [
|
|
25
|
-
"canner",
|
|
26
|
-
"deploy",
|
|
27
|
-
"cli",
|
|
28
|
-
"canadian",
|
|
29
|
-
"hosting"
|
|
30
|
-
],
|
|
31
|
-
"author": "Canner",
|
|
32
|
-
"license": "MIT",
|
|
33
|
-
"homepage": "https://canner.ca/cli",
|
|
34
|
-
"repository": {
|
|
35
|
-
"type": "git",
|
|
36
|
-
"url": "git+https://github.com/tzshand/canner.git",
|
|
37
|
-
"directory": "tools/cli"
|
|
38
|
-
},
|
|
39
|
-
"bugs": {
|
|
40
|
-
"url": "https://github.com/tzshand/canner/issues"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@canner-ca/cli",
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "Canner deploy CLI — git push from any terminal, no GitHub required",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"canner": "./src/cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"src/",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node src/cli.mjs",
|
|
15
|
+
"test": "node test/run.mjs",
|
|
16
|
+
"prepublishOnly": "node -e \"const s=require('fs').readFileSync('src/cli.mjs','utf8'); if(s.includes('\\r')){console.error('src/cli.mjs has CRLF line endings; publish it with LF (see .gitattributes).');process.exit(1)}\" && npm test"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"tar": "^7.4.3"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"canner",
|
|
26
|
+
"deploy",
|
|
27
|
+
"cli",
|
|
28
|
+
"canadian",
|
|
29
|
+
"hosting"
|
|
30
|
+
],
|
|
31
|
+
"author": "Canner",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"homepage": "https://canner.ca/cli",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/tzshand/canner.git",
|
|
37
|
+
"directory": "tools/cli"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/tzshand/canner/issues"
|
|
41
|
+
}
|
|
42
|
+
}
|