flingit 0.0.14 → 0.0.18

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 (127) hide show
  1. package/README.md +2 -1
  2. package/dist/cli/commands/cron.d.ts +29 -0
  3. package/dist/cli/commands/cron.d.ts.map +1 -1
  4. package/dist/cli/commands/cron.js +54 -37
  5. package/dist/cli/commands/cron.js.map +1 -1
  6. package/dist/cli/commands/db.d.ts.map +1 -1
  7. package/dist/cli/commands/db.js +15 -19
  8. package/dist/cli/commands/db.js.map +1 -1
  9. package/dist/cli/commands/dev.d.ts +1 -0
  10. package/dist/cli/commands/dev.d.ts.map +1 -1
  11. package/dist/cli/commands/dev.js +344 -86
  12. package/dist/cli/commands/dev.js.map +1 -1
  13. package/dist/cli/commands/feedback.js +3 -3
  14. package/dist/cli/commands/feedback.js.map +1 -1
  15. package/dist/cli/commands/init.d.ts.map +1 -1
  16. package/dist/cli/commands/init.js +9 -2
  17. package/dist/cli/commands/init.js.map +1 -1
  18. package/dist/cli/commands/launch.d.ts +45 -3
  19. package/dist/cli/commands/launch.d.ts.map +1 -1
  20. package/dist/cli/commands/launch.js +39 -17
  21. package/dist/cli/commands/launch.js.map +1 -1
  22. package/dist/cli/commands/logout.d.ts +18 -0
  23. package/dist/cli/commands/logout.d.ts.map +1 -1
  24. package/dist/cli/commands/logout.js +40 -14
  25. package/dist/cli/commands/logout.js.map +1 -1
  26. package/dist/cli/commands/logs.d.ts +3 -2
  27. package/dist/cli/commands/logs.d.ts.map +1 -1
  28. package/dist/cli/commands/logs.js +26 -43
  29. package/dist/cli/commands/logs.js.map +1 -1
  30. package/dist/cli/commands/onboard.d.ts.map +1 -1
  31. package/dist/cli/commands/onboard.js +3 -3
  32. package/dist/cli/commands/onboard.js.map +1 -1
  33. package/dist/cli/commands/project.d.ts.map +1 -1
  34. package/dist/cli/commands/project.js +44 -23
  35. package/dist/cli/commands/project.js.map +1 -1
  36. package/dist/cli/commands/push.d.ts.map +1 -1
  37. package/dist/cli/commands/push.js +6 -4
  38. package/dist/cli/commands/push.js.map +1 -1
  39. package/dist/cli/commands/register.d.ts +37 -0
  40. package/dist/cli/commands/register.d.ts.map +1 -1
  41. package/dist/cli/commands/register.js +96 -74
  42. package/dist/cli/commands/register.js.map +1 -1
  43. package/dist/cli/commands/tunnel.js +2 -2
  44. package/dist/cli/commands/tunnel.js.map +1 -1
  45. package/dist/cli/commands/whoami.d.ts +18 -0
  46. package/dist/cli/commands/whoami.d.ts.map +1 -1
  47. package/dist/cli/commands/whoami.js +54 -28
  48. package/dist/cli/commands/whoami.js.map +1 -1
  49. package/dist/cli/index.js +10 -4
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/cli/utils/cli-io-impl.d.ts +33 -2
  52. package/dist/cli/utils/cli-io-impl.d.ts.map +1 -1
  53. package/dist/cli/utils/cli-io-impl.js +99 -14
  54. package/dist/cli/utils/cli-io-impl.js.map +1 -1
  55. package/dist/cli/utils/cli-io.d.ts +27 -9
  56. package/dist/cli/utils/cli-io.d.ts.map +1 -1
  57. package/dist/cli/utils/config.d.ts.map +1 -1
  58. package/dist/cli/utils/config.js +2 -2
  59. package/dist/cli/utils/config.js.map +1 -1
  60. package/dist/cli/utils/db-adapter.d.ts +59 -0
  61. package/dist/cli/utils/db-adapter.d.ts.map +1 -0
  62. package/dist/cli/utils/db-adapter.js +74 -0
  63. package/dist/cli/utils/db-adapter.js.map +1 -0
  64. package/dist/cli/utils/email.d.ts +15 -0
  65. package/dist/cli/utils/email.d.ts.map +1 -0
  66. package/dist/cli/utils/email.js +31 -0
  67. package/dist/cli/utils/email.js.map +1 -0
  68. package/dist/cli/utils/project-name.d.ts +10 -2
  69. package/dist/cli/utils/project-name.d.ts.map +1 -1
  70. package/dist/cli/utils/project-name.js +12 -6
  71. package/dist/cli/utils/project-name.js.map +1 -1
  72. package/dist/cli/utils/project.d.ts +17 -6
  73. package/dist/cli/utils/project.d.ts.map +1 -1
  74. package/dist/cli/utils/project.js +30 -36
  75. package/dist/cli/utils/project.js.map +1 -1
  76. package/dist/cli/utils/registry.d.ts +8 -6
  77. package/dist/cli/utils/registry.d.ts.map +1 -1
  78. package/dist/cli/utils/registry.js +32 -30
  79. package/dist/cli/utils/registry.js.map +1 -1
  80. package/dist/shared/constants.d.ts +16 -3
  81. package/dist/shared/constants.d.ts.map +1 -1
  82. package/dist/shared/constants.js +16 -3
  83. package/dist/shared/constants.js.map +1 -1
  84. package/dist/worker-runtime/discord.js +1 -1
  85. package/dist/worker-runtime/discord.js.map +1 -1
  86. package/dist/worker-runtime/index.d.ts +2 -1
  87. package/dist/worker-runtime/index.d.ts.map +1 -1
  88. package/dist/worker-runtime/index.js +19 -6
  89. package/dist/worker-runtime/index.js.map +1 -1
  90. package/package.json +1 -1
  91. package/templates/default/.claude/settings.local.json +1 -0
  92. package/templates/default/CLAUDE.md +2 -314
  93. package/templates/default/skills/fling/.hash +1 -1
  94. package/templates/default/skills/fling/API.md +45 -4
  95. package/templates/default/skills/fling/SKILL.md +92 -1
  96. package/dist/cli/commands/admin.d.ts +0 -8
  97. package/dist/cli/commands/admin.d.ts.map +0 -1
  98. package/dist/cli/commands/admin.js +0 -244
  99. package/dist/cli/commands/admin.js.map +0 -1
  100. package/dist/cli/commands/dev-worker.d.ts +0 -12
  101. package/dist/cli/commands/dev-worker.d.ts.map +0 -1
  102. package/dist/cli/commands/dev-worker.js +0 -66
  103. package/dist/cli/commands/dev-worker.js.map +0 -1
  104. package/dist/cli/commands/tun.d.ts +0 -13
  105. package/dist/cli/commands/tun.d.ts.map +0 -1
  106. package/dist/cli/commands/tun.js +0 -189
  107. package/dist/cli/commands/tun.js.map +0 -1
  108. package/dist/cli/utils/launch-io-impl.d.ts +0 -13
  109. package/dist/cli/utils/launch-io-impl.d.ts.map +0 -1
  110. package/dist/cli/utils/launch-io-impl.js +0 -51
  111. package/dist/cli/utils/launch-io-impl.js.map +0 -1
  112. package/dist/cli/utils/launch-io.d.ts +0 -42
  113. package/dist/cli/utils/launch-io.d.ts.map +0 -1
  114. package/dist/cli/utils/launch-io.js +0 -8
  115. package/dist/cli/utils/launch-io.js.map +0 -1
  116. package/dist/cli/utils/onboarding-io-impl.d.ts +0 -12
  117. package/dist/cli/utils/onboarding-io-impl.d.ts.map +0 -1
  118. package/dist/cli/utils/onboarding-io-impl.js +0 -85
  119. package/dist/cli/utils/onboarding-io-impl.js.map +0 -1
  120. package/dist/cli/utils/onboarding-io.d.ts +0 -60
  121. package/dist/cli/utils/onboarding-io.d.ts.map +0 -1
  122. package/dist/cli/utils/onboarding-io.js +0 -9
  123. package/dist/cli/utils/onboarding-io.js.map +0 -1
  124. package/dist/client/assets/index-BqVrS7t9.js +0 -40
  125. package/dist/client/assets/index-DSLUsCtO.css +0 -1
  126. package/dist/client/index.html +0 -14
  127. package/dist/client/vite.svg +0 -1
