robodev 0.46.0 → 0.47.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "robodev",
3
- "version": "0.46.0",
3
+ "version": "0.47.0",
4
4
  "description": "CLI for Robodev Starbase — create, auth, link, deploy, load, and run a project locally with robodev dev",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,8 +26,8 @@
26
26
  "embedded-postgres": "17.10.0-beta.17",
27
27
  "fastify": "^5.12.1",
28
28
  "tsx": "^4.20.5",
29
- "@robodev-ai/runtime": "0.7.1",
30
- "@robodev-ai/sdk": "0.13.0"
29
+ "@robodev-ai/sdk": "0.13.0",
30
+ "@robodev-ai/runtime": "0.7.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^24.3.0",
@@ -167,9 +167,17 @@ test("emitStarter shadcn includes hosted Welcome plus orval and shadcn files", a
167
167
  assert.match(index, /<title>Kit<\/title>/);
168
168
  assert.match(index, /src\/main\.tsx/);
169
169
  const app = await readFile(join(dest, "src/App.tsx"), "utf8");
170
- assert.match(app, /<h1>Welcome<\/h1>/);
170
+ assert.match(app, /<Route path="\/" element=\{<Home \/>\} \/>/);
171
171
  assert.doesNotMatch(app, /<h1>Kit<\/h1>/);
172
- assert.match(app, /getHealth/);
172
+ assert.doesNotMatch(app, /<h1>Welcome<\/h1>/);
173
+ const home = await readFile(join(dest, "src/pages/Home.tsx"), "utf8");
174
+ assert.match(home, /<h1>Welcome<\/h1>/);
175
+ assert.match(home, /getHealth/);
176
+ const main = await readFile(join(dest, "src/main.tsx"), "utf8");
177
+ assert.match(main, /BrowserRouter/);
178
+ const notes = await readFile(join(dest, "ROBODEV.md"), "utf8");
179
+ assert.match(notes, /react-router-dom/);
180
+ assert.match(notes, /src\/pages\/Home\.tsx/);
173
181
  const endpoints = await readFile(join(dest, "src/api/generated/endpoints.ts"), "utf8");
174
182
  assert.match(endpoints, /export const getHealth/);
175
183
  assert.doesNotMatch(endpoints, /axios|@tanstack\/react-query/);
@@ -184,6 +192,7 @@ test("emitStarter shadcn includes hosted Welcome plus orval and shadcn files", a
184
192
  assert.equal(pkg.scripts?.["dev:fe"], "vite");
185
193
  assert.equal(pkg.scripts?.["generate:api"], "orval");
186
194
  assert.equal(pkg.dependencies?.["@robodev-ai/client"], "^0.12.0");
195
+ assert.match(pkg.dependencies?.["react-router-dom"] ?? "", /^\^6/);
187
196
  assert.match(pkg.devDependencies?.orval ?? "", /^\^/);
188
197
  const readme = await readFile(join(dest, "README.md"), "utf8");
189
198
  assert.match(readme, /^# Kit/m);
@@ -200,6 +209,8 @@ test("collectFiles for shadcn starter includes hosted Welcome and tooling config
200
209
  assert.ok(paths.has("robodev/api/health.ts"));
201
210
  assert.ok(paths.has("index.html"));
202
211
  assert.ok(paths.has("src/main.tsx"));
212
+ assert.ok(paths.has("src/pages/Home.tsx"));
213
+ assert.ok(paths.has("ROBODEV.md"));
203
214
  assert.ok(paths.has("src/components/ui/button.tsx"));
204
215
  assert.ok(paths.has("src/api/generated/endpoints.ts"));
205
216
  assert.ok(paths.has("src/api/openapi.json"));
@@ -12,7 +12,7 @@
12
12
  "@robodev-ai/sdk": "^0.13.0"
13
13
  },
14
14
  "devDependencies": {
15
- "robodev": "^0.46.0",
15
+ "robodev": "^0.47.0",
16
16
  "rulesync": "^8.18.0",
17
17
  "typescript": "^5.9.2"
18
18
  }
@@ -11,7 +11,7 @@
11
11
  "@robodev-ai/sdk": "^0.13.0"
12
12
  },
13
13
  "devDependencies": {
14
- "robodev": "^0.46.0",
14
+ "robodev": "^0.47.0",
15
15
  "typescript": "^5.9.2"
16
16
  }
17
17
  }
@@ -16,7 +16,7 @@
16
16
  "react-dom": "^18.3.1"
17
17
  },
18
18
  "devDependencies": {
19
- "robodev": "^0.46.0",
19
+ "robodev": "^0.47.0",
20
20
  "typescript": "^5.9.2",
21
21
  "vite": "^6.0.0"
22
22
  }
