@gapi/gcli 1.8.247 → 1.8.249

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 CHANGED
@@ -92,6 +92,10 @@ This repo is documentation-driven. With every change:
92
92
  3. **Skills / AGENTS.md** - learned something non-obvious, or a workflow
93
93
  bit you? Update the owning skill (`.agents/skills/<name>/SKILL.md`) or
94
94
  this file in the same change.
95
+ 4. **User docs + What's new** - a change users can see or do also updates
96
+ gql-fission's public docs page (`gql-fission/src/docs/<slug>.md`) and adds a
97
+ line to `gql-fission/src/app/changelog/releases.ts`. Skill:
98
+ `user-docs-and-changelog` in gql-fission.
95
99
 
96
100
  Before working on an existing feature: `node scripts/changelog.mjs render
97
101
  --feature <slug>` + its feature doc. That is where "how to test" and "how
package/README-CLI.md CHANGED
@@ -33,7 +33,7 @@ Commands:
33
33
  mq-trigger:create [options] Run a lambda for every message on a RabbitMQ queue
34
34
  mq-trigger:update [options] Change a message-queue trigger (same flags as create)
35
35
  mq-trigger:delete [options] Delete a message-queue trigger
36
- cluster:create [options] Provision a private Talos cluster for a project (runs in the background - takes several minutes; use --wait to block)
36
+ cluster:create [options] Provision a private Talos cluster, or with --virtual a virtual cluster, for a project (runs in the background; use --wait to block)
37
37
  cluster:apply [options] Make a private cluster match the `cluster:` section of lambforge.yaml: creates it if missing, then applies topology, workers, control planes, load balancer and autoscaling
38
38
  cluster:list [options] List every private cluster this project has (it may have several - dev/stage/prod, ...)
39
39
  cluster:teardown [options] Tear down one of a project's clusters (runs in the background - use --wait to block)
@@ -47,7 +47,7 @@ Commands:
47
47
  cluster:autoscale [options] Change the worker autoscaling policy - only the flags you pass change
48
48
  cluster:multi-node [options] Convert a single-node cluster to dedicated worker nodes (required for autoscaling)
49
49
  cluster:single-node [options] Convert a multi-node cluster back to a single node (removes the worker nodes)
50
- cluster:load-balancer [options] Add or remove the cluster's load balancer (billed per hour while enabled)
50
+ cluster:load-balancer [options] Add or remove the cluster's load balancer (billed per hour while enabled). On a virtual cluster this is its dedicated LB - its own IP; the platform subdomain keeps working either way
51
51
  rabbitmq:create [options] Provision a RabbitMQ broker for a project (a project may have several)
52
52
  rabbitmq:list [options] List every RabbitMQ broker for a project
53
53
  rabbitmq:delete [options] Delete a RabbitMQ broker
@@ -594,7 +594,7 @@ Options:
594
594
  --- Subcommand: cluster:create ---
595
595
  Usage: gcli cluster:create [options]
596
596
 
597
- Provision a private Talos cluster for a project (runs in the background - takes several minutes; use --wait to block)
597
+ Provision a private Talos cluster, or with --virtual a virtual cluster, for a project (runs in the background; use --wait to block)
598
598
 
599
599
  Options:
600
600
  -p, --project <project>
@@ -605,6 +605,14 @@ Options:
605
605
  -l, --location <location>
606
606
  --workers <workers> Worker count (ignored when --singleNode)
607
607
  --singleNode Control plane carries the workload too
608
+ --virtual A virtual cluster (own Kubernetes API + Fission,
609
+ no servers, ~2 minutes) instead of a private Talos
610
+ cluster
611
+ --host <host> With --virtual: name of a private cluster of this
612
+ project to run on (default: the shared cluster)
613
+ --dedicated-lb With --virtual: give its router its own load
614
+ balancer IP (billed per hour); without it lambdas
615
+ are served on the platform subdomain
608
616
  --wait Block until the cluster is ready (or errors)
609
617
  -h, --help display help for command
610
618
  
@@ -770,7 +778,7 @@ Options:
770
778
  --- Subcommand: cluster:load-balancer ---
771
779
  Usage: gcli cluster:load-balancer [options]
772
780
 
773
- Add or remove the cluster's load balancer (billed per hour while enabled)
781
+ Add or remove the cluster's load balancer (billed per hour while enabled). On a virtual cluster this is its dedicated LB - its own IP; the platform subdomain keeps working either way
774
782
 
