@alfe.ai/openclaw-sync 0.3.5 → 0.3.7

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
@@ -118,40 +118,117 @@ declare function filterIgnored(paths: string[], rules: IgnoreRules | string[]):
118
118
 
119
119
  //# sourceMappingURL=tool-error-capture.d.ts.map
120
120
  //#endregion
121
- //#region src/index.d.ts
121
+ //#region src/transport.d.ts
122
+ /**
123
+ * Shared HTTP transport for the Agent API client — request core, retry
124
+ * policy, error formatting, and the `ApiBase` class the domain method
125
+ * groups under `./domains/` build on.
126
+ */
122
127
  interface AgentApiClientConfig {
123
128
  apiKey: string;
124
129
  apiUrl: string;
125
130
  }
126
131
  /**
127
- * The broad-news providers behind the metered `services/news` Lambda. The
128
- * server validates this with a zod enum; a value outside the union is an
129
- * unpriceable product, so keep the literal union in lockstep with the service.
132
+ * Encode each path segment but keep the `/` separators — `encodeURIComponent`
133
+ * would escape the slashes too, breaking greedy proxy routes.
130
134
  */
131
- type NewsProvider = "apitube" | "newsdata";
132
- /** One normalized article. `sentiment` is provider-shaped (APITube supplies it). */
133
- interface NewsArticle {
134
- title: string;
135
- url: string;
136
- source: string;
137
- publishedAt: string;
138
- snippet: string;
139
- sentiment?: unknown;
135
+
136
+ declare class AgentApiTransport {
137
+ private readonly apiKey;
138
+ private readonly apiUrl;
139
+ constructor(config: AgentApiClientConfig);
140
+ /**
141
+ * Binary sibling of `request<T>()`. `request()` forces
142
+ * `Content-Type: application/json` and parses a `{ data: T }` envelope,
143
+ * neither of which fits a raw-audio flow (voice TTS/STT), so those go
144
+ * through this instead. Auth (Bearer), the request budget, and the single
145
+ * retry policy on transient 5xx / network errors is kept in sync with
146
+ * `request()`. Safe read methods retry once by default; mutation methods do
147
+ * not, because a response can be lost after a handler or provider call has
148
+ * already succeeded.
149
+ */
150
+ rawRequest(path: string, init: {
151
+ method: string;
152
+ headers: Headers;
153
+ body?: BodyInit | Uint8Array;
154
+ }, extra?: {
155
+ retry?: boolean;
156
+ }): Promise<Response>;
157
+ /**
158
+ * @param extra.timeoutMs Per-request abort timeout (default REQUEST_TIMEOUT_MS).
159
+ * Long endpoints (image generation) pass a larger value so the gateway's
160
+ * own timeout wins with a readable status instead of a client-side abort.
161
+ * @param extra.retry Whether to retry once on transient failures. Safe reads
162
+ * (GET/HEAD/OPTIONS) default to true; mutations default to false. Set true
163
+ * only when the endpoint's server-side contract is explicitly idempotent.
164
+ * @param extra.signal Optional caller cancellation combined with the client's
165
+ * own timeout budget. Aborting either signal cancels the request.
166
+ */
167
+ request<T>(path: string, options?: RequestInit, extra?: {
168
+ timeoutMs?: number;
169
+ retry?: boolean;
170
+ signal?: AbortSignal;
171
+ }): Promise<T>;
140
172
  }
141
- /** Provider-agnostic result — the server normalizes every adapter to this. */
142
- interface NewsResult {
143
- articles: NewsArticle[];
144
- provider: string;
173
+ /**
174
+ * Base class for the domain method groups. Holds the shared transport;
175
+ * `AgentApiClient` assembles the groups onto one class via `applyMixins`
176
+ * (prototype copy), so methods keep their original `this`-on-the-client
177
+ * call shape.
178
+ */
179
+ declare class ApiBase {
180
+ protected readonly transport: AgentApiTransport;
181
+ constructor(transport: AgentApiTransport);
145
182
  }
146
- interface RemoteSessionInfo {
147
- sessionId: string;
148
- agentId: string;
149
- surface: "browser" | "terminal";
150
- status: "agent_driving" | "awaiting_human" | "human_in_control" | "resuming" | "completed" | "expired" | "failed";
151
- url?: string;
152
- instructions?: string;
153
- requestedAt?: string;
183
+ //# sourceMappingURL=transport.d.ts.map
184
+ //#endregion
185
+ //#region src/domains/workspace.d.ts
186
+ /** Response of GET /agent/workspace (services/agents). */
187
+ interface AgentWorkspaceInfo {
188
+ templateKey?: string;
189
+ defaultModel?: string;
190
+ installedFrom?: {
191
+ templateKey: string;
192
+ authorTenantId: string;
193
+ version: number;
194
+ };
195
+ runtime?: string;
196
+ teams?: {
197
+ teamId: string;
198
+ name: string;
199
+ description?: string;
200
+ parentTeamId?: string;
201
+ }[];
202
+ projects?: {
203
+ projectId: string;
204
+ name: string;
205
+ description?: string;
206
+ status: string;
207
+ parentProjectId?: string;
208
+ }[];
209
+ teamIds?: string[];
210
+ projectIds?: string[];
211
+ }
212
+ declare class WorkspaceApi extends ApiBase {
213
+ /**
214
+ * GET /agent/workspace — workspace config for the authenticated agent
215
+ * (template assignment, default model, org roster).
216
+ */
217
+ getWorkspace(): Promise<AgentWorkspaceInfo>;
218
+ /**
219
+ * GET /templates/{key}/files — persona/workspace file contents for a
220
+ * template the agent has access to. Pass `version` to pin to the version
221
+ * the agent was installed from (omit → the endpoint resolves `latest`).
222
+ */
223
+ getTemplateFiles(templateKey: string, opts?: {
224
+ version?: number;
225
+ }): Promise<{
226
+ files: Record<string, string>;
227
+ }>;
154
228
  }
229
+ //# sourceMappingURL=workspace.d.ts.map
230
+ //#endregion
231
+ //#region src/domains/sync.d.ts
155
232
  interface SyncAgentInfo {
156
233
  agentId: string;
157
234
  tenantId: string;
@@ -236,6 +313,65 @@ interface SharedFileEntry {
236
313
  size: number;
237
314
  contentType?: string;
238
315
  }
316
+ declare class SyncApi extends ApiBase {
317
+ syncRegister(args?: {
318
+ displayName?: string;
319
+ }): Promise<{
320
+ agent: SyncAgentInfo;
321
+ }>;
322
+ syncGetManifest(): Promise<SyncManifest>;
323
+ syncPresign(args: {
324
+ files: {
325
+ path: string;
326
+ operation: "put" | "get";
327
+ contentType?: string;
328
+ }[];
329
+ }): Promise<{
330
+ urls: SyncPresignedUrl[];
331
+ }>;
332
+ syncConfirmUpload(args: {
333
+ filePath: string;
334
+ hash: string;
335
+ size: number;
336
+ storageClass?: "STANDARD" | "GLACIER_IR";
337
+ }): Promise<SyncConfirmedUpload>;
338
+ syncReconstruct(args: {
339
+ mode: "full" | "active" | "memory";
340
+ }): Promise<SyncReconstructBundle>;
341
+ syncGetStats(): Promise<SyncAgentStats>;
342
+ syncListFiles(args?: {
343
+ prefix?: string;
344
+ }): Promise<{
345
+ files: SyncFileEntry[];
346
+ }>;
347
+ syncListSessions(): Promise<{
348
+ sessions: SyncSessionEntry[];
349
+ }>;
350
+ syncGetSession(sessionId: string): Promise<SyncSessionContent>;
351
+ syncDeleteFile(filePath: string): Promise<{
352
+ removed: boolean;
353
+ }>;
354
+ sharedListFiles(args: {
355
+ scope: "org" | "team" | "project";
356
+ scopeId: string;
357
+ limit?: number;
358
+ cursor?: string;
359
+ }): Promise<{
360
+ files: SharedFileEntry[];
361
+ nextCursor: string | null;
362
+ }>;
363
+ sharedDownloadUrl(args: {
364
+ scope: "org" | "team" | "project";
365
+ scopeId: string;
366
+ filePath: string;
367
+ }): Promise<{
368
+ downloadUrl: string;
369
+ expiresIn: number;
370
+ }>;
371
+ }
372
+ //# sourceMappingURL=sync.d.ts.map
373
+ //#endregion
374
+ //#region src/domains/knowledge.d.ts
239
375
  type KnowledgeScopeType = "org" | "team" | "project";
240
376
  interface KnowledgeScope {
241
377
  scopeType: KnowledgeScopeType;
@@ -278,15 +414,6 @@ interface KnowledgeProfile {
278
414
  updatedAt: string | null;
279
415
  updatedBy: string | null;
280
416
  }
281
- interface KnowledgeDoc {
282
- filePath: string;
283
- fileName: string;
284
- contentType?: string;
285
- size: number;
286
- uploadedBy?: string;
287
- createdAt: string;
288
- updatedAt: string;
289
- }
290
417
  type ChangeRequestResourceType = "doc" | "profile";
291
418
  type ChangeRequestOperation = "create" | "update" | "delete";
292
419
  type ChangeRequestStatus = "open" | "approved" | "rejected" | "withdrawn" | "superseded";
@@ -328,6 +455,200 @@ interface ProposeScopeChangeInput {
328
455
  /** profile: the proposed value ({ about, description, links }). */
329
456
  proposedValue?: unknown;
330
457
  }
458
+ interface KnowledgeDoc {
459
+ filePath: string;
460
+ fileName: string;
461
+ contentType?: string;
462
+ size: number;
463
+ uploadedBy?: string;
464
+ createdAt: string;
465
+ updatedAt: string;
466
+ }
467
+ declare class KnowledgeApi extends ApiBase {
468
+ /**
469
+ * Semantic search across the agent's member scopes. Fan-out is gated
470
+ * server-side by `listScopes` set-inclusion (fail-closed). Pass
471
+ * `scopeType` + `scopeId` to narrow to one scope; a non-member scope
472
+ * yields empty results (never a cross-scope leak).
473
+ */
474
+ knowledgeSearch(query: string, opts?: {
475
+ limit?: number;
476
+ scopeType?: KnowledgeScopeType;
477
+ scopeId?: string;
478
+ }): Promise<KnowledgeSearchResult>;
479
+ /** Enumerate the scopes (org + teams + projects) this agent belongs to. */
480
+ listScopes(): Promise<{
481
+ scopes: KnowledgeScope[];
482
+ }>;
483
+ /** Read a scope's structured knowledge profile (after membership check). */
484
+ getScopeProfile(scopeType: KnowledgeScopeType, scopeId: string): Promise<KnowledgeProfile>;
485
+ /**
486
+ * Open a change request against a scope's knowledge resource. For a doc
487
+ * create/update, `services/org` returns a presigned staging PUT; this method
488
+ * uploads the proposed `content` to it (echoing the same Content-Type that
489
+ * was signed), mirroring `writeScopeDoc`. The staged body is applied to the
490
+ * canonical doc — attributed to this agent — only when a reviewer approves.
491
+ */
492
+ proposeScopeChange(scopeType: KnowledgeScopeType, scopeId: string, input: ProposeScopeChangeInput): Promise<KnowledgeChangeRequest>;
493
+ /**
494
+ * List the agent's OWN change requests in a scope (filtered server-side to
495
+ * this agent as proposer). Pass `status` to narrow to open / approved / etc.
496
+ */
497
+ listScopeChangeRequests(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
498
+ status?: ChangeRequestStatus;
499
+ limit?: number;
500
+ cursor?: string;
501
+ }): Promise<{
502
+ changeRequests: KnowledgeChangeRequest[];
503
+ nextCursor: string | null;
504
+ }>;
505
+ /** List a scope's docs (the org-files corpus; mirrored to shared/<scope>/). */
506
+ listScopeDocs(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
507
+ limit?: number;
508
+ cursor?: string;
509
+ }): Promise<{
510
+ files: KnowledgeDoc[];
511
+ nextCursor: string | null;
512
+ }>;
513
+ /**
514
+ * Read the full text of a scope doc. Resolves a presigned download URL
515
+ * from `services/org`, then fetches the bytes directly from S3 (the one
516
+ * legitimate raw fetch in a plugin — same pattern as sync).
517
+ */
518
+ readScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, opts?: {
519
+ maxBytes?: number;
520
+ }): Promise<{
521
+ filePath: string;
522
+ text: string;
523
+ }>;
524
+ /**
525
+ * Write (create or overwrite) a scope doc. Two-step presigned upload:
526
+ * `services/org` returns a signed URL plus `requiredHeaders` (author /
527
+ * authorKind / message as `x-amz-meta-*`) that MUST be sent verbatim on
528
+ * the PUT, alongside the same `Content-Type` that was signed. Author and
529
+ * authorKind are server-set from the agent token — never trusted here.
530
+ */
531
+ writeScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, content: string, opts?: {
532
+ contentType?: string;
533
+ message?: string;
534
+ }): Promise<{
535
+ filePath: string;
536
+ }>;
537
+ }
538
+ //# sourceMappingURL=knowledge.d.ts.map
539
+ //#endregion
540
+ //#region src/domains/mobile.d.ts
541
+ /** Response of GET /mobile/numbers for an agent (services/mobile). */
542
+ interface MobileNumberInfo {
543
+ phoneNumber: string;
544
+ countryCode: string;
545
+ monthlyPrice?: number;
546
+ status: string;
547
+ errorMessage?: string;
548
+ }
549
+ /** One purchasable number from GET /mobile/numbers/search. */
550
+ interface MobileAvailableNumber {
551
+ number: string;
552
+ friendlyName: string;
553
+ locality: string;
554
+ region: string;
555
+ country: string;
556
+ }
557
+ /** Approved WhatsApp content template from GET /mobile/whatsapp/templates. */
558
+ interface WhatsAppTemplate {
559
+ contentSid: string;
560
+ name: string;
561
+ language: string;
562
+ body: string;
563
+ variables: Record<string, string>;
564
+ category?: string;
565
+ }
566
+ declare class MobileApi extends ApiBase {
567
+ getMobileNumber(): Promise<MobileNumberInfo>;
568
+ searchMobileNumbers(args?: {
569
+ country?: string;
570
+ query?: string;
571
+ }): Promise<{
572
+ numbers: MobileAvailableNumber[];
573
+ monthlyPrice: number;
574
+ }>;
575
+ assignMobileNumber(args: {
576
+ phoneNumber: string;
577
+ countryCode: string;
578
+ }): Promise<{
579
+ phoneNumber: string;
580
+ countryCode: string;
581
+ status: "pending";
582
+ }>;
583
+ releaseMobileNumber(): Promise<{
584
+ released: true;
585
+ }>;
586
+ sendSms(args: {
587
+ to: string;
588
+ body: string;
589
+ }): Promise<{
590
+ sent: true;
591
+ sid: string;
592
+ }>;
593
+ startOutboundCall(args: {
594
+ to: string;
595
+ }): Promise<{
596
+ callSid: string;
597
+ status: string;
598
+ }>;
599
+ getWhatsAppSession(to: string): Promise<{
600
+ active: boolean;
601
+ expiresAt?: string;
602
+ }>;
603
+ sendWhatsAppMessage(args: {
604
+ to: string;
605
+ body: string;
606
+ }): Promise<{
607
+ sent: true;
608
+ sid: string;
609
+ }>;
610
+ sendWhatsAppTemplate(args: {
611
+ to: string;
612
+ contentSid: string;
613
+ contentVariables: Record<string, string>;
614
+ bodyPreview?: string;
615
+ }): Promise<{
616
+ sent: true;
617
+ sid: string;
618
+ }>;
619
+ listWhatsAppTemplates(): Promise<{
620
+ templates: WhatsAppTemplate[];
621
+ }>;
622
+ }
623
+ //# sourceMappingURL=mobile.d.ts.map
624
+ //#endregion
625
+ //#region src/domains/remote.d.ts
626
+ interface RemoteSessionInfo {
627
+ sessionId: string;
628
+ agentId: string;
629
+ surface: "browser" | "terminal";
630
+ status: "agent_driving" | "awaiting_human" | "human_in_control" | "resuming" | "completed" | "expired" | "failed";
631
+ url?: string;
632
+ instructions?: string;
633
+ requestedAt?: string;
634
+ }
635
+ declare class RemoteApi extends ApiBase {
636
+ requestBrowserTakeover(args: {
637
+ instructions: string;
638
+ url?: string;
639
+ conversationId?: string;
640
+ }): Promise<{
641
+ sessionId: string;
642
+ status: string;
643
+ }>;
644
+ getRemoteSession(sessionId: string): Promise<RemoteSessionInfo>;
645
+ completeRemoteSession(sessionId: string): Promise<{
646
+ ok: boolean;
647
+ }>;
648
+ }
649
+ //# sourceMappingURL=remote.d.ts.map
650
+ //#endregion
651
+ //#region src/domains/self.d.ts
331
652
  /** Voice settings — core agent config. Mirrors `VoiceConfig` in `@alfe/types`. */
332
653
  interface AgentVoiceConfig {
333
654
  /** ElevenLabs voice ID; platform default when unset. */
@@ -369,12 +690,51 @@ interface AgentVoice {
369
690
  labels: Record<string, string>;
370
691
  category: string;
371
692
  }
372
- /** The ElevenLabs models with a pricing row — the TTS endpoint rejects any other value. */
373
- type VoiceTtsModel = "eleven_turbo_v2_5" | "eleven_multilingual_v2";
374
- interface VoiceTtsArgs {
375
- /** Text to synthesize (1–5000 chars — the endpoint enforces this). */
376
- text: string;
377
- /** ElevenLabs voice id; platform default when unset. */
693
+ declare class SelfApi extends ApiBase {
694
+ /** Update the agent's own name and/or voice config. Returns the updated agent. */
695
+ updateSelf(update: {
696
+ name?: string;
697
+ voiceConfig?: AgentVoiceConfig;
698
+ }): Promise<AgentSelf>;
699
+ /**
700
+ * Generate the agent's own avatar from a text prompt. The image is generated,
701
+ * stored, and set on the agent server-side; returns the updated agent.
702
+ *
703
+ * ASYNC (same reason as `generateImage`): avatar gen runs `gpt-image-1`
704
+ * (30–60s) which exceeds the API Gateway 30s ceiling, so this enqueues a job
705
+ * (`POST /agent/avatar/generate` → `jobId`) then polls (`GET /agent/avatar/{jobId}`)
706
+ * until the avatar is set. Signature unchanged — the plugin is unaffected.
707
+ */
708
+ generateAvatar(args: {
709
+ prompt: string;
710
+ }): Promise<AgentSelf>;
711
+ /**
712
+ * Get a presigned PUT URL to upload a new avatar image. Upload the bytes to
713
+ * `uploadUrl`, then call `finalizeAvatar(s3Key)` to set it on the agent.
714
+ */
715
+ presignAvatar(args: {
716
+ mimeType: string;
717
+ size: number;
718
+ }): Promise<AgentAvatarPresign>;
719
+ /**
720
+ * Finalize an avatar upload — validates ownership + size, then sets the
721
+ * agent's `avatarUrl` server-side. Returns the updated agent.
722
+ */
723
+ finalizeAvatar(s3Key: string): Promise<AgentSelf>;
724
+ /** List the platform voice catalogue (ElevenLabs) so the agent can pick its own voice. */
725
+ listVoices(): Promise<{
726
+ voices: AgentVoice[];
727
+ }>;
728
+ }
729
+ //# sourceMappingURL=self.d.ts.map
730
+ //#endregion
731
+ //#region src/domains/voice.d.ts
732
+ /** The ElevenLabs models with a pricing row — the TTS endpoint rejects any other value. */
733
+ type VoiceTtsModel = "eleven_turbo_v2_5" | "eleven_multilingual_v2";
734
+ interface VoiceTtsArgs {
735
+ /** Text to synthesize (1–5000 chars — the endpoint enforces this). */
736
+ text: string;
737
+ /** ElevenLabs voice id; platform default when unset. */
378
738
  voiceId?: string;
379
739
  /** TTS model; `eleven_turbo_v2_5` (lower latency) when unset. */
380
740
  model?: VoiceTtsModel;
@@ -401,84 +761,161 @@ interface VoiceSttResult {
401
761
  /** Deepgram confidence in (0,1]. */
402
762
  confidence: number;
403
763
  }
404
- declare class AgentApiClient {
405
- private readonly apiKey;
406
- private readonly apiUrl;
407
- constructor(config: AgentApiClientConfig);
408
- private request;
409
- syncRegister(args?: {
410
- displayName?: string;
411
- }): Promise<{
412
- agent: SyncAgentInfo;
413
- }>;
414
- syncGetManifest(): Promise<SyncManifest>;
415
- syncPresign(args: {
416
- files: {
417
- path: string;
418
- operation: "put" | "get";
419
- contentType?: string;
420
- }[];
421
- }): Promise<{
422
- urls: SyncPresignedUrl[];
423
- }>;
424
- syncConfirmUpload(args: {
425
- filePath: string;
426
- hash: string;
764
+ declare class VoiceApi extends ApiBase {
765
+ /**
766
+ * Text-to-speech. Returns raw PCM audio bytes plus their framing — the
767
+ * voice service defaults to 24 kHz / mono / 16-bit. Wrap in a WAV container
768
+ * to produce a playable file. Metered per character against the tenant
769
+ * credit pool server-side; TTS completes regardless of metering outcome.
770
+ */
771
+ tts(args: VoiceTtsArgs): Promise<VoiceTtsResult>;
772
+ /**
773
+ * Speech-to-text. Accepts raw linear16 (16-bit LE) mono PCM — NOT a WAV or
774
+ * other container (the endpoint transcribes with a fixed linear16 encoding,
775
+ * so a container header would be transcribed as noise). Strip any WAV header
776
+ * and pass `sampleRate` from it before calling. Metered by transcribed
777
+ * duration against the tenant credit pool server-side.
778
+ */
779
+ stt(args: VoiceSttArgs): Promise<VoiceSttResult>;
780
+ }
781
+ //# sourceMappingURL=voice.d.ts.map
782
+ //#endregion
783
+ //#region src/domains/search.d.ts
784
+ /**
785
+ * The broad-news providers behind the metered `services/news` Lambda. The
786
+ * server validates this with a zod enum; a value outside the union is an
787
+ * unpriceable product, so keep the literal union in lockstep with the service.
788
+ */
789
+ type NewsProvider = "apitube" | "newsdata";
790
+ /** One normalized article. `sentiment` is provider-shaped (APITube supplies it). */
791
+ interface NewsArticle {
792
+ title: string;
793
+ url: string;
794
+ source: string;
795
+ publishedAt: string;
796
+ snippet: string;
797
+ sentiment?: unknown;
798
+ }
799
+ /** Provider-agnostic result — the server normalizes every adapter to this. */
800
+ interface NewsResult {
801
+ articles: NewsArticle[];
802
+ provider: string;
803
+ }
804
+ declare class SearchApi extends ApiBase {
805
+ searchWeb(params: {
806
+ query: string;
807
+ count?: number;
808
+ offset?: number;
809
+ country?: string;
810
+ freshness?: string;
811
+ }, options?: {
812
+ signal?: AbortSignal;
813
+ }): Promise<unknown>;
814
+ searchImages(params: {
815
+ query: string;
816
+ count?: number;
817
+ }, options?: {
818
+ signal?: AbortSignal;
819
+ }): Promise<unknown>;
820
+ searchNews(params: {
821
+ query: string;
822
+ count?: number;
823
+ offset?: number;
824
+ freshness?: string;
825
+ }, options?: {
826
+ signal?: AbortSignal;
827
+ }): Promise<unknown>;
828
+ /** Search news across the selected provider's corpus. → POST /agent/news/search */
829
+ newsSearch(params: {
830
+ query: string;
831
+ provider?: NewsProvider;
832
+ source?: string;
833
+ from?: string;
834
+ to?: string;
835
+ language?: string;
836
+ category?: string;
837
+ limit?: number;
838
+ }): Promise<NewsResult>;
839
+ /** Top headlines for the selected provider. → POST /agent/news/headlines */
840
+ newsHeadlines(params?: {
841
+ provider?: NewsProvider;
842
+ category?: string;
843
+ source?: string;
844
+ language?: string;
845
+ limit?: number;
846
+ }): Promise<NewsResult>;
847
+ }
848
+ //# sourceMappingURL=search.d.ts.map
849
+ //#endregion
850
+ //#region src/domains/webhooks.d.ts
851
+ interface AgentWebhook {
852
+ webhookId: string;
853
+ tenantId: string;
854
+ agentId: string;
855
+ name: string;
856
+ provider: string;
857
+ active: boolean;
858
+ createdBy: string;
859
+ createdAt: string;
860
+ updatedAt: string;
861
+ }
862
+ interface CreatedAgentWebhook extends AgentWebhook {
863
+ url: string;
864
+ signingSecret: string;
865
+ }
866
+ interface AgentWebhookDelivery {
867
+ deliveryId: string;
868
+ webhookId: string;
869
+ status: string;
870
+ attempts: number;
871
+ createdAt: string;
872
+ deliveredAt?: string;
873
+ }
874
+ declare class WebhooksApi extends ApiBase {
875
+ createWebhook(args: {
876
+ name: string;
877
+ provider?: "generic" | "github" | "stripe" | "slack";
878
+ }): Promise<CreatedAgentWebhook>;
879
+ listWebhooks(): Promise<AgentWebhook[]>;
880
+ deleteWebhook(webhookId: string): Promise<{
881
+ webhookId: string;
882
+ active: false;
883
+ }>;
884
+ rotateWebhookSecret(webhookId: string): Promise<{
885
+ webhookId: string;
886
+ signingSecret: string;
887
+ }>;
888
+ listWebhookDeliveries(webhookId: string): Promise<AgentWebhookDelivery[]>;
889
+ }
890
+ //# sourceMappingURL=webhooks.d.ts.map
891
+ //#endregion
892
+ //#region src/domains/chat.d.ts
893
+ declare class ChatApi extends ApiBase {
894
+ presignAttachments(files: {
895
+ filename: string;
896
+ mimeType: string;
427
897
  size: number;
428
- storageClass?: "STANDARD" | "GLACIER_IR";
429
- }): Promise<SyncConfirmedUpload>;
430
- syncReconstruct(args: {
431
- mode: "full" | "active" | "memory";
432
- }): Promise<SyncReconstructBundle>;
433
- syncGetStats(): Promise<SyncAgentStats>;
434
- syncListFiles(args?: {
435
- prefix?: string;
436
- }): Promise<{
437
- files: SyncFileEntry[];
438
- }>;
439
- syncListSessions(): Promise<{
440
- sessions: SyncSessionEntry[];
441
- }>;
442
- syncGetSession(sessionId: string): Promise<SyncSessionContent>;
443
- syncDeleteFile(filePath: string): Promise<{
444
- removed: boolean;
445
- }>;
446
- sharedListFiles(args: {
447
- scope: "org" | "team" | "project";
448
- scopeId: string;
449
- }): Promise<{
450
- files: SharedFileEntry[];
451
- nextCursor: string | null;
898
+ }[]): Promise<{
899
+ attachments: {
900
+ id: string;
901
+ uploadUrl: string;
902
+ downloadUrl: string;
903
+ s3Key: string;
904
+ expiresAt: string;
905
+ }[];
452
906
  }>;
453
- sharedDownloadUrl(args: {
454
- scope: "org" | "team" | "project";
455
- scopeId: string;
456
- filePath: string;
907
+ recordActivity(data: {
908
+ userId?: string;
909
+ channel: string;
910
+ role: "user" | "assistant";
457
911
  }): Promise<{
458
- downloadUrl: string;
459
- expiresIn: number;
460
- }>;
461
- listIntegrations(): Promise<IntegrationInstall[]>;
462
- getIntegrationConfig(integrationId: string): Promise<IntegrationConfigResult>;
463
- updateIntegrationConfig(integrationId: string, config: Record<string, unknown>): Promise<void>;
464
- installIntegration(integrationId: string, options?: {
465
- version?: string;
466
- config?: Record<string, unknown>;
467
- }): Promise<IntegrationInstall>;
468
- removeIntegration(integrationId: string): Promise<IntegrationInstall>;
469
- getOAuthUrl(provider: string, scopes?: string[]): Promise<{
470
- url: string;
471
- provider: string;
472
- expiresIn: number;
473
- }>;
474
- getOAuthStatus(provider: string): Promise<{
475
- provider: string;
476
- connected: boolean;
477
- config?: Record<string, string>;
478
- }>;
479
- getRegistry(): Promise<{
480
- integrations: RegistryEntry[];
912
+ recorded: boolean;
481
913
  }>;
914
+ }
915
+ //# sourceMappingURL=chat.d.ts.map
916
+ //#endregion
917
+ //#region src/domains/connect-credentials.d.ts
918
+ declare class ConnectCredentialsApi extends ApiBase {
482
919
  /**
483
920
  * Returns every connected Google account for the agent. Multi-account by
484
921
  * design — the openclaw-google plugin requires the LLM to pass `email`
@@ -535,82 +972,19 @@ declare class AgentApiClient {
535
972
  [key: string]: unknown;
536
973
  }>;
537
974
  /**
538
- * Resolve the primary cTrader Connection's credentials for the calling
539
- * agent. Unlike most providers, the cTrader Open API needs app-level auth
540
- * (`clientId` + `clientSecret`) AND account auth (`accessToken` +
541
- * `accountId`) on the socket, so `@alfe.ai/ctrader-mcp` self-fetches the
542
- * full set here at startup (the atlassian/google pattern). `clientId` /
543
- * `clientSecret` are the SST-sourced global app credentials the connect
544
- * endpoint injects — they are never persisted on the connection. `host` is
545
- * the resolved TLS endpoint (`live.ctraderapi.com` / `demo.ctraderapi.com`)
546
- * derived from the selected account's live/demo flag.
975
+ * @deprecated Returns a single primary credential blob (legacy "pick-the-
976
+ * default-connection" shape). Use `getGithubAccounts()` for the multi-
977
+ * account shape required by Pattern A explicit selector args on every
978
+ * tool. Retained because the `@alfe.ai/github-mcp` proxy is the
979
+ * only consumer that knows about Pattern A; legacy env-interpolation
980
+ * callers will keep hitting `/credentials` until they move to the proxy.
547
981
  */
548
- getCTraderCredentials(): Promise<{
982
+ getGithubCredentials(): Promise<{
983
+ login: string;
549
984
  accessToken: string;
550
- refreshToken: string;
551
- accountId: string;
552
- host: string;
553
- clientId: string;
554
- clientSecret: string;
555
985
  }>;
556
986
  /**
557
- * Pattern A: multi-account credential fetch for cTrader.
558
- *
559
- * Unlike atlassian/salesforce (one Connection row per account/site), a
560
- * cTrader is MULTI-grant per agent: an agent may connect several distinct
561
- * cTrader logins, each its own Connection row keyed on `accountIdentifier =
562
- * ctid:<userId>` (Phase 1). This aggregates the *trading accounts* across
563
- * ALL of those Connection rows — each row contributes its `availableAccounts`
564
- * flattened, and every account carries ITS OWN grant's `accessToken` (the
565
- * token that authenticates that account against the cTrader Open API). One
566
- * OAuth grant still covers all accounts under that single login on one shared
567
- * token; only the `ctidTraderAccountId` and the protobuf socket `host` (live
568
- * vs demo) differ within a grant. Across grants the tokens differ, so the
569
- * token is now PER-ACCOUNT rather than hoisted to the top level.
570
- *
571
- * `host` per account is derived from the account's `isLive` flag
572
- * (`live.ctraderapi.com` / `demo.ctraderapi.com`) — the same mapping the
573
- * connect provider applies server-side when an account is auto-selected.
574
- *
575
- * `clientId` / `clientSecret` are the SST-sourced GLOBAL app credentials the
576
- * connect endpoint injects — identical across every Connection row (one
577
- * cTrader app), never persisted on a connection. We take them from the first
578
- * row that carries them.
579
- *
580
- * Accounts are deduped on `ctidTraderAccountId` first-wins: Spotware ids are
581
- * globally unique across logins, so a duplicate can only appear if the same
582
- * account somehow surfaced under two grants — first-wins keeps it
583
- * deterministic.
584
- *
585
- * `accounts` may be empty (no cTrader Connection at all), in which case we
586
- * return empty creds rather than throwing.
587
- */
588
- getCTraderAccounts(): Promise<{
589
- accounts: {
590
- ctidTraderAccountId: string;
591
- host: string;
592
- isLive: boolean;
593
- brokerName?: string;
594
- accountNumber?: string;
595
- accessToken: string;
596
- }[];
597
- clientId: string;
598
- clientSecret: string;
599
- }>;
600
- /**
601
- * @deprecated Returns a single primary credential blob (legacy "pick-the-
602
- * default-connection" shape). Use `getGithubAccounts()` for the multi-
603
- * account shape required by Pattern A — explicit selector args on every
604
- * tool. Retained because the `@alfe.ai/github-mcp` proxy is the
605
- * only consumer that knows about Pattern A; legacy env-interpolation
606
- * callers will keep hitting `/credentials` until they move to the proxy.
607
- */
608
- getGithubCredentials(): Promise<{
609
- login: string;
610
- accessToken: string;
611
- }>;
612
- /**
613
- * Pattern A: multi-account credential fetch for GitHub.
987
+ * Pattern A: multi-account credential fetch for GitHub.
614
988
  *
615
989
  * Returns every agent-scoped GitHub connection. The caller is expected
616
990
  * to require a `login` selector on every credential-touching tool and
@@ -634,67 +1008,6 @@ declare class AgentApiClient {
634
1008
  scopes: string;
635
1009
  }[];
636
1010
  }>;
637
- /**
638
- * Pattern A: provider-parameterized multi-account credential fetch for the
639
- * social connectors (Bluesky, and the approval-gated backlog: X, Meta,
640
- * Threads, LinkedIn, Pinterest, TikTok, Reddit, YouTube).
641
- *
642
- * Unlike the bespoke `getGithubAccounts()` / `getXeroAccounts()` shapes,
643
- * this returns a UNIFORM normalized account shape so `@alfe.ai/social-mcp`'s
644
- * shared driver can require a single `account` selector on every
645
- * credential-touching tool regardless of platform. The backend
646
- * `api-agents/{provider}/accounts` route is already provider-generic; this
647
- * is the client-side normalization the plan (`do-we-need-any-moonlit-toucan`
648
- * Phase 0, step 5) calls for.
649
- *
650
- * `accountIdentifier` is the stable per-account selector the LLM should
651
- * pass back (for Bluesky: the account DID). `accessToken` carries whatever
652
- * the provider's `buildCredentialsResponse` bundles (for Bluesky: the JSON
653
- * session bundle — the driver parses the `accessJwt` out of it, or reads the
654
- * top-level `accessJwt` from `providerMetadata`-adjacent fields). Everything
655
- * else the driver needs for routing (handle, pdsHost, did, …) is on
656
- * `providerMetadata`.
657
- *
658
- * Token refresh is delegated to connect (never done in-plugin) via the
659
- * per-account route `POST /agent/connect/{provider}/accounts/{accountIdentifier}/refresh`
660
- * — call `refreshSocialAccount(provider, accountIdentifier)`. (The non-account
661
- * `POST /agent/connect/{provider}/refresh` route refreshes the provider's
662
- * PRIMARY connection, which is wrong under multi-account Pattern A.)
663
- */
664
- getSocialAccounts(provider: string): Promise<{
665
- provider: string;
666
- accounts: {
667
- connectionId: string;
668
- accountIdentifier: string;
669
- displayName: string | null;
670
- accessToken: string;
671
- providerMetadata: Record<string, unknown>;
672
- connectedAt: string;
673
- }[];
674
- }>;
675
- /**
676
- * Pattern A: refresh a specific social Connection by its stable
677
- * `accountIdentifier` (for Bluesky: the account DID) via the
678
- * provider-generic per-account refresh route. The counterpart to
679
- * `getSocialAccounts(provider)`; `@alfe.ai/social-mcp` calls this on a
680
- * 401/ExpiredToken from the platform PDS/API, then re-fetches accounts to
681
- * pick up the rotated bundle.
682
- *
683
- * Refresh itself is ALWAYS delegated to connect — the plugin never calls
684
- * the platform's own refresh XRPC (e.g. `com.atproto.server.refreshSession`)
685
- * because connect owns the encrypted refresh token + rotation persistence
686
- * (Bluesky rotates the refreshJwt; a missed rotation kills the connection
687
- * after one refresh). The returned `accessToken` is whatever the provider's
688
- * `refreshToken` hook re-bundled (for Bluesky: the JSON session bundle with
689
- * the fresh `accessJwt`) — callers typically ignore it and re-fetch via
690
- * `getSocialAccounts` for a consistent shape.
691
- */
692
- refreshSocialAccount(provider: string, accountIdentifier: string): Promise<{
693
- accountIdentifier: string;
694
- accessToken: string;
695
- accessTokenExpiresAt: string;
696
- expiresAt: string;
697
- }>;
698
1011
  /**
699
1012
  * @deprecated Returns a single primary credential blob (legacy "pick-the-
700
1013
  * default-connection" shape). Use `getXeroAccounts()` for the multi-
@@ -712,8 +1025,9 @@ declare class AgentApiClient {
712
1025
  * selector arg (e.g. `xeroTenantId`) on every credential-touching tool
713
1026
  * and look up the matching account by that selector at dispatch time.
714
1027
  *
715
- * Returned `accounts[i].accountIdentifier` is the Xero tenantId the
716
- * stable cross-session identifier the LLM should pass.
1028
+ * `xeroTenantId` is the model-facing organisation selector. The separate
1029
+ * `accountIdentifier` is the Connect persistence key used for refresh and
1030
+ * may be an email; never substitute one for the other.
717
1031
  */
718
1032
  getXeroAccounts(): Promise<{
719
1033
  accounts: {
@@ -731,12 +1045,12 @@ declare class AgentApiClient {
731
1045
  expiresAt: string;
732
1046
  }>;
733
1047
  /**
734
- * Pattern A: refresh a specific Xero connection by its `accountIdentifier`
735
- * (the Xero `tenantId`). The legacy `refreshXeroToken()` only refreshes
736
- * the *primary* connection, which is wrong for multi-tenant Xero where
737
- * each tenant has its own non-interchangeable access token.
1048
+ * Refresh a specific Xero Connection by its exact `accountIdentifier` from
1049
+ * `getXeroAccounts()`. Do not substitute `xeroTenantId`: current Xero OAuth
1050
+ * rows may use the account email as their persistence key even when a sole
1051
+ * organisation tenant ID is available in provider metadata.
738
1052
  */
739
- refreshXeroAccountToken(xeroTenantId: string): Promise<{
1053
+ refreshXeroAccountToken(accountIdentifier: string): Promise<{
740
1054
  accessToken: string;
741
1055
  accessTokenExpiresAt: string;
742
1056
  expiresAt: string;
@@ -891,6 +1205,21 @@ declare class AgentApiClient {
891
1205
  accessToken: string;
892
1206
  expiresAt: string;
893
1207
  }>;
1208
+ /**
1209
+ * Pattern A: refresh one MYOB Connection by its stable
1210
+ * `accountIdentifier` (the MYOB business id returned by
1211
+ * `getMYOBAccounts()`).
1212
+ *
1213
+ * MYOB refresh tokens belong to individual Connection rows. A
1214
+ * multi-business client must use this method instead of refreshing the
1215
+ * primary Connection and copying that access token into every cached
1216
+ * business client.
1217
+ */
1218
+ refreshMYOBAccountToken(accountIdentifier: string): Promise<{
1219
+ accessToken: string;
1220
+ accessTokenExpiresAt: string;
1221
+ expiresAt: string;
1222
+ }>;
894
1223
  /**
895
1224
  * @deprecated Returns a single primary credential blob. Use
896
1225
  * `getSalesforceAccounts()` for the multi-account shape required by
@@ -930,67 +1259,6 @@ declare class AgentApiClient {
930
1259
  accessTokenExpiresAt: string;
931
1260
  expiresAt: string;
932
1261
  }>;
933
- /**
934
- * @deprecated Returns a single primary credential blob. Use
935
- * `getShopifyAccounts()` for the multi-account shape required by Pattern A
936
- * (`@alfe.ai/shopify-mcp` keys per-shop on the myshopify domain).
937
- */
938
- getShopifyCredentials(): Promise<{
939
- accessToken: string;
940
- shopDomain: string;
941
- shopGid: string;
942
- shopName: string;
943
- apiVersion: string;
944
- }>;
945
- /**
946
- * Pattern A: multi-account credential fetch for Shopify. Returns every
947
- * agent-scoped Shopify Connection. One OAuth grant maps to one store, so the
948
- * stable per-call selector is the store's myshopify domain (`shopDomain`),
949
- * NOT `accountIdentifier` — the connect provider keys `accountIdentifier` on
950
- * the immutable shop GID (falling back to the domain), so `shopDomain` is the
951
- * value the LLM passes and the plugin routes on.
952
- *
953
- * Each entry is shaped by the connect provider's `buildCredentialsResponse`:
954
- * `{ accessToken, shopDomain, shopGid, shopName, apiVersion }` — offline
955
- * Shopify tokens never expire, so there is NO token / expiry field and no
956
- * refresh method (unlike Salesforce). The GraphQL Admin API authenticates
957
- * purely on `X-Shopify-Access-Token`; no client credentials are on the wire.
958
- */
959
- getShopifyAccounts(): Promise<{
960
- accounts: {
961
- connectionId: string;
962
- accountIdentifier: string;
963
- displayName: string | null;
964
- connectedAt: string;
965
- accessToken: string;
966
- shopDomain: string;
967
- shopGid: string;
968
- shopName: string;
969
- apiVersion: string;
970
- }[];
971
- }>;
972
- /**
973
- * Disconnects one connected Microsoft 365 account for the agent, by its
974
- * `accountIdentifier`. Hits the generic per-account disconnect route
975
- * (`DELETE /agent/connect/microsoft/accounts/{accountIdentifier}`), which
976
- * resolves across the agent's full effective scope chain and deletes the
977
- * matching Connection row. Returns the remaining accounts.
978
- *
979
- * IMPORTANT: pass the `accountIdentifier` from `getMicrosoftAccounts()`, NOT
980
- * a synthesised email. For Microsoft, `accountIdentifier` is the user's email
981
- * only when the Graph profile fetch succeeded at connect time; it falls back
982
- * to the Azure tenant id (`tid` claim) otherwise. The backend matches on
983
- * `accountIdentifier` exactly, so passing an email would 404 on those
984
- * fallback-identifier accounts. (This is why the param is not named `email`,
985
- * unlike `disconnectGoogleAccount` where the identifier is always the email.)
986
- */
987
- disconnectMicrosoftAccount(accountIdentifier: string): Promise<{
988
- accounts: {
989
- accountIdentifier: string;
990
- displayName?: string;
991
- connectedAt?: string;
992
- }[];
993
- }>;
994
1262
  /**
995
1263
  * Pattern A: multi-account credential fetch for Microsoft 365.
996
1264
  *
@@ -1014,9 +1282,6 @@ declare class AgentApiClient {
1014
1282
  connectedAt: string;
1015
1283
  accessToken: string;
1016
1284
  accessTokenExpiresAt: string;
1017
- refreshToken: string;
1018
- clientId: string;
1019
- clientSecret: string;
1020
1285
  email: string;
1021
1286
  microsoftTenantId: string;
1022
1287
  workspaceDomain: string;
@@ -1041,242 +1306,213 @@ declare class AgentApiClient {
1041
1306
  accessTokenExpiresAt: string;
1042
1307
  expiresAt: string;
1043
1308
  }>;
1044
- getTeamsCredentials(): Promise<{
1045
- agentId: string;
1046
- tenantId: string;
1047
- azureAppId: string;
1048
- azureBotId: string;
1049
- azureClientSecret: string;
1050
- botDisplayName?: string;
1051
- teamsTenantId?: string;
1052
- serviceUrl?: string;
1053
- }>;
1054
- sendTeamsMessage(data: {
1055
- conversationId: string;
1056
- text?: string;
1057
- adaptiveCard?: Record<string, unknown>;
1058
- }): Promise<{
1059
- ok: boolean;
1060
- activityId: string;
1061
- }>;
1062
- listTeamsChannels(): Promise<{
1063
- channels: {
1064
- id: string;
1065
- name: string;
1066
- description?: string;
1067
- }[];
1068
- }>;
1069
- presignAttachments(files: {
1070
- filename: string;
1071
- mimeType: string;
1072
- size: number;
1073
- }[]): Promise<{
1074
- attachments: {
1075
- id: string;
1076
- uploadUrl: string;
1077
- downloadUrl: string;
1078
- s3Key: string;
1079
- expiresAt: string;
1080
- }[];
1081
- }>;
1082
1309
  /**
1083
- * Generate an image from a text prompt and get back a STABLE, public URL
1084
- * (served from the agent-assets CDN — it does not expire). Embed the returned
1085
- * `imageUrl` in a reply as markdown to show it to the user.
1310
+ * Disconnects one connected Microsoft 365 account for the agent, by its
1311
+ * `accountIdentifier`. Hits the generic per-account disconnect route
1312
+ * (`DELETE /agent/connect/microsoft/accounts/{accountIdentifier}`), which
1313
+ * resolves across the agent's full effective scope chain and deletes the
1314
+ * matching Connection row. Returns the remaining accounts.
1086
1315
  *
1087
- * ASYNC: `gpt-image-1` routinely runs 30–60s, which exceeds the API Gateway
1088
- * 30s ceiling, so this enqueues a job (`POST /agent/images/generate`
1089
- * `jobId`) then polls (`GET /agent/images/{jobId}`) until it completes. The
1090
- * worker's real failure message (e.g. an unsupported `size`) surfaces via the
1091
- * job's `error` field.
1316
+ * IMPORTANT: pass the `accountIdentifier` from `getMicrosoftAccounts()`, NOT
1317
+ * a synthesised email. For Microsoft, `accountIdentifier` is the user's email
1318
+ * only when the Graph profile fetch succeeded at connect time; it falls back
1319
+ * to the Azure tenant id (`tid` claim) otherwise. The backend matches on
1320
+ * `accountIdentifier` exactly, so passing an email would 404 on those
1321
+ * fallback-identifier accounts. (This is why the param is not named `email`,
1322
+ * unlike `disconnectGoogleAccount` where the identifier is always the email.)
1092
1323
  */
1093
- generateImage(args: {
1094
- prompt: string;
1095
- model?: string;
1096
- size?: string;
1097
- quality?: string;
1098
- }): Promise<{
1099
- imageUrl: string;
1100
- model: string;
1101
- }>;
1102
- recordActivity(data: {
1103
- userId?: string;
1104
- channel: string;
1105
- role: "user" | "assistant";
1106
- }): Promise<{
1107
- recorded: boolean;
1324
+ disconnectMicrosoftAccount(accountIdentifier: string): Promise<{
1325
+ accounts: {
1326
+ accountIdentifier: string;
1327
+ displayName?: string;
1328
+ connectedAt?: string;
1329
+ }[];
1108
1330
  }>;
1109
- /** Update the agent's own name and/or voice config. Returns the updated agent. */
1110
- updateSelf(update: {
1111
- name?: string;
1112
- voiceConfig?: AgentVoiceConfig;
1113
- }): Promise<AgentSelf>;
1114
- /**
1115
- * Generate the agent's own avatar from a text prompt. The image is generated,
1116
- * stored, and set on the agent server-side; returns the updated agent.
1117
- *
1118
- * ASYNC (same reason as `generateImage`): avatar gen runs `gpt-image-1`
1119
- * (30–60s) which exceeds the API Gateway 30s ceiling, so this enqueues a job
1120
- * (`POST /agent/avatar/generate` → `jobId`) then polls (`GET /agent/avatar/{jobId}`)
1121
- * until the avatar is set. Signature unchanged — the plugin is unaffected.
1122
- */
1123
- generateAvatar(args: {
1124
- prompt: string;
1125
- }): Promise<AgentSelf>;
1126
1331
  /**
1127
- * Get a presigned PUT URL to upload a new avatar image. Upload the bytes to
1128
- * `uploadUrl`, then call `finalizeAvatar(s3Key)` to set it on the agent.
1129
- */
1130
- presignAvatar(args: {
1131
- mimeType: string;
1132
- size: number;
1133
- }): Promise<AgentAvatarPresign>;
1134
- /**
1135
- * Finalize an avatar upload validates ownership + size, then sets the
1136
- * agent's `avatarUrl` server-side. Returns the updated agent.
1332
+ * Resolve the primary cTrader Connection's credentials for the calling
1333
+ * agent. Unlike most providers, the cTrader Open API needs app-level auth
1334
+ * (`clientId` + `clientSecret`) AND account auth (`accessToken` +
1335
+ * `accountId`) on the socket, so `@alfe.ai/ctrader-mcp` self-fetches the
1336
+ * full set here at startup (the atlassian/google pattern). `clientId` /
1337
+ * `clientSecret` are the SST-sourced global app credentials the connect
1338
+ * endpoint injects — they are never persisted on the connection. `host` is
1339
+ * the resolved TLS endpoint (`live.ctraderapi.com` / `demo.ctraderapi.com`)
1340
+ * derived from the selected account's live/demo flag.
1137
1341
  */
1138
- finalizeAvatar(s3Key: string): Promise<AgentSelf>;
1139
- /** List the platform voice catalogue (ElevenLabs) so the agent can pick its own voice. */
1140
- listVoices(): Promise<{
1141
- voices: AgentVoice[];
1342
+ getCTraderCredentials(): Promise<{
1343
+ accessToken: string;
1344
+ refreshToken: string;
1345
+ accountId: string;
1346
+ host: string;
1347
+ clientId: string;
1348
+ clientSecret: string;
1142
1349
  }>;
1143
1350
  /**
1144
- * Mint a fresh AES-256 data key for a specific (secret, field) pair. The
1145
- * encryption context is rebuilt server-side from `auth.tenantId` + the body
1146
- * fields including `fieldKey`; the agent cannot forge context for a scope
1147
- * or field it doesn't own. Legacy single-envelope secrets are migrated to
1148
- * `field#value` rows by the data migration, so call with `fieldKey: "value"`
1149
- * to reach them.
1351
+ * Pattern A: multi-account credential fetch for cTrader.
1352
+ *
1353
+ * Unlike atlassian/salesforce (one Connection row per account/site), a
1354
+ * cTrader is MULTI-grant per agent: an agent may connect several distinct
1355
+ * cTrader logins, each its own Connection row keyed on `accountIdentifier =
1356
+ * ctid:<userId>` (Phase 1). This aggregates the *trading accounts* across
1357
+ * ALL of those Connection rows — each row contributes its `availableAccounts`
1358
+ * flattened, and every account carries ITS OWN grant's `accessToken` (the
1359
+ * token that authenticates that account against the cTrader Open API). One
1360
+ * OAuth grant still covers all accounts under that single login on one shared
1361
+ * token; only the `ctidTraderAccountId` and the protobuf socket `host` (live
1362
+ * vs demo) differ within a grant. Across grants the tokens differ, so the
1363
+ * token is now PER-ACCOUNT rather than hoisted to the top level.
1364
+ *
1365
+ * `host` per account is derived from the account's `isLive` flag
1366
+ * (`live.ctraderapi.com` / `demo.ctraderapi.com`) — the same mapping the
1367
+ * connect provider applies server-side when an account is auto-selected.
1368
+ *
1369
+ * `clientId` / `clientSecret` are the SST-sourced GLOBAL app credentials the
1370
+ * connect endpoint injects — identical across every Connection row (one
1371
+ * cTrader app), never persisted on a connection. We take them from the first
1372
+ * row that carries them.
1373
+ *
1374
+ * Accounts are deduped on `ctidTraderAccountId` first-wins: Spotware ids are
1375
+ * globally unique across logins, so a duplicate can only appear if the same
1376
+ * account somehow surfaced under two grants — first-wins keeps it
1377
+ * deterministic.
1378
+ *
1379
+ * `accounts` may be empty (no cTrader Connection at all), in which case we
1380
+ * return empty creds rather than throwing.
1150
1381
  */
1151
- generateSecretDataKey(args: {
1152
- scope: SecretScope;
1153
- scopeId: string;
1154
- secretId: string;
1155
- fieldKey: string;
1156
- }): Promise<GeneratedDataKey>;
1382
+ getCTraderAccounts(): Promise<{
1383
+ accounts: {
1384
+ ctidTraderAccountId: string;
1385
+ host: string;
1386
+ isLive: boolean;
1387
+ brokerName?: string;
1388
+ accountNumber?: string;
1389
+ accessToken: string;
1390
+ }[];
1391
+ clientId: string;
1392
+ clientSecret: string;
1393
+ }>;
1157
1394
  /**
1158
- * Unwrap a wrapped data key so the agent can decrypt the envelope locally.
1159
- * `fieldKey` MUST match the value supplied when the data key was generated
1160
- * (it's bound into KMS encryption context); mismatch fails with
1161
- * `InvalidCiphertextException`.
1395
+ * @deprecated Returns a single primary credential blob. Use
1396
+ * `getShopifyAccounts()` for the multi-account shape required by Pattern A
1397
+ * (`@alfe.ai/shopify-mcp` keys per-shop on the myshopify domain).
1162
1398
  */
1163
- decryptSecretDataKey(args: {
1164
- scope: SecretScope;
1165
- scopeId: string;
1166
- secretId: string;
1167
- fieldKey: string;
1168
- dataKeyCiphertext: string;
1169
- }): Promise<{
1170
- plaintextKey: string;
1399
+ getShopifyCredentials(): Promise<{
1400
+ accessToken: string;
1401
+ shopDomain: string;
1402
+ shopGid: string;
1403
+ shopName: string;
1404
+ apiVersion: string;
1171
1405
  }>;
1172
1406
  /**
1173
- * Create a new secret with one or more fields. Encrypted fields must arrive
1174
- * pre-sealed (the agent has already obtained per-field data keys via
1175
- * `generateSecretDataKey({ ..., fieldKey })` and AES-encrypted locally).
1176
- * Plaintext fields ship the value inline.
1407
+ * Pattern A: multi-account credential fetch for Shopify. Returns every
1408
+ * agent-scoped Shopify Connection. One OAuth grant maps to one store, so the
1409
+ * stable per-call selector is the store's myshopify domain (`shopDomain`),
1410
+ * NOT `accountIdentifier` the connect provider keys `accountIdentifier` on
1411
+ * the immutable shop GID (falling back to the domain), so `shopDomain` is the
1412
+ * value the LLM passes and the plugin routes on.
1413
+ *
1414
+ * Each entry is shaped by the connect provider's `buildCredentialsResponse`:
1415
+ * `{ accessToken, shopDomain, shopGid, shopName, apiVersion }` — offline
1416
+ * Shopify tokens never expire, so there is NO token / expiry field and no
1417
+ * refresh method (unlike Salesforce). The GraphQL Admin API authenticates
1418
+ * purely on `X-Shopify-Access-Token`; no client credentials are on the wire.
1177
1419
  */
1178
- createSecret(args: {
1179
- scope: SecretScope;
1180
- scopeId: string;
1181
- secretId: string;
1182
- secretName: string;
1183
- category?: SecretCategory;
1184
- description?: string;
1185
- tags?: string[];
1186
- fields: {
1187
- key: string;
1188
- format?: FieldFormat;
1189
- sensitivity: FieldSensitivity;
1190
- value?: string;
1191
- envelope?: EncryptedEnvelopeV1;
1420
+ getShopifyAccounts(): Promise<{
1421
+ accounts: {
1422
+ connectionId: string;
1423
+ accountIdentifier: string;
1424
+ displayName: string | null;
1425
+ connectedAt: string;
1426
+ accessToken: string;
1427
+ shopDomain: string;
1428
+ shopGid: string;
1429
+ shopName: string;
1430
+ apiVersion: string;
1192
1431
  }[];
1193
- reason?: string;
1194
- }): Promise<SecretAggregate>;
1195
- /** Fetch the secret aggregate plus per-field encrypted envelopes. */
1196
- getSecret(args: {
1197
- scope: SecretScope;
1198
- scopeId: string;
1199
- secretId: string;
1200
- }): Promise<{
1201
- aggregate: SecretAggregate;
1202
- envelopes: FieldEnvelope[];
1203
1432
  }>;
1204
- /** Fetch one field. Plaintext: value inline. Encrypted: envelope. */
1205
- getSecretField(args: {
1206
- scope: SecretScope;
1207
- scopeId: string;
1208
- secretId: string;
1209
- fieldKey: string;
1210
- }): Promise<{
1211
- key: string;
1212
- sensitivity: FieldSensitivity;
1213
- format?: FieldFormat;
1214
- value?: string;
1215
- envelope?: EncryptedEnvelopeV1;
1216
- rotatedAt?: string;
1217
- createdAt: string;
1218
- updatedAt: string;
1433
+ /**
1434
+ * Pattern A: provider-parameterized multi-account credential fetch for the
1435
+ * social connectors (Bluesky, and the approval-gated backlog: X, Meta,
1436
+ * Threads, LinkedIn, Pinterest, TikTok, Reddit, YouTube).
1437
+ *
1438
+ * Unlike the bespoke `getGithubAccounts()` / `getXeroAccounts()` shapes,
1439
+ * this returns a UNIFORM normalized account shape so `@alfe.ai/social-mcp`'s
1440
+ * shared driver can require a single `account` selector on every
1441
+ * credential-touching tool regardless of platform. The backend
1442
+ * `api-agents/{provider}/accounts` route is already provider-generic; this
1443
+ * is the client-side normalization the plan (`do-we-need-any-moonlit-toucan`
1444
+ * Phase 0, step 5) calls for.
1445
+ *
1446
+ * `accountIdentifier` is the stable per-account selector the LLM should
1447
+ * pass back (for Bluesky: the account DID). `accessToken` carries whatever
1448
+ * the provider's `buildCredentialsResponse` bundles (for Bluesky: the JSON
1449
+ * session bundle — the driver parses the `accessJwt` out of it, or reads the
1450
+ * top-level `accessJwt` from `providerMetadata`-adjacent fields). Everything
1451
+ * else the driver needs for routing (handle, pdsHost, did, …) is on
1452
+ * `providerMetadata`.
1453
+ *
1454
+ * Token refresh is delegated to connect (never done in-plugin) via the
1455
+ * per-account route `POST /agent/connect/{provider}/accounts/{accountIdentifier}/refresh`
1456
+ * — call `refreshSocialAccount(provider, accountIdentifier)`. (The non-account
1457
+ * `POST /agent/connect/{provider}/refresh` route refreshes the provider's
1458
+ * PRIMARY connection, which is wrong under multi-account Pattern A.)
1459
+ */
1460
+ getSocialAccounts(provider: string): Promise<{
1461
+ provider: string;
1462
+ accounts: {
1463
+ connectionId: string;
1464
+ accountIdentifier: string;
1465
+ displayName: string | null;
1466
+ accessToken: string;
1467
+ providerMetadata: Record<string, unknown>;
1468
+ connectedAt: string;
1469
+ }[];
1219
1470
  }>;
1220
- /** Add OR rotate one field. */
1221
- setSecretField(args: {
1222
- scope: SecretScope;
1223
- scopeId: string;
1224
- secretId: string;
1225
- fieldKey: string;
1226
- sensitivity: FieldSensitivity;
1227
- format?: FieldFormat;
1228
- value?: string;
1229
- envelope?: EncryptedEnvelopeV1;
1230
- reason?: string;
1231
- }): Promise<{
1232
- fieldKey: string;
1233
- rotated: boolean;
1471
+ /**
1472
+ * Pattern A: refresh a specific social Connection by its stable
1473
+ * `accountIdentifier` (for Bluesky: the account DID) via the
1474
+ * provider-generic per-account refresh route. The counterpart to
1475
+ * `getSocialAccounts(provider)`; `@alfe.ai/social-mcp` calls this on a
1476
+ * 401/ExpiredToken from the platform PDS/API, then re-fetches accounts to
1477
+ * pick up the rotated bundle.
1478
+ *
1479
+ * Refresh itself is ALWAYS delegated to connect — the plugin never calls
1480
+ * the platform's own refresh XRPC (e.g. `com.atproto.server.refreshSession`)
1481
+ * because connect owns the encrypted refresh token + rotation persistence
1482
+ * (Bluesky rotates the refreshJwt; a missed rotation kills the connection
1483
+ * after one refresh). The returned `accessToken` is whatever the provider's
1484
+ * `refreshToken` hook re-bundled (for Bluesky: the JSON session bundle with
1485
+ * the fresh `accessJwt`) — callers typically ignore it and re-fetch via
1486
+ * `getSocialAccounts` for a consistent shape.
1487
+ */
1488
+ refreshSocialAccount(provider: string, accountIdentifier: string): Promise<{
1489
+ accountIdentifier: string;
1490
+ accessToken: string;
1491
+ accessTokenExpiresAt: string;
1492
+ expiresAt: string;
1234
1493
  }>;
1235
- /** Remove one field. */
1236
- removeSecretField(args: {
1237
- scope: SecretScope;
1238
- scopeId: string;
1239
- secretId: string;
1240
- fieldKey: string;
1241
- }): Promise<void>;
1242
- /** Update secret-level metadata (name/description/tags/category). */
1243
- updateSecretMetadata(args: {
1244
- scope: SecretScope;
1245
- scopeId: string;
1246
- secretId: string;
1247
- secretName?: string;
1248
- description?: string;
1249
- tags?: string[];
1250
- category?: SecretCategory;
1251
- reason?: string;
1252
- }): Promise<SecretAggregate>;
1253
- /** List metadata for secrets in a scope. Optional filters route through the byFacet GSI. */
1254
- listSecrets(args: {
1255
- scope: SecretScope;
1256
- scopeId: string;
1257
- category?: SecretCategory;
1258
- tag?: string;
1259
- fieldKey?: string;
1260
- }): Promise<SecretMetadata[]>;
1261
- /** Bounded changelog read — metadata-only audit entries. */
1262
- getSecretHistory(args: {
1263
- scope: SecretScope;
1264
- scopeId: string;
1265
- secretId: string;
1266
- limit?: number;
1267
- cursor?: string;
1268
- }): Promise<{
1269
- entries: ChangelogEntry[];
1270
- nextCursor?: string;
1494
+ }
1495
+ //# sourceMappingURL=connect-credentials.d.ts.map
1496
+ //#endregion
1497
+ //#region src/domains/database.d.ts
1498
+ declare class DatabaseApi extends ApiBase {
1499
+ registerDatabaseCredentials(): Promise<{
1500
+ connectionString: string;
1501
+ username: string;
1502
+ password: string;
1503
+ databases: string[];
1271
1504
  }>;
1272
- /** Delete a secret (and all its field rows + tag rows + changelog rows). */
1273
- deleteSecret(args: {
1274
- scope: SecretScope;
1275
- scopeId: string;
1276
- secretId: string;
1505
+ reportDatabaseAudit(entry: {
1506
+ database: string;
1507
+ collection: string;
1508
+ operation: string;
1509
+ summary?: string;
1277
1510
  }): Promise<void>;
1278
- /** Enumerate scopes (org/team/project/agent) this agent can access. */
1279
- listSecretScopes(): Promise<ScopeInfo[]>;
1511
+ }
1512
+ //# sourceMappingURL=database.d.ts.map
1513
+ //#endregion
1514
+ //#region src/domains/identity.d.ts
1515
+ declare class IdentityApi extends ApiBase {
1280
1516
  /**
1281
1517
  * Returns the calling agent's own identity context — `{ agentId, tenantId }`
1282
1518
  * decoded server-side from the agent API token. Used by the
@@ -1319,59 +1555,35 @@ declare class AgentApiClient {
1319
1555
  }>;
1320
1556
  mergeIdentities(survivorId: string, args: {
1321
1557
  mergedId: string;
1322
- changedBy: {
1323
- type: string;
1324
- id: string;
1325
- name?: string;
1326
- };
1327
1558
  }): Promise<{
1328
1559
  ok: boolean;
1329
1560
  error?: string;
1330
1561
  }>;
1331
- unmergeIdentity(identityId: string, args: {
1332
- changedBy: {
1333
- type: string;
1334
- id: string;
1335
- name?: string;
1336
- };
1337
- }): Promise<{
1562
+ unmergeIdentity(identityId: string): Promise<{
1338
1563
  ok: boolean;
1339
1564
  error?: string;
1340
1565
  }>;
1341
1566
  addIdentityNote(identityId: string, args: {
1342
1567
  content: string;
1343
1568
  category?: string;
1344
- changedBy: {
1345
- type: string;
1346
- id: string;
1347
- name?: string;
1348
- };
1349
1569
  }): Promise<{
1350
1570
  noteId: string | null;
1351
1571
  }>;
1352
1572
  tagIdentity(identityId: string, args: {
1353
1573
  tag: string;
1354
1574
  action: "add" | "remove";
1355
- changedBy: {
1356
- type: string;
1357
- id: string;
1358
- name?: string;
1359
- };
1360
1575
  }): Promise<{
1361
1576
  ok: boolean;
1362
1577
  }>;
1363
1578
  getIdentityChangelog(identityId: string, args?: {
1364
1579
  limit?: number;
1580
+ cursor?: string;
1365
1581
  }): Promise<{
1366
1582
  entries: unknown[];
1583
+ cursor: string | null;
1367
1584
  }>;
1368
1585
  rollbackIdentity(identityId: string, args: {
1369
1586
  targetVersion: number;
1370
- changedBy: {
1371
- type: string;
1372
- id: string;
1373
- name?: string;
1374
- };
1375
1587
  }): Promise<{
1376
1588
  ok: boolean;
1377
1589
  entry?: unknown;
@@ -1410,7 +1622,7 @@ declare class AgentApiClient {
1410
1622
  verified: boolean;
1411
1623
  identityId?: string;
1412
1624
  /** Phase 2: how the confirm resolved — Scenario A vs B. */
1413
- action?: "merged" | "contact_verified";
1625
+ action?: "merged" | "contact_verified" | "already_confirmed";
1414
1626
  error?: string;
1415
1627
  }>;
1416
1628
  /**
@@ -1439,6 +1651,62 @@ declare class AgentApiClient {
1439
1651
  identityId: string | null;
1440
1652
  status: string;
1441
1653
  }>;
1654
+ }
1655
+ //# sourceMappingURL=identity.d.ts.map
1656
+ //#endregion
1657
+ //#region src/domains/images.d.ts
1658
+ declare class ImagesApi extends ApiBase {
1659
+ /**
1660
+ * Generate an image from a text prompt and get back a STABLE, public URL
1661
+ * (served from the agent-assets CDN — it does not expire). Embed the returned
1662
+ * `imageUrl` in a reply as markdown to show it to the user.
1663
+ *
1664
+ * ASYNC: `gpt-image-1` routinely runs 30–60s, which exceeds the API Gateway
1665
+ * 30s ceiling, so this enqueues a job (`POST /agent/images/generate` →
1666
+ * `jobId`) then polls (`GET /agent/images/{jobId}`) until it completes. The
1667
+ * worker's real failure message (e.g. an unsupported `size`) surfaces via the
1668
+ * job's `error` field.
1669
+ */
1670
+ generateImage(args: {
1671
+ prompt: string;
1672
+ model?: string;
1673
+ size?: string;
1674
+ quality?: string;
1675
+ }): Promise<{
1676
+ imageUrl: string;
1677
+ model: string;
1678
+ }>;
1679
+ }
1680
+ //# sourceMappingURL=images.d.ts.map
1681
+ //#endregion
1682
+ //#region src/domains/integrations.d.ts
1683
+ declare class IntegrationsApi extends ApiBase {
1684
+ listIntegrations(): Promise<IntegrationInstall[]>;
1685
+ getIntegrationConfig(integrationId: string): Promise<IntegrationConfigResult>;
1686
+ updateIntegrationConfig(integrationId: string, config: Record<string, unknown>): Promise<void>;
1687
+ installIntegration(integrationId: string, options?: {
1688
+ version?: string;
1689
+ config?: Record<string, unknown>;
1690
+ }): Promise<IntegrationInstall>;
1691
+ removeIntegration(integrationId: string): Promise<IntegrationInstall>;
1692
+ getOAuthUrl(provider: string, scopes?: string[]): Promise<{
1693
+ url: string;
1694
+ provider: string;
1695
+ expiresIn: number;
1696
+ }>;
1697
+ getOAuthStatus(provider: string): Promise<{
1698
+ provider: string;
1699
+ connected: boolean;
1700
+ config?: Record<string, string>;
1701
+ }>;
1702
+ getRegistry(): Promise<{
1703
+ integrations: RegistryEntry[];
1704
+ }>;
1705
+ }
1706
+ //# sourceMappingURL=integrations.d.ts.map
1707
+ //#endregion
1708
+ //#region src/domains/memory.d.ts
1709
+ declare class MemoryApi extends ApiBase {
1442
1710
  memorySearch(query: string, opts?: {
1443
1711
  limit?: number;
1444
1712
  topic?: string;
@@ -1486,8 +1754,21 @@ declare class AgentApiClient {
1486
1754
  messageCount: number;
1487
1755
  }>;
1488
1756
  memoryLoadContext(tier?: number, topicHint?: string): Promise<{
1757
+ tier: number;
1758
+ facts: {
1759
+ subject: string;
1760
+ predicate: string;
1761
+ object: string;
1762
+ since: string;
1763
+ }[];
1764
+ memories: {
1765
+ text: string;
1766
+ topic: string;
1767
+ subtopic: string;
1768
+ score: number;
1769
+ }[];
1770
+ tokenEstimate: number;
1489
1771
  formatted: string;
1490
- [key: string]: unknown;
1491
1772
  }>;
1492
1773
  memoryLookupEntity(subject: string): Promise<{
1493
1774
  subject: string;
@@ -1515,196 +1796,216 @@ declare class AgentApiClient {
1515
1796
  vectorCount: number;
1516
1797
  tripleCount: number;
1517
1798
  storageEstimateBytes: number;
1518
- lastIngestionAt?: string;
1519
- }>;
1520
- memoryLearn(args: {
1521
- text: string;
1522
- source?: string;
1523
- sourceType?: "file" | "url" | "inline";
1524
- metadata?: {
1525
- sessionId?: string;
1526
- channelId?: string;
1527
- userName?: string;
1528
- };
1529
- }): Promise<{
1530
- memoriesStored: number;
1531
- triplesStored: number;
1532
- chunks: number;
1533
- source?: string;
1534
- }>;
1535
- memoryBootstrapStatus(): Promise<{
1536
- synced: boolean;
1537
- syncedAt?: string;
1538
- sessionsBackfillSynced?: boolean;
1539
- sessionsBackfillSyncedAt?: string;
1540
- }>;
1541
- memoryBootstrapStatusMark(scope?: "files" | "sessions"): Promise<{
1542
- synced: true;
1543
- syncedAt: string;
1544
- }>;
1545
- sendSms(args: {
1546
- to: string;
1547
- body: string;
1548
- }): Promise<{
1549
- sent: boolean;
1550
- sid: string;
1551
- }>;
1552
- searchWeb(params: {
1553
- query: string;
1554
- count?: number;
1555
- offset?: number;
1556
- country?: string;
1557
- freshness?: string;
1558
- }): Promise<unknown>;
1559
- searchImages(params: {
1560
- query: string;
1561
- count?: number;
1562
- }): Promise<unknown>;
1563
- searchNews(params: {
1564
- query: string;
1565
- count?: number;
1566
- freshness?: string;
1567
- }): Promise<unknown>;
1568
- /** Search news across the selected provider's corpus. → POST /agent/news/search */
1569
- newsSearch(params: {
1570
- query: string;
1571
- provider?: NewsProvider;
1572
- source?: string;
1573
- from?: string;
1574
- to?: string;
1575
- language?: string;
1576
- category?: string;
1577
- limit?: number;
1578
- }): Promise<NewsResult>;
1579
- /** Top headlines for the selected provider. → POST /agent/news/headlines */
1580
- newsHeadlines(params?: {
1581
- provider?: NewsProvider;
1582
- category?: string;
1583
- source?: string;
1584
- language?: string;
1585
- limit?: number;
1586
- }): Promise<NewsResult>;
1587
- /**
1588
- * Semantic search across the agent's member scopes. Fan-out is gated
1589
- * server-side by `listScopes` set-inclusion (fail-closed). Pass
1590
- * `scopeType` + `scopeId` to narrow to one scope; a non-member scope
1591
- * yields empty results (never a cross-scope leak).
1592
- */
1593
- knowledgeSearch(query: string, opts?: {
1594
- limit?: number;
1595
- scopeType?: KnowledgeScopeType;
1596
- scopeId?: string;
1597
- }): Promise<KnowledgeSearchResult>;
1598
- /** Enumerate the scopes (org + teams + projects) this agent belongs to. */
1599
- listScopes(): Promise<{
1600
- scopes: KnowledgeScope[];
1601
- }>;
1602
- /** Read a scope's structured knowledge profile (after membership check). */
1603
- getScopeProfile(scopeType: KnowledgeScopeType, scopeId: string): Promise<KnowledgeProfile>;
1604
- /** List a scope's docs (the org-files corpus; mirrored to shared/<scope>/). */
1605
- listScopeDocs(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
1606
- limit?: number;
1607
- cursor?: string;
1799
+ lastIngestionAt?: string;
1800
+ }>;
1801
+ memoryLearn(args: {
1802
+ text: string;
1803
+ source?: string;
1804
+ sourceType?: "file" | "url" | "inline";
1805
+ metadata?: {
1806
+ sessionId?: string;
1807
+ channelId?: string;
1808
+ userName?: string;
1809
+ };
1608
1810
  }): Promise<{
1609
- files: KnowledgeDoc[];
1610
- nextCursor: string | null;
1811
+ memoriesStored: number;
1812
+ triplesStored: number;
1813
+ chunks: number;
1814
+ source?: string;
1815
+ }>;
1816
+ memoryBootstrapStatus(): Promise<{
1817
+ synced: boolean;
1818
+ syncedAt?: string;
1819
+ sessionsBackfillSynced?: boolean;
1820
+ sessionsBackfillSyncedAt?: string;
1821
+ }>;
1822
+ memoryBootstrapStatusMark(scope?: "files" | "sessions"): Promise<{
1823
+ synced: true;
1824
+ syncedAt: string;
1611
1825
  }>;
1826
+ }
1827
+ //# sourceMappingURL=memory.d.ts.map
1828
+ //#endregion
1829
+ //#region src/domains/secrets.d.ts
1830
+ declare class SecretsApi extends ApiBase {
1612
1831
  /**
1613
- * Read the full text of a scope doc. Resolves a presigned download URL
1614
- * from `services/org`, then fetches the bytes directly from S3 (the one
1615
- * legitimate raw fetch in a plugin same pattern as sync).
1832
+ * Mint a fresh AES-256 data key for a specific (secret, field) pair. The
1833
+ * encryption context is rebuilt server-side from `auth.tenantId` + the body
1834
+ * fields including `fieldKey`; the agent cannot forge context for a scope
1835
+ * or field it doesn't own. Legacy single-envelope secrets are migrated to
1836
+ * `field#value` rows by the data migration, so call with `fieldKey: "value"`
1837
+ * to reach them.
1616
1838
  */
1617
- readScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string): Promise<{
1618
- filePath: string;
1619
- text: string;
1620
- }>;
1839
+ generateSecretDataKey(args: {
1840
+ scope: SecretScope;
1841
+ scopeId: string;
1842
+ secretId: string;
1843
+ fieldKey: string;
1844
+ }): Promise<GeneratedDataKey>;
1621
1845
  /**
1622
- * Write (create or overwrite) a scope doc. Two-step presigned upload:
1623
- * `services/org` returns a signed URL plus `requiredHeaders` (author /
1624
- * authorKind / message as `x-amz-meta-*`) that MUST be sent verbatim on
1625
- * the PUT, alongside the same `Content-Type` that was signed. Author and
1626
- * authorKind are server-set from the agent token — never trusted here.
1846
+ * Unwrap a wrapped data key so the agent can decrypt the envelope locally.
1847
+ * `fieldKey` MUST match the value supplied when the data key was generated
1848
+ * (it's bound into KMS encryption context); mismatch fails with
1849
+ * `InvalidCiphertextException`.
1627
1850
  */
1628
- writeScopeDoc(scopeType: KnowledgeScopeType, scopeId: string, filePath: string, content: string, opts?: {
1629
- contentType?: string;
1630
- message?: string;
1851
+ decryptSecretDataKey(args: {
1852
+ scope: SecretScope;
1853
+ scopeId: string;
1854
+ secretId: string;
1855
+ fieldKey: string;
1856
+ dataKeyCiphertext: string;
1631
1857
  }): Promise<{
1632
- filePath: string;
1858
+ plaintextKey: string;
1633
1859
  }>;
1634
1860
  /**
1635
- * Open a change request against a scope's knowledge resource. For a doc
1636
- * create/update, `services/org` returns a presigned staging PUT; this method
1637
- * uploads the proposed `content` to it (echoing the same Content-Type that
1638
- * was signed), mirroring `writeScopeDoc`. The staged body is applied to the
1639
- * canonical doc — attributed to this agent — only when a reviewer approves.
1640
- */
1641
- proposeScopeChange(scopeType: KnowledgeScopeType, scopeId: string, input: ProposeScopeChangeInput): Promise<KnowledgeChangeRequest>;
1642
- /**
1643
- * List the agent's OWN change requests in a scope (filtered server-side to
1644
- * this agent as proposer). Pass `status` to narrow to open / approved / etc.
1861
+ * Create a new secret with one or more fields. Encrypted fields must arrive
1862
+ * pre-sealed (the agent has already obtained per-field data keys via
1863
+ * `generateSecretDataKey({ ..., fieldKey })` and AES-encrypted locally).
1864
+ * Plaintext fields ship the value inline.
1645
1865
  */
1646
- listScopeChangeRequests(scopeType: KnowledgeScopeType, scopeId: string, opts?: {
1647
- status?: ChangeRequestStatus;
1648
- limit?: number;
1649
- cursor?: string;
1866
+ createSecret(args: {
1867
+ scope: SecretScope;
1868
+ scopeId: string;
1869
+ secretId: string;
1870
+ secretName: string;
1871
+ category?: SecretCategory;
1872
+ description?: string;
1873
+ tags?: string[];
1874
+ fields: {
1875
+ key: string;
1876
+ format?: FieldFormat;
1877
+ sensitivity: FieldSensitivity;
1878
+ value?: string;
1879
+ envelope?: EncryptedEnvelopeV1;
1880
+ }[];
1881
+ reason?: string;
1882
+ }): Promise<SecretAggregate>;
1883
+ /** Fetch the secret aggregate plus per-field encrypted envelopes. */
1884
+ getSecret(args: {
1885
+ scope: SecretScope;
1886
+ scopeId: string;
1887
+ secretId: string;
1650
1888
  }): Promise<{
1651
- changeRequests: KnowledgeChangeRequest[];
1652
- nextCursor: string | null;
1889
+ aggregate: SecretAggregate;
1890
+ envelopes: FieldEnvelope[];
1653
1891
  }>;
1654
- registerDatabaseCredentials(): Promise<{
1655
- connectionString: string;
1656
- username: string;
1657
- password: string;
1658
- databases: string[];
1892
+ /** Fetch one field. Plaintext: value inline. Encrypted: envelope. */
1893
+ getSecretField(args: {
1894
+ scope: SecretScope;
1895
+ scopeId: string;
1896
+ secretId: string;
1897
+ fieldKey: string;
1898
+ }): Promise<{
1899
+ key: string;
1900
+ sensitivity: FieldSensitivity;
1901
+ format?: FieldFormat;
1902
+ value?: string;
1903
+ envelope?: EncryptedEnvelopeV1;
1904
+ rotatedAt?: string;
1905
+ createdAt: string;
1906
+ updatedAt: string;
1659
1907
  }>;
1660
- reportDatabaseAudit(entry: {
1661
- database: string;
1662
- collection: string;
1663
- operation: string;
1664
- summary?: string;
1908
+ /** Add OR rotate one field. */
1909
+ setSecretField(args: {
1910
+ scope: SecretScope;
1911
+ scopeId: string;
1912
+ secretId: string;
1913
+ fieldKey: string;
1914
+ sensitivity: FieldSensitivity;
1915
+ format?: FieldFormat;
1916
+ value?: string;
1917
+ envelope?: EncryptedEnvelopeV1;
1918
+ reason?: string;
1919
+ }): Promise<{
1920
+ fieldKey: string;
1921
+ rotated: boolean;
1922
+ }>;
1923
+ /** Remove one field. */
1924
+ removeSecretField(args: {
1925
+ scope: SecretScope;
1926
+ scopeId: string;
1927
+ secretId: string;
1928
+ fieldKey: string;
1665
1929
  }): Promise<void>;
1666
- requestBrowserTakeover(args: {
1667
- instructions: string;
1668
- url?: string;
1669
- conversationId?: string;
1930
+ /** Update secret-level metadata (name/description/tags/category). */
1931
+ updateSecretMetadata(args: {
1932
+ scope: SecretScope;
1933
+ scopeId: string;
1934
+ secretId: string;
1935
+ secretName?: string;
1936
+ description?: string;
1937
+ tags?: string[];
1938
+ category?: SecretCategory;
1939
+ reason?: string;
1940
+ }): Promise<SecretAggregate>;
1941
+ /** List metadata for secrets in a scope. Optional filters route through the byFacet GSI. */
1942
+ listSecrets(args: {
1943
+ scope: SecretScope;
1944
+ scopeId: string;
1945
+ category?: SecretCategory;
1946
+ tag?: string;
1947
+ fieldKey?: string;
1948
+ }): Promise<SecretMetadata[]>;
1949
+ /** Bounded changelog read — metadata-only audit entries. */
1950
+ getSecretHistory(args: {
1951
+ scope: SecretScope;
1952
+ scopeId: string;
1953
+ secretId: string;
1954
+ limit?: number;
1955
+ cursor?: string;
1670
1956
  }): Promise<{
1671
- sessionId: string;
1672
- status: string;
1957
+ entries: ChangelogEntry[];
1958
+ nextCursor?: string;
1673
1959
  }>;
1674
- getRemoteSession(sessionId: string): Promise<RemoteSessionInfo>;
1675
- completeRemoteSession(sessionId: string): Promise<{
1960
+ /** Delete a secret (and all its field rows + tag rows + changelog rows). */
1961
+ deleteSecret(args: {
1962
+ scope: SecretScope;
1963
+ scopeId: string;
1964
+ secretId: string;
1965
+ }): Promise<void>;
1966
+ /** Enumerate scopes (org/team/project/agent) this agent can access. */
1967
+ listSecretScopes(): Promise<ScopeInfo[]>;
1968
+ }
1969
+ //# sourceMappingURL=secrets.d.ts.map
1970
+ //#endregion
1971
+ //#region src/domains/teams.d.ts
1972
+ declare class TeamsApi extends ApiBase {
1973
+ getTeamsCredentials(): Promise<{
1974
+ agentId: string;
1975
+ tenantId: string;
1976
+ azureAppId: string;
1977
+ azureBotId: string;
1978
+ azureClientSecret: string;
1979
+ botDisplayName?: string;
1980
+ teamsTenantId?: string;
1981
+ serviceUrl?: string;
1982
+ }>;
1983
+ sendTeamsMessage(data: {
1984
+ conversationId: string;
1985
+ text?: string;
1986
+ adaptiveCard?: Record<string, unknown>;
1987
+ }): Promise<{
1676
1988
  ok: boolean;
1989
+ activityId: string;
1677
1990
  }>;
1678
- /**
1679
- * Issue a request that returns the raw `Response` (no JSON parsing, no
1680
- * forced Content-Type). The caller sets `Content-Type`/`Accept` on `headers`
1681
- * and reads the body itself (`arrayBuffer()` / `json()`).
1682
- *
1683
- * A single retry fires only on the same transient statuses `request()`
1684
- * retries (authorizer-timeout 500 + LB 502/503/504) and transient network
1685
- * errors — before the route handler runs — so re-issuing a POST does not
1686
- * risk a duplicate side effect. Voice TTS/STT are effectively idempotent
1687
- * (re-synthesize / re-transcribe) and meter server-side keyed on the
1688
- * gateway requestId, so a retried transcription doesn't double-bill.
1689
- */
1690
- private rawFetch;
1691
- /**
1692
- * Text-to-speech. Returns raw PCM audio bytes plus their framing — the
1693
- * voice service defaults to 24 kHz / mono / 16-bit. Wrap in a WAV container
1694
- * to produce a playable file. Metered per character against the tenant
1695
- * credit pool server-side; TTS completes regardless of metering outcome.
1696
- */
1697
- tts(args: VoiceTtsArgs): Promise<VoiceTtsResult>;
1698
- /**
1699
- * Speech-to-text. Accepts raw linear16 (16-bit LE) mono PCM — NOT a WAV or
1700
- * other container (the endpoint transcribes with a fixed linear16 encoding,
1701
- * so a container header would be transcribed as noise). Strip any WAV header
1702
- * and pass `sampleRate` from it before calling. Metered by transcribed
1703
- * duration against the tenant credit pool server-side.
1704
- */
1705
- stt(args: VoiceSttArgs): Promise<VoiceSttResult>;
1991
+ listTeamsChannels(): Promise<{
1992
+ channels: {
1993
+ id: string;
1994
+ name: string;
1995
+ description?: string;
1996
+ }[];
1997
+ }>;
1998
+ }
1999
+ //# sourceMappingURL=teams.d.ts.map
2000
+
2001
+ //#endregion
2002
+ //#region src/index.d.ts
2003
+ interface AgentApiClient extends SyncApi, IntegrationsApi, WorkspaceApi, ConnectCredentialsApi, TeamsApi, ChatApi, SecretsApi, IdentityApi, MemoryApi, SearchApi, KnowledgeApi, DatabaseApi, MobileApi, RemoteApi, SelfApi, VoiceApi, ImagesApi, WebhooksApi {}
2004
+ declare class AgentApiClient extends ApiBase {
2005
+ constructor(config: AgentApiClientConfig);
1706
2006
  }
1707
2007
  //# sourceMappingURL=index.d.ts.map
2008
+
1708
2009
  //#endregion
1709
2010
  //#endregion
1710
2011
  //#region src/sync-engine.d.ts
@@ -1943,6 +2244,25 @@ interface RetryOptions {
1943
2244
  declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
1944
2245
  //# sourceMappingURL=retry.d.ts.map
1945
2246
  //#endregion
2247
+ //#region src/path-contract.d.ts
2248
+ /**
2249
+ * Canonical path contract for the private workspace sync data plane.
2250
+ *
2251
+ * Paths received from manifests, relays, CLI arguments, and watcher events
2252
+ * are identifiers relative to the configured workspace. Keep validation in
2253
+ * one place so a malformed remote path can never become an arbitrary local
2254
+ * read, write, or delete.
2255
+ */
2256
+ declare function validatePrivateRelativePath(relativePath: string): string;
2257
+ declare function resolvePrivateWorkspacePath(workspacePath: string, relativePath: string): string;
2258
+ /**
2259
+ * Reject an existing symlink in any path component. Lexical containment alone
2260
+ * is insufficient: `workspace/link/file` can escape when `link` points out of
2261
+ * the workspace. This check covers reads, writes, and parent-directory walks.
2262
+ */
2263
+ declare function assertNoSymlinkTraversal(workspacePath: string, relativePath: string): Promise<string>;
2264
+ //# sourceMappingURL=path-contract.d.ts.map
2265
+ //#endregion
1946
2266
  //#region src/shared-sync.d.ts
1947
2267
  interface SharedScope {
1948
2268
  scopeType: "team" | "project" | "org";
@@ -1968,5 +2288,5 @@ interface SharedSyncEngine {
1968
2288
  }
1969
2289
  declare function createSharedSyncEngine(config: SharedSyncConfig, log: PluginLogger): SharedSyncEngine;
1970
2290
  //#endregion
1971
- export { DEFAULT_IGNORES, type DownloadResult, type IgnoreRules, type LocalManifest, type ManifestDiff, type ManifestEntry, type RemoteManifest, type RetryOptions, type SharedScope, type SharedSyncConfig, type SharedSyncEngine, type SyncEngine, type SyncPluginConfig, type SyncResult, type UploadResult, type WatcherOptions, computeFileHash, createSharedSyncEngine, createSyncEngine, diffManifests, downloadFiles, filterIgnored, loadIgnorePatterns, plugin, readManifest, removeManifestEntry, shouldIgnore, shouldIgnoreDir, startWatcher, updateManifestEntry, uploadFiles, withRetry, writeManifest };
2291
+ export { DEFAULT_IGNORES, type DownloadResult, type IgnoreRules, type LocalManifest, type ManifestDiff, type ManifestEntry, type RemoteManifest, type RetryOptions, type SharedScope, type SharedSyncConfig, type SharedSyncEngine, type SyncEngine, type SyncPluginConfig, type SyncResult, type UploadResult, type WatcherOptions, assertNoSymlinkTraversal, computeFileHash, createSharedSyncEngine, createSyncEngine, diffManifests, downloadFiles, filterIgnored, loadIgnorePatterns, plugin, readManifest, removeManifestEntry, resolvePrivateWorkspacePath, shouldIgnore, shouldIgnoreDir, startWatcher, updateManifestEntry, uploadFiles, validatePrivateRelativePath, withRetry, writeManifest };
1972
2292
  //# sourceMappingURL=index.d.cts.map