ghostdock 0.0.7 → 0.0.9
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/cli-reference.md +1527 -0
- package/dist/cli.md +733 -0
- package/dist/index.js +2920 -857
- package/package.json +4 -4
- package/CLI.md +0 -468
package/package.json
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghostdock",
|
|
3
3
|
"description": "Ghostdock CLI — device login and agent tool invocation from the command line",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.9",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ghostdock": "dist/index.js",
|
|
8
8
|
"gdock": "dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"dist"
|
|
12
|
-
"CLI.md"
|
|
11
|
+
"dist"
|
|
13
12
|
],
|
|
14
13
|
"repository": {
|
|
15
14
|
"type": "git",
|
|
@@ -20,8 +19,9 @@
|
|
|
20
19
|
},
|
|
21
20
|
"scripts": {
|
|
22
21
|
"sync-catalog": "bun run scripts/sync-catalog.ts",
|
|
22
|
+
"sync-reference": "bun run scripts/sync-reference.ts",
|
|
23
23
|
"needs-publish": "bun run scripts/needs-publish.ts",
|
|
24
|
-
"prebuild": "bun run sync-catalog",
|
|
24
|
+
"prebuild": "bun run sync-catalog && bun run sync-reference",
|
|
25
25
|
"build": "bun run scripts/build.ts",
|
|
26
26
|
"dev": "bun run src/index.ts",
|
|
27
27
|
"pretest": "bun run sync-catalog",
|
package/CLI.md
DELETED
|
@@ -1,468 +0,0 @@
|
|
|
1
|
-
# Ghostdock CLI
|
|
2
|
-
|
|
3
|
-
Command-line access to your Ghostdock account — built for agents, but usable by humans too.
|
|
4
|
-
Authenticate once, then call Ghostdock's tools without leaving the terminal.
|
|
5
|
-
|
|
6
|
-
This document is written for an agent (or human) driving the CLI directly. It is also published at
|
|
7
|
-
`https://ghostdock.brainchimps.com/cli.md` so an agent can `curl`/fetch it without cloning this repo.
|
|
8
|
-
|
|
9
|
-
## Install / run
|
|
10
|
-
|
|
11
|
-
No install required — run it with `npx`:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npx ghostdock --help
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Or install it globally:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install -g ghostdock
|
|
21
|
-
ghostdock --help
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
`gdock` is a short name for the same CLI: `npx gdock …`, or `gdock …` after a
|
|
25
|
-
global install. Help and hints use whichever name you typed.
|
|
26
|
-
|
|
27
|
-
Inside this monorepo (for development), run from the repo root or `packages/cli`:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
bun run --cwd packages/cli build # bundles src/index.ts -> dist/index.js
|
|
31
|
-
bun run --cwd packages/cli dev -- --help # run from source without building
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Global flags
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
ghostdock --version
|
|
38
|
-
ghostdock --base-url <url> <command>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
- `--version` / `-v` — print CLI version and exit
|
|
42
|
-
- `--base-url <url>` — API origin for this invocation (wins over `GHOSTDOCK_BASE_URL`)
|
|
43
|
-
|
|
44
|
-
## Commands
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
ghostdock login Sign in and store a device access token for this CLI
|
|
48
|
-
ghostdock logout Revoke the device session and remove stored credentials
|
|
49
|
-
ghostdock whoami Show the account this CLI is currently authenticated as
|
|
50
|
-
ghostdock tools List available agent tools
|
|
51
|
-
ghostdock skills List and read Agent Skills (same catalog as MCP)
|
|
52
|
-
ghostdock env Manage organization environment variables and secrets
|
|
53
|
-
ghostdock sandbox_upload Upload local files or directories to a sandbox
|
|
54
|
-
ghostdock sandbox_create Create a sandbox from a Dockerfile or Compose directory (or ZIP)
|
|
55
|
-
ghostdock publish_static Publish a local directory or ZIP to the CDN
|
|
56
|
-
ghostdock publish_auto Inspect local source and publish (CDN or sandbox)
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Every tool in the catalog (e.g. `list_organizations`, `list_published_apps`) is also registered as its
|
|
60
|
-
own top-level command — see **Invoking a tool** below.
|
|
61
|
-
|
|
62
|
-
Run `ghostdock <command> --help` for the full flag list of any command.
|
|
63
|
-
|
|
64
|
-
### `ghostdock login`
|
|
65
|
-
|
|
66
|
-
Ghostdock uses a device-authorization flow: no password is ever typed into the terminal.
|
|
67
|
-
|
|
68
|
-
**Default (print-and-exit) — best when a human is present to click the link:**
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
ghostdock login
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
This prints a URL to open in a browser and exits `0` immediately — it does not prompt for input or
|
|
75
|
-
poll for approval. Approve the request in the browser, then complete login with
|
|
76
|
-
**`ghostdock login --code <paste-code>`**, redeeming the one-time code from the browser's
|
|
77
|
-
"Having trouble? Show code" link (see below).
|
|
78
|
-
|
|
79
|
-
Each `login` invocation starts a **new** device session. A later `login --wait` does **not** resume
|
|
80
|
-
polling for a prior plain `login`. To block until approval, run **`ghostdock login --wait` up
|
|
81
|
-
front** instead of plain `login`.
|
|
82
|
-
|
|
83
|
-
**`--wait` — poll until approved:**
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
ghostdock login --wait
|
|
87
|
-
# or with a custom timeout (seconds, default 300):
|
|
88
|
-
ghostdock login --wait --timeout 120
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Prints the same URL, then polls the server every few seconds until the login is approved, denied,
|
|
92
|
-
or the timeout elapses. Exits `0` on success, non-zero otherwise.
|
|
93
|
-
|
|
94
|
-
**`--code` — paste-code fallback:**
|
|
95
|
-
|
|
96
|
-
If the CLI can't poll (e.g. it's running in a sandbox with no long-lived process, or the browser
|
|
97
|
-
approval happened on a different machine), the browser's "Having trouble? Show code" link reveals a
|
|
98
|
-
short one-time code. Redeem it directly:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
ghostdock login --code <paste-code>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
On success, credentials are written and the command exits `0`. If the code hasn't been approved
|
|
105
|
-
yet, it exits `1` — approve it in the browser first.
|
|
106
|
-
|
|
107
|
-
### `ghostdock logout`
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
ghostdock logout
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Revokes the device session on the server (best-effort — still clears local credentials even if the
|
|
114
|
-
server call fails, e.g. when offline) and deletes the local credentials file.
|
|
115
|
-
|
|
116
|
-
### `ghostdock whoami`
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
ghostdock whoami
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Prints the identity behind the stored access token as JSON (`{ "userId": ..., "baseUrl": ... }`).
|
|
123
|
-
Transparently refreshes an expired access token using the stored refresh token before failing.
|
|
124
|
-
Exits `1` with a message if not logged in or the session can't be refreshed.
|
|
125
|
-
|
|
126
|
-
### `ghostdock tools`
|
|
127
|
-
|
|
128
|
-
Lists the tool catalog for the authenticated account:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
ghostdock tools # name + description, one per line
|
|
132
|
-
ghostdock tools --json # the full catalog (including each tool's JSON Schema) as JSON
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Requires login — prints a hint and exits `1` if there's no valid session.
|
|
136
|
-
|
|
137
|
-
### `ghostdock skills`
|
|
138
|
-
|
|
139
|
-
Lists and reads **Agent Skills** for the authenticated account — the same catalog MCP
|
|
140
|
-
clients discover at `skill://index.json` (SEP-2640 / Agent Skills discovery 0.2.0).
|
|
141
|
-
Prefer resources. `list_skills` and `read_skill` are MCP fallbacks for clients that
|
|
142
|
-
cannot use `resources/list` and `resources/read` — skip them if those work.
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
ghostdock skills # name, description, and skill:// URI, one skill per block
|
|
146
|
-
ghostdock skills --json # official discovery index ($schema + skills[])
|
|
147
|
-
ghostdock skills get skill://github/SKILL.md # print SKILL.md
|
|
148
|
-
ghostdock skills get github # same, by name
|
|
149
|
-
ghostdock skills get org_1/release-notes # organization skill
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
`--json` on `get` prints `{ uri, name, description, markdown }`. If the same name exists
|
|
153
|
-
in more than one organization, pass the `skill://` URI from the index.
|
|
154
|
-
|
|
155
|
-
Requires login — prints a hint and exits `1` if there's no valid session.
|
|
156
|
-
|
|
157
|
-
### Invoking a tool
|
|
158
|
-
|
|
159
|
-
Every catalog tool is its own top-level command, named after the tool, with one `--flag` per
|
|
160
|
-
schema property (`organizationId` -> `--organization-id`). Run `ghostdock <tool-name> --help` to
|
|
161
|
-
see a tool's flags and which are required. Output is the tool's JSON result on stdout; nothing is
|
|
162
|
-
printed on stderr on success.
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
ghostdock list_organizations
|
|
166
|
-
# {"organizations": [{"id": "org_123", "name": "Acme", "slug": "acme"}]}
|
|
167
|
-
|
|
168
|
-
ghostdock list_published_apps --organization-id org_123
|
|
169
|
-
# {"apps": [{"id": "app_1", "url": "https://acme.example.app", "title": "Acme App", "publishedAt": "..."}]}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Number/boolean flags are parsed from their string form; array/object flags take a raw JSON string
|
|
173
|
-
(e.g. `--tags '["a","b"]'`). Requires login — prints a hint and exits `1` if there's no valid
|
|
174
|
-
session, or the server's error message (e.g. "Not a member of this organization") on a `4xx`.
|
|
175
|
-
|
|
176
|
-
The tool list embedded in the CLI binary is generated at build time from the server's tool catalog
|
|
177
|
-
(`bun run sync-catalog` in `packages/cli`), so `--help` and flag parsing work offline; invoking a
|
|
178
|
-
tool still requires a network call and a valid session.
|
|
179
|
-
|
|
180
|
-
### Sandbox tools
|
|
181
|
-
|
|
182
|
-
Use sandbox tools to publish and manage public static sites. Each sandbox serves its preview on port
|
|
183
|
-
`8080`; the platform automatically stops idle sandboxes and deletes stopped sandboxes unless you
|
|
184
|
-
override the intervals with `--auto-stop-interval-minutes` and
|
|
185
|
-
`--auto-delete-interval-minutes`. `--auto-restart` defaults to `false`, so wake-on-visit is off for
|
|
186
|
-
new sandboxes unless you set it.
|
|
187
|
-
|
|
188
|
-
| Tool | Purpose |
|
|
189
|
-
| --- | --- |
|
|
190
|
-
| `create_sandbox` | Create a sandbox (idle-stop + 14-day auto-delete by default). Dockerfile and Compose restart automatically after idle-stop. Inline Dockerfile text and inline Compose files only — a directory or ZIP (COPY/ADD, Compose build files) is `sandbox_create`. For bun-dev, pass an OCI `--source type=image` then `set_sandbox_boot`. |
|
|
191
|
-
| `list_sandboxes` | List an organization's sandboxes. |
|
|
192
|
-
| `upload_files` | Upload a small set of inline files or a base64-encoded ZIP. |
|
|
193
|
-
| `list_files` | List files in a sandbox directory (`path` defaults to `/workspace`). |
|
|
194
|
-
| `read_file` | Read a file from a sandbox (utf8 text, or base64 for small binaries). |
|
|
195
|
-
| `list_urls` | List sandbox URLs for a sandbox. |
|
|
196
|
-
| `create_url` | Expose a port as a sandbox URL (idempotent by port; `autoWake` and `public` default to false). |
|
|
197
|
-
| `update_url` | Update a URL's port, autoWake, and/or public. |
|
|
198
|
-
| `delete_url` | Delete a URL exposure. |
|
|
199
|
-
| `list_mcps` | List MCP exposures configured for a sandbox (name, port, path, autoWake). |
|
|
200
|
-
| `create_mcp` | Expose an MCP server running in a sandbox (idempotent by name; path defaults to `/mcp`). |
|
|
201
|
-
| `update_mcp` | Update an MCP exposure's name, port, path, and/or autoWake. |
|
|
202
|
-
| `delete_mcp` | Delete an MCP exposure. |
|
|
203
|
-
| `list_sandbox_tools` | List tools exposed by MCP servers configured on a sandbox. |
|
|
204
|
-
| `call_sandbox_tool` | Call a tool on a sandbox MCP server. |
|
|
205
|
-
| `get_ssh_access` | Return temporary SSH credentials (60 minutes); idle auto-stop still applies. |
|
|
206
|
-
| `revoke_ssh_access` | Revoke active SSH credentials for a sandbox. |
|
|
207
|
-
| `run_command` | Run a shell command, waiting up to 120 seconds before returning handles for polling; idle auto-stop still applies. Sessions do not survive idle-stop — use Dockerfile/Compose or `set_sandbox_boot`. |
|
|
208
|
-
| `set_sandbox_boot` | Register a bun-dev (or similar) command that starts now and after idle-stop. On Compose it runs after the stack; on a Dockerfile it replaces CMD. For host-only, create from `--source type=image`. |
|
|
209
|
-
| `get_command` | Get a shell command's status and exit code. |
|
|
210
|
-
| `get_command_logs` | Get paginated stdout and stderr for a shell command. |
|
|
211
|
-
| `kill_command` | Interrupt a running shell command. |
|
|
212
|
-
| `create_shell_session` | Create a sticky shell session that preserves cwd and environment between commands. |
|
|
213
|
-
| `close_shell_session` | Close a sticky shell session. |
|
|
214
|
-
| `update_sandbox` | Update the display name or idle-stop / auto-delete intervals (omit = no change; `null` = platform default). |
|
|
215
|
-
| `wake_sandbox` | Start a stopped sandbox, or reset the idle-stop countdown if already running. |
|
|
216
|
-
| `get_sandbox_status` | Get status, lifecycle deadlines, and optional features (tcp_bridge) without starting or touching activity. |
|
|
217
|
-
| `stop_sandbox` | Stop a sandbox without deleting its files. |
|
|
218
|
-
| `delete_sandbox` | Permanently delete a sandbox and its files. |
|
|
219
|
-
| `publish_static` | Publish a static file set or ZIP to the CDN and return a durable `{adjective}-{adjective}-{noun}.static…` URL (does not create a sandbox). |
|
|
220
|
-
| `publish_auto` | Inspect source (folder or ZIP) with the deploy agent and publish — CDN when pre-built static, otherwise a DeploymentSpec rendered to `Dockerfile.deploy` + `compose.deploy.yaml` and run with Compose. First deploy and replay use the same execute path. Same lifecycle flags as `create_sandbox`; minted URL defaults to public + auto-wake. Detected tests always run on Compose execution and are reported; `--require-verify` makes a failure `verify_failed` instead of deploying. On failure, inspect the kept sandbox and re-invoke with `--spec` to verify a DeploymentSpec on a clean box. Every terminal outcome stores the upload and returns authenticated `fileUrls`. Needs a usable compose-capable sandbox provider: with none, a call that plans fails with a not-configured error before planning, even for pre-built static files (use `publish_static` for those). |
|
|
221
|
-
| `list_projects` | List first-class Projects (name, live URL, latest attempt). Distinct from `list_published_apps`. |
|
|
222
|
-
| `get_project` | Get one project: name, slug, latest attempt, live deploy. |
|
|
223
|
-
| `create_project` | Create an empty project (name only). No deploy until `publish_auto` ships source to this `projectId`. |
|
|
224
|
-
| `update_project` | Rename a project. Pass `displayName` null or empty to clear the name. |
|
|
225
|
-
| `list_project_deployments` | List ship attempts for a project, newest first. |
|
|
226
|
-
| `get_project_deployment` | Get one deployment by id, including authenticated `fileUrls` when blobs were stored. |
|
|
227
|
-
| `redeploy_project` | Ship stored source again. Omit `--deployment-id` to retry the last attempt that stored source. Pass `--deployment-id` for that version. Current project env is applied. New deployment row. |
|
|
228
|
-
| `get_project_environment` | Get a project's stored environment (local entries, org opt-ins, bindings). Secret values withheld. |
|
|
229
|
-
| `set_project_environment_selection` | Full-replace organization environment exports for a project (`environment` names + optional `bindings`). |
|
|
230
|
-
| `set_project_environment_entry` | Create or replace one project-local variable or secret, by name (prefer CLI for secret values). |
|
|
231
|
-
| `delete_project_environment_entry` | Delete one project-local variable or secret, by name. |
|
|
232
|
-
| `unpublish_static` | Take a CDN-published static site offline so its public URL no longer serves files. |
|
|
233
|
-
| `get_sandbox_environment` | Get a sandbox's environment: organization entries (selected + exportAs + overriddenByLocal), bindings, local entries, and whether it's running. |
|
|
234
|
-
| `set_sandbox_environment_selection` | Full-replace organization exports (`environment` plain names + optional `bindings` remaps; omit bindings to clear remaps). |
|
|
235
|
-
| `set_sandbox_environment_entry` | Create or replace one of a sandbox's own (local) variables or secrets, by name (prefer CLI for secret values). |
|
|
236
|
-
| `delete_sandbox_environment_entry` | Delete one of a sandbox's own (local) variables or secrets, by name. |
|
|
237
|
-
|
|
238
|
-
For example, create a sandbox, then expose a URL:
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
ghostdock create_sandbox --organization-id org_123 --display-name "Marketing site"
|
|
242
|
-
ghostdock create_url --sandbox-id sandbox_123 --port 8080 --auto-wake true --public true
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
#### Environment in a sandbox
|
|
246
|
-
|
|
247
|
-
A sandbox exports **nothing** by default (unless you boot from an organization snapshot or catalog
|
|
248
|
-
image whose manifest supplies defaults). `environment` has three parts: `organization` (plain same-name opt-ins from the
|
|
249
|
-
catalogue, see [`ghostdock env`](#ghostdock-env)), `bindings` (slot ← org entry remaps), and `local` (sandbox-only variables/secrets). A local entry overrides an
|
|
250
|
-
organization export of the same name. Prefer the CLI when setting secret values so they are not
|
|
251
|
-
pasted into the agent conversation.
|
|
252
|
-
|
|
253
|
-
```bash
|
|
254
|
-
# At create time, in one call:
|
|
255
|
-
ghostdock create_sandbox --organization-id org_123 \
|
|
256
|
-
--environment '{"organization":["VITE_API_URL","BUILD_TOKEN"],"bindings":[{"name":"DATABASE_URL","organization":"PROD_DATABASE_URL"}],"local":[{"name":"API_KEY","value":"sk_live","kind":"secret"}]}'
|
|
257
|
-
|
|
258
|
-
# Afterwards:
|
|
259
|
-
ghostdock get_sandbox_environment --sandbox-id sandbox_123
|
|
260
|
-
ghostdock set_sandbox_environment_selection --sandbox-id sandbox_123 --environment '["VITE_API_URL"]' \
|
|
261
|
-
--bindings '[{"name":"DATABASE_URL","organization":"PROD_DATABASE_URL"}]'
|
|
262
|
-
ghostdock set_sandbox_environment_selection --sandbox-id sandbox_123 --environment '[]' # clears plain + remaps (omit bindings)
|
|
263
|
-
ghostdock set_sandbox_environment_entry --sandbox-id sandbox_123 --name API_KEY --value sk_live --kind secret
|
|
264
|
-
ghostdock delete_sandbox_environment_entry --sandbox-id sandbox_123 --name API_KEY
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Values arrive as real environment variables, so read them with `process.env` / `$VAR` inside the
|
|
268
|
-
sandbox. **Do not pass secrets in `run_command` strings** — the command text is retained and
|
|
269
|
-
readable through `get_command_logs`. `get_sandbox_environment` reports every organization entry
|
|
270
|
-
(selected + overriddenByLocal) and the sandbox's own local entries; `get_sandbox_status` reports
|
|
271
|
-
just the resolved names.
|
|
272
|
-
|
|
273
|
-
New shell commands and SSH sessions see a change immediately. Processes already running keep the
|
|
274
|
-
values they booted with until restarted (pass `--restart` to `set_sandbox_environment_selection` /
|
|
275
|
-
`set_sandbox_environment_entry` / `delete_sandbox_environment_entry` to restart a running sandbox
|
|
276
|
-
instead).
|
|
277
|
-
|
|
278
|
-
### Image tools
|
|
279
|
-
|
|
280
|
-
Organization image catalog: OCI bookmarks (`add_image`), stored Dockerfiles
|
|
281
|
-
(`add_image_dockerfile`), and refs currently in use on sandboxes. `list_images` and `get_image`
|
|
282
|
-
cover the same catalog family as those add tools — each org row includes `kind`, a redacted
|
|
283
|
-
`manifest` (from `ghostdock.*` Docker/OCI labels), `requiredEnvironment`, and `requiredUrls` (same
|
|
284
|
-
shape as snapshots). `create_sandbox` with `--source '{"type":"image","id":"..."}'` boots a catalog
|
|
285
|
-
row by id and applies its manifest (URLs + env) like an organization snapshot.
|
|
286
|
-
|
|
287
|
-
| Tool | Purpose |
|
|
288
|
-
| --- | --- |
|
|
289
|
-
| `list_images` | Discovery catalog (not an allowlist): platform bases, bookmarks, Dockerfiles, in-use refs. |
|
|
290
|
-
| `get_image` | One catalog row by id (OCI bookmark or Dockerfile from `list_images`). |
|
|
291
|
-
| `add_image` | Bookmark an OCI ref; best-effort inspect caches label manifest. |
|
|
292
|
-
| `add_image_dockerfile` | Store a Dockerfile; parses `ghostdock.*` LABEL lines into cached manifest. |
|
|
293
|
-
| `update_image_dockerfile` | Replace Dockerfile text and re-parse manifest. |
|
|
294
|
-
| `remove_image` | Delete a catalog row by id. |
|
|
295
|
-
|
|
296
|
-
```bash
|
|
297
|
-
ghostdock list_images --organization-id org_123
|
|
298
|
-
ghostdock get_image --organization-id org_123 --image-id img_abc
|
|
299
|
-
ghostdock add_image --organization-id org_123 --ref ghcr.io/acme/app:latest --label "Acme app"
|
|
300
|
-
ghostdock add_image_dockerfile --organization-id org_123 --name my-stack --dockerfile "$(cat Dockerfile)"
|
|
301
|
-
ghostdock create_sandbox --organization-id org_123 \
|
|
302
|
-
--source '{"type":"image","id":"img_abc"}' \
|
|
303
|
-
--environment '{"local":[{"name":"API_KEY","kind":"secret","value":"sk_test"}]}'
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
Booting with `--source '{"type":"dockerfile","content":"..."}'` parses labels inline without
|
|
307
|
-
persisting a catalog row. That JSON source is Dockerfile text only: COPY/ADD of local files fails.
|
|
308
|
-
`--source '{"type":"compose","files":{"compose.yaml":"..."}}'` boots Docker-in-Docker from those
|
|
309
|
-
inline files (must include `docker-compose.yml`/`yaml` or `compose.yml`/`yaml`) and runs
|
|
310
|
-
`docker compose up`; `ghostdock.*` service labels become the create-time manifest. A directory or
|
|
311
|
-
ZIP — Dockerfile build context, or a Compose project with extra files — is
|
|
312
|
-
[`ghostdock sandbox_create`](#ghostdock-sandbox_create), not this command. Any OCI ref may still
|
|
313
|
-
be passed as `{ type: "image", ref }` even when it does not appear in `list_images`. Catalog compose
|
|
314
|
-
rows still boot via `{ type: "image", id }`.
|
|
315
|
-
|
|
316
|
-
### `ghostdock publish_static`
|
|
317
|
-
|
|
318
|
-
Publish a local directory or ZIP to the CDN (durable public URL, no sandbox):
|
|
319
|
-
|
|
320
|
-
```bash
|
|
321
|
-
ghostdock publish_static --organization-id org_123 ./dist
|
|
322
|
-
ghostdock publish_static --organization-id org_123 --zip ./site.zip
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
MCP `publish_static` is for small inline payloads. Use this command for a real directory or large ZIP.
|
|
326
|
-
|
|
327
|
-
### `ghostdock publish_auto`
|
|
328
|
-
|
|
329
|
-
Inspect a local source tree and publish (CDN when pre-built static, otherwise Compose from a DeploymentSpec).
|
|
330
|
-
Required secrets without values return `awaiting_configuration` instead of a live URL.
|
|
331
|
-
Re-invoke with `--environment` (same JSON shape as `create_sandbox`) after configuring.
|
|
332
|
-
On `build_failed`, `start_failed`, or `verify_failed`, inspect the kept sandbox (unless verification tore it down), then re-invoke with `--spec` (JSON `DeploymentSpec`). The spec is executed on a fresh sandbox and stored for later replay. Do not pass `--spec` with `--replan`. Every terminal outcome stores the upload and returns authenticated `fileUrls`. Detected tests always run after the stack is up; pass `--require-verify` to refuse a deploy when they fail.
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
ghostdock publish_auto --organization-id org_123 ./app
|
|
336
|
-
ghostdock publish_auto --organization-id org_123 --auto-stop-interval-minutes -1 --zip ./app.zip
|
|
337
|
-
ghostdock publish_auto --organization-id org_123 --project-id proj_123 ./app
|
|
338
|
-
ghostdock publish_auto --organization-id org_123 ./app \
|
|
339
|
-
--environment '{"organization":["DATABASE_URL"],"local":[{"name":"API_KEY","value":"sk_live","kind":"secret"}]}'
|
|
340
|
-
ghostdock publish_auto --organization-id org_123 ./app --spec '{"version":1,"run":{"kind":"static","outputDir":"."},"env":[]}'
|
|
341
|
-
ghostdock publish_auto --organization-id org_123 --require-verify ./app
|
|
342
|
-
ghostdock publish_auto --organization-id org_123 --sandbox-provider-id prov_123 ./app
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
MCP `publish_auto` is for small inline payloads. Use this command for a real directory or large ZIP.
|
|
346
|
-
|
|
347
|
-
### `ghostdock sandbox_create`
|
|
348
|
-
|
|
349
|
-
Create a sandbox from a local Dockerfile or Compose directory. The CLI zips the directory (or sends
|
|
350
|
-
`--zip`) and the server builds it. MCP `create_sandbox` stays inline text only.
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
ghostdock sandbox_create --organization-id org_123 --kind dockerfile ./app
|
|
354
|
-
ghostdock sandbox_create --organization-id org_123 --kind compose --zip ./stack.zip
|
|
355
|
-
ghostdock sandbox_create --organization-id org_123 --kind dockerfile \
|
|
356
|
-
--sandbox-provider-id prov_123 --display-name "API" ./app
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
The Dockerfile (`Dockerfile` or `dockerfile`) or a compose file (`docker-compose.yml`/`yaml`,
|
|
360
|
-
`compose.yml`/`yaml`) must sit at the directory root, or at the root of the ZIP. A ZIP that wraps
|
|
361
|
-
the project in one folder is unwrapped. Pass one directory or `--zip`, not both.
|
|
362
|
-
|
|
363
|
-
### `ghostdock sandbox_upload`
|
|
364
|
-
|
|
365
|
-
`upload_files` is convenient for small payloads. For a local directory,
|
|
366
|
-
multiple files, or a large ZIP, use the dedicated multipart upload command instead:
|
|
367
|
-
|
|
368
|
-
```bash
|
|
369
|
-
ghostdock sandbox_upload --sandbox-id sandbox_123 ./dist
|
|
370
|
-
ghostdock sandbox_upload --sandbox-id sandbox_123 ./index.html ./assets
|
|
371
|
-
ghostdock sandbox_upload --sandbox-id sandbox_123 --zip ./site.zip
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
Each positional path may be a file or directory. Directory contents are uploaded recursively,
|
|
375
|
-
preserving their relative paths; a file is uploaded by its basename. A `sandbox_upload` call needs
|
|
376
|
-
at least one path or `--zip`. Uploading to a stopped sandbox resumes it automatically.
|
|
377
|
-
|
|
378
|
-
### `ghostdock env`
|
|
379
|
-
|
|
380
|
-
Manage the environment variables and secrets an organization offers to its sandboxes and projects.
|
|
381
|
-
A sandbox inherits nothing automatically — select the entries it needs on that sandbox.
|
|
382
|
-
|
|
383
|
-
```bash
|
|
384
|
-
ghostdock env list --organization org_123
|
|
385
|
-
ghostdock env get VITE_API_URL --organization org_123
|
|
386
|
-
ghostdock env set VITE_API_URL --organization org_123 --value https://api.example.com
|
|
387
|
-
ghostdock env delete VITE_API_URL --organization org_123
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**Variables vs secrets.** A variable is readable by anyone who can see the organization; `env list`
|
|
391
|
-
prints its value inline. A secret can be set and replaced but never read back — it shows as
|
|
392
|
-
`<secret>` in `env list` and `env get` refuses it. Pass `--secret` to create one:
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
# Keeps the value out of shell history and the process list
|
|
396
|
-
printf %s "$STRIPE_KEY" | ghostdock env set STRIPE_SECRET_KEY --organization org_123 --secret --value-stdin
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
`--secret` is only required when creating; updating an existing entry keeps its kind. To convert one,
|
|
400
|
-
pass `--kind variable` or `--kind secret` explicitly along with the new value:
|
|
401
|
-
|
|
402
|
-
```bash
|
|
403
|
-
ghostdock env set STRIPE_SECRET_KEY --organization org_123 --kind variable --value not-secret-anymore
|
|
404
|
-
# Warning: STRIPE_SECRET_KEY was a secret and is now a variable — its value is readable by everyone in the organization.
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
Converting never reveals the old secret: `set` always replaces the value, so the value you supply in
|
|
408
|
-
that call is the one that becomes readable. The command prints what changed either way.
|
|
409
|
-
|
|
410
|
-
`env get` prints the bare value so it can be captured in a shell (`API=$(ghostdock env get
|
|
411
|
-
VITE_API_URL --organization org_123)`). It also returns values too large for `env list`, which
|
|
412
|
-
withholds anything over 1024 characters rather than truncating it — a printed value is always the
|
|
413
|
-
complete value.
|
|
414
|
-
|
|
415
|
-
Add `--json` to `list`, `get` or `set` for machine-readable output. These commands wrap the
|
|
416
|
-
`list_environment_variables`, `get_environment_variable`, `set_environment_variable` and
|
|
417
|
-
`delete_environment_variable` tools, which are also available directly (and over MCP).
|
|
418
|
-
|
|
419
|
-
Names must be valid environment variable names, and names the sandbox runtime owns (`PATH`,
|
|
420
|
-
`HOME`, anything starting with `GHOSTDOCK_`, …) are rejected. Prefix a name with `VITE_`
|
|
421
|
-
only when browser code must read it: Vite inlines those into the published bundle, so a `VITE_`
|
|
422
|
-
secret is public.
|
|
423
|
-
|
|
424
|
-
## CLI settings
|
|
425
|
-
|
|
426
|
-
Environment variables read by the CLI process itself. For an organization's environment variables
|
|
427
|
-
and secrets, see [`ghostdock env`](#ghostdock-env).
|
|
428
|
-
|
|
429
|
-
| Variable | Purpose | Default |
|
|
430
|
-
| ------------------------------- | ------------------------------------------------------------- | --------------------------------- |
|
|
431
|
-
| `GHOSTDOCK_BASE_URL` | API origin the CLI talks to. Override for local dev / self-hosted instances. | Local/dev builds default to `http://localhost:3000`. npm-published builds default to the production API origin baked at publish time. Override with `--base-url` or this env var. |
|
|
432
|
-
| `GHOSTDOCK_CREDENTIALS_PATH` | Absolute path to the credentials file, overriding the default. | `./.ghostdock/credentials.json` (relative to the current working directory) |
|
|
433
|
-
|
|
434
|
-
Example for local development against a Nuxt dev server:
|
|
435
|
-
|
|
436
|
-
```bash
|
|
437
|
-
ghostdock --base-url http://localhost:3000 login --wait
|
|
438
|
-
# or
|
|
439
|
-
GHOSTDOCK_BASE_URL=http://localhost:3000 ghostdock login --wait
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
## Credentials file
|
|
443
|
-
|
|
444
|
-
Credentials are stored as JSON at `./.ghostdock/credentials.json` (relative to the directory the
|
|
445
|
-
CLI is run from), with file permissions restricted to the owner (`0600`):
|
|
446
|
-
|
|
447
|
-
```json
|
|
448
|
-
{
|
|
449
|
-
"accessToken": "ext_at_...",
|
|
450
|
-
"refreshToken": "ext_rt_...",
|
|
451
|
-
"accessExpiresAt": "2026-07-30T12:00:00.000Z"
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
**Add `.ghostdock/` to your project's `.gitignore`.** These are live tokens — never commit them.
|
|
456
|
-
This repository's own `.gitignore` already ignores `.ghostdock/` for local development/testing of
|
|
457
|
-
the CLI itself.
|
|
458
|
-
|
|
459
|
-
Access tokens are short-lived (1 hour); the CLI refreshes them automatically using the refresh token
|
|
460
|
-
(30-day rolling expiry) whenever a request gets a `401`. If both tokens are invalid or revoked (e.g.
|
|
461
|
-
after `ghostdock logout` from another session), re-run `ghostdock login`.
|
|
462
|
-
|
|
463
|
-
## Exit codes
|
|
464
|
-
|
|
465
|
-
- `0` — success (including the default `login` after only printing the URL — approval is still
|
|
466
|
-
pending, that's expected).
|
|
467
|
-
- `1` — failure: not logged in, session expired and unrefreshable, login denied/expired/timed out,
|
|
468
|
-
a missing/invalid tool flag, or a tool invocation error (e.g. not a member of the organization).
|