@solcreek/cli 0.3.6 → 0.3.8

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.
@@ -29,11 +29,6 @@ export declare const deployCommand: import("citty").CommandDef<{
29
29
  description: string;
30
30
  default: false;
31
31
  };
32
- demo: {
33
- type: "boolean";
34
- description: string;
35
- default: false;
36
- };
37
32
  }>;
38
33
  /**
39
34
  * Patch bare Node.js module imports (e.g. `from "fs"`) to use the `node:` prefix
@@ -45,11 +45,6 @@ export const deployCommand = defineCommand({
45
45
  description: "Skip the build step",
46
46
  default: false,
47
47
  },
48
- demo: {
49
- type: "boolean",
50
- description: "Deploy a sample site to see Creek in action",
51
- default: false,
52
- },
53
48
  ...globalArgs,
54
49
  template: {
55
50
  type: "string",
@@ -64,11 +59,7 @@ export const deployCommand = defineCommand({
64
59
  },
65
60
  async run({ args }) {
66
61
  const jsonMode = resolveJsonMode(args);
67
- // --- Demo deploy (zero-friction showcase) ---
68
- if (args.demo) {
69
- return await deployDemo(jsonMode);
70
- }
71
- // --- Ensure ToS accepted (all non-demo paths) ---
62
+ // --- Ensure ToS accepted ---
72
63
  const autoConfirm = shouldAutoConfirm(args);
73
64
  const tos = await ensureTosAccepted(autoConfirm);
74
65
  // --- Template deploy ---
@@ -130,8 +121,8 @@ export const deployCommand = defineCommand({
130
121
  if (jsonMode)
131
122
  jsonOutput({ error: "no_project", message: "No project found in this directory" }, 1, NO_PROJECT_BREADCRUMBS);
132
123
  consola.info("No project found in this directory.\n");
133
- consola.info(" creek deploy ./dist Deploy a build output directory");
134
- consola.info(" creek deploy --demo Deploy a sample site (see Creek in 5 seconds)");
124
+ consola.info(" creek deploy ./dist Deploy a build output directory");
125
+ consola.info(" npx create-creek-app Create a new project from a template");
135
126
  consola.info("");
136
127
  consola.info("Or create a project first:");
137
128
  consola.info(" npm create vite@latest my-app && cd my-app && npx creek deploy");
@@ -199,7 +190,7 @@ async function deployRepoUrl(input, options) {
199
190
  if (err instanceof RepoUrlError || err instanceof GitCloneError) {
200
191
  if (jsonMode)
201
192
  jsonOutput({ error: "repo_deploy_failed", message: err.message }, 1, [
202
- { command: "creek deploy --demo", description: "Deploy a sample site instead" },
193
+ { command: "npx create-creek-app", description: "Create a new project from a template" },
203
194
  ]);
204
195
  consola.error(err.message);
205
196
  process.exit(1);
@@ -208,84 +199,6 @@ async function deployRepoUrl(input, options) {
208
199
  }
209
200
  }
210
201
  // ============================================================================
211
- // Demo deploy — pre-built page, zero dependencies, instant
212
- // ============================================================================
213
- const DEMO_HTML = `<!DOCTYPE html>
214
- <html lang="en">
215
- <head>
216
- <meta charset="utf-8">
217
- <meta name="viewport" content="width=device-width, initial-scale=1">
218
- <title>Creek Deploy Demo</title>
219
- <style>
220
- *{margin:0;padding:0;box-sizing:border-box}
221
- body{font-family:system-ui,-apple-system,sans-serif;background:#0a0a0a;color:#f5f5f5;min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center}
222
- .card{max-width:480px;text-align:center;padding:3rem 2rem}
223
- h1{font-size:2rem;font-weight:700;letter-spacing:-0.03em;margin-bottom:0.5rem}
224
- .accent{background:linear-gradient(135deg,#38bdf8,#818cf8);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
225
- p{color:#888;line-height:1.6;margin-top:1rem}
226
- .meta{margin-top:2rem;font-size:0.85rem;color:#555}
227
- .cta{display:inline-block;margin-top:1.5rem;background:linear-gradient(135deg,#2563eb,#3b82f6);color:#fff;padding:10px 24px;border-radius:8px;text-decoration:none;font-weight:600;font-size:0.9rem;transition:opacity 0.15s}
228
- .cta:hover{opacity:0.9}
229
- code{background:#1a1a2e;padding:2px 8px;border-radius:4px;font-size:0.85rem;color:#a5b4fc}
230
- .pulse{width:12px;height:12px;background:#22c55e;border-radius:50%;display:inline-block;margin-right:8px;animation:pulse 2s infinite}
231
- @keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}
232
- </style>
233
- </head>
234
- <body>
235
- <div class="card">
236
- <h1><span class="accent">Creek</span> is live.</h1>
237
- <p>This site was deployed to the edge in seconds — no build step, no config, no account.</p>
238
- <p style="margin-top:1.5rem"><span class="pulse"></span>Running on Cloudflare's global network</p>
239
- <p class="meta">Now try it with your own project:</p>
240
- <p style="margin-top:0.5rem"><code>cd your-project && npx creek deploy</code></p>
241
- <a href="https://creek.dev" class="cta">Learn more about Creek</a>
242
- </div>
243
- <script>document.title="Creek Deploy Demo — "+new Date().toLocaleTimeString()</script>
244
- </body>
245
- </html>`;
246
- async function deployDemo(jsonMode) {
247
- if (!jsonMode)
248
- consola.start("Deploying demo site...");
249
- try {
250
- const result = await sandboxDeploy({
251
- assets: { "index.html": Buffer.from(DEMO_HTML).toString("base64") },
252
- source: "cli-demo",
253
- });
254
- if (!jsonMode)
255
- consola.start("Waiting for deployment...");
256
- const status = await pollSandboxStatus(result.statusUrl);
257
- if (jsonMode) {
258
- jsonOutput({
259
- ok: true,
260
- sandboxId: result.sandboxId,
261
- url: status.previewUrl,
262
- deployDurationMs: status.deployDurationMs,
263
- expiresAt: result.expiresAt,
264
- mode: "demo",
265
- }, 0, [
266
- { command: `creek status ${result.sandboxId}`, description: "Check sandbox status" },
267
- { command: `creek claim ${result.sandboxId}`, description: "Claim as permanent project" },
268
- ]);
269
- }
270
- const duration = status.deployDurationMs
271
- ? `in ${(status.deployDurationMs / 1000).toFixed(1)}s`
272
- : "in seconds";
273
- consola.success(`⬡ Live ${duration} → ${status.previewUrl}`);
274
- consola.info("");
275
- consola.info("That's Creek. Now deploy your own project:");
276
- consola.info(" cd your-project && npx creek deploy");
277
- }
278
- catch (err) {
279
- const message = err instanceof Error ? err.message : "Demo deploy failed";
280
- if (jsonMode)
281
- jsonOutput({ ok: false, error: "deploy_failed", message }, 1, [
282
- { command: "creek deploy --demo", description: "Retry demo deploy" },
283
- ]);
284
- consola.error(message);
285
- process.exit(1);
286
- }
287
- }
288
- // ============================================================================
289
202
  // Directory deploy — deploy pre-built static files directly
290
203
  // ============================================================================
291
204
  async function deployDirectory(dir, jsonMode, tos) {
@@ -296,8 +209,8 @@ async function deployDirectory(dir, jsonMode, tos) {
296
209
  if (jsonMode)
297
210
  jsonOutput({ ok: false, error: "no_files", message: `No files found in ${dir}` }, 1, NO_PROJECT_BREADCRUMBS);
298
211
  consola.error(`No files found in ${dir}\n`);
299
- consola.info(" creek deploy ./dist Deploy a build output directory");
300
- consola.info(" creek deploy --demo Deploy a sample site (see Creek in 5 seconds)");
212
+ consola.info(" creek deploy ./dist Deploy a build output directory");
213
+ consola.info(" npx create-creek-app Create a new project from a template");
301
214
  process.exit(1);
302
215
  }
303
216
  if (!jsonMode) {
@@ -814,6 +727,10 @@ async function deployAuthenticated(cwd, resolved, token, skipBuild, jsonMode = f
814
727
  if (res.url && res.previewUrl) {
815
728
  consola.info(` Preview: ${res.previewUrl}`);
816
729
  }
730
+ // Contextual next-step hints (non-JSON only)
731
+ if (!jsonMode) {
732
+ printNextStepHint(renderMode, resolved);
733
+ }
817
734
  return;
818
735
  }
819
736
  if (status === "failed") {
@@ -853,6 +770,24 @@ async function deployAuthenticated(cwd, resolved, token, skipBuild, jsonMode = f
853
770
  throw err;
854
771
  }
855
772
  }
773
+ // --- Hints ---
774
+ /**
775
+ * Print next-step hints after deploy.
776
+ * Shows capability overview — lets agents and developers discover what Creek offers.
777
+ */
778
+ function printNextStepHint(renderMode, config) {
779
+ const hasDb = config.bindings.some((b) => b.type === "d1");
780
+ if (hasDb)
781
+ return; // Already using Creek runtime — no hint needed
782
+ console.log("");
783
+ consola.info(" Next steps:");
784
+ consola.info(" import { db } from \"creek\" Database (managed, no config needed)");
785
+ consola.info(" import { define } from \"d1-schema\" Define your tables (auto-created)");
786
+ consola.info(" import { kv } from \"creek\" Key-value storage");
787
+ consola.info(" import { ai } from \"creek\" AI inference");
788
+ consola.info(" creek dev Local development");
789
+ consola.info(" https://creek.dev/docs Documentation");
790
+ }
856
791
  // --- Helpers ---
