@alfe.ai/agent-api-client 0.17.1 → 0.19.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/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChangelogAction, ChangelogActor, ChangelogEntry, ChangelogEntry as ChangelogEntry$1, EncryptedEnvelopeV1, EncryptedEnvelopeV1 as EncryptedEnvelopeV1$1, Field, FieldEnvelope, FieldEnvelope as FieldEnvelope$1, FieldFormat, FieldFormat as FieldFormat$1, FieldSensitivity, FieldSensitivity as FieldSensitivity$1, FieldView, GeneratedDataKey, GeneratedDataKey as GeneratedDataKey$1, IntegrationConfigResult, IntegrationConfigResult as IntegrationConfigResult$1, IntegrationConfigSchemaField, IntegrationInstall, IntegrationInstall as IntegrationInstall$1, RegistryEntry, RegistryEntry as RegistryEntry$1, ScopeInfo, ScopeInfo as ScopeInfo$1, SecretAggregate, SecretAggregate as SecretAggregate$1, SecretCategory, SecretCategory as SecretCategory$1, SecretMetadata, SecretMetadata as SecretMetadata$1, SecretScope, SecretScope as SecretScope$1 } from "@alfe/types";
1
+ import { ChangelogAction, ChangelogActor, ChangelogEntry, ChangelogEntry as ChangelogEntry$1, EncryptedEnvelopeV1, EncryptedEnvelopeV1 as EncryptedEnvelopeV1$1, Field, FieldEnvelope, FieldEnvelope as FieldEnvelope$1, FieldFormat, FieldFormat as FieldFormat$1, FieldSensitivity, FieldSensitivity as FieldSensitivity$1, FieldView, GeneratedDataKey, GeneratedDataKey as GeneratedDataKey$1, IntegrationActivationSource, IntegrationActivationSource as IntegrationActivationSource$1, IntegrationActualStatus, IntegrationConfigResult, IntegrationConfigResult as IntegrationConfigResult$1, IntegrationConfigSchemaField, IntegrationDesiredStatus, IntegrationInstall, IntegrationInstall as IntegrationInstall$1, IntegrationScope, RegistryEntry, RegistryEntry as RegistryEntry$1, ScopeInfo, ScopeInfo as ScopeInfo$1, SecretAggregate, SecretAggregate as SecretAggregate$1, SecretCategory, SecretCategory as SecretCategory$1, SecretMetadata, SecretMetadata as SecretMetadata$1, SecretScope, SecretScope as SecretScope$1 } from "@alfe/types";
2
2
 
3
3
  //#region src/tool-error-capture.d.ts
4
4
 
@@ -118,1519 +118,1602 @@ declare class ApiBase {
118
118
  }
119
119
  //# sourceMappingURL=transport.d.ts.map
120
120
  //#endregion