@@ -12,7 +12,7 @@
12
12
  "@robodev-ai/sdk": "^0.13.0"
13
13
  },
14
14
  "devDependencies": {
15
- "robodev": "^0.46.0",
15
+ "robodev": "^0.47.0",
16
16
  "rulesync": "^8.18.0",
17
17
  "typescript": "^5.9.2"
18
18
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  Blank `robodev/database.ts` and `GET /api/health` plus a hosted Welcome page with shadcn and an orval client. No sample schema.
4
4
 
5
- The project App URL serves the hosted Welcome page. Edit `index.html` and `src/`, then `robodev deploy` (or Code + Save).
5
+ The project App URL serves the hosted Welcome page (`/` via React Router in `src/pages/Home.tsx`). Edit `index.html` and `src/`, then `robodev deploy` (or Code + Save). Agents: read `ROBODEV.md`.
6
6
 
7
7
  ```bash
8
8
  robodev create my-app --template shadcn
@@ -0,0 +1,67 @@
1
+ # Robodev
2
+
3
+ Agent notes for this Shadcn workspace. Use this file for Robodev and SDK facts. Do not web-search the SDK.
4
+
5
+ This is the hosted Shadcn layout. Keep it. Do not convert this tree to Tiny (`packages/be` + `apps/fe`).
6
+
7
+ ## Layout
8
+
9
+ - Schema: `robodev/database.ts` (`defineDatabase` from `@robodev-ai/sdk`)
10
+ - HTTP handlers: `robodev/api/**/*.ts` (`defineApi` from `@robodev-ai/sdk`)
11
+ - Optional jobs: `robodev/jobs/**/*.ts`. Optional sockets: `robodev/sockets/**/*.ts` (`defineSocket`). Optional runtime packages go in `robodev/package.json` (allowlisted exact semver only). Do not npm install in this runner — Starbase installs on publish.
12
+ - Frontend: root `index.html` + `src/**` (React, React Router, shadcn, generated orval client)
13
+ - Auth is reserved at `/api/user/*`. Do not add `robodev/api/user/**`.
14
+
15
+ Do not write a `frontend` block in `robodev/.robodev` — that block is for Tiny `apps/fe`. Root `index.html` + `src/` deploy as hosted React.
16
+
17
+ ## defineApi (copy-paste)
18
+
19
+ `db`, `email`, `storage`, and `env` are injected. Never `import { db } from "@robodev-ai/sdk"`.
20
+ The SDK is not installed in the runner. Do not `import("@robodev-ai/sdk")`. Do not search `/opt`, `node_modules`, or grok/gemini home for it.
21
+
22
+ ```ts
23
+ import { defineApi, z } from "@robodev-ai/sdk";
24
+
25
+ export const get = defineApi({
26
+ response: z.object({ ok: z.literal(true) }),
27
+ handler: async ({ db, email, storage, env }) => {
28
+ void db;
29
+ void email;
30
+ void storage;
31
+ void env;
32
+ return { ok: true as const };
33
+ },
34
+ });
35
+ ```
36
+
37
+ ## Hard rules
38
+
39
+ - Do not run npm, pnpm, or yarn install.
40
+ - Do not start npm run dev, vite, or any local server.
41
+ - Do not run tsc (node_modules is not installed in this runner).
42
+ - Do not port-scan or curl/fetch localhost.
43
+ - Preview is the WebContainer. Live APIs exist only after `robodev-publish be`.
44
+ - Publish backend after a batch of file edits, not after every file.
45
+ - Do not publish the frontend.
46
+
47
+ ## Backend
48
+
49
+ - Layout is `robodev/`. `robodev-publish be` maps `robodev/database.ts` → `database.ts` and `robodev/api/**` → `api/**`.
50
+ - Auth: robodev-auth get / set / users / users-delete. Do not invent control-plane HTTP.
51
+ - Secrets: robodev-secret list / set / delete. Use env.NAME in defineApi. List names only.
52
+ - SQL: psql or robodev-sql for DML, SELECT, and seed only. Never print DATABASE_URL. Never run DDL.
53
+ - Publish backend only with robodev-publish be. Do not publish the frontend.
54
+
55
+ ## Frontend
56
+
57
+ - Route with React Router in `src/`. `src/pages/Home.tsx` is `/`. Add a page by adding a component and a `<Route>` in `src/App.tsx`.
58
+ - Call APIs through the committed orval client under `src/api/generated`. After API changes, update `src/api/openapi.json` and regenerate.
59
+ - UI: shadcn under `src/components/ui`. Hosted compile does not run Tailwind. Keep hosted CSS in `src/app.css`. `tailwind.config.ts` and `postcss.config.js` are for local `shadcn add` / Vite only.
60
+ - Hosted FE packages: `react`, `react-dom`, `react-router-dom`, `@robodev-ai/client`. Do not import other npm packages in `src/` — hosted compile will fail.
61
+ - Preview runs `pnpm install` / `vite --host` from the project root. Do not run those in this runner.
62
+
63
+ ## Allowed paths
64
+
65
+ `robodev/database.ts`, `robodev/api/**/*.ts`, `robodev/jobs/**/*.ts`, `robodev/sockets/**/*.ts`, `robodev/hooks/**/*.ts`, `robodev/package.json`, `index.html`, `src/**`, `package.json`, `README.md`, `ROBODEV.md`, `.gitignore`.
66
+
67
+ Never write `.env` or secrets. Never write `.robodev`.
@@ -14,13 +14,14 @@
14
14
  "@robodev-ai/sdk": "^0.13.0",
15
15
  "@robodev-ai/client": "^0.5.0",
16
16
  "react": "^18.3.1",
17
- "react-dom": "^18.3.1"
17
+ "react-dom": "^18.3.1",
18
+ "react-router-dom": "^6.30.1"
18
19
  },
19
20
  "devDependencies": {
20
21
  "autoprefixer": "^10.4.21",
21
22
  "orval": "^7.11.2",
22
23
  "postcss": "^8.5.6",
23
- "robodev": "^0.46.0",
24
+ "robodev": "^0.47.0",
24
25
  "shadcn": "^2.10.0",
25
26
  "tailwindcss": "^3.4.17",
26
27
  "typescript": "^5.9.2",
@@ -1,35 +1,10 @@
1
- import { useEffect, useState } from "react";
2
- import { getHealth } from "@/api/generated/endpoints";
3
- import { Button } from "@/components/ui/button";
1
+ import { Route, Routes } from "react-router-dom";
2
+ import { Home } from "./pages/Home";
4
3
 
5
4
  export function App() {
6
- const [status, setStatus] = useState("Checking health…");
7
-
8
- async function loadHealth() {
9
- try {
10
- const result = await getHealth();
11
- if (result.status !== 200 || result.data.ok !== true) {
12
- setStatus(`Request failed (${result.status})`);
13
- return;
14
- }
15
- setStatus("{ ok: true }");
16
- } catch (error) {
17
- setStatus(error instanceof Error ? error.message : "Request failed");
18
- }
19
- }
20
-
21
- useEffect(() => {
22
- void loadHealth();
23
- }, []);
24
-
25
5
  return (
26
- <main>
27
- <h1>Welcome</h1>
28
- <p>Your app is ready.</p>
29
- <Button type="button" onClick={() => void loadHealth()}>
30
- Check health
31
- </Button>
32
- <p>{status}</p>
33
- </main>
6
+ <Routes>
7
+ <Route path="/" element={<Home />} />
8
+ </Routes>
34
9
  );
35
10
  }
@@ -1,5 +1,10 @@
1
1
  import { createRoot } from "react-dom/client";
2
+ import { BrowserRouter } from "react-router-dom";
2
3
  import { App } from "./App";
3
4
  import "./app.css";
4
5
 
5
- createRoot(document.getElementById("root")!).render(<App />);
6
+ createRoot(document.getElementById("root")!).render(
7
+ <BrowserRouter>
8
+ <App />
9
+ </BrowserRouter>,
10
+ );
@@ -0,0 +1,35 @@
1
+ import { useEffect, useState } from "react";
2
+ import { getHealth } from "@/api/generated/endpoints";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ export function Home() {
6
+ const [status, setStatus] = useState("Checking health…");
7
+
8
+ async function loadHealth() {
9
+ try {
10
+ const result = await getHealth();
11
+ if (result.status !== 200 || result.data.ok !== true) {
12
+ setStatus(`Request failed (${result.status})`);
13
+ return;
14
+ }
15
+ setStatus("{ ok: true }");
16
+ } catch (error) {
17
+ setStatus(error instanceof Error ? error.message : "Request failed");
18
+ }
19
+ }
20
+
21
+ useEffect(() => {
22
+ void loadHealth();
23
+ }, []);
24
+
25
+ return (
26
+ <main>
27
+ <h1>Welcome</h1>
28
+ <p>Your app is ready.</p>
29
+ <Button type="button" onClick={() => void loadHealth()}>
30
+ Check health
31
+ </Button>
32
+ <p>{status}</p>
33
+ </main>
34
+ );
35
+ }
@@ -12,7 +12,7 @@
12
12
  "@robodev-ai/sdk": "^0.13.0"
13
13
  },
14
14
  "devDependencies": {
15
- "robodev": "^0.46.0",
15
+ "robodev": "^0.47.0",
16
16
  "rulesync": "^8.18.0",
17
17
  "typescript": "^5.9.2"
18
18
  }