@inference-gateway/adl-cli 0.64.1 → 0.64.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.
Files changed (2) hide show
  1. package/README.md +130 -53
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -231,7 +231,7 @@ adl init my-agent --defaults
231
231
 
232
232
  # Non-interactive with specific configuration
233
233
  adl init my-agent \
234
- --name "Weather Agent" \
234
+ --name weather-agent \
235
235
  --description "Provides weather information" \
236
236
  --provider deepseek \
237
237
  --model deepseek-v4-flash \
@@ -433,10 +433,24 @@ The `--deployment` flag generates platform-specific deployment configurations:
433
433
  - Configurable resources (CPU, memory), scaling (min/max instances), and service options
434
434
  - Uses direct gcloud commands for truly serverless deployment (no Kubernetes required)
435
435
  - Automatic container building with Docker or Cloud Build integration
436
- - **Kubernetes Deployment**: Creates `k8s/deployment.yaml` with standard Kubernetes manifests
437
- - Enterprise-ready configurations with resource limits and health checks
438
- - ConfigMap and Secret integration for environment variables
439
- - Service and Ingress configurations for load balancing
436
+ - **Kubernetes Deployment**: Creates `k8s/deployment.yaml` containing a `Namespace` named `<name>-ns` and an
437
+ `Agent` custom resource (`apiVersion: core.inference-gateway.com/v1alpha1`)
438
+ - The target cluster must have the Inference Gateway Operator and its `Agent` CRD installed - the operator
439
+ reconciles the `Agent` resource into the underlying workload
440
+ - No Deployment, Service, Ingress, ConfigMap, Secret, health checks or resource limits are generated; those
441
+ are the operator's responsibility
442
+ - The container image defaults to `<name>:<version>` and can be overridden with `spec.deployment.kubernetes.image`:
443
+
444
+ ```yaml
445
+ spec:
446
+ deployment:
447
+ type: kubernetes
448
+ kubernetes:
449
+ image:
450
+ registry: ghcr.io/your-org # optional, prefixed to the repository
451
+ repository: weather-agent # defaults to metadata.name
452
+ tag: 1.2.3 # defaults to metadata.version
453
+ ```
440
454
 
441
455
  ## Agent Definition Language (ADL)
442
456
 
@@ -465,8 +479,11 @@ spec:
465
479
  maxTokens: 4096
466
480
  temperature: 0.7
467
481
  tools:
468
- - name: get_weather
482
+ - id: get_weather
483
+ name: get_weather
469
484
  description: "Get current weather for a city"
485
+ tags:
486
+ - weather
470
487
  schema:
471
488
  type: object
472
489
  properties:
@@ -501,7 +518,7 @@ The complete ADL schema includes:
501
518
  - **services**: Service services with interfaces, factories, and type definitions
502
519
  - **agent**: AI provider configuration (OpenAI, Anthropic, Google, Groq, Mistral, DeepSeek, Cohere, Cloudflare, Moonshot, Ollama, Ollama Cloud, Nvidia)
503
520
  - **tools**: Function-call definitions with JSON schemas, validation, and service injection support
504
- - **skills**: Markdown playbooks (id + optional `bare`, version, source) pulled from the skills registry, fetched as a full directory from a GitHub repo (shorthand or URL), or scaffolded locally; advertised on the agent card and prepended to the system prompt at runtime
521
+ - **skills**: Markdown playbooks (id + optional `bare`, version, source) pulled from the skills registry, fetched as a full directory from a GitHub repo (shorthand or URL), or scaffolded locally into `.agents/skills/<id>/`; advertised on the agent card, and summarised at runtime in an `AVAILABLE SKILLS:` block appended to the system prompt (frontmatter only - the model reads each `SKILL.md` body on demand)
505
522
  - **server**: HTTP server configuration with authentication support
506
523
  - **language**: Programming language-specific settings (Go, Rust, TypeScript) and configurable acronyms
507
524
  - **scm**: Source control management configuration (GitHub, GitLab)
@@ -552,8 +569,11 @@ spec:
552
569
  factory: NewNotificationService
553
570
  description: Multi-channel notification service
554
571
  tools:
555
- - name: query_database
572
+ - id: query_database
573
+ name: query_database
556
574
  description: "Execute database queries with validation"
575
+ tags:
576
+ - database
557
577
  inject:
558
578
  - logger
559
579
  - database
@@ -573,8 +593,11 @@ spec:
573
593
  required:
574
594
  - query
575
595
  - table
576
- - name: send_notification
596
+ - id: send_notification
597
+ name: send_notification
577
598
  description: "Send multi-channel notifications"
599
+ tags:
600
+ - notifications
578
601
  inject:
579
602
  - logger
580
603
  - notifications
@@ -812,7 +835,9 @@ spec:
812
835
  The ADL spec distinguishes two complementary concepts:
813
836
 
