create-surf-app 0.1.14 → 0.1.16

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 (30) hide show
  1. package/dist/{chunk-53EUQV7R.js → chunk-MJDS5WZH.js} +6 -8
  2. package/dist/cli.js +1 -3
  3. package/dist/index.js +1 -1
  4. package/dist/templates/default/CLAUDE.md +75 -31
  5. package/dist/templates/default/backend/db/schema.js +8 -20
  6. package/dist/templates/default/backend/eslint.config.mjs +1 -1
  7. package/dist/templates/default/backend/package.json +2 -16
  8. package/dist/templates/default/backend/routes/.gitkeep +1 -0
  9. package/dist/templates/default/backend/server.js +2 -444
  10. package/package.json +1 -1
  11. package/dist/templates/default/backend/db/index.js +0 -23
  12. package/dist/templates/default/backend/lib/db.js +0 -67
  13. package/dist/templates/default/backend/routes/proxy.js +0 -66
  14. package/dist/templates/mini-surf/CLAUDE.md +0 -88
  15. package/dist/templates/mini-surf/backend/db/schema.js +0 -8
  16. package/dist/templates/mini-surf/backend/eslint.config.mjs +0 -21
  17. package/dist/templates/mini-surf/backend/package.json +0 -12
  18. package/dist/templates/mini-surf/backend/routes/.gitkeep +0 -0
  19. package/dist/templates/mini-surf/backend/server.js +0 -2
  20. package/dist/templates/mini-surf/frontend/components.json +0 -17
  21. package/dist/templates/mini-surf/frontend/eslint.config.js +0 -42
  22. package/dist/templates/mini-surf/frontend/index.html +0 -43
  23. package/dist/templates/mini-surf/frontend/package.json +0 -73
  24. package/dist/templates/mini-surf/frontend/src/App.tsx +0 -18
  25. package/dist/templates/mini-surf/frontend/src/entry-client.tsx +0 -109
  26. package/dist/templates/mini-surf/frontend/src/entry-server.tsx +0 -13
  27. package/dist/templates/mini-surf/frontend/src/index.css +0 -4
  28. package/dist/templates/mini-surf/frontend/src/vite-env.d.ts +0 -1
  29. package/dist/templates/mini-surf/frontend/tsconfig.json +0 -19
  30. package/dist/templates/mini-surf/frontend/vite.config.ts +0 -25
@@ -5,10 +5,8 @@ import path from "path";
5
5
  import { fileURLToPath } from "url";
6
6
  var DEFAULT_FRONTEND_PORT = "5173";
7
7
  var DEFAULT_BACKEND_PORT = "3001";
