@netlify/agent-runner-cli 1.192.0 → 1.193.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 +10 -0
- package/dist/bin-local.js +279 -245
- package/dist/bin.js +357 -323
- package/dist/index.js +276 -242
- package/dist/skills/netlify-edge-functions/SKILL.md +30 -0
- package/dist/skills/netlify-functions/SKILL.md +33 -0
- package/dist/skills/netlify-identity/SKILL.md +25 -0
- package/dist/skills/netlify-server@netlifyserver/SKILL.md +14 -0
- package/package.json +1 -1
|
@@ -244,6 +244,36 @@ context.cookies.set({ name: 'session', value: 'abc123', path: '/', httpOnly: tru
|
|
|
244
244
|
context.cookies.delete('session')
|
|
245
245
|
```
|
|
246
246
|
|
|
247
|
+
### `context.user`
|
|
248
|
+
|
|
249
|
+
The user who signed in through Netlify's SSO to reach a private project or a site protected by Netlify team login, or
|
|
250
|
+
`undefined` otherwise. Netlify verifies the visitor at the edge and sets this itself, so it can't be spoofed with
|
|
251
|
+
request headers.
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
context.user.id // string - user ID
|
|
255
|
+
context.user.email // string - user email address
|
|
256
|
+
context.user.expiresAt // Date - when the user's access expires
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// netlify/edge-functions/whoami.ts
|
|
261
|
+
import type { Config, Context } from '@netlify/edge-functions'
|
|
262
|
+
|
|
263
|
+
export default async (req: Request, context: Context) => {
|
|
264
|
+
if (!context.user) return new Response('Unauthorized', { status: 401 })
|
|
265
|
+
return Response.json({ id: context.user.id, email: context.user.email })
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export const config: Config = {
|
|
269
|
+
path: '/whoami',
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
This is the Netlify team member viewing the site, not a Netlify Identity user. See the
|
|
274
|
+
[changelog post](https://www.netlify.com/changelog/2026-10-07-context-user-in-functions/) and the
|
|
275
|
+
[Edge Functions API docs](https://docs.netlify.com/build/edge-functions/api/#user).
|
|
276
|
+
|
|
247
277
|
### `context.waitUntil(promise)`
|
|
248
278
|
|
|
249
279
|
Extends execution after the response is sent:
|
|
@@ -215,6 +215,39 @@ context.cookies.delete('session')
|
|
|
215
215
|
context.server.region // string - e.g., 'us-east-1'
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
+
### `context.user`
|
|
219
|
+
|
|
220
|
+
The user who signed in through Netlify's SSO to reach a private project or a site protected by Netlify team login.
|
|
221
|
+
`undefined` when the request didn't come from such a user. Netlify verifies the visitor and sets this itself, so it
|
|
222
|
+
can't be spoofed with request headers.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
context.user.id // string - user ID
|
|
226
|
+
context.user.email // string - user email address
|
|
227
|
+
context.user.expiresAt // Date - when the user's access expires
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// netlify/functions/whoami.mts
|
|
232
|
+
import type { Config, Context } from '@netlify/functions'
|
|
233
|
+
|
|
234
|
+
export default async (req: Request, context: Context) => {
|
|
235
|
+
if (!context.user) return new Response('Unauthorized', { status: 401 })
|
|
236
|
+
return Response.json({
|
|
237
|
+
id: context.user.id,
|
|
238
|
+
email: context.user.email,
|
|
239
|
+
expiresAt: context.user.expiresAt.toISOString(),
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export const config: Config = { path: '/whoami' }
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
This is the Netlify team member viewing the site, not a Netlify Identity user; for end-user accounts on your site use
|
|
247
|
+
the `netlify-identity` skill. See the
|
|
248
|
+
[changelog post](https://www.netlify.com/changelog/2026-10-07-context-user-in-functions/) and the
|
|
249
|
+
[Functions API docs](https://docs.netlify.com/build/functions/api/#user).
|
|
250
|
+
|
|
218
251
|
### `context.waitUntil(promise)`
|
|
219
252
|
|
|
220
253
|
Extends execution after the response is sent. Use for analytics, logging, or cleanup tasks.
|
|
@@ -402,6 +402,31 @@ browser sends the new cookie.
|
|
|
402
402
|
Always use `window.location.href` (not framework router navigation) after server-side auth mutations in Next.js,
|
|
403
403
|
TanStack Start, and SvelteKit. Remix `redirect()` is safe because Remix actions return real HTTP responses.
|
|
404
404
|
|
|
405
|
+
## Netlify SSO Users (`context.user`)
|
|
406
|
+
|
|
407
|
+
Netlify Identity is for your site's own end users. Separately, on private projects and sites protected by Netlify team
|
|
408
|
+
login, Netlify Functions, Edge Functions, and Netlify Server code can read the Netlify team member who signed in through
|
|
409
|
+
Netlify's SSO from the request context as `context.user` (`id`, `email`, `expiresAt`). Netlify verifies the visitor at
|
|
410
|
+
the edge and sets it itself, so it can't be spoofed with request headers.
|
|
411
|
+
|
|
412
|
+
Use `context.user` instead of Netlify Identity when the only people who should reach the site are members of the
|
|
413
|
+
Netlify team (internal dashboards, audit logs, approval workflows): there is no signup, login UI, or `@netlify/identity`
|
|
414
|
+
setup to build, and you don't run the enable script for it. Use `getUser()` from `@netlify/identity` when the site has
|
|
415
|
+
its own user accounts.
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
// netlify/functions/whoami.mts
|
|
419
|
+
import type { Context } from '@netlify/functions'
|
|
420
|
+
|
|
421
|
+
export default async (req: Request, context: Context) => {
|
|
422
|
+
if (!context.user) return new Response('Unauthorized', { status: 401 })
|
|
423
|
+
return Response.json({ id: context.user.id, email: context.user.email })
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
See the [changelog post](https://www.netlify.com/changelog/2026-10-07-context-user-in-functions/), and the
|
|
428
|
+
**netlify-functions**, **netlify-edge-functions**, and **netlify-server** skills for runtime-specific details.
|
|
429
|
+
|
|
405
430
|
## Identity Event Functions
|
|
406
431
|
|
|
407
432
|
Subscribe to Identity lifecycle events by exporting an object whose properties are named event handlers. See the
|
|
@@ -108,6 +108,20 @@ Rules:
|
|
|
108
108
|
- ONLY call `getContext()` while handling a request (inside a route handler, middleware, or code awaited from one). It throws outside a request.
|
|
109
109
|
- Works with every server form, including WebSocket upgrade handling.
|
|
110
110
|
|
|
111
|
+
### SSO user: `context.user`
|
|
112
|
+
|
|
113
|
+
On private projects and sites protected by Netlify team login, the context also carries the user who signed in through Netlify's SSO: `context.user` with `id`, `email`, and `expiresAt` (a `Date`). It is `undefined` when the request didn't come from such a user. Netlify verifies the visitor and sets it itself, so it can't be spoofed with request headers. This is the Netlify team member viewing the site, not a Netlify Identity user.
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
app.get('/api/whoami', (req, res) => {
|
|
117
|
+
const { user } = getContext()
|
|
118
|
+
if (!user) return res.status(401).send('Unauthorized')
|
|
119
|
+
res.json({ id: user.id, email: user.email })
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
See the [changelog post](https://www.netlify.com/changelog/2026-10-07-context-user-in-functions/).
|
|
124
|
+
|
|
111
125
|
## AI inference: Netlify AI Gateway
|
|
112
126
|
|
|
113
127
|
The AI Gateway works with zero configuration: provider credentials and base URLs (`OPENAI_API_KEY`, `OPENAI_BASE_URL`, and equivalents for other providers) are injected into `process.env` automatically. See the `netlify-ai-gateway` skill for supported models and usage.
|