@solcreek/cli 0.4.22 → 0.4.24

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/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @solcreek/cli
2
2
 
3
+ ## 0.4.24
4
+
5
+ ### Fixes / DX
6
+
7
+ - **`creek init --db` adds a database without prompting.** Non-interactive
8
+ runs (CI, coding agents) previously skipped the "Add a database?"
9
+ question silently and produced a config without one. With `--db`, init
10
+ writes `[resources] database = true` and `[build].worker`, and scaffolds
11
+ the worker/index.ts example. When the prompt is skipped, init now says
12
+ so and points at `--db` (`--json` output gets a `databasePromptSkipped`
13
+ field and a breadcrumb).
14
+
15
+ - **`creek init <name>` sets the project name.** The positional name was
16
+ ignored and the directory basename used instead; `--name` was the only
17
+ working form.
18
+
19
+ - **`creek doctor` catches the resources-without-worker mismatch.** Two new
20
+ findings: declaring resources with no worker entry (the deploy would be a
21
+ static SPA where `/api/*` serves index.html — warn), and a worker file on
22
+ disk that no config points at, so it would never deploy (info).
23
+
24
+ - **`creek deploy` warns before shipping a static SPA that declares
25
+ resources**, naming the bindings and pointing at `[build].worker` — the
26
+ same mismatch doctor flags, surfaced even when doctor never ran.
27
+
28
+ - **The "nothing to deploy" finding now presents both fixes.** Build output
29
+ and worker entry are separate inputs; the guidance previously steered
30
+ only toward re-running the build, leaving API-route projects chasing the
31
+ wrong one.
32
+
33
+ ## 0.4.23
34
+
35
+ ### Fixes / DX
36
+
37
+ - **`creek init` help now lists what it creates** — creek.toml (project
38
+ name, build command/output, detected framework) plus a worker/index.ts
39
+ example when you add a database — so first-timers know what to expect.
40
+
41
+ - **`creek doctor --json` prints a one-line summary to stderr** when a human
42
+ is watching, instead of only a wall of JSON. stdout stays pure JSON for
43
+ agents and pipes; CI / redirected runs stay silent.
44
+
45
+ - **The two SQLite doctor findings cross-reference each other.** A project
46
+ with both better-sqlite3 and Prisma no longer reads as two unrelated
47
+ problems — each notes it's the same Cloudflare-Workers SQLite migration.
48
+
49
+ - **`creek db/storage/cache attach --to` shows a value placeholder** in its
50
+ usage (`--to=<project>`) instead of a bare `--to`.
51
+
3
52
  ## 0.4.22
4
53
 
5
54
  ### Fixes / DX
