flingit 0.0.7 → 0.0.9
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/cli/commands/dev.d.ts +8 -6
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +210 -60
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/launch.d.ts.map +1 -1
- package/dist/cli/commands/launch.js +8 -2
- package/dist/cli/commands/launch.js.map +1 -1
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/onboard.js +10 -6
- package/dist/cli/commands/onboard.js.map +1 -1
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +82 -17
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/deploy/bundler.d.ts +44 -0
- package/dist/cli/deploy/bundler.d.ts.map +1 -1
- package/dist/cli/deploy/bundler.js +140 -3
- package/dist/cli/deploy/bundler.js.map +1 -1
- package/dist/cli/index.d.ts +0 -7
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/loaders/wasm-hooks.d.ts +12 -5
- package/dist/cli/loaders/wasm-hooks.d.ts.map +1 -1
- package/dist/cli/loaders/wasm-hooks.js +12 -5
- package/dist/cli/loaders/wasm-hooks.js.map +1 -1
- package/dist/cli/utils/claude-code.d.ts +19 -0
- package/dist/cli/utils/claude-code.d.ts.map +1 -0
- package/dist/cli/utils/claude-code.js +43 -0
- package/dist/cli/utils/claude-code.js.map +1 -0
- package/dist/cli/utils/node-version.d.ts +28 -0
- package/dist/cli/utils/node-version.d.ts.map +1 -0
- package/dist/cli/utils/node-version.js +54 -0
- package/dist/cli/utils/node-version.js.map +1 -0
- package/package.json +1 -1
- package/templates/default/CLAUDE.md +31 -0
- package/templates/default/skills/fling/API.md +78 -0
- package/templates/default/skills/fling/SKILL.md +2 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code detection and launch utilities.
|
|
3
|
+
*/
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
/**
|
|
6
|
+
* Check if Claude Code is installed and available in PATH.
|
|
7
|
+
* @returns true if claude command is available
|
|
8
|
+
*/
|
|
9
|
+
export function isClaudeCodeInstalled() {
|
|
10
|
+
try {
|
|
11
|
+
// Use 'which' on Unix-like systems, 'where' on Windows
|
|
12
|
+
const cmd = process.platform === "win32" ? "where claude" : "which claude";
|
|
13
|
+
execSync(cmd, { stdio: "ignore" });
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the error message for when Claude Code is not installed.
|
|
22
|
+
* @returns Error message with installation instructions
|
|
23
|
+
*/
|
|
24
|
+
export function getClaudeCodeNotInstalledError() {
|
|
25
|
+
return `Error: Claude Code is not installed or not in your PATH.
|
|
26
|
+
|
|
27
|
+
Fling uses Claude Code as its AI coding assistant. To install it, visit:
|
|
28
|
+
https://docs.anthropic.com/en/docs/claude-code/overview
|
|
29
|
+
|
|
30
|
+
After installation, run 'fling' again to continue.`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if Claude Code is installed and exit with error if not.
|
|
34
|
+
* @returns true if installed, process exits if not
|
|
35
|
+
*/
|
|
36
|
+
export function requireClaudeCode() {
|
|
37
|
+
if (!isClaudeCodeInstalled()) {
|
|
38
|
+
console.error(getClaudeCodeNotInstalledError());
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/cli/utils/claude-code.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC;QACH,uDAAuD;QACvD,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC;QAC3E,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B;IAC5C,OAAO;;;;;mDAK0C,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js version check utilities.
|
|
3
|
+
*/
|
|
4
|
+
export declare const MIN_NODE_VERSION = 22;
|
|
5
|
+
/**
|
|
6
|
+
* Parse the major version from a Node.js version string.
|
|
7
|
+
* @param version - Version string like "v20.10.0" or "22.0.0"
|
|
8
|
+
* @returns The major version number
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseMajorVersion(version: string): number;
|
|
11
|
+
/**
|
|
12
|
+
* Check if the current Node.js version meets the minimum requirement.
|
|
13
|
+
* @param version - Version string to check (defaults to process.version)
|
|
14
|
+
* @returns true if version is sufficient, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
export declare function isNodeVersionSupported(version?: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Get the error message for unsupported Node versions.
|
|
19
|
+
* @param version - Current Node.js version string
|
|
20
|
+
* @returns Error message with upgrade instructions
|
|
21
|
+
*/
|
|
22
|
+
export declare function getNodeVersionError(version: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Check Node.js version and exit with error if unsupported.
|
|
25
|
+
* This is called at CLI entry points.
|
|
26
|
+
*/
|
|
27
|
+
export declare function checkNodeVersion(): void;
|
|
28
|
+
//# sourceMappingURL=node-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/node-version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,MAAwB,GAAG,OAAO,CAGjF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js version check utilities.
|
|
3
|
+
*/
|
|
4
|
+
export const MIN_NODE_VERSION = 22;
|
|
5
|
+
/**
|
|
6
|
+
* Parse the major version from a Node.js version string.
|
|
7
|
+
* @param version - Version string like "v20.10.0" or "22.0.0"
|
|
8
|
+
* @returns The major version number
|
|
9
|
+
*/
|
|
10
|
+
export function parseMajorVersion(version) {
|
|
11
|
+
// Remove leading 'v' if present
|
|
12
|
+
const cleaned = version.startsWith("v") ? version.slice(1) : version;
|
|
13
|
+
const major = cleaned.split(".")[0] ?? "0";
|
|
14
|
+
return parseInt(major, 10);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Check if the current Node.js version meets the minimum requirement.
|
|
18
|
+
* @param version - Version string to check (defaults to process.version)
|
|
19
|
+
* @returns true if version is sufficient, false otherwise
|
|
20
|
+
*/
|
|
21
|
+
export function isNodeVersionSupported(version = process.version) {
|
|
22
|
+
const major = parseMajorVersion(version);
|
|
23
|
+
return major >= MIN_NODE_VERSION;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the error message for unsupported Node versions.
|
|
27
|
+
* @param version - Current Node.js version string
|
|
28
|
+
* @returns Error message with upgrade instructions
|
|
29
|
+
*/
|
|
30
|
+
export function getNodeVersionError(version) {
|
|
31
|
+
return `Error: Fling requires Node.js ${MIN_NODE_VERSION} or later.
|
|
32
|
+
|
|
33
|
+
You are running Node.js ${version}
|
|
34
|
+
|
|
35
|
+
To upgrade, we recommend using nvm (Node Version Manager):
|
|
36
|
+
https://github.com/nvm-sh/nvm
|
|
37
|
+
|
|
38
|
+
After installing nvm:
|
|
39
|
+
nvm install ${MIN_NODE_VERSION}
|
|
40
|
+
nvm use ${MIN_NODE_VERSION}
|
|
41
|
+
|
|
42
|
+
Then try again.`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check Node.js version and exit with error if unsupported.
|
|
46
|
+
* This is called at CLI entry points.
|
|
47
|
+
*/
|
|
48
|
+
export function checkNodeVersion() {
|
|
49
|
+
if (!isNodeVersionSupported()) {
|
|
50
|
+
console.error(getNodeVersionError(process.version));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=node-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version.js","sourceRoot":"","sources":["../../../src/cli/utils/node-version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,gCAAgC;IAChC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC3C,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAkB,OAAO,CAAC,OAAO;IACtE,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,KAAK,IAAI,gBAAgB,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,iCAAiC,gBAAgB;;0BAEhC,OAAO;;;;;;gBAMjB,gBAAgB;YACpB,gBAAgB;;gBAEZ,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,sBAAsB,EAAE,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -37,6 +37,14 @@ Run `npm start` (or `fling dev`) to start development:
|
|
|
37
37
|
- **API**: http://localhost:3210 (Hono backend)
|
|
38
38
|
- Vite proxies `/api/*` requests to the API server
|
|
39
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
|
+
|
|
40
48
|
## Fling API (Backend)
|
|
41
49
|
|
|
42
50
|
All primitives are imported from `"flingit"` in the backend:
|
|
@@ -206,6 +214,29 @@ Be aware of these constraints when building:
|
|
|
206
214
|
- Must use Workers-compatible packages (check package docs for "Cloudflare Workers" or "edge runtime" support)
|
|
207
215
|
- Web standard APIs work fine (fetch, crypto.subtle, TextEncoder, etc.)
|
|
208
216
|
|
|
217
|
+
### Backend Assets (Images, Fonts, etc.)
|
|
218
|
+
|
|
219
|
+
If the backend needs to return or process an asset (image, icon, font), keep it small and embed it directly in the code as base64:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Small assets should be base64 encoded directly in the code
|
|
223
|
+
const FAVICON_BASE64 = "iVBORw0KGgo..."; // base64-encoded PNG
|
|
224
|
+
|
|
225
|
+
app.get("/favicon.ico", (c) => {
|
|
226
|
+
const buffer = Uint8Array.from(atob(FAVICON_BASE64), c => c.charCodeAt(0));
|
|
227
|
+
return new Response(buffer, {
|
|
228
|
+
headers: { "Content-Type": "image/x-icon" }
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
This is necessary because:
|
|
234
|
+
- Workers have limited memory (~128MB)
|
|
235
|
+
- There's no built-in asset serving for backend code
|
|
236
|
+
- Base64 keeps assets bundled with the code
|
|
237
|
+
|
|
238
|
+
**For large assets:** Serve them from the frontend (`public/` folder) instead.
|
|
239
|
+
|
|
209
240
|
**If the user's request might hit these limitations, warn them early and suggest alternatives.**
|
|
210
241
|
|
|
211
242
|
## Key Points
|
|
@@ -333,3 +333,81 @@ Secret names must be uppercase with underscores:
|
|
|
333
333
|
- `apiKey` ✗
|
|
334
334
|
- `github-token` ✗
|
|
335
335
|
|
|
336
|
+
## WebAssembly (WASM)
|
|
337
|
+
|
|
338
|
+
Fling supports importing WebAssembly modules in your backend code. This enables using libraries like `@resvg/resvg-wasm` for SVG rendering, image processing, and other compute-intensive tasks.
|
|
339
|
+
|
|
340
|
+
### Basic Usage
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { app } from "flingit";
|
|
344
|
+
import wasmBinary from "@resvg/resvg-wasm/index_bg.wasm";
|
|
345
|
+
import { initWasm, Resvg } from "@resvg/resvg-wasm";
|
|
346
|
+
|
|
347
|
+
// Initialize WASM once
|
|
348
|
+
let initialized = false;
|
|
349
|
+
|
|
350
|
+
app.get("/api/svg-to-png", async (c) => {
|
|
351
|
+
if (!initialized) {
|
|
352
|
+
await initWasm(wasmBinary);
|
|
353
|
+
initialized = true;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const svg = c.req.query("svg") ?? '<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="red"/></svg>';
|
|
357
|
+
const resvg = new Resvg(svg);
|
|
358
|
+
const png = resvg.render().asPng();
|
|
359
|
+
|
|
360
|
+
return c.body(png, 200, { "Content-Type": "image/png" });
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### How It Works
|
|
365
|
+
|
|
366
|
+
WASM files are handled differently in local development vs production, but the same code works for both:
|
|
367
|
+
|
|
368
|
+
| Environment | What `import wasm from "*.wasm"` returns |
|
|
369
|
+
|-------------|------------------------------------------|
|
|
370
|
+
| Local (Node.js) | `Uint8Array` (raw bytes) |
|
|
371
|
+
| Production (Cloudflare) | `WebAssembly.Module` (pre-compiled) |
|
|
372
|
+
|
|
373
|
+
Most WASM libraries (like `@resvg/resvg-wasm`) accept both types in their init functions, so your code works unchanged in both environments.
|
|
374
|
+
|
|
375
|
+
### TypeScript Support
|
|
376
|
+
|
|
377
|
+
Add a type declaration file (e.g., `src/worker/wasm.d.ts`):
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
declare module "*.wasm" {
|
|
381
|
+
const content: WebAssembly.Module | Uint8Array;
|
|
382
|
+
export default content;
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Direct WASM Instantiation
|
|
387
|
+
|
|
388
|
+
For custom WASM modules without a library wrapper:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
import wasmModule from "./my-module.wasm";
|
|
392
|
+
|
|
393
|
+
let instance: WebAssembly.Instance | null = null;
|
|
394
|
+
|
|
395
|
+
app.get("/api/compute", async (c) => {
|
|
396
|
+
if (!instance) {
|
|
397
|
+
const result = await WebAssembly.instantiate(wasmModule);
|
|
398
|
+
instance = result instanceof WebAssembly.Instance ? result : result.instance;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const compute = instance.exports.compute as (x: number) => number;
|
|
402
|
+
const result = compute(42);
|
|
403
|
+
|
|
404
|
+
return c.json({ result });
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Important Notes
|
|
409
|
+
|
|
410
|
+
- **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.
|
|
411
|
+
- **Initialize once** - WASM initialization is expensive. Cache the instance and reuse it across requests.
|
|
412
|
+
- **Bundle size** - WASM modules count toward the 10MB bundle limit. Large WASM files may require optimization.
|
|
413
|
+
|
|
@@ -4,13 +4,14 @@ You are working on a Fling project - a personal software platform for building a
|
|
|
4
4
|
|
|
5
5
|
## Core Concepts
|
|
6
6
|
|
|
7
|
-
Fling provides
|
|
7
|
+
Fling provides six primitives that work identically in local development and production:
|
|
8
8
|
|
|
9
9
|
1. **HTTP** - Expose endpoints via Hono
|
|
10
10
|
2. **Database** - SQLite locally, D1 in production
|
|
11
11
|
3. **Secrets** - Secure credential management
|
|
12
12
|
4. **Migrations** - Version your database schema
|
|
13
13
|
5. **Cron** - Scheduled tasks that run on a schedule
|
|
14
|
+
6. **WASM** - WebAssembly modules for compute-intensive tasks
|
|
14
15
|
|
|
15
16
|
## Project Structure
|
|
16
17
|
|