@mediamonks/canopy-cli 0.7.5 → 0.7.6

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.
Files changed (52) hide show
  1. package/dist/docs/cli-create.md +46 -0
  2. package/dist/docs/cli-db.md +86 -0
  3. package/dist/docs/cli-delete.md +44 -0
  4. package/dist/docs/cli-deploy.md +58 -0
  5. package/dist/docs/cli-dev.md +63 -0
  6. package/dist/docs/cli-docs.md +47 -0
  7. package/dist/docs/cli-download.md +42 -0
  8. package/dist/docs/cli-egress.md +37 -0
  9. package/dist/docs/cli-index.md +61 -0
  10. package/dist/docs/cli-init.md +46 -0
  11. package/dist/docs/cli-login.md +43 -0
  12. package/dist/docs/cli-logout.md +32 -0
  13. package/dist/docs/cli-logs.md +57 -0
  14. package/dist/docs/cli-open.md +41 -0
  15. package/dist/docs/cli-projects.md +43 -0
  16. package/dist/docs/cli-promote.md +44 -0
  17. package/dist/docs/cli-rollback.md +45 -0
  18. package/dist/docs/cli-skill.md +39 -0
  19. package/dist/docs/cli-staging.md +54 -0
  20. package/dist/docs/cli-token.md +47 -0
  21. package/dist/docs/cli-upgrade.md +43 -0
  22. package/dist/docs/cli-usage.md +43 -0
  23. package/dist/docs/cli-whoami.md +46 -0
  24. package/dist/docs/developers-agents-and-ai.md +95 -0
  25. package/dist/docs/developers-architecture.md +106 -0
  26. package/dist/docs/index.json +321 -0
  27. package/dist/docs/infrastructure.md +5 -8
  28. package/dist/docs/overview-faq.md +105 -0
  29. package/dist/docs/overview-how-it-works.md +81 -0
  30. package/dist/docs/overview-use-cases.md +76 -0
  31. package/dist/docs/overview-what-is-canopy.md +75 -0
  32. package/dist/docs/platform-ai-usage.md +65 -0
  33. package/dist/docs/platform-client-access.md +53 -0
  34. package/dist/docs/platform-deploys-and-rollbacks.md +93 -0
  35. package/dist/docs/platform-egress.md +75 -0
  36. package/dist/docs/platform-members-and-access.md +71 -0
  37. package/dist/docs/platform-project-data.md +66 -0
  38. package/dist/docs/platform-schedules.md +90 -0
  39. package/dist/docs/platform-sites-and-profiles.md +61 -0
  40. package/dist/docs/static-serving.md +5 -8
  41. package/dist/docs/troubleshooting.md +6 -8
  42. package/dist/{docs-DQmUReJR.mjs → docs-DhAz6QWS.mjs} +42 -20
  43. package/dist/index.mjs +9 -9
  44. package/dist/{logs-DBLDS3aQ.mjs → logs-DuzM-_Rn.mjs} +1 -1
  45. package/dist/{package-yVoO2pq4.mjs → package-CPXtNnfc.mjs} +1 -1
  46. package/dist/{projects-D2fDeWNU.mjs → projects-C9TBoiW7.mjs} +5 -8
  47. package/dist/skill/canopy/SKILL.md +10 -8
  48. package/dist/{skill-12Ga-2UT.mjs → skill-BCX4cUeP.mjs} +1 -1
  49. package/dist/templates/worker/AGENTS.md +0 -3
  50. package/dist/templates/worker/README.md +1 -5
  51. package/dist/{upgrade-Du6U0xjp.mjs → upgrade-jLu7jI0r.mjs} +1 -1
  52. package/package.json +3 -3
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: Sites & profiles
3
+ description: Canopy runs as more than one installation. Most people only ever use main — here's what the others are and how the CLI keeps them straight.
4
+ ---
5
+
6
+ Canopy isn't a single installation: the same platform runs as a few separate
7
+ **sites**, each with its own domain, its own projects, and its own data.
8
+ Unless someone told you otherwise, **you're on `main` and can stop reading
9
+ here** — the rest of this page explains what the other sites are for and how
10
+ the CLI targets them.
11
+
12
+ ## The sites
13
+
14
+ | Site | Project URLs | What it's for |
15
+ | ----------- | --------------------- | ------------------------------------------------- |
16
+ | `main` | `*.canopy.website` | The real platform. Your projects live here. |
17
+ | `staging` | `*.thanarie.dev` | The platform team's testbed for platform changes. |
18
+ | `gcp-pilot` | `*.canopy.monks.zone` | A pilot running on Google Cloud. |
19
+
20
+ Sites are fully separate: a project on `main` doesn't exist on `staging`, and
21
+ signing in to one doesn't create anything on another. They can also differ in
22
+ what they support — the dashboard simply hides features a site can't honor,
23
+ and the API says `not_supported_on_target` if asked directly.
24
+
25
+ ## What a profile is
26
+
27
+ A **profile** is the CLI's name for a site. `canopy login` signs you in once
28
+ via OneLogin and stores a credential for every site in one go; the profile
29
+ just picks which one a command talks to.
30
+
31
+ Three things decide the effective profile, in order:
32
+
33
+ 1. `--profile <id>` on the command (or the `CANOPY_PROFILE` environment
34
+ variable) — one-off override.
35
+ 2. The `"profile"` pinned in the project's `canopy.json` — set when the
36
+ project was created, so a checkout always targets the site it belongs to.
37
+ 3. Your default active profile — `main` unless you chose otherwise at login.
38
+
39
+ Every command prints the site it's talking to in its header line, and
40
+ `canopy whoami` shows your email, active profile, and API host — so there's
41
+ never a mystery about where a deploy just went.
42
+
43
+ ```bash
44
+ canopy whoami # who am I, on which site?
45
+ canopy --profile gcp-pilot deploy # one command against the pilot
46
+ ```
47
+
48
+ ## When you'd actually care
49
+
50
+ - **Never, usually.** Day-to-day work on your own projects is all `main`,
51
+ and the `canopy.json` pin keeps it that way without any flags.
52
+ - **Trying backend features.** Custom backends and
53
+ [schedules](https://docs.canopy.website/platform/schedules) currently run on `gcp-pilot`, so
54
+ experiments with those happen there.
55
+ - **Helping test platform changes.** If the platform team asks you to check
56
+ something on `staging`, `--profile staging` points any command at it.
57
+
58
+ > **Note:** Deploying to a different site publishes a **separate copy** of the project there — it doesn't move
59
+ > or mirror the one on `main`. Each site keeps its own versions, data, and members.
60
+
61
+ - [CLI reference](https://docs.canopy.website/guides/cli) — Every canopy command, including login, whoami, and the --profile flag.
@@ -7,12 +7,10 @@ This explains the full path a browser request takes to receive a deployed
7
7
  project's `index.html` and its assets (JS/CSS/images/fonts), and reviews that
8
8
  path from a **security** and a **performance** angle.
9
9
 
10
- Everything a visitor sees is a _deployed_ build stored in R2. On Cloudflare
11
- there is no origin server running the project's code — the platform serves
12
- pre-built static files. (On the GCP target, `/api/*` requests dispatch to a
13
- per-project Cloud Run backend; everything else is still static serving. On
14
- Cloudflare, per-project workers remain a Phase 2 TODO and the capability is
15
- gated off.)
10
+ Everything a visitor sees is a _deployed_ build stored in R2 — the platform
11
+ serves pre-built static files. (When a project has a backend worker, `/api/*`
12
+ requests dispatch to it — Workers for Platforms on Cloudflare, Cloud Run on
13
+ GCP; everything else is still static serving.)
16
14
 
17
15
  Asset serving is the hottest **data-plane** path (see
18
16
  [`docs/09-plane-split.md`](../09-plane-split.md)): it lives at
@@ -213,8 +211,7 @@ These are observations, not known incidents — worth a conscious decision:
213
211
  runs on a `*.canopy.<domain>` origin that shares the session-cookie domain.
214
212
  The session cookie's flags (HttpOnly/SameSite/Secure) in
215
213
  [`session.ts`](../../apps/gateway/src/session.ts) are the mitigation to keep an
216
- eye on; a per-project origin isolation (Phase 2 dev workers) would be the
217
- stronger fix.
214
+ eye on; per-project origin isolation would be the stronger fix.
218
215
  3. **SPA fallback returns `index.html` with 200 for unknown paths**, including
219
216
  things that look like missing assets (`/assets/typo.js` → HTML). That's normal
220
217
  SPA behavior but can mask 404s and, combined with #1, is another reason
@@ -47,11 +47,11 @@ The `CANOPY_DEPLOY_TOKEN` was revoked or is wrong. Create a new one with
47
47
 
48
48
  ## `not_supported_on_target` (501)
49
49
 
50
- Some features are platform-target-specific: on the Cloudflare target,
51
- per-project worker backends, dashboard schedules, and secret injection are not
52
- available and answer this error (the dashboard hides those panels). It's not a
53
- failure of your project — the feature doesn't exist on the target your platform
54
- runs on.
50
+ Some features are platform-target-specific: a site whose platform target
51
+ doesn't support a feature (for example per-project worker backends, dashboard
52
+ schedules, or secret injection) answers this error, and the dashboard hides
53
+ those panels. It's not a failure of your project — the feature doesn't exist
54
+ on the target your platform runs on.
55
55
 
56
56
  ## `ai_budget_exceeded` (429)
57
57
 
@@ -73,9 +73,7 @@ canopy egress allow api.example.com
73
73
 
74
74
  or use dashboard Settings → Outbound hosts. Details and entry rules:
75
75
  [Outbound requests](https://docs.canopy.website/platform/egress). Calls made through the SDK /
76
- `env.CANOPY.fetch` don't count as egress and are unaffected. On the Cloudflare
77
- target outbound requests are currently unrestricted, so this error only
78
- appears on GCP.
76
+ `env.CANOPY.fetch` don't count as egress and are unaffected.
79
77
 
80
78
  ## The worker returns errors and you can't see why
81
79
 
@@ -1,4 +1,4 @@
1
- import { t as version } from "./package-yVoO2pq4.mjs";
1
+ import { t as version } from "./package-CPXtNnfc.mjs";
2
2
  import { n as siteConfig } from "./site-BUlQR117.mjs";
3
3
  import { i as latestKnownVersion, r as compareSemver } from "./version-check-CcsA1QjI.mjs";
4
4
  import { n as reportErrors } from "./ui-CpdtK7mt.mjs";
@@ -9,9 +9,10 @@ import { join } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
  //#region src/docs.ts
11
11
  /**
12
- * canopy docs — user/agent-facing guides, served live by the platform
13
- * (GET /control/v1/docs) so they never go stale, with a local cache and a bundled
14
- * snapshot as offline fallbacks.
12
+ * canopy docs — the full docs site in the terminal (guides, platform, CLI and
13
+ * SDK references), served live by the platform (GET /control/v1/docs) so it
14
+ * never goes stale, with a local cache and a bundled snapshot as offline
15
+ * fallbacks. The listing is grouped per docs-site section.
15
16
  *
16
17
  * The platform requires a login for docs (internal platform), so fetches carry
17
18
  * the CLI token when there is one; without it we simply fall back to the
@@ -98,15 +99,25 @@ function writeCache(file, content) {
98
99
  writeFileSync(join(cacheDir, file), content);
99
100
  } catch {}
100
101
  }
101
- /** Topics from cache, else from the bundled snapshot's frontmatter. */
102
- function topicsFromFallback() {
102
+ /** The index from cache, else from the bundled snapshot. */
103
+ function indexFromFallback() {
103
104
  try {
104
105
  const cached = JSON.parse(readFileSync(indexPath, "utf8"));
105
- if (cached.topics?.length) return cached.topics;
106
+ if (cached.topics?.length) return {
107
+ topics: cached.topics,
108
+ sections: cached.sections
109
+ };
106
110
  } catch {}
107
111
  const dir = bundledDocsDir();
108
- if (!dir) return [];
109
- return readdirSync(dir).filter((f) => /\.mdx?$/.test(f)).map((f) => {
112
+ if (!dir) return { topics: [] };
113
+ try {
114
+ const { sections } = JSON.parse(readFileSync(join(dir, "index.json"), "utf8"));
115
+ if (sections?.length) return {
116
+ topics: sections.flatMap((s) => s.topics),
117
+ sections
118
+ };
119
+ } catch {}
120
+ return { topics: readdirSync(dir).filter((f) => /\.mdx?$/.test(f)).map((f) => {
110
121
  const slug = f.replace(/\.mdx?$/, "");
111
122
  const { title, summary } = parseFrontmatter(readFileSync(join(dir, f), "utf8"));
112
123
  return {
@@ -114,7 +125,7 @@ function topicsFromFallback() {
114
125
  title: title ?? slug,
115
126
  summary: summary ?? ""
116
127
  };
117
- });
128
+ }) };
118
129
  }
119
130
  /** A single doc's body from cache, else from the bundled snapshot. */
120
131
  function bodyFromFallback(slug) {
@@ -129,7 +140,7 @@ function bodyFromFallback(slug) {
129
140
  }
130
141
  }
131
142
  }
132
- async function listTopics(refresh) {
143
+ async function listIndex(refresh) {
133
144
  const { apiUrl } = siteConfig();
134
145
  if (refresh || !cacheFresh()) {
135
146
  const data = await fetchJson(`${apiUrl}/control/v1/docs`);
@@ -138,10 +149,10 @@ async function listTopics(refresh) {
138
149
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
139
150
  ...data
140
151
  }));
141
- return data.topics;
152
+ return data;
142
153
  }
143
154
  }
144
- return topicsFromFallback();
155
+ return indexFromFallback();
145
156
  }
146
157
  async function readTopic(slug, refresh) {
147
158
  const { apiUrl } = siteConfig();
@@ -157,7 +168,7 @@ async function readTopic(slug, refresh) {
157
168
  const docsCommand = defineCommand({
158
169
  meta: {
159
170
  name: "docs",
160
- description: "Read the Canopy guides (offline-capable)"
171
+ description: "Read the Canopy docs (offline-capable)"
161
172
  },
162
173
  args: {
163
174
  topic: {
@@ -177,16 +188,27 @@ const docsCommand = defineCommand({
177
188
  const latest = latestKnownVersion();
178
189
  if (latest && compareSemver(version, latest) < 0) console.error(`Note: these docs describe CLI ${latest}; you have ${version} — commands or flags they mention may not exist here. Run \`canopy upgrade\`.\n`);
179
190
  if (!topic) {
180
- const topics = await listTopics(refresh);
181
- if (topics.length === 0) throw new Error("No docs available — check your connection, or reinstall the CLI.");
182
- const width = Math.max(...topics.map((t) => t.slug.length));
183
- console.log("Canopy docs — run `canopy docs <topic>`:\n");
184
- for (const t of topics) console.log(` ${t.slug.padEnd(width)} ${t.summary}`);
191
+ const index = await listIndex(refresh);
192
+ if (index.topics.length === 0) throw new Error("No docs available — check your connection, or reinstall the CLI.");
193
+ console.log("Canopy docs — run `canopy docs <topic>`:");
194
+ const groups = index.sections?.length ? index.sections : [{
195
+ key: "all",
196
+ title: "",
197
+ description: "",
198
+ topics: index.topics
199
+ }];
200
+ for (const section of groups) {
201
+ const heading = [section.title, section.description].filter(Boolean).join(" — ");
202
+ console.log(heading ? `\n${heading}` : "");
203
+ const width = Math.max(...section.topics.map((t) => t.slug.length));
204
+ for (const t of section.topics) console.log(` ${t.slug.padEnd(width)} ${t.summary}`);
205
+ }
185
206
  return;
186
207
  }
187
208
  const body = await readTopic(topic, refresh);
188
209
  if (body === void 0) {
189
- const known = (await listTopics(false)).map((t) => t.slug).join(", ");
210
+ const { topics } = await listIndex(false);
211
+ const known = topics.map((t) => t.slug).join(", ");
190
212
  throw new Error(`No doc "${topic}".${known ? ` Available: ${known}.` : ""}`);
191
213
  }
192
214
  console.log(body);
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "./package-yVoO2pq4.mjs";
2
+ import { t as version } from "./package-CPXtNnfc.mjs";
3
3
  import { r as siteHeaderLine, t as setInvocationProfile } from "./site-BUlQR117.mjs";
4
4
  import { a as notifyOfUpdate, o as runRefresh } from "./version-check-CcsA1QjI.mjs";
5
5
  import { defineCommand, runMain } from "citty";
@@ -63,10 +63,10 @@ const main = defineCommand({
63
63
  login: () => import("./login-C1x1l3qg.mjs").then((m) => m.loginCommand),
64
64
  whoami: () => import("./login-C1x1l3qg.mjs").then((m) => m.whoamiCommand),
65
65
  logout: () => import("./login-C1x1l3qg.mjs").then((m) => m.logoutCommand),
66
- create: () => import("./projects-D2fDeWNU.mjs").then((m) => m.createCommand),
67
- init: () => import("./projects-D2fDeWNU.mjs").then((m) => m.initCommand),
68
- projects: () => import("./projects-D2fDeWNU.mjs").then((m) => m.projectsCommand),
69
- delete: () => import("./projects-D2fDeWNU.mjs").then((m) => m.deleteCommand),
66
+ create: () => import("./projects-C9TBoiW7.mjs").then((m) => m.createCommand),
67
+ init: () => import("./projects-C9TBoiW7.mjs").then((m) => m.initCommand),
68
+ projects: () => import("./projects-C9TBoiW7.mjs").then((m) => m.projectsCommand),
69
+ delete: () => import("./projects-C9TBoiW7.mjs").then((m) => m.deleteCommand),
70
70
  dev: () => import("./dev-D6Sy15Wv.mjs").then((m) => m.devCommand),
71
71
  deploy: () => import("./deploy-ClioT9ZC.mjs").then((m) => m.deployCommand),
72
72
  promote: () => import("./deploy-ClioT9ZC.mjs").then((m) => m.promoteCommand),
@@ -78,10 +78,10 @@ const main = defineCommand({
78
78
  db: () => import("./db-D3RKaLVU.mjs").then((m) => m.dbCommand),
79
79
  usage: () => import("./usage-wpew0a2M.mjs").then((m) => m.usageCommand),
80
80
  open: () => import("./open-CLSh6oez.mjs").then((m) => m.openCommand),
81
- docs: () => import("./docs-DQmUReJR.mjs").then((m) => m.docsCommand),
82
- skill: () => import("./skill-12Ga-2UT.mjs").then((m) => m.skillCommand),
83
- upgrade: () => import("./upgrade-Du6U0xjp.mjs").then((m) => m.upgradeCommand),
84
- logs: () => import("./logs-DBLDS3aQ.mjs").then((m) => m.logsCommand)
81
+ docs: () => import("./docs-DhAz6QWS.mjs").then((m) => m.docsCommand),
82
+ skill: () => import("./skill-BCX4cUeP.mjs").then((m) => m.skillCommand),
83
+ upgrade: () => import("./upgrade-jLu7jI0r.mjs").then((m) => m.upgradeCommand),
84
+ logs: () => import("./logs-DuzM-_Rn.mjs").then((m) => m.logsCommand)
85
85
  }
86
86
  });
87
87
  if (process.argv[2] !== "upgrade") notifyOfUpdate(version);
@@ -34,7 +34,7 @@ async function fetchLogs(slug, params) {
34
34
  if (params.limit) query.set("limit", String(params.limit));
35
35
  return withContext(apiRequest("GET", `/projects/${slug}/logs?${query}`), {
36
36
  action: `read worker logs for "${slug}"`,
37
- fixes: { not_supported_on_target: "Worker logs aren't available on this site yet — GCP sites only." }
37
+ fixes: { not_supported_on_target: "Worker logs aren't available on this site yet." }
38
38
  });
39
39
  }
40
40
  const logsCommand = defineCommand({
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.7.5";
2
+ var version = "0.7.6";
3
3
  //#endregion
4
4
  export { version as t };
@@ -30,10 +30,9 @@ const TEMPLATES = [
30
30
  },
31
31
  {
32
32
  id: "worker",
33
- label: "React SPA + backend Worker",
34
- hint: "adds Hono handlers in worker/ — Phase 2 preview",
35
- needsInstall: true,
36
- hidden: true
33
+ label: "React SPA + backend worker",
34
+ hint: "spa plus server-side handlers in worker/ — for secrets, schedules, external APIs",
35
+ needsInstall: true
37
36
  }
38
37
  ];
39
38
  function templatesRoot() {
@@ -134,7 +133,7 @@ const createCommand = defineCommand({
134
133
  if (scaffold && !args.template && process.stdin.isTTY) {
135
134
  const id = unwrap(await p.select({
136
135
  message: "Template",
137
- options: TEMPLATES.filter((t) => !t.hidden).map((t) => ({
136
+ options: TEMPLATES.map((t) => ({
138
137
  value: t.id,
139
138
  label: t.label,
140
139
  hint: t.hint
@@ -142,7 +141,6 @@ const createCommand = defineCommand({
142
141
  }));
143
142
  template = TEMPLATES.find((t) => t.id === id) ?? template;
144
143
  }
145
- if (template.hidden) p.log.warn("Per-project Workers are not deployable yet (Phase 2) — `canopy deploy` publishes the frontend only for now.");
146
144
  const targetDir = resolve(slug);
147
145
  if (scaffold && existsSync(targetDir)) throw new Error(`Directory ./${slug} already exists — remove it, or use --no-scaffold to only register.`);
148
146
  const spin = p.spinner();
@@ -241,7 +239,7 @@ const initCommand = defineCommand({
241
239
  if (!args.template && process.stdin.isTTY) {
242
240
  const id = unwrap(await p.select({
243
241
  message: "Template",
244
- options: TEMPLATES.filter((t) => !t.hidden).map((t) => ({
242
+ options: TEMPLATES.map((t) => ({
245
243
  value: t.id,
246
244
  label: t.label,
247
245
  hint: t.hint
@@ -249,7 +247,6 @@ const initCommand = defineCommand({
249
247
  }));
250
248
  template = TEMPLATES.find((t) => t.id === id) ?? template;
251
249
  }
252
- if (template.hidden) p.log.warn("Per-project Workers are not deployable yet (Phase 2) — `canopy deploy` publishes the frontend only for now.");
253
250
  scaffoldTemplate(template.id, targetDir, {
254
251
  name: project.name,
255
252
  slug
@@ -75,10 +75,12 @@ canopy docs # list all topics
75
75
  canopy docs deploy # print one topic
76
76
  ```
77
77
 
78
- Available topics include: `getting-started`, `cli` (full command reference),
79
- `deploy`, `dev`, `data`, `ci`, `troubleshooting`. Always prefer `canopy docs`
80
- and `canopy <command> --help` over guessing flags — they are the source of
81
- truth and never go stale.
78
+ The listing is grouped by section: guides (`getting-started`, `deploy`, `dev`,
79
+ `data`, `ci`, `troubleshooting`, …), platform feature pages (`platform-*`), a
80
+ per-command CLI reference (`cli-<command>`, plus `cli` for the one-page
81
+ overview), and the SDK reference (`sdk-*`). Always prefer `canopy docs` and
82
+ `canopy <command> --help` over guessing flags — they are the source of truth
83
+ and never go stale.
82
84
 
83
85
  ## Command map (quick orientation — see `canopy docs cli` for detail)
84
86
 
@@ -133,10 +135,10 @@ Prefer **`spa`** the moment either is true — which covers most real projects:
133
135
  - **The app will grow.** `spa` is Vite + React + TypeScript, giving components,
134
136
  routing, and state a real home; `static` has no build step to organise into.
135
137
 
136
- Use **`worker`** (`--template worker`; hidden from the picker) only when you
137
- need server-side backend code — e.g. calling an external API with a secret the
138
- browser can't hold. Per-project Workers are a Phase 2 preview (frontend deploys
139
- now; `worker/` is picked up once the platform supports it).
138
+ Use **`worker`** when you need server-side backend code — e.g. calling an
139
+ external API with a secret the browser can't hold, or running scheduled jobs.
140
+ It's `spa` plus Hono-style handlers in `worker/`; `canopy deploy` publishes
141
+ the frontend and the worker together.
140
142
 
141
143
  Non-interactive: `canopy create "My App" --template spa`. **When unsure between
142
144
  `static` and `spa`, pick `spa`.**
@@ -1,4 +1,4 @@
1
- import { t as version } from "./package-yVoO2pq4.mjs";
1
+ import { t as version } from "./package-CPXtNnfc.mjs";
2
2
  import { n as reportErrors } from "./ui-CpdtK7mt.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { cpSync, existsSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
@@ -5,9 +5,6 @@ A Vite + React single-page app plus a per-project backend Worker on
5
5
  projects. Everything is served behind company login; there is no
6
6
  infrastructure to manage and none should be added.
7
7
 
8
- > On GCP, `canopy deploy` publishes the frontend **and** the `worker/`
9
- > backend (Cloud Run). Cloudflare WfP upload is still Phase 2.
10
-
11
8
  ## Canopy skill
12
9
 
13
10
  The full SDK reference (auth, db, blob, ai) and platform guardrails ship as an
@@ -4,14 +4,10 @@ A [Canopy](https://dashboard.thanarie.dev) project — Vite + React with a
4
4
  backend Worker (`worker/`). Live (behind company login) at
5
5
  https://{{slug}}.thanarie.dev after the first `canopy deploy`.
6
6
 
7
- > Per-project Workers are a Canopy Phase 2 capability: `canopy deploy`
8
- > publishes the frontend only for now — `worker/` deploys automatically once
9
- > the platform supports it.
10
-
11
7
  - `npm install` — once, then:
12
8
  - `canopy dev` — develop locally against the live platform (real data!)
13
9
  - `canopy dev --local [--pull]` — offline sandbox with local data instead
14
- - `canopy deploy` — build and publish `dist/`
10
+ - `canopy deploy` — build and publish the frontend and the `worker/` backend
15
11
  - `AGENTS.md` — project guardrails and skill setup for coding agents
16
12
 
17
13
  Push-to-main deploys are prepared in `.github/workflows/canopy-deploy.yml`
@@ -112,7 +112,7 @@ const upgradeCommand = defineCommand({
112
112
  const spec = `${PACKAGE_NAME}@${args.version ?? "latest"}`;
113
113
  const command = pmCommand(pm);
114
114
  const cmd = installArgs(pm, spec);
115
- const { skillInstalled } = await import("./skill-12Ga-2UT.mjs");
115
+ const { skillInstalled } = await import("./skill-BCX4cUeP.mjs");
116
116
  const refreshSkill = skillInstalled(process.cwd());
117
117
  console.log(`Upgrading via ${command}: ${command} ${cmd.join(" ")}`);
118
118
  await run(command, cmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediamonks/canopy-cli",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "Canopy CLI — create, develop and deploy Canopy projects.",
5
5
  "bin": {
6
6
  "canopy": "./dist/index.mjs"
@@ -20,8 +20,8 @@
20
20
  "esbuild": "^0.28.1",
21
21
  "hono": "^4.8.0",
22
22
  "vite-server": "npm:vite@^7",
23
- "@mediamonks/canopy": "0.0.4",
24
- "@mediamonks/canopy-data-plane": "0.0.2"
23
+ "@mediamonks/canopy-data-plane": "0.0.2",
24
+ "@mediamonks/canopy": "0.0.4"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/node": "^26.1.1",