@@ -55,6 +55,15 @@ export const doctorCommand = defineCommand({
55
55
  const ctx = buildDoctorContext(cwd);
56
56
  const report = runDoctor(ctx);
57
57
  if (jsonMode) {
58
+ // A one-line human summary on stderr so stdout stays pure JSON for
59
+ // agents/pipes, while a person who pipes this in a terminal isn't
60
+ // staring at a wall of JSON. Only when stderr is a TTY (a human is
61
+ // watching) — fully-redirected/CI runs stay silent.
62
+ if (process.stderr.isTTY) {
63
+ const { error, warn, info } = report.summary;
64
+ const counts = `${error} error${s(error)}, ${warn} warning${s(warn)}, ${info} info`;
65
+ process.stderr.write(`creek doctor: ${report.ok ? "ok" : "issues found"} — ${counts}\n`);
66
+ }
58
67
  jsonOutput({
59
68
  ok: report.ok,
60
69
  cwd,
@@ -160,7 +169,9 @@ function s(n) {
160
169
  // CK_FIX_HINTS). Keep all three in sync when adding a new CK-* rule.
161
170
  const CK_FIX_HINTS = {
162
171
  "CK-NO-CONFIG": "Run `creek init` to scaffold a creek.toml, or cd to a directory that contains creek.toml / wrangler.* / package.json / index.html.",
163
- "CK-NOTHING-TO-DEPLOY": "Run the project's build command so there's output in [build].output, or set [build].command in creek.toml if the project needs one.",
172
+ "CK-NOTHING-TO-DEPLOY": "Run the project's build command so there's output in [build].output, or set [build].command in creek.toml if the project needs one. If the project has server code / API routes, also set [build].worker — the build alone never declares it.",
173
+ "CK-RESOURCES-NO-WORKER": "Resources are declared but no worker entry — the deploy is a static SPA and /api/* serves index.html. Set [build].worker in creek.toml (e.g. worker = \"worker/index.ts\"), or remove [resources] if the site is purely static.",
174
+ "CK-WORKER-UNDECLARED": "A worker-shaped file exists on disk but no worker entry is declared, so it will not be deployed. Point [build].worker in creek.toml at it, or delete the file if unused.",
164
175
  "CK-DB-DUAL-DRIVER-SPLIT": "Consolidate the split db.local.ts + db.prod.ts files. Share schema.ts and routes.ts; keep only thin boot files (server/local.ts for dev, server/worker.ts for prod) that differ in driver setup. See examples/vite-react-drizzle.",
165
176
  "CK-SYNC-SQLITE": "better-sqlite3 is synchronous and won't run on Workers. Migrate to an async ORM with a D1 adapter — Drizzle or Kysely are the drop-in paths.",
166
177
  "CK-PRISMA-SQLITE": "Prisma's SQLite datasource isn't supported on Cloudflare Workers. Switch to Drizzle or Kysely with a D1 adapter.",
@@ -10,10 +10,15 @@ export declare const initCommand: import("citty").CommandDef<{
10
10
  default: boolean;
11
11
  };
12
12
  name: {
13
- type: "string";
13
+ type: "positional";
14
14
  description: string;
15
15
  required: false;
16
16
  };
17
+ db: {
18
+ type: "boolean";
19
+ description: string;
20
+ default: false;
21
+ };
17
22
  adopt: {
18
23
  type: "string";
19
24
  description: string;
@@ -11,14 +11,19 @@ import { ensureGitignoreEntries } from "../utils/gitignore.js";
11
11
  export const initCommand = defineCommand({
12
12
  meta: {
13
13
  name: "init",
14
- description: "Initialize a new Creek project (or register a self-host creekd via --adopt / --hostkey-fingerprint)",
14
+ description: "Initialize a new Creek project — writes creek.toml (project name, build command/output, detected framework) and, if you add a database (interactive prompt or --db), a worker/index.ts example. Or register a self-host creekd via --adopt / --hostkey-fingerprint.",
15
15
  },
16
16
  args: {
17
17
  name: {
18
- type: "string",
18
+ type: "positional",
19
19
  description: "Project name (project init) OR host short-name (self-host init)",
20
20
  required: false,
21
21
  },
22
+ db: {
23
+ type: "boolean",
24
+ description: "Add a database without prompting — writes [resources] database = true and scaffolds worker/index.ts. Required to get the database path in non-interactive runs (the prompt is skipped there).",
25
+ default: false,
26
+ },
22
27
  adopt: {
23
28
  type: "string",
24
29
  description: "TOFU-pin a creekd host at <addr> (Path B). Fetches GET /v1/hostkey, prompts to verify, writes ~/.creek/hosts.json.",
@@ -62,10 +67,20 @@ export const initCommand = defineCommand({
62
67
  }
63
68
  const defaultName = basename(cwd).toLowerCase().replace(/[^a-z0-9-]/g, "-");
64
69
  const name = args.name ?? defaultName;
65
- // Ask about database
66
- let useDb = false;
67
- if (!jsonMode && !shouldAutoConfirm(args)) {
68
- useDb = await consola.prompt("Add a database?", { type: "confirm" });
70
+ // Ask about database. --db answers without prompting; otherwise the
71
+ // prompt only fires in interactive runs. In non-interactive runs
72
+ // (agents, CI — jsonMode or auto-confirm) the question is skipped,
73
+ // and we say so: silently defaulting to "no database" is how users
74
+ // end up hand-editing creek.toml and missing [build].worker.
75
+ let useDb = args.db === true;
76
+ let dbPromptSkipped = false;
77
+ if (!useDb) {
78
+ if (!jsonMode && !shouldAutoConfirm(args)) {
79
+ useDb = await consola.prompt("Add a database?", { type: "confirm" });
80
+ }
81
+ else {
82
+ dbPromptSkipped = true;
83
+ }
69
84
  }
70
85
  const config = {
71
86
  project: {
@@ -127,13 +142,19 @@ export default app;
127
142
  }
128
143
  }
129
144
  if (jsonMode) {
130
- jsonOutput({ ok: true, name, framework: framework ?? null, database: useDb, path: configPath }, 0, [
145
+ jsonOutput({ ok: true, name, framework: framework ?? null, database: useDb, databasePromptSkipped: dbPromptSkipped, path: configPath }, 0, [
146
+ ...(dbPromptSkipped
147
+ ? [{ command: "creek init --db", description: "Re-run with a database — writes [resources] and [build].worker, scaffolds worker/index.ts" }]
148
+ : []),
131
149
  { command: "creek deploy", description: "Deploy the project" },
132
150
  { command: "creek dev", description: "Start local development server" },
133
151
  ]);
134
152
  }
135
153
  consola.success(`Created creek.toml for "${name}"`);
136
154
  if (!jsonMode) {
155
+ if (dbPromptSkipped) {
156
+ consola.info("Skipped the database prompt (non-interactive). Re-run with `creek init --db` to add one — it writes [resources] and [build].worker and scaffolds worker/index.ts.");
157
+ }
137
158
  console.log("");
138
159
  consola.info(" Next steps:");
139
160
  consola.info(" creek deploy Deploy to production");
@@ -146,7 +167,7 @@ export default app;
146
167
  *
147
168
  * Two paths:
148
169
  *
149
- * Path B: --adopt=<addr> [--name <name>]
170
+ * Path B: --adopt=<addr> [<name>]
150
171
  * Fetches GET /v1/hostkey, recomputes the fingerprint from the
151
172
  * returned publicKey, prompts the operator to verify against
152
173
  * the provider console / paper bundle, and writes the pinned
@@ -271,7 +292,7 @@ async function initHostAdopt(addr, pastedFingerprint, hostName, jsonMode, autoCo
271
292
  * Derive a short host name from the adopt address. e.g.
272
293
  * --adopt=5.75.231.44:9080 → "h-5-75-231-44"
273
294
  * --adopt=my.host.dev → "h-my-host-dev"
274
- * Operator may override via --name.
295
+ * Operator may override via the positional name argument.
275
296
  */
276
297
  function defaultHostName(addr) {
277
298
  const noScheme = addr.replace(/^https?:\/\//, "").replace(/[:/].*$/, "");
@@ -80,7 +80,7 @@ export function createResourceCommand(opts) {
80
80
  meta: { name: "attach", description: `Attach a ${label} to a project under the given ENV var name` },
81
81
  args: {
82
82
  name: { type: "positional", description: `${label} name (as shown by \`creek ${cmdName} ls\`)`, required: true },
83
- to: { type: "string", description: "Project slug to attach to", required: true },
83
+ to: { type: "string", description: "Project slug to attach to", required: true, valueHint: "project" },
84
84
  as: { type: "string", description: `ENV var name (uppercase, default: ${defaultBinding})`, default: defaultBinding },
85
85
  ...globalArgs,
86
86
  },
@@ -245,6 +245,15 @@ export async function prepareDeployBundle(input) {
245
245
  const effectiveEntrypoint = astroAdapter
246
246
  ? "entry.mjs"
247
247
  : (plan.worker.entry ?? null);
248
+ // Resources declared but the deploy carries no server code: the
249
+ // bindings get provisioned with nothing able to read them, and
250
+ // /api/* serves static assets (unknown paths fall back to
251
+ // index.html). Same condition as doctor's CK-RESOURCES-NO-WORKER —
252
+ // repeated here because most deploys never run `creek doctor` first.
253
+ const resourceBindings = resolved.bindings.filter((b) => b.type === "d1" || b.type === "r2" || b.type === "kv" || b.type === "ai");
254
+ if (effectiveRenderMode === "spa" && resourceBindings.length > 0) {
255
+ consola.warn(` Resources declared (${resourceBindings.map((b) => `env.${b.name}`).join(", ")}) but no worker entry — deploying as a static SPA. /api/* will serve index.html, not server code. If that's unintended, set [build].worker in creek.toml (details: creek doctor).`);
256
+ }
248
257
  return {
249
258
  plan,
250
259
  framework,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solcreek/cli",
3
- "version": "0.4.22",
3
+ "version": "0.4.24",
4
4
  "description": "CLI for the Creek deployment platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,7 +33,7 @@
33
33
  "esbuild": "^0.25.0",
34
34
  "smol-toml": "^1.3.1",
35
35
  "ws": "^8.20.0",
36
- "@solcreek/sdk": "0.4.10"
36
+ "@solcreek/sdk": "0.4.12"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@testing-library/dom": "^10.4.1",