@opengeni/api-router 0.12.12 → 0.14.3

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.
Files changed (87) hide show
  1. package/dist/app.d.ts +18 -38
  2. package/dist/app.js +3 -1
  3. package/dist/auth/managed-auth.d.ts +35 -0
  4. package/dist/{chunk-5TULDPWX.js → chunk-36PW33ND.js} +4111 -1277
  5. package/dist/chunk-36PW33ND.js.map +1 -0
  6. package/dist/codex-redemption-security.d.ts +15 -0
  7. package/dist/github-access.d.ts +12 -0
  8. package/dist/github-browser-flow.d.ts +14 -0
  9. package/dist/http/auth.d.ts +3 -0
  10. package/dist/http/common.d.ts +3 -0
  11. package/dist/http/sse.d.ts +70 -0
  12. package/dist/index.d.ts +11 -13
  13. package/dist/index.js +1 -1
  14. package/dist/integrations/google-drive.d.ts +76 -0
  15. package/dist/integrations/oauth-client.d.ts +42 -0
  16. package/dist/integrations/provider-domain.d.ts +7 -0
  17. package/dist/integrations/slack-bot.d.ts +343 -0
  18. package/dist/mcp/documents.d.ts +8 -0
  19. package/dist/mcp/files.d.ts +5 -0
  20. package/dist/mcp/server.d.ts +107 -0
  21. package/dist/mcp/session-view.d.ts +191 -0
  22. package/dist/mcp/toolspace.d.ts +61 -0
  23. package/dist/model-catalog.d.ts +39 -0
  24. package/dist/observability.d.ts +3 -0
  25. package/dist/routes/api-keys.d.ts +3 -0
  26. package/dist/routes/billing.d.ts +16 -0
  27. package/dist/routes/capabilities.d.ts +3 -0
  28. package/dist/routes/catalog-assets.d.ts +5 -0
  29. package/dist/routes/codex.d.ts +10 -0
  30. package/dist/routes/connections.d.ts +3 -0
  31. package/dist/routes/documents.d.ts +3 -0
  32. package/dist/routes/enrollments.d.ts +3 -0
  33. package/dist/routes/environments.d.ts +5 -0
  34. package/dist/routes/files.d.ts +4 -0
  35. package/dist/routes/github.d.ts +3 -0
  36. package/dist/routes/insights.d.ts +3 -0
  37. package/dist/routes/install.d.ts +5 -0
  38. package/dist/routes/machines.d.ts +3 -0
  39. package/dist/routes/packs.d.ts +3 -0
  40. package/dist/routes/preference-registry.d.ts +5 -0
  41. package/dist/routes/rigs.d.ts +3 -0
  42. package/dist/routes/scheduled-tasks.d.ts +3 -0
  43. package/dist/routes/sessions.d.ts +15 -0
  44. package/dist/routes/social.d.ts +3 -0
  45. package/dist/routes/transcriptions.d.ts +3 -0
  46. package/dist/routes/workspace-capture.d.ts +59 -0
  47. package/dist/routes/workspace-instruction-policies.d.ts +3 -0
  48. package/dist/routes/workspace-state.d.ts +3 -0
  49. package/dist/routes/workspaces.d.ts +5 -0
  50. package/dist/sandbox/access.d.ts +21 -0
  51. package/dist/sandbox/auth-callout.d.ts +30 -0
  52. package/dist/sandbox/channel-a.d.ts +37 -0
  53. package/dist/sandbox/enrollment.d.ts +120 -0
  54. package/dist/sandbox/machines.d.ts +29 -0
  55. package/dist/sandbox/metrics-ingestion.d.ts +128 -0
  56. package/dist/sandbox/rematerialize.d.ts +24 -0
  57. package/dist/sandbox/viewer.d.ts +251 -0
  58. package/dist/transcription/providers/azure-openai.d.ts +9 -0
  59. package/dist/transcription/providers/codex-subscription.d.ts +9 -0
  60. package/dist/transcription/providers/openai.d.ts +9 -0
  61. package/dist/transcription/service.d.ts +10 -0
  62. package/dist/workspace-state-projection.d.ts +16 -0
  63. package/package.json +13 -13
  64. package/src/app.ts +67 -5
  65. package/src/integrations/google-drive.ts +869 -0
  66. package/src/integrations/oauth-client.ts +41 -6
  67. package/src/integrations/slack-bot.ts +756 -26
  68. package/src/mcp/server.ts +200 -3
  69. package/src/mcp/session-view.ts +1 -0
  70. package/src/mcp/toolspace.ts +17 -9
  71. package/src/routes/connections.ts +137 -7
  72. package/src/routes/documents.ts +13 -2
  73. package/src/routes/github.ts +7 -5
  74. package/src/routes/insights.ts +30 -0
  75. package/src/routes/preference-registry.ts +482 -0
  76. package/src/routes/sessions.ts +10 -0
  77. package/src/routes/transcriptions.ts +155 -0
  78. package/src/routes/workspace-state.ts +61 -0
  79. package/src/sandbox/channel-a.ts +2 -0
  80. package/src/sandbox/rematerialize.ts +111 -4
  81. package/src/sandbox/viewer.ts +29 -12
  82. package/src/transcription/providers/azure-openai.ts +45 -0
  83. package/src/transcription/providers/codex-subscription.ts +100 -0
  84. package/src/transcription/providers/openai.ts +93 -0
  85. package/src/transcription/service.ts +121 -0
  86. package/src/workspace-state-projection.ts +244 -0
  87. package/dist/chunk-5TULDPWX.js.map +0 -1