8
- var DEFAULT_TEMPLATE = "default";
9
8
  async function createSurfApp({
10
9
  projectName = ".",
11
- templateName = DEFAULT_TEMPLATE,
12
10
  frontendPort = process.env.VITE_PORT || DEFAULT_FRONTEND_PORT,
13
11
  backendPort = process.env.VITE_BACKEND_PORT || DEFAULT_BACKEND_PORT,
14
12
  previewBase = process.env.VITE_BASE,
@@ -18,9 +16,9 @@ async function createSurfApp({
18
16
  const name = path.basename(root);
19
17
  const validatedFrontendPort = validatePort("frontend", frontendPort);
20
18
  const validatedBackendPort = validatePort("backend", backendPort);
21
- const templateDir = resolveTemplateDir(templateName);
19
+ const templateDir = resolveTemplateDir();
22
20
  logger(`
23
- Creating Surf app in ${root} (${templateName})
21
+ Creating Surf app in ${root}
24
22
  `);
25
23
  fs.mkdirSync(root, { recursive: true });
26
24
  copyDir(templateDir, root, root, logger);
@@ -42,16 +40,16 @@ Done! Next steps:
42
40
  `);
43
41
  return root;
44
42
  }
45
- function resolveTemplateDir(templateName) {
43
+ function resolveTemplateDir() {
46
44
  const here = path.dirname(fileURLToPath(import.meta.url));
47
45
  const candidates = [
48
- path.join(here, "templates", templateName),
49
- path.join(here, "..", "templates", templateName)
46
+ path.join(here, "templates", "default"),
47
+ path.join(here, "..", "templates", "default")
50
48
  ];
51
49
  for (const candidate of candidates) {
52
50
  if (fs.existsSync(candidate)) return candidate;
53
51
  }
54
- throw new Error(`Could not find template "${templateName}" near ${here}`);
52
+ throw new Error(`Could not find default template near ${here}`);
55
53
  }
56
54
  function copyDir(src, dest, root, logger) {
57
55
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
package/dist/cli.js CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createSurfApp
4
- } from "./chunk-53EUQV7R.js";
4
+ } from "./chunk-MJDS5WZH.js";
5
5
 
6
6
  // src/cli.ts
7
7
  var VALUE_FLAGS = /* @__PURE__ */ new Set([
8
- "--template",
9
8
  "--frontend-port",
10
9
  "--backend-port",
11
10
  "--preview-base"
@@ -35,7 +34,6 @@ function parseCliArgs(args) {
35
34
  }
36
35
  return {
37
36
  projectName: positionalArgs[0] || ".",
38
- templateName: getFlag(args, "--template"),
39
37
  frontendPort: getFlag(args, "--frontend-port"),
40
38
  backendPort: getFlag(args, "--backend-port"),
41
39
  previewBase: getFlag(args, "--preview-base")
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSurfApp
3
- } from "./chunk-53EUQV7R.js";
3
+ } from "./chunk-MJDS5WZH.js";
4
4
  export {
5
5
  createSurfApp
6
6
  };
@@ -1,44 +1,88 @@
1
- # Project Rules
1
+ # Project
2
2
 
3
- ## Do NOT Touch
3
+ Built with [Surf SDK](https://github.com/cyberconnecthq/urania/tree/main/packages/sdk).
4
4
 
5
- - `vite.config.ts` pre-configured proxy chain; changing it breaks preview.
6
- - `.env` files — managed by the system; editing causes Vite restart & preview downtime.
7
- - `entry-client.tsx` `notifyParentReady` / `data-surf-placeholder` — hosting app depends on these.
8
- ## npm install Rules
5
+ ## Imports from @surf-ai/sdk
9
6
 
10
- - **ALL packages in `frontend/package.json` are already installed.** Just import them directly — do NOT run `npm install` for them.
11
- - Running `npm install` on pre-installed packages corrupts the node_modules tmpfs mount, kills the Vite dev server, and causes 5+ minute preview downtime (white screen).
12
- - Only `npm install` packages that are NOT in package.json. When in doubt, read `frontend/package.json` first.
7
+ Everything comes from `@surf-ai/sdk`. Do NOT create local utility files for these.
13
8
 
14
- ## Editing Rules
9
+ **Frontend (`@surf-ai/sdk/react`):**
15
10
 
16
- - **Read before edit** — always Read a file before using Edit or Write on it.
17
- - **Edit, don't rewrite** use the Edit tool on scaffold files (marked SCAFFOLD). Never use Write to replace them entirely; it breaks infrastructure (proxy, HMR, cold-start guards).
18
- - **One file per tool call** — enables streaming progress and faster error recovery.
19
- - **200-line limit** — split components exceeding 200 lines into sub-components.
11
+ ```tsx
12
+ import { useMarketPrice, useTokenHolders } from "@surf-ai/sdk/react"; // data hooks
13
+ ```
20
14
 
21
- ## Storage Rules
15
+ **Backend (`@surf-ai/sdk/server`):**
22
16
 
23
- - **Never use localStorage or in-memory arrays for persistent user data** (CRUD, todos, plans, bookmarks, notes, watchlists, etc.). Read `.claude/skills/database/SKILL.md` and use PostgreSQL + Drizzle ORM.
24
- - localStorage is ONLY acceptable for: theme preference, UI collapsed/expanded state, session tokens.
17
+ ```js
18
+ const { dataApi } = require("@surf-ai/sdk/server");
19
+ const data = await dataApi.market.price({ symbol: "BTC" });
20
+ const holders = await dataApi.token.holders({
21
+ address: "0x...",
22
+ chain: "ethereum",
23
+ });
24
+ // Escape hatch for new endpoints:
25
+ const raw = await dataApi.get("newcategory/endpoint", { foo: "bar" });
26
+ ```
25
27
 
26
- ## Data Table Rules
28
+ ## Structure
27
29
 
28
- - **List tables need sorting + pagination + search.** Tables displaying browsable collections (token lists, tx history, leaderboards — unbounded row count) MUST use the SortableTable pattern from `component-reference/references/data-display.md`. Plain `<Table>` is fine for summary/comparison tables or small bounded-size API results (top-5, recent-3).
30
+ ```
31
+ frontend/src/App.tsx - build your UI here
32
+ frontend/src/components/ - add components
33
+ frontend/src/db/schema.ts - frontend DB schema mirror
34
+ backend/routes/*.js - add API routes (auto-mounted at /api/{name})
35
+ backend/db/schema.js - define database tables
36
+ ```
29
37
 
30
- ## First-Edit Checklist (do on every new project)
38
+ ## Built-in Endpoints (from @surf-ai/sdk/server)
31
39
 
32
- - **Page title** — ALWAYS update `<title>App</title>` in `frontend/index.html` to a meaningful title matching the website purpose. Never ship with `<title>App</title>`.
33
- - **Favicon** — `frontend/public/favicon.ico` is already provided; do NOT delete or overwrite it.
40
+ `createServer()` provides these automatically - do NOT create routes for them:
34
41
 
35
- ## Common Mistakes to Avoid
42
+ | Endpoint | Method | Purpose |
43
+ | -------------------- | ------ | ------------------------------------------------------ |
44
+ | `/api/health` | GET | Health check - `{ status: 'ok' }` |
45
+ | `/api/__sync-schema` | POST | Sync `backend/db/schema.js` tables to database |
46
+ | `/api/cron` | GET | List cron jobs with status and next run time |
47
+ | `/api/cron` | POST | Create a new cron task |
48
+ | `/api/cron/:id` | PATCH | Update a cron task (schedule, enabled, etc.) |
49
+ | `/api/cron/:id` | DELETE | Delete a cron task |
50
+ | `/api/cron/:id/run` | POST | Manually trigger a cron task |
51
+ | `/proxy/*` | ANY | Data API passthrough - `/proxy/market/price` -> hermod |
36
52
 
37
- - **API URLs** — NEVER use bare `/proxy/...` or `/api/...`. Always use `${API_BASE}/proxy/...`, `${API_BASE}/api/...`, or the generated hooks in `api.ts`.
38
- - **No React.lazy / dynamic import()** — HMR is unavailable in preview; causes "Invalid hook call" crashes.
39
- - **Hooks at top level** — ALL React hooks MUST be called before any conditional `return`. Use `useQuery({ enabled: !!condition })` for conditional fetching.
40
- - **SSR safety** — NEVER access `document`, `window`, `localStorage` at module top level or during render. Use `typeof window !== 'undefined'` or `useEffect`.
41
- - **API response safety** — NEVER render API fields without type-checking. Objects as React children cause white-screen crashes: `typeof x === 'string' ? x : x?.name ?? ''`.
42
- - **ThemeProvider** — MUST set `storageKey="surf-studio-theme"` to avoid conflicts with the parent Surf app iframe.
43
- - **No mock data** — never hardcode data. Use real API calls; show proper error/empty states.
44
- - **ASCII only** — no curly quotes, en-dash, em-dash in code. Non-ASCII punctuation causes build failures.
53
+ Auto-registered from `backend/routes/*.js`:
54
+ | File | Endpoint |
55
+ |------|----------|
56
+ | `routes/btc.js` | `/api/btc` |
57
+ | `routes/portfolio.js` | `/api/portfolio` |
58
+
59
+ ## Database
60
+
61
+ Define tables in `backend/db/schema.js` using Drizzle ORM:
62
+
63
+ ```js
64
+ const { pgTable, serial, text, timestamp } = require("drizzle-orm/pg-core");
65
+ exports.users = pgTable("users", {
66
+ id: serial("id").primaryKey(),
67
+ name: text("name").notNull(),
68
+ created_at: timestamp("created_at").defaultNow(),
69
+ });
70
+ ```
71
+
72
+ Tables are auto-created on startup and when `schema.js` changes (file watcher).
73
+ The agent can also call `POST /api/__sync-schema` explicitly after editing.
74
+
75
+ ## Do NOT modify
76
+
77
+ - `vite.config.ts` - proxy and build config
78
+ - `backend/server.js` - uses @surf-ai/sdk/server
79
+ - `entry-client.tsx` - app bootstrap with SSR hydration
80
+ - `entry-server.tsx` - SSR render for deploy
81
+ - `index.html` - cold-start guard and Surf badge
82
+ - `eslint.config.*` - lint rules
83
+ - `index.css` - only imports, do not add styles here (use Tailwind classes)
84
+
85
+ ## Rules
86
+
87
+ - Use `@surf-ai/sdk/react` hooks in frontend, `@surf-ai/sdk/server` dataApi in backend
88
+ - Frontend packages are pre-installed - check `package.json` before installing
@@ -1,20 +1,8 @@
1
- /**
2
- * Drizzle ORM schema definitions.
3
- *
4
- * Define your tables here using Drizzle's pgTable builder.
5
- * This file is the single source of truth for your database schema.
6
- *
7
- * Example:
8
- * const { pgTable, serial, text, boolean, timestamp } = require('drizzle-orm/pg-core');
9
- *
10
- * const todos = pgTable('todos', {
11
- * id: serial('id').primaryKey(),
12
- * title: text('title').notNull(),
13
- * completed: boolean('completed').default(false),
14
- * createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
15
- * });
16
- *
17
- * module.exports = { todos };
18
- */
19
-
20
- // Add your table definitions here.
1
+ // Define your Drizzle ORM tables here.
2
+ // Example:
3
+ // const { pgTable, serial, text, timestamp } = require('drizzle-orm/pg-core')
4
+ // exports.users = pgTable('users', {
5
+ // id: serial('id').primaryKey(),
6
+ // name: text('name').notNull(),
7
+ // created_at: timestamp('created_at').defaultNow(),
8
+ // })
@@ -2,7 +2,7 @@ import js from '@eslint/js';
2
2
  import globals from 'globals';
3
3
 
4
4
  export default [
5
- { ignores: ['node_modules', 'lib/api*.js'] },
5
+ { ignores: ['node_modules'] },
6
6
  {
7
7
  files: ['**/*.js'],
8
8
  ...js.configs.recommended,
@@ -1,26 +1,12 @@
1
1
  {
2
2
  "name": "backend",
3
3
  "private": true,
4
- "version": "0.0.0",
5
4
  "scripts": {
6
- "check": "node --check server.js && find routes lib db -type f -name '*.js' -print0 | xargs -0 -n1 node --check",
7
- "lint": "eslint .",
8
5
  "start": "node server.js",
9
- "dev": "node --watch --watch-path=./routes --watch-path=./lib --watch-path=./server.js server.js",
10
- "verify": "npm run lint && npm run check"
6
+ "dev": "node --watch server.js"
11
7
  },
12
8
  "dependencies": {
13
9
  "@surf-ai/sdk": "0.1.4-beta",
14
- "express": "4.22.1",
15
- "cors": "2.8.6",
16
- "http-proxy-middleware": "3.0.5",
17
- "drizzle-orm": "0.44.7",
18
- "drizzle-kit": "0.30.6",
19
- "croner": "9.1.0"
20
- },
21
- "devDependencies": {
22
- "@eslint/js": "9.39.4",
23
- "eslint": "9.39.4",
24
- "globals": "16.5.0"
10
+ "express": "4.22.1"
25
11
  }
26
12
  }