775
783
  Options:
776
784
  -p, --project <project>
package/README.md CHANGED
@@ -211,6 +211,42 @@ Steps that remove capacity or release the load balancer's IP (going back to
211
211
  `singleNode: true`, `loadBalancer: false`) are skipped unless you pass
212
212
  `--yes`. Nodes and the load balancer are billed per started hour.
213
213
 
214
+ #### Virtual clusters
215
+
216
+ A virtual cluster has its own Kubernetes API and Fission but no servers: it
217
+ runs in one namespace of the shared Lambforge cluster, or of one of your
218
+ private clusters, and is ready in about two minutes. Everything else
219
+ (environments, lambdas, `--clusterName`, `cluster:kubeconfig`,
220
+ `cluster:teardown`) works the same as for a private cluster; scaling
221
+ commands don't apply.
222
+
223
+ Its lambdas are served on a platform subdomain (`https://vc-<id>.lambforge.com`,
224
+ shown in the `router` column of `cluster:list`) at no extra cost. A
225
+ **dedicated load balancer** gives its router an IP of its own, billed per
226
+ started hour like any load balancer; the subdomain keeps working.
227
+ `cluster:kubeconfig` gives you admin access through
228
+ `https://k-<id>.lambforge.com` (the `api` column).
229
+
230
+ ```bash
231
+ gcli cluster:create --virtual --name dev # on the shared cluster
232
+ gcli cluster:create --virtual --name stage --host prod # on your private cluster "prod"
233
+ gcli cluster:create --virtual --name demo --dedicated-lb # with its own IP
234
+ gcli cluster:load-balancer --cluster <id> --enable # add the dedicated LB later
235
+ gcli cluster:load-balancer --cluster <id> --disable # release it (subdomain stays)
236
+ ```
237
+
238
+ ```yaml
239
+ cluster:
240
+ name: dev
241
+ provider: vcluster
242
+ host: prod # optional - omitted = the shared cluster
243
+ loadBalancer: true # optional - dedicated LB; cluster:apply adds/removes it
244
+ ```
245
+
246
+ `cluster:apply` creates the virtual cluster (with the load balancer if set)
247
+ and later adds or removes the dedicated load balancer when `loadBalancer`
248
+ changes; removing it is skipped unless you pass `--yes`.
249
+
214
250
  ### RabbitMQ Brokers
215
251
 
216
252
  A project may have several RabbitMQ brokers, each optionally scoped to one of its private clusters.