857
792
  /** Node.js built-in modules that may appear as bare imports in bundled workers. */
858
793
  const NODE_BUILTINS = new Set([
@@ -1,6 +1,6 @@
1
1
  import { defineCommand } from "citty";
2
2
  import consola from "consola";
3
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
4
4
  import { join, basename } from "node:path";
5
5
  import { stringify } from "smol-toml";
6
6
  import { detectFramework } from "@solcreek/sdk";
@@ -44,6 +44,11 @@ export const initCommand = defineCommand({
44
44
  }
45
45
  const defaultName = basename(cwd).toLowerCase().replace(/[^a-z0-9-]/g, "-");
46
46
  const name = args.name ?? defaultName;
47
+ // Ask about database
48
+ let useDb = false;
49
+ if (!jsonMode && !shouldAutoConfirm(args)) {
50
+ useDb = await consola.prompt("Add a database?", { type: "confirm" });
51
+ }
47
52
  const config = {
48
53
  project: {
49
54
  name,
@@ -52,22 +57,73 @@ export const initCommand = defineCommand({
52
57
  build: {
53
58
  command: "npm run build",
54
59
  output: "dist",
60
+ ...(useDb ? { worker: "worker/index.ts" } : {}),
55
61
  },
56
62
  resources: {
57
- d1: false,
63
+ d1: useDb,
58
64
  kv: false,
59
65
  r2: false,
60
66
  },
61
67
  };
62
68
  writeFileSync(configPath, stringify(config));
69
+ // Scaffold worker + d1-schema example when database enabled
70
+ if (useDb) {
71
+ const workerDir = join(cwd, "worker");
72
+ const workerFile = join(workerDir, "index.ts");
73
+ if (!existsSync(workerFile)) {
74
+ mkdirSync(workerDir, { recursive: true });
75
+ writeFileSync(workerFile, `import { Hono } from "hono";
76
+ import { db } from "creek";
77
+ import { define } from "d1-schema";
78
+
79
+ const app = new Hono();
80
+
81
+ // Define your tables — auto-created on first request
82
+ app.use("*", async (c, next) => {
83
+ await define(c.env.DB, {
84
+ users: {
85
+ id: "text primary key",
86
+ email: "text unique not null",
87
+ name: "text not null",
88
+ created_at: "text default (datetime('now'))",
89
+ },
90
+ });
91
+ return next();
92
+ });
93
+
94
+ app.get("/api/users", async (c) => {
95
+ const users = await db.query("SELECT * FROM users");
96
+ return c.json(users);
97
+ });
98
+
99
+ app.post("/api/users", async (c) => {
100
+ const { email, name } = await c.req.json();
101
+ const id = crypto.randomUUID().slice(0, 16);
102
+ await db.mutate("INSERT INTO users (id, email, name) VALUES (?, ?, ?)", id, email, name);
103
+ return c.json({ id, email, name });
104
+ });
105
+
106
+ export default app;
107
+ `);
108
+ if (!jsonMode) {
109
+ consola.success("Created worker/index.ts with database example");
110
+ consola.info(" Install dependencies: npm install hono creek d1-schema");
111
+ }
112
+ }
113
+ }
63
114
  if (jsonMode) {
64
- jsonOutput({ ok: true, name, framework: framework ?? null, path: configPath }, 0, [
115
+ jsonOutput({ ok: true, name, framework: framework ?? null, database: useDb, path: configPath }, 0, [
65
116
  { command: "creek deploy", description: "Deploy the project" },
66
- { command: "creek env set <KEY> <VALUE>", description: "Set an environment variable" },
67
117
  { command: "creek dev", description: "Start local development server" },
68
118
  ]);
69
119
  }
70
120
  consola.success(`Created creek.toml for "${name}"`);
121
+ if (!jsonMode) {
122
+ console.log("");
123
+ consola.info(" Next steps:");
124
+ consola.info(" creek deploy Deploy to production");
125
+ consola.info(" creek dev Start local development");
126
+ }
71
127
  },
72
128
  });
73
129
  //# sourceMappingURL=init.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solcreek/cli",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "CLI for the Creek deployment platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,7 +32,7 @@
32
32
  "directory": "packages/cli"
33
33
  },
34
34
  "dependencies": {
35
- "@solcreek/sdk": "^0.1.0-alpha.4",
35
+ "@solcreek/sdk": ">=0.1.0-alpha.4",
36
36
  "citty": "^0.1.6",
37
37
  "consola": "^3.4.2",
38
38
  "esbuild": "^0.25.0",