@agentforge-io/sdk-server 4.2.0 → 4.3.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.
@@ -263,6 +263,111 @@ export declare class ConnectorsResource {
263
263
  }): Promise<{
264
264
  ok: true;
265
265
  }>;
266
+ /**
267
+ * `GET /app-user/connector-resources/:connectorId?externalUserId=...` —
268
+ * real resource browsing (Slack channels, GitHub repos, ClickUp lists…)
269
+ * scoped to ONE end user's OWN grant. App-user counterpart of
270
+ * `listResources()` above — same return shape, same `unsupported: true`
271
+ * behavior for connectors without a resource selector implemented yet.
272
+ *
273
+ * Requires `appSecret` — throws early otherwise, same as
274
+ * `authorizeForAppUser`.
275
+ *
276
+ * @example
277
+ * const { items } = await af.connectors.listResourcesForAppUser('slack', {
278
+ * externalUserId: 'scrappydoc-user-42',
279
+ * });
280
+ */
281
+ listResourcesForAppUser(connectorId: string, input: {
282
+ externalUserId: string;
283
+ }): Promise<ListConnectorResourcesResult>;
284
+ /**
285
+ * `GET /app-user/connector-resources/:connectorId/defaults?externalUserId=...`
286
+ * — tool permissions for this connector, resolved with the App's own
287
+ * override always live (tier 0, `af_app_connectors`) since `appId` comes
288
+ * from the secret. App-user counterpart of `getDefaults()` above.
289
+ * `externalUserId` doesn't affect resolution (defaults are per-App, not
290
+ * per-end-user) — still required because the platform route always reads
291
+ * it off the scope helper shared by this controller's other routes.
292
+ *
293
+ * Requires `appSecret` — throws early otherwise, same as
294
+ * `authorizeForAppUser`.
295
+ */
296
+ getDefaultsForAppUser(connectorId: string, input: {
297
+ externalUserId: string;
298
+ }): Promise<ConnectorDefaultsResult>;
299
+ /**
300
+ * `PUT /app-user/connector-resources/:connectorId/defaults?externalUserId=...`
301
+ * — overwrites the connector's tool permissions. App-user counterpart of
302
+ * `updateDefaults()` above. NOTE (mirrors the platform controller's own
303
+ * doc comment): this write lands on the tenant-level row
304
+ * (`af_connector_tool_defaults`), same as the ak_live_ route — there's no
305
+ * App-scoped-only override write today. `externalUserId` travels as a
306
+ * query param (matching `getDefaultsForAppUser`); the platform route also
307
+ * accepts it in the body but query is canonical for this SDK's GET/PUT
308
+ * pair.
309
+ *
310
+ * Requires `appSecret` — throws early otherwise, same as
311
+ * `authorizeForAppUser`.
312
+ */
313
+ updateDefaultsForAppUser(connectorId: string, permissions: ToolPermission[], input: {
314
+ externalUserId: string;
315
+ }): Promise<{
316
+ ok: true;
317
+ }>;
318
+ /**
319
+ * `POST /app-user/connector-resources/clickup/tasks` — creates a REAL
320
+ * ClickUp task using the end user's OWN grant. App-user counterpart of
321
+ * `createClickupTask()` above. Unlike the GET/PUT methods above,
322
+ * `externalUserId` travels in the BODY here — the platform route reads it
323
+ * off `body.externalUserId` for this action endpoint (not a query param).
324
+ *
325
+ * Requires `appSecret` — throws early otherwise, same as
326
+ * `authorizeForAppUser`.
327
+ */
328
+ createClickupTaskForAppUser(input: CreateClickupTaskInput & {
329
+ externalUserId: string;
330
+ }): Promise<CreateClickupTaskResult>;
331
+ /**
332
+ * `POST /app-user/connector-resources/slack/messages` — posts a REAL
333
+ * Slack message using the end user's OWN grant. App-user counterpart of
334
+ * `postSlackMessage()` above. `externalUserId` travels in the BODY, same
335
+ * as `createClickupTaskForAppUser` (the platform route reads
336
+ * `body.externalUserId` for both action endpoints).
337
+ *
338
+ * Requires `appSecret` — throws early otherwise, same as
339
+ * `authorizeForAppUser`.
340
+ */
341
+ postSlackMessageForAppUser(input: {
342
+ channelId: string;
343
+ text: string;
344
+ externalUserId: string;
345
+ }): Promise<{
346
+ ok: true;
347
+ ts?: string;
348
+ permalink?: string;
349
+ }>;
350
+ /**
351
+ * `POST /app-user/connector-resources/:connectorId/api-key` — guarda un
352
+ * API key pegado por el end user, para SU PROPIO grant (no el tenant del
353
+ * App). App-user counterpart of `saveApiKeyForTenant()` above, para
354
+ * connectors que NO usan OAuth (Granola, Mapbox). `externalUserId` viaja
355
+ * en el BODY, mismo patrón que `createClickupTaskForAppUser`/
356
+ * `postSlackMessageForAppUser`.
357
+ *
358
+ * Requires `appSecret` — throws early otherwise, same as
359
+ * `authorizeForAppUser`.
360
+ *
361
+ * @example
362
+ * await af.connectors.saveApiKeyForAppUser('granola', 'grn_xxxxx', {
363
+ * externalUserId: 'scrappydoc-user-42',
364
+ * });
365
+ */
366
+ saveApiKeyForAppUser(connectorId: string, apiKey: string, input: {
367
+ externalUserId: string;
368
+ }): Promise<{
369
+ connectorId: string;
370
+ }>;
266
371
  }