@@ -0,0 +1,18 @@
1
+ ## 2026-10-27 - virtual-clusters: cluster:create --virtual and provider vcluster in cluster:apply
2
+
3
+ **Feature:** virtual-clusters · **Type:** feat
4
+
5
+ - `cluster:create --virtual [--host <private-cluster-name>]` and, in the
6
+ `cluster:` section, `provider: vcluster` + `host:` (both read by
7
+ `cluster:create` and `cluster:apply`). The host is resolved by name
8
+ (`helpers/virtual-cluster.ts`); no host = the shared cluster.
9
+ `cluster:apply` only creates a virtual cluster - nothing else to reconcile;
10
+ `validateDesired` rejects node settings on it and `host` without it.
11
+ - `GraphqlClienAPI.provisionProjectVirtualCluster` selects `routerUrl` and
12
+ `hostNamespace` itself (not in `ClusterFragment`, so older servers keep
13
+ working). Canonical doc: `graphql-server-functions/docs/features/virtual-clusters.md`.
14
+ - **Test:** `npx jest --coverage=false test/cluster-apply`.
15
+ - **Debug:** `No cluster named "<host>"` = the host name is not a live
16
+ cluster of the project (`gcli cluster:list`).
17
+ - **Verification:** jest 118/118 (4 new), tsc + eslint clean. README-CLI.md
18
+ not regenerated (needs a build of release/index.js).
@@ -0,0 +1,23 @@
1
+ ## 2026-10-28 - virtual-clusters: cluster:create --dedicated-lb, loadBalancer for virtual clusters, cluster:list URLs
2
+
3
+ **Feature:** virtual-clusters · **Type:** feat
4
+
5
+ - `cluster:create --virtual --dedicated-lb` -> provisionProjectVirtualCluster
6
+ `dedicatedLoadBalancer`; `lambforge.yaml` `loadBalancer: true` on a
7
+ `provider: vcluster` cluster is now accepted (no longer in
8
+ VIRTUAL_UNSUPPORTED): created with it, later added/removed by
9
+ `cluster:apply` (removal = destructive, `--yes`).
10
+ - `cluster:load-balancer` help explains the virtual case (dedicated LB, the
11
+ subdomain stays) - the backend already handles vClusters.
12
+ - `cluster:list`: type, router (lambda URL), api, loadBalancer columns;
13
+ `ClusterFragment` + `routerUrl withLoadBalancer loadBalancerIp`.
14
+ - README virtual-clusters section, README-CLI regenerated (it was also
15
+ missing --virtual/--host), public docs gcli page + What's new.
16
+ - **Test:** `npx jest --coverage=false test/cluster-apply` (plan: create
17
+ with LB in one step, add, destructive remove; command: spec ->
18
+ `dedicatedLoadBalancer: true`).
19
+ - **Debug:** `gcli cluster:apply --dry-run` prints the planned LB step;
20
+ `cluster:list` shows `loadBalancer` pending while the re-apply runs.
21
+ - **Verification:** 119/119 tests, tsc clean, eslint clean; built CLI shows
22
+ `--dedicated-lb` in `cluster:create --help`. Not run against a live
23
+ server (gcli is logged into production).
@@ -36,3 +36,4 @@ Outline (drop sections that don't apply):
36
36
  | `dedicated-platform-cluster` | [dedicated-platform-cluster.md](dedicated-platform-cluster.md) | `cluster:status/health/scale/autoscale/...` commands; canonical doc in lambforge-agent |
37
37
  | `ci-token-scopes` | [ci-token-scopes.md](ci-token-scopes.md) | Which permission each command needs; `mq-trigger:*` commands; canonical doc in graphql-server |
38
38
  | `workflows` | [workflows.md](workflows.md) | `workflow:*` commands incl. AI drafts (`workflow:generate`); canonical doc in graphql-server-lambdas |
39
+ | `virtual-clusters` | [virtual-clusters.md](virtual-clusters.md) | cluster:create --virtual, provider: vcluster (slice; canonical in graphql-server-functions) |
@@ -0,0 +1,26 @@
1
+ # Virtual clusters (slice)
2
+
3
+ **Status:** in production since 2026-10-28 (shared cluster host, subdomain routing, dedicated LB add-on, token kubeconfig). Feature slug `virtual-clusters`.
4
+ Canonical doc (how it works, test, debug, limits):
5
+ [`graphql-server-functions/docs/features/virtual-clusters.md`](../../../../../graphql-server-functions/docs/features/virtual-clusters.md).
6
+
7
+ Virtual clusters are vClusters (own Kubernetes API + Fission) on the shared
8
+ cluster or one of the project's private clusters, `provider: 'vcluster'`.
9
+
10
+ ## This repo
11
+
12
+ - `gcli cluster:create --virtual [--host <private-cluster>] [--dedicated-lb]`;
13
+ in `lambforge.yaml`: `cluster: { name: dev, provider: vcluster, host: prod,
14
+ loadBalancer: true }` for `cluster:create` / `cluster:apply` (no host =
15
+ shared cluster; node settings are rejected).
16
+ - `loadBalancer` on a virtual cluster = its **dedicated** LB (own IP,
17
+ billed). `cluster:apply` creates with it in one step, later adds/removes it
18
+ (removal is destructive -> needs `--yes`); `cluster:load-balancer
19
+ --enable|--disable` does the same by hand (the backend routes
20
+ enable/disableLoadBalancerProjectCluster to the vCluster re-apply).
21
+ - `cluster:list` columns: `type`, `router` (lambda base URL, the
22
+ `vc-<id>` subdomain), `api` (endpoint - `k-<id>` for vClusters on the
23
+ shared host), `loadBalancer` (IP / pending / off). `ClusterFragment`
24
+ selects `routerUrl withLoadBalancer loadBalancerIp`.
25
+ - Code: `src/commands/cluster/helpers/virtual-cluster.ts`, `helpers/plan.ts`,
26
+ `create.ts`, `apply.ts`, `list.ts`. Test: `npx jest --coverage=false test/cluster-apply`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gapi/gcli",
3
- "version": "1.8.247",
3
+ "version": "1.8.249",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/Stradivario/gapi.git"