@lunora/cli 1.0.0-alpha.42 → 1.0.0-alpha.420
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/LICENSE.md +33 -0
- package/README.md +3 -1
- package/dist/bin.mjs +2 -10
- package/dist/index.d.mts +1069 -374
- package/dist/index.d.ts +1069 -374
- package/dist/index.mjs +1 -19
- package/dist/packem_chunks/dispatch.mjs +1 -0
- package/dist/packem_chunks/handler.mjs +23 -158
- package/dist/packem_chunks/handler10.mjs +1 -16
- package/dist/packem_chunks/handler11.mjs +1 -22
- package/dist/packem_chunks/handler12.mjs +1 -192
- package/dist/packem_chunks/handler13.mjs +1 -131
- package/dist/packem_chunks/handler14.mjs +3 -65
- package/dist/packem_chunks/handler15.mjs +1 -58
- package/dist/packem_chunks/handler16.mjs +1 -80
- package/dist/packem_chunks/handler17.mjs +1 -43
- package/dist/packem_chunks/handler18.mjs +7 -105
- package/dist/packem_chunks/handler19.mjs +2 -170
- package/dist/packem_chunks/handler2.mjs +1 -114
- package/dist/packem_chunks/handler20.mjs +1 -94
- package/dist/packem_chunks/handler21.mjs +3 -94
- package/dist/packem_chunks/handler22.mjs +3 -0
- package/dist/packem_chunks/handler23.mjs +1 -0
- package/dist/packem_chunks/handler24.mjs +2 -0
- package/dist/packem_chunks/handler25.mjs +99 -0
- package/dist/packem_chunks/handler26.mjs +2 -0
- package/dist/packem_chunks/handler27.mjs +9 -0
- package/dist/packem_chunks/handler28.mjs +1 -0
- package/dist/packem_chunks/handler3.mjs +1 -204
- package/dist/packem_chunks/handler4.mjs +1 -33
- package/dist/packem_chunks/handler5.mjs +3 -49
- package/dist/packem_chunks/handler6.mjs +1 -91
- package/dist/packem_chunks/handler7.mjs +1 -42
- package/dist/packem_chunks/handler8.mjs +1 -174
- package/dist/packem_chunks/handler9.mjs +2 -315
- package/dist/packem_chunks/runCodegenCommand.mjs +4 -52
- package/dist/packem_chunks/runDevCommand.mjs +2 -0
- package/dist/packem_chunks/runInitCommand.mjs +165 -1432
- package/dist/packem_chunks/runResetCommand.mjs +1 -41
- package/dist/packem_chunks/runRpcCommand.mjs +1 -68
- package/dist/packem_shared/COMMANDS-BCSDC-pv.mjs +1 -0
- package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-CyIsI3S1.mjs +1 -0
- package/dist/packem_shared/EXIT_CODE-D_XCixv8.mjs +1 -0
- package/dist/packem_shared/admin-token-VdUnvnKW.mjs +1 -0
- package/dist/packem_shared/admin-url-DJB8P6Jh.mjs +1 -0
- package/dist/packem_shared/api-spec-lYyq4vL6.mjs +1 -0
- package/dist/packem_shared/binding-manifest-file-CQ1eQYy1.mjs +2 -0
- package/dist/packem_shared/buildRegistryIndex-Dc8D8AR6.mjs +1 -0
- package/dist/packem_shared/cap-error-body-YBKO32BF.mjs +1 -0
- package/dist/packem_shared/catalog-CahzmDLV.mjs +1 -0
- package/dist/packem_shared/cli-BbgDNGew.mjs +2 -0
- package/dist/packem_shared/cli-manifest-DoQ_3bzs.mjs +1 -0
- package/dist/packem_shared/cloudflare-credentials-BVmZnDZk.mjs +1 -0
- package/dist/packem_shared/codegen-error-AmH54ofi.mjs +3 -0
- package/dist/packem_shared/command-CB4JM-Jl.mjs +1 -0
- package/dist/packem_shared/commands-DvSfLvyt.mjs +13 -0
- package/dist/packem_shared/createLogger-4TujevyB.mjs +2 -0
- package/dist/packem_shared/createRecordingSpawner-Ch7zuQQE.mjs +1 -0
- package/dist/packem_shared/deploy-target-resolve-BTCW1Iv4.mjs +1 -0
- package/dist/packem_shared/diffSnapshots-htqNZT8Q.mjs +7 -0
- package/dist/packem_shared/docker-DpVxvYpL.mjs +1 -0
- package/dist/packem_shared/free-port-DjbFhaaT.mjs +1 -0
- package/dist/packem_shared/health-probe-Bw9JFfIy.mjs +1 -0
- package/dist/packem_shared/import-BRM1hs7j.mjs +12 -0
- package/dist/packem_shared/index-oHZBGBwB.mjs +1 -0
- package/dist/packem_shared/insertSchemaExtension-DuiV6cba.mjs +8 -0
- package/dist/packem_shared/lint-ignore-report-DKZagpqk.mjs +2 -0
- package/dist/packem_shared/mcp-config-file-CcDTeXIq.mjs +2 -0
- package/dist/packem_shared/open-url-EnKy--w-.mjs +1 -0
- package/dist/packem_shared/output-format-DWe_tkTR.mjs +2 -0
- package/dist/packem_shared/parseManifest-CwPTKdtS.mjs +1 -0
- package/dist/packem_shared/path-containment-CgxYZggb.mjs +1 -0
- package/dist/packem_shared/plan-DFY3CqHD.mjs +5 -0
- package/dist/packem_shared/planDevCommand-BDoJUgQ4.mjs +1 -0
- package/dist/packem_shared/platform-diagnostics-Cn2g6Jh-.mjs +4 -0
- package/dist/packem_shared/prompt-cancelled-BvsNxg_Q.mjs +1 -0
- package/dist/packem_shared/render-lunora-error-B6893vbU.mjs +2 -0
- package/dist/packem_shared/resolve-Bdc9KEUv.mjs +5 -0
- package/dist/packem_shared/resolve-target-C_ZloTvd.mjs +1 -0
- package/dist/packem_shared/runAddCommand-BChdJQ5L.mjs +1 -0
- package/dist/packem_shared/runDeployCommand-D40F3PLQ.mjs +1 -0
- package/dist/packem_shared/runExportCommand-slAq5BCF.mjs +5 -0
- package/dist/packem_shared/runMigrateGenerateCommand-BwemPIOz.mjs +11 -0
- package/dist/packem_shared/schemaIrToSnapshot-BHuNOfgs.mjs +1 -0
- package/dist/packem_shared/secret-key-8DPOH98z.mjs +1 -0
- package/dist/packem_shared/shared-D-zCOmgY.mjs +1 -0
- package/dist/packem_shared/storage-DNzYhXR-.mjs +1 -0
- package/dist/packem_shared/tui-prompts-B3YwUhGw.mjs +4 -0
- package/dist/packem_shared/variables-CPYyJtsL.mjs +1 -0
- package/dist/packem_shared/wrangler-name-Dsk5K1f-.mjs +1 -0
- package/dist/packem_shared/wrangler-secrets-CTQPpalP.mjs +1 -0
- package/package.json +39 -19
- package/skills/README.md +36 -17
- package/skills/lunora/SKILL.md +158 -65
- package/skills/lunora-cloudflare-audit/SKILL.md +163 -0
- package/skills/lunora-create-package/SKILL.md +97 -84
- package/skills/lunora-deploy/SKILL.md +175 -105
- package/skills/lunora-functions/SKILL.md +363 -56
- package/skills/lunora-migration-helper/SKILL.md +162 -137
- package/skills/lunora-performance-audit/SKILL.md +137 -95
- package/skills/lunora-quickstart/SKILL.md +136 -136
- package/skills/lunora-realtime/SKILL.md +217 -97
- package/skills/lunora-setup-auth/SKILL.md +162 -102
- package/skills/lunora-setup-hyperdrive/SKILL.md +130 -109
- package/skills/lunora-setup-hyperdrive-global/SKILL.md +93 -90
- package/skills/lunora-setup-mail/SKILL.md +85 -113
- package/skills/lunora-setup-scheduler/SKILL.md +132 -96
- package/skills/lunora-setup-storage/SKILL.md +189 -95
- package/dist/packem_chunks/planDevCommand.mjs +0 -541
- package/dist/packem_chunks/runDeployCommand.mjs +0 -594
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +0 -397
- package/dist/packem_shared/COMMANDS-B0ftFD_3.mjs +0 -948
- package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs +0 -244
- package/dist/packem_shared/admin-url-4UzT-CI4.mjs +0 -19
- package/dist/packem_shared/api-spec-CtA6ilu4.mjs +0 -13
- package/dist/packem_shared/buildRegistryIndex-BcYe607_.mjs +0 -38
- package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +0 -31
- package/dist/packem_shared/command-D3lB_4Az.mjs +0 -19
- package/dist/packem_shared/commands-B-gR09Z_.mjs +0 -845
- package/dist/packem_shared/createLogger-B40gPzQo.mjs +0 -78
- package/dist/packem_shared/createRecordingSpawner-DxI3mebw.mjs +0 -43
- package/dist/packem_shared/detect-package-manager-DYp7n3mJ.mjs +0 -61
- package/dist/packem_shared/diffSnapshots-BeDvvNiF.mjs +0 -161
- package/dist/packem_shared/docker-hMQ97KSQ.mjs +0 -21
- package/dist/packem_shared/insertSchemaExtension-DAqbfr9Z.mjs +0 -64
- package/dist/packem_shared/open-url-Dfq6fAyT.mjs +0 -41
- package/dist/packem_shared/output-format-wUvAN6AL.mjs +0 -17
- package/dist/packem_shared/parseArgs-YXFuKdEk.mjs +0 -56
- package/dist/packem_shared/parseManifest--vZf2FY1.mjs +0 -94
- package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +0 -9
- package/dist/packem_shared/resolve-target-qbsJ_5sF.mjs +0 -16
- package/dist/packem_shared/runAddCommand-bnY6-HKb.mjs +0 -4
- package/dist/packem_shared/schema-drift-gate-BtBt0as0.mjs +0 -79
- package/dist/packem_shared/schemaIrToSnapshot-DdsljJT-.mjs +0 -43
- package/dist/packem_shared/storage-BIsph-Vk.mjs +0 -84
- package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +0 -658
- package/dist/packem_shared/wrangler-name-cy4yhm9j.mjs +0 -12
- package/dist/packem_shared/wrangler-secrets-P2_ZUR-k.mjs +0 -47
|
@@ -1,119 +1,118 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lunora-quickstart
|
|
3
|
-
description: Creates or adds Lunora to an app
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
description: Creates a new Lunora project or adds Lunora to an existing app, then gets
|
|
4
|
+
the first schema + query/mutation round-trip running. Use when the user asks
|
|
5
|
+
to "start a Lunora app", "add Lunora to my Vite/Next/Nuxt/SvelteKit/Astro
|
|
6
|
+
app", runs `lunora init` (`--vite`, `-t`, `--here`, `--add`), needs the
|
|
7
|
+
client provider wired (`LunoraClient` + `LunoraProvider`), or is running
|
|
8
|
+
`lunora dev` for the first time (background mode, `lunora dev status`/`logs`/
|
|
9
|
+
`stop`, `VITE_LUNORA_URL`).
|
|
6
10
|
---
|
|
7
11
|
|
|
8
12
|
# Lunora Quickstart
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
Get a working Lunora project with one live query/mutation round-trip.
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
- Adding Lunora to an existing Vite, Next.js, Astro, Nuxt, SvelteKit, or
|
|
16
|
-
TanStack Start app.
|
|
17
|
-
- Scaffolding a Lunora app for prototyping.
|
|
18
|
-
|
|
19
|
-
## When Not to Use
|
|
20
|
-
|
|
21
|
-
- The project already has Lunora installed and `lunora/` exists — just build,
|
|
22
|
-
and run `lunora codegen` after schema/function edits.
|
|
23
|
-
- You only need to add auth to an existing Lunora app — use the
|
|
24
|
-
`lunora-setup-auth` skill.
|
|
16
|
+
Skip this skill when `lunora/` already exists (just build, and run
|
|
17
|
+
`lunora codegen` after edits) or when the task is only auth
|
|
18
|
+
(`lunora-setup-auth`).
|
|
25
19
|
|
|
26
20
|
## Workflow
|
|
27
21
|
|
|
28
|
-
1.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
4.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
start it in the background for cloud/headless agents — it is long-running and
|
|
36
|
-
does not exit).
|
|
37
|
-
6. Verify a query/mutation round-trip works end to end.
|
|
22
|
+
1. New project: `lunora init <name> --vite <framework>` or `-t <template>`.
|
|
23
|
+
Existing app: `lunora init --here`.
|
|
24
|
+
2. `lunora codegen` to generate `lunora/_generated/`.
|
|
25
|
+
3. Start the dev server in the background (`lunora dev --background`).
|
|
26
|
+
4. Write or adapt a query + mutation and use them from a component.
|
|
27
|
+
5. `lunora verify` (wrangler config + codegen dry-run + `tsc --noEmit`) passes,
|
|
28
|
+
and the client re-renders live after a mutation.
|
|
38
29
|
|
|
39
|
-
## Path 1:
|
|
40
|
-
|
|
41
|
-
`lunora init` fetches a whole-project template (frontend + worker entry + Vite
|
|
42
|
-
plugin + `lunora/` already wired together).
|
|
30
|
+
## Path 1: new project
|
|
43
31
|
|
|
44
32
|
```bash
|
|
45
|
-
lunora init my-app --
|
|
33
|
+
lunora init my-app --vite react
|
|
46
34
|
cd my-app
|
|
47
35
|
pnpm install
|
|
48
36
|
```
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
| `
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
`
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
38
|
+
Two scaffold paths take different flags.
|
|
39
|
+
|
|
40
|
+
`--vite <framework>` applies the Lunora layer over the official create-vite
|
|
41
|
+
base. Use it for a plain SPA: `react` (the default), `vue`, `solid`, `svelte`,
|
|
42
|
+
or `vanilla` (overlay-only, not in the picker). `-t react|vue|solid|svelte` is
|
|
43
|
+
accepted as an alias for the same overlay.
|
|
44
|
+
|
|
45
|
+
`-t` / `--template <type>` fetches a whole-project template from
|
|
46
|
+
`gh:anolilab/lunora/templates/<type>`:
|
|
47
|
+
|
|
48
|
+
| `-t` value | Stack |
|
|
49
|
+
| ----------------------------- | ---------------------------------------------------------------- |
|
|
50
|
+
| `next` | Next.js App Router (OpenNext) + a standalone Lunora worker |
|
|
51
|
+
| `vinext` | Next.js App Router on Vite (vinext), one worker (experimental) |
|
|
52
|
+
| `vinext-pages` | Next.js Pages Router on Vite (vinext), one worker (experimental) |
|
|
53
|
+
| `tanstack-start-react` | TanStack Start (React), SSR with live-loader routes |
|
|
54
|
+
| `tanstack-start-solid` | TanStack Start (Solid) |
|
|
55
|
+
| `tanstack-start-react-rspack` | TanStack Start (React) on Rsbuild, one worker |
|
|
56
|
+
| `rspack-react` | React SPA on Rsbuild (`@lunora/rspack`) |
|
|
57
|
+
| `solid-v2` | Solid 2.0 SPA (`@solidjs/web`, `vite-plugin-solid` 3) |
|
|
58
|
+
| `astro` | Astro, Lunora composed into the adapter worker |
|
|
59
|
+
| `sveltekit` | SvelteKit, Lunora composed into the adapter worker |
|
|
60
|
+
| `nuxt` | Nuxt (Vue), Lunora mounted in Nitro |
|
|
61
|
+
| `analog` | AnalogJS (Angular), Lunora mounted in Nitro |
|
|
62
|
+
| `expo` | React Native (Expo) app + a Lunora worker |
|
|
63
|
+
| `standalone` | Worker-only backend, no frontend |
|
|
64
|
+
|
|
65
|
+
There is no `vite` template value; `-t vite` errors. Solid 2.0 is a template
|
|
66
|
+
rather than an overlay because create-vite's Solid base is still 1.x, so
|
|
67
|
+
`--vite solid` stays on Solid 1.x.
|
|
68
|
+
|
|
69
|
+
In a non-interactive shell, `init` errors unless it gets a name and a framework
|
|
70
|
+
(or `--yes`, which takes the React overlay). As an agent, pass `--vite` or `-t`
|
|
71
|
+
explicitly; if the user stated no preference, use `--vite react`.
|
|
72
|
+
|
|
73
|
+
Other flags:
|
|
70
74
|
|
|
71
75
|
```bash
|
|
72
|
-
lunora
|
|
76
|
+
lunora init my-app --vite react --ci github # add a deploy pipeline (or --ci gitlab)
|
|
77
|
+
lunora init my-app -t next --add auth,email # add capabilities without prompting
|
|
78
|
+
lunora init my-app --vite react --yes # skip the interactive auth/email offer
|
|
79
|
+
lunora init my-app --vite react --dry-run # walk every step, write nothing
|
|
73
80
|
```
|
|
74
81
|
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
`--add` takes a comma-separated list of `ai | auth | auth-ui | backup | browser
|
|
83
|
+
| cloudflare-access | crons | email | flags | hyperdrive | payment | presence |
|
|
84
|
+
queue | storage | workflow`. `--ref <branch|tag|commit>` pins the template
|
|
85
|
+
source (e.g. `--ref alpha`); `--from <dir>` copies from a local templates root.
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
lunora dev
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
`lunora dev` runs the Vite dev server with the Cloudflare Worker on the same
|
|
85
|
-
origin, plus codegen-on-save and the Lunora Studio. It is long-running and does
|
|
86
|
-
not exit, so:
|
|
87
|
-
|
|
88
|
-
- **Local development (user at the keyboard):** ask the user to run `lunora dev`
|
|
89
|
-
in a terminal.
|
|
90
|
-
- **Cloud or headless agents:** start `lunora dev` in the background.
|
|
91
|
-
|
|
92
|
-
Vite serves on `http://localhost:5173` by default; the Worker is served on the
|
|
93
|
-
same origin via `@cloudflare/vite-plugin`.
|
|
94
|
-
|
|
95
|
-
## Path 2: Add Lunora to an Existing App
|
|
96
|
-
|
|
97
|
-
Use this when the user already has a Vite-based frontend and wants Lunora as the
|
|
98
|
-
backend.
|
|
87
|
+
## Path 2: add Lunora to an existing app
|
|
99
88
|
|
|
100
89
|
```bash
|
|
101
90
|
lunora init --here
|
|
102
91
|
```
|
|
103
92
|
|
|
104
|
-
This
|
|
105
|
-
|
|
106
|
-
`lunora
|
|
93
|
+
This detects the framework from `package.json`, scaffolds `lunora/schema.ts` and
|
|
94
|
+
`lunora/messages.ts` (skipped if a schema exists), and patches or creates the
|
|
95
|
+
Vite config with the `lunora()` plugin. SvelteKit, Nuxt and Astro wire Lunora
|
|
96
|
+
through their server entry instead, so their Vite config is left alone. It then
|
|
97
|
+
prints framework-specific next steps: the packages to install, the provider to
|
|
98
|
+
mount, and how to compose the worker. Follow those; the CLI does not edit
|
|
99
|
+
framework-owned files.
|
|
107
100
|
|
|
108
|
-
|
|
101
|
+
Templates and `--vite` overlays map `#lunora/*` to `./lunora/*` in
|
|
102
|
+
`package.json` `imports`, which is why their function files import
|
|
103
|
+
`#lunora/_generated/server.js`. A `--here` project has no such mapping; its
|
|
104
|
+
starter uses the relative `./_generated/server`. Match whichever the project
|
|
105
|
+
already uses.
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
### Client provider
|
|
108
|
+
|
|
109
|
+
Create the `LunoraClient` once at module scope (not inside a component, or every
|
|
110
|
+
render opens a new socket) and wrap the app in the framework provider:
|
|
112
111
|
|
|
113
112
|
```tsx
|
|
114
113
|
// src/client/main.tsx
|
|
115
|
-
import { LunoraClient } from "@lunora/client";
|
|
116
114
|
import { LunoraProvider } from "@lunora/react";
|
|
115
|
+
import { LunoraClient } from "lunorash/client";
|
|
117
116
|
import { StrictMode } from "react";
|
|
118
117
|
import { createRoot } from "react-dom/client";
|
|
119
118
|
|
|
@@ -132,18 +131,19 @@ createRoot(document.querySelector("#root")!).render(
|
|
|
132
131
|
);
|
|
133
132
|
```
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
`
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
`LunoraClient` is also exported by `@lunora/client`. Other adapters:
|
|
135
|
+
`@lunora/vue`, `@lunora/solid`, `@lunora/svelte`, `@lunora/angular`
|
|
136
|
+
(`provideLunora` / `injectLunoraClient`), and `@lunora/react-native`
|
|
137
|
+
(`createLunoraClient`, re-exporting `@lunora/react`). `@lunora/astro` and
|
|
138
|
+
`@lunora/nuxt` mount Lunora server-side. `VITE_LUNORA_URL` is optional; the
|
|
139
|
+
same-origin default is right for local dev.
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
## First function
|
|
142
142
|
|
|
143
143
|
`lunora/schema.ts`:
|
|
144
144
|
|
|
145
145
|
```ts
|
|
146
|
-
import { defineSchema, defineTable, v } from "
|
|
146
|
+
import { defineSchema, defineTable, v } from "lunorash/server";
|
|
147
147
|
|
|
148
148
|
export default defineSchema({
|
|
149
149
|
todos: defineTable({
|
|
@@ -157,27 +157,25 @@ export default defineSchema({
|
|
|
157
157
|
`lunora/todos.ts`:
|
|
158
158
|
|
|
159
159
|
```ts
|
|
160
|
-
import
|
|
161
|
-
import { mutation, query, v } from "@lunora/server";
|
|
160
|
+
import { mutation, query, v } from "#lunora/_generated/server.js";
|
|
162
161
|
|
|
163
162
|
export const list = query.query(async ({ ctx }) => ctx.db.query("todos").withIndex("by_creation").collect());
|
|
164
163
|
|
|
165
164
|
export const add = mutation
|
|
166
|
-
.input({ text: v.string() })
|
|
167
|
-
.mutation(async ({ ctx, args
|
|
165
|
+
.input({ text: v.string().max(4096) })
|
|
166
|
+
.mutation(async ({ ctx, args }) => ctx.db.insert("todos", { text: args.text, done: false, createdAt: Date.now() }));
|
|
168
167
|
```
|
|
169
168
|
|
|
170
|
-
Run `lunora codegen`, then
|
|
171
|
-
`
|
|
169
|
+
Run `lunora codegen`, then call it from a component. Argument and return types
|
|
170
|
+
are inferred from the generated `api`, so no casts are needed:
|
|
172
171
|
|
|
173
172
|
```tsx
|
|
174
173
|
import { useMutation, useQuery } from "@lunora/react";
|
|
175
174
|
|
|
176
175
|
import { api } from "../../lunora/_generated/api";
|
|
177
|
-
import type { Doc } from "../../lunora/_generated/dataModel";
|
|
178
176
|
|
|
179
|
-
|
|
180
|
-
const todos = useQuery(api.todos.list, {})
|
|
177
|
+
export const Todos = () => {
|
|
178
|
+
const todos = useQuery(api.todos.list, {});
|
|
181
179
|
const { mutate: add, pending } = useMutation(api.todos.add);
|
|
182
180
|
|
|
183
181
|
return (
|
|
@@ -185,56 +183,58 @@ function Todos() {
|
|
|
185
183
|
<button disabled={pending} onClick={() => add({ text: "New todo" })}>
|
|
186
184
|
Add
|
|
187
185
|
</button>
|
|
188
|
-
{todos?.map((
|
|
189
|
-
<div key={
|
|
186
|
+
{todos?.map((todo) => (
|
|
187
|
+
<div key={todo._id}>{todo.text}</div>
|
|
190
188
|
))}
|
|
191
189
|
</div>
|
|
192
190
|
);
|
|
193
|
-
}
|
|
191
|
+
};
|
|
194
192
|
```
|
|
195
193
|
|
|
196
|
-
`useQuery`
|
|
197
|
-
mutation changes the queried rows.
|
|
194
|
+
`useQuery` returns `undefined` while loading, then re-renders whenever a
|
|
195
|
+
mutation changes the queried rows. A function in a folder nests in `api`:
|
|
196
|
+
`lunora/billing/invoices.ts` is `api.billing.invoices.*`.
|
|
197
|
+
|
|
198
|
+
## Dev server
|
|
198
199
|
|
|
199
|
-
|
|
200
|
+
`lunora dev` runs the worker (behind Vite via `@cloudflare/vite-plugin` in Vite
|
|
201
|
+
projects), codegen-on-save, and the embedded Studio at `/__lunora`. It does not
|
|
202
|
+
exit on its own.
|
|
200
203
|
|
|
201
|
-
|
|
204
|
+
- User at the keyboard: ask them to run `lunora dev` in a terminal.
|
|
205
|
+
- Agent: run `lunora dev --background`. It detaches, waits until the server
|
|
206
|
+
answers, prints `Dev server running at <url> (pid <n>)`, and exits. When an AI
|
|
207
|
+
agent is detected (Claude Code, Cursor, Codex, …), plain `lunora dev` does
|
|
208
|
+
this automatically with JSON logs; `LUNORA_AGENT_MODE=0` opts out. Avoid a
|
|
209
|
+
bare foreground `lunora dev` in your own shell, since it blocks until killed.
|
|
202
210
|
|
|
203
211
|
```bash
|
|
204
|
-
lunora
|
|
212
|
+
lunora dev status --json # url, pid, uptime, logFile
|
|
213
|
+
lunora dev logs --lines 50 # tail .lunora/dev.log
|
|
214
|
+
lunora dev stop # idempotent
|
|
205
215
|
```
|
|
206
216
|
|
|
207
|
-
`lunora
|
|
208
|
-
|
|
217
|
+
A second `lunora dev` reports the running instance instead of starting another
|
|
218
|
+
(`.lunora/dev.json` is the lockfile). `GET /_lunora/status` returns
|
|
219
|
+
`{"ok":true}` once the worker is up. Vite defaults to `http://localhost:5173`.
|
|
220
|
+
`lunora dev --tunnel` shares the worker on a public `*.trycloudflare.com` URL
|
|
221
|
+
(needs `cloudflared`).
|
|
209
222
|
|
|
210
|
-
|
|
223
|
+
## Shipping
|
|
211
224
|
|
|
212
225
|
```bash
|
|
213
|
-
lunora doctor
|
|
226
|
+
lunora doctor # preflight: SHARD DO binding, placeholder D1 ids, .dev.vars secrets, container exports
|
|
227
|
+
lunora deploy # codegen + schema-drift gate + wrangler deploy
|
|
214
228
|
```
|
|
215
229
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
- Add
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
- Build your own reusable capability: use the `lunora-create-package` skill.
|
|
228
|
-
- Plan a schema change: use the `lunora-migration-helper` skill.
|
|
229
|
-
- Scaffold more functions: `vis generate lunora-query --name=listMessages`,
|
|
230
|
-
`lunora-mutation`, `lunora-action`, `lunora-table`, `lunora-cron` (always use
|
|
231
|
-
the `--name=value` form).
|
|
232
|
-
|
|
233
|
-
## Checklist
|
|
234
|
-
|
|
235
|
-
- [ ] Determined starting point: new project or existing app.
|
|
236
|
-
- [ ] New project: scaffolded with `lunora init --template <t>`.
|
|
237
|
-
- [ ] Existing app: ran `lunora init --here` and wired `LunoraProvider`.
|
|
238
|
-
- [ ] Ran `lunora codegen`: `lunora/_generated/` exists and typecheck is clean.
|
|
239
|
-
- [ ] `lunora dev` is running — user terminal, or background for cloud agents.
|
|
240
|
-
- [ ] Verified a query/mutation round-trip re-renders the client live.
|
|
230
|
+
Use `lunora-deploy` for bindings, secrets and environments.
|
|
231
|
+
|
|
232
|
+
## Next steps
|
|
233
|
+
|
|
234
|
+
- Auth: `lunora-setup-auth`.
|
|
235
|
+
- Add-ons: `lunora add <feature>` (e.g. `email`, `storage`, `crons`,
|
|
236
|
+
`presence`; `lunora registry list` for all). Mail, storage and scheduling have
|
|
237
|
+
their own skills: `lunora-setup-mail`, `lunora-setup-storage`,
|
|
238
|
+
`lunora-setup-scheduler`.
|
|
239
|
+
- Schema and function rules: `lunora-functions`. Schema changes on live data:
|
|
240
|
+
`lunora-migration-helper`.
|