267
372
  export interface InboxChannelView {
268
373
  id: string;
@@ -301,5 +301,149 @@ class ConnectorsResource {
301
301
  const params = new URLSearchParams({ externalUserId: input.externalUserId });
302
302
  return this.client.request('DELETE', `/connectors/oauth/${encodeURIComponent(connectorId)}/app-user?${params.toString()}`);
303
303
  }
304
+ // ─── App-user resource picker (AGF-072d — app-user twin of the picker
305
+ // methods at the top of this file) ──────────────────────────────────────
306
+ //
307
+ // Mirrors listResources/getDefaults/updateDefaults/createClickupTask/
308
+ // postSlackMessage above, scoped to (appId-from-secret, externalUserId)
309
+ // instead of the ak_live_ tenant. Hits `AppUserResourcePickerController`
310
+ // (`/app-user/connector-resources/*`) — a DISTINCT base path from the
311
+ // tenant picker's `/connector-resources/*`, not just a query-param
312
+ // variant. Same auth rule as the 3 methods above: requires `appSecret`,
313
+ // uses `this.client.request()` directly (not `requestWithApiKey()`).
314
+ //
315
+ // NOT mirrored here:
316
+ // - list-connected (`GET /app-user/connector-resources`): its
317
+ // `{connectorId,connected,browsable}[]` shape is a narrower duplicate
318
+ // of what `listConnectorsForAppUser()` above already returns (the
319
+ // richer `AppUserConnectorStatus[]` from
320
+ // `/connectors/oauth/app-user/directory`). Adding a second, thinner
321
+ // "list connected" would just invite callers to pick the wrong one.
322
+ // - disconnect (`DELETE /app-user/connector-resources/:connectorId`):
323
+ // redundant with `disconnectForAppUser()` above
324
+ // (`/connectors/oauth/:id/app-user`) — same ConnectorAuth row, same
325
+ // method name would collide. Use the existing one.
326
+ /**
327
+ * `GET /app-user/connector-resources/:connectorId?externalUserId=...` —
328
+ * real resource browsing (Slack channels, GitHub repos, ClickUp lists…)
329
+ * scoped to ONE end user's OWN grant. App-user counterpart of
330
+ * `listResources()` above — same return shape, same `unsupported: true`
331
+ * behavior for connectors without a resource selector implemented yet.
332
+ *
333
+ * Requires `appSecret` — throws early otherwise, same as
334
+ * `authorizeForAppUser`.
335
+ *
336
+ * @example
337
+ * const { items } = await af.connectors.listResourcesForAppUser('slack', {
338
+ * externalUserId: 'scrappydoc-user-42',
339
+ * });
340
+ */
341
+ async listResourcesForAppUser(connectorId, input) {
342
+ if (!this.client.getAppSecret()) {
343
+ throw new Error('connectors.listResourcesForAppUser requires appSecret (sk_live_/sk_test_) in ' +
344
+ 'AgentForgeClient. This surface authenticates AS the App, not via chatToken/apiKey.');
345
+ }
346
+ const params = new URLSearchParams({ externalUserId: input.externalUserId });
347
+ return this.client.request('GET', `/app-user/connector-resources/${encodeURIComponent(connectorId)}?${params.toString()}`);
348
+ }
349
+ /**
350
+ * `GET /app-user/connector-resources/:connectorId/defaults?externalUserId=...`
351
+ * — tool permissions for this connector, resolved with the App's own
352
+ * override always live (tier 0, `af_app_connectors`) since `appId` comes
353
+ * from the secret. App-user counterpart of `getDefaults()` above.
354
+ * `externalUserId` doesn't affect resolution (defaults are per-App, not
355
+ * per-end-user) — still required because the platform route always reads
356
+ * it off the scope helper shared by this controller's other routes.
357
+ *
358
+ * Requires `appSecret` — throws early otherwise, same as
359
+ * `authorizeForAppUser`.
360
+ */
361
+ async getDefaultsForAppUser(connectorId, input) {
362
+ if (!this.client.getAppSecret()) {
363
+ throw new Error('connectors.getDefaultsForAppUser requires appSecret (sk_live_/sk_test_) in ' +
364
+ 'AgentForgeClient. This surface authenticates AS the App, not via chatToken/apiKey.');
365
+ }
366
+ const params = new URLSearchParams({ externalUserId: input.externalUserId });
367
+ return this.client.request('GET', `/app-user/connector-resources/${encodeURIComponent(connectorId)}/defaults?${params.toString()}`);
368
+ }
369
+ /**
370
+ * `PUT /app-user/connector-resources/:connectorId/defaults?externalUserId=...`
371
+ * — overwrites the connector's tool permissions. App-user counterpart of
372
+ * `updateDefaults()` above. NOTE (mirrors the platform controller's own
373
+ * doc comment): this write lands on the tenant-level row
374
+ * (`af_connector_tool_defaults`), same as the ak_live_ route — there's no
375
+ * App-scoped-only override write today. `externalUserId` travels as a
376
+ * query param (matching `getDefaultsForAppUser`); the platform route also
377
+ * accepts it in the body but query is canonical for this SDK's GET/PUT
378
+ * pair.
379
+ *
380
+ * Requires `appSecret` — throws early otherwise, same as
381
+ * `authorizeForAppUser`.
382
+ */
383
+ async updateDefaultsForAppUser(connectorId, permissions, input) {
384
+ if (!this.client.getAppSecret()) {
385
+ throw new Error('connectors.updateDefaultsForAppUser requires appSecret (sk_live_/sk_test_) in ' +
386
+ 'AgentForgeClient. This surface authenticates AS the App, not via chatToken/apiKey.');
387
+ }
388
+ const params = new URLSearchParams({ externalUserId: input.externalUserId });
389
+ return this.client.request('PUT', `/app-user/connector-resources/${encodeURIComponent(connectorId)}/defaults?${params.toString()}`, { permissions });
390
+ }
391
+ /**
392
+ * `POST /app-user/connector-resources/clickup/tasks` — creates a REAL
393
+ * ClickUp task using the end user's OWN grant. App-user counterpart of
394
+ * `createClickupTask()` above. Unlike the GET/PUT methods above,
395
+ * `externalUserId` travels in the BODY here — the platform route reads it
396
+ * off `body.externalUserId` for this action endpoint (not a query param).
397
+ *
398
+ * Requires `appSecret` — throws early otherwise, same as
399
+ * `authorizeForAppUser`.
400
+ */
401
+ async createClickupTaskForAppUser(input) {
402
+ if (!this.client.getAppSecret()) {
403
+ throw new Error('connectors.createClickupTaskForAppUser requires appSecret (sk_live_/sk_test_) in ' +
404
+ 'AgentForgeClient. This surface authenticates AS the App, not via chatToken/apiKey.');
405
+ }
406
+ return this.client.request('POST', '/app-user/connector-resources/clickup/tasks', input);
407
+ }
408
+ /**
409
+ * `POST /app-user/connector-resources/slack/messages` — posts a REAL
410
+ * Slack message using the end user's OWN grant. App-user counterpart of
411
+ * `postSlackMessage()` above. `externalUserId` travels in the BODY, same
412
+ * as `createClickupTaskForAppUser` (the platform route reads
413
+ * `body.externalUserId` for both action endpoints).
414
+ *
415
+ * Requires `appSecret` — throws early otherwise, same as
416
+ * `authorizeForAppUser`.
417
+ */
418
+ async postSlackMessageForAppUser(input) {
419
+ if (!this.client.getAppSecret()) {
420
+ throw new Error('connectors.postSlackMessageForAppUser requires appSecret (sk_live_/sk_test_) in ' +
421
+ 'AgentForgeClient. This surface authenticates AS the App, not via chatToken/apiKey.');
422
+ }
423
+ return this.client.request('POST', '/app-user/connector-resources/slack/messages', input);
424
+ }
425
+ /**
426
+ * `POST /app-user/connector-resources/:connectorId/api-key` — guarda un
427
+ * API key pegado por el end user, para SU PROPIO grant (no el tenant del
428
+ * App). App-user counterpart of `saveApiKeyForTenant()` above, para
429
+ * connectors que NO usan OAuth (Granola, Mapbox). `externalUserId` viaja
430
+ * en el BODY, mismo patrón que `createClickupTaskForAppUser`/
431
+ * `postSlackMessageForAppUser`.
432
+ *
433
+ * Requires `appSecret` — throws early otherwise, same as
434
+ * `authorizeForAppUser`.
435
+ *
436
+ * @example
437
+ * await af.connectors.saveApiKeyForAppUser('granola', 'grn_xxxxx', {
438
+ * externalUserId: 'scrappydoc-user-42',
439
+ * });
440
+ */
441
+ async saveApiKeyForAppUser(connectorId, apiKey, input) {
442
+ if (!this.client.getAppSecret()) {
443
+ throw new Error('connectors.saveApiKeyForAppUser requires appSecret (sk_live_/sk_test_) in ' +
444
+ 'AgentForgeClient. This surface authenticates AS the App, not via chatToken/apiKey.');
445
+ }
446
+ return this.client.request('POST', `/app-user/connector-resources/${encodeURIComponent(connectorId)}/api-key`, { apiKey, externalUserId: input.externalUserId });
447
+ }
304
448
  }
305
449
  exports.ConnectorsResource = ConnectorsResource;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge-io/sdk-server",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "Server-side SDK for backend apps integrating with AgentForge platform. Auth via ChatToken or ak_live_ API key.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",