@gapi/gcli 1.8.240 → 1.8.241
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/skills/cluster-targeting/SKILL.md +23 -0
- package/README-CLI.md +153 -0
- package/README.md +128 -11
- package/docs/changelog.d/2026-10-19-dedicated-platform-cluster-cluster-scaling-topology-load-balancer-and-health-commands-c.md +31 -0
- package/docs/changelog.d/2026-10-19-lambforge-agent-skill-readme-points-to-the-lambforge-agent-skill-gcli-mcp-start-fo.md +17 -0
- package/docs/changelog.d/2026-10-19-repo-cron-create-honours-cron-triggername-readme-brought-up-to-da.md +21 -0
- package/docs/features/README.md +2 -0
- package/docs/features/dedicated-platform-cluster.md +70 -0
- package/docs/features/lambforge-agent-skill.md +22 -0
- package/package.json +1 -1
- package/release/index.js +1918 -785
|
@@ -68,3 +68,26 @@ shared with or generated from gql-fission's copy.
|
|
|
68
68
|
`jest.config.js` has no `moduleNameMapper` for the `~/` tsconfig path alias
|
|
69
69
|
— new test files must use relative imports (e.g. `'../src/helpers'`), not
|
|
70
70
|
`'~/helpers'`, or the test silently fails to resolve the module.
|
|
71
|
+
|
|
72
|
+
## Managing a private cluster itself (scaling, topology, autoscale)
|
|
73
|
+
|
|
74
|
+
The `cluster:*` commands that change or watch ONE cluster
|
|
75
|
+
(`status`, `health`, `scale-events`, `cost`, `scale`,
|
|
76
|
+
`scale:control-planes`, `multi-node`, `single-node`, `autoscale`,
|
|
77
|
+
`load-balancer`) share `commands/cluster/helpers/cluster-change.ts`:
|
|
78
|
+
`resolveClusterTarget` (`--cluster <id>` or `--clusterName <name>`,
|
|
79
|
+
required), `parseIntOption`, and `runClusterChange` (mutate → print →
|
|
80
|
+
`--wait` via `pollUntilReady`; ending in `error` exits non-zero). Their
|
|
81
|
+
selections and types live in `commands/cluster/types.ts` (newer than the
|
|
82
|
+
hand-kept `@introspection`).
|
|
83
|
+
|
|
84
|
+
`cluster:apply` is the declarative path: the `cluster:` section of
|
|
85
|
+
lambforge.yaml (`ClusterDesired` in `helpers/plan.ts`, also the type of
|
|
86
|
+
`load-spec.ts`'s `cluster`). Keep `planClusterChanges` pure and ordered
|
|
87
|
+
(create | topology → workers → control planes → load balancer →
|
|
88
|
+
autoscale): each step is one background job and the cluster must be
|
|
89
|
+
`ready` before the next. A new cluster setting = a key in `ClusterDesired`,
|
|
90
|
+
a check in `validateDesired`, a step in the plan, a test in
|
|
91
|
+
`test/cluster-apply.spec.ts`, and the README "Declarative clusters" block.
|
|
92
|
+
The server merges partial autoscale input into the stored policy, so the
|
|
93
|
+
plan sends only changed keys.
|
package/README-CLI.md
CHANGED
|
@@ -30,9 +30,20 @@ Commands:
|
|
|
30
30
|
cron:delete [options] Delete cron
|
|
31
31
|
cron:list [options] List of all cron jobs for project
|
|
32
32
|
cluster:create [options] Provision a private Talos cluster for a project (runs in the background - takes several minutes; use --wait to block)
|
|
33
|
+
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
|
|
33
34
|
cluster:list [options] List every private cluster this project has (it may have several - dev/stage/prod, ...)
|
|
34
35
|
cluster:teardown [options] Tear down one of a project's clusters (runs in the background - use --wait to block)
|
|
35
36
|
cluster:kubeconfig [options] Print (or save) a cluster's raw kubeconfig YAML - only available once it's 'ready'
|
|
37
|
+
cluster:status [options] Every cluster's status, agent, nodes, CPU/memory load, autoscaling and open issues (or one with --cluster)
|
|
38
|
+
cluster:health [options] The latest health report of a cluster's agent, with every node
|
|
39
|
+
cluster:scale-events [options] Manual and autoscaler scale history, newest first
|
|
40
|
+
cluster:cost [options] Month-to-date cost and the monthly estimate of the project's private clusters
|
|
41
|
+
cluster:scale [options] Set the number of worker nodes (1-10) of a multi-node cluster - billed per node-hour
|
|
42
|
+
cluster:scale:control-planes [options] Set the number of control-plane nodes (1, 3 or 5)
|
|
43
|
+
cluster:autoscale [options] Change the worker autoscaling policy - only the flags you pass change
|
|
44
|
+
cluster:multi-node [options] Convert a single-node cluster to dedicated worker nodes (required for autoscaling)
|
|
45
|
+
cluster:single-node [options] Convert a multi-node cluster back to a single node (removes the worker nodes)
|
|
46
|
+
cluster:load-balancer [options] Add or remove the cluster's load balancer (billed per hour while enabled)
|
|
36
47
|
rabbitmq:create [options] Provision a RabbitMQ broker for a project (a project may have several)
|
|
37
48
|
rabbitmq:list [options] List every RabbitMQ broker for a project
|
|
38
49
|
rabbitmq:delete [options] Delete a RabbitMQ broker
|
|
@@ -508,6 +519,19 @@ Options:
|
|
|
508
519
|
--wait Block until the cluster is ready (or errors)
|
|
509
520
|
-h, --help display help for command
|
|
510
521
|
[36m
|
|
522
|
+
--- Subcommand: cluster:apply ---[0m
|
|
523
|
+
Usage: gcli cluster:apply [options]
|
|
524
|
+
|
|
525
|
+
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
|
|
526
|
+
|
|
527
|
+
Options:
|
|
528
|
+
-p, --project <project>
|
|
529
|
+
-spec, --spec <spec> Spec file (default: lambforge.yaml / cluster.yaml)
|
|
530
|
+
--dry-run Print the plan, change nothing
|
|
531
|
+
--yes Also apply steps that remove capacity or the load
|
|
532
|
+
balancer IP
|
|
533
|
+
-h, --help display help for command
|
|
534
|
+
[36m
|
|
511
535
|
--- Subcommand: cluster:list ---[0m
|
|
512
536
|
Usage: gcli cluster:list [options]
|
|
513
537
|
|
|
@@ -539,6 +563,135 @@ Options:
|
|
|
539
563
|
-o, --output <output> Write to this file instead of stdout
|
|
540
564
|
-h, --help display help for command
|
|
541
565
|
[36m
|
|
566
|
+
--- Subcommand: cluster:status ---[0m
|
|
567
|
+
Usage: gcli cluster:status [options]
|
|
568
|
+
|
|
569
|
+
Every cluster's status, agent, nodes, CPU/memory load, autoscaling and open issues (or one with --cluster)
|
|
570
|
+
|
|
571
|
+
Options:
|
|
572
|
+
-p, --project <project>
|
|
573
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
574
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
575
|
+
-h, --help display help for command
|
|
576
|
+
[36m
|
|
577
|
+
--- Subcommand: cluster:health ---[0m
|
|
578
|
+
Usage: gcli cluster:health [options]
|
|
579
|
+
|
|
580
|
+
The latest health report of a cluster's agent, with every node
|
|
581
|
+
|
|
582
|
+
Options:
|
|
583
|
+
-p, --project <project>
|
|
584
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
585
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
586
|
+
-h, --help display help for command
|
|
587
|
+
[36m
|
|
588
|
+
--- Subcommand: cluster:scale-events ---[0m
|
|
589
|
+
Usage: gcli cluster:scale-events [options]
|
|
590
|
+
|
|
591
|
+
Manual and autoscaler scale history, newest first
|
|
592
|
+
|
|
593
|
+
Options:
|
|
594
|
+
-p, --project <project>
|
|
595
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
596
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
597
|
+
--limit <limit> How many events (default 20)
|
|
598
|
+
-h, --help display help for command
|
|
599
|
+
[36m
|
|
600
|
+
--- Subcommand: cluster:cost ---[0m
|
|
601
|
+
Usage: gcli cluster:cost [options]
|
|
602
|
+
|
|
603
|
+
Month-to-date cost and the monthly estimate of the project's private clusters
|
|
604
|
+
|
|
605
|
+
Options:
|
|
606
|
+
-p, --project <project>
|
|
607
|
+
-h, --help display help for command
|
|
608
|
+
[36m
|
|
609
|
+
--- Subcommand: cluster:scale ---[0m
|
|
610
|
+
Usage: gcli cluster:scale [options]
|
|
611
|
+
|
|
612
|
+
Set the number of worker nodes (1-10) of a multi-node cluster - billed per node-hour
|
|
613
|
+
|
|
614
|
+
Options:
|
|
615
|
+
-p, --project <project>
|
|
616
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
617
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
618
|
+
--workers <workers> Worker nodes, 1-10
|
|
619
|
+
--wait Block until the cluster settles
|
|
620
|
+
-h, --help display help for command
|
|
621
|
+
[36m
|
|
622
|
+
--- Subcommand: cluster:scale:control-planes ---[0m
|
|
623
|
+
Usage: gcli cluster:scale:control-planes [options]
|
|
624
|
+
|
|
625
|
+
Set the number of control-plane nodes (1, 3 or 5)
|
|
626
|
+
|
|
627
|
+
Options:
|
|
628
|
+
-p, --project <project>
|
|
629
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
630
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
631
|
+
--count <count> Control planes: 1, 3 or 5
|
|
632
|
+
--wait Block until the cluster settles
|
|
633
|
+
-h, --help display help for command
|
|
634
|
+
[36m
|
|
635
|
+
--- Subcommand: cluster:autoscale ---[0m
|
|
636
|
+
Usage: gcli cluster:autoscale [options]
|
|
637
|
+
|
|
638
|
+
Change the worker autoscaling policy - only the flags you pass change
|
|
639
|
+
|
|
640
|
+
Options:
|
|
641
|
+
-p, --project <project>
|
|
642
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
643
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
644
|
+
--enable Turn autoscaling on (multi-node clusters only)
|
|
645
|
+
--disable Turn autoscaling off
|
|
646
|
+
--min <min> Minimum workers (1-10)
|
|
647
|
+
--max <max> Maximum workers (1-10)
|
|
648
|
+
--cpuUp <percent> Scale up at this CPU % (1-100)
|
|
649
|
+
--memUp <percent> Scale up at this memory % (1-100)
|
|
650
|
+
--cpuDown <percent> Scale down below this CPU % (1-100)
|
|
651
|
+
--memDown <percent> Scale down below this memory % (1-100)
|
|
652
|
+
--samples <n> Consecutive readings before acting (1-20)
|
|
653
|
+
--cooldown <minutes> Minutes between scale actions (1-1440)
|
|
654
|
+
-h, --help display help for command
|
|
655
|
+
[36m
|
|
656
|
+
--- Subcommand: cluster:multi-node ---[0m
|
|
657
|
+
Usage: gcli cluster:multi-node [options]
|
|
658
|
+
|
|
659
|
+
Convert a single-node cluster to dedicated worker nodes (required for autoscaling)
|
|
660
|
+
|
|
661
|
+
Options:
|
|
662
|
+
-p, --project <project>
|
|
663
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
664
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
665
|
+
--workers <workers> Worker nodes, 1-10
|
|
666
|
+
--wait Block until the cluster settles
|
|
667
|
+
-h, --help display help for command
|
|
668
|
+
[36m
|
|
669
|
+
--- Subcommand: cluster:single-node ---[0m
|
|
670
|
+
Usage: gcli cluster:single-node [options]
|
|
671
|
+
|
|
672
|
+
Convert a multi-node cluster back to a single node (removes the worker nodes)
|
|
673
|
+
|
|
674
|
+
Options:
|
|
675
|
+
-p, --project <project>
|
|
676
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
677
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
678
|
+
--wait Block until the cluster settles
|
|
679
|
+
-h, --help display help for command
|
|
680
|
+
[36m
|
|
681
|
+
--- Subcommand: cluster:load-balancer ---[0m
|
|
682
|
+
Usage: gcli cluster:load-balancer [options]
|
|
683
|
+
|
|
684
|
+
Add or remove the cluster's load balancer (billed per hour while enabled)
|
|
685
|
+
|
|
686
|
+
Options:
|
|
687
|
+
-p, --project <project>
|
|
688
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
689
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
690
|
+
--enable Add the load balancer
|
|
691
|
+
--disable Remove the load balancer
|
|
692
|
+
--wait Block until the cluster settles
|
|
693
|
+
-h, --help display help for command
|
|
694
|
+
[36m
|
|
542
695
|
--- Subcommand: rabbitmq:create ---[0m
|
|
543
696
|
Usage: gcli rabbitmq:create [options]
|
|
544
697
|
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ Whether you are deploying scalable serverless functions, managing cloud environm
|
|
|
11
11
|
- [Managing Infrastructure](#managing-infrastructure)
|
|
12
12
|
- [Serverless Functions (Lambdas)](#serverless-functions-lambdas)
|
|
13
13
|
- [AI Integration (Model Context Protocol)](#ai-integration-model-context-protocol)
|
|
14
|
+
- [AI agent skill](#ai-agent-skill)
|
|
14
15
|
- [Local AI Models (Ollama runner)](#local-ai-models-ollama-runner)
|
|
15
16
|
- [Build System](#build-system)
|
|
16
17
|
- [Command Reference](#command-reference)
|
|
@@ -24,7 +25,7 @@ You can install `gcli` using a pre-built binary or via NPM.
|
|
|
24
25
|
For a standalone installation without Node.js dependencies:
|
|
25
26
|
|
|
26
27
|
```bash
|
|
27
|
-
curl -L "https://github.com/Stradivario/gapi/releases/download/
|
|
28
|
+
curl -L "https://github.com/Stradivario/gapi/releases/latest/download/gcli-linux" -o ~/.local/bin/gcli
|
|
28
29
|
chmod +x ~/.local/bin/gcli
|
|
29
30
|
```
|
|
30
31
|
|
|
@@ -95,6 +96,10 @@ gcli environment:get --name 'staging'
|
|
|
95
96
|
# (omit --clusterId to use the shared cluster - the default). Immutable
|
|
96
97
|
# after creation.
|
|
97
98
|
gcli environment:create --name 'staging' --clusterId '<clusterId>'
|
|
99
|
+
|
|
100
|
+
# Resize it, or remove it
|
|
101
|
+
gcli environment:update --name 'staging' --maxCpu 800 --maxMemory 1024
|
|
102
|
+
gcli environment:delete --name 'staging'
|
|
98
103
|
```
|
|
99
104
|
|
|
100
105
|
### Private Clusters
|
|
@@ -119,17 +124,79 @@ gcli cluster:kubeconfig --cluster '<clusterId>' --output ./kubeconfig.yaml
|
|
|
119
124
|
gcli cluster:teardown --cluster '<clusterId>' --wait
|
|
120
125
|
```
|
|
121
126
|
|
|
122
|
-
|
|
127
|
+
Scale, reshape and watch a cluster (the same operations as the dashboard's
|
|
128
|
+
cluster page). Changes run in the background; `--wait` blocks until the
|
|
129
|
+
cluster is `ready` again. `--clusterName <name>` works instead of
|
|
130
|
+
`--cluster <id>` everywhere.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Health, load, autoscaling and open issues of every cluster (or one)
|
|
134
|
+
gcli cluster:status [--cluster '<clusterId>']
|
|
135
|
+
gcli cluster:health --cluster '<clusterId>' # latest agent report, per node
|
|
136
|
+
gcli cluster:scale-events --cluster '<clusterId>' # manual + autoscaler history
|
|
137
|
+
gcli cluster:cost # month-to-date + monthly estimate
|
|
138
|
+
|
|
139
|
+
# Worker nodes (1-10, billed per node-hour) and control planes (1, 3 or 5)
|
|
140
|
+
gcli cluster:scale --cluster '<clusterId>' --workers 3 --wait
|
|
141
|
+
gcli cluster:scale:control-planes --cluster '<clusterId>' --count 3 --wait
|
|
142
|
+
|
|
143
|
+
# Topology: dedicated workers (needed for autoscaling) or back to one node
|
|
144
|
+
gcli cluster:multi-node --cluster '<clusterId>' --workers 2 --wait
|
|
145
|
+
gcli cluster:single-node --cluster '<clusterId>' --wait
|
|
146
|
+
|
|
147
|
+
# Autoscaling - only the flags you pass change
|
|
148
|
+
gcli cluster:autoscale --cluster '<clusterId>' --enable --min 2 --max 6
|
|
149
|
+
gcli cluster:autoscale --cluster '<clusterId>' --cpuUp 75 --cpuDown 25 --cooldown 20
|
|
150
|
+
gcli cluster:autoscale --cluster '<clusterId>' --disable
|
|
151
|
+
|
|
152
|
+
# Load balancer (billed per hour while enabled)
|
|
153
|
+
gcli cluster:load-balancer --cluster '<clusterId>' --enable --wait
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### Declarative clusters (`cluster:apply`)
|
|
157
|
+
|
|
158
|
+
Write the cluster you want in the `cluster:` section of `lambforge.yaml`
|
|
159
|
+
(or a standalone `cluster.yaml`) and let `cluster:apply` make it so: it
|
|
160
|
+
creates the cluster when it doesn't exist, then applies topology, workers,
|
|
161
|
+
control planes, the load balancer and autoscaling - one change at a time,
|
|
162
|
+
waiting for the cluster to be ready between them. Keys you leave out are
|
|
163
|
+
left as they are.
|
|
123
164
|
|
|
124
165
|
```yaml
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
166
|
+
cluster:
|
|
167
|
+
name: prod
|
|
168
|
+
# needed only to create it
|
|
169
|
+
imageId: <hcloud-image-id>
|
|
170
|
+
serverType: cpx22
|
|
171
|
+
location: nbg1
|
|
172
|
+
# desired state
|
|
173
|
+
singleNode: false # true = one node runs everything (cheapest, dev/stage)
|
|
174
|
+
workers: 3 # 1-10; only the initial size while autoscale is enabled
|
|
175
|
+
controlPlanes: 1 # 1, 3 or 5
|
|
176
|
+
loadBalancer: true
|
|
177
|
+
autoscale:
|
|
178
|
+
enabled: true # needs singleNode: false
|
|
179
|
+
minWorkers: 2
|
|
180
|
+
maxWorkers: 6
|
|
181
|
+
cpuScaleUpPercent: 70 # scale up above this (of allocatable)
|
|
182
|
+
memScaleUpPercent: 70
|
|
183
|
+
cpuScaleDownPercent: 30
|
|
184
|
+
memScaleDownPercent: 30
|
|
185
|
+
samplesToScale: 3 # consecutive readings before acting
|
|
186
|
+
cooldownMinutes: 15
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
gcli cluster:apply --dry-run # print the plan, change nothing
|
|
191
|
+
gcli cluster:apply # apply it
|
|
192
|
+
gcli cluster:apply --yes # also steps that remove capacity or the LB IP
|
|
193
|
+
gcli cluster:apply --spec cluster.yaml
|
|
131
194
|
```
|
|
132
195
|
|
|
196
|
+
Steps that remove capacity or release the load balancer's IP (going back to
|
|
197
|
+
`singleNode: true`, `loadBalancer: false`) are skipped unless you pass
|
|
198
|
+
`--yes`. Nodes and the load balancer are billed per started hour.
|
|
199
|
+
|
|
133
200
|
### RabbitMQ Brokers
|
|
134
201
|
|
|
135
202
|
A project may have several RabbitMQ brokers, each optionally scoped to one of its private clusters.
|
|
@@ -285,15 +352,25 @@ options:
|
|
|
285
352
|
external: []
|
|
286
353
|
```
|
|
287
354
|
|
|
288
|
-
The same file can also carry `cluster:`, `rabbitmq:`, and `
|
|
355
|
+
The same file can also carry `cluster:`, `rabbitmq:`, `plugin:` and `triggers:` sections, read by `cluster:apply` / `cluster:create`, `rabbitmq:create`, `plugin:install` and `cron:create` respectively (each also accepts its own dedicated `--spec` file, e.g. `cluster.yaml`, if you'd rather keep them separate):
|
|
289
356
|
|
|
290
357
|
```yaml
|
|
291
|
-
cluster:
|
|
358
|
+
cluster: # every key: see "Declarative clusters" above
|
|
292
359
|
name: prod
|
|
293
360
|
imageId: <hcloud-image-id>
|
|
294
361
|
serverType: cpx22
|
|
295
362
|
location: nbg1
|
|
296
363
|
workers: 2
|
|
364
|
+
loadBalancer: false
|
|
365
|
+
autoscale:
|
|
366
|
+
enabled: true
|
|
367
|
+
minWorkers: 2
|
|
368
|
+
maxWorkers: 5
|
|
369
|
+
|
|
370
|
+
triggers:
|
|
371
|
+
time:
|
|
372
|
+
triggerName: nightly
|
|
373
|
+
cron: '0 2 * * *' # cron syntax or @every 5m / @daily
|
|
297
374
|
|
|
298
375
|
rabbitmq:
|
|
299
376
|
name: events-broker
|
|
@@ -361,7 +438,7 @@ gcli lambda:create --project <projectId> --spec ./lambforge.yaml
|
|
|
361
438
|
`--mcp` and `--mcpGraph <name>` are also available as CLI flags; the array fields
|
|
362
439
|
(`mcpOperations`, `mcpHeaders`, `mcpForwardHeaders`) are spec-only. A full annotated example lives in
|
|
363
440
|
[`example/mcp/lambforge.yaml`](./example/mcp/lambforge.yaml). Client connects at
|
|
364
|
-
`https://<host>/<projectId>/<route>/mcp
|
|
441
|
+
`https://<host>/<projectId>/<route>` (with `route: mcp`: `https://<host>/<projectId>/mcp`).
|
|
365
442
|
|
|
366
443
|
### Conditional Configuration (Environment-Aware Specs)
|
|
367
444
|
|
|
@@ -638,10 +715,23 @@ gcli environment:update
|
|
|
638
715
|
|
|
639
716
|
### Function Lifecycle
|
|
640
717
|
|
|
718
|
+
- **List**: `gcli lambda:list` (`--clusterName <name>` for one cluster's lambdas)
|
|
641
719
|
- **Update**: `gcli lambda:update --name 'my-function' --file ./new-index.ts`
|
|
642
720
|
- **Delete**: `gcli lambda:delete --name 'my-function'`
|
|
643
721
|
- **Get Details**: `gcli lambda:get --name 'my-function'`
|
|
644
722
|
|
|
723
|
+
### Schedules (cron)
|
|
724
|
+
|
|
725
|
+
One time trigger per lambda. The platform calls the lambda's root with a
|
|
726
|
+
GET and an `X-Fission-Timer-Name` header.
|
|
727
|
+
|
|
728
|
+
```bash
|
|
729
|
+
gcli cron:create --lambdaName 'my-function' --triggerName nightly --cron '0 2 * * *'
|
|
730
|
+
gcli cron:create # reads triggers.time (and function.name) from lambforge.yaml
|
|
731
|
+
gcli cron:list
|
|
732
|
+
gcli cron:delete --lambdaName 'my-function'
|
|
733
|
+
```
|
|
734
|
+
|
|
645
735
|
### Monitoring & Testing
|
|
646
736
|
|
|
647
737
|
Debug your functions directly from the terminal.
|
|
@@ -715,6 +805,33 @@ To use this with Claude Desktop or other MCP-compatible tools, add the following
|
|
|
715
805
|
}
|
|
716
806
|
```
|
|
717
807
|
|
|
808
|
+
### AI agent skill
|
|
809
|
+
|
|
810
|
+
Give a coding agent (Claude Code and other agents that read skills) the
|
|
811
|
+
whole platform. Paste this into the agent:
|
|
812
|
+
|
|
813
|
+
```text
|
|
814
|
+
Install the Lambforge skill from https://lambforge.com/skills/platform.md and follow its setup.
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
Or by hand for Claude Code:
|
|
818
|
+
|
|
819
|
+
```bash
|
|
820
|
+
mkdir -p ~/.claude/skills/lambforge && cd ~/.claude/skills/lambforge
|
|
821
|
+
for f in $(curl -fsSL https://lambforge.com/skills/files.txt); do
|
|
822
|
+
curl -fsSLO "https://lambforge.com/skills/$f"
|
|
823
|
+
done
|
|
824
|
+
cp platform.md SKILL.md
|
|
825
|
+
claude mcp add --scope user lambforge -- gcli mcp:start
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
`platform.md` covers setup (install gcli, the login command you run from
|
|
829
|
+
Profile -> CLI - the agent never handles your token, `gcli mcp:start`) and
|
|
830
|
+
the rules, and indexes topic files the agent reads on demand: gcli, MCP
|
|
831
|
+
tools, deploy, REST code and testing, GraphQL and federation, websites,
|
|
832
|
+
MCP servers, secrets, cron and queues, clusters and plugins, operations and
|
|
833
|
+
costs, memory and plans. Source: gql-fission `src/skills/`.
|
|
834
|
+
|
|
718
835
|
## Local AI Models (Ollama runner)
|
|
719
836
|
|
|
720
837
|
Use models running on your own machine in the Lambforge chat - including
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
## 2026-10-19 - dedicated-platform-cluster: Cluster scaling, topology, load balancer and health commands (cluster:status, health, scale, autoscale, ...)
|
|
2
|
+
|
|
3
|
+
**Feature:** dedicated-platform-cluster · **Type:** feat
|
|
4
|
+
|
|
5
|
+
- New commands (the dashboard cluster page's actions, same
|
|
6
|
+
cluster-provisioner operations): `cluster:status`, `cluster:health`,
|
|
7
|
+
`cluster:scale-events`, `cluster:cost`, `cluster:scale --workers`,
|
|
8
|
+
`cluster:scale:control-planes --count`, `cluster:multi-node`,
|
|
9
|
+
`cluster:single-node`, `cluster:autoscale` (partial: only the given
|
|
10
|
+
flags change), `cluster:load-balancer --enable|--disable`. All take
|
|
11
|
+
`--cluster <id>` or `--clusterName <name>`; mutations take `--wait`
|
|
12
|
+
(polls until ready; ending in `error` exits non-zero with the reason).
|
|
13
|
+
- `cluster:apply [--spec] [--dry-run] [--yes]`: the `cluster:` section of
|
|
14
|
+
lambforge.yaml / cluster.yaml is now a desired state (new keys
|
|
15
|
+
`controlPlanes`, `loadBalancer`, `autoscale.*`; `singleNode`, `workers`
|
|
16
|
+
as before). It creates the cluster when missing (in the desired shape)
|
|
17
|
+
and otherwise plans and applies topology → workers → control planes →
|
|
18
|
+
load balancer → autoscale, waiting for `ready` between jobs; destructive
|
|
19
|
+
steps need `--yes`. `cluster:create` also passes `controlPlanes` and
|
|
20
|
+
`loadBalancer` from the spec now.
|
|
21
|
+
- Client-side checks mirror the server's bounds (workers 1-10, control
|
|
22
|
+
planes 1/3/5, autoscale ranges) so a bad value fails before any request.
|
|
23
|
+
- `README.md` Private Clusters section, regenerated `README-CLI.md`.
|
|
24
|
+
- **Test:** `npx jest --coverage=false` (71 tests; new
|
|
25
|
+
`test/cluster-scaling.spec.ts`, `test/cluster-apply.spec.ts` (the plan),
|
|
26
|
+
`test/cluster-apply-command.spec.ts` (dry-run, `--yes`, create, refusals)).
|
|
27
|
+
- **Debug:** slice doc `docs/features/dedicated-platform-cluster.md`.
|
|
28
|
+
- **Verification:** jest 71/71; the built binary's `cluster:apply` read a
|
|
29
|
+
real lambforge.yaml and rejected `controlPlanes: 2` before any request; tsc + eslint clean; `npm run build` and
|
|
30
|
+
`--help` checked for every command (`release/index.js` restored after,
|
|
31
|
+
not a release).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## 2026-10-19 - lambforge-agent-skill: README points to the Lambforge agent skill (gcli + mcp:start for AI agents)
|
|
2
|
+
|
|
3
|
+
**Feature:** lambforge-agent-skill · **Type:** docs
|
|
4
|
+
|
|
5
|
+
- README.md "AI agent skill" (under AI Integration): the prompt to paste into
|
|
6
|
+
an agent (https://lambforge.com/skills/platform.md), the manual Claude Code
|
|
7
|
+
install (every file from `files.txt`, `platform.md` copied to `SKILL.md`,
|
|
8
|
+
`claude mcp add --scope user lambforge -- gcli mcp:start`), and what the
|
|
9
|
+
topic files cover. The skill lives in gql-fission `src/skills/` (canonical
|
|
10
|
+
doc there).
|
|
11
|
+
- `docs/features/lambforge-agent-skill.md`: which gcli commands the skill
|
|
12
|
+
quotes - change them, update SKILL.md in the same change.
|
|
13
|
+
- **Test:** none (docs); the commands it lists were checked with
|
|
14
|
+
`node release/index.js <command> --help`.
|
|
15
|
+
- **Debug:** an agent runs a gcli command that fails → compare SKILL.md with
|
|
16
|
+
`gcli <command> --help`.
|
|
17
|
+
- **Verification:** no code change.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## 2026-10-19 - repo: cron:create honours --cron/--triggerName; README brought up to date with every command
|
|
2
|
+
|
|
3
|
+
**Feature:** repo · **Type:** fix
|
|
4
|
+
|
|
5
|
+
- `cron:create` declared `--cron` and `--triggerName` but only read them
|
|
6
|
+
from the spec (`triggers.time` of lambforge.yaml / cron.yaml), so the
|
|
7
|
+
documented `gcli cron:create --lambdaName x --triggerName nightly --cron
|
|
8
|
+
'0 2 * * *'` sent an empty schedule. Flags now win, the spec fills gaps,
|
|
9
|
+
and a missing schedule is a clear error before any request.
|
|
10
|
+
- README: binary install from `releases/latest` (was pinned to v1.8.198);
|
|
11
|
+
`environment:update/delete`, `lambda:list` and a "Schedules (cron)"
|
|
12
|
+
section (the commands were missing); `triggers:` in the unified
|
|
13
|
+
lambforge.yaml; the MCP client URL is `https://<host>/<projectId>/<route>`
|
|
14
|
+
(the `/mcp` suffix was wrong - see example/mcp/lambforge.yaml); the
|
|
15
|
+
declarative cluster section. Every command registered in `src/commands`
|
|
16
|
+
now appears in README.md.
|
|
17
|
+
- **Test:** `npx jest --coverage=false test/cron-create.spec.ts` (flags,
|
|
18
|
+
flags over yaml, missing schedule).
|
|
19
|
+
- **Debug:** a cron with an empty schedule → an older gcli; upgrade.
|
|
20
|
+
- **Verification:** jest 71/71; a script compared the commands registered in
|
|
21
|
+
`src/commands` against README.md (no command missing).
|
package/docs/features/README.md
CHANGED
|
@@ -31,3 +31,5 @@ Outline (drop sections that don't apply):
|
|
|
31
31
|
| Feature | Doc | Notes |
|
|
32
32
|
|---|---|---|
|
|
33
33
|
| `local-ai-runners` | [local-ai-runners.md](local-ai-runners.md) | `runner:*` commands; canonical doc in graphql-server |
|
|
34
|
+
| `lambforge-agent-skill` | [lambforge-agent-skill.md](lambforge-agent-skill.md) | The agent skill that teaches gcli + `mcp:start`; canonical doc in gql-fission |
|
|
35
|
+
| `dedicated-platform-cluster` | [dedicated-platform-cluster.md](dedicated-platform-cluster.md) | `cluster:status/health/scale/autoscale/...` commands; canonical doc in lambforge-agent |
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# dedicated-platform-cluster (gcli slice)
|
|
2
|
+
|
|
3
|
+
**Canonical doc:** `lambforge-agent/docs/features/dedicated-platform-cluster.md`
|
|
4
|
+
· **Since:** 2026-10-19 (cluster scaling and health commands)
|
|
5
|
+
|
|
6
|
+
The cluster page's scaling, topology, load balancer and health actions as
|
|
7
|
+
commands (cluster-provisioner operations, the same ones gql-fission's
|
|
8
|
+
`core/services/cluster/*.graphql` use; every one is USER-enabled with
|
|
9
|
+
`isMemberOrProjectOwner`):
|
|
10
|
+
|
|
11
|
+
| Command | Operation |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `cluster:status [--cluster]` | `projectClustersOverview` (status, agent, nodes, load, autoscale, issues) |
|
|
14
|
+
| `cluster:health --cluster` | `clusterHealth(limit: 1)` - latest agent report + nodes |
|
|
15
|
+
| `cluster:scale-events --cluster [--limit]` | `clusterScaleEvents` |
|
|
16
|
+
| `cluster:cost` | `projectClustersOverview` (`monthToDate`, `estimatedMonthlyCostEur`) |
|
|
17
|
+
| `cluster:scale --workers 1-10 [--wait]` | `scaleProjectCluster` |
|
|
18
|
+
| `cluster:scale:control-planes --count 1/3/5 [--wait]` | `scaleControlPlanesProjectCluster` |
|
|
19
|
+
| `cluster:multi-node --workers [--wait]` / `cluster:single-node [--wait]` | `migrateToMultiNodeProjectCluster` / `revertToSingleNodeProjectCluster` |
|
|
20
|
+
| `cluster:autoscale [--enable/--disable] [--min --max --cpuUp --memUp --cpuDown --memDown --samples --cooldown]` | `updateProjectClusterAutoscale` - partial: the server merges it into the stored policy and validates (min <= max, scale-down below scale-up, single-node cannot autoscale) |
|
|
21
|
+
| `cluster:load-balancer --enable/--disable [--wait]` | `enable/disableLoadBalancerProjectCluster` |
|
|
22
|
+
| `cluster:apply [--spec] [--dry-run] [--yes]` | reconciles the `cluster:` section of lambforge.yaml: `projectClusters` (current) → plan → provision / topology / scale / control planes / load balancer / autoscale, one job at a time, waiting for `ready` between them |
|
|
23
|
+
|
|
24
|
+
## Declarative clusters (`cluster:apply`)
|
|
25
|
+
|
|
26
|
+
`cluster:` keys: `name` (identity), `imageId` / `serverType` / `location`
|
|
27
|
+
(create only), `singleNode`, `workers` (1-10), `controlPlanes` (1/3/5),
|
|
28
|
+
`loadBalancer`, `autoscale.{enabled,minWorkers,maxWorkers,cpuScaleUpPercent,
|
|
29
|
+
memScaleUpPercent,cpuScaleDownPercent,memScaleDownPercent,samplesToScale,
|
|
30
|
+
cooldownMinutes}`. Missing keys are left alone.
|
|
31
|
+
|
|
32
|
+
- `helpers/plan.ts` `planClusterChanges(current, desired)` is pure (unit
|
|
33
|
+
tested): create in the desired shape (workers, control planes, load
|
|
34
|
+
balancer at provision time) then autoscale; otherwise topology → workers
|
|
35
|
+
→ control planes → load balancer → autoscale (only the changed keys).
|
|
36
|
+
- `workers` is skipped while `autoscale.enabled` (the autoscaler owns it);
|
|
37
|
+
converting to multi-node already creates the workers.
|
|
38
|
+
- Destructive steps (to single-node, removing the load balancer) need
|
|
39
|
+
`--yes`; without it they are printed and skipped.
|
|
40
|
+
- `validateDesired` mirrors the server's bounds; a cluster that is not
|
|
41
|
+
`ready` is refused (apply again once it settles).
|
|
42
|
+
|
|
43
|
+
## Files
|
|
44
|
+
|
|
45
|
+
| Path | Responsibility |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `src/commands/cluster/index.ts` | registration (`--cluster` / `--clusterName` on every one) |
|
|
48
|
+
| `src/commands/cluster/{status,health,scale-events,cost,scale,scale-control-planes,autoscale,multi-node,single-node,load-balancer}.ts` | actions |
|
|
49
|
+
| `src/commands/cluster/helpers/cluster-change.ts` | target resolution, int validation, mutate → print → `--wait` (`pollUntilReady`; ends in `error` → non-zero exit) |
|
|
50
|
+
| `src/commands/cluster/types.ts` | local types + selections (newer than `@introspection`) |
|
|
51
|
+
| `src/services/gql-client.ts` | the API calls |
|
|
52
|
+
|
|
53
|
+
## How to test
|
|
54
|
+
|
|
55
|
+
`npx jest --coverage=false test/cluster-scaling.spec.ts`; manually against a
|
|
56
|
+
project with a private cluster: `gcli cluster:status`, then
|
|
57
|
+
`gcli cluster:scale --clusterName <n> --workers 2 --wait`.
|
|
58
|
+
|
|
59
|
+
## How to debug
|
|
60
|
+
|
|
61
|
+
| Symptom | Look at |
|
|
62
|
+
|---|---|
|
|
63
|
+
| "Pass --cluster <id> or --clusterName" | no cluster given; `gcli cluster:list` |
|
|
64
|
+
| autoscale refused | the server's message: single-node clusters must `cluster:multi-node` first; external clusters cannot autoscale |
|
|
65
|
+
| `--wait` ends in error | `gcli cluster:list` (status + error), the dashboard's cluster page |
|
|
66
|
+
|
|
67
|
+
## Not in the CLI yet
|
|
68
|
+
|
|
69
|
+
Resource migration between clusters (`migrateResourcesToCluster` + status /
|
|
70
|
+
retry), Fission options, the cluster agent install/rotate - dashboard only.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# lambforge-agent-skill (gcli slice)
|
|
2
|
+
|
|
3
|
+
**Canonical doc:** `gql-fission/docs/features/lambforge-agent-skill.md` ·
|
|
4
|
+
**Since:** 2026-10-19
|
|
5
|
+
|
|
6
|
+
The Lambforge agent skill (entry https://lambforge.com/skills/platform.md,
|
|
7
|
+
topic files next to it; source in gql-fission `src/skills/`) teaches AI
|
|
8
|
+
agents to drive this CLI. `cli.md` lists every command, and `platform.md`,
|
|
9
|
+
`deploy.md`, `events.md`, `clusters.md` and `agents.md` quote gcli exactly:
|
|
10
|
+
|
|
11
|
+
- install: `npm i -g @gapi/gcli` (or `npx @gapi/gcli`);
|
|
12
|
+
- login: the command from Profile -> CLI (`login --token --key --url
|
|
13
|
+
--uploadUrl`), run by the human;
|
|
14
|
+
- `project:list` / `project:use`;
|
|
15
|
+
- `mcp:start` without `--url` (proxy to `<login url>/mcp`, token refresh on
|
|
16
|
+
401/403) as the MCP server: `claude mcp add --scope user lambforge -- gcli mcp:start`;
|
|
17
|
+
- the `lambda:*`, `environment:*`, `cron:*`, `cluster:*`, `rabbitmq:*`,
|
|
18
|
+
`plugin:*`, `build`, `start` commands and flags it lists.
|
|
19
|
+
|
|
20
|
+
**When you change any of those commands, flags or `mcp:start`, update
|
|
21
|
+
the skill files in gql-fission in the same change** - agents copy it verbatim.
|
|
22
|
+
README.md "AI agent skill" points users to it.
|