121
- //#region src/domains/workspace.d.ts
122
- /** Response of GET /agent/workspace (services/agents). */
123
- interface AgentWorkspaceInfo {
124
- templateKey?: string;
125
- defaultModel?: string;
126
- installedFrom?: {
127
- templateKey: string;
128
- authorTenantId: string;
129
- version: number;
130
- };
131
- runtime?: string;
132
- teams?: {
133
- teamId: string;
134
- name: string;
135
- description?: string;
136
- parentTeamId?: string;
137
- }[];
138
- projects?: {
139
- projectId: string;
140
- name: string;
141
- description?: string;
142
- status: string;
143
- parentProjectId?: string;
144
- }[];
145
- teamIds?: string[];
146
- projectIds?: string[];
121
+ //#region src/domains/connect-credentials.d.ts
122
+ /** Provider projection plus the stable identity of its backing Connection. */
123
+ interface ConnectProviderAccount {
124
+ connectionId: string;
125
+ accountIdentifier: string;
126
+ displayName: string | null;
127
+ connectedAt: string;
128
+ [key: string]: unknown;
147
129
  }
148
- declare class WorkspaceApi extends ApiBase {
130
+ interface ConnectProviderAccounts {
131
+ provider: string;
132
+ accounts: ConnectProviderAccount[];
133
+ }
134
+ declare class ConnectCredentialsApi extends ApiBase {
149
135
  /**
150
- * GET /agent/workspace workspace config for the authenticated agent
151
- * (template assignment, default model, org roster).
136
+ * Discover all active Connections visible to this agent for one provider.
137
+ * Preserve the provider-specific credential projection without guessing a
138
+ * token shape. These rows contain secrets: tool discovery must explicitly
139
+ * select public identity fields, never return/spread the complete response.
140
+ * Use getConnectionCredentials(connectionId) for fresh per-call authority.
152
141
  */
153
- getWorkspace(): Promise<AgentWorkspaceInfo>;
142
+ getConnectProviderAccounts(provider: string): Promise<ConnectProviderAccounts>;
154
143
  /**
155
- * GET /templates/{key}/files persona/workspace file contents for a
156
- * template the agent has access to. Pass `version` to pin to the version
157
- * the agent was installed from (omit the endpoint resolves `latest`).
144
+ * Returns every connected Google account for the agent. Multi-account by
145
+ * design the openclaw-google plugin requires the LLM to pass `email`
146
+ * explicitly to `google_run_command` so an account is always selected
147
+ * deliberately.
148
+ *
149
+ * 2026-05-14 (connections-redesign PR 1): the legacy flat shape (`email`,
150
+ * `refreshToken`, `accessToken`, etc., populated from the default account)
151
+ * is gone. Iterate over `accounts`.
158
152
  */
159
- getTemplateFiles(templateKey: string, opts?: {
160
- version?: number;
161
- }): Promise<{
162
- files: Record<string, string>;
163
- }>;
164
- }
165
- //# sourceMappingURL=workspace.d.ts.map
166
- //#endregion
167
- //#region src/domains/sync.d.ts
168
- interface SyncAgentInfo {
169
- agentId: string;
170
- tenantId: string;
171
- displayName: string;
172
- s3Prefix: string;
173
- status: "stale" | "syncing" | "synced";
174
- fileCount?: number;
175
- totalSize?: number;
176
- lastSync?: string;
177
- }
178
- interface SyncManifestEntry {
179
- hash: string;
180
- size: number;
181
- modified: string;
182
- etag?: string;
183
- storageClass?: string;
184
- compressed?: boolean;
185
- }
186
- interface SyncManifest {
187
- version: 1;
188
- agentId: string;
189
- lastSync: string;
190
- files: Record<string, SyncManifestEntry>;
191
- }
192
- interface SyncPresignedUrl {
193
- path: string;
194
- url: string;
195
- expiresAt: string;
196
- }
197
- interface SyncConfirmedUpload {
198
- filePath: string;
199
- hash: string;
200
- size: number;
201
- storageClass: "STANDARD" | "GLACIER_IR";
202
- syncedAt: string;
203
- }
204
- interface SyncReconstructFile {
205
- path: string;
206
- size: number;
207
- url: string;
208
- storageClass?: string;
209
- compressed?: boolean;
210
- }
211
- interface SyncReconstructBundle {
212
- agentId: string;
213
- mode: "full" | "active" | "memory";
214
- fileCount: number;
215
- totalSize: number;
216
- files: SyncReconstructFile[];
217
- expiresAt: string;
218
- }
219
- interface SyncAgentStats {
220
- agentId: string;
221
- standardBytes: number;
222
- glacierBytes: number;
223
- fileCount: number;
224
- lastSyncAt: string | null;
225
- }
226
- interface SyncFileEntry {
227
- filePath: string;
228
- size: number;
229
- modified: string;
230
- contentHash: string;
231
- storageClass?: string;
232
- compressed?: boolean;
233
- }
234
- interface SyncSessionEntry {
235
- sessionId: string;
236
- size: number;
237
- lastModified: string;
238
- storageClass?: string;
239
- isArchived: boolean;
240
- }
241
- interface SyncSessionContent {
242
- sessionId: string;
243
- content: string;
244
- compressed: boolean;
245
- }
246
- interface SharedFileEntry {
247
- filePath: string;
248
- fileName: string;
249
- size: number;
250
- contentType?: string;
251
- }
252
- declare class SyncApi extends ApiBase {
253
- syncRegister(args?: {
254
- displayName?: string;
255
- }): Promise<{
256
- agent: SyncAgentInfo;
257
- }>;
258
- syncGetManifest(): Promise<SyncManifest>;
259
- syncPresign(args: {
260
- files: {
261
- path: string;
262
- operation: "put" | "get";
263
- contentType?: string;
153
+ getGoogleCredentials(): Promise<{
154
+ accounts: {
155
+ email: string;
156
+ refreshToken: string;
157
+ clientId: string;
158
+ clientSecret: string;
159
+ displayName?: string;
160
+ connectedAt?: string;
264
161
  }[];
265
- }): Promise<{
266
- urls: SyncPresignedUrl[];
267
162
  }>;
268
- syncConfirmUpload(args: {
269
- filePath: string;
270
- hash: string;
271
- size: number;
272
- storageClass?: "STANDARD" | "GLACIER_IR";
273
- }): Promise<SyncConfirmedUpload>;
274
- syncReconstruct(args: {
275
- mode: "full" | "active" | "memory";
276
- }): Promise<SyncReconstructBundle>;
277
- syncGetStats(): Promise<SyncAgentStats>;
278
- syncListFiles(args?: {
279
- prefix?: string;
280
- }): Promise<{
281
- files: SyncFileEntry[];
282
- }>;
283
- syncListSessions(): Promise<{
284
- sessions: SyncSessionEntry[];
285
- }>;
286
- syncGetSession(sessionId: string): Promise<SyncSessionContent>;
287
- syncDeleteFile(filePath: string): Promise<{
288
- removed: boolean;
163
+ disconnectGoogleAccount(email: string): Promise<{
164
+ accounts: {
165
+ email: string;
166
+ displayName?: string;
167
+ connectedAt?: string;
168
+ }[];
289
169
  }>;
290
- sharedListFiles(args: {
291
- scope: "org" | "team" | "project";
292
- scopeId: string;
293
- limit?: number;
294
- cursor?: string;
295
- }): Promise<{
296
- files: SharedFileEntry[];
297
- nextCursor: string | null;
170
+ getGoogleChatCredentials(): Promise<{
171
+ email: string;
172
+ refreshToken: string;
173
+ clientId: string;
174
+ clientSecret: string;
175
+ displayName?: string;
298
176
  }>;
299
- sharedDownloadUrl(args: {
300
- scope: "org" | "team" | "project";
301
- scopeId: string;
302
- filePath: string;
303
- }): Promise<{
304
- downloadUrl: string;
305
- expiresIn: number;
177
+ /**
178
+ * Fetch decrypted credentials for ONE specific connection by its
179
+ * stable connectionId (connection-scoped, vs the provider-scoped
180
+ * `get<Provider>Credentials` helpers). Used by the daemon to resolve
181
+ * a Custom Connection-driven integration's credentials from the
182
+ * exact connection it was installed from — every custom connection
183
+ * shares the `custom` provider id, so provider-scoping is ambiguous.
184
+ *
185
+ * For custom connections `accessToken` is the JSON-encoded secret
186
+ * bundle (the daemon un-bundles it); non-secret fields are on
187
+ * `providerMetadata`. The endpoint enforces that the connection is in
188
+ * the calling agent's effective scope (403 otherwise).
189
+ */
190
+ getConnectionCredentials(connectionId: string): Promise<{
191
+ provider: string;
192
+ connectionId: string;
193
+ accountIdentifier?: string;
194
+ accessToken?: string;
195
+ providerMetadata?: Record<string, unknown>;
196
+ [key: string]: unknown;
306
197
  }>;
307
- }
308
- //# sourceMappingURL=sync.d.ts.map
309
- //#endregion
310
- //#region src/domains/knowledge.d.ts
311
- type KnowledgeScopeType = "org" | "team" | "project";
312
- interface KnowledgeScope {
313
- scopeType: KnowledgeScopeType;
314
- scopeId: string;
315
- name: string;
316
- }
317
- interface KnowledgeSearchHit {
318
- id: string;
319
- text: string;
320
- /** Normalized relevance in (0,1]; higher = closer. */
321
- score: number;
322
- scopeType: KnowledgeScopeType;
323
- scopeId: string;
324
198
  /**
325
- * Provenance of the hit. All live results are `"doc"`; `"fact"` only ever
326
- * appears for legacy vectors indexed before the facts primitive was removed
327
- * (the search index stays tolerant of them). Treat every hit as a doc.
199
+ * @deprecated Returns a single primary credential blob (legacy "pick-the-
200
+ * default-connection" shape). Use `getGithubAccounts()` for the multi-
201
+ * account shape required by Pattern A explicit selector args on every
202
+ * tool. Retained because the `@alfe.ai/github-mcp` proxy is the
203
+ * only consumer that knows about Pattern A; legacy env-interpolation
204
+ * callers will keep hitting `/credentials` until they move to the proxy.
328
205
  */
329
- source: "doc" | "fact";
330
- /** The canonical file under shared/<scope>/ (present on doc hits). */
331
- filePath?: string;
332
- /** Legacy-only: the id of a pre-removal fact vector. */
333
- factId?: string;
334
- }
335
- interface KnowledgeSearchResult {
336
- results: KnowledgeSearchHit[];
337
- /** True when fan-out breadth was capped (more member scopes than the cap). */
338
- truncatedScopes: boolean;
339
- }
340
- interface KnowledgeProfileLink {
341
- label: string;
342
- url: string;
343
- }
344
- interface KnowledgeProfile {
345
- scopeType: KnowledgeScopeType;
346
- scopeId: string;
347
- about: string | null;
348
- description: string | null;
349
- links: KnowledgeProfileLink[];
350
- updatedAt: string | null;
351
- updatedBy: string | null;
352
- }
353
- type ChangeRequestResourceType = "doc" | "profile";
354
- type ChangeRequestOperation = "create" | "update" | "delete";
355
- type ChangeRequestStatus = "open" | "approved" | "rejected" | "withdrawn" | "superseded";
356
- type ChangeRequestActorKind = "human" | "agent";
357
- /** Public projection of a change request (mirrors `PublicChangeRequest` in services/org). */
358
- interface KnowledgeChangeRequest {
359
- changeRequestId: string;
360
- scopeType: KnowledgeScopeType;
361
- scopeId: string;
362
- resourceType: ChangeRequestResourceType;
363
- operation: ChangeRequestOperation;
364
- targetPath: string | null;
365
- baseVersionId: string | null;
366
- proposedContentType: string | null;
367
- status: ChangeRequestStatus;
368
- proposerId: string;
369
- proposerKind: ChangeRequestActorKind;
370
- rationale: string;
371
- reviewerId: string | null;
372
- reviewerKind: ChangeRequestActorKind | null;
373
- reviewedAt: string | null;
374
- reviewNote: string | null;
375
- appliedRef: string | null;
376
- createdAt: string;
377
- updatedAt: string;
378
- }
379
- /** Per-type proposal payload for `proposeScopeChange`. */
380
- interface ProposeScopeChangeInput {
381
- resourceType: ChangeRequestResourceType;
382
- operation: ChangeRequestOperation;
383
- /** Why the change is proposed — shown to the reviewer. */
384
- rationale: string;
385
- /** doc: the path the proposal applies to (e.g. designs/data-center.md). */
386
- targetPath?: string;
387
- /** doc create/update: the staged body to upload (markdown or other text). */
388
- content?: string;
389
- /** doc create/update: content type of the staged body (default text/markdown). */
390
- contentType?: string;
391
- /** profile: the proposed value ({ about, description, links }). */
392
- proposedValue?: unknown;
393
- }
394
- interface KnowledgeDoc {
395
- filePath: string;
396
- fileName: string;
397
- contentType?: string;
398
- size: number;
399
- uploadedBy?: string;
400
- createdAt: string;
401
- updatedAt: string;
402
- }
403
- declare class KnowledgeApi extends ApiBase {
206
+ getGithubCredentials(): Promise<{
207
+ login: string;
208
+ accessToken: string;
209
+ }>;
404
210
  /**
405
- * Semantic search across the agent's member scopes. Fan-out is gated
406
- * server-side by `listScopes` set-inclusion (fail-closed). Pass
407
- * `scopeType` + `scopeId` to narrow to one scope; a non-member scope
408
- * yields empty results (never a cross-scope leak).
211
+ * Pattern A: multi-account credential fetch for GitHub.
212
+ *
213
+ * Returns every agent-scoped GitHub connection. The caller is expected
214
+ * to require a `login` selector on every credential-touching tool and
215
+ * look up the matching account at dispatch time.
216
+ *
217
+ * GitHub OAuth tokens have no expiry (`tokenLifecycle: "no_expiry"`),
218
+ * so there is intentionally no `refreshGithubAccountToken` method — if
219
+ * a token is revoked the user must re-run the OAuth flow.
220
+ *
221
+ * Returned `accounts[i].login` is the GitHub username — the stable
222
+ * cross-session identifier the LLM should pass.
409
223
  */
410
- knowledgeSearch(query: string, opts?: {
411
- limit?: number;
412
- scopeType?: KnowledgeScopeType;
413
- scopeId?: string;
414
- }): Promise<KnowledgeSearchResult>;
415
- /** Enumerate the scopes (org + teams + projects) this agent belongs to. */
416
- listScopes(): Promise<{
417
- scopes: KnowledgeScope[];
224
+ getGithubAccounts(): Promise<{
225
+ accounts: {
226
+ connectionId: string;
227
+ accountIdentifier: string;
228
+ displayName: string | null;
229
+ connectedAt: string;
230
+ accessToken: string;
231
+ login: string;
232
+ scopes: string;
233
+ }[];
418
234
  }>;
419
- /** Read a scope's structured knowledge profile (after membership check). */
420
- getScopeProfile(scopeType: KnowledgeScopeType, scopeId: string): Promise<KnowledgeProfile>;
421
235
  /**
422
- * Open a change request against a scope's knowledge resource. For a doc
423
- * create/update, `services/org` returns a presigned staging PUT; this method
424
- * uploads the proposed `content` to it (echoing the same Content-Type that
425
- * was signed), mirroring `writeScopeDoc`. The staged body is applied to the
426
- * canonical doc — attributed to this agent — only when a reviewer approves.
236
+ * @deprecated Returns a single primary credential blob (legacy "pick-the-
237
+ * default-connection" shape). Use `getXeroAccounts()` for the multi-
238
+ * account shape required by Pattern A explicit selector args on every
239
+ * tool. This method will be removed once all consumers migrate.
427
240
  */
428
- proposeScopeChange(scopeType: KnowledgeScopeType, scopeId: string, input: ProposeScopeChangeInput): Promise<KnowledgeChangeRequest>;
241
+ getXeroCredentials(): Promise<{
242
+ accessToken: string;
243
+ accessTokenExpiresAt: string;
244
+ xeroTenantId: string;
245
+ }>;
429
246
  /**
430
- * List the agent's OWN change requests in a scope (filtered server-side to
431
- * this agent as proposer). Pass `status` to narrow to open / approved / etc.
247
+ * Pattern A: multi-account credential fetch for Xero. Returns every
248
+ * agent-scoped Xero connection. The caller is expected to require a
249
+ * selector arg (e.g. `xeroTenantId`) on every credential-touching tool
250
+ * and look up the matching account by that selector at dispatch time.
251
+ *
252
+ * `xeroTenantId` is the model-facing organisation selector. The separate
253
+ * `accountIdentifier` is the Connect persistence key used for refresh and
254
+ * may be an email; never substitute one for the other.
432
255
  */
433
- listScopeChangeRequests(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
434
- status?: ChangeRequestStatus;
435
- limit?: number;
436
- cursor?: string;
437
- }): Promise<{
438
- changeRequests: KnowledgeChangeRequest[];
439
- nextCursor: string | null;
256
+ getXeroAccounts(): Promise<{
257
+ accounts: {
258
+ connectionId: string;
259
+ accountIdentifier: string;
260
+ displayName: string | null;
261
+ connectedAt: string;
262
+ accessToken: string;
263
+ accessTokenExpiresAt: string;
264
+ xeroTenantId: string;
265
+ }[];
440
266
  }>;
441
- /** List a scope's docs (the org-files corpus; mirrored to shared/<scope>/). */
442
- listScopeDocs(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
443
- limit?: number;
444
- cursor?: string;
445
- }): Promise<{
446
- files: KnowledgeDoc[];
447
- nextCursor: string | null;
267
+ refreshXeroToken(): Promise<{
268
+ accessToken: string;
269
+ expiresAt: string;
448
270
  }>;
449
271
  /**
450
- * Read the full text of a scope doc. Resolves a presigned download URL
451
- * from `services/org`, then fetches the bytes directly from S3 (the one
452
- * legitimate raw fetch in a plugin same pattern as sync).
272
+ * Refresh a specific Xero Connection by its exact `accountIdentifier` from
273
+ * `getXeroAccounts()`. Do not substitute `xeroTenantId`: current Xero OAuth
274
+ * rows may use the account email as their persistence key even when a sole
275
+ * organisation tenant ID is available in provider metadata.
453
276
  */
454
- readScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, opts?: {
455
- maxBytes?: number;
456
- }): Promise<{
457
- filePath: string;
458
- text: string;
277
+ refreshXeroAccountToken(accountIdentifier: string): Promise<{
278
+ accessToken: string;
279
+ accessTokenExpiresAt: string;
280
+ expiresAt: string;
459
281
  }>;
460
282
  /**
461
- * Write (create or overwrite) a scope doc. Two-step presigned upload:
462
- * `services/org` returns a signed URL plus `requiredHeaders` (author /
463
- * authorKind / message as `x-amz-meta-*`) that MUST be sent verbatim on
464
- * the PUT, alongside the same `Content-Type` that was signed. Author and
465
- * authorKind are server-set from the agent token — never trusted here.
283
+ * @deprecated Returns a single primary credential blob (legacy "pick-the-
284
+ * default-connection" shape). Use `getNotionAccounts()` for the multi-
285
+ * account shape required by Pattern A.
466
286
  */
467
- writeScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, content: string, opts?: {
468
- contentType?: string;
469
- message?: string;
470
- }): Promise<{
471
- filePath: string;
287
+ getNotionCredentials(): Promise<{
288
+ accessToken: string;
289
+ workspaceId: string;
290
+ workspaceName: string;
472
291
  }>;
473
- }
474
- //# sourceMappingURL=knowledge.d.ts.map
475
- //#endregion
476
- //#region src/domains/mobile.d.ts
477
- /** Response of GET /mobile/numbers for an agent (services/mobile). */
478
- interface MobileNumberInfo {
479
- phoneNumber: string;
480
- countryCode: string;
481
- monthlyPrice?: number;
482
- status: string;
483
- errorMessage?: string;
484
- }
485
- /** One purchasable number from GET /mobile/numbers/search. */
486
- interface MobileAvailableNumber {
487
- number: string;
488
- friendlyName: string;
489
- locality: string;
490
- region: string;
491
- country: string;
492
- }
493
- /** Approved WhatsApp content template from GET /mobile/whatsapp/templates. */
494
- interface WhatsAppTemplate {
495
- contentSid: string;
496
- name: string;
497
- language: string;
498
- body: string;
499
- variables: Record<string, string>;
500
- category?: string;
501
- }
502
- declare class MobileApi extends ApiBase {
503
- getMobileNumber(): Promise<MobileNumberInfo>;
504
- searchMobileNumbers(args?: {
505
- country?: string;
506
- query?: string;
507
- }): Promise<{
508
- numbers: MobileAvailableNumber[];
509
- monthlyPrice: number;
292
+ /**
293
+ * Pattern A: multi-account credential fetch for Notion. Returns every
294
+ * agent-scoped Notion connection. The caller is expected to require a
295
+ * selector arg (e.g. `workspaceId`) on every credential-touching tool.
296
+ *
297
+ * Returned `accounts[i].accountIdentifier` is the Notion workspaceId.
298
+ */
299
+ getNotionAccounts(): Promise<{
300
+ accounts: {
301
+ connectionId: string;
302
+ accountIdentifier: string;
303
+ displayName: string | null;
304
+ connectedAt: string;
305
+ accessToken: string;
306
+ workspaceId: string;
307
+ workspaceName: string;
308
+ }[];
510
309
  }>;
511
- assignMobileNumber(args: {
512
- phoneNumber: string;
513
- countryCode: string;
514
- }): Promise<{
515
- phoneNumber: string;
516
- countryCode: string;
517
- status: "pending";
518
- }>;
519
- releaseMobileNumber(): Promise<{
520
- released: true;
521
- }>;
522
- sendSms(args: {
523
- to: string;
524
- body: string;
525
- }): Promise<{
526
- sent: true;
527
- sid: string;
528
- }>;
529
- startOutboundCall(args: {
530
- to: string;
531
- }): Promise<{
532
- callSid: string;
533
- status: string;
310
+ /**
311
+ * @deprecated Returns a single primary Atlassian Connection's credentials
312
+ * (one OAuth user, one cloudId) — the legacy "pick-the-default-connection"
313
+ * shape. Atlassian is multi-site by nature (each OAuth user may have
314
+ * access to multiple Cloud sites), so Pattern A plugins MUST use
315
+ * `getAtlassianAccounts()` to discover the full set and dispatch via
316
+ * the `cloudId` selector arg.
317
+ */
318
+ getAtlassianCredentials(): Promise<{
319
+ accessToken: string;
320
+ refreshToken: string;
321
+ accessTokenExpiresAt: string;
322
+ cloudId: string;
323
+ siteName: string;
324
+ siteUrl: string;
325
+ email: string;
326
+ enabledProducts: string[];
327
+ clientId: string;
328
+ clientSecret: string;
534
329
  }>;
535
- getWhatsAppSession(to: string): Promise<{
536
- active: boolean;
537
- expiresAt?: string;
330
+ refreshAtlassianToken(): Promise<{
331
+ accessToken: string;
332
+ expiresAt: string;
538
333
  }>;
539
- sendWhatsAppMessage(args: {
540
- to: string;
541
- body: string;
542
- }): Promise<{
543
- sent: true;
544
- sid: string;
334
+ /**
335
+ * Pattern A: multi-account / multi-site credential fetch for Atlassian.
336
+ *
337
+ * Returns every agent-scoped Atlassian Connection. Each Connection is
338
+ * one OAuth user with a single access token and N accessible Cloud
339
+ * sites (`availableSites`). The caller is expected to:
340
+ *
341
+ * 1. Flatten (connection × cloudId) into one MCP child per site.
342
+ * 2. Require a `cloudId` selector on every credential-touching tool.
343
+ * 3. Use the access token bound to the Connection that owns the
344
+ * requested `cloudId` (Atlassian shares one access token across
345
+ * all sites accessible to the OAuth user).
346
+ *
347
+ * Per-account token refresh uses `refreshAtlassianAccountToken(email)`
348
+ * — refreshing one Connection rotates its single access token, which
349
+ * then applies to every cloudId for that Connection.
350
+ *
351
+ * Returned `accounts[i].accountIdentifier` is the OAuth user's email
352
+ * — the stable cross-session identifier for refresh purposes. The LLM
353
+ * never sees this directly: it picks a site via the `cloudId` arg
354
+ * instead.
355
+ */
356
+ getAtlassianAccounts(): Promise<{
357
+ accounts: {
358
+ connectionId: string;
359
+ accountIdentifier: string;
360
+ displayName: string | null;
361
+ connectedAt: string;
362
+ accessToken: string;
363
+ accessTokenExpiresAt: string;
364
+ clientId: string;
365
+ clientSecret: string;
366
+ cloudId: string;
367
+ siteName: string;
368
+ siteUrl: string;
369
+ availableSites: {
370
+ id: string;
371
+ url: string;
372
+ name: string;
373
+ scopes?: string[];
374
+ avatarUrl?: string;
375
+ }[];
376
+ }[];
545
377
  }>;
546
- sendWhatsAppTemplate(args: {
547
- to: string;
548
- contentSid: string;
549
- contentVariables: Record<string, string>;
550
- bodyPreview?: string;
551
- }): Promise<{
552
- sent: true;
553
- sid: string;
378
+ /**
379
+ * Pattern A: refresh a specific Atlassian Connection by `accountIdentifier`
380
+ * (the OAuth user's email).
381
+ *
382
+ * Atlassian rotates refresh tokens (`rotatesRefreshToken: true`); the
383
+ * server-side per-account refresh endpoint handles rotation and
384
+ * persistence. Refreshing one Connection updates its single access
385
+ * token, which applies to every accessible Cloud site (cloudId) for
386
+ * that OAuth user.
387
+ *
388
+ * Returns the new access token + expiry. The proxy is responsible for
389
+ * fanning the new token out to every child server it spawned for
390
+ * cloudIds owned by this Connection.
391
+ */
392
+ refreshAtlassianAccountToken(accountIdentifier: string): Promise<{
393
+ accessToken: string;
394
+ accessTokenExpiresAt: string;
395
+ expiresAt: string;
554
396
  }>;
555
- listWhatsAppTemplates(): Promise<{
556
- templates: WhatsAppTemplate[];
397
+ /**
398
+ * @deprecated Returns a single primary credential blob (legacy "pick-the-
399
+ * default-connection" shape). Use `getMYOBAccounts()` for the multi-
400
+ * account shape required by Pattern A.
401
+ */
402
+ getMYOBCredentials(): Promise<{
403
+ accessToken: string;
404
+ accessTokenExpiresAt: string;
405
+ myobBusinessId: string;
406
+ clientId: string;
557
407
  }>;
558
- }
559
- //# sourceMappingURL=mobile.d.ts.map
560
- //#endregion
561
- //#region src/domains/remote.d.ts
562
- interface RemoteSessionInfo {
563
- sessionId: string;
564
- agentId: string;
565
- surface: "browser" | "terminal";
566
- status: "agent_driving" | "awaiting_human" | "human_in_control" | "resuming" | "completed" | "expired" | "failed";
567
- url?: string;
568
- instructions?: string;
569
- requestedAt?: string;
570
- }
571
- declare class RemoteApi extends ApiBase {
572
- requestBrowserTakeover(args: {
573
- instructions: string;
574
- url?: string;
575
- conversationId?: string;
576
- }): Promise<{
577
- sessionId: string;
578
- status: string;
408
+ /**
409
+ * Pattern A: multi-account credential fetch for MYOB. Returns every
410
+ * agent-scoped MYOB connection. The caller is expected to require a
411
+ * selector arg (e.g. `myobBusinessId` / `accountIdentifier`) on every
412
+ * credential-touching tool.
413
+ *
414
+ * Returned `accounts[i].accountIdentifier` is the MYOB businessId.
415
+ */
416
+ getMYOBAccounts(): Promise<{
417
+ accounts: {
418
+ connectionId: string;
419
+ accountIdentifier: string;
420
+ displayName: string | null;
421
+ connectedAt: string;
422
+ accessToken: string;
423
+ accessTokenExpiresAt: string;
424
+ myobBusinessId: string;
425
+ clientId: string;
426
+ }[];
579
427
  }>;
580
- getRemoteSession(sessionId: string): Promise<RemoteSessionInfo>;
581
- completeRemoteSession(sessionId: string): Promise<{
582
- ok: boolean;
428
+ refreshMYOBToken(): Promise<{
429
+ accessToken: string;
430
+ expiresAt: string;
583
431
  }>;
584
- }
585
- //# sourceMappingURL=remote.d.ts.map
586
- //#endregion
587
- //#region src/domains/self.d.ts
588
- /** Voice settings — core agent config. Mirrors `VoiceConfig` in `@alfe/types`. */
589
- interface AgentVoiceConfig {
590
- /** ElevenLabs voice ID; platform default when unset. */
591
- voiceId?: string;
592
- ttsModel?: string;
593
- enabled?: boolean;
594
- }
595
- /**
596
- * The agent's own public identity, as returned by `updateSelf`, `generateAvatar`,
597
- * `presignAvatar`'s finalize (`finalizeAvatar`). This is the public agent
598
- * projection; only the identity-relevant fields are typed here — the response
599
- * carries the full public agent record.
600
- */
601
- interface AgentSelf {
602
- agentId: string;
603
- tenantId: string;
604
- name: string;
605
- avatarUrl?: string;
606
- voiceConfig?: AgentVoiceConfig;
607
- status: string;
608
- }
609
- /** Result of `presignAvatar` — the agent PUTs bytes to `uploadUrl`, then finalizes with `s3Key`. */
610
- interface AgentAvatarPresign {
611
- /** Presigned PUT URL to upload the image bytes to. */
612
- uploadUrl: string;
613
- /** Object key — echoed back to `finalizeAvatar`. */
614
- s3Key: string;
615
- /** Stable public URL the avatar will be served from once finalized. */
616
- publicUrl: string;
617
- /** ISO expiry of the presigned PUT URL. */
618
- expiresAt: string;
619
- }
620
- /** A voice in the platform catalogue (ElevenLabs), from `listVoices`. */
621
- interface AgentVoice {
622
- id: string;
623
- name: string;
624
- previewUrl: string;
625
- description: string;
626
- labels: Record<string, string>;
627
- category: string;
628
- }
629
- declare class SelfApi extends ApiBase {
630
- /** Update the agent's own name and/or voice config. Returns the updated agent. */
631
- updateSelf(update: {
632
- name?: string;
633
- voiceConfig?: AgentVoiceConfig;
634
- }): Promise<AgentSelf>;
635
432
  /**
636
- * Generate the agent's own avatar from a text prompt. The image is generated,
637
- * stored, and set on the agent server-side; returns the updated agent.
433
+ * Pattern A: refresh one MYOB Connection by its stable
434
+ * `accountIdentifier` (the MYOB business id returned by
435
+ * `getMYOBAccounts()`).
638
436
  *
639
- * ASYNC (same reason as `generateImage`): avatar gen runs `gpt-image-1`
640
- * (30–60s) which exceeds the API Gateway 30s ceiling, so this enqueues a job
641
- * (`POST /agent/avatar/generate` `jobId`) then polls (`GET /agent/avatar/{jobId}`)
642
- * until the avatar is set. Signature unchanged — the plugin is unaffected.
437
+ * MYOB refresh tokens belong to individual Connection rows. A
438
+ * multi-business client must use this method instead of refreshing the
439
+ * primary Connection and copying that access token into every cached
440
+ * business client.
643
441
  */
644
- generateAvatar(args: {
645
- prompt: string;
646
- }): Promise<AgentSelf>;
442
+ refreshMYOBAccountToken(accountIdentifier: string): Promise<{
443
+ accessToken: string;
444
+ accessTokenExpiresAt: string;
445
+ expiresAt: string;
446
+ }>;
647
447
  /**
648
- * Get a presigned PUT URL to upload a new avatar image. Upload the bytes to
649
- * `uploadUrl`, then call `finalizeAvatar(s3Key)` to set it on the agent.
448
+ * @deprecated Returns a single primary credential blob. Use
449
+ * `getSalesforceAccounts()` for the multi-account shape required by
450
+ * Pattern A.
650
451
  */
651
- presignAvatar(args: {
652
- mimeType: string;
653
- size: number;
654
- }): Promise<AgentAvatarPresign>;
452
+ getSalesforceCredentials(): Promise<{
453
+ accessToken: string;
454
+ accessTokenExpiresAt: string;
455
+ instanceUrl: string;
456
+ orgId: string;
457
+ }>;
655
458
  /**
656
- * Finalize an avatar upload validates ownership + size, then sets the
657
- * agent's `avatarUrl` server-side. Returns the updated agent.
459
+ * Pattern A: multi-account credential fetch for Salesforce. Returns every
460
+ * agent-scoped Salesforce connection. One OAuth grant maps to one org, so
461
+ * `accounts[i].accountIdentifier` (and `orgId`) is the Salesforce org id —
462
+ * the selector every credential-touching tool requires.
658
463
  */
659
- finalizeAvatar(s3Key: string): Promise<AgentSelf>;
660
- /** List the platform voice catalogue (ElevenLabs) so the agent can pick its own voice. */
661
- listVoices(): Promise<{
662
- voices: AgentVoice[];
464
+ getSalesforceAccounts(): Promise<{
465
+ accounts: {
466
+ connectionId: string;
467
+ accountIdentifier: string;
468
+ displayName: string | null;
469
+ connectedAt: string;
470
+ accessToken: string;
471
+ accessTokenExpiresAt: string;
472
+ instanceUrl: string;
473
+ orgId: string;
474
+ }[];
663
475
  }>;
664
- }
665
- //# sourceMappingURL=self.d.ts.map
666
- //#endregion
667
- //#region src/domains/voice.d.ts
668
- /** The ElevenLabs models with a pricing row — the TTS endpoint rejects any other value. */
669
- type VoiceTtsModel = "eleven_turbo_v2_5" | "eleven_multilingual_v2";
670
- interface VoiceTtsArgs {
671
- /** Text to synthesize (1–5000 chars — the endpoint enforces this). */
672
- text: string;
673
- /** ElevenLabs voice id; platform default when unset. */
674
- voiceId?: string;
675
- /** TTS model; `eleven_turbo_v2_5` (lower latency) when unset. */
676
- model?: VoiceTtsModel;
677
- }
678
- /** Raw synthesized audio plus its PCM framing (from the response headers). */
679
- interface VoiceTtsResult {
680
- /** Raw little-endian PCM samples — no container. Wrap in WAV to make a playable file. */
681
- audio: Buffer;
682
- /** Samples per second (e.g. 24000). */
683
- sampleRate: number;
684
- /** Channel count (mono = 1). */
685
- channels: number;
686
- /** Bits per sample (e.g. 16). */
687
- bitDepth: number;
688
- }
689
- interface VoiceSttArgs {
690
- /** Raw linear16 (16-bit little-endian) mono PCM samples — no WAV/container header. */
691
- audio: Uint8Array;
692
- /** Sample rate of `audio` in Hz (8000–48000). */
693
- sampleRate: number;
694
- }
695
- interface VoiceSttResult {
696
- text: string;
697
- /** Deepgram confidence in (0,1]. */
698
- confidence: number;
699
- }
700
- declare class VoiceApi extends ApiBase {
701
476
  /**
702
- * Text-to-speech. Returns raw PCM audio bytes plus their framing — the
703
- * voice service defaults to 24 kHz / mono / 16-bit. Wrap in a WAV container
704
- * to produce a playable file. Metered per character against the tenant
705
- * credit pool server-side; TTS completes regardless of metering outcome.
477
+ * Refresh the access token for a specific Salesforce org. Salesforce
478
+ * tokens aren't interchangeable across orgs, so the connection is targeted
479
+ * by `accountIdentifier` (the org id) mirrors `refreshXeroAccountToken`.
706
480
  */
707
- tts(args: VoiceTtsArgs): Promise<VoiceTtsResult>;
481
+ refreshSalesforceAccountToken(orgId: string): Promise<{
482
+ accessToken: string;
483
+ accessTokenExpiresAt: string;
484
+ expiresAt: string;
485
+ }>;
708
486
  /**
709
- * Speech-to-text. Accepts raw linear16 (16-bit LE) mono PCM NOT a WAV or
710
- * other container (the endpoint transcribes with a fixed linear16 encoding,
711
- * so a container header would be transcribed as noise). Strip any WAV header
712
- * and pass `sampleRate` from it before calling. Metered by transcribed
713
- * duration against the tenant credit pool server-side.
487
+ * Pattern A: multi-account credential fetch for Microsoft 365.
488
+ *
489
+ * Returns every agent-scoped Microsoft connection. The caller is expected
490
+ * to require an `email` selector on every credential-touching tool and
491
+ * look up the matching account at dispatch time.
492
+ *
493
+ * Returned `accounts[i].accountIdentifier` is the user's primary email
494
+ * (or the tid claim as fallback) — the stable cross-session identifier
495
+ * the LLM should pass.
496
+ *
497
+ * Per-account token refresh is exposed via `refreshMicrosoftAccountToken`,
498
+ * NOT `refreshXeroAccountToken` — Microsoft refresh tokens are not
499
+ * interchangeable across (tenant, user) pairs.
714
500
  */
715
- stt(args: VoiceSttArgs): Promise<VoiceSttResult>;
716
- }
717
- //# sourceMappingURL=voice.d.ts.map
718
- //#endregion
719
- //#region src/domains/identity.d.ts
720
- type IdentityStatus = "anonymous" | "partial" | "identified" | "verified";
721
- interface IdentityDirectoryEntry {
722
- identityId: string;
723
- status: IdentityStatus;
724
- displayName: string;
725
- name?: string;
726
- avatarUrl?: string;
727
- lastSeenAt: string;
728
- lastSeenProvider?: string;
729
- messageable: boolean;
730
- }
731
- declare class IdentityApi extends ApiBase {
501
+ getMicrosoftAccounts(): Promise<{
502
+ accounts: {
503
+ connectionId: string;
504
+ accountIdentifier: string;
505
+ displayName: string | null;
506
+ connectedAt: string;
507
+ accessToken: string;
508
+ accessTokenExpiresAt: string;
509
+ email: string;
510
+ microsoftTenantId: string;
511
+ workspaceDomain: string;
512
+ }[];
513
+ }>;
732
514
  /**
733
- * Returns the calling agent's own identity context `{ agentId, tenantId }`
734
- * decoded server-side from the agent API token. Used by the
735
- * `@alfe.ai/openclaw-identity` plugin to bootstrap context when the
736
- * OpenClaw daemon doesn't plumb `ctx.agentId` through to plugin hooks.
737
- * Plugins should cache this for the daemon's lifetime (single-agent-per-
738
- * process invariant). One HTTP round-trip per process activate; not for
739
- * per-call use.
515
+ * Pattern A: refresh a specific Microsoft 365 connection by its
516
+ * `accountIdentifier`. For Microsoft, `accountIdentifier` is the user's
517
+ * email when the Graph profile fetch succeeded at connect time, and the
518
+ * Azure tenant id (`tid` claim) as fallback. Callers should pass the
519
+ * value returned by `getMicrosoftAccounts()` rather than synthesising
520
+ * an email locally.
521
+ *
522
+ * Microsoft refresh tokens are bound to a specific (tenant, user) pair —
523
+ * they are NOT interchangeable across accounts, so per-account refresh
524
+ * is mandatory. The generic /accounts/{accountIdentifier}/refresh
525
+ * endpoint walks the agent's full visible scope chain to find a matching
526
+ * connection (works for inherited team/project Microsoft connections).
740
527
  */
741
- whoami(): Promise<{
742
- agentId: string;
743
- tenantId: string;
744
- }>;
745
- resolveIdentity(args: {
746
- provider: string;
747
- platformId: string;
748
- kind?: "user" | "agent" | "service" | "bot" | "workspace";
749
- displayName?: string;
750
- }): Promise<{
751
- identityId: string | null;
752
- status: string;
753
- created?: boolean;
754
- reason?: string;
755
- /**
756
- * Flattened auriclabs permission strings for the resolved identity
757
- * (scope-prefixed where applicable). Empty array on miss / org service
758
- * outage — the runtime gate fails closed in that case.
759
- */
760
- permissions: string[];
761
- }>;
762
- searchIdentities(args?: {
763
- q?: string;
764
- status?: string;
765
- limit?: number;
766
- }): Promise<{
767
- identities: unknown[];
768
- }>;
769
- listIdentities(args?: {
770
- status?: IdentityStatus;
771
- limit?: number;
772
- cursor?: string;
773
- }): Promise<{
774
- identities: IdentityDirectoryEntry[];
775
- cursor: string | null;
776
- }>;
777
- getIdentityContext(identityId: string): Promise<{
778
- context: unknown;
779
- }>;
780
- mergeIdentities(survivorId: string, args: {
781
- mergedId: string;
782
- }): Promise<{
783
- ok: boolean;
784
- error?: string;
785
- }>;
786
- unmergeIdentity(identityId: string): Promise<{
787
- ok: boolean;
788
- error?: string;
789
- }>;
790
- addIdentityNote(identityId: string, args: {
791
- content: string;
792
- category?: string;
793
- }): Promise<{
794
- noteId: string | null;
528
+ refreshMicrosoftAccountToken(accountIdentifier: string): Promise<{
529
+ accessToken: string;
530
+ accessTokenExpiresAt: string;
531
+ expiresAt: string;
795
532
  }>;
796
- tagIdentity(identityId: string, args: {
797
- tag: string;
798
- action: "add" | "remove";
799
- }): Promise<{
800
- ok: boolean;
533
+ /**
534
+ * Disconnects one connected Microsoft 365 account for the agent, by its
535
+ * `accountIdentifier`. Hits the generic per-account disconnect route
536
+ * (`DELETE /agent/connect/microsoft/accounts/{accountIdentifier}`), which
537
+ * resolves across the agent's full effective scope chain and deletes the
538
+ * matching Connection row. Returns the remaining accounts.
539
+ *
540
+ * IMPORTANT: pass the `accountIdentifier` from `getMicrosoftAccounts()`, NOT
541
+ * a synthesised email. For Microsoft, `accountIdentifier` is the user's email
542
+ * only when the Graph profile fetch succeeded at connect time; it falls back
543
+ * to the Azure tenant id (`tid` claim) otherwise. The backend matches on
544
+ * `accountIdentifier` exactly, so passing an email would 404 on those
545
+ * fallback-identifier accounts. (This is why the param is not named `email`,
546
+ * unlike `disconnectGoogleAccount` where the identifier is always the email.)
547
+ */
548
+ disconnectMicrosoftAccount(accountIdentifier: string): Promise<{
549
+ accounts: {
550
+ accountIdentifier: string;
551
+ displayName?: string;
552
+ connectedAt?: string;
553
+ }[];
801
554
  }>;
802
- getIdentityChangelog(identityId: string, args?: {
803
- limit?: number;
804
- cursor?: string;
805
- }): Promise<{
806
- entries: unknown[];
807
- cursor: string | null;
555
+ /**
556
+ * Resolve the primary cTrader Connection's credentials for the calling
557
+ * agent. Unlike most providers, the cTrader Open API needs app-level auth
558
+ * (`clientId` + `clientSecret`) AND account auth (`accessToken` +
559
+ * `accountId`) on the socket, so `@alfe.ai/ctrader-mcp` self-fetches the
560
+ * full set here at startup (the atlassian/google pattern). `clientId` /
561
+ * `clientSecret` are the SST-sourced global app credentials the connect
562
+ * endpoint injects — they are never persisted on the connection. `host` is
563
+ * the resolved TLS endpoint (`live.ctraderapi.com` / `demo.ctraderapi.com`)
564
+ * derived from the selected account's live/demo flag.
565
+ */
566
+ getCTraderCredentials(): Promise<{
567
+ accessToken: string;
568
+ refreshToken: string;
569
+ accountId: string;
570
+ host: string;
571
+ clientId: string;
572
+ clientSecret: string;
808
573
  }>;
809
- rollbackIdentity(identityId: string, args: {
810
- targetVersion: number;
811
- }): Promise<{
812
- ok: boolean;
813
- entry?: unknown;
574
+ /**
575
+ * Pattern A: multi-account credential fetch for cTrader.
576
+ *
577
+ * Unlike atlassian/salesforce (one Connection row per account/site), a
578
+ * cTrader is MULTI-grant per agent: an agent may connect several distinct
579
+ * cTrader logins, each its own Connection row keyed on `accountIdentifier =
580
+ * ctid:<userId>` (Phase 1). This aggregates the *trading accounts* across
581
+ * ALL of those Connection rows — each row contributes its `availableAccounts`
582
+ * flattened, and every account carries ITS OWN grant's `accessToken` (the
583
+ * token that authenticates that account against the cTrader Open API). One
584
+ * OAuth grant still covers all accounts under that single login on one shared
585
+ * token; only the `ctidTraderAccountId` and the protobuf socket `host` (live
586
+ * vs demo) differ within a grant. Across grants the tokens differ, so the
587
+ * token is now PER-ACCOUNT rather than hoisted to the top level.
588
+ *
589
+ * `host` per account is derived from the account's `isLive` flag
590
+ * (`live.ctraderapi.com` / `demo.ctraderapi.com`) — the same mapping the
591
+ * connect provider applies server-side when an account is auto-selected.
592
+ *
593
+ * `clientId` / `clientSecret` are the SST-sourced GLOBAL app credentials the
594
+ * connect endpoint injects — identical across every Connection row (one
595
+ * cTrader app), never persisted on a connection. We take them from the first
596
+ * row that carries them.
597
+ *
598
+ * Accounts are deduped on `ctidTraderAccountId` first-wins: Spotware ids are
599
+ * globally unique across logins, so a duplicate can only appear if the same
600
+ * account somehow surfaced under two grants — first-wins keeps it
601
+ * deterministic.
602
+ *
603
+ * `accounts` may be empty (no cTrader Connection at all), in which case we
604
+ * return empty creds rather than throwing.
605
+ */
606
+ getCTraderAccounts(): Promise<{
607
+ accounts: {
608
+ ctidTraderAccountId: string;
609
+ host: string;
610
+ isLive: boolean;
611
+ brokerName?: string;
612
+ accountNumber?: string;
613
+ accessToken: string;
614
+ /**
615
+ * The stable per-grant Connection key (`ctid:<userId>`) this account
616
+ * belongs to. Every trading account under one cTrader login shares one
617
+ * grant (one OAuth token), so this is the identifier the MCP server
618
+ * passes to `refreshCTraderAccount()` to rotate the token for the whole
619
+ * grant on a `CH_ACCESS_TOKEN_INVALID` expiry. Empty string when the
620
+ * server did not supply one (legacy rows) — such an account can still
621
+ * trade with its current token but cannot self-refresh.
622
+ */
623
+ accountIdentifier: string;
624
+ }[];
625
+ clientId: string;
626
+ clientSecret: string;
814
627
  }>;
815
- requestIdentityVerification(args: {
816
- claimedIdentityId: string;
817
- requestingIdentityId: string;
818
- requestingProvider: string;
819
- requestingPlatformId: string;
820
- preferredChannel?: "mobile" | "email";
821
- /**
822
- * Phase 2: agent-supplied contact endpoint. When provided, the top-level
823
- * `preferredChannel` is ignored the contact's channel wins.
824
- */
825
- contact?: {
826
- channel: "email" | "mobile";
827
- value: string;
828
- };
829
- }): Promise<{
830
- verificationId: string;
831
- channel: string;
832
- deliveredTo: string;
628
+ /**
629
+ * Pattern A: refresh a specific cTrader grant by its stable
630
+ * `accountIdentifier` (`ctid:<userId>` from `getCTraderAccounts()`).
631
+ *
632
+ * cTrader access tokens live ~30 days; the `getCTraderAccounts()` /
633
+ * credentials reads serve the STORED token without refreshing, so refresh is
634
+ * the consumer's job. `@alfe.ai/ctrader-mcp` calls this when the cTrader Open
635
+ * API rejects an account-auth with `CH_ACCESS_TOKEN_INVALID`, then re-runs
636
+ * the socket handshake with the returned `accessToken`.
637
+ *
638
+ * Refreshing one grant rotates the single OAuth token that covers EVERY
639
+ * trading account under that login. cTrader's refresh token itself does not
640
+ * expire but may rotate on refresh (`rotatesRefreshToken: true`); connect
641
+ * persists the rotated refresh token server-side, so the caller only needs
642
+ * the new `accessToken`. Mirrors `refreshXeroAccountToken`.
643
+ */
644
+ refreshCTraderAccount(accountIdentifier: string): Promise<{
645
+ accessToken: string;
646
+ accessTokenExpiresAt: string;
833
647
  expiresAt: string;
834
- availableChannels: {
835
- channel: string;
836
- deliveredTo: string;
837
- }[];
838
- } | {
839
- error: string;
840
648
  }>;
841
- confirmIdentityVerification(args: {
842
- claimedIdentityId: string;
843
- verificationId: string;
844
- phrase: string;
845
- }): Promise<{
846
- verified: boolean;
847
- identityId?: string;
848
- /** Phase 2: how the confirm resolved — Scenario A vs B. */
849
- action?: "merged" | "contact_verified" | "already_confirmed";
850
- error?: string;
649
+ /**
650
+ * @deprecated Returns a single primary credential blob. Use
651
+ * `getShopifyAccounts()` for the multi-account shape required by Pattern A
652
+ * (`@alfe.ai/shopify-mcp` keys per-shop on the myshopify domain).
653
+ */
654
+ getShopifyCredentials(): Promise<{
655
+ accessToken: string;
656
+ shopDomain: string;
657
+ shopGid: string;
658
+ shopName: string;
659
+ apiVersion: string;
851
660
  }>;
852
661
  /**
853
- * Update display-shape fields on an Identity. Body excludes `email` /
854
- * `phone` / `title` / `company` / `metadata` per Section D4 contacts go
855
- * via the verify flow, title/company live on OrgMembership, metadata is
856
- * not agent-writable.
662
+ * Pattern A: multi-account credential fetch for Shopify. Returns every
663
+ * agent-scoped Shopify Connection. One OAuth grant maps to one store, so the
664
+ * stable per-call selector is the store's myshopify domain (`shopDomain`),
665
+ * NOT `accountIdentifier` — the connect provider keys `accountIdentifier` on
666
+ * the immutable shop GID (falling back to the domain), so `shopDomain` is the
667
+ * value the LLM passes and the plugin routes on.
668
+ *
669
+ * Each entry is shaped by the connect provider's `buildCredentialsResponse`:
670
+ * `{ accessToken, shopDomain, shopGid, shopName, apiVersion }` — offline
671
+ * Shopify tokens never expire, so there is NO token / expiry field and no
672
+ * refresh method (unlike Salesforce). The GraphQL Admin API authenticates
673
+ * purely on `X-Shopify-Access-Token`; no client credentials are on the wire.
857
674
  */
858
- updateIdentity(identityId: string, args: {
859
- name?: string;
860
- avatarUrl?: string;
861
- timezone?: string;
862
- locale?: string;
863
- }): Promise<{
864
- ok: boolean;
675
+ getShopifyAccounts(): Promise<{
676
+ accounts: {
677
+ connectionId: string;
678
+ accountIdentifier: string;
679
+ displayName: string | null;
680
+ connectedAt: string;
681
+ accessToken: string;
682
+ shopDomain: string;
683
+ shopGid: string;
684
+ shopName: string;
685
+ apiVersion: string;
686
+ }[];
865
687
  }>;
866
688
  /**
867
- * Phase 2 (Section H): server-side verification of a Google Chat sender via
868
- * the agent's existing Google OAuth credentials. Returns the resolved
869
- * identity (created or matched via Scenario-B email enrichment).
689
+ * Pattern A: provider-parameterized multi-account credential fetch for the
690
+ * social connectors (Bluesky, and the approval-gated backlog: X, Meta,
691
+ * Threads, LinkedIn, Pinterest, TikTok, Reddit, YouTube).
692
+ *
693
+ * Unlike the bespoke `getGithubAccounts()` / `getXeroAccounts()` shapes,
694
+ * this returns a UNIFORM normalized account shape so `@alfe.ai/social-mcp`'s
695
+ * shared driver can require a single `account` selector on every
696
+ * credential-touching tool regardless of platform. The backend
697
+ * `api-agents/{provider}/accounts` route is already provider-generic; this
698
+ * is the client-side normalization the plan (`do-we-need-any-moonlit-toucan`
699
+ * Phase 0, step 5) calls for.
700
+ *
701
+ * `accountIdentifier` is the stable per-account selector the LLM should
702
+ * pass back (for Bluesky: the account DID). `accessToken` carries whatever
703
+ * the provider's `buildCredentialsResponse` bundles (for Bluesky: the JSON
704
+ * session bundle — the driver parses the `accessJwt` out of it, or reads the
705
+ * top-level `accessJwt` from `providerMetadata`-adjacent fields). Everything
706
+ * else the driver needs for routing (handle, pdsHost, did, …) is on
707
+ * `providerMetadata`.
708
+ *
709
+ * Token refresh is delegated to connect (never done in-plugin) via the
710
+ * per-account route `POST /agent/connect/{provider}/accounts/{accountIdentifier}/refresh`
711
+ * — call `refreshSocialAccount(provider, accountIdentifier)`. (The non-account
712
+ * `POST /agent/connect/{provider}/refresh` route refreshes the provider's
713
+ * PRIMARY connection, which is wrong under multi-account Pattern A.)
870
714
  */
871
- resolveGoogleChatSender(args: {
872
- senderUserId: string;
873
- spaceId?: string;
874
- }): Promise<{
875
- identityId: string | null;
876
- status: string;
715
+ getSocialAccounts(provider: string): Promise<{
716
+ provider: string;
717
+ accounts: {
718
+ connectionId: string;
719
+ accountIdentifier: string;
720
+ displayName: string | null;
721
+ accessToken: string;
722
+ providerMetadata: Record<string, unknown>;
723
+ connectedAt: string;
724
+ }[];
725
+ }>;
726
+ /**
727
+ * Pattern A: refresh a specific social Connection by its stable
728
+ * `accountIdentifier` (for Bluesky: the account DID) via the
729
+ * provider-generic per-account refresh route. The counterpart to
730
+ * `getSocialAccounts(provider)`; `@alfe.ai/social-mcp` calls this on a
731
+ * 401/ExpiredToken from the platform PDS/API, then re-fetches accounts to
732
+ * pick up the rotated bundle.
733
+ *
734
+ * Refresh itself is ALWAYS delegated to connect — the plugin never calls
735
+ * the platform's own refresh XRPC (e.g. `com.atproto.server.refreshSession`)
736
+ * because connect owns the encrypted refresh token + rotation persistence
737
+ * (Bluesky rotates the refreshJwt; a missed rotation kills the connection
738
+ * after one refresh). The returned `accessToken` is whatever the provider's
739
+ * `refreshToken` hook re-bundled (for Bluesky: the JSON session bundle with
740
+ * the fresh `accessJwt`) — callers typically ignore it and re-fetch via
741
+ * `getSocialAccounts` for a consistent shape.
742
+ */
743
+ refreshSocialAccount(provider: string, accountIdentifier: string): Promise<{
744
+ accountIdentifier: string;
745
+ accessToken: string;
746
+ accessTokenExpiresAt: string;
747
+ expiresAt: string;
877
748
  }>;
878
749
  }
879
- //# sourceMappingURL=identity.d.ts.map
750
+ //# sourceMappingURL=connect-credentials.d.ts.map
880
751
  //#endregion
881
- //#region src/domains/search.d.ts
752
+ //#region src/domains/integrations.d.ts
882
753
  /**
883
- * The broad-news providers behind the metered `services/news` Lambda. The
884
- * server validates this with a zod enum; a value outside the union is an
885
- * unpriceable product, so keep the literal union in lockstep with the service.
754
+ * One entry in the agent's EFFECTIVE integration list. Agent-scope install
755
+ * rows keep their full public row shape (config included, `scope: "agent"`);
756
+ * connection-/channel-/custom-driven activations and inherited
757
+ * org/team/project installs have no agent-scope row and appear as the
758
+ * narrower projection. Discriminate on `config`: only the agent-scope row
759
+ * arm carries it (`source` alone is NOT a discriminator — inherited explicit
760
+ * rows land in the narrow arm with `source: "explicit"` too).
886
761
  */
887
- type NewsProvider = "apitube" | "newsdata";
888
- /** One normalized article. `sentiment` is provider-shaped (APITube supplies it). */
889
- interface NewsArticle {
890
- title: string;
891
- url: string;
892
- source: string;
893
- publishedAt: string;
894
- snippet: string;
895
- sentiment?: unknown;
896
- }
897
- /** Provider-agnostic result — the server normalizes every adapter to this. */
898
- interface NewsResult {
899
- articles: NewsArticle[];
900
- provider: string;
901
- }
902
- declare class SearchApi extends ApiBase {
903
- searchWeb(params: {
904
- query: string;
905
- count?: number;
906
- offset?: number;
907
- country?: string;
908
- freshness?: string;
909
- }, options?: {
910
- signal?: AbortSignal;
911
- }): Promise<unknown>;
912
- searchImages(params: {
913
- query: string;
914
- count?: number;
915
- }, options?: {
916
- signal?: AbortSignal;
917
- }): Promise<unknown>;
918
- searchNews(params: {
919
- query: string;
920
- count?: number;
921
- offset?: number;
922
- freshness?: string;
923
- }, options?: {
924
- signal?: AbortSignal;
925
- }): Promise<unknown>;
926
- /** Search news across the selected provider's corpus. → POST /agent/news/search */
927
- newsSearch(params: {
928
- query: string;
929
- provider?: NewsProvider;
930
- source?: string;
931
- from?: string;
932
- to?: string;
933
- language?: string;
934
- category?: string;
935
- limit?: number;
936
- }): Promise<NewsResult>;
937
- /** Top headlines for the selected provider. → POST /agent/news/headlines */
938
- newsHeadlines(params?: {
939
- provider?: NewsProvider;
940
- category?: string;
941
- source?: string;
942
- language?: string;
943
- limit?: number;
944
- }): Promise<NewsResult>;
762
+ type AgentIntegrationListEntry = (IntegrationInstall$1 & {
763
+ source: "explicit";
764
+ }) | {
765
+ integrationId: string;
766
+ version: string;
767
+ desiredStatus: IntegrationDesiredStatus;
768
+ actualStatus: IntegrationActualStatus;
769
+ source: IntegrationActivationSource$1;
770
+ /** Winning row's scope — present only on inherited explicit entries. */
771
+ scope?: IntegrationScope;
772
+ scopeId?: string;
773
+ config?: undefined;
774
+ connectionId?: string;
775
+ channelId?: string;
776
+ displayName?: string;
777
+ icon?: string;
778
+ availableVersion?: string;
779
+ reinstallRequestedAt?: string;
780
+ };
781
+ declare class IntegrationsApi extends ApiBase {
782
+ /**
783
+ * List the integrations EFFECTIVE for this agent — explicit agent-scope
784
+ * installs plus driven activations (google, myob, xero, google-chat, …)
785
+ * and inherited org-scope installs, discriminated by `source`.
786
+ */
787
+ listIntegrations(): Promise<{
788
+ integrations: AgentIntegrationListEntry[];
789
+ }>;
790
+ getIntegrationConfig(integrationId: string): Promise<IntegrationConfigResult$1>;
791
+ updateIntegrationConfig(integrationId: string, config: Record<string, unknown>): Promise<void>;
792
+ installIntegration(integrationId: string, options?: {
793
+ version?: string;
794
+ config?: Record<string, unknown>;
795
+ }): Promise<IntegrationInstall$1>;
796
+ removeIntegration(integrationId: string): Promise<IntegrationInstall$1>;
797
+ getOAuthUrl(provider: string, scopes?: string[], options?: {
798
+ shop?: string;
799
+ }): Promise<{
800
+ url: string;
801
+ provider: string;
802
+ expiresIn: number;
803
+ }>;
804
+ getOAuthStatus(provider: string): Promise<{
805
+ provider: string;
806
+ connected: boolean;
807
+ config?: Record<string, string>;
808
+ }>;
809
+ getRegistry(): Promise<{
810
+ integrations: RegistryEntry$1[];
811
+ }>;
945
812
  }
946
- //# sourceMappingURL=search.d.ts.map
813
+ //# sourceMappingURL=integrations.d.ts.map
947
814
  //#endregion
948
- //#region src/domains/webhooks.d.ts
949
- interface AgentWebhook {
950
- webhookId: string;
815
+ //#region src/domains/workspace.d.ts
816
+ /** Response of GET /agent/workspace (services/agents). */
817
+ interface AgentWorkspaceInfo {
818
+ templateKey?: string;
819
+ defaultModel?: string;
820
+ installedFrom?: {
821
+ templateKey: string;
822
+ authorTenantId: string;
823
+ version: number;
824
+ };
825
+ runtime?: string;
826
+ teams?: {
827
+ teamId: string;
828
+ name: string;
829
+ description?: string;
830
+ parentTeamId?: string;
831
+ }[];
832
+ projects?: {
833
+ projectId: string;
834
+ name: string;
835
+ description?: string;
836
+ status: string;
837
+ parentProjectId?: string;
838
+ }[];
839
+ teamIds?: string[];
840
+ projectIds?: string[];
841
+ }
842
+ declare class WorkspaceApi extends ApiBase {
843
+ /**
844
+ * GET /agent/workspace — workspace config for the authenticated agent
845
+ * (template assignment, default model, org roster).
846
+ */
847
+ getWorkspace(): Promise<AgentWorkspaceInfo>;
848
+ /**
849
+ * GET /templates/{key}/files — persona/workspace file contents for a
850
+ * template the agent has access to. Pass `version` to pin to the version
851
+ * the agent was installed from (omit → the endpoint resolves `latest`).
852
+ */
853
+ getTemplateFiles(templateKey: string, opts?: {
854
+ version?: number;
855
+ }): Promise<{
856
+ files: Record<string, string>;
857
+ }>;
858
+ }
859
+ //# sourceMappingURL=workspace.d.ts.map
860
+ //#endregion
861
+ //#region src/domains/sync.d.ts
862
+ interface SyncAgentInfo {
863
+ agentId: string;
951
864
  tenantId: string;
865
+ displayName: string;
866
+ s3Prefix: string;
867
+ status: "stale" | "syncing" | "synced";
868
+ fileCount?: number;
869
+ totalSize?: number;
870
+ lastSync?: string;
871
+ }
872
+ interface SyncManifestEntry {
873
+ hash: string;
874
+ size: number;
875
+ modified: string;
876
+ etag?: string;
877
+ storageClass?: string;
878
+ compressed?: boolean;
879
+ }
880
+ interface SyncManifest {
881
+ version: 1;
952
882
  agentId: string;
953
- name: string;
954
- provider: string;
955
- active: boolean;
956
- createdBy: string;
957
- createdAt: string;
958
- updatedAt: string;
883
+ lastSync: string;
884
+ files: Record<string, SyncManifestEntry>;
959
885
  }
960
- interface CreatedAgentWebhook extends AgentWebhook {
886
+ interface SyncPresignedUrl {
887
+ path: string;
961
888
  url: string;
962
- signingSecret: string;
889
+ expiresAt: string;
963
890
  }
964
- interface AgentWebhookDelivery {
965
- deliveryId: string;
966
- webhookId: string;
967
- status: string;
968
- attempts: number;
969
- createdAt: string;
970
- deliveredAt?: string;
891
+ interface SyncConfirmedUpload {
892
+ filePath: string;
893
+ hash: string;
894
+ size: number;
895
+ storageClass: "STANDARD" | "GLACIER_IR";
896
+ syncedAt: string;
971
897
  }
972
- declare class WebhooksApi extends ApiBase {
973
- createWebhook(args: {
974
- name: string;
975
- provider?: "generic" | "github" | "stripe" | "slack";
976
- }): Promise<CreatedAgentWebhook>;
977
- listWebhooks(): Promise<AgentWebhook[]>;
978
- deleteWebhook(webhookId: string): Promise<{
979
- webhookId: string;
980
- active: false;
981
- }>;
982
- rotateWebhookSecret(webhookId: string): Promise<{
983
- webhookId: string;
984
- signingSecret: string;
985
- }>;
986
- listWebhookDeliveries(webhookId: string): Promise<AgentWebhookDelivery[]>;
898
+ interface SyncReconstructFile {
899
+ path: string;
900
+ size: number;
901
+ url: string;
902
+ storageClass?: string;
903
+ compressed?: boolean;
987
904
  }
988
- //# sourceMappingURL=webhooks.d.ts.map
989
- //#endregion
990
- //#region src/domains/chat.d.ts
991
- declare class ChatApi extends ApiBase {
992
- ensureDirectConversation(identityId: string): Promise<{
993
- conversationId: string;
994
- identityId: string;
995
- tenantId: string;
996
- userId: string;
997
- displayName: string;
998
- created: boolean;
905
+ interface SyncReconstructBundle {
906
+ agentId: string;
907
+ mode: "full" | "active" | "memory";
908
+ fileCount: number;
909
+ totalSize: number;
910
+ files: SyncReconstructFile[];
911
+ expiresAt: string;
912
+ }
913
+ interface SyncAgentStats {
914
+ agentId: string;
915
+ standardBytes: number;
916
+ glacierBytes: number;
917
+ fileCount: number;
918
+ lastSyncAt: string | null;
919
+ }
920
+ interface SyncFileEntry {
921
+ filePath: string;
922
+ size: number;
923
+ modified: string;
924
+ contentHash: string;
925
+ storageClass?: string;
926
+ compressed?: boolean;
927
+ }
928
+ interface SyncSessionEntry {
929
+ sessionId: string;
930
+ size: number;
931
+ lastModified: string;
932
+ storageClass?: string;
933
+ isArchived: boolean;
934
+ }
935
+ interface SyncSessionContent {
936
+ sessionId: string;
937
+ content: string;
938
+ compressed: boolean;
939
+ }
940
+ interface SharedFileEntry {
941
+ filePath: string;
942
+ fileName: string;
943
+ size: number;
944
+ contentType?: string;
945
+ }
946
+ declare class SyncApi extends ApiBase {
947
+ syncRegister(args?: {
948
+ displayName?: string;
949
+ }): Promise<{
950
+ agent: SyncAgentInfo;
999
951
  }>;
1000
- presignAttachments(files: {
1001
- filename: string;
1002
- mimeType: string;
1003
- size: number;
1004
- }[]): Promise<{
1005
- attachments: {
1006
- id: string;
1007
- uploadUrl: string;
1008
- uploadHeaders: Record<string, string>;
1009
- downloadUrl: string;
1010
- s3Key: string;
1011
- expiresAt: string;
952
+ syncGetManifest(): Promise<SyncManifest>;
953
+ syncPresign(args: {
954
+ files: {
955
+ path: string;
956
+ operation: "put" | "get";
957
+ contentType?: string;
1012
958
  }[];
1013
- }>;
1014
- recordActivity(data: {
1015
- userId?: string;
1016
- channel: string;
1017
- role: "user" | "assistant";
1018
959
  }): Promise<{
1019
- recorded: boolean;
960
+ urls: SyncPresignedUrl[];
1020
961
  }>;
1021
- }
1022
- //# sourceMappingURL=chat.d.ts.map
1023
- //#endregion
1024
- //#region src/domains/connect-credentials.d.ts
1025
- declare class ConnectCredentialsApi extends ApiBase {
1026
- /**
1027
- * Returns every connected Google account for the agent. Multi-account by
1028
- * design the openclaw-google plugin requires the LLM to pass `email`
1029
- * explicitly to `google_run_command` so an account is always selected
1030
- * deliberately.
1031
- *
1032
- * 2026-05-14 (connections-redesign PR 1): the legacy flat shape (`email`,
1033
- * `refreshToken`, `accessToken`, etc., populated from the default account)
1034
- * is gone. Iterate over `accounts`.
1035
- */
1036
- getGoogleCredentials(): Promise<{
1037
- accounts: {
1038
- email: string;
1039
- refreshToken: string;
1040
- clientId: string;
1041
- clientSecret: string;
1042
- displayName?: string;
1043
- connectedAt?: string;
1044
- }[];
962
+ syncConfirmUpload(args: {
963
+ filePath: string;
964
+ hash: string;
965
+ size: number;
966
+ storageClass?: "STANDARD" | "GLACIER_IR";
967
+ }): Promise<SyncConfirmedUpload>;
968
+ syncReconstruct(args: {
969
+ mode: "full" | "active" | "memory";
970
+ }): Promise<SyncReconstructBundle>;
971
+ syncGetStats(): Promise<SyncAgentStats>;
972
+ syncListFiles(args?: {
973
+ prefix?: string;
974
+ }): Promise<{
975
+ files: SyncFileEntry[];
1045
976
  }>;
1046
- disconnectGoogleAccount(email: string): Promise<{
1047
- accounts: {
1048
- email: string;
1049
- displayName?: string;
1050
- connectedAt?: string;
1051
- }[];
977
+ syncListSessions(): Promise<{
978
+ sessions: SyncSessionEntry[];
1052
979
  }>;
1053
- getGoogleChatCredentials(): Promise<{
1054
- email: string;
1055
- refreshToken: string;
1056
- clientId: string;
1057
- clientSecret: string;
1058
- displayName?: string;
980
+ syncGetSession(sessionId: string): Promise<SyncSessionContent>;
981
+ syncDeleteFile(filePath: string): Promise<{
982
+ removed: boolean;
983
+ }>;
984
+ sharedListFiles(args: {
985
+ scope: "org" | "team" | "project";
986
+ scopeId: string;
987
+ limit?: number;
988
+ cursor?: string;
989
+ }): Promise<{
990
+ files: SharedFileEntry[];
991
+ nextCursor: string | null;
992
+ }>;
993
+ sharedDownloadUrl(args: {
994
+ scope: "org" | "team" | "project";
995
+ scopeId: string;
996
+ filePath: string;
997
+ }): Promise<{
998
+ downloadUrl: string;
999
+ expiresIn: number;
1059
1000
  }>;
1001
+ }
1002
+ //# sourceMappingURL=sync.d.ts.map
1003
+ //#endregion
1004
+ //#region src/domains/knowledge.d.ts
1005
+ type KnowledgeScopeType = "org" | "team" | "project";
1006
+ interface KnowledgeScope {
1007
+ scopeType: KnowledgeScopeType;
1008
+ scopeId: string;
1009
+ name: string;
1010
+ }
1011
+ interface KnowledgeSearchHit {
1012
+ id: string;
1013
+ text: string;
1014
+ /** Normalized relevance in (0,1]; higher = closer. */
1015
+ score: number;
1016
+ scopeType: KnowledgeScopeType;
1017
+ scopeId: string;
1060
1018
  /**
1061
- * Fetch decrypted credentials for ONE specific connection by its
1062
- * stable connectionId (connection-scoped, vs the provider-scoped
1063
- * `get<Provider>Credentials` helpers). Used by the daemon to resolve
1064
- * a Custom Connection-driven integration's credentials from the
1065
- * exact connection it was installed from — every custom connection
1066
- * shares the `custom` provider id, so provider-scoping is ambiguous.
1067
- *
1068
- * For custom connections `accessToken` is the JSON-encoded secret
1069
- * bundle (the daemon un-bundles it); non-secret fields are on
1070
- * `providerMetadata`. The endpoint enforces that the connection is in
1071
- * the calling agent's effective scope (403 otherwise).
1019
+ * Provenance of the hit. All live results are `"doc"`; `"fact"` only ever
1020
+ * appears for legacy vectors indexed before the facts primitive was removed
1021
+ * (the search index stays tolerant of them). Treat every hit as a doc.
1072
1022
  */
1073
- getConnectionCredentials(connectionId: string): Promise<{
1074
- provider: string;
1075
- connectionId: string;
1076
- accountIdentifier?: string;
1077
- accessToken?: string;
1078
- providerMetadata?: Record<string, unknown>;
1079
- [key: string]: unknown;
1080
- }>;
1023
+ source: "doc" | "fact";
1024
+ /** The canonical file under shared/<scope>/ (present on doc hits). */
1025
+ filePath?: string;
1026
+ /** Legacy-only: the id of a pre-removal fact vector. */
1027
+ factId?: string;
1028
+ }
1029
+ interface KnowledgeSearchResult {
1030
+ results: KnowledgeSearchHit[];
1031
+ /** True when fan-out breadth was capped (more member scopes than the cap). */
1032
+ truncatedScopes: boolean;
1033
+ }
1034
+ interface KnowledgeProfileLink {
1035
+ label: string;
1036
+ url: string;
1037
+ }
1038
+ interface KnowledgeProfile {
1039
+ scopeType: KnowledgeScopeType;
1040
+ scopeId: string;
1041
+ about: string | null;
1042
+ description: string | null;
1043
+ links: KnowledgeProfileLink[];
1044
+ updatedAt: string | null;
1045
+ updatedBy: string | null;
1046
+ }
1047
+ type ChangeRequestResourceType = "doc" | "profile";
1048
+ type ChangeRequestOperation = "create" | "update" | "delete";
1049
+ type ChangeRequestStatus = "open" | "approved" | "rejected" | "withdrawn" | "superseded";
1050
+ type ChangeRequestActorKind = "human" | "agent";
1051
+ /** Public projection of a change request (mirrors `PublicChangeRequest` in services/org). */
1052
+ interface KnowledgeChangeRequest {
1053
+ changeRequestId: string;
1054
+ scopeType: KnowledgeScopeType;
1055
+ scopeId: string;
1056
+ resourceType: ChangeRequestResourceType;
1057
+ operation: ChangeRequestOperation;
1058
+ targetPath: string | null;
1059
+ baseVersionId: string | null;
1060
+ proposedContentType: string | null;
1061
+ status: ChangeRequestStatus;
1062
+ proposerId: string;
1063
+ proposerKind: ChangeRequestActorKind;
1064
+ rationale: string;
1065
+ reviewerId: string | null;
1066
+ reviewerKind: ChangeRequestActorKind | null;
1067
+ reviewedAt: string | null;
1068
+ reviewNote: string | null;
1069
+ appliedRef: string | null;
1070
+ createdAt: string;
1071
+ updatedAt: string;
1072
+ }
1073
+ /** Per-type proposal payload for `proposeScopeChange`. */
1074
+ interface ProposeScopeChangeInput {
1075
+ resourceType: ChangeRequestResourceType;
1076
+ operation: ChangeRequestOperation;
1077
+ /** Why the change is proposed — shown to the reviewer. */
1078
+ rationale: string;
1079
+ /** doc: the path the proposal applies to (e.g. designs/data-center.md). */
1080
+ targetPath?: string;
1081
+ /** doc create/update: the staged body to upload (markdown or other text). */
1082
+ content?: string;
1083
+ /** doc create/update: content type of the staged body (default text/markdown). */
1084
+ contentType?: string;
1085
+ /** profile: the proposed value ({ about, description, links }). */
1086
+ proposedValue?: unknown;
1087
+ }
1088
+ interface KnowledgeDoc {
1089
+ filePath: string;
1090
+ fileName: string;
1091
+ contentType?: string;
1092
+ size: number;
1093
+ uploadedBy?: string;
1094
+ createdAt: string;
1095
+ updatedAt: string;
1096
+ }
1097
+ declare class KnowledgeApi extends ApiBase {
1081
1098
  /**
1082
- * @deprecated Returns a single primary credential blob (legacy "pick-the-
1083
- * default-connection" shape). Use `getGithubAccounts()` for the multi-
1084
- * account shape required by Pattern A explicit selector args on every
1085
- * tool. Retained because the `@alfe.ai/github-mcp` proxy is the
1086
- * only consumer that knows about Pattern A; legacy env-interpolation
1087
- * callers will keep hitting `/credentials` until they move to the proxy.
1099
+ * Semantic search across the agent's member scopes. Fan-out is gated
1100
+ * server-side by `listScopes` set-inclusion (fail-closed). Pass
1101
+ * `scopeType` + `scopeId` to narrow to one scope; a non-member scope
1102
+ * yields empty results (never a cross-scope leak).
1088
1103
  */
1089
- getGithubCredentials(): Promise<{
1090
- login: string;
1091
- accessToken: string;
1104
+ knowledgeSearch(query: string, opts?: {
1105
+ limit?: number;
1106
+ scopeType?: KnowledgeScopeType;
1107
+ scopeId?: string;
1108
+ }): Promise<KnowledgeSearchResult>;
1109
+ /** Enumerate the scopes (org + teams + projects) this agent belongs to. */
1110
+ listScopes(): Promise<{
1111
+ scopes: KnowledgeScope[];
1092
1112
  }>;
1113
+ /** Read a scope's structured knowledge profile (after membership check). */
1114
+ getScopeProfile(scopeType: KnowledgeScopeType, scopeId: string): Promise<KnowledgeProfile>;
1093
1115
  /**
1094
- * Pattern A: multi-account credential fetch for GitHub.
1095
- *
1096
- * Returns every agent-scoped GitHub connection. The caller is expected
1097
- * to require a `login` selector on every credential-touching tool and
1098
- * look up the matching account at dispatch time.
1099
- *
1100
- * GitHub OAuth tokens have no expiry (`tokenLifecycle: "no_expiry"`),
1101
- * so there is intentionally no `refreshGithubAccountToken` method — if
1102
- * a token is revoked the user must re-run the OAuth flow.
1103
- *
1104
- * Returned `accounts[i].login` is the GitHub username — the stable
1105
- * cross-session identifier the LLM should pass.
1116
+ * Open a change request against a scope's knowledge resource. For a doc
1117
+ * create/update, `services/org` returns a presigned staging PUT; this method
1118
+ * uploads the proposed `content` to it (echoing the same Content-Type that
1119
+ * was signed), mirroring `writeScopeDoc`. The staged body is applied to the
1120
+ * canonical doc attributed to this agent — only when a reviewer approves.
1106
1121
  */
1107
- getGithubAccounts(): Promise<{
1108
- accounts: {
1109
- connectionId: string;
1110
- accountIdentifier: string;
1111
- displayName: string | null;
1112
- connectedAt: string;
1113
- accessToken: string;
1114
- login: string;
1115
- scopes: string;
1116
- }[];
1117
- }>;
1122
+ proposeScopeChange(scopeType: KnowledgeScopeType, scopeId: string, input: ProposeScopeChangeInput): Promise<KnowledgeChangeRequest>;
1118
1123
  /**
1119
- * @deprecated Returns a single primary credential blob (legacy "pick-the-
1120
- * default-connection" shape). Use `getXeroAccounts()` for the multi-
1121
- * account shape required by Pattern A — explicit selector args on every
1122
- * tool. This method will be removed once all consumers migrate.
1124
+ * List the agent's OWN change requests in a scope (filtered server-side to
1125
+ * this agent as proposer). Pass `status` to narrow to open / approved / etc.
1123
1126
  */
1124
- getXeroCredentials(): Promise<{
1125
- accessToken: string;
1126
- accessTokenExpiresAt: string;
1127
- xeroTenantId: string;
1127
+ listScopeChangeRequests(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
1128
+ status?: ChangeRequestStatus;
1129
+ limit?: number;
1130
+ cursor?: string;
1131
+ }): Promise<{
1132
+ changeRequests: KnowledgeChangeRequest[];
1133
+ nextCursor: string | null;
1128
1134
  }>;
1129
- /**
1130
- * Pattern A: multi-account credential fetch for Xero. Returns every
1131
- * agent-scoped Xero connection. The caller is expected to require a
1132
- * selector arg (e.g. `xeroTenantId`) on every credential-touching tool
1133
- * and look up the matching account by that selector at dispatch time.
1134
- *
1135
- * `xeroTenantId` is the model-facing organisation selector. The separate
1136
- * `accountIdentifier` is the Connect persistence key used for refresh and
1137
- * may be an email; never substitute one for the other.
1138
- */
1139
- getXeroAccounts(): Promise<{
1140
- accounts: {
1141
- connectionId: string;
1142
- accountIdentifier: string;
1143
- displayName: string | null;
1144
- connectedAt: string;
1145
- accessToken: string;
1146
- accessTokenExpiresAt: string;
1147
- xeroTenantId: string;
1148
- }[];
1149
- }>;
1150
- refreshXeroToken(): Promise<{
1151
- accessToken: string;
1152
- expiresAt: string;
1153
- }>;
1154
- /**
1155
- * Refresh a specific Xero Connection by its exact `accountIdentifier` from
1156
- * `getXeroAccounts()`. Do not substitute `xeroTenantId`: current Xero OAuth
1157
- * rows may use the account email as their persistence key even when a sole
1158
- * organisation tenant ID is available in provider metadata.
1159
- */
1160
- refreshXeroAccountToken(accountIdentifier: string): Promise<{
1161
- accessToken: string;
1162
- accessTokenExpiresAt: string;
1163
- expiresAt: string;
1135
+ /** List a scope's docs (the org-files corpus; mirrored to shared/<scope>/). */
1136
+ listScopeDocs(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
1137
+ limit?: number;
1138
+ cursor?: string;
1139
+ }): Promise<{
1140
+ files: KnowledgeDoc[];
1141
+ nextCursor: string | null;
1164
1142
  }>;
1165
1143
  /**
1166
- * @deprecated Returns a single primary credential blob (legacy "pick-the-
1167
- * default-connection" shape). Use `getNotionAccounts()` for the multi-
1168
- * account shape required by Pattern A.
1144
+ * Read the full text of a scope doc. Resolves a presigned download URL
1145
+ * from `services/org`, then fetches the bytes directly from S3 (the one
1146
+ * legitimate raw fetch in a plugin — same pattern as sync).
1169
1147
  */
1170
- getNotionCredentials(): Promise<{
1171
- accessToken: string;
1172
- workspaceId: string;
1173
- workspaceName: string;
1148
+ readScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, opts?: {
1149
+ maxBytes?: number;
1150
+ }): Promise<{
1151
+ filePath: string;
1152
+ text: string;
1174
1153
  }>;
1175
1154
  /**
1176
- * Pattern A: multi-account credential fetch for Notion. Returns every
1177
- * agent-scoped Notion connection. The caller is expected to require a
1178
- * selector arg (e.g. `workspaceId`) on every credential-touching tool.
1179
- *
1180
- * Returned `accounts[i].accountIdentifier` is the Notion workspaceId.
1155
+ * Write (create or overwrite) a scope doc. Two-step presigned upload:
1156
+ * `services/org` returns a signed URL plus `requiredHeaders` (author /
1157
+ * authorKind / message as `x-amz-meta-*`) that MUST be sent verbatim on
1158
+ * the PUT, alongside the same `Content-Type` that was signed. Author and
1159
+ * authorKind are server-set from the agent token — never trusted here.
1181
1160
  */
1182
- getNotionAccounts(): Promise<{
1183
- accounts: {
1184
- connectionId: string;
1185
- accountIdentifier: string;
1186
- displayName: string | null;
1187
- connectedAt: string;
1188
- accessToken: string;
1189
- workspaceId: string;
1190
- workspaceName: string;
1191
- }[];
1161
+ writeScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, content: string, opts?: {
1162
+ contentType?: string;
1163
+ message?: string;
1164
+ }): Promise<{
1165
+ filePath: string;
1192
1166
  }>;
1193
- /**
1194
- * @deprecated Returns a single primary Atlassian Connection's credentials
1195
- * (one OAuth user, one cloudId) — the legacy "pick-the-default-connection"
1196
- * shape. Atlassian is multi-site by nature (each OAuth user may have
1197
- * access to multiple Cloud sites), so Pattern A plugins MUST use
1198
- * `getAtlassianAccounts()` to discover the full set and dispatch via
1199
- * the `cloudId` selector arg.
1200
- */
1201
- getAtlassianCredentials(): Promise<{
1202
- accessToken: string;
1203
- refreshToken: string;
1204
- accessTokenExpiresAt: string;
1205
- cloudId: string;
1206
- siteName: string;
1207
- siteUrl: string;
1208
- email: string;
1209
- enabledProducts: string[];
1210
- clientId: string;
1211
- clientSecret: string;
1167
+ }
1168
+ //# sourceMappingURL=knowledge.d.ts.map
1169
+ //#endregion
1170
+ //#region src/domains/mobile.d.ts
1171
+ /** Response of GET /mobile/numbers for an agent (services/mobile). */
1172
+ interface MobileNumberInfo {
1173
+ phoneNumber: string;
1174
+ countryCode: string;
1175
+ monthlyPrice?: number;
1176
+ status: string;
1177
+ errorMessage?: string;
1178
+ }
1179
+ /** One purchasable number from GET /mobile/numbers/search. */
1180
+ interface MobileAvailableNumber {
1181
+ number: string;
1182
+ friendlyName: string;
1183
+ locality: string;
1184
+ region: string;
1185
+ country: string;
1186
+ }
1187
+ /** Approved WhatsApp content template from GET /mobile/whatsapp/templates. */
1188
+ interface WhatsAppTemplate {
1189
+ contentSid: string;
1190
+ name: string;
1191
+ language: string;
1192
+ body: string;
1193
+ variables: Record<string, string>;
1194
+ category?: string;
1195
+ }
1196
+ declare class MobileApi extends ApiBase {
1197
+ getMobileNumber(): Promise<MobileNumberInfo>;
1198
+ searchMobileNumbers(args?: {
1199
+ country?: string;
1200
+ query?: string;
1201
+ }): Promise<{
1202
+ numbers: MobileAvailableNumber[];
1203
+ monthlyPrice: number;
1212
1204
  }>;
1213
- refreshAtlassianToken(): Promise<{
1214
- accessToken: string;
1215
- expiresAt: string;
1205
+ assignMobileNumber(args: {
1206
+ phoneNumber: string;
1207
+ countryCode: string;
1208
+ }): Promise<{
1209
+ phoneNumber: string;
1210
+ countryCode: string;
1211
+ status: "pending";
1216
1212
  }>;
1217
- /**
1218
- * Pattern A: multi-account / multi-site credential fetch for Atlassian.
1219
- *
1220
- * Returns every agent-scoped Atlassian Connection. Each Connection is
1221
- * one OAuth user with a single access token and N accessible Cloud
1222
- * sites (`availableSites`). The caller is expected to:
1223
- *
1224
- * 1. Flatten (connection × cloudId) into one MCP child per site.
1225
- * 2. Require a `cloudId` selector on every credential-touching tool.
1226
- * 3. Use the access token bound to the Connection that owns the
1227
- * requested `cloudId` (Atlassian shares one access token across
1228
- * all sites accessible to the OAuth user).
1229
- *
1230
- * Per-account token refresh uses `refreshAtlassianAccountToken(email)`
1231
- * — refreshing one Connection rotates its single access token, which
1232
- * then applies to every cloudId for that Connection.
1233
- *
1234
- * Returned `accounts[i].accountIdentifier` is the OAuth user's email
1235
- * — the stable cross-session identifier for refresh purposes. The LLM
1236
- * never sees this directly: it picks a site via the `cloudId` arg
1237
- * instead.
1238
- */
1239
- getAtlassianAccounts(): Promise<{
1240
- accounts: {
1241
- connectionId: string;
1242
- accountIdentifier: string;
1243
- displayName: string | null;
1244
- connectedAt: string;
1245
- accessToken: string;
1246
- accessTokenExpiresAt: string;
1247
- clientId: string;
1248
- clientSecret: string;
1249
- cloudId: string;
1250
- siteName: string;
1251
- siteUrl: string;
1252
- availableSites: {
1253
- id: string;
1254
- url: string;
1255
- name: string;
1256
- scopes?: string[];
1257
- avatarUrl?: string;
1258
- }[];
1259
- }[];
1213
+ releaseMobileNumber(): Promise<{
1214
+ released: true;
1260
1215
  }>;
1261
- /**
1262
- * Pattern A: refresh a specific Atlassian Connection by `accountIdentifier`
1263
- * (the OAuth user's email).
1264
- *
1265
- * Atlassian rotates refresh tokens (`rotatesRefreshToken: true`); the
1266
- * server-side per-account refresh endpoint handles rotation and
1267
- * persistence. Refreshing one Connection updates its single access
1268
- * token, which applies to every accessible Cloud site (cloudId) for
1269
- * that OAuth user.
1270
- *
1271
- * Returns the new access token + expiry. The proxy is responsible for
1272
- * fanning the new token out to every child server it spawned for
1273
- * cloudIds owned by this Connection.
1274
- */
1275
- refreshAtlassianAccountToken(accountIdentifier: string): Promise<{
1276
- accessToken: string;
1277
- accessTokenExpiresAt: string;
1278
- expiresAt: string;
1216
+ sendSms(args: {
1217
+ to: string;
1218
+ body: string;
1219
+ }): Promise<{
1220
+ sent: true;
1221
+ sid: string;
1279
1222
  }>;
1280
- /**
1281
- * @deprecated Returns a single primary credential blob (legacy "pick-the-
1282
- * default-connection" shape). Use `getMYOBAccounts()` for the multi-
1283
- * account shape required by Pattern A.
1284
- */
1285
- getMYOBCredentials(): Promise<{
1286
- accessToken: string;
1287
- accessTokenExpiresAt: string;
1288
- myobBusinessId: string;
1289
- clientId: string;
1223
+ startOutboundCall(args: {
1224
+ to: string;
1225
+ }): Promise<{
1226
+ callSid: string;
1227
+ status: string;
1290
1228
  }>;
1291
- /**
1292
- * Pattern A: multi-account credential fetch for MYOB. Returns every
1293
- * agent-scoped MYOB connection. The caller is expected to require a
1294
- * selector arg (e.g. `myobBusinessId` / `accountIdentifier`) on every
1295
- * credential-touching tool.
1296
- *
1297
- * Returned `accounts[i].accountIdentifier` is the MYOB businessId.
1298
- */
1299
- getMYOBAccounts(): Promise<{
1300
- accounts: {
1301
- connectionId: string;
1302
- accountIdentifier: string;
1303
- displayName: string | null;
1304
- connectedAt: string;
1305
- accessToken: string;
1306
- accessTokenExpiresAt: string;
1307
- myobBusinessId: string;
1308
- clientId: string;
1309
- }[];
1229
+ getWhatsAppSession(to: string): Promise<{
1230
+ active: boolean;
1231
+ expiresAt?: string;
1310
1232
  }>;
1311
- refreshMYOBToken(): Promise<{
1312
- accessToken: string;
1313
- expiresAt: string;
1233
+ sendWhatsAppMessage(args: {
1234
+ to: string;
1235
+ body: string;
1236
+ }): Promise<{
1237
+ sent: true;
1238
+ sid: string;
1239
+ }>;
1240
+ sendWhatsAppTemplate(args: {
1241
+ to: string;
1242
+ contentSid: string;
1243
+ contentVariables: Record<string, string>;
1244
+ bodyPreview?: string;
1245
+ }): Promise<{
1246
+ sent: true;
1247
+ sid: string;
1248
+ }>;
1249
+ listWhatsAppTemplates(): Promise<{
1250
+ templates: WhatsAppTemplate[];
1251
+ }>;
1252
+ }
1253
+ //# sourceMappingURL=mobile.d.ts.map
1254
+ //#endregion
1255
+ //#region src/domains/remote.d.ts
1256
+ interface RemoteSessionInfo {
1257
+ sessionId: string;
1258
+ agentId: string;
1259
+ surface: "browser" | "terminal";
1260
+ status: "agent_driving" | "awaiting_human" | "human_in_control" | "resuming" | "completed" | "expired" | "failed";
1261
+ url?: string;
1262
+ instructions?: string;
1263
+ requestedAt?: string;
1264
+ }
1265
+ declare class RemoteApi extends ApiBase {
1266
+ requestBrowserTakeover(args: {
1267
+ instructions: string;
1268
+ url?: string;
1269
+ conversationId?: string;
1270
+ }): Promise<{
1271
+ sessionId: string;
1272
+ status: string;
1273
+ }>;
1274
+ getRemoteSession(sessionId: string): Promise<RemoteSessionInfo>;
1275
+ completeRemoteSession(sessionId: string): Promise<{
1276
+ ok: boolean;
1314
1277
  }>;
1278
+ }
1279
+ //# sourceMappingURL=remote.d.ts.map
1280
+ //#endregion
1281
+ //#region src/domains/self.d.ts
1282
+ /** Voice settings — core agent config. Mirrors `VoiceConfig` in `@alfe/types`. */
1283
+ interface AgentVoiceConfig {
1284
+ /** ElevenLabs voice ID; platform default when unset. */
1285
+ voiceId?: string;
1286
+ ttsModel?: string;
1287
+ enabled?: boolean;
1288
+ }
1289
+ /**
1290
+ * The agent's own public identity, as returned by `updateSelf`, `generateAvatar`,
1291
+ * `presignAvatar`'s finalize (`finalizeAvatar`). This is the public agent
1292
+ * projection; only the identity-relevant fields are typed here — the response
1293
+ * carries the full public agent record.
1294
+ */
1295
+ interface AgentSelf {
1296
+ agentId: string;
1297
+ tenantId: string;
1298
+ name: string;
1299
+ avatarUrl?: string;
1300
+ voiceConfig?: AgentVoiceConfig;
1301
+ status: string;
1302
+ }
1303
+ /** Result of `presignAvatar` — the agent PUTs bytes to `uploadUrl`, then finalizes with `s3Key`. */
1304
+ interface AgentAvatarPresign {
1305
+ /** Presigned PUT URL to upload the image bytes to. */
1306
+ uploadUrl: string;
1307
+ /** Object key — echoed back to `finalizeAvatar`. */
1308
+ s3Key: string;
1309
+ /** Stable public URL the avatar will be served from once finalized. */
1310
+ publicUrl: string;
1311
+ /** ISO expiry of the presigned PUT URL. */
1312
+ expiresAt: string;
1313
+ }
1314
+ /** A voice in the platform catalogue (ElevenLabs), from `listVoices`. */
1315
+ interface AgentVoice {
1316
+ id: string;
1317
+ name: string;
1318
+ previewUrl: string;
1319
+ description: string;
1320
+ labels: Record<string, string>;
1321
+ category: string;
1322
+ }
1323
+ declare class SelfApi extends ApiBase {
1324
+ /** Update the agent's own name and/or voice config. Returns the updated agent. */
1325
+ updateSelf(update: {
1326
+ name?: string;
1327
+ voiceConfig?: AgentVoiceConfig;
1328
+ }): Promise<AgentSelf>;
1315
1329
  /**
1316
- * Pattern A: refresh one MYOB Connection by its stable
1317
- * `accountIdentifier` (the MYOB business id returned by
1318
- * `getMYOBAccounts()`).
1330
+ * Generate the agent's own avatar from a text prompt. The image is generated,
1331
+ * stored, and set on the agent server-side; returns the updated agent.
1319
1332
  *
1320
- * MYOB refresh tokens belong to individual Connection rows. A
1321
- * multi-business client must use this method instead of refreshing the
1322
- * primary Connection and copying that access token into every cached
1323
- * business client.
1333
+ * ASYNC (same reason as `generateImage`): avatar gen runs `gpt-image-1`
1334
+ * (30–60s) which exceeds the API Gateway 30s ceiling, so this enqueues a job
1335
+ * (`POST /agent/avatar/generate` `jobId`) then polls (`GET /agent/avatar/{jobId}`)
1336
+ * until the avatar is set. Signature unchanged — the plugin is unaffected.
1324
1337
  */
1325
- refreshMYOBAccountToken(accountIdentifier: string): Promise<{
1326
- accessToken: string;
1327
- accessTokenExpiresAt: string;
1328
- expiresAt: string;
1329
- }>;
1338
+ generateAvatar(args: {
1339
+ prompt: string;
1340
+ }): Promise<AgentSelf>;
1330
1341
  /**
1331
- * @deprecated Returns a single primary credential blob. Use
1332
- * `getSalesforceAccounts()` for the multi-account shape required by
1333
- * Pattern A.
1342
+ * Get a presigned PUT URL to upload a new avatar image. Upload the bytes to
1343
+ * `uploadUrl`, then call `finalizeAvatar(s3Key)` to set it on the agent.
1334
1344
  */
1335
- getSalesforceCredentials(): Promise<{
1336
- accessToken: string;
1337
- accessTokenExpiresAt: string;
1338
- instanceUrl: string;
1339
- orgId: string;
1340
- }>;
1345
+ presignAvatar(args: {
1346
+ mimeType: string;
1347
+ size: number;
1348
+ }): Promise<AgentAvatarPresign>;
1341
1349
  /**
1342
- * Pattern A: multi-account credential fetch for Salesforce. Returns every
1343
- * agent-scoped Salesforce connection. One OAuth grant maps to one org, so
1344
- * `accounts[i].accountIdentifier` (and `orgId`) is the Salesforce org id —
1345
- * the selector every credential-touching tool requires.
1350
+ * Finalize an avatar upload validates ownership + size, then sets the
1351
+ * agent's `avatarUrl` server-side. Returns the updated agent.
1346
1352
  */
1347
- getSalesforceAccounts(): Promise<{
1348
- accounts: {
1349
- connectionId: string;
1350
- accountIdentifier: string;
1351
- displayName: string | null;
1352
- connectedAt: string;
1353
- accessToken: string;
1354
- accessTokenExpiresAt: string;
1355
- instanceUrl: string;
1356
- orgId: string;
1357
- }[];
1353
+ finalizeAvatar(s3Key: string): Promise<AgentSelf>;
1354
+ /** List the platform voice catalogue (ElevenLabs) so the agent can pick its own voice. */
1355
+ listVoices(): Promise<{
1356
+ voices: AgentVoice[];
1358
1357
  }>;
1358
+ }
1359
+ //# sourceMappingURL=self.d.ts.map
1360
+ //#endregion
1361
+ //#region src/domains/voice.d.ts
1362
+ /** The ElevenLabs models with a pricing row — the TTS endpoint rejects any other value. */
1363
+ type VoiceTtsModel = "eleven_turbo_v2_5" | "eleven_multilingual_v2";
1364
+ interface VoiceTtsArgs {
1365
+ /** Text to synthesize (1–5000 chars — the endpoint enforces this). */
1366
+ text: string;
1367
+ /** ElevenLabs voice id; platform default when unset. */
1368
+ voiceId?: string;
1369
+ /** TTS model; `eleven_turbo_v2_5` (lower latency) when unset. */
1370
+ model?: VoiceTtsModel;
1371
+ }
1372
+ /** Raw synthesized audio plus its PCM framing (from the response headers). */
1373
+ interface VoiceTtsResult {
1374
+ /** Raw little-endian PCM samples — no container. Wrap in WAV to make a playable file. */
1375
+ audio: Buffer;
1376
+ /** Samples per second (e.g. 24000). */
1377
+ sampleRate: number;
1378
+ /** Channel count (mono = 1). */
1379
+ channels: number;
1380
+ /** Bits per sample (e.g. 16). */
1381
+ bitDepth: number;
1382
+ }
1383
+ interface VoiceSttArgs {
1384
+ /** Raw linear16 (16-bit little-endian) mono PCM samples — no WAV/container header. */
1385
+ audio: Uint8Array;
1386
+ /** Sample rate of `audio` in Hz (8000–48000). */
1387
+ sampleRate: number;
1388
+ }
1389
+ interface VoiceSttResult {
1390
+ text: string;
1391
+ /** Deepgram confidence in (0,1]. */
1392
+ confidence: number;
1393
+ }
1394
+ declare class VoiceApi extends ApiBase {
1359
1395
  /**
1360
- * Refresh the access token for a specific Salesforce org. Salesforce
1361
- * tokens aren't interchangeable across orgs, so the connection is targeted
1362
- * by `accountIdentifier` (the org id) mirrors `refreshXeroAccountToken`.
1396
+ * Text-to-speech. Returns raw PCM audio bytes plus their framing — the
1397
+ * voice service defaults to 24 kHz / mono / 16-bit. Wrap in a WAV container
1398
+ * to produce a playable file. Metered per character against the tenant
1399
+ * credit pool server-side; TTS completes regardless of metering outcome.
1363
1400
  */
1364
- refreshSalesforceAccountToken(orgId: string): Promise<{
1365
- accessToken: string;
1366
- accessTokenExpiresAt: string;
1367
- expiresAt: string;
1368
- }>;
1401
+ tts(args: VoiceTtsArgs): Promise<VoiceTtsResult>;
1369
1402
  /**
1370
- * Pattern A: multi-account credential fetch for Microsoft 365.
1371
- *
1372
- * Returns every agent-scoped Microsoft connection. The caller is expected
1373
- * to require an `email` selector on every credential-touching tool and
1374
- * look up the matching account at dispatch time.
1375
- *
1376
- * Returned `accounts[i].accountIdentifier` is the user's primary email
1377
- * (or the tid claim as fallback) — the stable cross-session identifier
1378
- * the LLM should pass.
1379
- *
1380
- * Per-account token refresh is exposed via `refreshMicrosoftAccountToken`,
1381
- * NOT `refreshXeroAccountToken` — Microsoft refresh tokens are not
1382
- * interchangeable across (tenant, user) pairs.
1403
+ * Speech-to-text. Accepts raw linear16 (16-bit LE) mono PCM NOT a WAV or
1404
+ * other container (the endpoint transcribes with a fixed linear16 encoding,
1405
+ * so a container header would be transcribed as noise). Strip any WAV header
1406
+ * and pass `sampleRate` from it before calling. Metered by transcribed
1407
+ * duration against the tenant credit pool server-side.
1383
1408
  */
1384
- getMicrosoftAccounts(): Promise<{
1385
- accounts: {
1386
- connectionId: string;
1387
- accountIdentifier: string;
1388
- displayName: string | null;
1389
- connectedAt: string;
1390
- accessToken: string;
1391
- accessTokenExpiresAt: string;
1392
- email: string;
1393
- microsoftTenantId: string;
1394
- workspaceDomain: string;
1395
- }[];
1396
- }>;
1409
+ stt(args: VoiceSttArgs): Promise<VoiceSttResult>;
1410
+ }
1411
+ //# sourceMappingURL=voice.d.ts.map
1412
+ //#endregion
1413
+ //#region src/domains/identity.d.ts
1414
+ type IdentityStatus = "anonymous" | "partial" | "identified" | "verified";
1415
+ interface IdentityDirectoryEntry {
1416
+ identityId: string;
1417
+ status: IdentityStatus;
1418
+ displayName: string;
1419
+ name?: string;
1420
+ avatarUrl?: string;
1421
+ lastSeenAt: string;
1422
+ lastSeenProvider?: string;
1423
+ messageable: boolean;
1424
+ }
1425
+ declare class IdentityApi extends ApiBase {
1397
1426
  /**
1398
- * Pattern A: refresh a specific Microsoft 365 connection by its
1399
- * `accountIdentifier`. For Microsoft, `accountIdentifier` is the user's
1400
- * email when the Graph profile fetch succeeded at connect time, and the
1401
- * Azure tenant id (`tid` claim) as fallback. Callers should pass the
1402
- * value returned by `getMicrosoftAccounts()` rather than synthesising
1403
- * an email locally.
1404
- *
1405
- * Microsoft refresh tokens are bound to a specific (tenant, user) pair —
1406
- * they are NOT interchangeable across accounts, so per-account refresh
1407
- * is mandatory. The generic /accounts/{accountIdentifier}/refresh
1408
- * endpoint walks the agent's full visible scope chain to find a matching
1409
- * connection (works for inherited team/project Microsoft connections).
1427
+ * Returns the calling agent's own identity context `{ agentId, tenantId }`
1428
+ * decoded server-side from the agent API token. Used by the
1429
+ * `@alfe.ai/openclaw-identity` plugin to bootstrap context when the
1430
+ * OpenClaw daemon doesn't plumb `ctx.agentId` through to plugin hooks.
1431
+ * Plugins should cache this for the daemon's lifetime (single-agent-per-
1432
+ * process invariant). One HTTP round-trip per process activate; not for
1433
+ * per-call use.
1410
1434
  */
1411
- refreshMicrosoftAccountToken(accountIdentifier: string): Promise<{
1412
- accessToken: string;
1413
- accessTokenExpiresAt: string;
1414
- expiresAt: string;
1435
+ whoami(): Promise<{
1436
+ agentId: string;
1437
+ tenantId: string;
1415
1438
  }>;
1416
- /**
1417
- * Disconnects one connected Microsoft 365 account for the agent, by its
1418
- * `accountIdentifier`. Hits the generic per-account disconnect route
1419
- * (`DELETE /agent/connect/microsoft/accounts/{accountIdentifier}`), which
1420
- * resolves across the agent's full effective scope chain and deletes the
1421
- * matching Connection row. Returns the remaining accounts.
1422
- *
1423
- * IMPORTANT: pass the `accountIdentifier` from `getMicrosoftAccounts()`, NOT
1424
- * a synthesised email. For Microsoft, `accountIdentifier` is the user's email
1425
- * only when the Graph profile fetch succeeded at connect time; it falls back
1426
- * to the Azure tenant id (`tid` claim) otherwise. The backend matches on
1427
- * `accountIdentifier` exactly, so passing an email would 404 on those
1428
- * fallback-identifier accounts. (This is why the param is not named `email`,
1429
- * unlike `disconnectGoogleAccount` where the identifier is always the email.)
1430
- */
1431
- disconnectMicrosoftAccount(accountIdentifier: string): Promise<{
1432
- accounts: {
1433
- accountIdentifier: string;
1434
- displayName?: string;
1435
- connectedAt?: string;
1436
- }[];
1439
+ resolveIdentity(args: {
1440
+ provider: string;
1441
+ platformId: string;
1442
+ kind?: "user" | "agent" | "service" | "bot" | "workspace";
1443
+ displayName?: string;
1444
+ }): Promise<{
1445
+ identityId: string | null;
1446
+ status: string;
1447
+ created?: boolean;
1448
+ reason?: string;
1449
+ /**
1450
+ * Flattened auriclabs permission strings for the resolved identity
1451
+ * (scope-prefixed where applicable). Empty array on miss / org service
1452
+ * outage the runtime gate fails closed in that case.
1453
+ */
1454
+ permissions: string[];
1437
1455
  }>;
1438
- /**
1439
- * Resolve the primary cTrader Connection's credentials for the calling
1440
- * agent. Unlike most providers, the cTrader Open API needs app-level auth
1441
- * (`clientId` + `clientSecret`) AND account auth (`accessToken` +
1442
- * `accountId`) on the socket, so `@alfe.ai/ctrader-mcp` self-fetches the
1443
- * full set here at startup (the atlassian/google pattern). `clientId` /
1444
- * `clientSecret` are the SST-sourced global app credentials the connect
1445
- * endpoint injects — they are never persisted on the connection. `host` is
1446
- * the resolved TLS endpoint (`live.ctraderapi.com` / `demo.ctraderapi.com`)
1447
- * derived from the selected account's live/demo flag.
1448
- */
1449
- getCTraderCredentials(): Promise<{
1450
- accessToken: string;
1451
- refreshToken: string;
1452
- accountId: string;
1453
- host: string;
1454
- clientId: string;
1455
- clientSecret: string;
1456
+ searchIdentities(args?: {
1457
+ q?: string;
1458
+ status?: string;
1459
+ limit?: number;
1460
+ }): Promise<{
1461
+ identities: unknown[];
1456
1462
  }>;
1457
- /**
1458
- * Pattern A: multi-account credential fetch for cTrader.
1459
- *
1460
- * Unlike atlassian/salesforce (one Connection row per account/site), a
1461
- * cTrader is MULTI-grant per agent: an agent may connect several distinct
1462
- * cTrader logins, each its own Connection row keyed on `accountIdentifier =
1463
- * ctid:<userId>` (Phase 1). This aggregates the *trading accounts* across
1464
- * ALL of those Connection rows — each row contributes its `availableAccounts`
1465
- * flattened, and every account carries ITS OWN grant's `accessToken` (the
1466
- * token that authenticates that account against the cTrader Open API). One
1467
- * OAuth grant still covers all accounts under that single login on one shared
1468
- * token; only the `ctidTraderAccountId` and the protobuf socket `host` (live
1469
- * vs demo) differ within a grant. Across grants the tokens differ, so the
1470
- * token is now PER-ACCOUNT rather than hoisted to the top level.
1471
- *
1472
- * `host` per account is derived from the account's `isLive` flag
1473
- * (`live.ctraderapi.com` / `demo.ctraderapi.com`) — the same mapping the
1474
- * connect provider applies server-side when an account is auto-selected.
1475
- *
1476
- * `clientId` / `clientSecret` are the SST-sourced GLOBAL app credentials the
1477
- * connect endpoint injects — identical across every Connection row (one
1478
- * cTrader app), never persisted on a connection. We take them from the first
1479
- * row that carries them.
1480
- *
1481
- * Accounts are deduped on `ctidTraderAccountId` first-wins: Spotware ids are
1482
- * globally unique across logins, so a duplicate can only appear if the same
1483
- * account somehow surfaced under two grants — first-wins keeps it
1484
- * deterministic.
1485
- *
1486
- * `accounts` may be empty (no cTrader Connection at all), in which case we
1487
- * return empty creds rather than throwing.
1488
- */
1489
- getCTraderAccounts(): Promise<{
1490
- accounts: {
1491
- ctidTraderAccountId: string;
1492
- host: string;
1493
- isLive: boolean;
1494
- brokerName?: string;
1495
- accountNumber?: string;
1496
- accessToken: string;
1497
- /**
1498
- * The stable per-grant Connection key (`ctid:<userId>`) this account
1499
- * belongs to. Every trading account under one cTrader login shares one
1500
- * grant (one OAuth token), so this is the identifier the MCP server
1501
- * passes to `refreshCTraderAccount()` to rotate the token for the whole
1502
- * grant on a `CH_ACCESS_TOKEN_INVALID` expiry. Empty string when the
1503
- * server did not supply one (legacy rows) — such an account can still
1504
- * trade with its current token but cannot self-refresh.
1505
- */
1506
- accountIdentifier: string;
1507
- }[];
1508
- clientId: string;
1509
- clientSecret: string;
1463
+ listIdentities(args?: {
1464
+ status?: IdentityStatus;
1465
+ limit?: number;
1466
+ cursor?: string;
1467
+ }): Promise<{
1468
+ identities: IdentityDirectoryEntry[];
1469
+ cursor: string | null;
1510
1470
  }>;
1511
- /**
1512
- * Pattern A: refresh a specific cTrader grant by its stable
1513
- * `accountIdentifier` (`ctid:<userId>` from `getCTraderAccounts()`).
1514
- *
1515
- * cTrader access tokens live ~30 days; the `getCTraderAccounts()` /
1516
- * credentials reads serve the STORED token without refreshing, so refresh is
1517
- * the consumer's job. `@alfe.ai/ctrader-mcp` calls this when the cTrader Open
1518
- * API rejects an account-auth with `CH_ACCESS_TOKEN_INVALID`, then re-runs
1519
- * the socket handshake with the returned `accessToken`.
1520
- *
1521
- * Refreshing one grant rotates the single OAuth token that covers EVERY
1522
- * trading account under that login. cTrader's refresh token itself does not
1523
- * expire but may rotate on refresh (`rotatesRefreshToken: true`); connect
1524
- * persists the rotated refresh token server-side, so the caller only needs
1525
- * the new `accessToken`. Mirrors `refreshXeroAccountToken`.
1526
- */
1527
- refreshCTraderAccount(accountIdentifier: string): Promise<{
1528
- accessToken: string;
1529
- accessTokenExpiresAt: string;
1530
- expiresAt: string;
1471
+ getIdentityContext(identityId: string): Promise<{
1472
+ context: unknown;
1531
1473
  }>;
1532
- /**
1533
- * @deprecated Returns a single primary credential blob. Use
1534
- * `getShopifyAccounts()` for the multi-account shape required by Pattern A
1535
- * (`@alfe.ai/shopify-mcp` keys per-shop on the myshopify domain).
1536
- */
1537
- getShopifyCredentials(): Promise<{
1538
- accessToken: string;
1539
- shopDomain: string;
1540
- shopGid: string;
1541
- shopName: string;
1542
- apiVersion: string;
1474
+ mergeIdentities(survivorId: string, args: {
1475
+ mergedId: string;
1476
+ }): Promise<{
1477
+ ok: boolean;
1478
+ error?: string;
1543
1479
  }>;
1544
- /**
1545
- * Pattern A: multi-account credential fetch for Shopify. Returns every
1546
- * agent-scoped Shopify Connection. One OAuth grant maps to one store, so the
1547
- * stable per-call selector is the store's myshopify domain (`shopDomain`),
1548
- * NOT `accountIdentifier` — the connect provider keys `accountIdentifier` on
1549
- * the immutable shop GID (falling back to the domain), so `shopDomain` is the
1550
- * value the LLM passes and the plugin routes on.
1551
- *
1552
- * Each entry is shaped by the connect provider's `buildCredentialsResponse`:
1553
- * `{ accessToken, shopDomain, shopGid, shopName, apiVersion }` — offline
1554
- * Shopify tokens never expire, so there is NO token / expiry field and no
1555
- * refresh method (unlike Salesforce). The GraphQL Admin API authenticates
1556
- * purely on `X-Shopify-Access-Token`; no client credentials are on the wire.
1557
- */
1558
- getShopifyAccounts(): Promise<{
1559
- accounts: {
1560
- connectionId: string;
1561
- accountIdentifier: string;
1562
- displayName: string | null;
1563
- connectedAt: string;
1564
- accessToken: string;
1565
- shopDomain: string;
1566
- shopGid: string;
1567
- shopName: string;
1568
- apiVersion: string;
1480
+ unmergeIdentity(identityId: string): Promise<{
1481
+ ok: boolean;
1482
+ error?: string;
1483
+ }>;
1484
+ addIdentityNote(identityId: string, args: {
1485
+ content: string;
1486
+ category?: string;
1487
+ }): Promise<{
1488
+ noteId: string | null;
1489
+ }>;
1490
+ tagIdentity(identityId: string, args: {
1491
+ tag: string;
1492
+ action: "add" | "remove";
1493
+ }): Promise<{
1494
+ ok: boolean;
1495
+ }>;
1496
+ getIdentityChangelog(identityId: string, args?: {
1497
+ limit?: number;
1498
+ cursor?: string;
1499
+ }): Promise<{
1500
+ entries: unknown[];
1501
+ cursor: string | null;
1502
+ }>;
1503
+ rollbackIdentity(identityId: string, args: {
1504
+ targetVersion: number;
1505
+ }): Promise<{
1506
+ ok: boolean;
1507
+ entry?: unknown;
1508
+ }>;
1509
+ requestIdentityVerification(args: {
1510
+ claimedIdentityId: string;
1511
+ requestingIdentityId: string;
1512
+ requestingProvider: string;
1513
+ requestingPlatformId: string;
1514
+ preferredChannel?: "mobile" | "email";
1515
+ /**
1516
+ * Phase 2: agent-supplied contact endpoint. When provided, the top-level
1517
+ * `preferredChannel` is ignored — the contact's channel wins.
1518
+ */
1519
+ contact?: {
1520
+ channel: "email" | "mobile";
1521
+ value: string;
1522
+ };
1523
+ }): Promise<{
1524
+ verificationId: string;
1525
+ channel: string;
1526
+ deliveredTo: string;
1527
+ expiresAt: string;
1528
+ availableChannels: {
1529
+ channel: string;
1530
+ deliveredTo: string;
1569
1531
  }[];
1532
+ } | {
1533
+ error: string;
1534
+ }>;
1535
+ confirmIdentityVerification(args: {
1536
+ claimedIdentityId: string;
1537
+ verificationId: string;
1538
+ phrase: string;
1539
+ }): Promise<{
1540
+ verified: boolean;
1541
+ identityId?: string;
1542
+ /** Phase 2: how the confirm resolved — Scenario A vs B. */
1543
+ action?: "merged" | "contact_verified" | "already_confirmed";
1544
+ error?: string;
1570
1545
  }>;
1571
1546
  /**
1572
- * Pattern A: provider-parameterized multi-account credential fetch for the
1573
- * social connectors (Bluesky, and the approval-gated backlog: X, Meta,
1574
- * Threads, LinkedIn, Pinterest, TikTok, Reddit, YouTube).
1575
- *
1576
- * Unlike the bespoke `getGithubAccounts()` / `getXeroAccounts()` shapes,
1577
- * this returns a UNIFORM normalized account shape so `@alfe.ai/social-mcp`'s
1578
- * shared driver can require a single `account` selector on every
1579
- * credential-touching tool regardless of platform. The backend
1580
- * `api-agents/{provider}/accounts` route is already provider-generic; this
1581
- * is the client-side normalization the plan (`do-we-need-any-moonlit-toucan`
1582
- * Phase 0, step 5) calls for.
1583
- *
1584
- * `accountIdentifier` is the stable per-account selector the LLM should
1585
- * pass back (for Bluesky: the account DID). `accessToken` carries whatever
1586
- * the provider's `buildCredentialsResponse` bundles (for Bluesky: the JSON
1587
- * session bundle — the driver parses the `accessJwt` out of it, or reads the
1588
- * top-level `accessJwt` from `providerMetadata`-adjacent fields). Everything
1589
- * else the driver needs for routing (handle, pdsHost, did, …) is on
1590
- * `providerMetadata`.
1591
- *
1592
- * Token refresh is delegated to connect (never done in-plugin) via the
1593
- * per-account route `POST /agent/connect/{provider}/accounts/{accountIdentifier}/refresh`
1594
- * — call `refreshSocialAccount(provider, accountIdentifier)`. (The non-account
1595
- * `POST /agent/connect/{provider}/refresh` route refreshes the provider's
1596
- * PRIMARY connection, which is wrong under multi-account Pattern A.)
1547
+ * Update display-shape fields on an Identity. Body excludes `email` /
1548
+ * `phone` / `title` / `company` / `metadata` per Section D4 — contacts go
1549
+ * via the verify flow, title/company live on OrgMembership, metadata is
1550
+ * not agent-writable.
1597
1551
  */
1598
- getSocialAccounts(provider: string): Promise<{
1599
- provider: string;
1600
- accounts: {
1601
- connectionId: string;
1602
- accountIdentifier: string;
1603
- displayName: string | null;
1604
- accessToken: string;
1605
- providerMetadata: Record<string, unknown>;
1606
- connectedAt: string;
1607
- }[];
1552
+ updateIdentity(identityId: string, args: {
1553
+ name?: string;
1554
+ avatarUrl?: string;
1555
+ timezone?: string;
1556
+ locale?: string;
1557
+ }): Promise<{
1558
+ ok: boolean;
1608
1559
  }>;
1609
1560
  /**
1610
- * Pattern A: refresh a specific social Connection by its stable
1611
- * `accountIdentifier` (for Bluesky: the account DID) via the
1612
- * provider-generic per-account refresh route. The counterpart to
1613
- * `getSocialAccounts(provider)`; `@alfe.ai/social-mcp` calls this on a
1614
- * 401/ExpiredToken from the platform PDS/API, then re-fetches accounts to
1615
- * pick up the rotated bundle.
1616
- *
1617
- * Refresh itself is ALWAYS delegated to connect — the plugin never calls
1618
- * the platform's own refresh XRPC (e.g. `com.atproto.server.refreshSession`)
1619
- * because connect owns the encrypted refresh token + rotation persistence
1620
- * (Bluesky rotates the refreshJwt; a missed rotation kills the connection
1621
- * after one refresh). The returned `accessToken` is whatever the provider's
1622
- * `refreshToken` hook re-bundled (for Bluesky: the JSON session bundle with
1623
- * the fresh `accessJwt`) — callers typically ignore it and re-fetch via
1624
- * `getSocialAccounts` for a consistent shape.
1561
+ * Phase 2 (Section H): server-side verification of a Google Chat sender via
1562
+ * the agent's existing Google OAuth credentials. Returns the resolved
1563
+ * identity (created or matched via Scenario-B email enrichment).
1625
1564
  */
1626
- refreshSocialAccount(provider: string, accountIdentifier: string): Promise<{
1627
- accountIdentifier: string;
1628
- accessToken: string;
1629
- accessTokenExpiresAt: string;
1630
- expiresAt: string;
1565
+ resolveGoogleChatSender(args: {
1566
+ senderUserId: string;
1567
+ spaceId?: string;
1568
+ }): Promise<{
1569
+ identityId: string | null;
1570
+ status: string;
1631
1571
  }>;
1632
1572
  }
1633
- //# sourceMappingURL=connect-credentials.d.ts.map
1573
+ //# sourceMappingURL=identity.d.ts.map
1574
+ //#endregion
1575
+ //#region src/domains/search.d.ts
1576
+ /**
1577
+ * The broad-news providers behind the metered `services/news` Lambda. The
1578
+ * server validates this with a zod enum; a value outside the union is an
1579
+ * unpriceable product, so keep the literal union in lockstep with the service.
1580
+ */
1581
+ type NewsProvider = "apitube" | "newsdata";
1582
+ /** One normalized article. `sentiment` is provider-shaped (APITube supplies it). */
1583
+ interface NewsArticle {
1584
+ title: string;
1585
+ url: string;
1586
+ source: string;
1587
+ publishedAt: string;
1588
+ snippet: string;
1589
+ sentiment?: unknown;
1590
+ }
1591
+ /** Provider-agnostic result — the server normalizes every adapter to this. */
1592
+ interface NewsResult {
1593
+ articles: NewsArticle[];
1594
+ provider: string;
1595
+ }
1596
+ declare class SearchApi extends ApiBase {
1597
+ searchWeb(params: {
1598
+ query: string;
1599
+ count?: number;
1600
+ offset?: number;
1601
+ country?: string;
1602
+ freshness?: string;
1603
+ }, options?: {
1604
+ signal?: AbortSignal;
1605
+ }): Promise<unknown>;
1606
+ searchImages(params: {
1607
+ query: string;
1608
+ count?: number;
1609
+ }, options?: {
1610
+ signal?: AbortSignal;
1611
+ }): Promise<unknown>;
1612
+ searchNews(params: {
1613
+ query: string;
1614
+ count?: number;
1615
+ offset?: number;
1616
+ freshness?: string;
1617
+ }, options?: {
1618
+ signal?: AbortSignal;
1619
+ }): Promise<unknown>;
1620
+ /** Search news across the selected provider's corpus. → POST /agent/news/search */
1621
+ newsSearch(params: {
1622
+ query: string;
1623
+ provider?: NewsProvider;
1624
+ source?: string;
1625
+ from?: string;
1626
+ to?: string;
1627
+ language?: string;
1628
+ category?: string;
1629
+ limit?: number;
1630
+ }): Promise<NewsResult>;
1631
+ /** Top headlines for the selected provider. → POST /agent/news/headlines */
1632
+ newsHeadlines(params?: {
1633
+ provider?: NewsProvider;
1634
+ category?: string;
1635
+ source?: string;
1636
+ language?: string;
1637
+ limit?: number;
1638
+ }): Promise<NewsResult>;
1639
+ }
1640
+ //# sourceMappingURL=search.d.ts.map
1641
+ //#endregion
1642
+ //#region src/domains/webhooks.d.ts
1643
+ interface AgentWebhook {
1644
+ webhookId: string;
1645
+ tenantId: string;
1646
+ agentId: string;
1647
+ name: string;
1648
+ provider: string;
1649
+ active: boolean;
1650
+ createdBy: string;
1651
+ createdAt: string;
1652
+ updatedAt: string;
1653
+ }
1654
+ interface CreatedAgentWebhook extends AgentWebhook {
1655
+ url: string;
1656
+ signingSecret: string;
1657
+ }
1658
+ interface AgentWebhookDelivery {
1659
+ deliveryId: string;
1660
+ webhookId: string;
1661
+ status: string;
1662
+ attempts: number;
1663
+ createdAt: string;
1664
+ deliveredAt?: string;
1665
+ }
1666
+ declare class WebhooksApi extends ApiBase {
1667
+ createWebhook(args: {
1668
+ name: string;
1669
+ provider?: "generic" | "github" | "stripe" | "slack";
1670
+ }): Promise<CreatedAgentWebhook>;
1671
+ listWebhooks(): Promise<AgentWebhook[]>;
1672
+ deleteWebhook(webhookId: string): Promise<{
1673
+ webhookId: string;
1674
+ active: false;
1675
+ }>;
1676
+ rotateWebhookSecret(webhookId: string): Promise<{
1677
+ webhookId: string;
1678
+ signingSecret: string;
1679
+ }>;
1680
+ listWebhookDeliveries(webhookId: string): Promise<AgentWebhookDelivery[]>;
1681
+ }
1682
+ //# sourceMappingURL=webhooks.d.ts.map
1683
+ //#endregion
1684
+ //#region src/domains/chat.d.ts
1685
+ declare class ChatApi extends ApiBase {
1686
+ ensureDirectConversation(identityId: string): Promise<{
1687
+ conversationId: string;
1688
+ identityId: string;
1689
+ tenantId: string;
1690
+ userId: string;
1691
+ displayName: string;
1692
+ created: boolean;
1693
+ }>;
1694
+ presignAttachments(files: {
1695
+ filename: string;
1696
+ mimeType: string;
1697
+ size: number;
1698
+ }[]): Promise<{
1699
+ attachments: {
1700
+ id: string;
1701
+ uploadUrl: string;
1702
+ uploadHeaders: Record<string, string>;
1703
+ downloadUrl: string;
1704
+ s3Key: string;
1705
+ expiresAt: string;
1706
+ }[];
1707
+ }>;
1708
+ recordActivity(data: {
1709
+ userId?: string;
1710
+ channel: string;
1711
+ role: "user" | "assistant";
1712
+ }): Promise<{
1713
+ recorded: boolean;
1714
+ }>;
1715
+ }
1716
+ //# sourceMappingURL=chat.d.ts.map
1634
1717
  //#endregion
1635
1718
  //#region src/domains/database.d.ts
1636
1719
  declare class DatabaseApi extends ApiBase {
@@ -1674,34 +1757,6 @@ declare class ImagesApi extends ApiBase {
1674
1757
  }
1675
1758
  //# sourceMappingURL=images.d.ts.map
1676
1759
  //#endregion
1677
- //#region src/domains/integrations.d.ts
1678
- declare class IntegrationsApi extends ApiBase {
1679
- listIntegrations(): Promise<IntegrationInstall$1[]>;
1680
- getIntegrationConfig(integrationId: string): Promise<IntegrationConfigResult$1>;
1681
- updateIntegrationConfig(integrationId: string, config: Record<string, unknown>): Promise<void>;
1682
- installIntegration(integrationId: string, options?: {
1683
- version?: string;
1684
- config?: Record<string, unknown>;
1685
- }): Promise<IntegrationInstall$1>;
1686
- removeIntegration(integrationId: string): Promise<IntegrationInstall$1>;
1687
- getOAuthUrl(provider: string, scopes?: string[], options?: {
1688
- shop?: string;
1689
- }): Promise<{
1690
- url: string;
1691
- provider: string;
1692
- expiresIn: number;
1693
- }>;
1694
- getOAuthStatus(provider: string): Promise<{
1695
- provider: string;
1696
- connected: boolean;
1697
- config?: Record<string, string>;
1698
- }>;
1699
- getRegistry(): Promise<{
1700
- integrations: RegistryEntry$1[];
1701
- }>;
1702
- }
1703
- //# sourceMappingURL=integrations.d.ts.map
1704
- //#endregion
1705
1760
  //#region src/domains/memory.d.ts
1706
1761
  declare class MemoryApi extends ApiBase {
1707
1762
  memorySearch(query: string, opts?: {
@@ -2004,5 +2059,5 @@ declare class AgentApiClient extends ApiBase {
2004
2059
  //# sourceMappingURL=index.d.ts.map
2005
2060
 
2006
2061
  //#endregion
2007
- export { AgentApiClient, type AgentApiClientConfig, type AgentAvatarPresign, type AgentSelf, type AgentVoice, type AgentVoiceConfig, type AgentWebhook, type AgentWebhookDelivery, type AgentWorkspaceInfo, type ChangeRequestActorKind, type ChangeRequestOperation, type ChangeRequestResourceType, type ChangeRequestStatus, type ChangelogAction, type ChangelogActor, type ChangelogEntry, type CreatedAgentWebhook, type EncryptedEnvelopeV1, type Field, type FieldEnvelope, type FieldFormat, type FieldSensitivity, type FieldView, type GeneratedDataKey, type IdentityDirectoryEntry, type IdentityStatus, type InstallToolErrorCaptureOptions, type IntegrationConfigResult, type IntegrationConfigSchemaField, type IntegrationInstall, type KnowledgeChangeRequest, type KnowledgeDoc, type KnowledgeProfile, type KnowledgeProfileLink, type KnowledgeScope, type KnowledgeScopeType, type KnowledgeSearchHit, type KnowledgeSearchResult, type MobileAvailableNumber, type MobileNumberInfo, type NewsArticle, type NewsProvider, type NewsResult, type ProposeScopeChangeInput, type RegistryEntry, type RemoteSessionInfo, type ScopeInfo, type SecretAggregate, type SecretCategory, type SecretMetadata, type SecretScope, type SharedFileEntry, type SyncAgentInfo, type SyncAgentStats, type SyncConfirmedUpload, type SyncFileEntry, type SyncManifest, type SyncManifestEntry, type SyncPresignedUrl, type SyncReconstructBundle, type SyncReconstructFile, type SyncSessionContent, type SyncSessionEntry, type ToolCaptureApi, type VoiceSttArgs, type VoiceSttResult, type VoiceTtsArgs, type VoiceTtsModel, type VoiceTtsResult, type WhatsAppTemplate, installToolErrorCapture };
2062
+ export { AgentApiClient, type AgentApiClientConfig, type AgentAvatarPresign, type AgentIntegrationListEntry, type AgentSelf, type AgentVoice, type AgentVoiceConfig, type AgentWebhook, type AgentWebhookDelivery, type AgentWorkspaceInfo, type ChangeRequestActorKind, type ChangeRequestOperation, type ChangeRequestResourceType, type ChangeRequestStatus, type ChangelogAction, type ChangelogActor, type ChangelogEntry, type ConnectProviderAccount, type ConnectProviderAccounts, type CreatedAgentWebhook, type EncryptedEnvelopeV1, type Field, type FieldEnvelope, type FieldFormat, type FieldSensitivity, type FieldView, type GeneratedDataKey, type IdentityDirectoryEntry, type IdentityStatus, type InstallToolErrorCaptureOptions, type IntegrationActivationSource, type IntegrationConfigResult, type IntegrationConfigSchemaField, type IntegrationInstall, type KnowledgeChangeRequest, type KnowledgeDoc, type KnowledgeProfile, type KnowledgeProfileLink, type KnowledgeScope, type KnowledgeScopeType, type KnowledgeSearchHit, type KnowledgeSearchResult, type MobileAvailableNumber, type MobileNumberInfo, type NewsArticle, type NewsProvider, type NewsResult, type ProposeScopeChangeInput, type RegistryEntry, type RemoteSessionInfo, type ScopeInfo, type SecretAggregate, type SecretCategory, type SecretMetadata, type SecretScope, type SharedFileEntry, type SyncAgentInfo, type SyncAgentStats, type SyncConfirmedUpload, type SyncFileEntry, type SyncManifest, type SyncManifestEntry, type SyncPresignedUrl, type SyncReconstructBundle, type SyncReconstructFile, type SyncSessionContent, type SyncSessionEntry, type ToolCaptureApi, type VoiceSttArgs, type VoiceSttResult, type VoiceTtsArgs, type VoiceTtsModel, type VoiceTtsResult, type WhatsAppTemplate, installToolErrorCapture };
2008
2063
  //# sourceMappingURL=index.d.cts.map