@@ -1,317 +1,5 @@
1
1
  # Fling Project
2
2
 
3
- This is a Fling project - a personal software platform for building and deploying personal tools with a React frontend and Hono API backend.
3
+ This is a Fling project - a personal software platform for building and deploying personal tools with a React frontend, API backend, SQL database, storage, and more.
4
4
 
5
- ## IMPORTANT: Do NOT ask about deployment, hosting, or technology choices!
6
-
7
- Fling handles all of this automatically. When the user asks you to build something:
8
- 1. Write backend code in `src/worker/index.ts` using the Fling API
9
- 2. Write frontend code in `src/react-app/` using React
10
- 3. Run `npm start` to test it locally (you have bash access - run commands yourself!)
11
- 4. When it works, run `npm exec fling push` to deploy
12
-
13
- **IMPORTANT: Run CLI commands yourself.** You have bash access. Do NOT ask the user to run commands like `fling push`, `fling dev`, or `npm start`. Execute them directly and report the results.
14
-
15
- ## Project Structure
16
-
17
- ```
18
- src/
19
- worker/
20
- index.ts # Backend API entry point (routes, migrations)
21
- react-app/
22
- main.tsx # React entry point
23
- App.tsx # Main React component
24
- App.css # Component styles
25
- index.css # Global styles
26
- public/ # Static assets (served by Vite)
27
- index.html # Vite entry HTML
28
- vite.config.ts # Vite configuration
29
- .fling/secrets # Local secrets (gitignored)
30
- .fling/data/ # SQLite database (gitignored)
31
- ```
32
-
33
- ## Development
34
-
35
- Run `npm start` (or `fling dev`) to start development:
36
- - **Frontend**: http://localhost:5173 (Vite with React HMR)
37
- - **API**: http://localhost:3210 (Hono backend)
38
- - Vite proxies `/api/*` requests to the API server
39
-
40
- ### Hot Module Replacement (HMR)
41
-
42
- The dev server provides hot reloading for both frontend AND backend - no restart needed:
43
- - **Frontend (React)**: Changes to `src/react-app/` are instantly reflected via Vite HMR
44
- - **Backend (Worker)**: Changes to `src/worker/` are automatically reloaded via tsx watch
45
-
46
- Just edit and save - changes appear immediately.
47
-
48
- ## Fling API (Backend)
49
-
50
- All primitives are imported from `"flingit"` in the backend:
51
-
52
- ```typescript
53
- import { app, db, migrate, secrets, cron, storage } from "flingit";
54
- ```
55
-
56
- ### HTTP Routes (Hono)
57
-
58
- ```typescript
59
- // API routes should use /api prefix for Vite proxy
60
- app.get("/api/hello", (c) => c.json({ message: "Hello!" }));
61
- app.post("/api/data", async (c) => {
62
- const body = await c.req.json();
63
- return c.json({ received: body });
64
- });
65
- ```
66
-
67
- **Note:** Paths starting with `/__` are reserved for internal platform use. Do not create routes with these prefixes.
68
-
69
- ### Migrations
70
-
71
- **IMPORTANT: Migrations MUST be idempotent** (safe to run multiple times).
72
-
73
- ```typescript
74
- migrate("001_create_users", async () => {
75
- await db.prepare(`
76
- CREATE TABLE IF NOT EXISTS users (
77
- id INTEGER PRIMARY KEY AUTOINCREMENT,
78
- name TEXT NOT NULL,
79
- created_at TEXT DEFAULT (datetime('now'))
80
- )
81
- `).run();
82
- });
83
- ```
84
-
85
- ### Database (SQLite, D1-compatible)
86
-
87
- ```typescript
88
- // Query
89
- const item = await db.prepare("SELECT * FROM items WHERE id = ?").bind(id).first();
90
- const all = await db.prepare("SELECT * FROM items").all();
91
-
92
- // Insert/Update/Delete
93
- await db.prepare("INSERT INTO items (name) VALUES (?)").bind(name).run();
94
- ```
95
-
96
- ### Secrets
97
-
98
- ```typescript
99
- const apiKey = secrets.get("API_KEY"); // Throws if not set
100
- ```
101
-
102
- ### Cron Jobs
103
-
104
- Schedule tasks to run automatically on a schedule using standard cron syntax:
105
-
106
- ```typescript
107
- cron("daily-cleanup", "0 3 * * *", async () => {
108
- // Runs at 3 AM daily
109
- await db.prepare("DELETE FROM old_logs WHERE created_at < ?")
110
- .bind(Date.now() - 86400000).run();
111
- });
112
-
113
- cron("hourly-report", "0 * * * *", async () => {
114
- // Runs every hour - can return a result that's stored in history
115
- const count = await processRecords();
116
- return { processed: count };
117
- });
118
- ```
119
-
120
- Cron expressions: `minute hour day-of-month month day-of-week`
121
- - `"0 9 * * *"` - 9 AM daily
122
- - `"*/15 * * * *"` - Every 15 minutes
123
- - `"0 0 * * 1"` - Midnight on Mondays
124
-
125
- Manage cron jobs with CLI:
126
- ```bash
127
- npm exec fling cron list # List all cron jobs
128
- npm exec fling cron history <name> # View invocation history
129
- npm exec fling cron trigger <name> # Manually trigger a job
130
- ```
131
-
132
- ### Storage (R2)
133
-
134
- Store and retrieve files. Uses local filesystem in development, Cloudflare R2 in production.
135
-
136
- ```typescript
137
- import { storage } from "flingit";
138
-
139
- // Store objects
140
- await storage.put("images/logo.png", imageBuffer, { contentType: "image/png" });
141
- await storage.put("data/config.json", JSON.stringify(config));
142
-
143
- // Retrieve objects
144
- const file = await storage.get("images/logo.png");
145
- if (file) {
146
- const buffer = await file.arrayBuffer();
147
- const text = await file.text();
148
- const json = await file.json<ConfigType>();
149
- // Or stream: file.body (ReadableStream)
150
- }
151
-
152
- // Check existence without downloading
153
- const meta = await storage.head("images/logo.png");
154
-
155
- // Delete objects
156
- await storage.delete("old-file.txt");
157
- await storage.delete(["file1.txt", "file2.txt"]); // Batch delete
158
-
159
- // List objects
160
- const result = await storage.list({ prefix: "images/", limit: 100 });
161
- for (const obj of result.objects) {
162
- console.log(`${obj.key}: ${obj.size} bytes`);
163
- }
164
- ```
165
-
166
- Manage storage with CLI:
167
- ```bash
168
- npm exec fling storage list # List local storage objects
169
- npm exec fling storage put key file.txt # Upload file to storage
170
- npm exec fling storage get key output # Download object to file
171
- npm exec fling storage delete key --yes # Delete object
172
- npm exec fling storage info # Show storage stats
173
- ```
174
-
175
- ## React Frontend
176
-
177
- The frontend is a standard React + Vite setup. Call the backend API:
178
-
179
- ```typescript
180
- // In React components
181
- useEffect(() => {
182
- fetch("/api/hello")
183
- .then(res => res.json())
184
- .then(data => setMessage(data.message));
185
- }, []);
186
- ```
187
-
188
- ## CLI Commands
189
-
190
- Always use `npm exec` to run the project's Fling:
191
-
192
- ```bash
193
- npm exec fling dev # Start local dev server (API + Vite)
194
- npm exec fling dev -- --port 8080 # Custom API port
195
- npm exec fling db sql "SELECT * FROM users" # Query local SQLite
196
- npm exec fling db reset # Wipe local database
197
- npm exec fling db sql "SELECT * FROM users" # Query local SQLite
198
- npm exec fling secret set K=V # Set local secret
199
- npm exec fling secret list # List local secrets
200
- npm exec fling logs # View local logs
201
- npm exec fling storage list # List storage objects
202
- npm exec fling storage put K F # Upload file F as key K
203
- npm exec fling storage get K O # Download key K to file O
204
- npm exec fling push # Build and deploy to production
205
- npm exec fling tunnel 3000 # Expose localhost:3000 via public URL
206
- ```
207
-
208
- ### Local vs Production (`--prod`)
209
-
210
- Most CLI commands operate on the **local** environment by default. Add `--prod` for production:
211
-
212
- ```bash
213
- # Local (default)
214
- npm exec fling secret list # Local secrets
215
- npm exec fling logs # Local logs
216
- npm exec fling db sql "SELECT 1" # Local SQLite
217
- npm exec fling storage list # Local storage
218
-
219
- # Production (requires login)
220
- npm exec fling -- --prod logs # Deployed logs
221
- npm exec fling -- --prod db sql "SELECT 1" # Deployed D1
222
- npm exec fling -- --prod storage list # R2 storage
223
- ```
224
-
225
- **Note:** Production logs have a delay of ~10 seconds or more before they appear.
226
-
227
- **Secrets:** Always stored locally in `.fling/secrets`. Use `fling push` to deploy secrets to production along with your code.
228
-
229
- ## Deployment
230
-
231
- `fling push` handles everything automatically:
232
-
233
- 1. Builds React frontend with Vite → `dist/client/`
234
- 2. Uploads static assets (HTML, JS, CSS, images, fonts)
235
- 3. Bundles backend code with esbuild
236
- 4. Deploys to Cloudflare Workers
237
-
238
- **Limits:** 25MB per file, 100MB total assets.
239
-
240
- **Routing in production:**
241
- - `/api/*` → Backend worker code
242
- - Everything else → Static assets from `dist/client/`
243
- - SPA fallback: Unknown paths serve `index.html`
244
-
245
- ## Platform Limitations
246
-
247
- Be aware of these constraints when building:
248
-
249
- ### Feature Scope
250
- - **Supported:** Frontend (React), backend (Hono API), database (SQLite/D1), cron jobs, file storage (R2), Discord integration
251
- - **Not yet supported:** Websockets
252
- - If the user needs unsupported features, encourage them to send feedback via `npm exec fling feedback`
253
-
254
- ### Backend Memory (128MB limit)
255
- - The backend runs in a Cloudflare Worker with ~128MB memory
256
- - Cannot process large datasets in memory all at once
257
- - For large data: use streaming, pagination, or chunked processing
258
- - Example: process files line-by-line instead of loading entirely into memory
259
-
260
- ### Cloudflare Workers Runtime
261
- - Workers do NOT have the full Node.js API
262
- - Some npm packages won't work (those requiring `fs`, `path`, `child_process`, native modules)
263
- - Must use Workers-compatible packages (check package docs for "Cloudflare Workers" or "edge runtime" support)
264
- - Web standard APIs work fine (fetch, crypto.subtle, TextEncoder, etc.)
265
-
266
- ### Backend Assets (Images, Fonts, etc.)
267
-
268
- If the backend needs to return or process an asset (image, icon, font), keep it small and store the base64 data in a separate file to keep your main code clean:
269
-
270
- ```typescript
271
- // src/worker/assets/favicon.ts - separate file for the asset
272
- export const FAVICON_BASE64 = "iVBORw0KGgo..."; // base64-encoded PNG
273
- ```
274
-
275
- ```typescript
276
- // src/worker/index.ts - import and use the asset
277
- import { FAVICON_BASE64 } from "./assets/favicon";
278
-
279
- app.get("/favicon.ico", (c) => {
280
- const buffer = Uint8Array.from(atob(FAVICON_BASE64), c => c.charCodeAt(0));
281
- return new Response(buffer, {
282
- headers: { "Content-Type": "image/x-icon" }
283
- });
284
- });
285
- ```
286
-
287
- This approach:
288
- - Keeps the main code readable (no long base64 strings inline)
289
- - Makes assets easy to find and update
290
- - Base64 keeps assets bundled with the code (required for Workers)
291
-
292
- **For large assets:** Serve them from the frontend (`public/` folder) instead.
293
-
294
- **If the user's request might hit these limitations, warn them early and suggest alternatives.**
295
-
296
- ## Key Points
297
-
298
- - **Don't ask about hosting** - Fling handles deployment
299
- - **Don't ask about databases** - Use `db` from fling
300
- - **Don't suggest external services** - Fling provides what you need
301
- - **Use /api prefix** - For Vite proxy to work in development
302
- - **Run commands yourself** - You have bash access, don't ask the user to run CLI commands
303
-
304
- ## After First Deployment
305
-
306
- After your first `fling push`, consider asking the user if they want a custom URL.
307
- Their project was auto-assigned a slug like `proj-abc123`.
308
-
309
- To change it: `npm exec fling project slug:set my-custom-slug`
310
-
311
- Slugs must be:
312
- - More than 4 characters
313
- - Lowercase alphanumeric with optional hyphens
314
- - Globally unique across all Fling projects
315
-
316
- See `.claude/skills/fling/` for detailed API documentation.
317
- See `.claude/skills/discord/` for Discord chatops integration (slash commands, messages, interactions).
5
+ Read the `fling` skill in detail!
@@ -1 +1 @@
1
- effee60df04f3781c257b08a6cf0c6bb
1
+ 48c43a6cab25d1a064e710509399ca76
@@ -190,7 +190,7 @@ migrate("004_normalize_emails", async () => {
190
190
 
191
191
  - Migrations MUST be declared at module top-level (not inside functions)
192
192
  - Each migration must have a unique name
193
- - Always use `await db.prepare(...).run()` for DDL statements (not `db.exec()` - it doesn't work in production D1)
193
+ - `db.exec()` doesn't return results, so it is not suitable for `SELECT` queries.
194
194
  - Tables starting with `_` are reserved for the system (`_migrations`, `_fling_logs`)
195
195
  - Do NOT perform database operations at module top-level outside of migrations
196
196
  - The `_migrations` table is created automatically on first migration
@@ -263,6 +263,20 @@ await db.prepare("DELETE FROM users WHERE id = ?")
263
263
  .run();
264
264
  ```
265
265
 
266
+ ### Batch
267
+
268
+ Execute multiple statements atomically:
269
+
270
+ ```typescript
271
+ const results = await db.batch([
272
+ db.prepare("INSERT INTO users (name) VALUES (?)").bind("Alice"),
273
+ db.prepare("INSERT INTO users (name) VALUES (?)").bind("Bob"),
274
+ ]);
275
+ // Returns: [{ success: true, meta: ... }, { success: true, meta: ... }]
276
+ ```
277
+
278
+ This is also faster than executing statements individually.
279
+
266
280
  ### Schema (DDL)
267
281
 
268
282
  Schema changes should be done in migrations (see Migrations section above):
@@ -284,8 +298,6 @@ migrate("001_create_users", async () => {
284
298
  });
285
299
  ```
286
300
 
287
- **Important**: Always use `db.prepare(...).run()` for DDL statements. The `db.exec()` method does not work in production D1 databases.
288
-
289
301
  ### Important Notes
290
302
 
291
303
  - Schema changes should be done in migrations (see Migrations section)
@@ -333,6 +345,36 @@ Secret names must be uppercase with underscores:
333
345
  - `apiKey` ✗
334
346
  - `github-token` ✗
335
347
 
348
+ ## Cron Jobs
349
+
350
+ Schedule tasks to run automatically on a schedule using standard cron syntax:
351
+
352
+ ```typescript
353
+ cron("daily-cleanup", "0 3 * * *", async () => {
354
+ // Runs at 3 AM daily
355
+ await db.prepare("DELETE FROM old_logs WHERE created_at < ?")
356
+ .bind(Date.now() - 86400000).run();
357
+ });
358
+
359
+ cron("hourly-report", "0 * * * *", async () => {
360
+ // Runs every hour - can return a result that's stored in history
361
+ const count = await processRecords();
362
+ return { processed: count };
363
+ });
364
+ ```
365
+
366
+ Cron expressions: `minute hour day-of-month month day-of-week`
367
+ - `"0 9 * * *"` - 9 AM daily
368
+ - `"*/15 * * * *"` - Every 15 minutes
369
+ - `"0 0 * * 1"` - Midnight on Mondays
370
+
371
+ Manage cron jobs with CLI:
372
+ ```bash
373
+ npm exec fling cron list # List all cron jobs
374
+ npm exec fling cron history <name> # View invocation history
375
+ npm exec fling cron trigger <name> # Manually trigger a job
376
+ ```
377
+
336
378
  ## Storage (R2)
337
379
 
338
380
  Object storage for files and binary data. Uses local filesystem in development, Cloudflare R2 in production.
@@ -618,4 +660,3 @@ app.get("/api/compute", async (c) => {
618
660
  - **Cloudflare blocks dynamic WASM compilation** - You cannot use `WebAssembly.instantiate(bytes)` with raw bytes fetched at runtime. WASM must be imported statically so Cloudflare can pre-compile it at deploy time.
619
661
  - **Initialize once** - WASM initialization is expensive. Cache the instance and reuse it across requests.
620
662
  - **Bundle size** - WASM modules count toward the 10MB bundle limit. Large WASM files may require optimization.
621
-
@@ -7,6 +7,25 @@ description: Building and deploying this app easily to the internet
7
7
 
8
8
  You are working on a Fling project - a personal software platform for building and deploying personal tools with a React frontend and Hono API backend.
9
9
 
10
+ ## IMPORTANT: Do NOT ask about deployment, hosting, or technology choices!
11
+
12
+ Fling handles all of this automatically. When the user asks you to build something:
13
+ 1. Write backend code in `src/worker/index.ts` using the Fling API
14
+ 2. Write frontend code in `src/react-app/` using React
15
+ 3. Run `npm start` to test it locally (you have bash access - run commands yourself!)
16
+ 4. When it works, run `npm exec fling push` to deploy
17
+
18
+ ## When to Send Feedback
19
+
20
+ Fling can send feedback to its authors. Read FEEDBACK.md for details.
21
+
22
+ Proactively offer to send feedback in these situations:
23
+
24
+ 1. **User frustration** - When the user expresses frustration with Fling
25
+ 2. **Product limitations** - When Fling can't do something the user needs
26
+ 3. **After difficulties** - When you've helped resolve a confusing issue
27
+ 4. **Feature requests** - When the user wishes Fling could do something differently
28
+
10
29
  ## Core Concepts
11
30
 
12
31
  Fling provides seven primitives that work identically in local development and production:
@@ -181,11 +200,33 @@ Run `npm start` (or `fling dev`) to start development:
181
200
  - **API**: http://localhost:3210 (Hono backend)
182
201
  - Vite proxies `/api/*` requests to the API server
183
202
 
203
+ ### Hot Module Replacement (HMR)
204
+
205
+ The dev server provides hot reloading for both frontend AND backend - no restart needed:
206
+ - **Frontend (React)**: Changes to `src/react-app/` are instantly reflected via Vite HMR
207
+ - **Backend (Worker)**: Changes to `src/worker/` are automatically reloaded via tsx watch
208
+
209
+ Just edit and save - changes appear immediately.
210
+
184
211
  ## Deployment
185
212
 
186
- When the user's request is complete and working locally, deploy it:
213
+ When the user's request is complete and working locally, offer to deploy it. But if their app has a backend and no secure authorization method, you must make it clear to them that the deployed app will be visible on the internet, and that they should not expose anything that should not be publicly visible!
214
+
215
+ To deploy:
187
216
  **Run `npm exec fling push` directly** - you have bash access, don't ask the user to run commands.
188
217
 
218
+ ### After First Deployment
219
+
220
+ After your first `fling push`, consider asking the user if they want a custom URL.
221
+ Their project was auto-assigned a slug like `proj-abc123`.
222
+
223
+ To change it: `npm exec fling project slug:set my-custom-slug`
224
+
225
+ Slugs must be:
226
+ - More than 4 characters
227
+ - Lowercase alphanumeric with optional hyphens
228
+ - Globally unique across all Fling projects
229
+
189
230
  ### What `fling push` does:
190
231
 
191
232
  1. **Builds frontend** - Runs `vite build`, outputs to `dist/client/`
@@ -193,6 +234,8 @@ When the user's request is complete and working locally, deploy it:
193
234
  3. **Bundles backend** - Compiles `src/worker/index.ts` with esbuild
194
235
  4. **Deploys to Cloudflare** - Both frontend and backend go live
195
236
 
237
+ **Secrets:** Always stored locally in `.fling/secrets`. Use `fling push` to deploy secrets to production along with your code.
238
+
196
239
  ### Static Asset Limits
197
240
 
198
241
  - **25MB** per file maximum
@@ -245,4 +288,52 @@ This gives collaborators:
245
288
 
246
289
  **If the user's request might hit platform limitations, warn them early and suggest alternatives.**
247
290
 
291
+ ## Migrations
292
+
293
+ **IMPORTANT: Migrations MUST be idempotent** (safe to run multiple times).
294
+
295
+ Use the `migrate` helper for schema changes:
296
+
297
+ ```typescript
298
+ import { migrate, db } from "flingit";
299
+
300
+ migrate("001_create_users", async () => {
301
+ await db.prepare(`
302
+ CREATE TABLE IF NOT EXISTS users (
303
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
304
+ name TEXT NOT NULL,
305
+ created_at TEXT DEFAULT (datetime('now'))
306
+ )
307
+ `).run();
308
+ });
309
+ ```
310
+
311
+ ## Backend Assets (Images, Fonts, etc.)
312
+
313
+ If the backend needs to return or process an asset (image, icon, font), keep it small and store the base64 data in a separate file to keep your main code clean:
314
+
315
+ ```typescript
316
+ // src/worker/assets/favicon.ts - separate file for the asset
317
+ export const FAVICON_BASE64 = "iVBORw0KGgo..."; // base64-encoded PNG
318
+ ```
319
+
320
+ ```typescript
321
+ // src/worker/index.ts - import and use the asset
322
+ import { FAVICON_BASE64 } from "./assets/favicon";
323
+
324
+ app.get("/favicon.ico", (c) => {
325
+ const buffer = Uint8Array.from(atob(FAVICON_BASE64), c => c.charCodeAt(0));
326
+ return new Response(buffer, {
327
+ headers: { "Content-Type": "image/x-icon" }
328
+ });
329
+ });
330
+ ```
331
+
332
+ This approach:
333
+ - Keeps the main code readable (no long base64 strings inline)
334
+ - Makes assets easy to find and update
335
+ - Base64 keeps assets bundled with the code (required for Workers)
336
+
337
+ **For large assets:** Serve them from the frontend (`public/` folder) instead.
338
+
248
339
  See API.md for detailed API reference, EXAMPLES.md for common patterns, and FEEDBACK.md for collecting user feedback.
@@ -1,8 +0,0 @@
1
- /**
2
- * fling admin - Admin commands for platform management
3
- *
4
- * Requires ADMIN_KEY environment variable to be set.
5
- */
6
- import { Command } from "commander";
7
- export declare const adminCommand: Command;
8
- //# sourceMappingURL=admin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/admin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmKpC,eAAO,MAAM,YAAY,SAWtB,CAAC"}