@agent-native/core 0.16.1 → 0.16.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.
- package/README.md +21 -5
- package/dist/cli/code-agent-executor.js +1 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code.d.ts.map +1 -1
- package/dist/cli/code.js +29 -4
- package/dist/cli/code.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +9 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.js +2 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.js +1 -1
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +3 -1
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/AgentComposerFrame.d.ts +3 -1
- package/dist/client/composer/AgentComposerFrame.d.ts.map +1 -1
- package/dist/client/composer/AgentComposerFrame.js +3 -3
- package/dist/client/composer/AgentComposerFrame.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +2 -7
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts +4 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +3 -3
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +13 -3
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +16 -10
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +1 -1
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.js +9 -2
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
- package/dist/client/settings/BrowserSection.d.ts.map +1 -1
- package/dist/client/settings/BrowserSection.js +17 -3
- package/dist/client/settings/BrowserSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +5 -5
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +15 -2
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +99 -11
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.spec.js +12 -6
- package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
- package/dist/code-agents/background-controller.d.ts +39 -0
- package/dist/code-agents/background-controller.d.ts.map +1 -0
- package/dist/code-agents/background-controller.js +249 -0
- package/dist/code-agents/background-controller.js.map +1 -0
- package/dist/code-agents/background-run.d.ts +58 -0
- package/dist/code-agents/background-run.d.ts.map +1 -0
- package/dist/code-agents/background-run.js +58 -0
- package/dist/code-agents/background-run.js.map +1 -0
- package/dist/code-agents/index.d.ts +2 -0
- package/dist/code-agents/index.d.ts.map +1 -1
- package/dist/code-agents/index.js +2 -0
- package/dist/code-agents/index.js.map +1 -1
- package/dist/connections/index.d.ts +1 -0
- package/dist/connections/index.d.ts.map +1 -1
- package/dist/connections/index.js +1 -0
- package/dist/connections/index.js.map +1 -1
- package/dist/connections/reader.d.ts +248 -0
- package/dist/connections/reader.d.ts.map +1 -0
- package/dist/connections/reader.js +461 -0
- package/dist/connections/reader.js.map +1 -0
- package/dist/credentials/index.d.ts +11 -0
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +40 -15
- package/dist/credentials/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +18 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +57 -9
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-teams.d.ts +66 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +433 -16
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/builder-browser.d.ts +11 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +45 -0
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +25 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/templates/workspace-root/AGENTS.md +5 -5
- package/dist/templates/workspace-root/README.md +1 -1
- package/dist/workspace-connections/credentials.d.ts +64 -0
- package/dist/workspace-connections/credentials.d.ts.map +1 -0
- package/dist/workspace-connections/credentials.js +378 -0
- package/dist/workspace-connections/credentials.js.map +1 -0
- package/dist/workspace-connections/index.d.ts +2 -1
- package/dist/workspace-connections/index.d.ts.map +1 -1
- package/dist/workspace-connections/index.js +2 -1
- package/dist/workspace-connections/index.js.map +1 -1
- package/dist/workspace-connections/store.d.ts +16 -0
- package/dist/workspace-connections/store.d.ts.map +1 -1
- package/dist/workspace-connections/store.js +57 -1
- package/dist/workspace-connections/store.js.map +1 -1
- package/docs/content/agent-teams.md +22 -5
- package/docs/content/cloneable-saas.md +2 -2
- package/docs/content/code-agents-ui.md +103 -3
- package/docs/content/creating-templates.md +16 -0
- package/docs/content/getting-started.md +40 -14
- package/docs/content/migration-workbench.md +25 -2
- package/docs/content/multi-app-workspace.md +1 -1
- package/docs/content/template-analytics.md +17 -1
- package/docs/content/template-brain.md +57 -28
- package/docs/content/template-dispatch.md +9 -2
- package/docs/content/workspace-connections.md +63 -14
- package/docs/content/workspace-management.md +9 -2
- package/docs/content/workspace.md +12 -5
- package/package.json +1 -1
- package/src/templates/workspace-root/AGENTS.md +5 -5
- package/src/templates/workspace-root/README.md +1 -1
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { getWorkspaceConnectionProvider, } from "./catalog.js";
|
|
2
|
+
import { resolveWorkspaceConnectionCredentialsForApp, } from "../workspace-connections/index.js";
|
|
3
|
+
import { resolveWorkspaceConnectionForApp, } from "../workspace-connections/store.js";
|
|
4
|
+
export class ProviderReaderRuntimeError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
providerId;
|
|
7
|
+
operation;
|
|
8
|
+
constructor(code, message, options) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ProviderReaderRuntimeError";
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.providerId = options.providerId;
|
|
13
|
+
this.operation = options.operation;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function defineProviderReader(reader) {
|
|
17
|
+
return reader;
|
|
18
|
+
}
|
|
19
|
+
export function defineProviderReaderImplementation(implementation) {
|
|
20
|
+
return implementation;
|
|
21
|
+
}
|
|
22
|
+
const searchParameters = [
|
|
23
|
+
{
|
|
24
|
+
name: "query",
|
|
25
|
+
type: "string",
|
|
26
|
+
required: true,
|
|
27
|
+
description: "Provider-native search text.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "limit",
|
|
31
|
+
type: "number",
|
|
32
|
+
description: "Maximum normalized results to return.",
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const getParameters = [
|
|
36
|
+
{
|
|
37
|
+
name: "id",
|
|
38
|
+
type: "string",
|
|
39
|
+
required: true,
|
|
40
|
+
description: "Provider-native object identifier.",
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
const listRecentParameters = [
|
|
44
|
+
{
|
|
45
|
+
name: "limit",
|
|
46
|
+
type: "number",
|
|
47
|
+
description: "Maximum recent objects to return.",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
function operation(operationName, label, description, implementationStatus, parameters) {
|
|
51
|
+
return {
|
|
52
|
+
operation: operationName,
|
|
53
|
+
label,
|
|
54
|
+
description,
|
|
55
|
+
implementationStatus,
|
|
56
|
+
parameters,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function providerCredentialKeys(providerId) {
|
|
60
|
+
return getWorkspaceConnectionProvider(providerId)?.credentialKeys ?? [];
|
|
61
|
+
}
|
|
62
|
+
function requiredCredentialKeys(providerId) {
|
|
63
|
+
return providerCredentialKeys(providerId)
|
|
64
|
+
.filter((credential) => credential.required !== false)
|
|
65
|
+
.map((credential) => credential.key);
|
|
66
|
+
}
|
|
67
|
+
export const PROVIDER_READERS = [
|
|
68
|
+
defineProviderReader({
|
|
69
|
+
providerId: "slack",
|
|
70
|
+
label: "Slack reader",
|
|
71
|
+
description: "Normalized metadata for reading Slack messages and channel history through template-owned Slack implementations.",
|
|
72
|
+
implementationStatus: "template-owned",
|
|
73
|
+
credentialKeys: providerCredentialKeys("slack"),
|
|
74
|
+
requiredCredentialKeys: requiredCredentialKeys("slack"),
|
|
75
|
+
capabilities: [
|
|
76
|
+
{
|
|
77
|
+
capability: "search",
|
|
78
|
+
label: "Message search",
|
|
79
|
+
description: "Search conversation history using Slack's message search semantics.",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
capability: "messages",
|
|
83
|
+
label: "Message retrieval",
|
|
84
|
+
description: "Read individual messages or recent channel activity when a template owns the Slack client.",
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
operations: [
|
|
88
|
+
operation("search", "Search Slack messages", "Find Slack messages matching text and optional channel filters.", "template-owned", [
|
|
89
|
+
...searchParameters,
|
|
90
|
+
{
|
|
91
|
+
name: "channelId",
|
|
92
|
+
type: "string",
|
|
93
|
+
description: "Optional Slack channel id to narrow the search.",
|
|
94
|
+
},
|
|
95
|
+
]),
|
|
96
|
+
operation("get", "Get Slack message", "Load one Slack message by channel and timestamp/id.", "template-owned", [
|
|
97
|
+
...getParameters,
|
|
98
|
+
{
|
|
99
|
+
name: "channelId",
|
|
100
|
+
type: "string",
|
|
101
|
+
required: true,
|
|
102
|
+
description: "Slack channel id containing the message.",
|
|
103
|
+
},
|
|
104
|
+
]),
|
|
105
|
+
operation("listRecent", "List recent Slack messages", "List recent messages from channels visible to the connected Slack app.", "template-owned", listRecentParameters),
|
|
106
|
+
],
|
|
107
|
+
notes: "Core only exposes the contract; templates still own Slack API calls and provider-specific pagination.",
|
|
108
|
+
}),
|
|
109
|
+
defineProviderReader({
|
|
110
|
+
providerId: "github",
|
|
111
|
+
label: "GitHub reader",
|
|
112
|
+
description: "Normalized metadata for reading repositories, issues, pull requests, and code search results.",
|
|
113
|
+
implementationStatus: "template-owned",
|
|
114
|
+
credentialKeys: providerCredentialKeys("github"),
|
|
115
|
+
requiredCredentialKeys: requiredCredentialKeys("github"),
|
|
116
|
+
capabilities: [
|
|
117
|
+
{
|
|
118
|
+
capability: "search",
|
|
119
|
+
label: "Repository search",
|
|
120
|
+
description: "Search GitHub issues, pull requests, repositories, code, or docs using template-owned clients.",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
capability: "code",
|
|
124
|
+
label: "Code context",
|
|
125
|
+
description: "Read code-oriented objects such as repositories, files, issues, and pull requests.",
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
operations: [
|
|
129
|
+
operation("search", "Search GitHub", "Find repositories, issues, pull requests, code, or documentation matching a query.", "template-owned", [
|
|
130
|
+
...searchParameters,
|
|
131
|
+
{
|
|
132
|
+
name: "owner",
|
|
133
|
+
type: "string",
|
|
134
|
+
description: "Optional repository owner or organization filter.",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "repo",
|
|
138
|
+
type: "string",
|
|
139
|
+
description: "Optional repository filter.",
|
|
140
|
+
},
|
|
141
|
+
]),
|
|
142
|
+
operation("get", "Get GitHub object", "Load one repository, issue, pull request, or file by provider-native id or URL.", "template-owned", getParameters),
|
|
143
|
+
operation("listRecent", "List recent GitHub activity", "List recent issues, pull requests, or repository activity visible to the connection.", "template-owned", listRecentParameters),
|
|
144
|
+
],
|
|
145
|
+
notes: "No shared Octokit client is exported from core in this spike; templates remain responsible for API calls.",
|
|
146
|
+
}),
|
|
147
|
+
defineProviderReader({
|
|
148
|
+
providerId: "notion",
|
|
149
|
+
label: "Notion reader",
|
|
150
|
+
description: "Normalized metadata for reading Notion pages, databases, and workspace docs.",
|
|
151
|
+
implementationStatus: "template-owned",
|
|
152
|
+
credentialKeys: providerCredentialKeys("notion"),
|
|
153
|
+
requiredCredentialKeys: requiredCredentialKeys("notion"),
|
|
154
|
+
capabilities: [
|
|
155
|
+
{
|
|
156
|
+
capability: "search",
|
|
157
|
+
label: "Page search",
|
|
158
|
+
description: "Search pages and databases shared with the Notion integration.",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
capability: "docs",
|
|
162
|
+
label: "Document retrieval",
|
|
163
|
+
description: "Read Notion page or database metadata through template-owned clients.",
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
operations: [
|
|
167
|
+
operation("search", "Search Notion", "Find Notion pages or databases matching text and optional object type filters.", "template-owned", searchParameters),
|
|
168
|
+
operation("get", "Get Notion object", "Load one Notion page or database by id.", "template-owned", getParameters),
|
|
169
|
+
operation("listRecent", "List recent Notion objects", "List recently edited pages or databases visible to the integration.", "template-owned", listRecentParameters),
|
|
170
|
+
],
|
|
171
|
+
notes: "Core does not traverse Notion blocks yet; templates own page hydration and rate-limit behavior.",
|
|
172
|
+
}),
|
|
173
|
+
defineProviderReader({
|
|
174
|
+
providerId: "hubspot",
|
|
175
|
+
label: "HubSpot reader",
|
|
176
|
+
description: "Normalized metadata for CRM object lookup through template-owned HubSpot integrations.",
|
|
177
|
+
implementationStatus: "template-owned",
|
|
178
|
+
credentialKeys: providerCredentialKeys("hubspot"),
|
|
179
|
+
requiredCredentialKeys: requiredCredentialKeys("hubspot"),
|
|
180
|
+
capabilities: [
|
|
181
|
+
{
|
|
182
|
+
capability: "search",
|
|
183
|
+
label: "CRM search",
|
|
184
|
+
description: "Search CRM contacts, companies, deals, tickets, and engagements.",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
capability: "crm",
|
|
188
|
+
label: "CRM retrieval",
|
|
189
|
+
description: "Read CRM objects when a template owns HubSpot object mapping.",
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
operations: [
|
|
193
|
+
operation("search", "Search HubSpot CRM", "Find CRM records matching text or provider-native filters.", "template-owned", [
|
|
194
|
+
...searchParameters,
|
|
195
|
+
{
|
|
196
|
+
name: "objectType",
|
|
197
|
+
type: "string",
|
|
198
|
+
description: "Optional HubSpot object type such as contact, company, deal, or ticket.",
|
|
199
|
+
},
|
|
200
|
+
]),
|
|
201
|
+
operation("get", "Get HubSpot CRM object", "Load one CRM record by object type and id.", "template-owned", [
|
|
202
|
+
...getParameters,
|
|
203
|
+
{
|
|
204
|
+
name: "objectType",
|
|
205
|
+
type: "string",
|
|
206
|
+
required: true,
|
|
207
|
+
description: "HubSpot object type such as contact, company, deal, or ticket.",
|
|
208
|
+
},
|
|
209
|
+
]),
|
|
210
|
+
operation("listRecent", "List recent HubSpot CRM objects", "List recently updated CRM records visible to the private app token.", "template-owned", listRecentParameters),
|
|
211
|
+
],
|
|
212
|
+
notes: "Templates define object allow-lists and property projections; core only documents the reader shape.",
|
|
213
|
+
}),
|
|
214
|
+
defineProviderReader({
|
|
215
|
+
providerId: "gmail",
|
|
216
|
+
label: "Gmail reader",
|
|
217
|
+
description: "Normalized metadata for mailbox search and thread/message reads through app-owned Google OAuth flows.",
|
|
218
|
+
implementationStatus: "template-owned",
|
|
219
|
+
credentialKeys: providerCredentialKeys("gmail"),
|
|
220
|
+
requiredCredentialKeys: requiredCredentialKeys("gmail"),
|
|
221
|
+
capabilities: [
|
|
222
|
+
{
|
|
223
|
+
capability: "search",
|
|
224
|
+
label: "Mailbox search",
|
|
225
|
+
description: "Search Gmail messages and threads.",
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
capability: "messages",
|
|
229
|
+
label: "Mail retrieval",
|
|
230
|
+
description: "Read Gmail messages and threads when a template owns OAuth token handling.",
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
operations: [
|
|
234
|
+
operation("search", "Search Gmail", "Find Gmail messages or threads matching a query.", "template-owned", searchParameters),
|
|
235
|
+
operation("get", "Get Gmail message or thread", "Load one Gmail message or thread by provider-native id.", "template-owned", getParameters),
|
|
236
|
+
operation("listRecent", "List recent Gmail messages", "List recent mailbox messages visible to the connected Google account.", "template-owned", listRecentParameters),
|
|
237
|
+
],
|
|
238
|
+
notes: "This is metadata for templates with Google OAuth; core does not expose a shared Gmail network client here.",
|
|
239
|
+
}),
|
|
240
|
+
defineProviderReader({
|
|
241
|
+
providerId: "google_drive",
|
|
242
|
+
label: "Google Drive reader",
|
|
243
|
+
description: "Normalized metadata for Drive file search and document lookup through app-owned Google OAuth flows.",
|
|
244
|
+
implementationStatus: "template-owned",
|
|
245
|
+
credentialKeys: providerCredentialKeys("google_drive"),
|
|
246
|
+
requiredCredentialKeys: requiredCredentialKeys("google_drive"),
|
|
247
|
+
capabilities: [
|
|
248
|
+
{
|
|
249
|
+
capability: "search",
|
|
250
|
+
label: "Drive search",
|
|
251
|
+
description: "Search files visible to the connected Google account.",
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
capability: "docs",
|
|
255
|
+
label: "Drive document retrieval",
|
|
256
|
+
description: "Read file metadata or exported document content through template-owned Google clients.",
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
operations: [
|
|
260
|
+
operation("search", "Search Google Drive", "Find Drive files matching text, MIME type, or folder filters.", "template-owned", [
|
|
261
|
+
...searchParameters,
|
|
262
|
+
{
|
|
263
|
+
name: "mimeType",
|
|
264
|
+
type: "string",
|
|
265
|
+
description: "Optional MIME type filter.",
|
|
266
|
+
},
|
|
267
|
+
]),
|
|
268
|
+
operation("get", "Get Google Drive file", "Load one Drive file by id.", "template-owned", getParameters),
|
|
269
|
+
operation("listRecent", "List recent Google Drive files", "List recently modified files visible to the connected Google account.", "template-owned", listRecentParameters),
|
|
270
|
+
],
|
|
271
|
+
notes: "Templates still own file export formats, Docs/Sheets/Slides handling, and OAuth token refresh.",
|
|
272
|
+
}),
|
|
273
|
+
defineProviderReader({
|
|
274
|
+
providerId: "generic",
|
|
275
|
+
label: "Generic metadata reader",
|
|
276
|
+
description: "Placeholder reader metadata for custom sources that expose searchable documents through a template-specific adapter.",
|
|
277
|
+
implementationStatus: "metadata-only",
|
|
278
|
+
credentialKeys: providerCredentialKeys("generic"),
|
|
279
|
+
requiredCredentialKeys: requiredCredentialKeys("generic"),
|
|
280
|
+
capabilities: [
|
|
281
|
+
{
|
|
282
|
+
capability: "search",
|
|
283
|
+
label: "Custom search",
|
|
284
|
+
description: "Describe a template-specific search interface for one-off sources.",
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
capability: "docs",
|
|
288
|
+
label: "Custom document retrieval",
|
|
289
|
+
description: "Describe a template-specific document retrieval interface.",
|
|
290
|
+
},
|
|
291
|
+
],
|
|
292
|
+
operations: [
|
|
293
|
+
operation("search", "Search custom source", "Metadata-only descriptor for searching a custom source.", "metadata-only", searchParameters),
|
|
294
|
+
operation("get", "Get custom source object", "Metadata-only descriptor for loading one custom source object by id.", "metadata-only", getParameters),
|
|
295
|
+
],
|
|
296
|
+
notes: "Use this only to document a template-owned adapter; core cannot execute generic provider reads.",
|
|
297
|
+
}),
|
|
298
|
+
];
|
|
299
|
+
const READERS_BY_PROVIDER_ID = new Map(PROVIDER_READERS.map((reader) => [reader.providerId, reader]));
|
|
300
|
+
export function listProviderReaders(options = {}) {
|
|
301
|
+
return PROVIDER_READERS.filter((reader) => {
|
|
302
|
+
if (options.providerId && reader.providerId !== options.providerId) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
if (options.capability &&
|
|
306
|
+
!reader.capabilities.some((capability) => capability.capability === options.capability)) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
if (options.operation &&
|
|
310
|
+
!reader.operations.some((operation) => operation.operation === options.operation)) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
if (options.implementationStatus &&
|
|
314
|
+
reader.implementationStatus !== options.implementationStatus) {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
return true;
|
|
318
|
+
}).map(cloneProviderReader);
|
|
319
|
+
}
|
|
320
|
+
export function getProviderReader(providerId) {
|
|
321
|
+
const reader = READERS_BY_PROVIDER_ID.get(providerId);
|
|
322
|
+
return reader ? cloneProviderReader(reader) : undefined;
|
|
323
|
+
}
|
|
324
|
+
export function providerReaderSupports(providerOrReader, operationName) {
|
|
325
|
+
const reader = typeof providerOrReader === "string"
|
|
326
|
+
? getProviderReader(providerOrReader)
|
|
327
|
+
: providerOrReader;
|
|
328
|
+
return (reader?.operations.some((operation) => operation.operation === operationName) ?? false);
|
|
329
|
+
}
|
|
330
|
+
export function createProviderReaderRuntime(options) {
|
|
331
|
+
const appId = options.appId.trim();
|
|
332
|
+
if (!appId) {
|
|
333
|
+
throw new Error("createProviderReaderRuntime appId is required.");
|
|
334
|
+
}
|
|
335
|
+
const implementations = new Map();
|
|
336
|
+
for (const implementation of options.readers) {
|
|
337
|
+
implementations.set(implementation.providerId, implementation);
|
|
338
|
+
}
|
|
339
|
+
const connectionResolver = options.resolveConnection ??
|
|
340
|
+
((resolverOptions) => resolveWorkspaceConnectionForApp({
|
|
341
|
+
appId: resolverOptions.appId,
|
|
342
|
+
provider: resolverOptions.providerId,
|
|
343
|
+
connectionId: resolverOptions.connectionId,
|
|
344
|
+
includeDisabled: false,
|
|
345
|
+
requireConnected: true,
|
|
346
|
+
}));
|
|
347
|
+
const credentialsResolver = options.resolveCredentials ??
|
|
348
|
+
((resolverOptions) => resolveWorkspaceConnectionCredentialsForApp({
|
|
349
|
+
appId: resolverOptions.appId,
|
|
350
|
+
provider: resolverOptions.providerId,
|
|
351
|
+
connectionId: resolverOptions.connectionId,
|
|
352
|
+
keys: resolverOptions.keys,
|
|
353
|
+
userEmail: resolverOptions.userEmail,
|
|
354
|
+
orgId: resolverOptions.orgId,
|
|
355
|
+
}));
|
|
356
|
+
return {
|
|
357
|
+
async read(request) {
|
|
358
|
+
const reader = getProviderReader(request.providerId);
|
|
359
|
+
if (!reader) {
|
|
360
|
+
throw new ProviderReaderRuntimeError("unsupported_provider", `No provider reader metadata is registered for ${request.providerId}.`, { providerId: request.providerId, operation: request.operation });
|
|
361
|
+
}
|
|
362
|
+
const operation = reader.operations.find((entry) => entry.operation === request.operation);
|
|
363
|
+
if (!operation) {
|
|
364
|
+
throw new ProviderReaderRuntimeError("unsupported_operation", `${reader.label} does not support ${request.operation}.`, { providerId: request.providerId, operation: request.operation });
|
|
365
|
+
}
|
|
366
|
+
const implementation = implementations.get(request.providerId);
|
|
367
|
+
if (!implementation) {
|
|
368
|
+
throw new ProviderReaderRuntimeError("unsupported_provider", `${reader.label} has no runtime implementation registered.`, { providerId: request.providerId, operation: request.operation });
|
|
369
|
+
}
|
|
370
|
+
const handler = implementation.operations[request.operation];
|
|
371
|
+
if (!handler) {
|
|
372
|
+
throw new ProviderReaderRuntimeError("unsupported_operation", `${reader.label} has no runtime handler for ${request.operation}.`, { providerId: request.providerId, operation: request.operation });
|
|
373
|
+
}
|
|
374
|
+
const resolvedConnection = await connectionResolver({
|
|
375
|
+
appId,
|
|
376
|
+
providerId: request.providerId,
|
|
377
|
+
connectionId: request.connectionId?.trim() || undefined,
|
|
378
|
+
});
|
|
379
|
+
if (!resolvedConnection.available || !resolvedConnection.connection) {
|
|
380
|
+
throw new ProviderReaderRuntimeError("connection_not_available", resolvedConnection.reason, { providerId: request.providerId, operation: request.operation });
|
|
381
|
+
}
|
|
382
|
+
const connection = publicRuntimeConnection(resolvedConnection.connection);
|
|
383
|
+
const context = {
|
|
384
|
+
appId,
|
|
385
|
+
providerId: request.providerId,
|
|
386
|
+
reader,
|
|
387
|
+
connection,
|
|
388
|
+
resolveCredentials: (keys = reader.requiredCredentialKeys) => credentialsResolver({
|
|
389
|
+
appId,
|
|
390
|
+
providerId: request.providerId,
|
|
391
|
+
connectionId: connection.id,
|
|
392
|
+
keys: [...keys],
|
|
393
|
+
userEmail: request.userEmail,
|
|
394
|
+
orgId: request.orgId,
|
|
395
|
+
}),
|
|
396
|
+
requireCredentials: async (keys = reader.requiredCredentialKeys) => {
|
|
397
|
+
const resolution = await credentialsResolver({
|
|
398
|
+
appId,
|
|
399
|
+
providerId: request.providerId,
|
|
400
|
+
connectionId: connection.id,
|
|
401
|
+
keys: [...keys],
|
|
402
|
+
userEmail: request.userEmail,
|
|
403
|
+
orgId: request.orgId,
|
|
404
|
+
});
|
|
405
|
+
if (!resolution.available) {
|
|
406
|
+
throw new ProviderReaderRuntimeError("credentials_unavailable", `Missing workspace connection credentials for ${reader.label}: ${resolution.missingKeys.join(", ")}.`, {
|
|
407
|
+
providerId: request.providerId,
|
|
408
|
+
operation: request.operation,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
return { values: resolution.values, resolution };
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
return handler((request.params ?? {}), context);
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function cloneProviderReader(reader) {
|
|
419
|
+
return {
|
|
420
|
+
...reader,
|
|
421
|
+
credentialKeys: reader.credentialKeys.map((credential) => ({
|
|
422
|
+
...credential,
|
|
423
|
+
})),
|
|
424
|
+
requiredCredentialKeys: [...reader.requiredCredentialKeys],
|
|
425
|
+
capabilities: reader.capabilities.map((capability) => ({
|
|
426
|
+
...capability,
|
|
427
|
+
})),
|
|
428
|
+
operations: reader.operations.map((operation) => ({
|
|
429
|
+
...operation,
|
|
430
|
+
parameters: operation.parameters.map((parameter) => ({
|
|
431
|
+
...parameter,
|
|
432
|
+
})),
|
|
433
|
+
})),
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function publicRuntimeConnection(connection) {
|
|
437
|
+
return {
|
|
438
|
+
id: connection.id,
|
|
439
|
+
provider: connection.provider,
|
|
440
|
+
label: connection.label,
|
|
441
|
+
accountId: connection.accountId,
|
|
442
|
+
accountLabel: connection.accountLabel,
|
|
443
|
+
credentialRefs: publicCredentialRefs(connection),
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
function publicCredentialRefs(connection) {
|
|
447
|
+
return [
|
|
448
|
+
...(connection.explicitGrant?.credentialRefs ?? []).map((ref) => publicCredentialRef(ref, "grant")),
|
|
449
|
+
...connection.credentialRefs.map((ref) => publicCredentialRef(ref, "connection")),
|
|
450
|
+
];
|
|
451
|
+
}
|
|
452
|
+
function publicCredentialRef(ref, source) {
|
|
453
|
+
return {
|
|
454
|
+
key: ref.key,
|
|
455
|
+
scope: ref.scope,
|
|
456
|
+
provider: ref.provider,
|
|
457
|
+
label: ref.label,
|
|
458
|
+
source,
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/connections/reader.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getWorkspaceConnectionProvider,\n type WorkspaceConnectionCapability,\n type WorkspaceConnectionCredentialKey,\n type WorkspaceConnectionProviderId,\n} from \"./catalog.js\";\nimport {\n resolveWorkspaceConnectionCredentialsForApp,\n type ResolveWorkspaceConnectionCredentialsForAppOptions,\n type WorkspaceConnectionCredentialRef,\n type WorkspaceConnectionCredentialsResolution,\n type WorkspaceConnectionForApp,\n type WorkspaceConnectionPublicCredentialRef,\n} from \"../workspace-connections/index.js\";\nimport {\n resolveWorkspaceConnectionForApp,\n type ResolvedWorkspaceConnectionForApp,\n type ResolveWorkspaceConnectionForAppOptions,\n} from \"../workspace-connections/store.js\";\n\nexport type ProviderReaderOperation = \"search\" | \"get\" | \"listRecent\";\n\nexport type ProviderReaderImplementationStatus =\n | \"metadata-only\"\n | \"template-owned\"\n | \"shared\";\n\nexport interface ProviderReaderCapability {\n capability: WorkspaceConnectionCapability;\n label: string;\n description: string;\n}\n\nexport interface ProviderReaderOperationParameter {\n name: string;\n type: \"string\" | \"number\" | \"boolean\" | \"string[]\";\n required?: boolean;\n description: string;\n}\n\nexport interface ProviderReaderOperationDescriptor {\n operation: ProviderReaderOperation;\n label: string;\n description: string;\n implementationStatus: ProviderReaderImplementationStatus;\n parameters: readonly ProviderReaderOperationParameter[];\n}\n\nexport interface ProviderReaderDefinition {\n providerId: WorkspaceConnectionProviderId;\n label: string;\n description: string;\n implementationStatus: ProviderReaderImplementationStatus;\n credentialKeys: readonly WorkspaceConnectionCredentialKey[];\n requiredCredentialKeys: readonly string[];\n capabilities: readonly ProviderReaderCapability[];\n operations: readonly ProviderReaderOperationDescriptor[];\n notes?: string;\n}\n\nexport interface ListProviderReadersOptions {\n providerId?: WorkspaceConnectionProviderId;\n capability?: WorkspaceConnectionCapability;\n operation?: ProviderReaderOperation;\n implementationStatus?: ProviderReaderImplementationStatus;\n}\n\nexport type ProviderReaderRuntimeErrorCode =\n | \"unsupported_provider\"\n | \"unsupported_operation\"\n | \"connection_not_available\"\n | \"credentials_unavailable\";\n\nexport interface ProviderReaderRequest<\n TParams extends Record<string, unknown> = Record<string, unknown>,\n> {\n providerId: WorkspaceConnectionProviderId;\n operation: ProviderReaderOperation;\n params?: TParams;\n connectionId?: string | null;\n userEmail?: string | null;\n orgId?: string | null;\n}\n\nexport interface ProviderReaderRuntimeItem {\n id: string;\n type: string;\n title?: string;\n url?: string;\n text?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ProviderReaderRuntimeResponse {\n providerId: WorkspaceConnectionProviderId;\n operation: ProviderReaderOperation;\n connectionId: string;\n items?: ProviderReaderRuntimeItem[];\n item?: ProviderReaderRuntimeItem | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ProviderReaderRuntimeConnection {\n id: string;\n provider: string;\n label: string;\n accountId: string | null;\n accountLabel: string | null;\n credentialRefs: WorkspaceConnectionPublicCredentialRef[];\n}\n\nexport interface ProviderReaderCredentialRequirement {\n values: Record<string, string>;\n resolution: WorkspaceConnectionCredentialsResolution;\n}\n\nexport interface ProviderReaderRuntimeContext {\n appId: string;\n providerId: WorkspaceConnectionProviderId;\n reader: ProviderReaderDefinition;\n connection: ProviderReaderRuntimeConnection;\n resolveCredentials(\n keys?: readonly string[],\n ): Promise<WorkspaceConnectionCredentialsResolution>;\n requireCredentials(\n keys?: readonly string[],\n ): Promise<ProviderReaderCredentialRequirement>;\n}\n\nexport type ProviderReaderRuntimeHandler<\n TParams extends Record<string, unknown> = Record<string, unknown>,\n> = (\n params: TParams,\n context: ProviderReaderRuntimeContext,\n) => ProviderReaderRuntimeResponse | Promise<ProviderReaderRuntimeResponse>;\n\nexport interface ProviderReaderRuntimeImplementation<\n TProviderId extends WorkspaceConnectionProviderId =\n WorkspaceConnectionProviderId,\n> {\n providerId: TProviderId;\n operations: Partial<\n Record<ProviderReaderOperation, ProviderReaderRuntimeHandler>\n >;\n}\n\nexport interface ProviderReaderRuntimeConnectionResolverOptions extends Pick<\n ResolveWorkspaceConnectionForAppOptions,\n \"appId\" | \"connectionId\"\n> {\n providerId: WorkspaceConnectionProviderId;\n}\n\nexport interface ProviderReaderRuntimeCredentialsResolverOptions extends Pick<\n ResolveWorkspaceConnectionCredentialsForAppOptions,\n \"appId\" | \"connectionId\" | \"keys\" | \"userEmail\" | \"orgId\"\n> {\n providerId: WorkspaceConnectionProviderId;\n}\n\nexport interface ProviderReaderRuntimeOptions {\n appId: string;\n readers: readonly ProviderReaderRuntimeImplementation[];\n resolveConnection?: (\n options: ProviderReaderRuntimeConnectionResolverOptions,\n ) => Promise<ResolvedWorkspaceConnectionForApp>;\n resolveCredentials?: (\n options: ProviderReaderRuntimeCredentialsResolverOptions,\n ) => Promise<WorkspaceConnectionCredentialsResolution>;\n}\n\nexport interface ProviderReaderRuntime {\n read<TParams extends Record<string, unknown> = Record<string, unknown>>(\n request: ProviderReaderRequest<TParams>,\n ): Promise<ProviderReaderRuntimeResponse>;\n}\n\nexport class ProviderReaderRuntimeError extends Error {\n readonly code: ProviderReaderRuntimeErrorCode;\n readonly providerId: string;\n readonly operation?: ProviderReaderOperation;\n\n constructor(\n code: ProviderReaderRuntimeErrorCode,\n message: string,\n options: {\n providerId: string;\n operation?: ProviderReaderOperation;\n },\n ) {\n super(message);\n this.name = \"ProviderReaderRuntimeError\";\n this.code = code;\n this.providerId = options.providerId;\n this.operation = options.operation;\n }\n}\n\nexport function defineProviderReader<const T extends ProviderReaderDefinition>(\n reader: T,\n): T {\n return reader;\n}\n\nexport function defineProviderReaderImplementation<\n const T extends ProviderReaderRuntimeImplementation,\n>(implementation: T): T {\n return implementation;\n}\n\nconst searchParameters = [\n {\n name: \"query\",\n type: \"string\",\n required: true,\n description: \"Provider-native search text.\",\n },\n {\n name: \"limit\",\n type: \"number\",\n description: \"Maximum normalized results to return.\",\n },\n] as const satisfies readonly ProviderReaderOperationParameter[];\n\nconst getParameters = [\n {\n name: \"id\",\n type: \"string\",\n required: true,\n description: \"Provider-native object identifier.\",\n },\n] as const satisfies readonly ProviderReaderOperationParameter[];\n\nconst listRecentParameters = [\n {\n name: \"limit\",\n type: \"number\",\n description: \"Maximum recent objects to return.\",\n },\n] as const satisfies readonly ProviderReaderOperationParameter[];\n\nfunction operation(\n operationName: ProviderReaderOperation,\n label: string,\n description: string,\n implementationStatus: ProviderReaderImplementationStatus,\n parameters: readonly ProviderReaderOperationParameter[],\n): ProviderReaderOperationDescriptor {\n return {\n operation: operationName,\n label,\n description,\n implementationStatus,\n parameters,\n };\n}\n\nfunction providerCredentialKeys(\n providerId: WorkspaceConnectionProviderId,\n): readonly WorkspaceConnectionCredentialKey[] {\n return getWorkspaceConnectionProvider(providerId)?.credentialKeys ?? [];\n}\n\nfunction requiredCredentialKeys(\n providerId: WorkspaceConnectionProviderId,\n): readonly string[] {\n return providerCredentialKeys(providerId)\n .filter((credential) => credential.required !== false)\n .map((credential) => credential.key);\n}\n\nexport const PROVIDER_READERS = [\n defineProviderReader({\n providerId: \"slack\",\n label: \"Slack reader\",\n description:\n \"Normalized metadata for reading Slack messages and channel history through template-owned Slack implementations.\",\n implementationStatus: \"template-owned\",\n credentialKeys: providerCredentialKeys(\"slack\"),\n requiredCredentialKeys: requiredCredentialKeys(\"slack\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"Message search\",\n description:\n \"Search conversation history using Slack's message search semantics.\",\n },\n {\n capability: \"messages\",\n label: \"Message retrieval\",\n description:\n \"Read individual messages or recent channel activity when a template owns the Slack client.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search Slack messages\",\n \"Find Slack messages matching text and optional channel filters.\",\n \"template-owned\",\n [\n ...searchParameters,\n {\n name: \"channelId\",\n type: \"string\",\n description: \"Optional Slack channel id to narrow the search.\",\n },\n ],\n ),\n operation(\n \"get\",\n \"Get Slack message\",\n \"Load one Slack message by channel and timestamp/id.\",\n \"template-owned\",\n [\n ...getParameters,\n {\n name: \"channelId\",\n type: \"string\",\n required: true,\n description: \"Slack channel id containing the message.\",\n },\n ],\n ),\n operation(\n \"listRecent\",\n \"List recent Slack messages\",\n \"List recent messages from channels visible to the connected Slack app.\",\n \"template-owned\",\n listRecentParameters,\n ),\n ],\n notes:\n \"Core only exposes the contract; templates still own Slack API calls and provider-specific pagination.\",\n }),\n defineProviderReader({\n providerId: \"github\",\n label: \"GitHub reader\",\n description:\n \"Normalized metadata for reading repositories, issues, pull requests, and code search results.\",\n implementationStatus: \"template-owned\",\n credentialKeys: providerCredentialKeys(\"github\"),\n requiredCredentialKeys: requiredCredentialKeys(\"github\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"Repository search\",\n description:\n \"Search GitHub issues, pull requests, repositories, code, or docs using template-owned clients.\",\n },\n {\n capability: \"code\",\n label: \"Code context\",\n description:\n \"Read code-oriented objects such as repositories, files, issues, and pull requests.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search GitHub\",\n \"Find repositories, issues, pull requests, code, or documentation matching a query.\",\n \"template-owned\",\n [\n ...searchParameters,\n {\n name: \"owner\",\n type: \"string\",\n description: \"Optional repository owner or organization filter.\",\n },\n {\n name: \"repo\",\n type: \"string\",\n description: \"Optional repository filter.\",\n },\n ],\n ),\n operation(\n \"get\",\n \"Get GitHub object\",\n \"Load one repository, issue, pull request, or file by provider-native id or URL.\",\n \"template-owned\",\n getParameters,\n ),\n operation(\n \"listRecent\",\n \"List recent GitHub activity\",\n \"List recent issues, pull requests, or repository activity visible to the connection.\",\n \"template-owned\",\n listRecentParameters,\n ),\n ],\n notes:\n \"No shared Octokit client is exported from core in this spike; templates remain responsible for API calls.\",\n }),\n defineProviderReader({\n providerId: \"notion\",\n label: \"Notion reader\",\n description:\n \"Normalized metadata for reading Notion pages, databases, and workspace docs.\",\n implementationStatus: \"template-owned\",\n credentialKeys: providerCredentialKeys(\"notion\"),\n requiredCredentialKeys: requiredCredentialKeys(\"notion\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"Page search\",\n description:\n \"Search pages and databases shared with the Notion integration.\",\n },\n {\n capability: \"docs\",\n label: \"Document retrieval\",\n description:\n \"Read Notion page or database metadata through template-owned clients.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search Notion\",\n \"Find Notion pages or databases matching text and optional object type filters.\",\n \"template-owned\",\n searchParameters,\n ),\n operation(\n \"get\",\n \"Get Notion object\",\n \"Load one Notion page or database by id.\",\n \"template-owned\",\n getParameters,\n ),\n operation(\n \"listRecent\",\n \"List recent Notion objects\",\n \"List recently edited pages or databases visible to the integration.\",\n \"template-owned\",\n listRecentParameters,\n ),\n ],\n notes:\n \"Core does not traverse Notion blocks yet; templates own page hydration and rate-limit behavior.\",\n }),\n defineProviderReader({\n providerId: \"hubspot\",\n label: \"HubSpot reader\",\n description:\n \"Normalized metadata for CRM object lookup through template-owned HubSpot integrations.\",\n implementationStatus: \"template-owned\",\n credentialKeys: providerCredentialKeys(\"hubspot\"),\n requiredCredentialKeys: requiredCredentialKeys(\"hubspot\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"CRM search\",\n description:\n \"Search CRM contacts, companies, deals, tickets, and engagements.\",\n },\n {\n capability: \"crm\",\n label: \"CRM retrieval\",\n description:\n \"Read CRM objects when a template owns HubSpot object mapping.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search HubSpot CRM\",\n \"Find CRM records matching text or provider-native filters.\",\n \"template-owned\",\n [\n ...searchParameters,\n {\n name: \"objectType\",\n type: \"string\",\n description:\n \"Optional HubSpot object type such as contact, company, deal, or ticket.\",\n },\n ],\n ),\n operation(\n \"get\",\n \"Get HubSpot CRM object\",\n \"Load one CRM record by object type and id.\",\n \"template-owned\",\n [\n ...getParameters,\n {\n name: \"objectType\",\n type: \"string\",\n required: true,\n description:\n \"HubSpot object type such as contact, company, deal, or ticket.\",\n },\n ],\n ),\n operation(\n \"listRecent\",\n \"List recent HubSpot CRM objects\",\n \"List recently updated CRM records visible to the private app token.\",\n \"template-owned\",\n listRecentParameters,\n ),\n ],\n notes:\n \"Templates define object allow-lists and property projections; core only documents the reader shape.\",\n }),\n defineProviderReader({\n providerId: \"gmail\",\n label: \"Gmail reader\",\n description:\n \"Normalized metadata for mailbox search and thread/message reads through app-owned Google OAuth flows.\",\n implementationStatus: \"template-owned\",\n credentialKeys: providerCredentialKeys(\"gmail\"),\n requiredCredentialKeys: requiredCredentialKeys(\"gmail\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"Mailbox search\",\n description: \"Search Gmail messages and threads.\",\n },\n {\n capability: \"messages\",\n label: \"Mail retrieval\",\n description:\n \"Read Gmail messages and threads when a template owns OAuth token handling.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search Gmail\",\n \"Find Gmail messages or threads matching a query.\",\n \"template-owned\",\n searchParameters,\n ),\n operation(\n \"get\",\n \"Get Gmail message or thread\",\n \"Load one Gmail message or thread by provider-native id.\",\n \"template-owned\",\n getParameters,\n ),\n operation(\n \"listRecent\",\n \"List recent Gmail messages\",\n \"List recent mailbox messages visible to the connected Google account.\",\n \"template-owned\",\n listRecentParameters,\n ),\n ],\n notes:\n \"This is metadata for templates with Google OAuth; core does not expose a shared Gmail network client here.\",\n }),\n defineProviderReader({\n providerId: \"google_drive\",\n label: \"Google Drive reader\",\n description:\n \"Normalized metadata for Drive file search and document lookup through app-owned Google OAuth flows.\",\n implementationStatus: \"template-owned\",\n credentialKeys: providerCredentialKeys(\"google_drive\"),\n requiredCredentialKeys: requiredCredentialKeys(\"google_drive\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"Drive search\",\n description: \"Search files visible to the connected Google account.\",\n },\n {\n capability: \"docs\",\n label: \"Drive document retrieval\",\n description:\n \"Read file metadata or exported document content through template-owned Google clients.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search Google Drive\",\n \"Find Drive files matching text, MIME type, or folder filters.\",\n \"template-owned\",\n [\n ...searchParameters,\n {\n name: \"mimeType\",\n type: \"string\",\n description: \"Optional MIME type filter.\",\n },\n ],\n ),\n operation(\n \"get\",\n \"Get Google Drive file\",\n \"Load one Drive file by id.\",\n \"template-owned\",\n getParameters,\n ),\n operation(\n \"listRecent\",\n \"List recent Google Drive files\",\n \"List recently modified files visible to the connected Google account.\",\n \"template-owned\",\n listRecentParameters,\n ),\n ],\n notes:\n \"Templates still own file export formats, Docs/Sheets/Slides handling, and OAuth token refresh.\",\n }),\n defineProviderReader({\n providerId: \"generic\",\n label: \"Generic metadata reader\",\n description:\n \"Placeholder reader metadata for custom sources that expose searchable documents through a template-specific adapter.\",\n implementationStatus: \"metadata-only\",\n credentialKeys: providerCredentialKeys(\"generic\"),\n requiredCredentialKeys: requiredCredentialKeys(\"generic\"),\n capabilities: [\n {\n capability: \"search\",\n label: \"Custom search\",\n description:\n \"Describe a template-specific search interface for one-off sources.\",\n },\n {\n capability: \"docs\",\n label: \"Custom document retrieval\",\n description:\n \"Describe a template-specific document retrieval interface.\",\n },\n ],\n operations: [\n operation(\n \"search\",\n \"Search custom source\",\n \"Metadata-only descriptor for searching a custom source.\",\n \"metadata-only\",\n searchParameters,\n ),\n operation(\n \"get\",\n \"Get custom source object\",\n \"Metadata-only descriptor for loading one custom source object by id.\",\n \"metadata-only\",\n getParameters,\n ),\n ],\n notes:\n \"Use this only to document a template-owned adapter; core cannot execute generic provider reads.\",\n }),\n] as const satisfies readonly ProviderReaderDefinition[];\n\nconst READERS_BY_PROVIDER_ID = new Map<\n WorkspaceConnectionProviderId,\n ProviderReaderDefinition\n>(PROVIDER_READERS.map((reader) => [reader.providerId, reader]));\n\nexport function listProviderReaders(\n options: ListProviderReadersOptions = {},\n): ProviderReaderDefinition[] {\n return PROVIDER_READERS.filter((reader) => {\n if (options.providerId && reader.providerId !== options.providerId) {\n return false;\n }\n if (\n options.capability &&\n !reader.capabilities.some(\n (capability) => capability.capability === options.capability,\n )\n ) {\n return false;\n }\n if (\n options.operation &&\n !reader.operations.some(\n (operation) => operation.operation === options.operation,\n )\n ) {\n return false;\n }\n if (\n options.implementationStatus &&\n reader.implementationStatus !== options.implementationStatus\n ) {\n return false;\n }\n return true;\n }).map(cloneProviderReader);\n}\n\nexport function getProviderReader(\n providerId: string,\n): ProviderReaderDefinition | undefined {\n const reader = READERS_BY_PROVIDER_ID.get(\n providerId as WorkspaceConnectionProviderId,\n );\n return reader ? cloneProviderReader(reader) : undefined;\n}\n\nexport function providerReaderSupports(\n providerOrReader: ProviderReaderDefinition | WorkspaceConnectionProviderId,\n operationName: ProviderReaderOperation,\n): boolean {\n const reader =\n typeof providerOrReader === \"string\"\n ? getProviderReader(providerOrReader)\n : providerOrReader;\n return (\n reader?.operations.some(\n (operation) => operation.operation === operationName,\n ) ?? false\n );\n}\n\nexport function createProviderReaderRuntime(\n options: ProviderReaderRuntimeOptions,\n): ProviderReaderRuntime {\n const appId = options.appId.trim();\n if (!appId) {\n throw new Error(\"createProviderReaderRuntime appId is required.\");\n }\n\n const implementations = new Map<\n WorkspaceConnectionProviderId,\n ProviderReaderRuntimeImplementation\n >();\n for (const implementation of options.readers) {\n implementations.set(implementation.providerId, implementation);\n }\n\n const connectionResolver =\n options.resolveConnection ??\n ((resolverOptions: ProviderReaderRuntimeConnectionResolverOptions) =>\n resolveWorkspaceConnectionForApp({\n appId: resolverOptions.appId,\n provider: resolverOptions.providerId,\n connectionId: resolverOptions.connectionId,\n includeDisabled: false,\n requireConnected: true,\n }));\n const credentialsResolver =\n options.resolveCredentials ??\n ((resolverOptions: ProviderReaderRuntimeCredentialsResolverOptions) =>\n resolveWorkspaceConnectionCredentialsForApp({\n appId: resolverOptions.appId,\n provider: resolverOptions.providerId,\n connectionId: resolverOptions.connectionId,\n keys: resolverOptions.keys,\n userEmail: resolverOptions.userEmail,\n orgId: resolverOptions.orgId,\n }));\n\n return {\n async read<\n TParams extends Record<string, unknown> = Record<string, unknown>,\n >(\n request: ProviderReaderRequest<TParams>,\n ): Promise<ProviderReaderRuntimeResponse> {\n const reader = getProviderReader(request.providerId);\n if (!reader) {\n throw new ProviderReaderRuntimeError(\n \"unsupported_provider\",\n `No provider reader metadata is registered for ${request.providerId}.`,\n { providerId: request.providerId, operation: request.operation },\n );\n }\n\n const operation = reader.operations.find(\n (entry) => entry.operation === request.operation,\n );\n if (!operation) {\n throw new ProviderReaderRuntimeError(\n \"unsupported_operation\",\n `${reader.label} does not support ${request.operation}.`,\n { providerId: request.providerId, operation: request.operation },\n );\n }\n\n const implementation = implementations.get(request.providerId);\n if (!implementation) {\n throw new ProviderReaderRuntimeError(\n \"unsupported_provider\",\n `${reader.label} has no runtime implementation registered.`,\n { providerId: request.providerId, operation: request.operation },\n );\n }\n\n const handler = implementation.operations[request.operation];\n if (!handler) {\n throw new ProviderReaderRuntimeError(\n \"unsupported_operation\",\n `${reader.label} has no runtime handler for ${request.operation}.`,\n { providerId: request.providerId, operation: request.operation },\n );\n }\n\n const resolvedConnection = await connectionResolver({\n appId,\n providerId: request.providerId,\n connectionId: request.connectionId?.trim() || undefined,\n });\n if (!resolvedConnection.available || !resolvedConnection.connection) {\n throw new ProviderReaderRuntimeError(\n \"connection_not_available\",\n resolvedConnection.reason,\n { providerId: request.providerId, operation: request.operation },\n );\n }\n\n const connection = publicRuntimeConnection(resolvedConnection.connection);\n const context: ProviderReaderRuntimeContext = {\n appId,\n providerId: request.providerId,\n reader,\n connection,\n resolveCredentials: (keys = reader.requiredCredentialKeys) =>\n credentialsResolver({\n appId,\n providerId: request.providerId,\n connectionId: connection.id,\n keys: [...keys],\n userEmail: request.userEmail,\n orgId: request.orgId,\n }),\n requireCredentials: async (keys = reader.requiredCredentialKeys) => {\n const resolution = await credentialsResolver({\n appId,\n providerId: request.providerId,\n connectionId: connection.id,\n keys: [...keys],\n userEmail: request.userEmail,\n orgId: request.orgId,\n });\n if (!resolution.available) {\n throw new ProviderReaderRuntimeError(\n \"credentials_unavailable\",\n `Missing workspace connection credentials for ${reader.label}: ${resolution.missingKeys.join(\", \")}.`,\n {\n providerId: request.providerId,\n operation: request.operation,\n },\n );\n }\n return { values: resolution.values, resolution };\n },\n };\n\n return handler((request.params ?? {}) as TParams, context);\n },\n };\n}\n\nfunction cloneProviderReader(\n reader: ProviderReaderDefinition,\n): ProviderReaderDefinition {\n return {\n ...reader,\n credentialKeys: reader.credentialKeys.map((credential) => ({\n ...credential,\n })),\n requiredCredentialKeys: [...reader.requiredCredentialKeys],\n capabilities: reader.capabilities.map((capability) => ({\n ...capability,\n })),\n operations: reader.operations.map((operation) => ({\n ...operation,\n parameters: operation.parameters.map((parameter) => ({\n ...parameter,\n })),\n })),\n };\n}\n\nfunction publicRuntimeConnection(\n connection: WorkspaceConnectionForApp,\n): ProviderReaderRuntimeConnection {\n return {\n id: connection.id,\n provider: connection.provider,\n label: connection.label,\n accountId: connection.accountId,\n accountLabel: connection.accountLabel,\n credentialRefs: publicCredentialRefs(connection),\n };\n}\n\nfunction publicCredentialRefs(\n connection: WorkspaceConnectionForApp,\n): WorkspaceConnectionPublicCredentialRef[] {\n return [\n ...(connection.explicitGrant?.credentialRefs ?? []).map((ref) =>\n publicCredentialRef(ref, \"grant\"),\n ),\n ...connection.credentialRefs.map((ref) =>\n publicCredentialRef(ref, \"connection\"),\n ),\n ];\n}\n\nfunction publicCredentialRef(\n ref: WorkspaceConnectionCredentialRef,\n source: WorkspaceConnectionPublicCredentialRef[\"source\"],\n): WorkspaceConnectionPublicCredentialRef {\n return {\n key: ref.key,\n scope: ref.scope,\n provider: ref.provider,\n label: ref.label,\n source,\n };\n}\n"]}
|
|
@@ -2,6 +2,17 @@ export interface CredentialContext {
|
|
|
2
2
|
userEmail: string;
|
|
3
3
|
orgId?: string | null;
|
|
4
4
|
}
|
|
5
|
+
export type CredentialStorageScope = "user" | "org";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a credential from one explicit legacy SQL credential scope.
|
|
8
|
+
*
|
|
9
|
+
* Prefer `resolveCredential()` for normal app-local credential lookup. This
|
|
10
|
+
* helper exists for workspace connection refs, where a ref can explicitly say
|
|
11
|
+
* "use the org-scoped key" and must not accidentally read a user override.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveCredentialForScope(key: string, ctx: CredentialContext & {
|
|
14
|
+
scope: CredentialStorageScope;
|
|
15
|
+
}): Promise<string | undefined>;
|
|
5
16
|
/**
|
|
6
17
|
* Resolve a credential, scoped to the caller's user (and falling back to
|
|
7
18
|
* the active org's shared credential, if any).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credentials/index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credentials/index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,KAAK,CAAC;AAmBpD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,iBAAiB,GAAG;IAAE,KAAK,EAAE,sBAAsB,CAAA;CAAE,GACzD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAc7B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,iBAAiB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,GAClD,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,iBAAiB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,GAClD,OAAO,CAAC,IAAI,CAAC,CAcf"}
|