@lunora/cli 1.0.0-alpha.58 → 1.0.0-alpha.59
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/bin.mjs +1 -1
- package/dist/index.d.mts +36 -10
- package/dist/index.d.ts +36 -10
- package/dist/index.mjs +3 -3
- package/dist/packem_chunks/handler.mjs +2 -2
- package/dist/packem_chunks/handler10.mjs +1 -1
- package/dist/packem_chunks/handler11.mjs +1 -1
- package/dist/packem_chunks/handler12.mjs +1 -1
- package/dist/packem_chunks/handler13.mjs +1 -1
- package/dist/packem_chunks/handler14.mjs +1 -1
- package/dist/packem_chunks/handler15.mjs +2 -2
- package/dist/packem_chunks/handler16.mjs +1 -1
- package/dist/packem_chunks/handler17.mjs +1 -1
- package/dist/packem_chunks/handler18.mjs +1 -1
- package/dist/packem_chunks/handler19.mjs +1 -1
- package/dist/packem_chunks/handler2.mjs +2 -2
- package/dist/packem_chunks/handler20.mjs +3 -3
- package/dist/packem_chunks/handler21.mjs +1 -1
- package/dist/packem_chunks/handler3.mjs +1 -1
- package/dist/packem_chunks/handler4.mjs +1 -1
- package/dist/packem_chunks/handler5.mjs +2 -2
- package/dist/packem_chunks/handler6.mjs +2 -2
- package/dist/packem_chunks/handler7.mjs +1 -1
- package/dist/packem_chunks/handler8.mjs +1 -1
- package/dist/packem_chunks/handler9.mjs +2 -2
- package/dist/packem_chunks/planDevCommand.mjs +497 -28
- package/dist/packem_chunks/runCodegenCommand.mjs +2 -2
- package/dist/packem_chunks/runDeployCommand.mjs +3 -3
- package/dist/packem_chunks/runInitCommand.mjs +3 -3
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +1 -1
- package/dist/packem_chunks/runResetCommand.mjs +1 -1
- package/dist/packem_chunks/runRpcCommand.mjs +1 -1
- package/dist/packem_shared/{COMMANDS-DsWLzOXZ.mjs → COMMANDS-0BD3K1pb.mjs} +20 -1
- package/dist/packem_shared/{command-D3lB_4Az.mjs → command-lYnl4QyF.mjs} +1 -1
- package/dist/packem_shared/{createLogger-B40gPzQo.mjs → createLogger-CIWSHrTL.mjs} +33 -6
- package/dist/packem_shared/{createRecordingSpawner-DxI3mebw.mjs → createRecordingSpawner-Cw5Iu73G.mjs} +12 -2
- package/dist/packem_shared/{output-format-wUvAN6AL.mjs → output-format-B4642rjE.mjs} +1 -1
- package/package.json +2 -2
- package/skills/lunora-quickstart/SKILL.md +25 -5
|
@@ -4,7 +4,7 @@ import { createCerebro } from '@visulima/cerebro';
|
|
|
4
4
|
import completionCommand from '@visulima/cerebro/command/completion';
|
|
5
5
|
import versionCommand from '@visulima/cerebro/command/version';
|
|
6
6
|
import { A as API_SPEC_HELP } from './api-spec-Bx0iKbxA.mjs';
|
|
7
|
-
import { createLogger } from './createLogger-
|
|
7
|
+
import { createLogger } from './createLogger-CIWSHrTL.mjs';
|
|
8
8
|
import { VisulimaError, renderError } from '@visulima/error';
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { join } from 'node:path';
|
|
@@ -215,9 +215,19 @@ const deploymentsCommand = {
|
|
|
215
215
|
};
|
|
216
216
|
|
|
217
217
|
const devCommand = {
|
|
218
|
+
argument: {
|
|
219
|
+
description: "Optional subcommand: stop (shut the running dev server down) | status (report it) | logs (print its captured output)",
|
|
220
|
+
name: "args",
|
|
221
|
+
type: String
|
|
222
|
+
},
|
|
218
223
|
description: "Run the dev stack: wrangler worker + studio + codegen watch",
|
|
219
224
|
examples: [
|
|
220
225
|
["lunora dev", "Run the worker + studio + codegen watch"],
|
|
226
|
+
["lunora dev --background", "Run detached: blocks until ready, prints URL + PID, then returns"],
|
|
227
|
+
["lunora dev stop", "Stop the background/tracked dev server (idempotent)"],
|
|
228
|
+
["lunora dev status", "Report the running dev server (URL, PID, uptime)"],
|
|
229
|
+
["lunora dev logs", "Print the captured dev-server log (background runs)"],
|
|
230
|
+
["lunora dev --json", "Machine-readable JSON log lines (also LUNORA_LOG_JSON=1)"],
|
|
221
231
|
["lunora dev --no-studio", "Skip the embedded studio server"],
|
|
222
232
|
["lunora dev --worker-port 8080", "Use a custom wrangler dev port"],
|
|
223
233
|
["lunora dev --remote", "Proxy D1/KV/R2 to the deployed worker (also LUNORA_REMOTE=1)"]
|
|
@@ -227,10 +237,19 @@ const devCommand = {
|
|
|
227
237
|
return { default: m.execute };
|
|
228
238
|
}),
|
|
229
239
|
name: "dev",
|
|
240
|
+
// KEEP IN SYNC with `daemonArguments` in `./lifecycle.ts`: a new flag that
|
|
241
|
+
// must reach a `--background` daemon has to be forwarded there explicitly.
|
|
230
242
|
options: [
|
|
231
243
|
{ description: `Which API spec(s) codegen emits: ${API_SPEC_HELP} (default openapi)`, name: "api-spec", type: String },
|
|
232
244
|
{ description: "Studio server port (default 6173)", name: "port", type: Number },
|
|
233
245
|
{ description: "wrangler dev port (default 8787)", name: "worker-port", type: Number },
|
|
246
|
+
{
|
|
247
|
+
description: "Run the dev server as a managed background process (auto-enabled when an AI agent is detected; LUNORA_AGENT_MODE=0 disables)",
|
|
248
|
+
name: "background",
|
|
249
|
+
type: Boolean
|
|
250
|
+
},
|
|
251
|
+
{ description: "Emit machine-readable JSON log lines (also LUNORA_LOG_JSON=1; auto-enabled for AI agents)", name: "json", type: Boolean },
|
|
252
|
+
{ description: "How many trailing lines `lunora dev logs` prints (default 100, 0 = all)", name: "lines", type: Number },
|
|
234
253
|
{ description: "Don't start the embedded studio server", name: "no-studio", type: Boolean },
|
|
235
254
|
{ description: "Don't watch + regenerate codegen", name: "no-codegen", type: Boolean },
|
|
236
255
|
{ description: "Proxy D1/KV/R2 bindings to the deployed worker (or set LUNORA_REMOTE=1)", name: "remote", type: Boolean }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createLogger } from './createLogger-
|
|
1
|
+
import { createLogger } from './createLogger-CIWSHrTL.mjs';
|
|
2
2
|
import { P as PromptCancelledError, a as PROMPT_CANCEL_EXIT_CODE } from './prompt-cancelled-APzX1Im-.mjs';
|
|
3
3
|
|
|
4
4
|
const defineHandler = (body) => async (toolbox) => {
|
|
@@ -2,19 +2,46 @@ import { STEP_BADGE_NAMES, LunoraReporter } from '@lunora/config';
|
|
|
2
2
|
import { JsonReporter } from '@visulima/pail/reporter/json';
|
|
3
3
|
import { createPail } from '@visulima/pail/server';
|
|
4
4
|
|
|
5
|
+
let sharedPail;
|
|
6
|
+
let jsonForced = false;
|
|
7
|
+
let configuredReporters;
|
|
5
8
|
const wantJson = () => {
|
|
9
|
+
if (jsonForced) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
6
12
|
const flag = process.env.LUNORA_LOG_JSON;
|
|
7
13
|
return flag === "1" || flag === "true";
|
|
8
14
|
};
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
const constructReporter = (Reporter) => new Reporter();
|
|
16
|
+
const buildReporters = () => {
|
|
17
|
+
if (jsonForced) {
|
|
18
|
+
return [constructReporter(JsonReporter)];
|
|
19
|
+
}
|
|
20
|
+
if (configuredReporters !== void 0 && configuredReporters.length > 0) {
|
|
21
|
+
return configuredReporters;
|
|
22
|
+
}
|
|
23
|
+
return [constructReporter(wantJson() ? JsonReporter : LunoraReporter)];
|
|
24
|
+
};
|
|
25
|
+
const forceJsonLogging = () => {
|
|
26
|
+
if (jsonForced) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
jsonForced = true;
|
|
30
|
+
sharedPail = void 0;
|
|
31
|
+
};
|
|
32
|
+
const logHandlers = {
|
|
33
|
+
compose: (...reporters) => reporters,
|
|
34
|
+
console: () => constructReporter(LunoraReporter),
|
|
35
|
+
json: () => constructReporter(JsonReporter)
|
|
36
|
+
};
|
|
37
|
+
const configureLogHandlers = (reporters) => {
|
|
38
|
+
configuredReporters = Array.isArray(reporters) ? reporters : [reporters];
|
|
39
|
+
sharedPail = void 0;
|
|
12
40
|
};
|
|
13
41
|
const STEP_LOG_TYPES = Object.fromEntries(STEP_BADGE_NAMES.map((name) => [name, { label: name, logLevel: "informational" }]));
|
|
14
|
-
let sharedPail;
|
|
15
42
|
const getPail = () => {
|
|
16
43
|
sharedPail ??= createPail({
|
|
17
|
-
reporters:
|
|
44
|
+
reporters: buildReporters(),
|
|
18
45
|
scope: ["lunora"],
|
|
19
46
|
stderr: process.stderr,
|
|
20
47
|
stdout: process.stdout,
|
|
@@ -75,4 +102,4 @@ const logStep = (type, message) => {
|
|
|
75
102
|
getPail()[type](message);
|
|
76
103
|
};
|
|
77
104
|
|
|
78
|
-
export { createLogger, createStderrLogger, getPail, logStep, pail };
|
|
105
|
+
export { configureLogHandlers, createLogger, createStderrLogger, forceJsonLogging, getPail, logHandlers, logStep, pail };
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
|
|
3
|
+
const NEEDS_CMD_QUOTING = /\s/;
|
|
4
|
+
const spawnShellCompat = (command, args, platform = process.platform) => {
|
|
5
|
+
if (platform !== "win32" || command === process.execPath) {
|
|
6
|
+
return { args: [...args], command, shell: false };
|
|
7
|
+
}
|
|
8
|
+
const quote = (value) => NEEDS_CMD_QUOTING.test(value) ? `"${value}"` : value;
|
|
9
|
+
return { args: args.map((argument) => quote(argument)), command: quote(command), shell: true };
|
|
10
|
+
};
|
|
3
11
|
const defaultSpawner = (descriptor) => new Promise((resolve, reject) => {
|
|
4
12
|
const hasInput = typeof descriptor.input === "string";
|
|
5
13
|
const wantCapture = descriptor.captureStdout === true;
|
|
@@ -9,9 +17,11 @@ const defaultSpawner = (descriptor) => new Promise((resolve, reject) => {
|
|
|
9
17
|
} else if (descriptor.stdoutToStderr) {
|
|
10
18
|
stdout = 2;
|
|
11
19
|
}
|
|
12
|
-
const
|
|
20
|
+
const exec = spawnShellCompat(descriptor.command, descriptor.args);
|
|
21
|
+
const child = spawn(exec.command, exec.args, {
|
|
13
22
|
cwd: descriptor.cwd ?? process.cwd(),
|
|
14
23
|
env: descriptor.env ? { ...process.env, ...descriptor.env } : process.env,
|
|
24
|
+
shell: exec.shell,
|
|
15
25
|
stdio: [hasInput ? "pipe" : "inherit", stdout, "inherit"]
|
|
16
26
|
});
|
|
17
27
|
let captured = "";
|
|
@@ -40,4 +50,4 @@ const createRecordingSpawner = (exitCode = 0) => {
|
|
|
40
50
|
return { calls, spawner };
|
|
41
51
|
};
|
|
42
52
|
|
|
43
|
-
export { createRecordingSpawner, defaultSpawner };
|
|
53
|
+
export { createRecordingSpawner, defaultSpawner, spawnShellCompat };
|
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.59",
|
|
4
4
|
"description": "The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@bomb.sh/tab": "0.0.17",
|
|
55
55
|
"@lunora/codegen": "1.0.0-alpha.29",
|
|
56
|
-
"@lunora/config": "1.0.0-alpha.
|
|
56
|
+
"@lunora/config": "1.0.0-alpha.47",
|
|
57
57
|
"@lunora/container": "1.0.0-alpha.6",
|
|
58
58
|
"@lunora/d1": "1.0.0-alpha.22",
|
|
59
59
|
"@lunora/errors": "1.0.0-alpha.1",
|
|
@@ -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)
|
|
@@ -87,7 +90,23 @@ not exit, so:
|
|
|
87
90
|
|
|
88
91
|
- **Local development (user at the keyboard):** ask the user to run `lunora dev`
|
|
89
92
|
in a terminal.
|
|
90
|
-
- **
|
|
93
|
+
- **Agents:** run `lunora dev --background`. It detaches the server, waits until
|
|
94
|
+
it answers HTTP, prints `Dev server running at <url> (pid <n>)`, and exits —
|
|
95
|
+
no orphaned shell, no PID bookkeeping. When Lunora detects an AI agent
|
|
96
|
+
(Claude Code, Cursor, Codex, …), plain `lunora dev` flips into this mode
|
|
97
|
+
automatically with JSON logs; `LUNORA_AGENT_MODE=0` opts out.
|
|
98
|
+
|
|
99
|
+
Manage the running server afterwards:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
lunora dev status --json # machine-readable: url, pid, uptime, logFile
|
|
103
|
+
lunora dev logs --lines 50 # tail the captured output (.lunora/dev.log)
|
|
104
|
+
lunora dev stop # idempotent — succeeds even if nothing runs
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
A second `lunora dev` never double-starts: it reports the existing instance
|
|
108
|
+
(`.lunora/dev.json` is the lockfile). Probe readiness or liveness at
|
|
109
|
+
`GET /_lunora/status` (`{"ok":true}`).
|
|
91
110
|
|
|
92
111
|
Vite serves on `http://localhost:5173` by default; the Worker is served on the
|
|
93
112
|
same origin via `@cloudflare/vite-plugin`.
|
|
@@ -236,5 +255,6 @@ ids, `.dev.vars` secrets, and container exports.
|
|
|
236
255
|
- [ ] New project: scaffolded with `lunora init --template <t>`.
|
|
237
256
|
- [ ] Existing app: ran `lunora init --here` and wired `LunoraProvider`.
|
|
238
257
|
- [ ] Ran `lunora codegen`: `lunora/_generated/` exists and typecheck is clean.
|
|
239
|
-
- [ ]
|
|
258
|
+
- [ ] Dev server is running — user terminal, or `lunora dev --background`
|
|
259
|
+
(check with `lunora dev status`).
|
|
240
260
|
- [ ] Verified a query/mutation round-trip re-renders the client live.
|