@groundfloorcloud/cli 0.1.0 → 0.1.2
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/README.md +137 -114
- package/dist/index.js +1090 -30
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
# `@groundfloorcloud/cli` (`gf`)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
scripts, or any app). It works like `vercel login`: run `gf login` once, the
|
|
6
|
-
browser opens, you sign in, and the session is cached and auto-refreshed.
|
|
3
|
+
Sign in to Groundfloor, manage workspaces, and work with Coderunner,
|
|
4
|
+
secrets, files, apps, and Dataplane from your terminal.
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
`gf login` opens a browser, you sign in, and the session is cached and
|
|
7
|
+
refreshed automatically.
|
|
8
|
+
|
|
9
|
+
Agents in Cursor use [`@groundfloorcloud/mcp`](../mcp/README.md) against the
|
|
10
|
+
same `gf login` session to inspect the workspace and docs, then run `gf`
|
|
11
|
+
commands to take action.
|
|
13
12
|
|
|
14
13
|
## Install
|
|
15
14
|
|
|
@@ -18,85 +17,66 @@ npm i -g @groundfloorcloud/cli
|
|
|
18
17
|
gf login
|
|
19
18
|
```
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
Without a global install:
|
|
22
21
|
|
|
23
22
|
```bash
|
|
24
23
|
npx @groundfloorcloud/cli login
|
|
25
24
|
```
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
npm install
|
|
31
|
-
npm run build --workspace=@groundfloorcloud/cli
|
|
32
|
-
npm link --workspace=@groundfloorcloud/cli # then: gf --help
|
|
33
|
-
```
|
|
26
|
+
Requires Node.js 20 or later. `gf login` signs in to production
|
|
27
|
+
(`https://platform.groundfloor.cloud`). Use `--dev` or `--stage` for
|
|
28
|
+
other cells; later commands reuse that session.
|
|
34
29
|
|
|
35
30
|
## Quick start
|
|
36
31
|
|
|
37
32
|
```bash
|
|
38
|
-
gf login
|
|
39
|
-
gf
|
|
40
|
-
gf
|
|
41
|
-
gf
|
|
42
|
-
gf
|
|
33
|
+
gf login # production
|
|
34
|
+
gf login --stage
|
|
35
|
+
gf login --dev
|
|
36
|
+
gf whoami
|
|
37
|
+
gf workspaces
|
|
38
|
+
gf workspaces use <uuid>
|
|
39
|
+
gf coderunner ls
|
|
40
|
+
gf deploy
|
|
43
41
|
```
|
|
44
42
|
|
|
45
|
-
Use the session from
|
|
43
|
+
Use the session from a shell or script:
|
|
46
44
|
|
|
47
45
|
```bash
|
|
48
|
-
eval "$(gf env)"
|
|
46
|
+
eval "$(gf env)"
|
|
49
47
|
curl -H "Authorization: Bearer $(gf token)" \
|
|
50
|
-
"$CONTROLPLANE_URL/v1/workspaces"
|
|
48
|
+
"$CONTROLPLANE_URL/v1/workspaces"
|
|
51
49
|
```
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
agent) need a fresh token to call CP APIs during development.
|
|
51
|
+
## Deploy workloads
|
|
55
52
|
|
|
56
|
-
|
|
53
|
+
`gf deploy` packages your code and runs the full Coderunner lifecycle:
|
|
54
|
+
create if needed, upload a version, wait for the build, deploy, poll until
|
|
55
|
+
complete, and print IDs and the URL.
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
`gf deploy` packages your code and runs the full lifecycle: create the
|
|
63
|
-
coderunner if it does not exist, upload a new version, wait for the build,
|
|
64
|
-
deploy, **poll deployment until Completed**, and print IDs/URL.
|
|
57
|
+
Do not create an App just to run a function, job, schedule, or service.
|
|
58
|
+
Use `gf deploy`. Bind `--app-id` only when the coderunner should be a helper
|
|
59
|
+
of an existing product App.
|
|
65
60
|
|
|
66
61
|
```bash
|
|
67
|
-
# Deploy the current folder (zips the working tree, honoring .gitignore)
|
|
68
62
|
gf deploy
|
|
69
|
-
|
|
70
|
-
# Deploy a remote git/bitbucket repo (upload description includes git_sha=…)
|
|
71
63
|
gf deploy --git https://github.com/me/my-fn.git --ref main
|
|
72
|
-
|
|
73
|
-
# Override target + resources + env
|
|
74
64
|
gf deploy --name my-fn --runtime python --cpu 250m --memory 256Mi \
|
|
75
|
-
-e API_KEY=secret
|
|
76
|
-
|
|
77
|
-
# Bind a newly created coderunner as a helper of an App (optional)
|
|
65
|
+
-e API_KEY=secret
|
|
78
66
|
gf deploy --app-id <app-uuid>
|
|
79
67
|
```
|
|
80
68
|
|
|
81
|
-
**Server push-to-deploy:** connect a repo on the coderunner **Git source** card
|
|
82
|
-
(or `PUT …/coderunners/{id}/git-source`). Point GitHub/Gitea at
|
|
83
|
-
`POST /v1/webhooks/git/{source_id}` with the returned webhook secret. Private
|
|
84
|
-
repos use a workspace Secret named in `secret_key`. App creation is not required.
|
|
85
|
-
|
|
86
69
|
How the target is chosen:
|
|
87
70
|
|
|
88
|
-
- `--coderunner <id>` deploys into that
|
|
71
|
+
- `--coderunner <id>` deploys into that coderunner.
|
|
89
72
|
- Otherwise the name comes from `--name`, then `groundfloor.json`, then the
|
|
90
|
-
folder
|
|
91
|
-
|
|
73
|
+
folder or repo name. A matching slug is reused; otherwise a new coderunner
|
|
74
|
+
is created.
|
|
92
75
|
|
|
93
|
-
Runtime is auto-detected when
|
|
94
|
-
`requirements.txt
|
|
76
|
+
Runtime is auto-detected when omitted (`package.json` → node,
|
|
77
|
+
`requirements.txt` / `pyproject.toml` → python), defaulting to python.
|
|
95
78
|
|
|
96
|
-
###
|
|
97
|
-
|
|
98
|
-
Drop a `groundfloor.json` in your project root to set defaults (CLI flags still
|
|
99
|
-
win):
|
|
79
|
+
### `groundfloor.json`
|
|
100
80
|
|
|
101
81
|
```json
|
|
102
82
|
{
|
|
@@ -109,13 +89,13 @@ win):
|
|
|
109
89
|
}
|
|
110
90
|
```
|
|
111
91
|
|
|
112
|
-
###
|
|
92
|
+
### Deploy flags
|
|
113
93
|
|
|
114
94
|
| Flag | Description |
|
|
115
95
|
|------|-------------|
|
|
116
|
-
| `-w, --workspace <id>` | Workspace override (else
|
|
117
|
-
| `-p, --path <dir>` |
|
|
118
|
-
| `--git <url>` / `--ref <ref>` | Clone and deploy a remote repo
|
|
96
|
+
| `-w, --workspace <id>` | Workspace override (else `gf workspaces use`). |
|
|
97
|
+
| `-p, --path <dir>` | Directory to package (default: cwd). |
|
|
98
|
+
| `--git <url>` / `--ref <ref>` | Clone and deploy a remote repo. |
|
|
119
99
|
| `--subdir <dir>` | Package a subdirectory of the source. |
|
|
120
100
|
| `--runtime <r>` | `python` \| `node` \| `dotnet-script`. |
|
|
121
101
|
| `--workload-type <t>` | `function` \| `service` \| `job` \| `schedule`. |
|
|
@@ -124,36 +104,100 @@ win):
|
|
|
124
104
|
| `-m, --message <text>` | Version description. |
|
|
125
105
|
| `--skip-deploy` | Upload a new version but do not deploy it. |
|
|
126
106
|
|
|
107
|
+
## Publish a Shell app
|
|
108
|
+
|
|
109
|
+
Product **Apps** are packaging (Shell Module Federation remotes, or a
|
|
110
|
+
standalone wrapper around a service). That is separate from `gf deploy`.
|
|
111
|
+
|
|
112
|
+
**Always start from the official starter-kit.** Do not scaffold `App.tsx` or
|
|
113
|
+
put `BrowserRouter` in the federated export — that crashes the Shell.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
gf apps init --slug my-federated-app
|
|
117
|
+
cd my-federated-app
|
|
118
|
+
gf apps create --name "My Federated App" --slug my-federated-app \
|
|
119
|
+
--manifest ./groundfloor.manifest.json
|
|
120
|
+
npm install
|
|
121
|
+
npm run release
|
|
122
|
+
gf apps publish --path release.zip
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`gf apps init` downloads the public ZIP from the Customer Portal
|
|
126
|
+
(`/downloads/shell-starter-kit.zip` on the current cell) and stamps
|
|
127
|
+
`APP_ID` / `groundfloor.manifest.json` `appId` to the slug.
|
|
128
|
+
|
|
129
|
+
`gf apps publish` uploads `release.zip` (or `remoteEntry.js`), flattens a
|
|
130
|
+
Vite `dist/assets/` layout so chunks sit next to `remoteEntry.js`, finalizes
|
|
131
|
+
the release, and by default PATCHes the Portal manifest from
|
|
132
|
+
`groundfloor.manifest.json` next to the bundle. Pass an app id/slug, or set
|
|
133
|
+
`appId` in that manifest. Prefer `npm run release` over zipping `dist/` by hand.
|
|
134
|
+
|
|
135
|
+
Wrap an existing **service** coderunner as a product:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
gf apps create --kind standalone --name "My Product" --slug my-product \
|
|
139
|
+
--primary-coderunner <coderunner-id>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Do not create `app_kind=coderunner`. Functions, jobs, schedules, and services
|
|
143
|
+
use `gf deploy`.
|
|
144
|
+
|
|
145
|
+
## Secrets, files, Dataplane
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
gf dataplane status
|
|
149
|
+
gf dataplane provision
|
|
150
|
+
|
|
151
|
+
gf secrets ls
|
|
152
|
+
gf secrets set DATABASE_URL 'postgres://…'
|
|
153
|
+
gf secrets get DATABASE_URL
|
|
154
|
+
gf secrets rm DATABASE_URL
|
|
155
|
+
|
|
156
|
+
gf files ls
|
|
157
|
+
gf files upload ./report.pdf
|
|
158
|
+
gf files download <file-id> -o ./report.pdf
|
|
159
|
+
gf files rm <file-id>
|
|
160
|
+
|
|
161
|
+
gf apps ls
|
|
162
|
+
gf apps get <id|slug>
|
|
163
|
+
```
|
|
164
|
+
|
|
127
165
|
## Commands
|
|
128
166
|
|
|
129
167
|
| Command | Description |
|
|
130
168
|
|---------|-------------|
|
|
131
|
-
| `gf login [--device]` | Browser
|
|
169
|
+
| `gf login [--dev\|--stage] [--device]` | Browser sign-in (production default). |
|
|
132
170
|
| `gf logout` | Clear the cached session. |
|
|
133
|
-
| `gf whoami` | Show identity and verify the
|
|
134
|
-
| `gf token` | Print a fresh
|
|
135
|
-
| `gf env` | Print `export
|
|
171
|
+
| `gf whoami` | Show identity and verify the Control Plane session. |
|
|
172
|
+
| `gf token` | Print a fresh access token. |
|
|
173
|
+
| `gf env` | Print `export …` lines for `eval "$(gf env)"`. |
|
|
136
174
|
| `gf workspaces` (`ws`) | List workspaces; `gf workspaces use <id>` sets the default. |
|
|
137
|
-
| `gf coderunner ls` (`cr ls`) | List coderunners
|
|
138
|
-
| `gf coderunner status -c <id\|slug>` | Status
|
|
139
|
-
| `gf coderunner run -c <id\|slug> [--payload '{}']` |
|
|
140
|
-
| `gf deploy` | Package code
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
175
|
+
| `gf coderunner ls` (`cr ls`) | List coderunners. |
|
|
176
|
+
| `gf coderunner status -c <id\|slug>` | Status and current deployment. |
|
|
177
|
+
| `gf coderunner run -c <id\|slug> [--payload '{}']` | Invoke a deployed function or job. |
|
|
178
|
+
| `gf deploy` | Package code and deploy as a coderunner. |
|
|
179
|
+
| `gf domains ls\|add\|rm\|verify -c <id\|slug>` | Custom domains for a service. |
|
|
180
|
+
| `gf secrets ls\|get\|set\|rm` | Workspace secrets. |
|
|
181
|
+
| `gf files ls\|upload\|download\|rm` | Workspace files. |
|
|
182
|
+
| `gf apps init --slug <slug>` | Download the official Shell starter-kit and stamp APP_ID. |
|
|
183
|
+
| `gf apps ls\|get\|create\|publish` | Product apps (Shell publish / standalone wrap). |
|
|
184
|
+
| `gf dataplane status\|provision` | Dataplane setup for the workspace. |
|
|
146
185
|
|
|
147
186
|
## Configuration
|
|
148
187
|
|
|
149
|
-
Settings resolve
|
|
150
|
-
|
|
188
|
+
Settings resolve as: command flags > environment > `~/.groundfloor/config.json`
|
|
189
|
+
> Groundfloor production.
|
|
151
190
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
191
|
+
`gf login` with no cell flag **always** uses production, even if a previous
|
|
192
|
+
`--dev` / `--stage` session is still in `config.json`. Pass `--dev`, `--stage`,
|
|
193
|
+
or `--env <production|stage|dev>` to pick another cell. `--api-url` / `--issuer`
|
|
194
|
+
still override the hosts for that login.
|
|
195
|
+
|
|
196
|
+
| Setting | Flag | Env | Production default |
|
|
197
|
+
|---------|------|-----|--------------------|
|
|
198
|
+
| Control Plane URL | `--api-url` | `GROUNDFLOOR_API_URL` | `https://platform.groundfloor.cloud` |
|
|
199
|
+
| IdP issuer | `--issuer` | `GROUNDFLOOR_ISSUER` | Groundfloor managed IdP |
|
|
155
200
|
| OIDC client id | `--client-id` | `GROUNDFLOOR_CLIENT_ID` | `groundfloor-cli` |
|
|
156
|
-
| Control Plane URL | `--api-url` | `GROUNDFLOOR_API_URL` | `http://localhost:8088` |
|
|
157
201
|
| Default workspace | (via `gf workspaces use`) | `GROUNDFLOOR_WORKSPACE_ID` | (none) |
|
|
158
202
|
|
|
159
203
|
State is stored under `~/.groundfloor/`:
|
|
@@ -161,41 +205,20 @@ State is stored under `~/.groundfloor/`:
|
|
|
161
205
|
- `auth.json` — cached tokens (chmod `600`).
|
|
162
206
|
- `config.json` — non-secret defaults (issuer, client id, api url, workspace).
|
|
163
207
|
|
|
164
|
-
|
|
165
|
-
later commands match the login.
|
|
166
|
-
|
|
167
|
-
## Identity provider setup (one-time)
|
|
168
|
-
|
|
169
|
-
`gf` needs a **public** OIDC client (default id `groundfloor-cli`) with:
|
|
170
|
-
|
|
171
|
-
- Standard Flow enabled, PKCE method `S256`.
|
|
172
|
-
- Valid redirect URIs covering the loopback callback. The CLI redirects to
|
|
173
|
-
`http://127.0.0.1:<port>/callback`, so configure **both**:
|
|
174
|
-
- `http://127.0.0.1/*`
|
|
175
|
-
- `http://localhost/*`
|
|
176
|
-
- Optionally, OAuth 2.0 Device Authorization Grant enabled for `gf login --device`.
|
|
177
|
-
|
|
178
|
-
Then add the client id to the Control Plane `KEYCLOAK_AUDIENCE`
|
|
179
|
-
(see `.env.example`) so its tokens verify. The CLI user still needs workspace
|
|
180
|
-
membership in the Portal for workspace-scoped routes.
|
|
181
|
-
|
|
182
|
-
### Redirect URI mismatch ("Invalid parameter: redirect_uri")
|
|
183
|
-
|
|
184
|
-
This means the client's Valid Redirect URIs do not match the loopback URL the
|
|
185
|
-
CLI sends. Options:
|
|
208
|
+
### Redirect URI mismatch
|
|
186
209
|
|
|
187
|
-
|
|
188
|
-
-
|
|
189
|
-
- If wildcard/port matching is restrictive, pin an exact URI: register
|
|
190
|
-
`http://127.0.0.1:8976/callback` on the client and run
|
|
191
|
-
`gf login --redirect-port 8976`.
|
|
210
|
+
`gf login` uses a loopback callback (`http://127.0.0.1:<port>/callback`). If
|
|
211
|
+
sign-in fails with an invalid redirect URI:
|
|
192
212
|
|
|
193
|
-
|
|
213
|
+
- Prefer `127.0.0.1` (the CLI default).
|
|
214
|
+
- If your identity provider only allows `localhost`, run
|
|
215
|
+
`gf login --redirect-host localhost`.
|
|
216
|
+
- To pin a port: `gf login --redirect-port 8976`.
|
|
194
217
|
|
|
195
|
-
|
|
196
|
-
- Phase 2: `gf deploy` for local folders and remote git/bitbucket repos. The CLI
|
|
197
|
-
packages the code into a ZIP and drives the Control Plane create -> upload ->
|
|
198
|
-
build -> deploy lifecycle (upstream Code Runner is ZIP-based).
|
|
218
|
+
## More
|
|
199
219
|
|
|
200
|
-
|
|
201
|
-
|
|
220
|
+
- [Customer Portal](https://app.groundfloor.cloud)
|
|
221
|
+
- [Developers](https://docs.groundfloor.cloud/docs/customer-portal/developers)
|
|
222
|
+
- [Deploy with agents](https://docs.groundfloor.cloud/docs/customer-portal/agents)
|
|
223
|
+
- [Coderunner](https://docs.groundfloor.cloud/docs/customer-portal/coderunner)
|
|
224
|
+
- [API authentication](https://docs.groundfloor.cloud/docs/api/authentication)
|