@mediamonks/canopy-cli 0.7.12 → 0.7.13
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/dist/{db-8Etjmzxh.mjs → db-DKnJQPm5.mjs} +2 -2
- package/dist/{deploy-B1WrPq5W.mjs → deploy-CnxJ4TE6.mjs} +2 -2
- package/dist/dev-BqLvttKc.mjs +2 -0
- package/dist/{dev-BnUYGQQm.mjs → dev-CyJT6EfQ.mjs} +4 -4
- package/dist/docs/ci.md +50 -0
- package/dist/docs/cli-create.md +46 -0
- package/dist/docs/cli-db.md +86 -0
- package/dist/docs/cli-delete.md +44 -0
- package/dist/docs/cli-deploy.md +58 -0
- package/dist/docs/cli-dev.md +82 -0
- package/dist/docs/cli-docs.md +47 -0
- package/dist/docs/cli-download.md +42 -0
- package/dist/docs/cli-egress.md +37 -0
- package/dist/docs/cli-feedback.md +75 -0
- package/dist/docs/cli-index.md +61 -0
- package/dist/docs/cli-init.md +46 -0
- package/dist/docs/cli-login.md +43 -0
- package/dist/docs/cli-logout.md +32 -0
- package/dist/docs/cli-logs.md +57 -0
- package/dist/docs/cli-open.md +41 -0
- package/dist/docs/cli-projects.md +43 -0
- package/dist/docs/cli-promote.md +44 -0
- package/dist/docs/cli-rollback.md +45 -0
- package/dist/docs/cli-skill.md +39 -0
- package/dist/docs/cli-staging.md +54 -0
- package/dist/docs/cli-token.md +47 -0
- package/dist/docs/cli-upgrade.md +43 -0
- package/dist/docs/cli-usage.md +43 -0
- package/dist/docs/cli-whoami.md +46 -0
- package/dist/docs/cli.md +86 -0
- package/dist/docs/data.md +85 -0
- package/dist/docs/deploy.md +81 -0
- package/dist/docs/dev.md +72 -0
- package/dist/docs/developers-agents-and-ai.md +95 -0
- package/dist/docs/developers-architecture.md +106 -0
- package/dist/docs/getting-started.md +108 -0
- package/dist/docs/index.json +336 -0
- package/dist/docs/infrastructure.md +406 -0
- package/dist/docs/migrations.md +183 -0
- package/dist/docs/overview-faq.md +105 -0
- package/dist/docs/overview-how-it-works.md +82 -0
- package/dist/docs/overview-use-cases.md +76 -0
- package/dist/docs/overview-what-is-canopy.md +75 -0
- package/dist/docs/platform-ai-usage.md +65 -0
- package/dist/docs/platform-client-access.md +54 -0
- package/dist/docs/platform-deploys-and-rollbacks.md +93 -0
- package/dist/docs/platform-egress.md +75 -0
- package/dist/docs/platform-feedback.md +114 -0
- package/dist/docs/platform-google.md +213 -0
- package/dist/docs/platform-members-and-access.md +71 -0
- package/dist/docs/platform-project-data.md +76 -0
- package/dist/docs/platform-schedules.md +90 -0
- package/dist/docs/platform-sites-and-profiles.md +61 -0
- package/dist/docs/porting-nextjs.md +233 -0
- package/dist/docs/sdk-ai.md +103 -0
- package/dist/docs/sdk-auth.md +57 -0
- package/dist/docs/sdk-database.md +126 -0
- package/dist/docs/sdk-files.md +82 -0
- package/dist/docs/sdk-services.md +58 -0
- package/dist/docs/sdk.md +126 -0
- package/dist/docs/staging.md +106 -0
- package/dist/docs/static-serving.md +323 -0
- package/dist/docs/troubleshooting.md +102 -0
- package/dist/{docs-DxB7NhZs.mjs → docs-BBMVxVta.mjs} +2 -2
- package/dist/{egress-CN_axsAN.mjs → egress-BFSwa8Uu.mjs} +1 -1
- package/dist/{feedback-B-GXUBPs.mjs → feedback-BMX_d4KZ.mjs} +2 -2
- package/dist/index.mjs +25 -24
- package/dist/{local-BGRd_FMZ.mjs → local-BQxsp-ZQ.mjs} +2 -2
- package/dist/{login-D7dI8D9N.mjs → login-BDTO3nVw.mjs} +1 -1
- package/dist/{logs-DNiZquki.mjs → logs-C53y2eAS.mjs} +1 -1
- package/dist/{migrations-C-5x6SYf.mjs → migrations-C6EcKD6a.mjs} +1 -1
- package/dist/{open-DRPp4QJg.mjs → open-C5x3tX6I.mjs} +1 -1
- package/dist/{package-CDLufecy.mjs → package-vJXq4RNN.mjs} +1 -1
- package/dist/{projects-C6JQjVqg.mjs → projects-MMbv7MmK.mjs} +1 -1
- package/dist/schedule-Cq9K0rnE.mjs +106 -0
- package/dist/skill/canopy/SKILL.md +160 -0
- package/dist/{skill-BOWfqwr2.mjs → skill-Zq9aIPKf.mjs} +2 -2
- package/dist/{staging-Bw1D_J8M.mjs → staging-D8G4amjO.mjs} +1 -1
- package/dist/templates/spa/.github/workflows/canopy-deploy.yml +34 -0
- package/dist/templates/spa/AGENTS.md +47 -0
- package/dist/templates/spa/README.md +14 -0
- package/dist/templates/spa/_gitignore +4 -0
- package/dist/templates/spa/canopy.json +5 -0
- package/dist/templates/spa/index.html +12 -0
- package/dist/templates/spa/package.json +21 -0
- package/dist/templates/spa/src/app.tsx +25 -0
- package/dist/templates/spa/src/canopy.ts +5 -0
- package/dist/templates/spa/src/main.tsx +10 -0
- package/dist/templates/spa/src/style.css +29 -0
- package/dist/templates/spa/tsconfig.json +16 -0
- package/dist/templates/spa/vite.config.ts +7 -0
- package/dist/templates/static/AGENTS.md +45 -0
- package/dist/templates/static/README.md +9 -0
- package/dist/templates/static/_gitignore +2 -0
- package/dist/templates/static/canopy.json +4 -0
- package/dist/templates/static/index.html +21 -0
- package/dist/templates/static/main.js +9 -0
- package/dist/templates/static/style.css +29 -0
- package/dist/templates/worker/.dev.vars.example +9 -0
- package/dist/templates/worker/.github/workflows/canopy-deploy.yml +34 -0
- package/dist/templates/worker/AGENTS.md +63 -0
- package/dist/templates/worker/README.md +17 -0
- package/dist/templates/worker/_gitignore +5 -0
- package/dist/templates/worker/canopy.json +6 -0
- package/dist/templates/worker/index.html +12 -0
- package/dist/templates/worker/package.json +22 -0
- package/dist/templates/worker/src/app.tsx +25 -0
- package/dist/templates/worker/src/canopy.ts +5 -0
- package/dist/templates/worker/src/main.tsx +10 -0
- package/dist/templates/worker/src/style.css +29 -0
- package/dist/templates/worker/tsconfig.json +16 -0
- package/dist/templates/worker/vite.config.ts +7 -0
- package/dist/templates/worker/worker/index.ts +52 -0
- package/dist/{token-D7zrIF8G.mjs → token-BUxgRJVA.mjs} +1 -1
- package/dist/{ui-2mrJcjYC.mjs → ui-B1Px5y7q.mjs} +17 -0
- package/dist/{upgrade-fhfrid_O.mjs → upgrade-ES8u8_Pn.mjs} +2 -2
- package/dist/{usage-CX1Izj_l.mjs → usage-DjNngyvy.mjs} +1 -1
- package/package.json +1 -1
- package/dist/dev-CySBxW7I.mjs +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c as resolveProject, o as projectFlagArgs } from "./site-BUlQR117.mjs";
|
|
2
|
-
import { i as unwrap, n as reportErrors, o as apiDataRequest, r as requireTty, u as withContext } from "./ui-
|
|
3
|
-
import { n as migrateProject, r as readMigrationFiles, t as describeMigrateResult } from "./migrations-
|
|
2
|
+
import { i as unwrap, n as reportErrors, o as apiDataRequest, r as requireTty, u as withContext } from "./ui-B1Px5y7q.mjs";
|
|
3
|
+
import { n as migrateProject, r as readMigrationFiles, t as describeMigrateResult } from "./migrations-C6EcKD6a.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import * as p from "@clack/prompts";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as projectDirArgs, c as resolveProject, l as stagingUrl, n as siteConfig, o as projectFlagArgs, s as projectUrl, u as tryReadCanopyJson } from "./site-BUlQR117.mjs";
|
|
2
|
-
import { c as apiRequest, i as unwrap, n as reportErrors, o as apiDataRequest, s as apiDownload, u as withContext } from "./ui-
|
|
3
|
-
import { n as migrateProject, r as readMigrationFiles, t as describeMigrateResult } from "./migrations-
|
|
2
|
+
import { c as apiRequest, i as unwrap, n as reportErrors, o as apiDataRequest, s as apiDownload, u as withContext } from "./ui-B1Px5y7q.mjs";
|
|
3
|
+
import { n as migrateProject, r as readMigrationFiles, t as describeMigrateResult } from "./migrations-C6EcKD6a.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as projectDirArgs, c as resolveProject, i as projectDialect, n as siteConfig, u as tryReadCanopyJson } from "./site-BUlQR117.mjs";
|
|
2
|
-
import { a as ApiError, c as apiRequest, n as reportErrors, u as withContext } from "./ui-
|
|
3
|
-
import { r as readMigrationFiles } from "./migrations-
|
|
2
|
+
import { a as ApiError, c as apiRequest, n as reportErrors, u as withContext } from "./ui-B1Px5y7q.mjs";
|
|
3
|
+
import { r as readMigrationFiles } from "./migrations-C6EcKD6a.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { defineCommand } from "citty";
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
@@ -165,7 +165,7 @@ async function devRemote(flags, slug) {
|
|
|
165
165
|
async function devLocal(flags, slug) {
|
|
166
166
|
let dump;
|
|
167
167
|
if (flags.pull) {
|
|
168
|
-
const { fetchProjectDump } = await import("./local-
|
|
168
|
+
const { fetchProjectDump } = await import("./local-BQxsp-ZQ.mjs");
|
|
169
169
|
console.log(`Pulling a fresh export of ${slug}${flags.staging ? " [staging]" : ""}…`);
|
|
170
170
|
dump = await fetchProjectDump(slug, flags.staging ? "staging" : "live");
|
|
171
171
|
}
|
|
@@ -180,7 +180,7 @@ async function devLocal(flags, slug) {
|
|
|
180
180
|
const reason = err instanceof ApiError ? err.explain().why : String(err);
|
|
181
181
|
console.log(`Note: ai/services will be unavailable — could not reach the platform (${reason}).`);
|
|
182
182
|
}
|
|
183
|
-
const { createSandbox } = await import("./local-
|
|
183
|
+
const { createSandbox } = await import("./local-BQxsp-ZQ.mjs");
|
|
184
184
|
const sandbox = await createSandbox({
|
|
185
185
|
slug,
|
|
186
186
|
persistDir: join(flags.dir, ".canopy", "local"),
|
package/dist/docs/ci.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CI and deploy tokens
|
|
3
|
+
description: Push-to-main deploys using a project-scoped deploy token.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Interactive `canopy login` is for humans at a terminal. For automated deploys
|
|
7
|
+
(GitHub Actions, etc.) use a **deploy token**: a project-scoped credential that
|
|
8
|
+
can deploy that one project and nothing else.
|
|
9
|
+
|
|
10
|
+
## Create a token
|
|
11
|
+
|
|
12
|
+
From inside the project directory:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
canopy token create --name "GitHub Actions"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This prints the token **once** — copy it immediately and store it as a CI secret
|
|
19
|
+
(e.g. `CANOPY_DEPLOY_TOKEN`). It is not shown again.
|
|
20
|
+
|
|
21
|
+
Manage tokens:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
canopy token list
|
|
25
|
+
canopy token revoke <id>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Use it in CI
|
|
29
|
+
|
|
30
|
+
The CLI picks up `CANOPY_DEPLOY_TOKEN` from the environment and uses it instead
|
|
31
|
+
of an interactive login. A minimal GitHub Actions step:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
- run: npm install -g @mediamonks/canopy-cli
|
|
35
|
+
- run: canopy deploy
|
|
36
|
+
env:
|
|
37
|
+
CANOPY_DEPLOY_TOKEN: ${{ secrets.CANOPY_DEPLOY_TOKEN }}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
(`canopy deploy` runs the project's `canopy.json` build command by default;
|
|
41
|
+
pass `--no-build` if CI already built the output directory.)
|
|
42
|
+
|
|
43
|
+
No `canopy login` step is needed — the token is the credential.
|
|
44
|
+
|
|
45
|
+
## Notes
|
|
46
|
+
|
|
47
|
+
- A deploy token can only deploy its own project — it reaches that project's
|
|
48
|
+
deploy endpoints and upload grants and nothing else. If it strays to another
|
|
49
|
+
project's resources, the platform rejects it.
|
|
50
|
+
- Revoke a token the moment it might be exposed; create a fresh one to replace it.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy create
|
|
3
|
+
description: Register a new project on Canopy and scaffold it locally from a starter template.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy create` is the start of every new project: it registers the project on Canopy (claiming its slug and live URL) and scaffolds a runnable starter into `./<slug>/`. Everything is prompted for interactively, or passable as flags for scripted use.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
canopy create # fully interactive
|
|
12
|
+
canopy create "My Portfolio" --slug my-portfolio --template spa
|
|
13
|
+
canopy create existing-app --no-scaffold # register only, no files written
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments & flags
|
|
17
|
+
|
|
18
|
+
- `<name>` — the project's display name. Multi-word names work unquoted (every positional joins the name). Prompted for when omitted on a TTY.
|
|
19
|
+
- `--slug <slug>` — the URL slug; the project will live at `https://<slug>.<site-domain>`. Lowercase letters, digits and dashes only. Defaults to a slugified version of the name (prompted on a TTY).
|
|
20
|
+
- `--template <id>` — starter to scaffold: `static` (plain HTML/CSS/JS, no build step, untyped SDK from the platform — simplest apps), `spa` (Vite + React + TypeScript with the typed SDK from npm — best for real SDK use or growth), or `worker` (`spa` plus a backend worker in `worker/` — for server-side code: secrets, schedules, calling external APIs). A picker appears when omitted on a TTY; `static` is the default otherwise.
|
|
21
|
+
- `--scaffold` / `--no-scaffold` — whether to write `./<slug>/` from the template. When neither is given, the CLI scaffolds unless the current directory already has a `canopy.json` (in which case it assumes you're registering an existing app and only registers).
|
|
22
|
+
- `--profile <site>` — global flag (or `CANOPY_PROFILE`): which site to create the project on. The chosen profile is pinned into the scaffolded `canopy.json`.
|
|
23
|
+
|
|
24
|
+
## How it works
|
|
25
|
+
|
|
26
|
+
The project is registered with the platform first — this is what reserves the slug and creates the entry you'll see in `canopy projects` and the dashboard. Taken, reserved, or invalid slugs fail here with an actionable error, before anything touches disk.
|
|
27
|
+
|
|
28
|
+
With scaffolding on, the CLI then copies the template into `./<slug>/` (refusing if that directory already exists), substituting the name and slug into the files, and writes a `canopy.json` containing the slug and the profile pin. Templates ship a README, an `AGENTS.md`, and a `.gitignore`; the `spa` template also needs an `npm install` before `canopy dev`. With `--no-scaffold`, nothing is written — an existing `canopy.json` is left untouched, and you're told to add one if the directory has none.
|
|
29
|
+
|
|
30
|
+
The live URL is printed at the end, but it only serves content after your first `canopy deploy`.
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
canopy create
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Walks you through name, slug, and template, registers the project, and scaffolds a ready-to-run starter with next steps printed.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
canopy create "Team Retro Board" --slug retro-board --template spa
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Registers `retro-board`, scaffolds a React SPA into `./retro-board/`, and tells you to `npm install` then `canopy dev`.
|
|
45
|
+
|
|
46
|
+
To set up a local folder for a project that already exists on Canopy, use [canopy init](https://docs.canopy.website/cli/init) instead. See also [canopy projects](https://docs.canopy.website/cli/projects) and [canopy delete](https://docs.canopy.website/cli/delete).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy db
|
|
3
|
+
description: Pull, snapshot, list, restore, and migrate a project's database from the terminal.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy db` is the data-safety toolbox: export the project database as SQL, store restorable snapshots server-side, restore from either, and apply schema migrations. The project comes from `canopy.json` in the current directory, or from `--project <slug>` on any subcommand.
|
|
7
|
+
|
|
8
|
+
The habit that makes restores safe: **always `canopy db snapshot` before `canopy db restore`**. A restore replaces everything, and a snapshot taken seconds earlier is your undo button.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
canopy db pull [--out <file>] [--project <slug>]
|
|
14
|
+
canopy db snapshot [--project <slug>]
|
|
15
|
+
canopy db snapshots [--project <slug>]
|
|
16
|
+
canopy db restore [file.sql] [--snapshot <key>] [--yes] [--project <slug>]
|
|
17
|
+
canopy db migrate [--plan] [--project <slug>]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
All subcommands accept `--project <slug>` (overrides `canopy.json` in the
|
|
21
|
+
current directory), and `--staging` to operate on the
|
|
22
|
+
[staging channel's](https://docs.canopy.website/guides/staging) database instead of live — its snapshots
|
|
23
|
+
live in their own history, and `db migrate --staging` is the migration
|
|
24
|
+
rehearsal.
|
|
25
|
+
|
|
26
|
+
### canopy db pull
|
|
27
|
+
|
|
28
|
+
Downloads a fresh SQL dump of the project database to a local file.
|
|
29
|
+
|
|
30
|
+
- `--out <file>` — output path. Defaults to `<slug>-<timestamp>.sql` in the current directory.
|
|
31
|
+
|
|
32
|
+
The platform exports the database and hands the CLI a download URL; the CLI fetches it and writes the file, reporting its size. Use this for local inspection, ad-hoc backups, or as input to a later `db restore`.
|
|
33
|
+
|
|
34
|
+
### canopy db snapshot
|
|
35
|
+
|
|
36
|
+
Stores a dump **server-side**, restorable anytime from the CLI or the dashboard. No flags beyond `--project`. On success it prints the snapshot key and size, plus the exact `canopy db restore --snapshot <key>` command to bring it back. Take one before every restore, schema experiment, or bulk data change.
|
|
37
|
+
|
|
38
|
+
### canopy db snapshots
|
|
39
|
+
|
|
40
|
+
Lists stored snapshots for the project — one line per snapshot with its key, size, and creation time. If there are none yet, it points you at `canopy db snapshot`.
|
|
41
|
+
|
|
42
|
+
### canopy db restore
|
|
43
|
+
|
|
44
|
+
Replaces **all** current project data from a snapshot or a local `.sql` file.
|
|
45
|
+
|
|
46
|
+
- `[file.sql]` — positional: a local SQL dump to restore from.
|
|
47
|
+
- `--snapshot <key>` — a server-side snapshot key to restore from instead.
|
|
48
|
+
- `--yes` — skip the confirmation (default `false`).
|
|
49
|
+
|
|
50
|
+
Behavior:
|
|
51
|
+
|
|
52
|
+
1. With neither a file nor `--snapshot`, and on an interactive terminal, it fetches the stored snapshots and lets you pick one. On a non-TTY you must pass a source explicitly.
|
|
53
|
+
2. Unless `--yes` is passed, it asks you to **type the project slug** to confirm — a deliberate speed bump, since restore is destructive. A non-TTY without `--yes` errors instead of guessing.
|
|
54
|
+
3. The chosen snapshot or file replaces the entire database, and the CLI confirms `Restored <slug>.`
|
|
55
|
+
|
|
56
|
+
### canopy db migrate
|
|
57
|
+
|
|
58
|
+
Applies pending schema migrations to the project's **live** database, without deploying. Requires a `"migrations"` directory in `canopy.json` (for example your `drizzle-kit generate` output — see the [migrations guide](https://docs.canopy.website/guides/migrations)).
|
|
59
|
+
|
|
60
|
+
- `--plan` — dry run: lists what would apply, touches nothing.
|
|
61
|
+
|
|
62
|
+
Migration files are ordered `.sql` files, applied in filename order and journaled in the database, so each file applies exactly once. The platform stores an automatic **pre-migrate snapshot** before applying anything — a botched migration is one `canopy db restore` away. Files that were already applied must not be edited afterwards (write a new migration instead); the platform refuses edited history.
|
|
63
|
+
|
|
64
|
+
Normally you won't run this yourself: `canopy deploy` applies pending migrations automatically so schema and code ship together. `canopy db migrate` exists for applying schema changes without a deploy, and for CI.
|
|
65
|
+
|
|
66
|
+
## Examples
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
canopy db snapshot && canopy db pull
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Belt and braces before risky work: a server-side snapshot you can restore from the dashboard, plus a local dump on disk.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
canopy db restore --snapshot snap-2026-08-11-1200 --yes --project my-app
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Non-interactive restore (for scripts): restores the named snapshot into `my-app` without the typed confirmation — only sensible right after taking it.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
canopy db restore seed.sql
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Loads a local dump — for example a seed file — after the type-the-slug confirmation.
|
|
85
|
+
|
|
86
|
+
See also the [Data guide](https://docs.canopy.website/guides/data) and [Project data](https://docs.canopy.website/platform/project-data) for how the database, snapshots, and blobs fit together.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy delete
|
|
3
|
+
description: Permanently delete a Canopy project — its deploys, database, and files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy delete` removes a project from Canopy entirely: the live site stops serving, and its deploy history, database, and stored files are torn down. It is not a pause or an archive — there is no undo, and nothing to restore from afterwards.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
canopy delete my-project
|
|
12
|
+
canopy delete my-project --yes # skip the confirmation (scripts/agents)
|
|
13
|
+
canopy delete # pick from a list of your projects
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments & flags
|
|
17
|
+
|
|
18
|
+
- `<slug>` — the project to delete. When omitted on a TTY, you pick from a list of projects you can actually delete (deleting is owner-level: owners see their own projects, admins see all).
|
|
19
|
+
- `--yes` — skip the type-the-slug confirmation. Required on non-interactive runs; use with care, since it removes the last safeguard.
|
|
20
|
+
- `--profile <site>` — global flag (or `CANOPY_PROFILE`): sites are independent, so make sure you're deleting on the site you mean. Deleting a project on `main` does not touch a same-named project on `staging`.
|
|
21
|
+
|
|
22
|
+
## Details
|
|
23
|
+
|
|
24
|
+
Without `--yes`, the CLI asks you to **type the slug back exactly** to confirm; anything else aborts with no changes. On a non-TTY, omitting `--yes` (or the slug) is an error rather than a hang.
|
|
25
|
+
|
|
26
|
+
Once confirmed, the platform tears the project down completely: the project itself, its deploys (so rollback targets are gone too), its database, and its uploaded files. Your local project directory is **not** touched — the code on disk survives, only the platform side is destroyed. That local copy is your only remaining artifact, so if you might want the data later, pull a database snapshot first.
|
|
27
|
+
|
|
28
|
+
Only project owners (and site admins) can delete; the platform refuses the request otherwise.
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
canopy delete old-prototype
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Prompts you to type `old-prototype` to confirm, then tears the project down and prints a success line.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
canopy delete scratch-test --yes --profile staging
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Deletes without prompting — the pattern for cleaning up scratch projects in scripts, made explicit about which site it hits.
|
|
43
|
+
|
|
44
|
+
See also [canopy projects](https://docs.canopy.website/cli/projects) to find slugs, and [Project data](https://docs.canopy.website/platform/project-data) for what a project stores.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy deploy
|
|
3
|
+
description: Build the project and push a new version live, from your machine or from CI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy deploy` builds your project (if `canopy.json` defines a build command), uploads the output directory, and makes the new version live at the project's URL. It's the same command whether you run it by hand or from a CI runner with a deploy token.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
canopy deploy # build, upload, go live
|
|
12
|
+
canopy deploy --no-build # deploy the output directory as-is
|
|
13
|
+
canopy deploy --project my-app ./out
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments & flags
|
|
17
|
+
|
|
18
|
+
- `[dir]` — project directory (defaults to the current directory).
|
|
19
|
+
- `--project <slug>` — project slug, overriding `canopy.json`. With `--project`, a `canopy.json` is optional — you can deploy any static directory; when one exists it still supplies `build` and `dist`.
|
|
20
|
+
- `--build` / `--no-build` — run the `canopy.json` build command first (default on). Use `--no-build` when the output is already built, e.g. a CI step that built earlier.
|
|
21
|
+
- `--migrate` / `--no-migrate` — apply pending schema migrations before the new version goes live (default on; only does anything when `canopy.json` configures a `"migrations"` directory — see the [migrations guide](https://docs.canopy.website/guides/migrations)).
|
|
22
|
+
- `--staging` — deploy to the project's [staging channel](https://docs.canopy.website/guides/staging) instead of live: created on first use with a copy of the live database, served at `staging-dot-<slug>`, promoted with [canopy promote](https://docs.canopy.website/cli/promote). Pending migrations apply to the _staging_ database (the rehearsal). Not to be confused with `--profile staging`, which picks a whole different site.
|
|
23
|
+
- `--profile <site>` / `CANOPY_PROFILE` — which site to deploy to (`main`, `staging`, …). Always pass it explicitly when the target matters; a `canopy.json` profile pin is the fallback.
|
|
24
|
+
|
|
25
|
+
## How it works
|
|
26
|
+
|
|
27
|
+
1. **Build.** If `canopy.json` has a `build` command and you didn't pass `--no-build`, it runs in the project directory with your shell; a non-zero exit aborts the deploy.
|
|
28
|
+
2. **Collect files.** Everything under the `dist` directory from `canopy.json` (default: the project directory itself) is gathered, skipping `canopy.json`, `README.md`, `AGENTS.md`, `CLAUDE.md`, `.gitignore`, `.DS_Store`, and any dot-directories plus `.git`, `node_modules`, and `.claude`. An empty or missing output directory is an error.
|
|
29
|
+
3. **Bundle the backend (if any).** When `canopy.json` names a `worker` entry, that backend code is bundled into a single file (dependencies included) and ships in the same version as the static files — frontend and backend always move together.
|
|
30
|
+
4. **Upload.** The files upload in parallel; the new version is staged alongside the old one, so the live site keeps serving until everything has arrived.
|
|
31
|
+
5. **Migrate (if configured).** With a `"migrations"` directory in `canopy.json`, pending schema migrations apply now — after the bundle is staged, before the version flips — so the incoming code never runs against the old schema. The platform stores an automatic pre-migrate snapshot first. If a migration fails, the deploy aborts and the live version is unchanged; the error names the snapshot to restore if needed.
|
|
32
|
+
6. **Go live.** The platform validates the staged version and switches the site over to it in one step. The upload must contain an `index.html` at the top level — the deploy is rejected otherwise — so double-check `dist` points at the folder that actually holds `index.html`. On success the CLI prints the live URL and version number (plus the backend service URL for worker projects).
|
|
33
|
+
|
|
34
|
+
Deploys are versioned and immutable: nothing overwrites an old version, so [canopy rollback](https://docs.canopy.website/cli/rollback) can always take you back.
|
|
35
|
+
|
|
36
|
+
**CI.** Set the `CANOPY_DEPLOY_TOKEN` environment variable to a project-scoped deploy token (from [canopy token create](https://docs.canopy.website/cli/token)) and `canopy deploy` works with no `canopy login` — the token can deploy exactly one project and nothing else. Deploys from GitHub Actions are tagged with their source in the deploy history.
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
canopy deploy
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
From a project directory: runs the build from `canopy.json`, uploads the `dist` output, and prints the live URL with the new version number.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
canopy deploy --profile staging
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Same project, deployed to the staging site instead of the profile pinned in `canopy.json`.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
CANOPY_DEPLOY_TOKEN=cnpy_… canopy deploy --no-build
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
A CI step deploying already-built output with a deploy token — no interactive login involved.
|
|
57
|
+
|
|
58
|
+
See also [canopy rollback](https://docs.canopy.website/cli/rollback), [canopy token](https://docs.canopy.website/cli/token), the [deploy guide](https://docs.canopy.website/guides/deploy), and [CI setup](https://docs.canopy.website/guides/ci).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy dev
|
|
3
|
+
description: Run your project locally with a Vite dev server, against live platform data or a local sandbox.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy dev` starts a Vite dev server for the project directory and wires up `/_api` so the SDK works exactly as it does in production. By default it's remote-first: your local pages talk to the **live** platform API and see the same data the deployed app sees. When you'd rather experiment on a disposable copy, `--local` swaps in a sandbox on your machine.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
canopy dev # remote-first: live project data
|
|
12
|
+
canopy dev --local # local sandbox: your data stays on your machine
|
|
13
|
+
canopy dev --local --pull # sandbox hydrated from a fresh prod export
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments & flags
|
|
17
|
+
|
|
18
|
+
- `[dir]` — project directory (defaults to the current directory). Needs a `canopy.json` unless you pass `--project`.
|
|
19
|
+
- `--project <slug>` — project slug, overriding the `canopy.json` in the target directory.
|
|
20
|
+
- `--port <n>` — dev server port (Vite picks one when omitted).
|
|
21
|
+
- `--local` — use the local-data sandbox instead of live data. Default off.
|
|
22
|
+
- `--pull` — hydrate the sandbox from a fresh export of the project's production database first. Only valid with `--local`; the command errors otherwise (remote dev already sees live data).
|
|
23
|
+
- `--staging` — point remote dev at the [staging channel's](https://docs.canopy.website/guides/staging) data instead of live (the safe remote target while a schema is in flux), or, with `--local --pull`, hydrate the sandbox from the staging dump.
|
|
24
|
+
- `--profile <site>` / `CANOPY_PROFILE` — which site the dev token and API calls target. Projects usually pin a profile in `canopy.json`.
|
|
25
|
+
|
|
26
|
+
## How it works
|
|
27
|
+
|
|
28
|
+
**Remote-first (default).** The CLI mints a short-lived, project-scoped dev token from the platform, then starts Vite with a proxy: every `/_api/*` request is forwarded to the real platform API with that token attached. The token stays inside the proxy — browser code never holds a credential. When the token expires (the expiry is printed at startup), restart `canopy dev`. Because you're on live data, the startup banner suggests `canopy db snapshot` before risky changes, or switching to `--local --pull`.
|
|
29
|
+
|
|
30
|
+
**Local sandbox (`--local`).** Database, file, and auth requests are answered entirely on your machine, from a sandbox stored under `.canopy/local/` in the project directory — no database to install, and writes never reach the platform. The sandbox behaves the same as the real API, so code that works locally works deployed. Two things still go remote: `ai` and `services` calls go through to the real platform (metered as usual) when you're logged in — fully offline, they return errors until you log in and restart.
|
|
31
|
+
|
|
32
|
+
**Matching your site's SQL dialect.** The document API (`canopy.db.collection(…)`) behaves identically everywhere, but raw `canopy.db.sql()` speaks the deployment target's dialect — SQLite on Cloudflare-backed sites, Postgres on GCP-backed ones (see [dialect()](https://docs.canopy.website/guides/data)). The sandbox defaults to Postgres. If your project uses raw SQL written for a SQLite site, lock the dialect in `canopy.json`:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{ "slug": "my-project", "dialect": "sqlite" }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
With the lock in place, `--local` runs on an embedded SQLite engine instead — the same raw SQL, full-text search behavior, and `--pull` dumps as your deployed site. `"dialect": "postgres"` makes today's default explicit. Each engine keeps its own state under `.canopy/local/`, so switching the lock never corrupts data. The SQLite engine uses Node's built-in database and needs **Node 24+** (older Node builds lack full-text search); the CLI says so plainly if yours is older.
|
|
39
|
+
|
|
40
|
+
**Your backend worker.** If `canopy.json` names a `worker` entry (the worker scaffold does), `canopy dev` serves it too: requests to `/api/*` go to your worker, everything else to the SPA — the same split the platform makes once you deploy. There's no build step; save the file and the next request runs the new code.
|
|
41
|
+
|
|
42
|
+
Your worker gets the same `env` it gets in production: `env.CANOPY.fetch` for the SDK, `env.DB` and `env.BLOB` for raw database and file access, `env.USER` for the signed-in person, `env.PROJECT_SLUG`. They all follow the mode you're in — live project data by default, your sandbox under `--local`. Two differences worth knowing: `env.USER` is you (the account you logged in with), since there's no company login in front of a local server, and a write through `env.DB` reports no row count locally.
|
|
43
|
+
|
|
44
|
+
To tick a schedule by hand, post its name to the same path the platform uses:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
curl -X POST localhost:5173/__canopy/scheduled -d '{"name":"nightly-digest"}'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Worker secrets.** Secrets you set in the dashboard are never downloaded — the platform can't hand a stored value back, and your laptop is not where a live API key belongs. Put local values in a `.dev.vars` file next to `canopy.json` instead:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
STRIPE_KEY=sk_test_local
|
|
54
|
+
SLACK_WEBHOOK="https://hooks.slack.com/services/…"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Your worker reads them exactly as it reads dashboard secrets (`c.env.STRIPE_KEY`). Keep `.dev.vars` out of git — the scaffolds already ignore it. At startup `canopy dev` lists the dashboard secret names your `.dev.vars` doesn't define, so you know what's still missing (names only, never values).
|
|
58
|
+
|
|
59
|
+
**`--pull`.** Before the sandbox boots, the CLI requests a fresh SQL export of the project's production database and applies it locally. Sync is pull-only — nothing ever pushes back. Blobs are not pulled; the local blob store starts empty.
|
|
60
|
+
|
|
61
|
+
**Schema migrations.** When `canopy.json` configures a `"migrations"` directory (see the [migrations guide](https://docs.canopy.website/guides/migrations)), the `--local` sandbox applies pending migrations on boot, so the local schema always matches the repo. Remote-first dev **never** applies migrations — it points at production, and schema changes ship with `canopy deploy`. While a schema change is in flux, work in `--local`.
|
|
62
|
+
|
|
63
|
+
A few practical notes:
|
|
64
|
+
|
|
65
|
+
- If your project ships its own Vite (the spa and worker scaffolds do), `canopy dev` uses that install and merges your `vite.config`; the `/_api` proxy always wins. The no-build static scaffold falls back to the CLI's bundled Vite.
|
|
66
|
+
- If the slug in `canopy.json` isn't registered on Canopy (or your account can't access it), the dev-token lookup fails with instructions to either fix the slug or create the project in the dashboard.
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
canopy dev
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Serves the current directory and proxies `/_api` to the live project — good for day-to-day work where you want real data.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
canopy dev --local --pull --port 3000
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Pulls a fresh copy of production data into `.canopy/local/`, then serves the app on port 3000 against that copy — safe for destructive experiments.
|
|
81
|
+
|
|
82
|
+
See also [canopy deploy](https://docs.canopy.website/cli/deploy) and the [local development guide](https://docs.canopy.website/guides/dev).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy docs
|
|
3
|
+
description: Read the Canopy docs from the terminal — live from the platform, with offline fallbacks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy docs` lists and prints the full Canopy documentation in the terminal — the same content as this site, section by section: the overview, the guides, the platform pages, and the CLI and SDK references. It's built for agents and humans alike: the content is served live by the platform so it never goes stale, but the command still works offline and before you've ever signed in.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
canopy docs # list all topics
|
|
12
|
+
canopy docs <topic> # print one topic
|
|
13
|
+
canopy docs <topic> --refresh
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments & flags
|
|
17
|
+
|
|
18
|
+
- `[topic]` — positional: the topic slug to print. Omit it to list every topic with a one-line summary, grouped by section. Guides keep bare slugs (`deploy`, `staging`); other sections prefix theirs (`sdk-database`, `cli-deploy`, `platform-schedules`).
|
|
19
|
+
- `--refresh` — re-fetch from the platform, bypassing the local cache. Default `false`.
|
|
20
|
+
|
|
21
|
+
## How it works
|
|
22
|
+
|
|
23
|
+
Content resolves in a fixed fallback order:
|
|
24
|
+
|
|
25
|
+
1. **Platform** — fetched live (topics are cached for an hour; `--refresh` forces a fetch). Requests carry your CLI token or `CANOPY_DEPLOY_TOKEN` when one exists, since platform docs require a login.
|
|
26
|
+
2. **Local cache** — `~/.canopy/docs-cache/`, filled by every successful platform fetch.
|
|
27
|
+
3. **Bundled snapshot** — a copy of the docs shipped inside the CLI package itself.
|
|
28
|
+
|
|
29
|
+
That last step is why `canopy docs` works with no network and no login: a fresh install always has the bundled snapshot, and it only gets fresher from there. Fetches time out after a few seconds and fall through silently, so a flaky connection degrades to slightly older docs rather than an error.
|
|
30
|
+
|
|
31
|
+
Asking for an unknown topic errors with the list of available slugs. Everything prints as plain Markdown to stdout, so it pipes cleanly into a pager or an agent's context.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
canopy docs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Lists every topic with its summary — the starting point when you're not sure which guide covers what you're doing.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
canopy docs deploy --refresh
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Prints the deploy guide, guaranteed fresh from the platform rather than the hour-old cache.
|
|
46
|
+
|
|
47
|
+
See also [canopy skill](https://docs.canopy.website/cli/skill), which teaches coding agents to reach for `canopy docs` on their own.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy download
|
|
3
|
+
description: Download the deployed files of any version of a project as a zip archive.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy download` fetches the exact files a deploy is serving — the live version by default, or any version from the history — and writes them to a zip on your machine. Useful for recovering a project whose source you've lost, auditing what's actually live, or diffing two versions.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
canopy download # the live version (or pick from history)
|
|
12
|
+
canopy download v3 # a specific version
|
|
13
|
+
canopy download --project my-app --out backup.zip
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Arguments & flags
|
|
17
|
+
|
|
18
|
+
- `[version]` — the deploy version to download, as `3` or `v3`. Optional: on an interactive terminal you get a picker over the deploy history with the live version preselected; on a non-TTY run the live version is taken automatically (an error if the project has no live version — pass one explicitly).
|
|
19
|
+
- `--out <file>` — output file path. Defaults to `<slug>-v<version>.zip` in the current directory.
|
|
20
|
+
- `--project <slug>` — project slug, overriding `canopy.json` in the target directory.
|
|
21
|
+
- `--dir <path>` — project directory (defaults to the current directory).
|
|
22
|
+
- `--profile <site>` / `CANOPY_PROFILE` — which site to download from.
|
|
23
|
+
|
|
24
|
+
## How it works
|
|
25
|
+
|
|
26
|
+
The CLI resolves the target version (argument, picker, or live), asks the platform for that deploy's assets as a zip, and writes the archive to `--out`. The zip contains the deployed bundle as uploaded — the static files, and for worker projects the bundled `_canopy/worker.mjs`. It does not include files [canopy deploy](https://docs.canopy.website/cli/deploy) skips (like `canopy.json` itself), nor your project's database or blobs — those are handled by the data tooling, not deploy versions. A project with no deploys yet has nothing to download.
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
canopy download
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
From a project directory: pick a version from history (live preselected) and get e.g. `my-app-v5.zip` next to you, with the written size reported.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
canopy download v2 --project legacy-site --out /tmp/legacy-v2.zip
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Grabs version 2 of another project without needing its directory, writing to an explicit path — handy before comparing it against what's live now.
|
|
41
|
+
|
|
42
|
+
See also [canopy deploy](https://docs.canopy.website/cli/deploy), [canopy rollback](https://docs.canopy.website/cli/rollback), and [Deploys & rollbacks](https://docs.canopy.website/platform/deploys-and-rollbacks).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy egress
|
|
3
|
+
description: Manage which outbound hosts the project's backend worker may fetch.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy egress` manages the project's outbound-host allowlist. Worker `fetch`
|
|
7
|
+
calls to hosts outside the list are denied (`egress_denied`) — see
|
|
8
|
+
[Outbound requests](https://docs.canopy.website/platform/egress).
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
canopy egress list
|
|
14
|
+
canopy egress allow api.example.com
|
|
15
|
+
canopy egress allow "*.googleapis.com"
|
|
16
|
+
canopy egress remove api.example.com
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Arguments & flags
|
|
20
|
+
|
|
21
|
+
All subcommands resolve the project the usual way — `canopy.json` in the
|
|
22
|
+
target directory, or `--project <slug>` to override — and honor the global
|
|
23
|
+
`--profile <site>` / `CANOPY_PROFILE`.
|
|
24
|
+
|
|
25
|
+
- `list` — print the allowed hosts, one per line.
|
|
26
|
+
- `allow <host>` — add a hostname (or `*.` subdomain wildcard; quote it so the
|
|
27
|
+
shell doesn't expand the `*`).
|
|
28
|
+
- `remove <host>` — remove an entry (as shown by `list`).
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
The list lives on the platform, per project, shared by the live and staging
|
|
33
|
+
channels — deliberately **not** in `canopy.json`, so a repo file can never
|
|
34
|
+
widen egress silently on deploy. Changes re-roll the running workers
|
|
35
|
+
immediately; no deploy is needed. Entries are validated server-side: bare
|
|
36
|
+
hostnames or `*.` wildcards only, no IPs, ports, schemes, or paths, at most 32
|
|
37
|
+
entries.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: canopy feedback
|
|
3
|
+
description: Read and triage a project's feedback inbox, or file a bug/feedback report — against a project or against Canopy itself.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`canopy feedback` is the CLI side of [Feedback & bug reports](https://docs.canopy.website/platform/feedback):
|
|
7
|
+
agents (and humans) pull reports, append findings, move statuses, and file new
|
|
8
|
+
ones.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
canopy feedback list --status investigate
|
|
14
|
+
canopy feedback show <id>
|
|
15
|
+
canopy feedback comment <id> "root cause: the upload grant expires too early"
|
|
16
|
+
canopy feedback status <id> investigated --comment "root cause: the grant expires too early"
|
|
17
|
+
canopy feedback list --status accepted
|
|
18
|
+
canopy feedback status <id> resolved --comment "fixed in v42"
|
|
19
|
+
canopy feedback mine
|
|
20
|
+
canopy feedback report "canopy deploy exits 1 after upload" --command "canopy deploy"
|
|
21
|
+
canopy feedback report "the header overlaps the logo" --attach ./shot.png
|
|
22
|
+
canopy feedback attach <id> ./after-fix.png --comment "fixed — see the shot"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Subcommands
|
|
26
|
+
|
|
27
|
+
Inbox commands (`list`, `show`, `comment`, `status`) resolve the project the
|
|
28
|
+
usual way — `canopy.json` in the target directory, or `--project <slug>` — and
|
|
29
|
+
require project membership. `list` and `show` take `--json` for
|
|
30
|
+
machine-readable output.
|
|
31
|
+
|
|
32
|
+
- `list [--status <s>] [--kind <k>]` — the project's inbox. Statuses:
|
|
33
|
+
`investigate`, `investigated`, `accepted`, `in_progress`, `resolved`,
|
|
34
|
+
`declined`; kinds: `bug`, `feedback`, `docs`. (Reports filed before triage
|
|
35
|
+
statuses existed sit in `new`, which you can still filter for.)
|
|
36
|
+
- `show <id> [--download <dir>]` — full detail: body, captured context (page
|
|
37
|
+
URL, deploy version, console errors — or CLI context), the screenshots on
|
|
38
|
+
the report, and the comment trail. `--download` saves the screenshots into
|
|
39
|
+
a directory so you can actually look at them.
|
|
40
|
+
- `comment <id> <text>` — append a comment (findings, questions, updates).
|
|
41
|
+
- `attach <id> <file> [--attach <more>] [--caption <text>] [--comment <text>]` —
|
|
42
|
+
add screenshots to an existing report. With `--comment`, the comment is
|
|
43
|
+
posted first and the screenshots hang off that trail entry — how you show
|
|
44
|
+
"here's what it looks like after the fix".
|
|
45
|
+
- `status <id> <new-status> [--comment <note>]` — move the ticket; the
|
|
46
|
+
transition is recorded on the trail. Moving to `investigated` needs the
|
|
47
|
+
findings: pass `--comment`, or comment first.
|
|
48
|
+
- `mine [--project <slug>] [--json]` — your own reports across all projects,
|
|
49
|
+
with current statuses.
|
|
50
|
+
- `report <text> [--kind bug|feedback] [--project <slug>] [--command <cmd>] [--error <output>] [--attach <file>] [--caption <text>]` —
|
|
51
|
+
file a new report. **Without `--project` it goes to the platform inbox**
|
|
52
|
+
(Canopy itself) — the right target when a `canopy` command misbehaves. The
|
|
53
|
+
CLI attaches its version, the active site, your platform, and the project
|
|
54
|
+
you were working in. Reports open as `investigate`; a project member may
|
|
55
|
+
pass `--status` to open one further along — `investigated` when the report
|
|
56
|
+
itself is the write-up of what you found, `accepted` when the person you are
|
|
57
|
+
working with asked for it.
|
|
58
|
+
|
|
59
|
+
## For agents
|
|
60
|
+
|
|
61
|
+
Two loops.
|
|
62
|
+
|
|
63
|
+
**Investigate:** `list --status investigate` is everything nobody has looked at
|
|
64
|
+
yet. Reproduce with the context in `show` (including the deploy version that
|
|
65
|
+
served the page), then `status <id> investigated --comment "<what you found>"`.
|
|
66
|
+
Stop there — say what it would take to fix and let the person decide.
|
|
67
|
+
|
|
68
|
+
**Build:** `list --status accepted` is what a person has asked for. Do the
|
|
69
|
+
work, then `resolve` with a note, or `declined` if it turns out to be a bad
|
|
70
|
+
idea. Set `accepted` yourself only when the person you are working with told
|
|
71
|
+
you to.
|
|
72
|
+
|
|
73
|
+
When a `canopy` command itself fails: rule out user error, check
|
|
74
|
+
`canopy feedback mine` for a duplicate, then `report` with the exact command
|
|
75
|
+
and error output.
|