@@ -0,0 +1,15 @@
1
+ type CodexRedemptionConfirmationClaims = {
2
+ version: 1;
3
+ attemptId: string;
4
+ workspaceId: string;
5
+ credentialId: string;
6
+ creditId: string;
7
+ subjectId: string;
8
+ browserSessionHash: string;
9
+ expiresAt: number;
10
+ };
11
+ export declare function hashCodexBrowserSession(sessionId: string): Promise<string>;
12
+ /** Five-minute, session-bound, HMAC-confirmed browser mutation token. */
13
+ export declare function signCodexRedemptionConfirmation(secret: string, claims: CodexRedemptionConfirmationClaims): Promise<string>;
14
+ export declare function verifyCodexRedemptionConfirmation(secret: string, token: string, now?: number): Promise<CodexRedemptionConfirmationClaims | null>;
15
+ export type { CodexRedemptionConfirmationClaims };
@@ -0,0 +1,12 @@
1
+ import type { GitHubBindingStatus, GitHubInstallationBinding, GitHubRepository } from "@opengeni/contracts";
2
+ import { listGitHubInstallationAccessForWorkspace } from "@opengeni/db";
3
+ import type { ApiRouteDeps } from "@opengeni/core";
4
+ export declare function listWorkspaceGitHubInstallationBindings(deps: ApiRouteDeps, workspaceId: string): Promise<GitHubInstallationBinding[]>;
5
+ export declare function githubBindingStatus(configured: boolean, installations: GitHubInstallationBinding[]): GitHubBindingStatus;
6
+ export type LiveGitHubInstallation = {
7
+ installationId: number;
8
+ accountId: number;
9
+ suspended: boolean;
10
+ };
11
+ export declare function githubInstallationBindingLifecycle(stored: Awaited<ReturnType<typeof listGitHubInstallationAccessForWorkspace>>[number], liveById: Map<number, LiveGitHubInstallation | null>, installationId: number, lifecycleVerified: boolean): GitHubInstallationBinding["lifecycle"];
12
+ export declare function listWorkspaceGitHubRepositories(deps: ApiRouteDeps, workspaceId: string): Promise<GitHubRepository[]>;
@@ -0,0 +1,14 @@
1
+ import type { Settings } from "@opengeni/config";
2
+ import type { AccessGrant } from "@opengeni/contracts";
3
+ import type { GitHubSignedStatePayload } from "@opengeni/github";
4
+ /**
5
+ * Bounded configured-token browser handoff. These signed claims preserve only
6
+ * the exact OpenGeni github:manage grant across GitHub redirects; the callback
7
+ * independently proves current GitHub personal/organization ownership. This
8
+ * state must never be interpreted as GitHub installation authority.
9
+ */
10
+ export declare const githubBrowserGrantMaxAgeSeconds: number;
11
+ export declare function githubBrowserGrantClaims(settings: Pick<Settings, "productAccessMode">, grant: AccessGrant, nowSeconds?: number): Record<string, unknown>;
12
+ export declare function continuedGitHubBrowserGrantClaims(payload: GitHubSignedStatePayload): Record<string, unknown>;
13
+ export declare function githubBrowserGrantFromState(settings: Pick<Settings, "productAccessMode">, payload: GitHubSignedStatePayload, workspaceId: string, nowSeconds?: number): AccessGrant | null;
14
+ export declare function githubBrowserBaseUrl(settings: Pick<Settings, "githubAppManifestBaseUrl" | "publicBaseUrl">, requestOrigin?: string | null): string;
@@ -0,0 +1,3 @@
1
+ import type { Settings } from "@opengeni/config";
2
+ import type { MiddlewareHandler } from "hono";
3
+ export declare function requireAccessKey(settings: Settings): MiddlewareHandler;
@@ -0,0 +1,3 @@
1
+ import { type Database } from "@opengeni/db";
2
+ export declare function boundedLimit(raw: string | undefined): number;
3
+ export declare function assertSessionExists(db: Database, workspaceId: string, sessionId: string): Promise<void>;
@@ -0,0 +1,70 @@
1
+ import type { SessionEvent } from "@opengeni/contracts";
2
+ import { type Database } from "@opengeni/db";
3
+ import { type EventBus } from "@opengeni/events";
4
+ import type { Observability } from "@opengeni/observability";
5
+ export declare const SSE_QUEUED_FRAME_MAX_COUNT = 1;
6
+ export declare const SSE_WRITE_STALL_TIMEOUT_MS = 30000;
7
+ export type SseDeliveryBoundObservation = {
8
+ reason: "desired_size_non_positive" | "stall_timeout" | "frame_too_large";
9
+ desiredSize: number | null;
10
+ queuedFrames: number;
11
+ queuedBytes: number;
12
+ };
13
+ export type ByteBoundedSseStreamOptions = {
14
+ maxQueuedBytes?: number;
15
+ stallTimeoutMs?: number;
16
+ onStop?: () => void;
17
+ onObservation?: (observation: SseDeliveryBoundObservation) => void;
18
+ };
19
+ export type ByteBoundedSseStream = {
20
+ stream: ReadableStream<Uint8Array>;
21
+ write: (frame: string) => Promise<boolean>;
22
+ close: () => void;
23
+ fail: (error: unknown) => void;
24
+ stopped: () => boolean;
25
+ };
26
+ /**
27
+ * A byte-counted SSE body. `ReadableStreamDefaultController.enqueue()` does not
28
+ * itself wait for a slow HTTP consumer, so replaying bounded frames without
29
+ * checking `desiredSize` can still accumulate an unbounded server-side queue.
30
+ *
31
+ * One writer is expected per stream. The Web Streams queue holds at most one
32
+ * complete frame, and that frame must fit inside the byte cap. A second write
33
+ * waits for consumer pull only for a bounded interval; cancellation or a stalled
34
+ * reader wakes it and terminates upstream delivery before another durable page is
35
+ * read. One frame is deliberate: it makes both queued-frame count and queued
36
+ * bytes independently bounded instead of relying on byte accounting alone.
37
+ */
38
+ export declare function createByteBoundedSseStream(options?: ByteBoundedSseStreamOptions): ByteBoundedSseStream;
39
+ export type LatestWinsDelivery<T extends {
40
+ sequence: number;
41
+ }> = {
42
+ publish: (events: readonly T[]) => void;
43
+ stop: () => void;
44
+ whenIdle: () => Promise<void>;
45
+ pendingSequence: () => number | null;
46
+ };
47
+ /**
48
+ * Keep at most one live notification while an earlier notification is being
49
+ * delivered. The notification is only a cursor target: `send` gap-fills every
50
+ * missing durable event from Postgres, so replacing N intermediate notices with
51
+ * their newest sequence loses no event and prevents backpressure from migrating
52
+ * into the NATS subscription queue.
53
+ */
54
+ export declare function createLatestWinsDelivery<T extends {
55
+ sequence: number;
56
+ }>(send: (event: T) => Promise<void>, onError: (error: unknown) => void): LatestWinsDelivery<T>;
57
+ export declare function sseSessionStream(db: Database, bus: EventBus, workspaceId: string, sessionId: string, after: number, signal: AbortSignal, options?: SessionSseDeliveryOptions): Promise<Response>;
58
+ export declare function replaySessionEvents(loadPage: (after: number, limit: number) => Promise<SessionEvent[]>, send: (event: SessionEvent) => Promise<void>, after: number, pageSize?: number): Promise<void>;
59
+ export declare function sseWorkspaceControlStream(db: Database, bus: EventBus, workspaceId: string, after: number, signal: AbortSignal, options?: SseDeliveryOptions): Promise<Response>;
60
+ export type SseDeliveryOptions = {
61
+ maxQueuedBytes?: number;
62
+ stallTimeoutMs?: number;
63
+ observability?: Observability | undefined;
64
+ onObservation?: ((observation: SseDeliveryBoundObservation) => void) | undefined;
65
+ };
66
+ export type SessionSseDeliveryOptions = SseDeliveryOptions & {
67
+ /** Host ACL re-check, run even while the event stream is otherwise idle. */
68
+ reauthorize?: (() => Promise<void>) | undefined;
69
+ reauthorizeAfterMs?: number | undefined;
70
+ };
package/dist/index.d.ts CHANGED
@@ -1,20 +1,18 @@
1
- import { getSettings } from '@opengeni/config';
2
- import { ScheduledTaskOverlapPolicy, ScheduledTaskScheduleSpec } from '@opengeni/contracts';
3
- import { Database } from '@opengeni/db';
4
- import { ScheduleOverlapPolicy, ScheduleSpec } from '@temporalio/client';
5
- import { SessionWorkflowClient, DocumentIndexClient } from '@opengeni/core';
6
-
7
- declare function createTemporalWorkflowClient(settings: ReturnType<typeof getSettings>, db: Database): Promise<{
1
+ import { getSettings } from "@opengeni/config";
2
+ import type { ScheduledTaskOverlapPolicy, ScheduledTaskScheduleSpec } from "@opengeni/contracts";
3
+ import { type Database } from "@opengeni/db";
4
+ import { ScheduleOverlapPolicy } from "@temporalio/client";
5
+ import type { ScheduleSpec } from "@temporalio/client";
6
+ import { type DocumentIndexClient, type SessionWorkflowClient } from "./app";
7
+ export declare function createTemporalWorkflowClient(settings: ReturnType<typeof getSettings>, db: Database): Promise<{
8
8
  client: SessionWorkflowClient;
9
9
  documentIndexer: DocumentIndexClient;
10
10
  close: () => Promise<void>;
11
11
  }>;
12
- declare function startApi(): Promise<{
12
+ export declare function startApi(): Promise<{
13
13
  server: Bun.Server<undefined>;
14
14
  close: () => Promise<void>;
15
15
  }>;
16
- declare function temporalOverlapPolicy(policy: ScheduledTaskOverlapPolicy): ScheduleOverlapPolicy;
17
- declare function shouldCreateScheduleAfterUpdateError(error: unknown): boolean;
18
- declare function temporalScheduleSpec(schedule: ScheduledTaskScheduleSpec): ScheduleSpec;
19
-
20
- export { createTemporalWorkflowClient, shouldCreateScheduleAfterUpdateError, startApi, temporalOverlapPolicy, temporalScheduleSpec };
16
+ export declare function temporalOverlapPolicy(policy: ScheduledTaskOverlapPolicy): ScheduleOverlapPolicy;
17
+ export declare function shouldCreateScheduleAfterUpdateError(error: unknown): boolean;
18
+ export declare function temporalScheduleSpec(schedule: ScheduledTaskScheduleSpec): ScheduleSpec;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "./chunk-5TULDPWX.js";
3
+ } from "./chunk-36PW33ND.js";
4
4
 
5
5
  // src/index.ts
6
6
  import {
@@ -0,0 +1,76 @@
1
+ import { GoogleDriveOAuthStartResponse, type GoogleDriveOAuthStartRequest } from "@opengeni/contracts/google-drive";
2
+ import type { ApiRouteDeps } from "@opengeni/core";
3
+ export declare function startGoogleDriveOAuth(deps: ApiRouteDeps, input: {
4
+ accountId: string;
5
+ workspaceId: string;
6
+ subjectId: string;
7
+ requestUrl: string;
8
+ payload: GoogleDriveOAuthStartRequest;
9
+ }): Promise<GoogleDriveOAuthStartResponse>;
10
+ export declare function completeGoogleDriveOAuthCallback(deps: ApiRouteDeps, input: {
11
+ code?: string | undefined;
12
+ state?: string | undefined;
13
+ error?: string | undefined;
14
+ requestUrl: string;
15
+ }): Promise<{
16
+ redirectTo: string;
17
+ }>;
18
+ export declare function browseGoogleDrive(deps: ApiRouteDeps, input: {
19
+ workspaceId: string;
20
+ subjectId: string;
21
+ connectionId: string;
22
+ parentId: string;
23
+ pageToken?: string | undefined;
24
+ }): Promise<{
25
+ connection: {
26
+ id: string;
27
+ accountId: string;
28
+ workspaceId: string;
29
+ subjectId: string | null;
30
+ providerDomain: string;
31
+ kind: "api_key" | "app_install" | "delegated" | "oauth2";
32
+ status: "active" | "error" | "needs_reauth" | "revoked";
33
+ grantedScopes: string[];
34
+ expiresAt: string | null;
35
+ lastRefreshAt: string | null;
36
+ lastUsedAt: string | null;
37
+ lastError: string | null;
38
+ version: number;
39
+ verifiedInstallAt?: string | null | undefined;
40
+ verifiedInstallVersion?: number | null | undefined;
41
+ metadata: Record<string, unknown>;
42
+ createdBySubjectId: string | null;
43
+ updatedBySubjectId: string | null;
44
+ createdAt: string;
45
+ updatedAt: string;
46
+ };
47
+ parentId: string;
48
+ current: {
49
+ id: string;
50
+ name: string;
51
+ mimeType: string;
52
+ kind: "file" | "folder";
53
+ driveId: string | null;
54
+ modifiedTime: string | null;
55
+ size: string | null;
56
+ webViewLink: string | null;
57
+ } | null;
58
+ items: {
59
+ id: string;
60
+ name: string;
61
+ mimeType: string;
62
+ kind: "file" | "folder";
63
+ driveId: string | null;
64
+ modifiedTime: string | null;
65
+ size: string | null;
66
+ webViewLink: string | null;
67
+ }[];
68
+ nextPageToken: string | null;
69
+ incompleteSearch: boolean;
70
+ }>;
71
+ export declare function saveGoogleDriveSource(deps: ApiRouteDeps, input: {
72
+ workspaceId: string;
73
+ subjectId: string;
74
+ connectionId: string;
75
+ payload: unknown;
76
+ }): Promise<import("@opengeni/db").ConnectionMetadataWithVerification>;
@@ -0,0 +1,42 @@
1
+ import { type Settings } from "@opengeni/config";
2
+ import { OAuthStartResponse, type OAuthStartRequest } from "@opengeni/contracts";
3
+ import type { Observability } from "@opengeni/observability";
4
+ import { type Database } from "@opengeni/db";
5
+ export declare const oauthStateTtlMs: number;
6
+ export declare const OFFICIAL_SLACK_MCP_URL: "https://mcp.slack.com/mcp";
7
+ export { OAUTH_MAX_RESPONSE_BYTES } from "@opengeni/network";
8
+ type OAuthClientDeps = {
9
+ db: Database;
10
+ settings: Settings;
11
+ observability?: Observability | undefined;
12
+ };
13
+ export type OAuthStartContext = {
14
+ accountId: string;
15
+ workspaceId: string;
16
+ subjectId: string;
17
+ requestUrl: string;
18
+ payload: OAuthStartRequest;
19
+ };
20
+ export type OAuthCallbackResult = {
21
+ redirectTo: string;
22
+ };
23
+ type AuthorizationServerMetadata = {
24
+ issuer: string;
25
+ authorizationServer: string;
26
+ authorizationEndpoint: string;
27
+ tokenEndpoint: string;
28
+ registrationEndpoint?: string;
29
+ clientIdMetadataDocumentSupported: boolean;
30
+ tokenEndpointAuthMethodsSupported: string[];
31
+ codeChallengeMethodsSupported: string[];
32
+ raw: Record<string, unknown>;
33
+ };
34
+ export declare function startMcpOAuth(deps: OAuthClientDeps, context: OAuthStartContext): Promise<OAuthStartResponse>;
35
+ export declare function completeMcpOAuthCallback(deps: OAuthClientDeps, input: {
36
+ code?: string | undefined;
37
+ state?: string | undefined;
38
+ requestUrl: string;
39
+ }): Promise<OAuthCallbackResult>;
40
+ export declare function integrationBaseUrl(publicBaseUrl: string | undefined, requestUrl: string): string;
41
+ export declare function requireIntegrationsStateSecret(settings: Settings): string;
42
+ export declare function assertSlackAuthorizationServer(as: AuthorizationServerMetadata): void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Canonical form of a connection's providerDomain: trimmed, lowercased, no
3
+ * leading "www.". Rejects a value that canonicalizes to empty (whitespace-only,
4
+ * or a bare "www.") — `min(1)` validation passes such input, but an empty stored
5
+ * domain silently breaks the enable-time connectionRef domain match.
6
+ */
7
+ export declare function canonicalProviderDomain(value: string): string;
@@ -0,0 +1,343 @@
1
+ import { type Settings } from "@opengeni/config";
2
+ import { OPENGENI_SLACK_BOT_CREDENTIAL_LABEL, OPENGENI_SLACK_BOT_CREDENTIAL_ROLE, type AccessGrant, type ConnectionMetadata, type OpenGeniSlackBotConnectionMetadata } from "@opengeni/contracts";
3
+ import { type Database } from "@opengeni/db";
4
+ import { type FetchLike } from "@opengeni/network";
5
+ import { HTTPException } from "hono/http-exception";
6
+ type SlackPayload = Record<string, unknown> & {
7
+ ok?: unknown;
8
+ error?: unknown;
9
+ };
10
+ export type SlackFilesListPage = {
11
+ count: number;
12
+ page: number;
13
+ };
14
+ export type SlackFilesCursorContext = {
15
+ connectionId: string;
16
+ key: Uint8Array;
17
+ };
18
+ export type VerifiedOpenGeniSlackBot = {
19
+ grantedScopes: string[];
20
+ metadata: OpenGeniSlackBotConnectionMetadata;
21
+ };
22
+ export declare function exchangeOpenGeniSlackAuthorizationCode(input: {
23
+ code: string;
24
+ clientId: string;
25
+ clientSecret: string;
26
+ redirectUri: string;
27
+ }, fetchImpl?: FetchLike): Promise<string>;
28
+ export type SlackBotReceipt = {
29
+ credentialRole: typeof OPENGENI_SLACK_BOT_CREDENTIAL_ROLE;
30
+ credentialLabel: typeof OPENGENI_SLACK_BOT_CREDENTIAL_LABEL;
31
+ connectionId: string;
32
+ slackTeamId: string;
33
+ operation: SlackBotOperation;
34
+ operationId?: string;
35
+ clientMessageId?: string;
36
+ };
37
+ type SlackBotOperation = "channels.list" | "channel_history.read" | "thread_replies.read" | "users.list" | "files.list" | "file.info" | "file.content.read" | "message.post" | "message.delete";
38
+ type SlackBotContext = {
39
+ accountId: string;
40
+ workspaceId: string;
41
+ subjectId: string | null;
42
+ sessionId?: string | null;
43
+ scheduledTaskId?: string | null;
44
+ };
45
+ export declare class SlackBotProviderError extends Error {
46
+ readonly code: string;
47
+ constructor(code: string);
48
+ }
49
+ export type SlackBotCredentialVerificationFailureReason = "scope_mismatch" | "identity_mismatch";
50
+ export declare class SlackBotCredentialVerificationError extends HTTPException {
51
+ readonly failureReason: SlackBotCredentialVerificationFailureReason;
52
+ constructor(failureReason: SlackBotCredentialVerificationFailureReason, message: string);
53
+ }
54
+ /**
55
+ * Validates a write-only xoxb credential before it can enter encrypted storage.
56
+ * Slack does not expose the app's display_information name to this scope set;
57
+ * users.info provides the authoritative installed bot display name, while the
58
+ * documented manifest fixes the app name itself to the same exact value.
59
+ */
60
+ export declare function verifyOpenGeniSlackBotCredential(token: string, fetchImpl?: FetchLike, now?: Date): Promise<VerifiedOpenGeniSlackBot>;
61
+ export declare function resolveSlackBotConnectionForTool(input: {
62
+ db: Database;
63
+ grant: AccessGrant;
64
+ sessionId: string | null;
65
+ requestedConnectionId?: string;
66
+ }): Promise<{
67
+ connection: ConnectionMetadata;
68
+ metadata: OpenGeniSlackBotConnectionMetadata;
69
+ context: SlackBotContext;
70
+ }>;
71
+ export declare class OpenGeniSlackBotClient {
72
+ private readonly db;
73
+ private readonly settings;
74
+ private readonly connection;
75
+ private readonly metadata;
76
+ private readonly context;
77
+ private readonly fetchImpl;
78
+ private readonly resolveCredential;
79
+ constructor(db: Database, settings: Settings, connection: ConnectionMetadata, metadata: OpenGeniSlackBotConnectionMetadata, context: SlackBotContext, fetchImpl?: FetchLike);
80
+ listChannels(input?: {
81
+ limit?: number;
82
+ cursor?: string;
83
+ }): Promise<{
84
+ channels: {
85
+ id: string;
86
+ name: string;
87
+ isPrivate: boolean;
88
+ isMember: boolean;
89
+ isArchived: boolean;
90
+ topic: string;
91
+ purpose: string;
92
+ numMembers: number | null;
93
+ }[];
94
+ nextCursor: string | null;
95
+ } & {
96
+ receipt: SlackBotReceipt;
97
+ }>;
98
+ channelHistory(input: {
99
+ channelId: string;
100
+ limit?: number;
101
+ cursor?: string;
102
+ }): Promise<{
103
+ channel: {
104
+ id: string;
105
+ name: string;
106
+ isPrivate: boolean;
107
+ isMember: boolean;
108
+ isArchived: boolean;
109
+ topic: string;
110
+ purpose: string;
111
+ numMembers: number | null;
112
+ };
113
+ messages: {
114
+ timestamp: string;
115
+ userId: string;
116
+ botId: string;
117
+ threadTimestamp: string;
118
+ text: string;
119
+ files: {
120
+ id: string;
121
+ name: string;
122
+ title: string;
123
+ mimetype: string;
124
+ filetype: string;
125
+ mode: string;
126
+ size: number | null;
127
+ originatingHuddleId: string;
128
+ huddleTranscriptFileId: string;
129
+ }[];
130
+ }[];
131
+ nextCursor: string | null;
132
+ } & {
133
+ receipt: SlackBotReceipt;
134
+ }>;
135
+ threadReplies(input: {
136
+ channelId: string;
137
+ threadTimestamp: string;
138
+ limit?: number;
139
+ cursor?: string;
140
+ }): Promise<{
141
+ channel: {
142
+ id: string;
143
+ name: string;
144
+ isPrivate: boolean;
145
+ isMember: boolean;
146
+ isArchived: boolean;
147
+ topic: string;
148
+ purpose: string;
149
+ numMembers: number | null;
150
+ };
151
+ threadTimestamp: string;
152
+ messages: {
153
+ timestamp: string;
154
+ userId: string;
155
+ botId: string;
156
+ threadTimestamp: string;
157
+ text: string;
158
+ files: {
159
+ id: string;
160
+ name: string;
161
+ title: string;
162
+ mimetype: string;
163
+ filetype: string;
164
+ mode: string;
165
+ size: number | null;
166
+ originatingHuddleId: string;
167
+ huddleTranscriptFileId: string;
168
+ }[];
169
+ }[];
170
+ nextCursor: string | null;
171
+ } & {
172
+ receipt: SlackBotReceipt;
173
+ }>;
174
+ listUsers(input?: {
175
+ limit?: number;
176
+ cursor?: string;
177
+ }): Promise<{
178
+ users: {
179
+ id: string;
180
+ name: string;
181
+ displayName: string;
182
+ realName: string;
183
+ isBot: boolean;
184
+ deleted: boolean;
185
+ }[];
186
+ nextCursor: string | null;
187
+ } & {
188
+ receipt: SlackBotReceipt;
189
+ }>;
190
+ listFiles(input: {
191
+ channelId: string;
192
+ limit?: number;
193
+ cursor?: string;
194
+ }): Promise<{
195
+ channel: {
196
+ id: string;
197
+ name: string;
198
+ isPrivate: boolean;
199
+ isMember: boolean;
200
+ isArchived: boolean;
201
+ topic: string;
202
+ purpose: string;
203
+ numMembers: number | null;
204
+ };
205
+ files: {
206
+ id: string;
207
+ name: string;
208
+ title: string;
209
+ mimetype: string;
210
+ filetype: string;
211
+ mode: string;
212
+ size: number | null;
213
+ originatingHuddleId: string;
214
+ huddleTranscriptFileId: string;
215
+ }[];
216
+ nextCursor: string | null;
217
+ } & {
218
+ receipt: SlackBotReceipt;
219
+ }>;
220
+ fileInfo(input: {
221
+ channelId: string;
222
+ fileId: string;
223
+ parentFileId?: string;
224
+ }): Promise<{
225
+ channel: {
226
+ id: string;
227
+ name: string;
228
+ isPrivate: boolean;
229
+ isMember: boolean;
230
+ isArchived: boolean;
231
+ topic: string;
232
+ purpose: string;
233
+ numMembers: number | null;
234
+ };
235
+ file: {
236
+ id: string;
237
+ name: string;
238
+ title: string;
239
+ mimetype: string;
240
+ filetype: string;
241
+ mode: string;
242
+ size: number | null;
243
+ originatingHuddleId: string;
244
+ huddleTranscriptFileId: string;
245
+ };
246
+ } & {
247
+ receipt: SlackBotReceipt;
248
+ }>;
249
+ fileContent(input: {
250
+ channelId: string;
251
+ fileId: string;
252
+ parentFileId?: string;
253
+ offset?: number;
254
+ }): Promise<{
255
+ channel: {
256
+ id: string;
257
+ name: string;
258
+ isPrivate: boolean;
259
+ isMember: boolean;
260
+ isArchived: boolean;
261
+ topic: string;
262
+ purpose: string;
263
+ numMembers: number | null;
264
+ };
265
+ file: {
266
+ id: string;
267
+ name: string;
268
+ title: string;
269
+ mimetype: string;
270
+ filetype: string;
271
+ mode: string;
272
+ size: number | null;
273
+ originatingHuddleId: string;
274
+ huddleTranscriptFileId: string;
275
+ };
276
+ contentType: string;
277
+ offset: number;
278
+ content: string;
279
+ nextOffset: number | null;
280
+ truncated: boolean;
281
+ } & {
282
+ receipt: SlackBotReceipt;
283
+ }>;
284
+ postMessage(input: {
285
+ operationId: string;
286
+ channelId?: string;
287
+ userId?: string;
288
+ threadTimestamp?: string;
289
+ text: string;
290
+ }): Promise<{
291
+ channelId: string;
292
+ timestamp: string;
293
+ threadTimestamp: string | null;
294
+ receipt: SlackBotReceipt;
295
+ }>;
296
+ deleteMessage(input: {
297
+ operationId: string;
298
+ channelId: string;
299
+ timestamp: string;
300
+ }): Promise<{
301
+ channelId: string;
302
+ timestamp: string;
303
+ deleted: boolean;
304
+ receipt: SlackBotReceipt;
305
+ }>;
306
+ private slackMessageExists;
307
+ private requireMemberChannel;
308
+ private requireFileForChannel;
309
+ private readPrivateFileText;
310
+ private call;
311
+ private withAudit;
312
+ private headersFor;
313
+ private headersForDestination;
314
+ private fetchPrivateFile;
315
+ private fetchPrivateFileOnce;
316
+ private receipt;
317
+ private completedPostResult;
318
+ private completedDeleteResult;
319
+ private postRequestDigest;
320
+ private deleteRequestDigest;
321
+ private deletePrincipal;
322
+ private fileListPage;
323
+ private fileListCursor;
324
+ private recordAudit;
325
+ private auditMetadata;
326
+ }
327
+ export declare function createOpenGeniSlackBotClient(deps: {
328
+ db: Database;
329
+ settings: Settings;
330
+ slackFetch?: typeof fetch;
331
+ }, resolved: Awaited<ReturnType<typeof resolveSlackBotConnectionForTool>>): OpenGeniSlackBotClient;
332
+ export declare function resolveSlackFilesListPage(input: {
333
+ channelId: string;
334
+ limit?: number;
335
+ cursor?: string;
336
+ }, context: SlackFilesCursorContext): SlackFilesListPage;
337
+ export declare function createSlackFilesListCursor(input: {
338
+ channelId: string;
339
+ count: number;
340
+ page: number;
341
+ }, context: SlackFilesCursorContext): string;
342
+ export declare function nextSlackFilesListPage(payload: SlackPayload, requested: SlackFilesListPage, returnedFileCount: number): number | null;
343
+ export {};
@@ -0,0 +1,8 @@
1
+ import { type DocumentServices } from "@opengeni/documents";
2
+ import { type Database } from "@opengeni/db";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ export declare function buildDocumentsMcpServer(db: Database, accountId: string, workspaceId: string, documentServices: DocumentServices, options?: {
5
+ createdBySessionId?: string | undefined;
6
+ /** The human subject whose agent is making this retrieval request. */
7
+ viewerSubjectId?: string | undefined;
8
+ }): McpServer;
@@ -0,0 +1,5 @@
1
+ import type { AccessGrant } from "@opengeni/contracts";
2
+ import { type ApiRouteDeps } from "@opengeni/core";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ /** Dedicated file MCP surface. The broad `opengeni` server never registers it. */
5
+ export declare function buildFilesMcpServer(deps: ApiRouteDeps, grant: AccessGrant): McpServer;