@netlify/agent-runner-cli 1.30.0 → 1.30.1-broken.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/bin-local.d.ts +1 -0
- package/dist/bin-local.js +301 -0
- package/dist/bin.js +225 -78
- package/dist/index.d.ts +64 -12
- package/dist/index.js +211 -77
- package/dist/scripts/scaffold.d.ts +2 -0
- package/dist/scripts/scaffold.js +13 -0
- package/dist/skills/frontend-design/SKILL.md +86 -0
- package/dist/skills/general-database/SKILL.md +45 -0
- package/dist/skills/netlify-ai-gateway/SKILL.md +411 -0
- package/dist/skills/netlify-blobs/SKILL.md +421 -0
- package/dist/skills/netlify-database/SKILL.md +423 -0
- package/dist/skills/netlify-edge-functions/SKILL.md +478 -0
- package/dist/skills/netlify-forms/SKILL.md +358 -0
- package/dist/skills/netlify-forms/scripts/enable.cjs +12 -0
- package/dist/skills/netlify-functions/SKILL.md +478 -0
- package/dist/skills/netlify-identity/SKILL.md +632 -0
- package/dist/skills/netlify-identity/scripts/enable.cjs +12 -0
- package/dist/skills/netlify-image-cdn/SKILL.md +244 -0
- package/package.json +40 -28
- package/scripts/scenarios/install-skills.mjs +57 -0
- package/scripts/scenarios/netlify-deploy.mjs +311 -0
- package/scripts/scenarios/prewarm-template-mirror.mjs +69 -0
- package/patches/@google+gemini-cli+0.1.17.patch +0 -87
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: netlify-image-cdn
|
|
3
|
+
description: Transform and optimize images on-demand using Netlify Image CDN. Use when implementing responsive images, format conversion, resizing, cropping, or dynamic image optimization without build-time processing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Netlify Image CDN
|
|
7
|
+
|
|
8
|
+
Netlify Image CDN transforms and optimizes images on demand at the edge without impacting build times. It handles
|
|
9
|
+
content negotiation to serve the most efficient format and caches transformed images for fast delivery.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
All Netlify projects have a `/.netlify/images` route without any additional enablement. Use it with query parameters to
|
|
14
|
+
transform any image:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<!-- Resize to 400px wide, convert to WebP -->
|
|
18
|
+
<img src="/.netlify/images?url=/photo.jpg&w=400&fm=webp" alt="Optimized photo" />
|
|
19
|
+
|
|
20
|
+
<!-- Cover crop to 200x200 square -->
|
|
21
|
+
<img src="/.netlify/images?url=/photo.jpg&w=200&h=200&fit=cover" alt="Cropped photo" />
|
|
22
|
+
|
|
23
|
+
<!-- Transform a remote image -->
|
|
24
|
+
<img src="/.netlify/images?url=https://example.com/image.jpg&w=800&q=80" alt="Remote image" />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Query Parameters
|
|
28
|
+
|
|
29
|
+
| Parameter | Required | Type | Description |
|
|
30
|
+
|-----------|----------|------|-------------|
|
|
31
|
+
| `url` | Yes | `string` | Source image path (relative) or URL (remote, requires config) |
|
|
32
|
+
| `w` | No | `integer` | Width in pixels |
|
|
33
|
+
| `h` | No | `integer` | Height in pixels |
|
|
34
|
+
| `fit` | No | `string` | Resize mode: `contain` (default), `cover`, `fill` |
|
|
35
|
+
| `position` | No | `string` | Crop anchor for `fit=cover`: `center` (default), `top`, `bottom`, `left`, `right` |
|
|
36
|
+
| `fm` | No | `string` | Output format: `avif`, `jpg`, `png`, `webp`, `gif`, `blurhash` |
|
|
37
|
+
| `q` | No | `integer` | Quality 1-100 for lossy formats (default: 75) |
|
|
38
|
+
|
|
39
|
+
The `url` value must be URI-encoded when it contains special characters.
|
|
40
|
+
|
|
41
|
+
## Fit Modes
|
|
42
|
+
|
|
43
|
+
| `fit=` | Aspect Ratio Maintained | Crops | Always Returns Exact Dimensions |
|
|
44
|
+
|--------|------------------------|-------|-------------------------------|
|
|
45
|
+
| `contain` (default) | Yes | No | No, one dimension may be smaller |
|
|
46
|
+
| `cover` | Yes | Yes | Yes, crops excess after proportional resize |
|
|
47
|
+
| `fill` | No | No | Yes, stretches/squishes to exact dimensions |
|
|
48
|
+
|
|
49
|
+
### `fit=contain` (default)
|
|
50
|
+
|
|
51
|
+
Resizes proportionally to fit within the specified dimensions. If only one dimension is given, the other is calculated
|
|
52
|
+
to maintain aspect ratio.
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<img src="/.netlify/images?url=/photo.jpg&w=600&h=400&fit=contain" />
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### `fit=cover`
|
|
59
|
+
|
|
60
|
+
Resizes proportionally to fill the dimensions, then crops excess pixels. Requires **both** `w` and `h`. Use `position`
|
|
61
|
+
to control which area is retained.
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<img src="/.netlify/images?url=/photo.jpg&w=300&h=300&fit=cover&position=top" />
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `fit=fill`
|
|
68
|
+
|
|
69
|
+
Stretches the image to exactly match the specified dimensions. May distort the image if aspect ratios differ.
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<img src="/.netlify/images?url=/photo.jpg&w=400&h=200&fit=fill" />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Format Negotiation
|
|
76
|
+
|
|
77
|
+
When `fm` is **not** specified, Image CDN automatically negotiates the best format using the browser's `Accept` header:
|
|
78
|
+
|
|
79
|
+
1. Use `webp` if the browser accepts it
|
|
80
|
+
2. Otherwise use `avif` if accepted
|
|
81
|
+
3. Otherwise serve the original format
|
|
82
|
+
|
|
83
|
+
Explicitly set `fm` only when a specific format is required (e.g., `blurhash` for placeholders).
|
|
84
|
+
|
|
85
|
+
## Remote Image Configuration
|
|
86
|
+
|
|
87
|
+
To transform images from external domains, allowlist them in `netlify.toml` using regex patterns:
|
|
88
|
+
|
|
89
|
+
```toml
|
|
90
|
+
[images]
|
|
91
|
+
remote_images = [
|
|
92
|
+
"https://my-images\\.com/.*",
|
|
93
|
+
"https://animals\\.more-images\\.com/[bcr]at/.*"
|
|
94
|
+
]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Then reference the full URL:
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<img src="/.netlify/images?url=https://my-images.com/photo.jpg&w=400" />
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Only absolute URLs to external servers need to be in `remote_images`. Local site images work without configuration.
|
|
104
|
+
|
|
105
|
+
## Redirects & Rewrites
|
|
106
|
+
|
|
107
|
+
If you do not want to use the default `/.netlify/images` path, a redirect or rewrite can be used to have a different
|
|
108
|
+
URL. When doing so, the parameters can remain parameters to pass in or can be statically defined.
|
|
109
|
+
|
|
110
|
+
**Using `netlify.toml`:**
|
|
111
|
+
|
|
112
|
+
```toml
|
|
113
|
+
[[redirects]]
|
|
114
|
+
from = "/transform-small/*"
|
|
115
|
+
to = "/.netlify/images?url=/:splat&w=50&h=50"
|
|
116
|
+
status = 200
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Using `_redirects` file:**
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
/transform-small/* /.netlify/images?url=/:splat&w=50&h=50 200
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Usage:**
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<!-- Transforms /photo.jpg with w=50&h=50 -->
|
|
129
|
+
<img src="/transform-small/photo.jpg" />
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
DO NOT create circular redirects where an image URL redirects to another URL that redirects back. This causes infinite
|
|
133
|
+
loops and errors.
|
|
134
|
+
|
|
135
|
+
## Custom Headers
|
|
136
|
+
|
|
137
|
+
Apply custom headers to source images on your site's domain. Headers propagate to the transformed output. ONLY do this
|
|
138
|
+
when explicitly asked.
|
|
139
|
+
|
|
140
|
+
**Using `netlify.toml`:**
|
|
141
|
+
|
|
142
|
+
```toml
|
|
143
|
+
[[headers]]
|
|
144
|
+
for = "/source-images/*"
|
|
145
|
+
[headers.values]
|
|
146
|
+
Cache-Control = "public, max-age=604800, must-revalidate"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Using `_headers` file:**
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
/source-images/*
|
|
153
|
+
Cache-Control: public, max-age=604800, must-revalidate
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Limitations:**
|
|
157
|
+
- Custom headers only work for images on the same domain
|
|
158
|
+
- Cannot apply custom headers to remote source images
|
|
159
|
+
- Netlify respects cache headers that external domains send with their images
|
|
160
|
+
- `Cache-Control` headers on source images apply to browsers/CDNs, not the Netlify cache itself
|
|
161
|
+
|
|
162
|
+
## Framework Integration
|
|
163
|
+
|
|
164
|
+
Many frameworks automatically use Netlify Image CDN when deployed to Netlify:
|
|
165
|
+
|
|
166
|
+
| Framework | Setup | Remote Image Allowlist |
|
|
167
|
+
|-----------|-------|----------------------|
|
|
168
|
+
| **Angular** | Automatic via `NgOptimizedImage` | `[images] remote_images` in `netlify.toml` |
|
|
169
|
+
| **Astro** | Automatic via `<Image />` component | `image.domains` or `image.remotePatterns` in `astro.config.mjs` |
|
|
170
|
+
| **Gatsby 5.13+** | Set env var `NETLIFY_IMAGE_CDN=true` | `[images] remote_images` in `netlify.toml` |
|
|
171
|
+
| **Next.js 13.5+** | Automatic with adapter v5 | `remotePatterns` in `next.config.js` |
|
|
172
|
+
| **Nuxt** | Automatic via `nuxt/image` module | `image.domains` in `nuxt.config.ts` |
|
|
173
|
+
|
|
174
|
+
## Caching & Deploy Behavior
|
|
175
|
+
|
|
176
|
+
- Transformed images are uniquely cached at the edge per transformation parameters
|
|
177
|
+
- Future requests for the same transformation serve the cached version
|
|
178
|
+
- After a new deploy, cached images are invalidated if the source changed
|
|
179
|
+
- Source images are also cached to speed up future transformations
|
|
180
|
+
- Use asset fingerprinting (content hashes in filenames) for fine-grained cache control
|
|
181
|
+
|
|
182
|
+
## Response Codes
|
|
183
|
+
|
|
184
|
+
| Condition | Response |
|
|
185
|
+
|-----------|----------|
|
|
186
|
+
| Valid query, new transformation | `200` with transformed image |
|
|
187
|
+
| Request for previously cached transformation | `304` Not Modified |
|
|
188
|
+
| Invalid parameter values or missing source | `404` Not Found |
|
|
189
|
+
|
|
190
|
+
## Common Errors & Solutions
|
|
191
|
+
|
|
192
|
+
### "404 on image transformation"
|
|
193
|
+
|
|
194
|
+
**Cause:** Invalid parameter values or source image not found.
|
|
195
|
+
|
|
196
|
+
**Fix:**
|
|
197
|
+
|
|
198
|
+
1. Verify the source image exists at the specified `url` path
|
|
199
|
+
2. Check parameter values are valid (e.g., `q` must be 1-100, `fit` must be `contain`, `cover`, or `fill`)
|
|
200
|
+
3. For remote images, ensure the domain is in `remote_images` config
|
|
201
|
+
|
|
202
|
+
### Blurry or low-quality output
|
|
203
|
+
|
|
204
|
+
**Cause:** Quality setting too low or dimensions too small.
|
|
205
|
+
|
|
206
|
+
**Fix:**
|
|
207
|
+
|
|
208
|
+
1. Increase the `q` parameter (default is 75, max is 100)
|
|
209
|
+
2. Ensure `w` and `h` are appropriate for the display size
|
|
210
|
+
3. Use `fm=png` for images that need lossless quality
|
|
211
|
+
|
|
212
|
+
### Remote image not loading
|
|
213
|
+
|
|
214
|
+
**Cause:** External domain not allowlisted.
|
|
215
|
+
|
|
216
|
+
**Fix:**
|
|
217
|
+
|
|
218
|
+
1. Add the domain to `remote_images` in `netlify.toml`:
|
|
219
|
+
```toml
|
|
220
|
+
[images]
|
|
221
|
+
remote_images = ["https://example\\.com/.*"]
|
|
222
|
+
```
|
|
223
|
+
2. Escape dots in regex patterns with double backslash
|
|
224
|
+
3. Redeploy after updating config
|
|
225
|
+
|
|
226
|
+
### Images not updating after deploy
|
|
227
|
+
|
|
228
|
+
**Cause:** Browser or CDN cache serving stale version.
|
|
229
|
+
|
|
230
|
+
**Fix:**
|
|
231
|
+
|
|
232
|
+
1. Use asset fingerprinting (e.g., `/photo-abc123.jpg`) for cache busting
|
|
233
|
+
2. Clear browser cache or use hard refresh
|
|
234
|
+
3. Wait a few minutes for edge cache propagation
|
|
235
|
+
|
|
236
|
+
### Circular redirect error
|
|
237
|
+
|
|
238
|
+
**Cause:** Redirect rule creates a loop with the image transformation endpoint.
|
|
239
|
+
|
|
240
|
+
**Fix:**
|
|
241
|
+
|
|
242
|
+
1. Ensure redirect `from` path does not overlap with the `to` path
|
|
243
|
+
2. Avoid redirecting `/.netlify/images` to another `/.netlify/images` URL
|
|
244
|
+
3. Use status `200` (rewrite) not `301`/`302` (redirect) when possible
|
package/package.json
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/agent-runner-cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.30.0",
|
|
4
|
+
"version": "1.30.1-broken.0",
|
|
5
5
|
"description": "CLI tool for running Netlify agents",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": "./dist/index.js",
|
|
9
9
|
"bin": {
|
|
10
|
-
"agent-runner-cli": "./dist/bin.js"
|
|
10
|
+
"agent-runner-cli": "./dist/bin.js",
|
|
11
|
+
"agent-runner-cli-local": "./dist/bin-local.js"
|
|
11
12
|
},
|
|
12
13
|
"files": [
|
|
13
14
|
"dist/**/*.js",
|
|
14
15
|
"dist/**/*.d.ts",
|
|
16
|
+
"dist/skills/**",
|
|
15
17
|
"patches",
|
|
16
18
|
"scripts"
|
|
17
19
|
],
|
|
@@ -25,21 +27,24 @@
|
|
|
25
27
|
"format": "run-s build format:check-fix:*",
|
|
26
28
|
"format:ci": "run-s build format:check:*",
|
|
27
29
|
"format:check-fix:lint": "run-e format:check:lint format:fix:lint",
|
|
28
|
-
"format:check:lint": "
|
|
29
|
-
"format:fix:lint": "
|
|
30
|
+
"format:check:lint": "eslint --cache --format=codeframe --max-warnings=0 \"{src,scripts,test,.github}/**/*.{js,ts,md,html}\"",
|
|
31
|
+
"format:fix:lint": "eslint --fix --cache --format=codeframe --max-warnings=0 \"{src,scripts,test,.github}/**/*.{js,ts,md,html}\"",
|
|
30
32
|
"format:check-fix:prettier": "run-e format:check:prettier format:fix:prettier",
|
|
31
|
-
"format:check:prettier": "
|
|
32
|
-
"format:fix:prettier": "
|
|
33
|
+
"format:check:prettier": "prettier --check --ignore-path .gitignore --loglevel=warn \"{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}\" \"*.{js,ts,yml,json,html}\" \".*.{js,ts,yml,json,html}\" \"!**/package-lock.json\" \"!package-lock.json\" \"!src/skills/**/*.md\"",
|
|
34
|
+
"format:fix:prettier": "prettier --write --ignore-path .gitignore --loglevel=warn \"{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}\" \"*.{js,ts,yml,json,html}\" \".*.{js,ts,yml,json,html}\" \"!**/package-lock.json\" \"!package-lock.json\" \"!src/skills/**/*.md\"",
|
|
33
35
|
"test:dev": "run-s build test:dev:*",
|
|
34
36
|
"test:ci": "run-s build test:ci:*",
|
|
35
|
-
"test:dev:vitest": "vitest",
|
|
36
|
-
"test:ci:vitest": "
|
|
37
|
+
"test:dev:vitest": "LOG=0 vitest --exclude '**/integration/**'",
|
|
38
|
+
"test:ci:vitest": "LOG=0 vitest run --coverage --exclude '**/integration/**'",
|
|
39
|
+
"test:integration": "vitest run test/integration/",
|
|
40
|
+
"test:integration:codex": "vitest run test/integration/codex.test.ts",
|
|
41
|
+
"test:integration:claude": "vitest run test/integration/claude.test.ts",
|
|
42
|
+
"test:integration:gemini": "vitest run test/integration/gemini.test.ts",
|
|
43
|
+
"test:integration:skill-invocation": "vitest run test/integration/skill-invocation.test.ts",
|
|
44
|
+
"test:integration:feature-enablement": "vitest run test/integration/feature-enablement.test.ts",
|
|
45
|
+
"check:types": "tsc --noEmit",
|
|
37
46
|
"postinstall": "node scripts/postinstall.js"
|
|
38
47
|
},
|
|
39
|
-
"config": {
|
|
40
|
-
"eslint": "--cache --format=codeframe --max-warnings=0 \"{src,scripts,test,.github}/**/*.{js,ts,md,html}\"",
|
|
41
|
-
"prettier": "--ignore-path .gitignore --loglevel=warn \"{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}\" \"*.{js,ts,yml,json,html}\" \".*.{js,ts,yml,json,html}\" \"!**/package-lock.json\" \"!package-lock.json\""
|
|
42
|
-
},
|
|
43
48
|
"keywords": [],
|
|
44
49
|
"license": "MIT",
|
|
45
50
|
"repository": "netlify/agent-runner-cli",
|
|
@@ -51,33 +56,40 @@
|
|
|
51
56
|
"test": "test"
|
|
52
57
|
},
|
|
53
58
|
"devDependencies": {
|
|
54
|
-
"@commitlint/cli": "^
|
|
55
|
-
"@commitlint/config-conventional": "^
|
|
56
|
-
"@eslint/compat": "^
|
|
59
|
+
"@commitlint/cli": "^20.0.0",
|
|
60
|
+
"@commitlint/config-conventional": "^20.0.0",
|
|
61
|
+
"@eslint/compat": "^2.0.0",
|
|
57
62
|
"@eslint/js": "^9.35.0",
|
|
63
|
+
"@netlify/axis": "^1.14.0",
|
|
58
64
|
"@netlify/eslint-config-node": "^7.0.1",
|
|
59
65
|
"@types/node": "^24.5.0",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
61
|
-
"@typescript-eslint/parser": "^
|
|
62
|
-
"@vitest/
|
|
63
|
-
"
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
67
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
68
|
+
"@vitest/coverage-v8": "^4.1.5",
|
|
69
|
+
"@vitest/eslint-plugin": "^1.6.6",
|
|
64
70
|
"eslint-config-prettier": "^10.1.8",
|
|
65
71
|
"eslint-plugin-n": "^17.0.0",
|
|
66
|
-
"husky": "^
|
|
72
|
+
"husky": "^9.0.0",
|
|
73
|
+
"jiti": "^2.7.0",
|
|
67
74
|
"patch-package": "^8.0.0",
|
|
68
75
|
"tsup": "^8.5.0",
|
|
69
76
|
"typescript": "^5.0.0",
|
|
70
77
|
"typescript-eslint": "^8.44.0",
|
|
71
|
-
"vitest": "^
|
|
78
|
+
"vitest": "^4.0.16"
|
|
72
79
|
},
|
|
73
80
|
"dependencies": {
|
|
74
|
-
"@anthropic-ai/claude-code": "
|
|
75
|
-
"@
|
|
76
|
-
"@
|
|
77
|
-
"@
|
|
78
|
-
"
|
|
79
|
-
"
|
|
81
|
+
"@anthropic-ai/claude-code": "2.1.154",
|
|
82
|
+
"@anthropic-ai/sdk": "0.91.1",
|
|
83
|
+
"@google/gemini-cli": "0.42.0",
|
|
84
|
+
"@netlify/database-proxy": "^0.1.5",
|
|
85
|
+
"@netlify/otel": "^6.0.3",
|
|
86
|
+
"@netlify/ts-cli": "^1.2.0",
|
|
87
|
+
"@openai/codex": "0.128.0",
|
|
88
|
+
"@opentelemetry/api": "^1.9.0",
|
|
89
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "0.218.0",
|
|
90
|
+
"execa": "^9.6.1",
|
|
91
|
+
"fastify": "5.8.5",
|
|
80
92
|
"minimist": "^1.2.8",
|
|
81
|
-
"
|
|
93
|
+
"openai": "6.34.0"
|
|
82
94
|
}
|
|
83
95
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Installs the orchestrator's bundled skills into the agent's skill directory
|
|
4
|
+
* by calling `setupAgentSkills` from `src/context.js` — the same function the
|
|
5
|
+
* orchestrator itself uses at runtime. Intended to run as an axis scenario
|
|
6
|
+
* setup action when the scenario wants to A/B with-skills vs without.
|
|
7
|
+
*
|
|
8
|
+
* Uses `jiti` to import the orchestrator source directly so we don't need a
|
|
9
|
+
* pre-built `dist/` (context.js transitively imports several `.ts` modules
|
|
10
|
+
* that plain Node ESM can't resolve).
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* node install-skills.mjs [--agent claude-code|codex|gemini] [--target-dir <abs>]
|
|
14
|
+
*
|
|
15
|
+
* Omit `--agent` to install for all known agents in one pass.
|
|
16
|
+
*/
|
|
17
|
+
import process from 'node:process'
|
|
18
|
+
import { parseArgs } from 'node:util'
|
|
19
|
+
|
|
20
|
+
import { createJiti } from 'jiti'
|
|
21
|
+
|
|
22
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true })
|
|
23
|
+
const { setupAgentSkills, resetSkillsCache } = await jiti.import('../../src/context.js')
|
|
24
|
+
|
|
25
|
+
// Axis adapter name → orchestrator runner key (matches `AGENT_SKILLS_DIRS` in src/context.js).
|
|
26
|
+
const RUNNER_BY_AGENT = {
|
|
27
|
+
'claude-code': 'claude',
|
|
28
|
+
codex: 'codex',
|
|
29
|
+
gemini: 'gemini',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ALL_AGENTS = Object.keys(RUNNER_BY_AGENT)
|
|
33
|
+
|
|
34
|
+
const main = async () => {
|
|
35
|
+
const { values } = parseArgs({
|
|
36
|
+
args: process.argv.slice(2),
|
|
37
|
+
options: {
|
|
38
|
+
agent: { type: 'string' },
|
|
39
|
+
'target-dir': { type: 'string' },
|
|
40
|
+
},
|
|
41
|
+
strict: false,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const agents = values.agent ? [values.agent] : ALL_AGENTS
|
|
45
|
+
|
|
46
|
+
for (const agent of agents) {
|
|
47
|
+
const runner = RUNNER_BY_AGENT[agent] ?? agent
|
|
48
|
+
resetSkillsCache()
|
|
49
|
+
const installed = await setupAgentSkills(runner, values['target-dir'] ? { targetDir: values['target-dir'] } : {})
|
|
50
|
+
process.stderr.write(`[install-skills] ${runner}: ${installed.length} skill(s)\n`)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
main().catch((err) => {
|
|
55
|
+
process.stderr.write(`[install-skills] error: ${err.message ?? err}\n`)
|
|
56
|
+
process.exit(1)
|
|
57
|
+
})
|