814
837
  - **Tools** (`spec.tools`) are function-call entrypoints with explicit JSON schemas. They are generated as code in the target language and registered with the agent's toolbox. The model invokes them by name with structured arguments.
815
- - **Skills** (`spec.skills`) are markdown playbooks (with YAML frontmatter) that describe _when and how_ to use the tools. Each is written to its own directory at `skills/<id>/SKILL.md` in the generated project, advertised on the agent card so orchestrators can discover them, and prepended to the system prompt at runtime. The directory layout matches Anthropic's [agent skills convention](https://github.com/anthropics/skills) - bare skills can ship arbitrary scripts, templates, or reference material alongside `SKILL.md`.
838
+ - **Skills** (`spec.skills`) are markdown playbooks (with YAML frontmatter) that describe _when and how_ to use the tools. Each is written to its own directory at `.agents/skills/<id>/SKILL.md` in the generated project, advertised on the agent card so orchestrators can discover them, and summarised at runtime in an `AVAILABLE SKILLS:` block appended to the system prompt - only the frontmatter is inlined; the model reads each `SKILL.md` body on demand (see [Runtime: AVAILABLE SKILLS manifest + on-demand Read](#runtime-available-skills-manifest--on-demand-read)). The directory layout matches Anthropic's [agent skills convention](https://github.com/anthropics/skills) - bare skills can ship arbitrary scripts, templates, or reference material alongside `SKILL.md`.
839
+
840
+ When `spec.skills` is non-empty, `adl generate` also creates a `.claude/skills` → `../.agents/skills` relative symlink in the generated project, so Claude Code discovers the same skill tree at its conventional path without duplicating any files.
816
841
 
817
842
  A skill entry is small:
818
843
 
@@ -836,9 +861,9 @@ spec:
836
861
 
837
862
  ### Resolution rules
838
863
 
839
- - **`bare: true`** → the CLI scaffolds `skills/<id>/SKILL.md` with frontmatter from the manifest and a TODO body that you author by hand. The whole `skills/<id>/` directory is listed in `.adl-ignore`, so any bundled scripts, templates, or resources you drop alongside `SKILL.md` are preserved on regeneration.
840
- - **`source:` set** → the source must resolve to a public GitHub directory (a `/tree/<ref>/<path>` URL, or one of the shorthand forms below). The CLI pulls the _entire_ directory - `SKILL.md`, reference docs, bundled scripts, anything else - and writes it to `skills/<id>/`. Non-`github.com` URLs are rejected so the same code path always produces a complete skill bundle, not a stray markdown file.
841
- - **Otherwise** → fetch `https://registry.inference-gateway.com/skills/<id>[/<version>].md` (becomes `skills/<id>/SKILL.md`). Override the registry with `ADL_SKILLS_REGISTRY`. Registry-by-id currently ships `SKILL.md` only; if you need bundled assets, use `source:` to point at a GitHub directory.
864
+ - **`bare: true`** → the CLI scaffolds `.agents/skills/<id>/SKILL.md` with frontmatter from the manifest and a TODO body that you author by hand. The whole `.agents/skills/<id>/` directory is listed in `.adl-ignore`, so any bundled scripts, templates, or resources you drop alongside `SKILL.md` are preserved on regeneration.
865
+ - **`source:` set** → the source must resolve to a public GitHub directory (a `/tree/<ref>/<path>` URL, or one of the shorthand forms below). The CLI pulls the _entire_ directory - `SKILL.md`, reference docs, bundled scripts, anything else - and writes it to `.agents/skills/<id>/`. Non-`github.com` URLs are rejected so the same code path always produces a complete skill bundle, not a stray markdown file.
866
+ - **Otherwise** → fetch `https://registry.inference-gateway.com/skills/<id>[/<version>].md` (becomes `.agents/skills/<id>/SKILL.md`). Override the registry with `ADL_SKILLS_REGISTRY`. Registry-by-id currently ships `SKILL.md` only; if you need bundled assets, use `source:` to point at a GitHub directory.
842
867
 
843
868
  ### Licensing
844
869
 
@@ -894,7 +919,7 @@ The 3-segment form assumes a `skills/<id>/` subdirectory inside the repo (the co
894
919
 
895
920
  ### Runtime: AVAILABLE SKILLS manifest + on-demand Read
896
921
 
897
- The generated agent advertises skills to the LLM via a frontmatter-only manifest, **not** by inlining SKILL.md bodies. At startup it walks first-level subdirectories under `skills/` (overridable with `A2A_SKILLS_DIR`), parses each `<id>/SKILL.md`'s YAML frontmatter, and appends an `AVAILABLE SKILLS:` block to the system prompt:
922
+ The generated agent advertises skills to the LLM via a frontmatter-only manifest, **not** by inlining SKILL.md bodies. At startup it walks first-level subdirectories under `.agents/skills` (overridable with `A2A_SKILLS_DIR`), parses each `<id>/SKILL.md`'s YAML frontmatter, and appends an `AVAILABLE SKILLS:` block to the system prompt:
898
923
 
899
924
  ```text
900
925
  AVAILABLE SKILLS:
@@ -903,12 +928,14 @@ skill's description, read the SKILL.md file at the listed path using the Read
903
928
  tool, then follow its instructions.
904
929
 
905
930
  - incident-response: Use this when the user reports a production incident...
906
- Path: skills/incident-response/SKILL.md
931
+ Path: .agents/skills/incident-response/SKILL.md
907
932
  - pdf: Fill in PDF forms and extract structured data from PDFs.
908
- Path: skills/pdf/SKILL.md
933
+ Path: .agents/skills/pdf/SKILL.md
909
934
  ```
910
935
 
911
- The model loads each SKILL.md body on demand via the `Read` built-in tool, and executes any bundled scripts via `Bash` / `Write` / `Edit`. **A skills-using agent must therefore list `- id: read` in `spec.tools` and set `spec.config.tools.read.enabled: true`** - the validator enforces this; see [Reserved built-in tools](#reserved-built-in-tools).
936
+ The model loads each SKILL.md body on demand via the `Read` built-in tool, and executes any bundled scripts via `Bash` / `Write` / `Edit`. **A skills-using agent must therefore list `- id: read` in `spec.tools` and set `spec.config.tools.read.enabled: true`** - see [Reserved built-in tools](#reserved-built-in-tools). `adl validate` does not enforce this: when `spec.skills` and `spec.agent` are both set, `validateSkills` (`internal/schema/validator.go`) emits a non-fatal **warning** if `- id: read` is missing from `spec.tools` or `spec.config.tools.read.enabled` is not `true`. The manifest still validates; the agent just cannot load any SKILL.md body at runtime.
937
+
938
+ The `Read` built-in always allows the skills directory regardless of `allowed_roots`, so skills work even with a narrow read allowlist.
912
939
 
913
940
  ### Reserved built-in tools
914
941
 
@@ -932,6 +959,8 @@ spec:
932
959
  - id: query_database # user tool: full entry still required
933
960
  name: query_database
934
961
  description: "..."
962
+ tags:
963
+ - database
935
964
  schema: { type: object, ... }
936
965
  ```
937
966
 
@@ -944,26 +973,36 @@ spec:
944
973
  read:
945
974
  enabled: true
946
975
  max_lines: 2000 # offset/limit default window
947
- allowed_roots: [] # empty = project-wide
976
+ allowed_roots: # REQUIRED: empty denies every path (fail-closed)
977
+ - ./docs
978
+ - ./data
948
979
  bash:
949
980
  enabled: true
950
981
  whitelist: [ls, cat, grep, jq]
951
982
  timeout_seconds: 30
983
+ working_dir: ./workspace # optional cwd for the command (default: process cwd)
952
984
  write:
953
985
  enabled: false # listed but explicitly disabled
986
+ allowed_roots: # REQUIRED when enabled: empty denies every path
987
+ - ./output
954
988
  edit:
955
989
  enabled: true
990
+ allowed_roots: # REQUIRED: empty denies every path
991
+ - ./output
956
992
  fetch:
957
993
  enabled: true
958
- allowed_domains: # whitelist of hosts (empty = unrestricted, discouraged)
994
+ allowed_domains: # whitelist of hosts (empty = any public host)
959
995
  - example.com
960
996
  - .api.dev # entries starting with "." match any subdomain
997
+ allow_internal: false # true to permit loopback/private/link-local hosts
961
998
  max_bytes: 10485760 # 10 MiB cap on response body (default)
962
999
  timeout_seconds: 30 # total request timeout (default)
963
1000
  download_dir: /tmp # root for save_path writes (default /tmp)
964
1001
  allow_downloads: false # set true to allow writing response bodies to disk
965
1002
  ```
966
1003
 
1004
+ **`allowed_roots` fails closed.** In the Go and Rust built-in templates an empty (or omitted) `allowed_roots` denies **every** path for `read`, `write` and `edit` - it is not "project-wide". You must list the roots you want to permit. Two directories are exempt: `read` always allows the skills directory (`A2A_SKILLS_DIR`, default `.agents/skills`) and the artifacts directory (`A2A_ARTIFACTS_STORAGE_BASE_PATH`, default `/tmp/artifacts`); `write` and `edit` always allow the artifacts directory.
1005
+
967
1006
  Values are baked into the generated constructor as compile-time literals - there's no `ToolsConfig` struct in `config/config.go` because reserved-namespace sections are intentionally skipped. The validator decodes each `spec.config.tools.<id>` block into the built-in's typed shape and rejects unknown keys (typos like `tymeout_seconds` fail with `spec.config.tools.bash.tymeout_seconds`).
968
1007
 
969
1008
  Runtime overrides for Bash (read inside `tools/bash.go`):
@@ -973,8 +1012,10 @@ Runtime overrides for Bash (read inside `tools/bash.go`):
973
1012
 
974
1013
  Runtime overrides for Fetch (resolution precedence: env > compile-time literal > default-disabled):
975
1014
 
976
- - Go: `TOOLS_FETCH_ENABLED`, `TOOLS_FETCH_ALLOWED_DOMAINS`, `TOOLS_FETCH_MAX_BYTES`, `TOOLS_FETCH_TIMEOUT_SECONDS`, `TOOLS_FETCH_DOWNLOAD_DIR`, `TOOLS_FETCH_ALLOW_DOWNLOADS` (envconfig-style; comma-separated for lists).
977
- - Rust: `A2A_FETCH_DISABLED=1` (kill switch), `A2A_FETCH_ALLOWED_DOMAINS`, `A2A_FETCH_MAX_BYTES`, `A2A_FETCH_TIMEOUT_SECONDS`, `A2A_FETCH_DOWNLOAD_DIR`, `A2A_FETCH_ALLOW_DOWNLOADS`.
1015
+ - Go: `TOOLS_FETCH_ENABLED`, `TOOLS_FETCH_ALLOWED_DOMAINS`, `TOOLS_FETCH_ALLOW_INTERNAL`, `TOOLS_FETCH_MAX_BYTES`, `TOOLS_FETCH_TIMEOUT_SECONDS`, `TOOLS_FETCH_DOWNLOAD_DIR`, `TOOLS_FETCH_ALLOW_DOWNLOADS` (envconfig-style; comma-separated for lists).
1016
+ - Rust: `A2A_FETCH_DISABLED=1` (kill switch), `A2A_FETCH_ALLOWED_DOMAINS`, `A2A_FETCH_ALLOW_INTERNAL`, `A2A_FETCH_MAX_BYTES`, `A2A_FETCH_TIMEOUT_SECONDS`, `A2A_FETCH_DOWNLOAD_DIR`, `A2A_FETCH_ALLOW_DOWNLOADS`.
1017
+
1018
+ **An empty `allowed_domains` is not unrestricted.** With no allowlist, `fetch` still refuses any host that resolves to a loopback, private (RFC 1918 / IPv6 ULA), link-local or unspecified address - an SSRF guard applied to the initial request and to every redirect hop. Set `allow_internal: true` (or `TOOLS_FETCH_ALLOW_INTERNAL` / `A2A_FETCH_ALLOW_INTERNAL` at runtime) to reach internal hosts, e.g. when calling a sidecar or a service on the cluster network. When `allowed_domains` _is_ non-empty the allowlist decides on its own and `allow_internal` is not consulted.
978
1019
 
979
1020
  The Fetch tool supports `GET` and `HEAD` only. Optional `save_path` writes the response body to a path resolved under `download_dir` - absolute paths and parent-directory traversal (`..`) are rejected, and the request fails unless `allow_downloads: true`. Bodies (and on-disk files) are capped at `max_bytes`; oversized responses are truncated and the result payload sets `"truncated": true`. The Go template uses only the standard library (`net/http`); the Rust template adds `reqwest` (rustls-tls + json features) to `Cargo.toml` automatically when `- id: fetch` is present in `spec.tools`.
980
1021
 
@@ -1011,8 +1052,11 @@ spec:
1011
1052
  factory: NewCacheRepository
1012
1053
  description: High-performance caching layer for API responses
1013
1054
  tools:
1014
- - name: create_event
1055
+ - id: create_event
1056
+ name: create_event
1015
1057
  description: "Create a new calendar event"
1058
+ tags:
1059
+ - calendar
1016
1060
  inject:
1017
1061
  - logger # Built-in, always available
1018
1062
  - googleCalendar # Custom service
@@ -1089,8 +1133,11 @@ spec:
1089
1133
  factory: NewDatabaseService
1090
1134
  description: PostgreSQL database service
1091
1135
  tools:
1092
- - name: export_report
1136
+ - id: export_report
1137
+ name: export_report
1093
1138
  description: "Export data and email report"
1139
+ tags:
1140
+ - reporting
1094
1141
  inject:
1095
1142
  - logger
1096
1143
  - database
@@ -1105,7 +1152,7 @@ spec:
1105
1152
 
1106
1153
  **Generated Tool Code:**
1107
1154
 
1108
- > Illustrative example - see `internal/templates/languages/go/tool.go.tmpl` for the actual template. Generated tools live under `tools/`, not `skills/`.
1155
+ > Illustrative example - see `internal/templates/languages/go/tool.go.tmpl` for the actual template. Generated tools live under `tools/`, not `.agents/skills/`.
1109
1156
 
1110
1157
  ```go
1111
1158
  type ExportReportTool struct {
@@ -1199,8 +1246,8 @@ my-agent/
1199
1246
  ├── tools/
1200
1247
  │ ├── create_event.go # Function-call tools with injected services
1201
1248
  │ └── list_events.go
1202
- ├── skills/
1203
- │ ├── calendar-workflow/ # Markdown playbooks loaded into the system prompt
1249
+ ├── .agents/skills/
1250
+ │ ├── calendar-workflow/ # Markdown playbooks read on demand by the model
1204
1251
  │ │ └── SKILL.md
1205
1252
  │ └── meeting-summary/
1206
1253
  │ └── SKILL.md
@@ -1239,7 +1286,7 @@ Skills automatically receive injected services as constructor parameters:
1239
1286
 
1240
1287
  **Example `tools/create_event.go`:**
1241
1288
 
1242
- > Illustrative example - see `internal/templates/languages/go/tool.go.tmpl` for the actual template. Generated tools live under `tools/`, not `skills/`.
1289
+ > Illustrative example - see `internal/templates/languages/go/tool.go.tmpl` for the actual template. Generated tools live under `tools/`, not `.agents/skills/`.
1243
1290
 
1244
1291
  ```go
1245
1292
  type CreateEventTool struct {
@@ -1301,11 +1348,13 @@ my-go-agent/
1301
1348
  ├── tools/ # Function-call tool implementations
1302
1349
  │ ├── query_database.go # Individual tool files (TODO placeholders)
1303
1350
  │ └── send_notification.go
1304
- ├── skills/ # Skill directories (SKILL.md + optional bundled assets)
1305
- │ ├── incident-response/ # Loaded into the system prompt at startup
1351
+ ├── .agents/skills/ # Skill directories (SKILL.md + optional bundled assets)
1352
+ │ ├── incident-response/ # Frontmatter listed in the AVAILABLE SKILLS block at startup
1306
1353
  │ │ └── SKILL.md
1307
1354
  │ └── support-handoff/
1308
1355
  │ └── SKILL.md
1356
+ ├── .claude/
1357
+ │ └── skills -> ../.agents/skills # Symlink so Claude Code finds the same tree
1309
1358
  ├── Taskfile.yml # Development tasks (build, test, lint)
1310
1359
  ├── Dockerfile # Container configuration
1311
1360
  ├── .adl-ignore # Files to protect from regeneration
@@ -1345,11 +1394,13 @@ my-rust-agent/
1345
1394
  │ ├── mod.rs # Module declarations
1346
1395
  │ ├── query_database.rs # Individual tool implementations
1347
1396
  │ └── send_notification.rs
1348
- ├── skills/ # Skill directories (SKILL.md + optional bundled assets)
1397
+ ├── .agents/skills/ # Skill directories (SKILL.md + optional bundled assets)
1349
1398
  │ ├── incident-response/
1350
1399
  │ │ └── SKILL.md
1351
1400
  │ └── support-handoff/
1352
1401
  │ └── SKILL.md
1402
+ ├── .claude/
1403
+ │ └── skills -> ../.agents/skills # Symlink so Claude Code finds the same tree
1353
1404
  ├── Cargo.toml # Rust package configuration
1354
1405
  ├── Taskfile.yml # Development tasks
1355
1406
  ├── Dockerfile # Rust-optimized container
@@ -1380,11 +1431,13 @@ my-typescript-agent/
1380
1431
  │ ├── index.ts # Toolbox wiring
1381
1432
  │ ├── query_database.ts # Individual tool implementations (TODO placeholders)
1382
1433
  │ └── send_notification.ts
1383
- ├── skills/ # Skill directories (SKILL.md + optional bundled assets)
1434
+ ├── .agents/skills/ # Skill directories (SKILL.md + optional bundled assets)
1384
1435
  │ ├── incident-response/
1385
1436
  │ │ └── SKILL.md
1386
1437
  │ └── support-handoff/
1387
1438
  │ └── SKILL.md
1439
+ ├── .claude/
1440
+ │ └── skills -> ../.agents/skills # Symlink so Claude Code finds the same tree
1388
1441
  ├── package.json # Node package definition + scripts
1389
1442
  ├── tsconfig.json # TypeScript compiler configuration
1390
1443
  ├── Taskfile.yml # Development tasks
@@ -1440,7 +1493,7 @@ This creates a GitHub Actions workflow (`.github/workflows/ci.yml`) that include
1440
1493
 
1441
1494
  - **Automated Testing**: Runs all tests on every push and pull request
1442
1495
  - **Code Quality**: Format checking and linting
1443
- - **Multi-Environment**: Supports main and develop branches
1496
+ - **Branch Scope**: Triggers on push and pull requests targeting `main`
1444
1497
  - **Caching**: Go module caching for faster builds
1445
1498
  - **Task Integration**: Uses the generated Taskfile for consistent build steps
1446
1499
 
@@ -1489,11 +1542,13 @@ gh workflow run cd.yml
1489
1542
  **Container Registry**: Published images are available at:
1490
1543
 
1491
1544
  ```text
1545
+ ghcr.io/your-org/your-agent:1.0.0
1492
1546
  ghcr.io/your-org/your-agent:latest
1493
- ghcr.io/your-org/your-agent:v1.0.0
1494
- ghcr.io/your-org/your-agent:1.0
1495
1547
  ```
1496
1548
 
1549
+ The version tag carries no `v` prefix (the git tag does), and `:latest` is only pushed from `main` - releases
1550
+ from `rc/*` branches publish the version tag alone.
1551
+
1497
1552
  ## CloudRun Deployment
1498
1553
 
1499
1554
  The ADL CLI provides native support for deploying A2A agents to Google Cloud Run, offering a truly serverless deployment experience without Kubernetes complexity.
@@ -1589,10 +1644,15 @@ This creates:
1589
1644
 
1590
1645
  **Required GitHub Secrets:**
1591
1646
 
1592
- - `GCP_SA_KEY`: Service account key JSON
1647
+ - `GCP_CREDENTIALS`: Service account credentials JSON (used by the CloudRun deploy job)
1593
1648
  - `GCP_PROJECT_ID`: Google Cloud project ID
1594
1649
  - `GCP_REGION`: Deployment region (e.g., us-central1)
1595
1650
 
1651
+ The same `.github/workflows/cd.yml` also contains deploy jobs for the other platforms, which require:
1652
+
1653
+ - `KUBECONFIG`: Kubeconfig for the target cluster (Kubernetes deploy job)
1654
+ - `VERCEL_TOKEN`: Vercel API token (Vercel deploy job)
1655
+
1596
1656
  ### CloudRun Benefits
1597
1657
 
1598
1658
  - **Truly Serverless**: No Kubernetes clusters or infrastructure management
@@ -1847,14 +1907,28 @@ Enable OpenTelemetry instrumentation for the generated agent:
1847
1907
  spec:
1848
1908
  telemetry:
1849
1909
  enabled: true
1910
+ traces:
1911
+ exporter:
1912
+ otlp:
1913
+ endpoint: http://localhost:4318
1914
+ protocol: http/protobuf # grpc or http/protobuf
1915
+ metrics:
1916
+ exporter:
1917
+ prometheus: # pull endpoint - Go only
1918
+ host: 0.0.0.0
1919
+ port: 9464
1850
1920
  ```
1851
1921
 
1852
- The manifest field is a single on/off switch - exporter endpoints, ports, and sampling stay runtime concerns configured via environment variables in the generated `.env.example`:
1922
+ `enabled` is the master switch; the optional `traces.exporter` and `metrics.exporter` blocks pick how each signal leaves the agent. Traces accept `otlp` (`endpoint`, `protocol`); metrics accept either `otlp` (same fields) or `prometheus` (`host`, `port`). Omitting a signal's exporter disables it (`none`). Every field is a default only - each one renders into the generated `.env.example` and is overridden by the environment at runtime. Auth headers, credentials, and sampling stay runtime-only concerns.
1853
1923
 
1854
- - **Go**: the ADK spans every tool call (`tool.<name>`, carrying the propagated `session.id`/`gen_ai.tool.call.id`) and the generator surfaces `A2A_TELEMETRY_ENABLED`, `A2A_TELEMETRY_METRICS_PORT`/`_HOST`, `A2A_TELEMETRY_TRACE_ENABLED`/`_ENDPOINT`/`_HEADERS` in `.env.example`.
1855
- - **TypeScript**: wires the ADK's `createTelemetryProvider` into `src/index.ts` (no extra npm dependencies) and surfaces `TELEMETRY_ENABLED` plus the standard `OTEL_EXPORTER_OTLP_*` / `OTEL_SERVICE_*` variables in `.env.example`.
1924
+ > **Note:** Prometheus pull is Go-only - the TypeScript ADK does not support it yet, and the validator warns when a TypeScript manifest configures it.
1925
+
1926
+ - **Go**: the ADK spans every tool call (`tool.<name>`, carrying the propagated `session.id`/`gen_ai.tool.call.id`) and the generator surfaces `A2A_TELEMETRY_ENABLED` plus `A2A_OTEL_TRACES_EXPORTER`, `A2A_OTEL_METRICS_EXPORTER`, `A2A_OTEL_EXPORTER_OTLP_ENDPOINT`/`_PROTOCOL` and `A2A_OTEL_EXPORTER_PROMETHEUS_HOST`/`_PORT` in `.env.example`. The Go ADK nests its whole config under the `A2A_` prefix, so each standard `OTEL_*` name is read as `A2A_OTEL_*`; it has no per-signal OTLP variants.
1927
+ - **TypeScript**: wires the ADK's `createTelemetryProvider` into `src/index.ts` (no extra npm dependencies) and surfaces the same `A2A_TELEMETRY_ENABLED` / `A2A_OTEL_*` names, using the per-signal `A2A_OTEL_EXPORTER_OTLP_TRACES_*` / `_METRICS_*` forms when traces and metrics push to different collectors. `A2A_OTEL_SERVICE_NAME` / `_VERSION` are emitted commented out. The generated `src/index.ts` mirrors each `A2A_OTEL_*` variable onto its bare `OTEL_*` name at startup, since the OpenTelemetry Node SDK reads the unprefixed names.
1856
1928
 
1857
1929
  > **Note:** Telemetry generation currently supports Go and TypeScript only; Rust agents ignore `spec.telemetry`.
1930
+ >
1931
+ > `.env.example` is only generated when `spec.development.sandbox.dockerCompose.enabled: true`.
1858
1932
 
1859
1933
  **Examples:**
1860
1934
 
@@ -1881,6 +1955,8 @@ spec:
1881
1955
  `enabled` is the master switch. When true (and omitted the block is off), the generator wires an `MCPClientManager` into `main.go` that connects to the servers in the background, discovers their tools, and registers two selector tools - `mcp_list_tools` and `mcp_call_tool` - into the agent's toolbox. Everything else is a runtime concern: each `mcp` field maps 1:1 to an `A2A_MCP_*` variable in the generated `.env.example` (the manifest value is the default, overridden by the environment). `A2A_MCP_SERVERS` is derived from the `http` servers' base URLs. Defaults: `endpoint=/mcp`, `refreshInterval=5m`, `dialTimeout=30s`, `callTimeout=30s`, `maxRetries=0`, `retryInterval=2s`, `retryMaxInterval=30s`.
1882
1956
 
1883
1957
  > **Note:** The ADK MCP client is generated for Go agents only and is streamable-HTTP-only; `stdio`/`sse` servers are dropped from `A2A_MCP_SERVERS` (the validator warns), and the block is ignored for TypeScript/Rust agents.
1958
+ >
1959
+ > `.env.example` is only generated when `spec.development.sandbox.dockerCompose.enabled: true`.
1884
1960
 
1885
1961
  **Example:**
1886
1962
 
@@ -2004,7 +2080,7 @@ Each language has its own file mapping that determines what gets generated:
2004
2080
  - `internal/{service}/{service}.go` → Service implementation per ADL service
2005
2081
  - `tools/{toolname}.go` → Individual function-call tool implementations
2006
2082
  - `tools/{builtin}.go` + `tools/{builtin}_test.go` → Reserved built-in tool implementations (read, bash, write, edit, fetch)
2007
- - `skills/{skillid}/SKILL.md` → Markdown skill playbooks (loaded into system prompt at runtime)
2083
+ - `.agents/skills/{skillid}/SKILL.md` → Markdown skill playbooks (frontmatter listed in the runtime `AVAILABLE SKILLS:` block; body read on demand)
2008
2084
  - `go.mod` → Go module configuration
2009
2085
  - `Dockerfile` → Container image
2010
2086
  - `.dockerignore` → Docker build exclusions
@@ -2020,9 +2096,9 @@ Each language has its own file mapping that determines what gets generated:
2020
2096
  - `CLAUDE.md`, `GEMINI.md`, `AGENTS.md` → AI assistant documentation (conditional on AI toggles)
2021
2097
  - `.github/ISSUE_TEMPLATE/*.md` → GitHub issue templates (conditional on SCM config)
2022
2098
  - `.github/dependabot.yml` → Dependabot configuration (conditional on SCM config)
2023
- - CI workflow (`.github/workflows/ci.go.yaml`) → Conditional on SCM CI toggle
2024
- - CD workflow (`.github/workflows/cd.yaml`) → Conditional on SCM CD toggle
2025
- - AI agent workflows (`.github/workflows/ai-*.yaml`) → Conditional on AI orchestrator toggles
2099
+ - CI workflow (`.github/workflows/ci.yml`) → Conditional on SCM CI toggle
2100
+ - CD workflow (`.github/workflows/cd.yml`) → Conditional on SCM CD toggle
2101
+ - AI agent workflows (`.github/workflows/claude.yml`, `codex.yml`, `gemini.yml`, `infer.yml`) → Conditional on AI orchestrator toggles
2026
2102
 
2027
2103
  **Rust Projects:**
2028
2104
 
@@ -2030,7 +2106,7 @@ Each language has its own file mapping that determines what gets generated:
2030
2106
  - `src/tools/{toolname}.rs` → Tool descriptor + handler
2031
2107
  - `src/tools/{builtin}.rs` → Reserved built-in tool implementations (read, bash, write, edit, fetch)
2032
2108
  - `src/tools/mod.rs` → Module declarations
2033
- - `skills/{skillid}/SKILL.md` → Markdown skill playbooks
2109
+ - `.agents/skills/{skillid}/SKILL.md` → Markdown skill playbooks
2034
2110
  - `Cargo.toml` → Rust package configuration
2035
2111
  - `Dockerfile` → Container image
2036
2112
  - `.dockerignore` → Docker build exclusions
@@ -2046,9 +2122,9 @@ Each language has its own file mapping that determines what gets generated:
2046
2122
  - `CLAUDE.md`, `GEMINI.md`, `AGENTS.md` → AI assistant documentation (conditional on AI toggles)
2047
2123
  - `.github/ISSUE_TEMPLATE/*.md` → GitHub issue templates (conditional on SCM config)
2048
2124
  - `.github/dependabot.yml` → Dependabot configuration (conditional on SCM config)
2049
- - CI workflow (`.github/workflows/ci.rust.yaml`) → Conditional on SCM CI toggle
2050
- - CD workflow (`.github/workflows/cd.yaml`) → Conditional on SCM CD toggle
2051
- - AI agent workflows (`.github/workflows/ai-*.yaml`) → Conditional on AI orchestrator toggles
2125
+ - CI workflow (`.github/workflows/ci.yml`) → Conditional on SCM CI toggle
2126
+ - CD workflow (`.github/workflows/cd.yml`) → Conditional on SCM CD toggle
2127
+ - AI agent workflows (`.github/workflows/claude.yml`, `codex.yml`, `gemini.yml`, `infer.yml`) → Conditional on AI orchestrator toggles
2052
2128
 
2053
2129
  **TypeScript Projects:**
2054
2130
 
@@ -2059,7 +2135,7 @@ Each language has its own file mapping that determines what gets generated:
2059
2135
  - `src/tools/{toolname}.ts` → Individual function-call tool implementations
2060
2136
  - `src/tools/index.ts` → Tool module barrel export
2061
2137
  - `src/worker.ts` → Cloudflare Worker entrypoint (only when `spec.deployment.type: cloudflare`)
2062
- - `skills/{skillid}/SKILL.md` → Markdown skill playbooks
2138
+ - `.agents/skills/{skillid}/SKILL.md` → Markdown skill playbooks
2063
2139
  - `package.json` → Node.js package configuration
2064
2140
  - `pnpm-workspace.yaml` → pnpm workspace configuration
2065
2141
  - `tsconfig.json` → TypeScript compiler configuration
@@ -2078,9 +2154,9 @@ Each language has its own file mapping that determines what gets generated:
2078
2154
  - `CLAUDE.md`, `GEMINI.md`, `AGENTS.md` → AI assistant documentation (conditional on AI toggles)
2079
2155
  - `.github/ISSUE_TEMPLATE/*.md` → GitHub issue templates (conditional on SCM config)
2080
2156
  - `.github/dependabot.yml` → Dependabot configuration (conditional on SCM config)
2081
- - CI workflow (`.github/workflows/ci.typescript.yaml`) → Conditional on SCM CI toggle
2082
- - CD workflow (`.github/workflows/cd.yaml`) → Conditional on SCM CD toggle
2083
- - AI agent workflows (`.github/workflows/ai-*.yaml`) → Conditional on AI orchestrator toggles
2157
+ - CI workflow (`.github/workflows/ci.yml`) → Conditional on SCM CI toggle
2158
+ - CD workflow (`.github/workflows/cd.yml`) → Conditional on SCM CD toggle
2159
+ - AI agent workflows (`.github/workflows/claude.yml`, `codex.yml`, `gemini.yml`, `infer.yml`) → Conditional on AI orchestrator toggles
2084
2160
 
2085
2161
  ### Template Context
2086
2162
 
@@ -2252,13 +2328,14 @@ Each language has sensible defaults:
2252
2328
 
2253
2329
  **Go Projects:**
2254
2330
 
2255
- - `go fmt ./...` - Format all Go source files
2256
2331
  - `go mod tidy` - Download dependencies and clean up go.mod
2332
+ - `go fmt ./...` - Format all Go source files
2257
2333
 
2258
2334
  **Rust Projects:**
2259
2335
 
2260
2336
  - `cargo fmt` - Format all Rust source files
2261
- - `cargo check` - Check the project for errors
2337
+
2338
+ **TypeScript Projects:** no default hooks run.
2262
2339
 
2263
2340
  ### Custom Hooks
2264
2341
 
@@ -2288,7 +2365,7 @@ spec:
2288
2365
  - **Command Execution**: Commands run in the generated project directory
2289
2366
  - **Error Handling**: Failed commands show warnings but don't stop generation
2290
2367
  - **Sequential Execution**: Commands run in the order specified
2291
- - **Shell Support**: Commands are executed through the system shell
2368
+ - **No Shell**: Each command is split on whitespace and executed directly - pipes, redirects, `&&`, quoting, and variable expansion do not work. Put anything that needs a shell into a script and invoke it (`./scripts/setup.sh`).
2292
2369
 
2293
2370
  ### Example Configurations
2294
2371
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inference-gateway/adl-cli",
3
- "version": "0.64.1",
3
+ "version": "0.64.2",
4
4
  "description": "Scaffold complete A2A (Agent-to-Agent) projects from YAML Agent Definition Language (ADL) manifests. Thin npm wrapper around the native adl binary.",
5
5
  "bin": {
6
6
  "adl": "bin/run.js"