@netlify/agent-runner-cli 1.192.0 → 1.193.0-PAW-739.1

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.
@@ -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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/agent-runner-cli",
3
3
  "type": "module",
4
- "version": "1.192.0",
4
+ "version": "1.193.0-PAW-739.1",
5
5
  "description": "CLI tool for running Netlify agents",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",