@lizard-build/cli 4.0.44 → 4.0.45
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/AGENTS.md +3 -0
- package/dist/commands/skill.js +89 -16
- package/dist/commands/skill.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/skills-data.generated.d.ts +2 -0
- package/dist/lib/skills-data.generated.js +6 -1
- package/dist/lib/skills-data.generated.js.map +1 -1
- package/dist/lib/updater.d.ts +1 -1
- package/dist/lib/updater.js +1 -1
- package/package.json +1 -1
- package/scripts/gen-skills.mjs +24 -5
- package/skill-data/core/SKILL.md +51 -327
- package/skill-data/core/references/deploys.md +190 -0
- package/skill-data/core/references/sandboxes.md +144 -0
- package/skill-data/core/references/sdk.md +215 -0
- package/src/commands/skill.ts +95 -21
- package/src/index.ts +4 -1
- package/src/lib/updater.ts +1 -1
- package/test/unit/skills.test.ts +31 -12
package/dist/lib/updater.d.ts
CHANGED
package/dist/lib/updater.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Readable } from "node:stream";
|
|
|
4
4
|
import { join, dirname } from "node:path";
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
|
-
export const CURRENT_VERSION = "4.0.
|
|
7
|
+
export const CURRENT_VERSION = "4.0.45";
|
|
8
8
|
const RELEASES_API = "https://api.github.com/repos/lizard-build/lizard-cli/releases/latest";
|
|
9
9
|
const RELEASE_BASE = "https://github.com/lizard-build/lizard-cli/releases/latest/download";
|
|
10
10
|
/** Minimum gap between background update checks. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lizard-build/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.45",
|
|
4
4
|
"description": "Lizard CLI — deploy apps, databases and sandboxes to Lizard (lizard.build) from your terminal or your coding agent. Detects Go, Node, Python, Rust, Ruby, PHP, Java and static sites; adds Managed Postgres, Managed Redis and Managed Object Storage in one command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/scripts/gen-skills.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Codegen step: inlines
|
|
3
|
-
// TypeScript module so the CLI can ship skills inside a Bun --compile binary,
|
|
2
|
+
// Codegen step: inlines skill-data/<name>/SKILL.md and its references/*.md
|
|
3
|
+
// into a TypeScript module so the CLI can ship skills inside a Bun --compile binary,
|
|
4
4
|
// where fs paths to skill-data/ don't exist.
|
|
5
5
|
//
|
|
6
6
|
// Output: src/lib/skills-data.generated.ts (gitignored)
|
|
@@ -33,7 +33,18 @@ try {
|
|
|
33
33
|
const entries = names.map((name) => {
|
|
34
34
|
const file = path.join(srcDir, name, "SKILL.md");
|
|
35
35
|
const content = readFileSync(file, "utf8");
|
|
36
|
-
|
|
36
|
+
const refDir = path.join(srcDir, name, "references");
|
|
37
|
+
let refs = [];
|
|
38
|
+
try {
|
|
39
|
+
refs = readdirSync(refDir).filter((f) => f.endsWith(".md")).sort();
|
|
40
|
+
} catch {
|
|
41
|
+
// no references/ directory
|
|
42
|
+
}
|
|
43
|
+
const references = refs.map((f) => ({
|
|
44
|
+
name: f.slice(0, -3),
|
|
45
|
+
content: readFileSync(path.join(refDir, f), "utf8"),
|
|
46
|
+
}));
|
|
47
|
+
return { name, content, references };
|
|
37
48
|
});
|
|
38
49
|
|
|
39
50
|
let out = "// AUTO-GENERATED by scripts/gen-skills.mjs — do not edit.\n";
|
|
@@ -41,18 +52,26 @@ out += "// Run `npm run gen:skills` to regenerate.\n\n";
|
|
|
41
52
|
out += "export interface EmbeddedSkill {\n";
|
|
42
53
|
out += " name: string;\n";
|
|
43
54
|
out += " content: string;\n";
|
|
55
|
+
out += " /** references/<name>.md, keyed by <name> */\n";
|
|
56
|
+
out += " references: Record<string, string>;\n";
|
|
44
57
|
out += "}\n\n";
|
|
45
58
|
out += "export const EMBEDDED_SKILLS: Record<string, EmbeddedSkill> = {\n";
|
|
46
|
-
for (const { name, content } of entries) {
|
|
59
|
+
for (const { name, content, references } of entries) {
|
|
47
60
|
out += ` ${JSON.stringify(name)}: {\n`;
|
|
48
61
|
out += ` name: ${JSON.stringify(name)},\n`;
|
|
49
62
|
out += ` content: ${JSON.stringify(content)},\n`;
|
|
63
|
+
out += " references: {\n";
|
|
64
|
+
for (const ref of references) {
|
|
65
|
+
out += ` ${JSON.stringify(ref.name)}: ${JSON.stringify(ref.content)},\n`;
|
|
66
|
+
}
|
|
67
|
+
out += " },\n";
|
|
50
68
|
out += " },\n";
|
|
51
69
|
}
|
|
52
70
|
out += "};\n";
|
|
53
71
|
|
|
54
72
|
mkdirSync(path.dirname(outFile), { recursive: true });
|
|
55
73
|
writeFileSync(outFile, out);
|
|
74
|
+
const refCount = entries.reduce((n, e) => n + e.references.length, 0);
|
|
56
75
|
console.log(
|
|
57
|
-
`gen:skills wrote ${entries.length} skill(s) to ${path.relative(root, outFile)}`,
|
|
76
|
+
`gen:skills wrote ${entries.length} skill(s), ${refCount} reference(s) to ${path.relative(root, outFile)}`,
|
|
58
77
|
);
|
package/skill-data/core/SKILL.md
CHANGED
|
@@ -9,19 +9,13 @@ allowed-tools: Bash(lizard:*), Bash(~/.lizard/bin/lizard:*), Bash(which:*), Bash
|
|
|
9
9
|
|
|
10
10
|
Lizard runs sandboxes and hosts apps, services, agents and managed databases. All capabilities are exposed through the `lizard` CLI (npm package `@lizard-build/cli`). This skill teaches you to drive it. If `lizard` isn't on PATH, install it: `curl -fsSL https://lizard.build/install.sh | bash` on macOS and Linux (no Node.js or sudo needed; if `lizard` is still not found, call `~/.lizard/bin/lizard`), `irm https://lizard.build/api/cli/install.ps1 | iex` in Windows PowerShell, or `npm install -g @lizard-build/cli` anywhere. The install script ends by running `lizard login`, so its output may already hold the sign-in links: see [Sign-in](#sign-in).
|
|
11
11
|
|
|
12
|
-
This guide covers
|
|
12
|
+
This guide covers the whole platform. Three references go deeper; read one only when the task needs that depth:
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
This skill documents platform behavior (build pipeline, env precedence, what knobs the API exposes). It does not describe the user's repo.
|
|
19
|
-
|
|
20
|
-
Before writing commands for a specific project:
|
|
14
|
+
- `lizard skills get core --ref sandboxes --json`: templates, commands, files and ports in depth, lifetime, sizes, shell, coding agents in a sandbox, desktop (computer use), volumes, snapshots and pause/resume.
|
|
15
|
+
- `lizard skills get core --ref deploys --json`: how builds are chosen, git and upload deploys, service fields, worker mode, secret precedence and scoping, addon variables, multi-step recipes.
|
|
16
|
+
- `lizard skills get core --ref sdk --json`: building with Lizard from code through Lizard SDK (TypeScript, Python): sandboxes inside your own product, per-user workspaces and scoped keys, platform APIs.
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
2. Don't assume scripts/conventions that aren't visible. On the lizardpack auto-detect path, `Procfile` (`web:` line, Python/Ruby) and `package.json scripts.start` (Node) ARE picked up as the start command; on the synthesized-Dockerfile path (`buildCommand`/`startCommand` set) neither is read. Ports are inferred only from `EXPOSE`, framework defaults, or an explicit `PORT` env.
|
|
24
|
-
3. When in doubt, ask the user or run `lizard <cmd> --help --json`.
|
|
18
|
+
If `$ARGUMENTS` is non-empty, treat it as the user's request and act on it. If empty, ask what they want to do on Lizard.
|
|
25
19
|
|
|
26
20
|
## Execution rules
|
|
27
21
|
|
|
@@ -38,13 +32,15 @@ For streaming commands (`lizard up` without `--detach`), `--json` produces one J
|
|
|
38
32
|
## Mental model
|
|
39
33
|
|
|
40
34
|
```
|
|
41
|
-
workspace → project →
|
|
35
|
+
workspace → project → services, sandboxes, managed addons, volumes
|
|
42
36
|
```
|
|
43
37
|
|
|
44
38
|
- Workspace — account/org level. User belongs to one or more.
|
|
45
39
|
- Project — group of related services and sandboxes in one workspace. The cwd gets linked to a project (config at `~/.lizard/config.json`).
|
|
46
40
|
- Service — a deployable unit. Source is either a git repo (`sourceType=github`) or an uploaded tarball (`sourceType=upload`).
|
|
47
|
-
-
|
|
41
|
+
- Sandbox — a short-lived Linux machine (Firecracker microVM) for running code and agents. See [Sandboxes](#sandboxes).
|
|
42
|
+
- Volume — persistent disk for sandboxes, mounted at `/workspace`.
|
|
43
|
+
- Managed addons — `postgres`, `redis`, `s3`. Provisioned with `lizard add <type>`; `s3` ships with a private bucket named `default`. See [Databases and storage](#databases-and-storage) for the env vars each type exposes.
|
|
48
44
|
- Cross-resource refs — `${{<name>.<KEY>}}` resolves at deploy time against the target's merged env. A ref to a missing target or key resolves to an empty string and does NOT fail the deploy (only circular refs throw). After wiring refs, deploy and check `lizard logs --build --service <svc>`: the build log warns about every reference that came back empty. `lizard secrets list --service <svc> --show` shows what is stored. Refs match the target's current name, so renaming the target breaks them: update them after a rename.
|
|
49
45
|
|
|
50
46
|
## Discovery
|
|
@@ -89,12 +85,8 @@ A command that works on a project takes it from `--project`, then from the folde
|
|
|
89
85
|
|
|
90
86
|
A sandbox is a Linux machine for running code and agents: a Firecracker microVM with its own kernel. It lives 5 minutes by default and is then deleted with its files.
|
|
91
87
|
|
|
92
|
-
### Sandbox or deploy?
|
|
93
|
-
|
|
94
88
|
- **Sandbox:** run code, tests, a build or an agent on demand, for minutes or hours, then delete it or snapshot it. The place for untrusted or AI-generated code.
|
|
95
|
-
- **Deploy** (`lizard up`): a service that keeps running and serves traffic at a stable URL, with managed databases next to it. See [
|
|
96
|
-
|
|
97
|
-
### Quickstart
|
|
89
|
+
- **Deploy** (`lizard up`): a service that keeps running and serves traffic at a stable URL, with managed databases next to it. See [Deploys](#deploys).
|
|
98
90
|
|
|
99
91
|
```
|
|
100
92
|
lizard sandbox create --json # base template, medium size, 5-minute lifetime; the JSON has the id
|
|
@@ -108,174 +100,16 @@ lizard sandbox rm <id> -y # delete it now
|
|
|
108
100
|
|
|
109
101
|
`lizard sandbox list --json` shows the project's sandboxes; `--all` shows every one you have.
|
|
110
102
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
| `codex` | Coding agents: see [Coding agents](#coding-agents) |
|
|
118
|
-
| `desktop` | A graphical desktop with Chromium: see [Desktop](#desktop-computer-use) |
|
|
119
|
-
|
|
120
|
-
The platform validates the name; `lizard sandbox create --help --json` lists the templates this CLI knows.
|
|
121
|
-
|
|
122
|
-
### Running commands
|
|
123
|
-
|
|
124
|
-
`lizard sandbox exec <id> -- <cmd> [args...]` runs the command through `sh -c` in the sandbox, streams stdout and stderr, and exits with the command's exit code. In JSON mode it prints the raw output without the `$ <cmd>` header. Each call is a new process, so `cd` and exported variables don't carry over: chain steps in one call, e.g. `lizard sandbox exec <id> -- sh -c 'cd /workspace && npm test'`, and keep results in files.
|
|
125
|
-
|
|
126
|
-
### Files
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
lizard sandbox files ls <id> [path] # default /
|
|
130
|
-
lizard sandbox files cat <id> <path>
|
|
131
|
-
lizard sandbox files put <id> <local> <remote>
|
|
132
|
-
lizard sandbox files get <id> <remote> <local>
|
|
133
|
-
lizard sandbox files rm <id> <path>
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
`/workspace` is the working directory: `ssh` starts there and volumes mount there. `files put` and `files get` keep binary files intact.
|
|
137
|
-
|
|
138
|
-
### Ports
|
|
139
|
-
|
|
140
|
-
`lizard sandbox expose <id> <port>` publishes a port inside the sandbox on an HTTPS URL; `lizard sandbox unexpose <id> <port>` removes it. The URL carries the sandbox's access token, so treat it like a password. The platform keeps one port for itself and refuses to expose it.
|
|
141
|
-
|
|
142
|
-
### Lifetime
|
|
143
|
-
|
|
144
|
-
`lizard sandbox create` sends a five-minute lifetime (`300000` milliseconds) by default. Pass `--timeout 0` to create a sandbox without expiration, or pass an integer up to `2147483647` milliseconds. This is a lifetime, not an idle timer: commands do not reset it. `lizard sandbox timeout <id> <ms>` sets a new lifetime of at least `1000` milliseconds. Pausing a sandbox freezes its remaining lifetime; resuming continues from it (see [private snapshots and pause/resume](#snapshots-and-pauseresume)). The CLI has no sandbox fork command. Use volumes for persistent files.
|
|
145
|
-
|
|
146
|
-
### Size and pricing
|
|
147
|
-
|
|
148
|
-
`lizard sandbox create -s/--size small|medium|large` picks the machine; the default is `medium`. There are exactly three sizes:
|
|
149
|
-
|
|
150
|
-
| Size | vCPU | RAM | Disk | Price |
|
|
151
|
-
|---|---|---|---|---|
|
|
152
|
-
| `small` | 2 | 4 GiB | 5 GB | $0.0162/h |
|
|
153
|
-
| `medium` (default) | 4 | 8 GiB | 20 GB | $0.0324/h |
|
|
154
|
-
| `large` | 8 | 16 GiB | 50 GB | $0.0648/h |
|
|
155
|
-
|
|
156
|
-
Prices are per hour, billed per second while the sandbox runs, flat by size: measured CPU/RAM is not charged, disk is included, and egress is included up to 2 TB per account over a rolling 30 days (past that, the account's sandboxes lose outbound network until the total drops). A paused sandbox costs nothing. Attached volumes bill separately. `--size` cannot be combined with `--snapshot`: a snapshot restores at the size it was captured at (see [private snapshots](#snapshots-and-pauseresume)).
|
|
157
|
-
|
|
158
|
-
Sandboxes run as Firecracker microVMs, each with its own kernel. A sandbox that attaches an existing pod-backed volume, or restores an older pod snapshot, runs as a Kubernetes pod instead.
|
|
159
|
-
|
|
160
|
-
### Interactive shell
|
|
161
|
-
|
|
162
|
-
`lizard sandbox ssh <id>` (alias `shell`) opens an interactive shell in any running sandbox,
|
|
163
|
-
in `/workspace` as root. It uses your Lizard login, so there are no SSH keys to set up; a
|
|
164
|
-
scoped API key only reaches sandboxes in its scope. It needs a real terminal — from a script
|
|
165
|
-
or an agent, use `lizard sandbox exec <id> -- <cmd>` instead, which returns output and an
|
|
166
|
-
exit code.
|
|
167
|
-
|
|
168
|
-
### Coding agents
|
|
169
|
-
|
|
170
|
-
Run a coding agent inside a sandbox (use `-t codex`) on the user's own credentials:
|
|
171
|
-
|
|
172
|
-
- `lizard agents` — your account's credentials and which agents can run. Connect once (here or in the
|
|
173
|
-
dashboard: Account settings › Agents); every sandbox and every agent that accepts it uses it.
|
|
174
|
-
- `lizard agents login chatgpt` — ChatGPT subscription via device code.
|
|
175
|
-
`lizard agents add claude` (token from `claude setup-token`), `add anthropic|openai|openrouter|llmgateway|deepseek` for API keys.
|
|
176
|
-
- `lizard agents use <agent> --credential … --model … --effort …` — per-agent defaults.
|
|
177
|
-
- `lizard sandbox prompt <id> --agent codex|claude|pi|opencode|prime "task"` — streams tool calls and
|
|
178
|
-
the answer; `-c <conversation>` continues one; `--no-wait` returns at once.
|
|
179
|
-
- `lizard sandbox conversations <id>`, `lizard sandbox interrupt <id> [-c <conversation>]`.
|
|
180
|
-
|
|
181
|
-
Codex and Claude Code use one credential at a time; pi, OpenCode and Prime use every connected one
|
|
182
|
-
they accept. Sandboxes never receive a subscription's refresh token, only a short-lived access token.
|
|
183
|
-
|
|
184
|
-
Use `sandbox exec` to read a log file written by your process.
|
|
185
|
-
|
|
186
|
-
### Desktop (computer use)
|
|
187
|
-
|
|
188
|
-
The `desktop` template is a sandbox with a graphical desktop (Openbox + Chromium) streamed to a browser over WebRTC (H.264), falling back to noVNC where WebRTC cannot connect. The viewer's side panel has fullscreen with keyboard lock, send-keys, type-clipboard and a switch to VNC.
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
lizard sandbox create -t desktop # only this template has a desktop
|
|
192
|
-
lizard sandbox desktop <id> --open # start it (idempotent) and open it in the browser
|
|
193
|
-
lizard sandbox desktop <id> --resolution 1920x1080 # 640-3840 x 480-2160
|
|
194
|
-
lizard sandbox desktop <id> --view-only # watch-only link
|
|
195
|
-
lizard sandbox desktop <id> --status # URLs/state without starting
|
|
196
|
-
lizard sandbox desktop <id> --stop # stop and unpublish
|
|
197
|
-
lizard sandbox vnc <id> # native VNC app: tunnels localhost:5900 to the desktop
|
|
198
|
-
lizard sandbox vnc <id> --open # macOS: opens Screen Sharing; --view-only, --port N
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
The printed URLs embed secrets (the desktop's token and its password): the main URL grants control of the sandbox, so treat it like a password and don't paste it into logs, issues or chat; share `--view-only` for watching. On any other template the command fails with `DESKTOP_NOT_SUPPORTED`.
|
|
202
|
-
|
|
203
|
-
Agents drive the desktop from inside the sandbox once it is started (`DISPLAY=:1` is preset in the image):
|
|
204
|
-
|
|
205
|
-
```
|
|
206
|
-
lizard sandbox exec <id> -- xdotool mousemove 400 300 click 1
|
|
207
|
-
lizard sandbox exec <id> -- xdotool type 'hello'
|
|
208
|
-
lizard sandbox exec <id> -- lizard-desktop screenshot | grep -E '^[A-Za-z0-9+/=]+$' | base64 -d > screen.png
|
|
209
|
-
lizard sandbox exec <id> -- lizard-desktop screenshot --path # writes the PNG to a file in the sandbox, prints its path
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
`lizard-desktop screenshot` prints the PNG as base64 wrapped at 76 columns; the `grep` keeps only those lines (it drops the `$ <cmd>` header `sandbox exec` prints). Use `--path` to save the PNG, then download that path with `lizard sandbox files get <id> <remote-path> screen.png`. `files put` and `files get` preserve binary files.
|
|
213
|
-
|
|
214
|
-
### Volumes
|
|
215
|
-
|
|
216
|
-
Use `lizard volume create <name> --size <gb> --project <project>` for persistent sandbox storage. Names are unique within a project; use lowercase letters, digits and dashes (up to 64 characters). Pass the name to `lizard sandbox create --volume <name>`. New volumes default to 5 GB and allow 1–50 GB. The CLI reads the server's current size limits before creating a volume; a server config override may change the maximum. Existing larger volumes keep their size. Storage charges cover used bytes, not the whole allocation.
|
|
217
|
-
|
|
218
|
-
Persistent volumes for sandboxes. A volume's name is its key within the project; every command takes a name or ID.
|
|
219
|
-
|
|
220
|
-
```
|
|
221
|
-
lizard volume create <name> [--size <gb>] [--region <code>] # default 5 GB; region must match the sandbox's
|
|
222
|
-
lizard volume list --json # name, sizeGb, status, attachedTo
|
|
223
|
-
lizard volume resize <name> --size <gb> # grow in place
|
|
224
|
-
lizard volume rm <name> [-y] # refused while attached; delete the sandbox first
|
|
225
|
-
lizard sandbox create --volume <name> # attach at create time
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
`volume resize` is online: an attached sandbox keeps running, and its `/workspace` shows the new size right away. A volume grown while detached gets the new size when a sandbox next mounts it. Firecracker volumes (the default) only grow; asking for less fails with `volume_shrink_unsupported`. A Kubernetes volume can also shrink if at least 10% of the new size stays free (`volume_too_full_to_shrink` otherwise). The size limit (`volume_too_large`) and the workspace's volume quota apply as at create. `The volume is not ready` (HTTP 409) right after create means retry in a few seconds.
|
|
229
|
-
|
|
230
|
-
### Snapshots and pause/resume
|
|
231
|
-
|
|
232
|
-
- `lizard sandbox snapshot <sandbox-id> --name my-app` saves files and running memory privately. The snapshot is yours: by default it restores into any of your projects and workspaces; `--scope workspace` keeps it to the sandbox's workspace and `--scope project` to its project, and `sandbox snapshot-scope <id> <user|workspace|project>` changes that later. A Firecracker snapshot is ready as soon as the capture ends. A snapshot of a pod sandbox keeps **five** independent copies warm; `--warm 1..10` changes that count. It waits until ready; `--no-wait` returns the queued capture.
|
|
233
|
-
- `lizard sandbox restore <snapshot-id> [--project <project>]` starts a new sandbox from a warm copy, in the snapshot's project unless `--project` names another. `--volume <volume>` mounts a volume at `/workspace` in the restored sandbox (Firecracker snapshots of a sandbox that had no volume attached; the volume must be in the snapshot's region). `sandbox create --snapshot <id> --project <project> [--volume <volume>]` also works. Restores stay in the snapshot's region. A Firecracker snapshot restores at its source's size and bills flat at that size; a pod snapshot runs on the machine it was captured on and bills by measured usage. `--size` with `--snapshot` is an error.
|
|
234
|
-
- `lizard sandbox snapshots --project <project>` lists a project's snapshots; `--mine` lists every snapshot you took. `sandbox snapshot-warm <id> <count>` changes capacity. `sandbox snapshot-rm <id>` deletes the snapshot and free copies, preserving already running sandboxes.
|
|
235
|
-
- `lizard sandbox pause <id>` snapshots and stops a Firecracker VM (a pod sandbox is checkpointed with CRIU), stops billing, and freezes its remaining lifetime. `sandbox resume <id>` restores the same sandbox ID, files, processes, memory, published ports, and remaining lifetime. Paused sandboxes keep no warm copies; resume includes a cold restore. Both support `--no-wait`.
|
|
236
|
-
- Disconnect clients and terminals and stop workspace writes before capturing or pausing. On a pod sandbox, active TCP connections and unsupported CRIU process state cause a clear failure. To reuse one snapshot across sandboxes that each keep their own data, snapshot a sandbox with no volume attached and pass `--volume` on each restore; a snapshot taken with a volume attached cannot take a different one.
|
|
237
|
-
|
|
238
|
-
### From code: Lizard SDK
|
|
239
|
-
|
|
240
|
-
For an app or script that creates sandboxes itself, use Lizard SDK instead of calling the CLI:
|
|
241
|
-
|
|
242
|
-
| SDK | Install | Requires |
|
|
243
|
-
|---|---|---|
|
|
244
|
-
| TypeScript | `npm install @lizard-build/sdk` | Node.js 18+ |
|
|
245
|
-
| Python | `pip install lizard-sdk` | Python 3.10+ |
|
|
246
|
-
|
|
247
|
-
The SDK reads `LIZARD_API_KEY`. Create one with `lizard keys create <name> --project <project> --json`: a key limited to one project is safest when the code runs somewhere else.
|
|
248
|
-
|
|
249
|
-
```ts
|
|
250
|
-
import { Lizard } from '@lizard-build/sdk'
|
|
251
|
-
|
|
252
|
-
const lizard = new Lizard({ project: 'my-project' })
|
|
253
|
-
const sandbox = await lizard.create('base', { timeoutMs: 300_000 })
|
|
254
|
-
try {
|
|
255
|
-
await sandbox.fs.write('/tmp/hello.txt', 'Hello from Lizard!')
|
|
256
|
-
const result = await sandbox.process.exec('cat /tmp/hello.txt')
|
|
257
|
-
if (result.exitCode !== 0) throw new Error(result.stderr)
|
|
258
|
-
console.log(result.stdout)
|
|
259
|
-
} finally {
|
|
260
|
-
await sandbox.kill()
|
|
261
|
-
}
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
```python
|
|
265
|
-
from lizard import Lizard
|
|
266
|
-
|
|
267
|
-
lizard = Lizard(project="my-project")
|
|
268
|
-
with lizard.create("base", timeout_ms=300_000) as sandbox:
|
|
269
|
-
sandbox.fs.write("/tmp/hello.txt", "Hello from Lizard!")
|
|
270
|
-
result = sandbox.process.exec_("cat /tmp/hello.txt")
|
|
271
|
-
if result.exit_code != 0:
|
|
272
|
-
raise RuntimeError(result.stderr)
|
|
273
|
-
print(result.stdout)
|
|
274
|
-
```
|
|
103
|
+
- **Templates:** `base` (default, Python 3.11 on Alpine Linux), `interpreter` (Python code interpreter), `codex` (coding agents), `desktop` (graphical desktop with Chromium).
|
|
104
|
+
- **Sizes:** `-s small|medium|large`, $0.0162 / $0.0324 (default) / $0.0648 per hour, billed per second while it runs. A paused sandbox costs nothing.
|
|
105
|
+
- **Lifetime:** 5 minutes by default, then the sandbox is deleted with its files. `--timeout 0` at create means no limit; `lizard sandbox timeout <id> <ms>` sets a new lifetime from now. Commands do not reset it.
|
|
106
|
+
- **Commands:** `exec` runs through `sh -c` as a new process each time and exits with the command's exit code; chain steps in one call (`sh -c 'cd /workspace && npm test'`). `ssh` needs a real terminal: from an agent, use `exec`.
|
|
107
|
+
- **Ports:** `lizard sandbox expose <id> <port>` prints an HTTPS URL that carries the sandbox's access token: treat it like a password.
|
|
108
|
+
- **Keeping work:** files outlive a sandbox only on a volume (`--volume <name>`); `pause` keeps memory and processes and stops billing; a snapshot saves a sandbox to start new ones from.
|
|
275
109
|
|
|
276
|
-
|
|
110
|
+
Everything else (files, coding agents, desktop, volumes, snapshots): `lizard skills get core --ref sandboxes --json`. From your own code: `--ref sdk`.
|
|
277
111
|
|
|
278
|
-
##
|
|
112
|
+
## Deploys
|
|
279
113
|
|
|
280
114
|
When the user wants to deploy or set up something new, work out the right action from cwd context before running anything:
|
|
281
115
|
|
|
@@ -286,157 +120,59 @@ When the user wants to deploy or set up something new, work out the right action
|
|
|
286
120
|
|
|
287
121
|
Naming heuristic: app-style names (`my-api`, `worker`, `flappy-bird`) are service names. Use the repo or directory name for the project.
|
|
288
122
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
Builds run on the platform's build nodes (no local Docker needed). When a build fails, read logs with `lizard logs --build`.
|
|
292
|
-
|
|
293
|
-
### Build decision order
|
|
294
|
-
|
|
295
|
-
1. Repo Dockerfile (verbatim) — if `dockerfilePath` is set on the service, the platform builds that Dockerfile from the repo unchanged and ignores `buildCommand`/`startCommand` for the image. A set `startCommand` still replaces the image's CMD at run time.
|
|
296
|
-
2. Synthesized Dockerfile — if `buildCommand` and/or `startCommand` are set on the service (or passed via `lizard up`), the platform generates a Dockerfile from those commands. No lizardpack invocation.
|
|
297
|
-
3. lizardpack auto-detect — clone, run `lizardpack`. If a repo `Dockerfile` exists AND has a real build step (a `RUN <pkg-manager>` line, not just `COPY dist/`), it's used verbatim; otherwise lizardpack generates a multi-stage one. Supported: Go, Node, Python, Rust, Ruby, PHP, Java, static — first match in that order.
|
|
298
|
-
|
|
299
|
-
### What triggers a rebuild
|
|
300
|
-
|
|
301
|
-
- `git push` to the tracked branch → auto-rebuild via GitHub webhook.
|
|
302
|
-
- `lizard redeploy` / `lizard up` → explicit rebuild.
|
|
303
|
-
- Setting a `VITE_*` or `NEXT_PUBLIC_*` variable → the platform redeploys the running services that receive it, so the build bakes it in. Do NOT chain a `lizard redeploy`. See [Applying an env change](#applying-an-env-change) for which builds receive them.
|
|
304
|
-
- `service set` for build-affecting fields (`repoUrl`, `branch`, `sourceType`, `buildCommand`, `dockerfilePath`, `rootDirectory`) → auto-rebuilds running services. Do NOT chain a `lizard redeploy` after it — that queues a second, redundant build.
|
|
305
|
-
- `service set` for runtime-only fields (`startCommand`, `preDeployCommand`, `containerPort`, `watchPatterns`) → no auto-rebuild. Follow with `lizard redeploy` to apply.
|
|
306
|
-
- All other env vars / secrets → applied without a rebuild; the service restarts to pick them up.
|
|
307
|
-
|
|
308
|
-
## Deploying
|
|
309
|
-
|
|
310
|
-
First question for a new service: upload vs git repo. **Always check for a git remote before reaching for `up`** — the CLI never auto-detects one, so you must do it yourself:
|
|
311
|
-
|
|
312
|
-
```
|
|
313
|
-
git remote get-url origin
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
- **Exit 0 with a GitHub URL → use the git-source path below**, not `up`. Parse `owner/repo` from the URL and run `lizard add -r owner/repo`. This is strongly preferred: pushes auto-redeploy via webhook, and there's no re-upload on every change.
|
|
317
|
-
- **No remote / non-GitHub / not a git repo → use tarball upload (`lizard up`).** This is the fallback for quick local iteration or no-remote situations, not the default.
|
|
318
|
-
|
|
319
|
-
`lizard up` always works regardless of git state, which makes it the path of least resistance — resist it when a GitHub remote exists. Only fall back to upload when the remote check actually fails. (For a private repo whose remote exists but isn't yet accessible to Lizard, run `lizard git connect` to install the GitHub App, then use the git-source path — don't silently downgrade to a tarball.)
|
|
123
|
+
**Git or upload.** Check `git remote get-url origin` first. A GitHub remote → `lizard add -r owner/repo --json`: pushes to the branch redeploy through a webhook. No remote, not GitHub, or not a git repo → `lizard up --json`. For a private repo Lizard cannot reach yet, run `lizard git connect` to install the GitHub App instead of falling back to an upload. `lizard up` always switches a service to `sourceType=upload`: don't use it on a git-backed service.
|
|
320
124
|
|
|
321
|
-
|
|
125
|
+
**Builds** run on the platform's build nodes; no local Docker needed. lizardpack detects Go, Node, Python, Rust, Ruby, PHP, Java and static sites; a repo Dockerfile with a real build step is used as is. Read a failed build with `lizard logs --build --json`.
|
|
322
126
|
|
|
323
|
-
|
|
324
|
-
# One-shot for a new service from GitHub:
|
|
325
|
-
lizard add -r owner/repo --json
|
|
326
|
-
|
|
327
|
-
# Existing service: switch source to git or update branch:
|
|
328
|
-
lizard service set <svc> \
|
|
329
|
-
--set sourceType=github \
|
|
330
|
-
--set repoUrl=https://github.com/owner/repo \
|
|
331
|
-
--set branch=main \
|
|
332
|
-
--json
|
|
333
|
-
lizard redeploy --service <svc>
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
When `repoUrl` is set, pushes to the matching branch auto-redeploy via the GitHub webhook. If the service has a `rootDirectory` (monorepo subpath) or watch patterns, only matching changes trigger redeploys.
|
|
337
|
-
|
|
338
|
-
Useful `service set` fields (discover full list with `lizard service set --help --json`):
|
|
127
|
+
**Rebuilds.** `service set` on a build field (`repoUrl`, `branch`, `buildCommand`, `dockerfilePath`, `rootDirectory`) and setting a `VITE_*` or `NEXT_PUBLIC_*` variable rebuild on their own: don't chain `lizard redeploy`. Runtime-only fields (`startCommand`, `preDeployCommand`, `containerPort`) need `lizard redeploy`.
|
|
339
128
|
|
|
340
|
-
|
|
341
|
-
- `repoUrl`, `branch`, `rootDirectory`
|
|
342
|
-
- `dockerfilePath` — use a specific repo Dockerfile, bypasses lizardpack auto-detect
|
|
343
|
-
- `buildCommand`
|
|
344
|
-
- `startCommand`, `preDeployCommand` — `preDeployCommand` runs before `startCommand` at the start of every container (each replica, each restart), and only when `startCommand` is also set. Make it safe to run many times and at the same time.
|
|
345
|
-
- `watchPatterns` — string array, comma-separated or JSON
|
|
346
|
-
- `containerPort` — TCP port the app listens on (defaults to 3000). Set to `0` for [worker mode](#worker-mode).
|
|
347
|
-
- `name` — rename a service (lowercase a-z, digits, hyphens; 1–40 chars). Goes through `config:apply`; the legacy `PATCH /api/apps/:id` returns 410. Refs to the old name (`${{old.KEY}}`) stop resolving: update them.
|
|
129
|
+
**Workers** without an HTTP listener: `containerPort=0` (`lizard up --port 0`, or `lizard port 0` on an existing service).
|
|
348
130
|
|
|
349
|
-
|
|
131
|
+
Details (build order, service fields, worker mode, recipes): `lizard skills get core --ref deploys --json`.
|
|
350
132
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
### Tarball upload (no git remote, or quick local iteration)
|
|
133
|
+
## Databases and storage
|
|
354
134
|
|
|
355
135
|
```
|
|
356
|
-
lizard
|
|
136
|
+
lizard add postgres redis s3 # all three in one command
|
|
137
|
+
lizard add postgres # or one at a time
|
|
357
138
|
```
|
|
358
139
|
|
|
359
|
-
-
|
|
360
|
-
-
|
|
361
|
-
-
|
|
362
|
-
-
|
|
363
|
-
-
|
|
364
|
-
|
|
365
|
-
## Worker mode
|
|
366
|
-
|
|
367
|
-
For services that don't expose an HTTP listener (background workers, reconcilers, queue consumers, cron-style polling loops), set `containerPort=0`. The platform then:
|
|
140
|
+
- The first addon of each type is named after it (`postgres`, `redis`, `s3`); later ones get names like `postgres-autumn-bear`. References use the real name: `${{postgres.DATABASE_PRIVATE_URL}}`.
|
|
141
|
+
- Every running Postgres and Redis reaches every service in the project as `DATABASE_URL` / `REDIS_URL`. Inside the project, prefer the private URL: `lizard secrets set DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' --service <svc>`.
|
|
142
|
+
- A reference to a missing addon or key becomes an empty string and does not fail the deploy; renaming an addon breaks its references.
|
|
143
|
+
- S3 comes with a private bucket named `default`, up to 16 GiB per account. `lizard s3 upload <file>` and `lizard s3 list` work without an AWS SDK; AWS SDKs need `forcePathStyle: true`. Making a bucket public is done in the dashboard.
|
|
144
|
+
- Redis has no persistence settings: keep data you cannot lose in Postgres.
|
|
368
145
|
|
|
369
|
-
|
|
370
|
-
- Skips the port reachability check (no `app port X unreachable` log spam, no false-positive "unhealthy" status).
|
|
371
|
-
- Skips `EXPOSE` in the synthesized Dockerfile.
|
|
372
|
-
- Skips the LB route registration on the node — nothing is served. (A generated `.onlizard.com` domain may still appear on the service; it won't respond.)
|
|
146
|
+
Every variable each addon exposes: `lizard skills get core --ref deploys --json`.
|
|
373
147
|
|
|
374
|
-
|
|
148
|
+
## Secrets and config
|
|
375
149
|
|
|
376
150
|
```
|
|
377
|
-
lizard
|
|
378
|
-
lizard
|
|
379
|
-
lizard
|
|
151
|
+
lizard secrets list [--service <svc>] [--global]
|
|
152
|
+
lizard secrets set KEY=v [K2=v2 …] [--service <svc>] # service scope, the default
|
|
153
|
+
lizard secrets set KEY=v --global # every service in the project
|
|
154
|
+
lizard secrets import [--service <svc>] < .env
|
|
380
155
|
```
|
|
381
156
|
|
|
382
|
-
|
|
157
|
+
- List before you set, so you don't duplicate or shadow a key.
|
|
158
|
+
- Keep secrets in service scope. `--global` is for values that are not secret (`LOG_LEVEL`, `NODE_ENV`, feature flags).
|
|
159
|
+
- Precedence, last wins: addon env < project secrets < project env < app env < app secrets < platform vars (`PORT`, `LIZARD_*`, which cannot be overridden).
|
|
160
|
+
- A runtime value applies with a restart, no rebuild. Never print a service's full environment.
|
|
383
161
|
|
|
384
|
-
|
|
162
|
+
Scoping rules and build-time variables in detail: `lizard skills get core --ref deploys --json`.
|
|
385
163
|
|
|
386
|
-
##
|
|
387
|
-
|
|
388
|
-
Two scopes exist. No workspace-level globals.
|
|
389
|
-
|
|
390
|
-
- Project ("global"): `lizard secrets set KEY=v [K2=v2 …] --global` → project scope (wire: `secrets.shared`)
|
|
391
|
-
- Service (default): `lizard secrets set KEY=v [K2=v2 …] [--service <svc>]` → service scope (wire: `secrets.services[<svc>]`)
|
|
392
|
-
|
|
393
|
-
`set` is variadic. Companion subcommands: `lizard secrets list|delete K1 K2|import` (import reads dotenv from stdin). When the linked service in cwd is set, plain `lizard secrets set KEY=v` writes to that service. Pass `--global` to escape to project scope.
|
|
394
|
-
|
|
395
|
-
### Precedence (last writer wins)
|
|
164
|
+
## Domains
|
|
396
165
|
|
|
397
166
|
```
|
|
398
|
-
|
|
167
|
+
lizard domain --json # show or generate the service's onlizard.com domain
|
|
168
|
+
lizard domain example.com --service <svc> # attach; the hostname is positional, there is no `add`
|
|
169
|
+
lizard domain verify example.com # once the DNS records have propagated
|
|
170
|
+
lizard domain example.com --service <svc> --force # move it here from another of your services
|
|
399
171
|
```
|
|
400
172
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
### Secret scoping
|
|
404
|
-
|
|
405
|
-
Default to service-scope. `--global` puts the value into `process.env` of every service in the project — including ones that don't need it.
|
|
173
|
+
Give the user the TXT and CNAME records the attach prints, then verify once they propagate.
|
|
406
174
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
- Check first: `lizard secrets list` (+ `--global`) before set/update — avoid creating a duplicate or shadowing an existing key (service scope wins over global; see [Precedence](#precedence-last-writer-wins)).
|
|
410
|
-
- Default — service-scope: `lizard secrets set KEY=v --service <svc>` per consumer. For addon DSNs, prefer a private reference when the consumer can reach it: `lizard secrets set DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' --service <svc>` (no separate `env` command — refs are interpolated at deploy time wherever they appear). A ref reads the addon's current value on each deploy of the consumer; there is no automatic credential rotation.
|
|
411
|
-
- `--global` only for non-secrets and provably-public values: `LOG_LEVEL`, `NODE_ENV`, feature flags, frontend `SENTRY_DSN`. If unsure whether a value is a secret, treat it as one. A compromised service reads its own env; broader scope = more credentials exposed for no reason.
|
|
412
|
-
|
|
413
|
-
### Applying an env change
|
|
414
|
-
|
|
415
|
-
- Runtime vars/secrets apply without rebuilding the image. The application process restarts to read its new environment; do not promise uninterrupted requests.
|
|
416
|
-
- `VITE_*` / `NEXT_PUBLIC_*` (build-time baked) → setting one redeploys the running services that receive it; a plain restart won't pick them up. Only a Dockerfile the platform generates bakes them in: lizardpack on a GitHub service, or a service with `buildCommand`/`startCommand`. A `dockerfilePath` build, or a `lizard up` upload without those overrides, gets no Lizard variables at build time, and no build gets build args except `COMMIT_SHA`. For public values there, commit them in `.env.production`, set a build command, or write them into the Dockerfile.
|
|
417
|
-
- Verify a non-secret value or the application's behavior. Do not print the full environment: it can expose credentials.
|
|
418
|
-
|
|
419
|
-
## Managed addons
|
|
420
|
-
|
|
421
|
-
Provision with `lizard add <type>`. Each addon exposes a fixed env-var set; reference by name from a consumer service via `${{<addon-name>.KEY}}`. The first addon of a given type gets the bare type as its name (so use `postgres` in the reference for the first Managed Postgres instance); subsequent ones get `{type}-{adjective}-{noun}` like `postgres-autumn-bear`. There's no type-alias fallback — a ref must use the addon's actual name. Refs match the addon's current name, so renaming it breaks existing refs: update them after a rename. Every running Postgres and Redis addon's `DATABASE_URL` / `REDIS_URL` also reaches every service in the project at the lowest precedence; a value set on the consumer overrides it.
|
|
422
|
-
|
|
423
|
-
- `postgres` — two connection URLs: prefer `DATABASE_PRIVATE_URL` when available and reachable within the same project and region (no ingress/egress charges); use `DATABASE_URL` for public access, such as local clients or external CI (network charges may apply). Also exposes `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE`, `POSTGRES_USER`, `POSTGRES_DB`, `POSTGRES_PASSWORD`.
|
|
424
|
-
- `redis` — `REDIS_URL`; services in the same project should use `REDIS_PRIVATE_URL`. No eviction policy and no append-only file are configured: if it runs out of memory, the instance restarts and recent writes can be lost. Keep data you cannot lose in Postgres.
|
|
425
|
-
- `s3` — `S3_ENDPOINT`, `S3_DEFAULT_BUCKET`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_REGION`. Auto-creates a private bucket named `default`, and each account can store up to 16 GiB across its addons. Make a bucket public from the dashboard's S3 browser; objects in a public bucket are served without auth two ways: the gateway URL the dashboard shows, `https://s3-<region>.onlizard.com/<addonId>/<bucket>/<key>`, or the platform proxy `<dashboard-host>/api/s3/<addonId>/public/<bucket>/<key>` (the host `lizard open` launches; long-lived immutable cache headers). For AWS SDK use, set `forcePathStyle: true`. ACL flips aren't on the CLI yet, so point users at the dashboard. To push a local file into a bucket directly (no AWS SDK needed), use `lizard s3 upload <file> [--addon <name>] [--bucket <name>] [--key <key>] [--content-type <type>]` — auto-resolves the project's only S3 addon and bucket `default` if omitted; prints `{key, etag, size, url}` (`url` is `null` unless the bucket is public). `lizard s3 list|ls [--bucket <name>] [--prefix <p>]` lists objects in a bucket.
|
|
426
|
-
|
|
427
|
-
## Composition patterns
|
|
428
|
-
|
|
429
|
-
Multi-step requests follow natural chains. Return one unified response, don't farm out steps:
|
|
430
|
-
|
|
431
|
-
- First deploy from git — pick action via [Setup decision flow](#setup-decision-flow) → `lizard add -r owner/repo` → stream build → surface URL.
|
|
432
|
-
- First deploy from local code — Setup decision flow → `lizard up` → surface URL.
|
|
433
|
-
- Add a managed database to an existing service — `lizard add postgres` → bind the consumer's `DATABASE_URL` to the private reference as described above (the service restarts with it; no redeploy needed).
|
|
434
|
-
- Add object storage to a service — `lizard add s3` → reference `${{s3.S3_ENDPOINT}}`, `${{s3.S3_DEFAULT_BUCKET}}`, `${{s3.S3_ACCESS_KEY_ID}}`, `${{s3.S3_SECRET_ACCESS_KEY}}`, `${{s3.S3_REGION}}` from the consumer service. The `default` bucket is private; to serve files without auth, have the user make it public in the dashboard's S3 browser, then objects are served at `<dashboard-host>/api/s3/<addonId>/public/default/<key>`. See [Managed addons](#managed-addons).
|
|
435
|
-
- Wire a fresh git source on an existing service — `service set --set sourceType=github --set repoUrl=… --set branch=…` → `redeploy`.
|
|
436
|
-
- Fix a failed build — `logs --build` → diagnose → fix project (user's repo) OR adjust `buildCommand` / `startCommand` via `service set` → `redeploy` → `logs` to verify.
|
|
437
|
-
- Add a custom domain — `domain <host> --service <svc>` (the hostname is a positional, there is no `add` subcommand) → surface the TXT/CNAME records to the user → `domain verify <host>` once DNS propagates. Bare `domain` shows (or auto-generates) the service's current domain. If the host is already attached to another of the user's services, the attach 409s with a reclaim hint — re-run with `--force` to move it here.
|
|
438
|
-
|
|
439
|
-
## Common ops
|
|
175
|
+
## Logs and operations
|
|
440
176
|
|
|
441
177
|
```
|
|
442
178
|
lizard logs --json [--service <name>] # last 200 runtime log lines, then exit (--tail N to override)
|
|
@@ -466,19 +202,7 @@ lizard s3 upload <file> [--bucket <b>] # upload a local file to an S3 addon
|
|
|
466
202
|
lizard s3 list --json [--bucket <b>] # list objects in an S3 addon bucket
|
|
467
203
|
```
|
|
468
204
|
|
|
469
|
-
`lizard
|
|
470
|
-
It uses the linked project unless `--project <name>` selects another project.
|
|
471
|
-
Without `--all`, metrics defaults to the linked service, or the project overview
|
|
472
|
-
when no service is linked. Do not combine `--all` with `--service`.
|
|
473
|
-
The project overview includes `Egress` (outbound bytes per second) and `Volumes`
|
|
474
|
-
(used / total bytes). These columns use the latest sample from the past hour;
|
|
475
|
-
`Sampled` refers to CPU and memory. Missing measurements show `—`.
|
|
476
|
-
Watch mode refreshes CPU and memory every 3 seconds and I/O history every 30 seconds.
|
|
477
|
-
JSON output includes the history in each service's `series` and `timestamps` fields.
|
|
478
|
-
|
|
479
|
-
`lizard run --service <app>` injects stored values only: `${{…}}` refs arrive as literal text, and platform vars (`PORT`, `LIZARD_*`) are not set. `--service <addon>` injects the addon's real connection values, so use it to run a local command against a database. To check a service's wiring, use `lizard logs --build --service <svc>` and `lizard secrets list --service <svc> --show`; shell access into services is off.
|
|
480
|
-
|
|
481
|
-
For exact flags, `lizard <cmd> --help --json`. Other commands not shown above: `lizard git` (GitHub integration), `lizard config` (project configuration), `lizard workspace` (workspace info) — discover each with `lizard <cmd> --help --json`.
|
|
205
|
+
Metrics options and `lizard run` in detail: `lizard skills get core --ref deploys --json`.
|
|
482
206
|
|
|
483
207
|
## Response format
|
|
484
208
|
|
|
@@ -497,7 +221,7 @@ Skip command-by-command transcripts unless they explain a failure.
|
|
|
497
221
|
3. Don't use `lizard up` to switch a service to a git source. It always forces `sourceType=upload`. Use `service set` + `redeploy` instead.
|
|
498
222
|
4. A Dockerfile that copies pre-built artifacts (`COPY dist/`, `build/`, `out/`, `.next/`, `public/`) without a `RUN` build step gets silently regenerated by lizardpack. Add a build step or set `dockerfilePath` to force verbatim use.
|
|
499
223
|
5. Don't generate Dockerfiles unsolicited — lizardpack auto-detects most stacks. Try a deploy first; write one only if it fails. Ask before either.
|
|
500
|
-
6. Don't put runtime secrets (DB credentials, API keys, RPC creds, S3 keys) in `--global` "just in case another service needs it later". Scope to the services that consume them — see [
|
|
224
|
+
6. Don't put runtime secrets (DB credentials, API keys, RPC creds, S3 keys) in `--global` "just in case another service needs it later". Scope to the services that consume them — see [Secrets and config](#secrets-and-config).
|
|
501
225
|
|
|
502
226
|
## Billing
|
|
503
227
|
|