@lunora/cli 1.0.0-alpha.1 → 1.0.0-alpha.100
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 +6 -0
- package/__assets__/package-og.svg +1 -1
- package/dist/bin.mjs +1 -1
- package/dist/index.d.mts +473 -344
- package/dist/index.d.ts +473 -344
- package/dist/index.mjs +10 -11
- package/dist/packem_chunks/handler.mjs +91 -7
- package/dist/packem_chunks/handler10.mjs +8 -14
- package/dist/packem_chunks/handler11.mjs +20 -189
- package/dist/packem_chunks/handler12.mjs +176 -115
- package/dist/packem_chunks/handler13.mjs +118 -52
- package/dist/packem_chunks/handler14.mjs +50 -43
- package/dist/packem_chunks/handler15.mjs +27 -6
- package/dist/packem_chunks/handler16.mjs +6 -3
- package/dist/packem_chunks/handler17.mjs +1 -1
- package/dist/packem_chunks/handler18.mjs +5 -7
- package/dist/packem_chunks/handler19.mjs +44 -5
- package/dist/packem_chunks/handler2.mjs +6 -4
- package/dist/packem_chunks/handler20.mjs +2 -2
- package/dist/packem_chunks/handler21.mjs +158 -267
- package/dist/packem_chunks/handler3.mjs +8 -4
- package/dist/packem_chunks/handler4.mjs +2 -2
- package/dist/packem_chunks/handler5.mjs +7 -4
- package/dist/packem_chunks/handler6.mjs +10 -7
- package/dist/packem_chunks/handler7.mjs +2 -2
- package/dist/packem_chunks/handler8.mjs +1 -1
- package/dist/packem_chunks/handler9.mjs +330 -12
- package/dist/packem_chunks/planDevCommand.mjs +759 -121
- package/dist/packem_chunks/runCodegenCommand.mjs +5 -4
- package/dist/packem_chunks/runDeployCommand.mjs +137 -22
- package/dist/packem_chunks/runInitCommand.mjs +2053 -112
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +98 -51
- package/dist/packem_chunks/runResetCommand.mjs +4 -4
- package/dist/packem_chunks/runRpcCommand.mjs +3 -2
- package/dist/packem_shared/{COMMANDS-1V_KEx35.mjs → COMMANDS-BOJIDoVY.mjs} +154 -28
- package/dist/packem_shared/{DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs → DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs} +7 -2
- package/dist/packem_shared/{api-spec-CtA6ilu4.mjs → api-spec-Bx0iKbxA.mjs} +3 -1
- package/dist/packem_shared/{buildRegistryIndex-BcYe607_.mjs → buildRegistryIndex-BS5ig822.mjs} +1 -1
- package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +31 -0
- package/dist/packem_shared/{command-BDXcJCCJ.mjs → command-lYnl4QyF.mjs} +6 -1
- package/dist/packem_shared/{runAddCommand-BZGkRnBs.mjs → commands-D5Yxt9VY.mjs} +331 -33
- package/dist/packem_shared/{createLogger-CHPNjFw2.mjs → createLogger-CIWSHrTL.mjs} +40 -8
- package/dist/packem_shared/{defaultSpawner-DxI3mebw.mjs → createRecordingSpawner-WuSn20kb.mjs} +23 -2
- package/dist/packem_shared/detect-package-manager-v4hHpQd0.mjs +62 -0
- package/dist/packem_shared/{diffSnapshots-RR2ZE8Ya.mjs → diffSnapshots-BeDvvNiF.mjs} +1 -1
- package/dist/packem_shared/{insertSchemaExtension-BuzF6-t2.mjs → insertSchemaExtension-DAqbfr9Z.mjs} +15 -10
- package/dist/packem_shared/{open-url-Dfq6fAyT.mjs → open-url-4PBLY9X0.mjs} +3 -2
- package/dist/packem_shared/{output-format-7gyGR3h8.mjs → output-format-B4642rjE.mjs} +1 -1
- package/dist/packem_shared/{parseManifest--vZf2FY1.mjs → parseManifest-Dbp-Q2q3.mjs} +36 -9
- package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +9 -0
- package/dist/packem_shared/runAddCommand-D1hgfqFQ.mjs +4 -0
- package/dist/packem_shared/{schemaIrToSnapshot-aBTo7TM5.mjs → schemaIrToSnapshot-DdsljJT-.mjs} +1 -1
- package/dist/packem_shared/storage-BXU4ax4O.mjs +84 -0
- package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +658 -0
- package/dist/packem_shared/wrangler-secrets-Coni-mER.mjs +49 -0
- package/package.json +23 -17
- package/skills/lunora-quickstart/SKILL.md +26 -5
- package/skills/lunora-setup-storage/SKILL.md +7 -3
- package/dist/packem_shared/features-ocSSpZtS.mjs +0 -24
- package/dist/packem_shared/parseArgs-YXFuKdEk.mjs +0 -56
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.100",
|
|
4
4
|
"description": "The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"lunora": "./dist/bin.mjs"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
|
-
"dist",
|
|
33
|
+
"./dist",
|
|
34
34
|
"__assets__",
|
|
35
35
|
"skills",
|
|
36
36
|
"README.md",
|
|
@@ -51,23 +51,29 @@
|
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@bomb.sh/tab": "0.0.
|
|
55
|
-
"@lunora/
|
|
56
|
-
"@lunora/
|
|
57
|
-
"@lunora/
|
|
58
|
-
"@lunora/
|
|
59
|
-
"@lunora/
|
|
60
|
-
"@lunora/
|
|
61
|
-
"@lunora/
|
|
62
|
-
"@lunora/
|
|
63
|
-
"@visulima/cerebro": "3.0.0
|
|
64
|
-
"@visulima/
|
|
65
|
-
"@visulima/
|
|
66
|
-
"@visulima/
|
|
67
|
-
"@visulima/
|
|
54
|
+
"@bomb.sh/tab": "0.0.19",
|
|
55
|
+
"@lunora/bindings": "1.0.0-alpha.11",
|
|
56
|
+
"@lunora/codegen": "1.0.0-alpha.54",
|
|
57
|
+
"@lunora/config": "1.0.0-alpha.80",
|
|
58
|
+
"@lunora/container": "1.0.0-alpha.16",
|
|
59
|
+
"@lunora/d1": "1.0.0-alpha.40",
|
|
60
|
+
"@lunora/errors": "1.0.0-alpha.8",
|
|
61
|
+
"@lunora/runtime": "1.0.0-alpha.37",
|
|
62
|
+
"@lunora/seed": "1.0.0-alpha.30",
|
|
63
|
+
"@visulima/cerebro": "3.0.0",
|
|
64
|
+
"@visulima/error": "6.0.0",
|
|
65
|
+
"@visulima/fs": "5.0.4",
|
|
66
|
+
"@visulima/package": "5.0.4",
|
|
67
|
+
"@visulima/pail": "4.0.0",
|
|
68
|
+
"@visulima/path": "3.0.0",
|
|
69
|
+
"@visulima/spinner": "1.0.0",
|
|
70
|
+
"@visulima/tui": "1.0.4",
|
|
71
|
+
"cfonts": "^3.3.1",
|
|
68
72
|
"giget": "3.3.0",
|
|
69
73
|
"jsonc-parser": "^3.3.1",
|
|
70
|
-
"magic-string": "^0.
|
|
74
|
+
"magic-string": "^1.0.0",
|
|
75
|
+
"react": "^19.2.7",
|
|
76
|
+
"react-reconciler": "^0.33.0",
|
|
71
77
|
"ts-morph": "^28.0.0"
|
|
72
78
|
},
|
|
73
79
|
"engines": {
|
|
@@ -31,9 +31,12 @@ Set up a working Lunora project as fast as possible.
|
|
|
31
31
|
Lunora into the current project.
|
|
32
32
|
4. Run `lunora codegen` to generate `lunora/_generated/` and typecheck the
|
|
33
33
|
schema + functions. This is the agent's feedback loop.
|
|
34
|
-
5. Start the dev loop
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
5. Start the dev loop. As an agent, run `lunora dev --background` — it starts
|
|
35
|
+
the server as a managed detached process, blocks until it accepts requests,
|
|
36
|
+
prints the URL + PID, and returns (under a detected AI agent, plain
|
|
37
|
+
`lunora dev` does this automatically, with JSON logs). Never leave a bare
|
|
38
|
+
`lunora dev` running in your own shell — it is long-running and does not
|
|
39
|
+
exit.
|
|
37
40
|
6. Verify a query/mutation round-trip works end to end.
|
|
38
41
|
|
|
39
42
|
## Path 1: New Project (Recommended)
|
|
@@ -54,6 +57,7 @@ pnpm install
|
|
|
54
57
|
| `vite` | React + Vite (the simplest full-stack starter) |
|
|
55
58
|
| `standalone` | Worker-only Lunora backend, no frontend |
|
|
56
59
|
| `astro` | Astro integration |
|
|
60
|
+
| `next` | Next.js (App Router, OpenNext on Cloudflare) |
|
|
57
61
|
| `nuxt` | Nuxt (Vue) |
|
|
58
62
|
| `sveltekit` | SvelteKit |
|
|
59
63
|
| `tanstack-start-react` | TanStack Start (React) |
|
|
@@ -87,7 +91,23 @@ not exit, so:
|
|
|
87
91
|
|
|
88
92
|
- **Local development (user at the keyboard):** ask the user to run `lunora dev`
|
|
89
93
|
in a terminal.
|
|
90
|
-
- **
|
|
94
|
+
- **Agents:** run `lunora dev --background`. It detaches the server, waits until
|
|
95
|
+
it answers HTTP, prints `Dev server running at <url> (pid <n>)`, and exits —
|
|
96
|
+
no orphaned shell, no PID bookkeeping. When Lunora detects an AI agent
|
|
97
|
+
(Claude Code, Cursor, Codex, …), plain `lunora dev` flips into this mode
|
|
98
|
+
automatically with JSON logs; `LUNORA_AGENT_MODE=0` opts out.
|
|
99
|
+
|
|
100
|
+
Manage the running server afterwards:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
lunora dev status --json # machine-readable: url, pid, uptime, logFile
|
|
104
|
+
lunora dev logs --lines 50 # tail the captured output (.lunora/dev.log)
|
|
105
|
+
lunora dev stop # idempotent — succeeds even if nothing runs
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A second `lunora dev` never double-starts: it reports the existing instance
|
|
109
|
+
(`.lunora/dev.json` is the lockfile). Probe readiness or liveness at
|
|
110
|
+
`GET /_lunora/status` (`{"ok":true}`).
|
|
91
111
|
|
|
92
112
|
Vite serves on `http://localhost:5173` by default; the Worker is served on the
|
|
93
113
|
same origin via `@cloudflare/vite-plugin`.
|
|
@@ -236,5 +256,6 @@ ids, `.dev.vars` secrets, and container exports.
|
|
|
236
256
|
- [ ] New project: scaffolded with `lunora init --template <t>`.
|
|
237
257
|
- [ ] Existing app: ran `lunora init --here` and wired `LunoraProvider`.
|
|
238
258
|
- [ ] Ran `lunora codegen`: `lunora/_generated/` exists and typecheck is clean.
|
|
239
|
-
- [ ]
|
|
259
|
+
- [ ] Dev server is running — user terminal, or `lunora dev --background`
|
|
260
|
+
(check with `lunora dev status`).
|
|
240
261
|
- [ ] Verified a query/mutation round-trip re-renders the client live.
|
|
@@ -41,7 +41,7 @@ This:
|
|
|
41
41
|
1. Adds `@lunora/storage` and `@lunora/server` to `package.json` (run
|
|
42
42
|
`pnpm install` afterwards).
|
|
43
43
|
2. Adds an R2 bucket binding to `wrangler.jsonc` (`r2_buckets`, binding
|
|
44
|
-
**`UPLOADS`**, `bucket_name: "
|
|
44
|
+
**`UPLOADS`**, `bucket_name: "replace-me-uploads"` — rename it to a real
|
|
45
45
|
bucket). It **merges** into any existing `r2_buckets`.
|
|
46
46
|
3. Scaffolds `STORAGE_SIGNING_SECRET` (a secret) and `STORAGE_PUBLIC_BASE_URL`
|
|
47
47
|
into `.dev.vars`.
|
|
@@ -137,8 +137,12 @@ persist that, and pass the bare key back in — the component re-scopes it.
|
|
|
137
137
|
|
|
138
138
|
1. **Skipping `verifySignedUrl` on the download route.** Without it, anyone can
|
|
139
139
|
read any key. Always verify before streaming.
|
|
140
|
-
2. **Placeholder bucket name.** `
|
|
141
|
-
|
|
140
|
+
2. **Placeholder bucket name.** `lunora init` and `lunora add storage` prompt for
|
|
141
|
+
the bucket name (or take `--bucket <name>`), but the low-level
|
|
142
|
+
`lunora registry add storage` writes the placeholder
|
|
143
|
+
`bucket_name: "replace-me-uploads"` — rename it to a real R2 bucket. (R2 names
|
|
144
|
+
are lowercase alphanumeric + hyphens, 3–63 chars; wrangler rejects anything
|
|
145
|
+
else on `dev`/`deploy`.)
|
|
142
146
|
3. **Short / shared signing secret.** Use ≥32 chars and a distinct secret per
|
|
143
147
|
bucket; reusing it lets one bucket's URLs sign for another.
|
|
144
148
|
4. **Proxying bytes through the Worker.** The design uploads/downloads directly
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const AUTH_PROVIDER_OPTIONS = [
|
|
2
|
-
{ description: "Email + password on better-auth (default)", label: "Email & password", value: "auth" },
|
|
3
|
-
{ description: "Clerk-hosted auth", label: "Clerk", value: "auth-clerk" },
|
|
4
|
-
{ description: "Auth0 (OIDC)", label: "Auth0", value: "auth-auth0" }
|
|
5
|
-
];
|
|
6
|
-
const DEFAULT_AUTH_ITEM = "auth";
|
|
7
|
-
const promptAuthProvider = async (select) => await select("Which auth provider?", AUTH_PROVIDER_OPTIONS, { default: DEFAULT_AUTH_ITEM }) ?? DEFAULT_AUTH_ITEM;
|
|
8
|
-
const EMAIL_ITEM = "mail";
|
|
9
|
-
const normalizeFeature = (raw) => {
|
|
10
|
-
const value = raw.trim();
|
|
11
|
-
if (value === "") {
|
|
12
|
-
return void 0;
|
|
13
|
-
}
|
|
14
|
-
const lower = value.toLowerCase();
|
|
15
|
-
if (lower === "auth") {
|
|
16
|
-
return { kind: "auth" };
|
|
17
|
-
}
|
|
18
|
-
if (lower === "email" || lower === "mail") {
|
|
19
|
-
return { kind: "email" };
|
|
20
|
-
}
|
|
21
|
-
return { item: lower, kind: "item" };
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export { AUTH_PROVIDER_OPTIONS as A, DEFAULT_AUTH_ITEM as D, EMAIL_ITEM as E, normalizeFeature as n, promptAuthProvider as p };
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
const consumeLongOption = (body, next, booleanFlags, accumulator) => {
|
|
2
|
-
const eqIndex = body.indexOf("=");
|
|
3
|
-
if (eqIndex !== -1) {
|
|
4
|
-
accumulator.options[body.slice(0, eqIndex)] = body.slice(eqIndex + 1);
|
|
5
|
-
return 1;
|
|
6
|
-
}
|
|
7
|
-
if (booleanFlags.has(body)) {
|
|
8
|
-
accumulator.flags[body] = true;
|
|
9
|
-
return 1;
|
|
10
|
-
}
|
|
11
|
-
if (next !== void 0 && !next.startsWith("-")) {
|
|
12
|
-
accumulator.options[body] = next;
|
|
13
|
-
return 2;
|
|
14
|
-
}
|
|
15
|
-
accumulator.flags[body] = true;
|
|
16
|
-
return 1;
|
|
17
|
-
};
|
|
18
|
-
const consumeShortOption = (body, next, accumulator) => {
|
|
19
|
-
if (body.length > 1) {
|
|
20
|
-
accumulator.options[body[0]] = body.slice(1);
|
|
21
|
-
return 1;
|
|
22
|
-
}
|
|
23
|
-
if (next !== void 0 && !next.startsWith("-")) {
|
|
24
|
-
accumulator.options[body] = next;
|
|
25
|
-
return 2;
|
|
26
|
-
}
|
|
27
|
-
accumulator.flags[body] = true;
|
|
28
|
-
return 1;
|
|
29
|
-
};
|
|
30
|
-
const parseArgs = (argv, booleanFlags = /* @__PURE__ */ new Set()) => {
|
|
31
|
-
const accumulator = { flags: {}, options: {}, positional: [] };
|
|
32
|
-
let index = 0;
|
|
33
|
-
let terminated = false;
|
|
34
|
-
while (index < argv.length) {
|
|
35
|
-
const token = argv[index];
|
|
36
|
-
if (token === void 0) {
|
|
37
|
-
index += 1;
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
if (terminated || !token.startsWith("-") || token.length === 1) {
|
|
41
|
-
accumulator.positional.push(token);
|
|
42
|
-
index += 1;
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
if (token === "--") {
|
|
46
|
-
terminated = true;
|
|
47
|
-
index += 1;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
const next = argv[index + 1];
|
|
51
|
-
index += token.startsWith("--") ? consumeLongOption(token.slice(2), next, booleanFlags, accumulator) : consumeShortOption(token.slice(1), next, accumulator);
|
|
52
|
-
}
|
|
53
|
-
return { flags: accumulator.flags, options: accumulator.options, positional: accumulator.positional };
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export { parseArgs as default };
|