@gapi/gcli 1.8.240 → 1.8.242
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 +220 -0
- package/README.md +157 -11
- package/docs/changelog.d/2026-10-19-ci-token-scopes-mq-trigger-list-create-update-delete-commands-readme-documen.md +21 -0
- 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 +3 -0
- package/docs/features/ci-token-scopes.md +25 -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 +2187 -793
|
@@ -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
|
@@ -29,10 +29,25 @@ Commands:
|
|
|
29
29
|
cron:create [options] Create cron
|
|
30
30
|
cron:delete [options] Delete cron
|
|
31
31
|
cron:list [options] List of all cron jobs for project
|
|
32
|
+
mq-trigger:list [options] List the message-queue triggers of a project
|
|
33
|
+
mq-trigger:create [options] Run a lambda for every message on a RabbitMQ queue
|
|
34
|
+
mq-trigger:update [options] Change a message-queue trigger (same flags as create)
|
|
35
|
+
mq-trigger:delete [options] Delete a message-queue trigger
|
|
32
36
|
cluster:create [options] Provision a private Talos cluster for a project (runs in the background - takes several minutes; use --wait to block)
|
|
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
|
|
33
38
|
cluster:list [options] List every private cluster this project has (it may have several - dev/stage/prod, ...)
|
|
34
39
|
cluster:teardown [options] Tear down one of a project's clusters (runs in the background - use --wait to block)
|
|
35
40
|
cluster:kubeconfig [options] Print (or save) a cluster's raw kubeconfig YAML - only available once it's 'ready'
|
|
41
|
+
cluster:status [options] Every cluster's status, agent, nodes, CPU/memory load, autoscaling and open issues (or one with --cluster)
|
|
42
|
+
cluster:health [options] The latest health report of a cluster's agent, with every node
|
|
43
|
+
cluster:scale-events [options] Manual and autoscaler scale history, newest first
|
|
44
|
+
cluster:cost [options] Month-to-date cost and the monthly estimate of the project's private clusters
|
|
45
|
+
cluster:scale [options] Set the number of worker nodes (1-10) of a multi-node cluster - billed per node-hour
|
|
46
|
+
cluster:scale:control-planes [options] Set the number of control-plane nodes (1, 3 or 5)
|
|
47
|
+
cluster:autoscale [options] Change the worker autoscaling policy - only the flags you pass change
|
|
48
|
+
cluster:multi-node [options] Convert a single-node cluster to dedicated worker nodes (required for autoscaling)
|
|
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)
|
|
36
51
|
rabbitmq:create [options] Provision a RabbitMQ broker for a project (a project may have several)
|
|
37
52
|
rabbitmq:list [options] List every RabbitMQ broker for a project
|
|
38
53
|
rabbitmq:delete [options] Delete a RabbitMQ broker
|
|
@@ -491,6 +506,69 @@ Options:
|
|
|
491
506
|
-p, --project <project>
|
|
492
507
|
-h, --help display help for command
|
|
493
508
|
[36m
|
|
509
|
+
--- Subcommand: mq-trigger:list ---[0m
|
|
510
|
+
Usage: gcli mq-trigger:list [options]
|
|
511
|
+
|
|
512
|
+
List the message-queue triggers of a project
|
|
513
|
+
|
|
514
|
+
Options:
|
|
515
|
+
-p, --project <project>
|
|
516
|
+
-h, --help display help for command
|
|
517
|
+
[36m
|
|
518
|
+
--- Subcommand: mq-trigger:create ---[0m
|
|
519
|
+
Usage: gcli mq-trigger:create [options]
|
|
520
|
+
|
|
521
|
+
Run a lambda for every message on a RabbitMQ queue
|
|
522
|
+
|
|
523
|
+
Options:
|
|
524
|
+
-p, --project <project>
|
|
525
|
+
-n, --name <name> Trigger name
|
|
526
|
+
-l, --lambda <lambda> Lambda the trigger runs per message
|
|
527
|
+
--request-topic <queue> Queue the trigger consumes
|
|
528
|
+
--response-topic <queue> Queue for the lambda response
|
|
529
|
+
--error-topic <queue> Queue for failed messages
|
|
530
|
+
--broker <rabbitMqId> RabbitMQ broker id (see rabbitmq:list) - needed
|
|
531
|
+
when several brokers share queue names
|
|
532
|
+
--max-retries <n>
|
|
533
|
+
--cool-down-period <seconds>
|
|
534
|
+
--polling-interval <seconds>
|
|
535
|
+
--min-replicas <n>
|
|
536
|
+
--max-replicas <n>
|
|
537
|
+
--threshold <n> Messages per replica before scaling out
|
|
538
|
+
-h, --help display help for command
|
|
539
|
+
[36m
|
|
540
|
+
--- Subcommand: mq-trigger:update ---[0m
|
|
541
|
+
Usage: gcli mq-trigger:update [options]
|
|
542
|
+
|
|
543
|
+
Change a message-queue trigger (same flags as create)
|
|
544
|
+
|
|
545
|
+
Options:
|
|
546
|
+
-p, --project <project>
|
|
547
|
+
-n, --name <name> Trigger name
|
|
548
|
+
-l, --lambda <lambda> Lambda the trigger runs per message
|
|
549
|
+
--request-topic <queue> Queue the trigger consumes
|
|
550
|
+
--response-topic <queue> Queue for the lambda response
|
|
551
|
+
--error-topic <queue> Queue for failed messages
|
|
552
|
+
--broker <rabbitMqId> RabbitMQ broker id (see rabbitmq:list) - needed
|
|
553
|
+
when several brokers share queue names
|
|
554
|
+
--max-retries <n>
|
|
555
|
+
--cool-down-period <seconds>
|
|
556
|
+
--polling-interval <seconds>
|
|
557
|
+
--min-replicas <n>
|
|
558
|
+
--max-replicas <n>
|
|
559
|
+
--threshold <n> Messages per replica before scaling out
|
|
560
|
+
-h, --help display help for command
|
|
561
|
+
[36m
|
|
562
|
+
--- Subcommand: mq-trigger:delete ---[0m
|
|
563
|
+
Usage: gcli mq-trigger:delete [options]
|
|
564
|
+
|
|
565
|
+
Delete a message-queue trigger
|
|
566
|
+
|
|
567
|
+
Options:
|
|
568
|
+
-p, --project <project>
|
|
569
|
+
-n, --name <name> Trigger name
|
|
570
|
+
-h, --help display help for command
|
|
571
|
+
[36m
|
|
494
572
|
--- Subcommand: cluster:create ---[0m
|
|
495
573
|
Usage: gcli cluster:create [options]
|
|
496
574
|
|
|
@@ -508,6 +586,19 @@ Options:
|
|
|
508
586
|
--wait Block until the cluster is ready (or errors)
|
|
509
587
|
-h, --help display help for command
|
|
510
588
|
[36m
|
|
589
|
+
--- Subcommand: cluster:apply ---[0m
|
|
590
|
+
Usage: gcli cluster:apply [options]
|
|
591
|
+
|
|
592
|
+
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
|
|
593
|
+
|
|
594
|
+
Options:
|
|
595
|
+
-p, --project <project>
|
|
596
|
+
-spec, --spec <spec> Spec file (default: lambforge.yaml / cluster.yaml)
|
|
597
|
+
--dry-run Print the plan, change nothing
|
|
598
|
+
--yes Also apply steps that remove capacity or the load
|
|
599
|
+
balancer IP
|
|
600
|
+
-h, --help display help for command
|
|
601
|
+
[36m
|
|
511
602
|
--- Subcommand: cluster:list ---[0m
|
|
512
603
|
Usage: gcli cluster:list [options]
|
|
513
604
|
|
|
@@ -539,6 +630,135 @@ Options:
|
|
|
539
630
|
-o, --output <output> Write to this file instead of stdout
|
|
540
631
|
-h, --help display help for command
|
|
541
632
|
[36m
|
|
633
|
+
--- Subcommand: cluster:status ---[0m
|
|
634
|
+
Usage: gcli cluster:status [options]
|
|
635
|
+
|
|
636
|
+
Every cluster's status, agent, nodes, CPU/memory load, autoscaling and open issues (or one with --cluster)
|
|
637
|
+
|
|
638
|
+
Options:
|
|
639
|
+
-p, --project <project>
|
|
640
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
641
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
642
|
+
-h, --help display help for command
|
|
643
|
+
[36m
|
|
644
|
+
--- Subcommand: cluster:health ---[0m
|
|
645
|
+
Usage: gcli cluster:health [options]
|
|
646
|
+
|
|
647
|
+
The latest health report of a cluster's agent, with every node
|
|
648
|
+
|
|
649
|
+
Options:
|
|
650
|
+
-p, --project <project>
|
|
651
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
652
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
653
|
+
-h, --help display help for command
|
|
654
|
+
[36m
|
|
655
|
+
--- Subcommand: cluster:scale-events ---[0m
|
|
656
|
+
Usage: gcli cluster:scale-events [options]
|
|
657
|
+
|
|
658
|
+
Manual and autoscaler scale history, newest first
|
|
659
|
+
|
|
660
|
+
Options:
|
|
661
|
+
-p, --project <project>
|
|
662
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
663
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
664
|
+
--limit <limit> How many events (default 20)
|
|
665
|
+
-h, --help display help for command
|
|
666
|
+
[36m
|
|
667
|
+
--- Subcommand: cluster:cost ---[0m
|
|
668
|
+
Usage: gcli cluster:cost [options]
|
|
669
|
+
|
|
670
|
+
Month-to-date cost and the monthly estimate of the project's private clusters
|
|
671
|
+
|
|
672
|
+
Options:
|
|
673
|
+
-p, --project <project>
|
|
674
|
+
-h, --help display help for command
|
|
675
|
+
[36m
|
|
676
|
+
--- Subcommand: cluster:scale ---[0m
|
|
677
|
+
Usage: gcli cluster:scale [options]
|
|
678
|
+
|
|
679
|
+
Set the number of worker nodes (1-10) of a multi-node cluster - billed per node-hour
|
|
680
|
+
|
|
681
|
+
Options:
|
|
682
|
+
-p, --project <project>
|
|
683
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
684
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
685
|
+
--workers <workers> Worker nodes, 1-10
|
|
686
|
+
--wait Block until the cluster settles
|
|
687
|
+
-h, --help display help for command
|
|
688
|
+
[36m
|
|
689
|
+
--- Subcommand: cluster:scale:control-planes ---[0m
|
|
690
|
+
Usage: gcli cluster:scale:control-planes [options]
|
|
691
|
+
|
|
692
|
+
Set the number of control-plane nodes (1, 3 or 5)
|
|
693
|
+
|
|
694
|
+
Options:
|
|
695
|
+
-p, --project <project>
|
|
696
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
697
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
698
|
+
--count <count> Control planes: 1, 3 or 5
|
|
699
|
+
--wait Block until the cluster settles
|
|
700
|
+
-h, --help display help for command
|
|
701
|
+
[36m
|
|
702
|
+
--- Subcommand: cluster:autoscale ---[0m
|
|
703
|
+
Usage: gcli cluster:autoscale [options]
|
|
704
|
+
|
|
705
|
+
Change the worker autoscaling policy - only the flags you pass change
|
|
706
|
+
|
|
707
|
+
Options:
|
|
708
|
+
-p, --project <project>
|
|
709
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
710
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
711
|
+
--enable Turn autoscaling on (multi-node clusters only)
|
|
712
|
+
--disable Turn autoscaling off
|
|
713
|
+
--min <min> Minimum workers (1-10)
|
|
714
|
+
--max <max> Maximum workers (1-10)
|
|
715
|
+
--cpuUp <percent> Scale up at this CPU % (1-100)
|
|
716
|
+
--memUp <percent> Scale up at this memory % (1-100)
|
|
717
|
+
--cpuDown <percent> Scale down below this CPU % (1-100)
|
|
718
|
+
--memDown <percent> Scale down below this memory % (1-100)
|
|
719
|
+
--samples <n> Consecutive readings before acting (1-20)
|
|
720
|
+
--cooldown <minutes> Minutes between scale actions (1-1440)
|
|
721
|
+
-h, --help display help for command
|
|
722
|
+
[36m
|
|
723
|
+
--- Subcommand: cluster:multi-node ---[0m
|
|
724
|
+
Usage: gcli cluster:multi-node [options]
|
|
725
|
+
|
|
726
|
+
Convert a single-node cluster to dedicated worker nodes (required for autoscaling)
|
|
727
|
+
|
|
728
|
+
Options:
|
|
729
|
+
-p, --project <project>
|
|
730
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
731
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
732
|
+
--workers <workers> Worker nodes, 1-10
|
|
733
|
+
--wait Block until the cluster settles
|
|
734
|
+
-h, --help display help for command
|
|
735
|
+
[36m
|
|
736
|
+
--- Subcommand: cluster:single-node ---[0m
|
|
737
|
+
Usage: gcli cluster:single-node [options]
|
|
738
|
+
|
|
739
|
+
Convert a multi-node cluster back to a single node (removes the worker nodes)
|
|
740
|
+
|
|
741
|
+
Options:
|
|
742
|
+
-p, --project <project>
|
|
743
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
744
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
745
|
+
--wait Block until the cluster settles
|
|
746
|
+
-h, --help display help for command
|
|
747
|
+
[36m
|
|
748
|
+
--- Subcommand: cluster:load-balancer ---[0m
|
|
749
|
+
Usage: gcli cluster:load-balancer [options]
|
|
750
|
+
|
|
751
|
+
Add or remove the cluster's load balancer (billed per hour while enabled)
|
|
752
|
+
|
|
753
|
+
Options:
|
|
754
|
+
-p, --project <project>
|
|
755
|
+
-c, --cluster <cluster> Cluster id (see cluster:list)
|
|
756
|
+
--clusterName <clusterName> Cluster name instead of --cluster
|
|
757
|
+
--enable Add the load balancer
|
|
758
|
+
--disable Remove the load balancer
|
|
759
|
+
--wait Block until the cluster settles
|
|
760
|
+
-h, --help display help for command
|
|
761
|
+
[36m
|
|
542
762
|
--- Subcommand: rabbitmq:create ---[0m
|
|
543
763
|
Usage: gcli rabbitmq:create [options]
|
|
544
764
|
|
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
|
|
|
@@ -46,6 +47,20 @@ For automated pipelines (e.g., GitHub Actions), you can use `npx` with a long-li
|
|
|
46
47
|
run: npx gcli login --ci --token ${{ secrets.GCLI_AUTH_TOKEN }}
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
Create the token in the dashboard (Project → CI/CD) with only the permissions the pipeline needs. Every project command has a permission:
|
|
51
|
+
|
|
52
|
+
| Permission | Commands |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Lambdas: read / deploy / create / delete | `lambda:get/list/log/build:log/test`, `lambda:update`, `lambda:create`, `lambda:delete` |
|
|
55
|
+
| Environments: read / write / delete | `environment:list/get`, `environment:create/update`, `environment:delete` |
|
|
56
|
+
| Schedules: read / write | `cron:list`, `cron:create/delete` |
|
|
57
|
+
| RabbitMQ: read / install / uninstall | `rabbitmq:list`, `rabbitmq:create`, `rabbitmq:delete` |
|
|
58
|
+
| Queue triggers: read / manage | `mq-trigger:list`, `mq-trigger:create/update/delete` |
|
|
59
|
+
| Plugins: read / install | `plugin:list/installed`, `plugin:install/uninstall` |
|
|
60
|
+
| Clusters: read / scale / create / tear down / kubeconfig | `cluster:list/status/health/scale-events/cost`, `cluster:scale/autoscale/multi-node/single-node/load-balancer/apply`, `cluster:create/apply`, `cluster:teardown`, `cluster:kubeconfig` |
|
|
61
|
+
|
|
62
|
+
A token can also be limited to some lambdas (lambda, schedule and queue-trigger commands). Typical tokens: *Deploy only* (`lambda:update`), or *DevOps (clusters)* for an infra repo that runs `gcli cluster:apply`. A command the token may not run fails with `ci-token-missing-scope: <operation> needs <permission>`. `runner:*` and `project:list` are personal and not available to CI tokens.
|
|
63
|
+
|
|
49
64
|
## Authentication
|
|
50
65
|
|
|
51
66
|
Before interacting with the platform, you must authenticate. You can log in using an API key or a personal access token.
|
|
@@ -95,6 +110,10 @@ gcli environment:get --name 'staging'
|
|
|
95
110
|
# (omit --clusterId to use the shared cluster - the default). Immutable
|
|
96
111
|
# after creation.
|
|
97
112
|
gcli environment:create --name 'staging' --clusterId '<clusterId>'
|
|
113
|
+
|
|
114
|
+
# Resize it, or remove it
|
|
115
|
+
gcli environment:update --name 'staging' --maxCpu 800 --maxMemory 1024
|
|
116
|
+
gcli environment:delete --name 'staging'
|
|
98
117
|
```
|
|
99
118
|
|
|
100
119
|
### Private Clusters
|
|
@@ -119,17 +138,79 @@ gcli cluster:kubeconfig --cluster '<clusterId>' --output ./kubeconfig.yaml
|
|
|
119
138
|
gcli cluster:teardown --cluster '<clusterId>' --wait
|
|
120
139
|
```
|
|
121
140
|
|
|
122
|
-
|
|
141
|
+
Scale, reshape and watch a cluster (the same operations as the dashboard's
|
|
142
|
+
cluster page). Changes run in the background; `--wait` blocks until the
|
|
143
|
+
cluster is `ready` again. `--clusterName <name>` works instead of
|
|
144
|
+
`--cluster <id>` everywhere.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Health, load, autoscaling and open issues of every cluster (or one)
|
|
148
|
+
gcli cluster:status [--cluster '<clusterId>']
|
|
149
|
+
gcli cluster:health --cluster '<clusterId>' # latest agent report, per node
|
|
150
|
+
gcli cluster:scale-events --cluster '<clusterId>' # manual + autoscaler history
|
|
151
|
+
gcli cluster:cost # month-to-date + monthly estimate
|
|
152
|
+
|
|
153
|
+
# Worker nodes (1-10, billed per node-hour) and control planes (1, 3 or 5)
|
|
154
|
+
gcli cluster:scale --cluster '<clusterId>' --workers 3 --wait
|
|
155
|
+
gcli cluster:scale:control-planes --cluster '<clusterId>' --count 3 --wait
|
|
156
|
+
|
|
157
|
+
# Topology: dedicated workers (needed for autoscaling) or back to one node
|
|
158
|
+
gcli cluster:multi-node --cluster '<clusterId>' --workers 2 --wait
|
|
159
|
+
gcli cluster:single-node --cluster '<clusterId>' --wait
|
|
160
|
+
|
|
161
|
+
# Autoscaling - only the flags you pass change
|
|
162
|
+
gcli cluster:autoscale --cluster '<clusterId>' --enable --min 2 --max 6
|
|
163
|
+
gcli cluster:autoscale --cluster '<clusterId>' --cpuUp 75 --cpuDown 25 --cooldown 20
|
|
164
|
+
gcli cluster:autoscale --cluster '<clusterId>' --disable
|
|
165
|
+
|
|
166
|
+
# Load balancer (billed per hour while enabled)
|
|
167
|
+
gcli cluster:load-balancer --cluster '<clusterId>' --enable --wait
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Declarative clusters (`cluster:apply`)
|
|
171
|
+
|
|
172
|
+
Write the cluster you want in the `cluster:` section of `lambforge.yaml`
|
|
173
|
+
(or a standalone `cluster.yaml`) and let `cluster:apply` make it so: it
|
|
174
|
+
creates the cluster when it doesn't exist, then applies topology, workers,
|
|
175
|
+
control planes, the load balancer and autoscaling - one change at a time,
|
|
176
|
+
waiting for the cluster to be ready between them. Keys you leave out are
|
|
177
|
+
left as they are.
|
|
123
178
|
|
|
124
179
|
```yaml
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
180
|
+
cluster:
|
|
181
|
+
name: prod
|
|
182
|
+
# needed only to create it
|
|
183
|
+
imageId: <hcloud-image-id>
|
|
184
|
+
serverType: cpx22
|
|
185
|
+
location: nbg1
|
|
186
|
+
# desired state
|
|
187
|
+
singleNode: false # true = one node runs everything (cheapest, dev/stage)
|
|
188
|
+
workers: 3 # 1-10; only the initial size while autoscale is enabled
|
|
189
|
+
controlPlanes: 1 # 1, 3 or 5
|
|
190
|
+
loadBalancer: true
|
|
191
|
+
autoscale:
|
|
192
|
+
enabled: true # needs singleNode: false
|
|
193
|
+
minWorkers: 2
|
|
194
|
+
maxWorkers: 6
|
|
195
|
+
cpuScaleUpPercent: 70 # scale up above this (of allocatable)
|
|
196
|
+
memScaleUpPercent: 70
|
|
197
|
+
cpuScaleDownPercent: 30
|
|
198
|
+
memScaleDownPercent: 30
|
|
199
|
+
samplesToScale: 3 # consecutive readings before acting
|
|
200
|
+
cooldownMinutes: 15
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
gcli cluster:apply --dry-run # print the plan, change nothing
|
|
205
|
+
gcli cluster:apply # apply it
|
|
206
|
+
gcli cluster:apply --yes # also steps that remove capacity or the LB IP
|
|
207
|
+
gcli cluster:apply --spec cluster.yaml
|
|
131
208
|
```
|
|
132
209
|
|
|
210
|
+
Steps that remove capacity or release the load balancer's IP (going back to
|
|
211
|
+
`singleNode: true`, `loadBalancer: false`) are skipped unless you pass
|
|
212
|
+
`--yes`. Nodes and the load balancer are billed per started hour.
|
|
213
|
+
|
|
133
214
|
### RabbitMQ Brokers
|
|
134
215
|
|
|
135
216
|
A project may have several RabbitMQ brokers, each optionally scoped to one of its private clusters.
|
|
@@ -158,6 +239,21 @@ storage:
|
|
|
158
239
|
size: SMALL
|
|
159
240
|
```
|
|
160
241
|
|
|
242
|
+
### Message-Queue Triggers
|
|
243
|
+
|
|
244
|
+
A trigger runs a lambda for every message on a RabbitMQ queue (and can publish the response and failures to other queues).
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
gcli mq-trigger:create --name orders --lambda order-handler \
|
|
248
|
+
--request-topic orders --response-topic orders-done --error-topic orders-failed \
|
|
249
|
+
--broker '<brokerId>' # see rabbitmq:list; needed when brokers share queue names
|
|
250
|
+
gcli mq-trigger:update --name orders --max-replicas 5 --threshold 20 # only the flags you pass change
|
|
251
|
+
gcli mq-trigger:list
|
|
252
|
+
gcli mq-trigger:delete --name orders
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Scaling flags: `--max-retries`, `--cool-down-period`, `--polling-interval`, `--min-replicas`, `--max-replicas`, `--threshold` (messages per replica).
|
|
256
|
+
|
|
161
257
|
### Marketplace Plugins
|
|
162
258
|
|
|
163
259
|
Plugins (Redis, MongoDB, NATS, FalkorDB, ...) can be installed on the shared cluster or on any private cluster - the same plugin can be installed on several clusters at once.
|
|
@@ -285,15 +381,25 @@ options:
|
|
|
285
381
|
external: []
|
|
286
382
|
```
|
|
287
383
|
|
|
288
|
-
The same file can also carry `cluster:`, `rabbitmq:`, and `
|
|
384
|
+
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
385
|
|
|
290
386
|
```yaml
|
|
291
|
-
cluster:
|
|
387
|
+
cluster: # every key: see "Declarative clusters" above
|
|
292
388
|
name: prod
|
|
293
389
|
imageId: <hcloud-image-id>
|
|
294
390
|
serverType: cpx22
|
|
295
391
|
location: nbg1
|
|
296
392
|
workers: 2
|
|
393
|
+
loadBalancer: false
|
|
394
|
+
autoscale:
|
|
395
|
+
enabled: true
|
|
396
|
+
minWorkers: 2
|
|
397
|
+
maxWorkers: 5
|
|
398
|
+
|
|
399
|
+
triggers:
|
|
400
|
+
time:
|
|
401
|
+
triggerName: nightly
|
|
402
|
+
cron: '0 2 * * *' # cron syntax or @every 5m / @daily
|
|
297
403
|
|
|
298
404
|
rabbitmq:
|
|
299
405
|
name: events-broker
|
|
@@ -361,7 +467,7 @@ gcli lambda:create --project <projectId> --spec ./lambforge.yaml
|
|
|
361
467
|
`--mcp` and `--mcpGraph <name>` are also available as CLI flags; the array fields
|
|
362
468
|
(`mcpOperations`, `mcpHeaders`, `mcpForwardHeaders`) are spec-only. A full annotated example lives in
|
|
363
469
|
[`example/mcp/lambforge.yaml`](./example/mcp/lambforge.yaml). Client connects at
|
|
364
|
-
`https://<host>/<projectId>/<route>/mcp
|
|
470
|
+
`https://<host>/<projectId>/<route>` (with `route: mcp`: `https://<host>/<projectId>/mcp`).
|
|
365
471
|
|
|
366
472
|
### Conditional Configuration (Environment-Aware Specs)
|
|
367
473
|
|
|
@@ -638,10 +744,23 @@ gcli environment:update
|
|
|
638
744
|
|
|
639
745
|
### Function Lifecycle
|
|
640
746
|
|
|
747
|
+
- **List**: `gcli lambda:list` (`--clusterName <name>` for one cluster's lambdas)
|
|
641
748
|
- **Update**: `gcli lambda:update --name 'my-function' --file ./new-index.ts`
|
|
642
749
|
- **Delete**: `gcli lambda:delete --name 'my-function'`
|
|
643
750
|
- **Get Details**: `gcli lambda:get --name 'my-function'`
|
|
644
751
|
|
|
752
|
+
### Schedules (cron)
|
|
753
|
+
|
|
754
|
+
One time trigger per lambda. The platform calls the lambda's root with a
|
|
755
|
+
GET and an `X-Fission-Timer-Name` header.
|
|
756
|
+
|
|
757
|
+
```bash
|
|
758
|
+
gcli cron:create --lambdaName 'my-function' --triggerName nightly --cron '0 2 * * *'
|
|
759
|
+
gcli cron:create # reads triggers.time (and function.name) from lambforge.yaml
|
|
760
|
+
gcli cron:list
|
|
761
|
+
gcli cron:delete --lambdaName 'my-function'
|
|
762
|
+
```
|
|
763
|
+
|
|
645
764
|
### Monitoring & Testing
|
|
646
765
|
|
|
647
766
|
Debug your functions directly from the terminal.
|
|
@@ -715,6 +834,33 @@ To use this with Claude Desktop or other MCP-compatible tools, add the following
|
|
|
715
834
|
}
|
|
716
835
|
```
|
|
717
836
|
|
|
837
|
+
### AI agent skill
|
|
838
|
+
|
|
839
|
+
Give a coding agent (Claude Code and other agents that read skills) the
|
|
840
|
+
whole platform. Paste this into the agent:
|
|
841
|
+
|
|
842
|
+
```text
|
|
843
|
+
Install the Lambforge skill from https://lambforge.com/skills/platform.md and follow its setup.
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
Or by hand for Claude Code:
|
|
847
|
+
|
|
848
|
+
```bash
|
|
849
|
+
mkdir -p ~/.claude/skills/lambforge && cd ~/.claude/skills/lambforge
|
|
850
|
+
for f in $(curl -fsSL https://lambforge.com/skills/files.txt); do
|
|
851
|
+
curl -fsSLO "https://lambforge.com/skills/$f"
|
|
852
|
+
done
|
|
853
|
+
cp platform.md SKILL.md
|
|
854
|
+
claude mcp add --scope user lambforge -- gcli mcp:start
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
`platform.md` covers setup (install gcli, the login command you run from
|
|
858
|
+
Profile -> CLI - the agent never handles your token, `gcli mcp:start`) and
|
|
859
|
+
the rules, and indexes topic files the agent reads on demand: gcli, MCP
|
|
860
|
+
tools, deploy, REST code and testing, GraphQL and federation, websites,
|
|
861
|
+
MCP servers, secrets, cron and queues, clusters and plugins, operations and
|
|
862
|
+
costs, memory and plans. Source: gql-fission `src/skills/`.
|
|
863
|
+
|
|
718
864
|
## Local AI Models (Ollama runner)
|
|
719
865
|
|
|
720
866
|
Use models running on your own machine in the Lambforge chat - including
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## 2026-10-19 - ci-token-scopes: mq-trigger:list/create/update/delete commands; README documents CI token permissions per command
|
|
2
|
+
|
|
3
|
+
**Feature:** ci-token-scopes · **Type:** feat
|
|
4
|
+
|
|
5
|
+
- New `mq-trigger:list`, `mq-trigger:create`, `mq-trigger:update`,
|
|
6
|
+
`mq-trigger:delete` (`src/commands/triggers/message-queue/`) - message-queue
|
|
7
|
+
triggers had an API and a dashboard page but no CLI. Flags: `--name`,
|
|
8
|
+
`--lambda`, `--request-topic`, `--response-topic`, `--error-topic`,
|
|
9
|
+
`--broker` (RabbitMQ id), scaling counts; `update` reads the current
|
|
10
|
+
trigger and sends it with the passed flags on top (the service needs the
|
|
11
|
+
full spec).
|
|
12
|
+
- README: CI/CD section lists the permission each command needs (CI token
|
|
13
|
+
scopes now cover every project command, incl. clusters for DevOps
|
|
14
|
+
tokens) and a Message-Queue Triggers section; `README-CLI.md`
|
|
15
|
+
regenerated from the built CLI's `--help`.
|
|
16
|
+
- **Test:** `npx jest test/mq-trigger.spec.ts` (flag mapping, create needs
|
|
17
|
+
lambda + queue, numbers validated, update merged over the current trigger).
|
|
18
|
+
- **Debug:** `docs/features/ci-token-scopes.md`; `ci-token-missing-scope`
|
|
19
|
+
comes from the services - reissue the token with that permission.
|
|
20
|
+
- **Verification:** jest 75/75; tsc clean; `gcli mq-trigger:create --help`
|
|
21
|
+
from a fresh build; `release/index.js` restored after the build.
|
|
@@ -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,6 @@ 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 |
|
|
36
|
+
| `ci-token-scopes` | [ci-token-scopes.md](ci-token-scopes.md) | Which permission each command needs; `mq-trigger:*` commands; canonical doc in graphql-server |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ci-token-scopes (gcli slice)
|
|
2
|
+
|
|
3
|
+
**Canonical doc:** `graphql-server/docs/features/ci-token-scopes.md` ·
|
|
4
|
+
**Since:** 2026-10-19
|
|
5
|
+
|
|
6
|
+
gcli itself enforces nothing - a CI/CD token (`gcli login --ci --token …`)
|
|
7
|
+
is checked by the services. What this package owns:
|
|
8
|
+
|
|
9
|
+
- Every project command maps to one permission (README → CI/CD
|
|
10
|
+
Integration has the table). A refused command prints the service error
|
|
11
|
+
`ci-token-missing-scope: <operation> needs <scope>` /
|
|
12
|
+
`ci-token-lambda-not-allowed` / `ci-token-wrong-project`.
|
|
13
|
+
- `mq-trigger:list/create/update/delete`
|
|
14
|
+
(`src/commands/triggers/message-queue/`, `GraphqlClienAPI.
|
|
15
|
+
listMessageQueueTriggers / saveMessageQueueTrigger / deleteMessageQueueTrigger`)
|
|
16
|
+
- the `mq-trigger:*` permissions had no CLI before. `update` reads the
|
|
17
|
+
current trigger and sends it with the given flags on top
|
|
18
|
+
(`mergeOverExisting`): the service hands the payload to Fission as the
|
|
19
|
+
whole spec and picks the cluster by `lambdaName`, so a partial payload
|
|
20
|
+
would drop settings. Counts are validated as whole numbers
|
|
21
|
+
(`toTriggerInput`). The trigger types are declared in `gql-client.ts`
|
|
22
|
+
(not in the bundled introspection yet).
|
|
23
|
+
- Not for CI tokens: `runner:*`, `project:list`, `mcp:start`.
|
|
24
|
+
|
|
25
|
+
**Test:** `npx jest test/mq-trigger.spec.ts`.
|