@opengeni/core 0.28.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/access/external-actor-authority.d.ts +47 -0
- package/dist/access/index.d.ts +182 -3
- package/dist/access/service-initiator.d.ts +3 -0
- package/dist/application/api-integration-servers.d.ts +20 -0
- package/dist/application/archived-session-imports.d.ts +6 -0
- package/dist/application/composer-submit.d.ts +24 -0
- package/dist/application/connect-authority.d.ts +13 -0
- package/dist/application/connect-operation.d.ts +31 -0
- package/dist/application/external-continuation.d.ts +15 -0
- package/dist/application/external-identity-lifecycle.d.ts +20 -0
- package/dist/application/external-link-work-admission.d.ts +12 -0
- package/dist/application/external-workspace-members.d.ts +34 -0
- package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
- package/dist/application/new-session-drafts.d.ts +39 -2
- package/dist/application/sandbox-recovery.d.ts +58 -0
- package/dist/application/session-commands.d.ts +26 -13
- package/dist/application/session-mcp-credential-rotation.d.ts +29 -0
- package/dist/application/session-tenancy.d.ts +19 -0
- package/dist/application/user-resource-grants.d.ts +20 -0
- package/dist/billing/limits.d.ts +11 -0
- package/dist/canonical-human-identities.d.ts +7 -2
- package/dist/canonical-human-identities.js +17 -4
- package/dist/canonical-human-identities.js.map +1 -1
- package/dist/{chunk-6WKPWE5S.js → chunk-2MKMRGSY.js} +108 -24
- package/dist/chunk-2MKMRGSY.js.map +1 -0
- package/dist/{chunk-NYPMQ7NO.js → chunk-GVO3N37G.js} +205 -37
- package/dist/chunk-GVO3N37G.js.map +1 -0
- package/dist/{chunk-JJU6I5XD.js → chunk-LCQXNR62.js} +36 -10
- package/dist/chunk-LCQXNR62.js.map +1 -0
- package/dist/chunk-MM6N7CTO.js +387 -0
- package/dist/chunk-MM6N7CTO.js.map +1 -0
- package/dist/chunk-QO5GVFFO.js +235 -0
- package/dist/chunk-QO5GVFFO.js.map +1 -0
- package/dist/codex-model-availability.d.ts +14 -0
- package/dist/default-session-model.d.ts +139 -0
- package/dist/dependencies.d.ts +87 -4
- package/dist/developer-setup-credential-ceiling.d.ts +10 -0
- package/dist/domain/agent-config-resolution.d.ts +49 -0
- package/dist/domain/automations.d.ts +58 -0
- package/dist/domain/capabilities.d.ts +22 -4
- package/dist/domain/company-profile-agent-admin.d.ts +25 -0
- package/dist/domain/connection-account-selection-error.d.ts +8 -0
- package/dist/domain/connector-tool-permissions.d.ts +36 -0
- package/dist/domain/direct-model-provider.d.ts +3 -0
- package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
- package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
- package/dist/domain/editable-artifacts/ports.d.ts +10 -0
- package/dist/domain/editable-artifacts/service.d.ts +4 -3
- package/dist/domain/environments.d.ts +5 -9
- package/dist/domain/external-creation-attribution.d.ts +6 -0
- package/dist/domain/file-owner.d.ts +8 -0
- package/dist/domain/github-action-policies.d.ts +36 -0
- package/dist/domain/github-repository-bindings.d.ts +117 -0
- package/dist/domain/github-skill-source.d.ts +5 -0
- package/dist/domain/governed-learning-slack-publication.d.ts +45 -0
- package/dist/domain/insights-timing.d.ts +16 -0
- package/dist/domain/insights-usage.d.ts +27 -0
- package/dist/domain/insights.d.ts +28 -1
- package/dist/domain/knowledge-files.d.ts +20 -0
- package/dist/domain/knowledge-messages.d.ts +39 -0
- package/dist/domain/knowledge-messages.test.d.ts +1 -0
- package/dist/domain/knowledge-preparation.d.ts +10 -0
- package/dist/domain/knowledge-preparation.test.d.ts +1 -0
- package/dist/domain/knowledge-search.d.ts +15 -0
- package/dist/domain/knowledge-search.test.d.ts +1 -0
- package/dist/domain/knowledge.d.ts +9 -0
- package/dist/domain/mcp-account-bindings.d.ts +19 -0
- package/dist/domain/mcp-account-routes.d.ts +21 -0
- package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
- package/dist/domain/organization-integration-catalog.d.ts +15 -0
- package/dist/domain/organization-membership-lifecycle.d.ts +1 -0
- package/dist/domain/personal-connection-delegations.d.ts +87 -4
- package/dist/domain/pr-review.d.ts +249 -0
- package/dist/domain/resources.d.ts +24 -3
- package/dist/domain/scheduled-task-access.d.ts +247 -0
- package/dist/domain/scheduled-tasks.d.ts +103 -6
- package/dist/domain/session-connection-accounts.d.ts +16 -0
- package/dist/domain/session-file-access.d.ts +4 -0
- package/dist/domain/session-native-connection-replacement.d.ts +14 -0
- package/dist/domain/session-start-timing.d.ts +7 -0
- package/dist/domain/session-tool-policy.d.ts +93 -4
- package/dist/domain/sessions.d.ts +275 -28
- package/dist/domain/skill-imports.d.ts +1 -0
- package/dist/domain/skill-search.d.ts +30 -0
- package/dist/domain/skills.d.ts +117 -0
- package/dist/domain/slack-bot.d.ts +46 -1
- package/dist/domain/workspace-members.d.ts +8 -1
- package/dist/editable-artifact-live/application.d.ts +12 -3
- package/dist/editable-artifact-live/ports.d.ts +0 -1
- package/dist/editable-artifact-live/server.d.ts +5 -2
- package/dist/editable-artifact-live/ticket.d.ts +2 -2
- package/dist/editable-artifact-live/types.d.ts +14 -2
- package/dist/editable-artifact-live.js +2 -2
- package/dist/editable-artifacts.js +10 -4
- package/dist/index.d.ts +49 -3
- package/dist/index.js +18826 -6847
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-sets.d.ts +131 -0
- package/dist/managed-auth-session-sets.js +51 -0
- package/dist/managed-auth-session-sets.js.map +1 -0
- package/dist/managed-session.d.ts +98 -11
- package/dist/model-catalog.d.ts +117 -0
- package/dist/product-usage-metrics.d.ts +30 -0
- package/dist/rigs/index.d.ts +22 -5
- package/dist/rigs/provider-images.d.ts +1 -1
- package/dist/sandbox/fleet.d.ts +59 -10
- package/dist/sandbox/routing.d.ts +22 -2
- package/dist/sandbox/runtime-settings.d.ts +56 -0
- package/dist/session-authorization.d.ts +38 -1
- package/dist/site-session-origin.d.ts +9 -0
- package/dist/transcription.d.ts +12 -1
- package/dist/turn-surface.d.ts +18 -0
- package/dist/user-presence.d.ts +32 -0
- package/package.json +18 -11
- package/src/access/external-actor-authority.ts +94 -0
- package/src/access/index.ts +1386 -44
- package/src/access/service-initiator.ts +50 -0
- package/src/application/api-integration-servers.ts +215 -0
- package/src/application/archived-session-imports.ts +161 -0
- package/src/application/composer-submit.ts +77 -0
- package/src/application/connect-authority.ts +77 -0
- package/src/application/connect-operation.ts +80 -0
- package/src/application/external-continuation.ts +129 -0
- package/src/application/external-identity-lifecycle.ts +48 -0
- package/src/application/external-link-work-admission.ts +90 -0
- package/src/application/external-workspace-members.ts +232 -0
- package/src/application/modal-native-worker-host-transport.ts +263 -0
- package/src/application/new-session-drafts.ts +222 -29
- package/src/application/sandbox-recovery.ts +78 -0
- package/src/application/session-commands.ts +430 -73
- package/src/application/session-mcp-credential-rotation.ts +217 -0
- package/src/application/session-tenancy.ts +445 -0
- package/src/application/user-resource-grants.ts +154 -0
- package/src/billing/limits.ts +103 -24
- package/src/canonical-human-identities.ts +22 -3
- package/src/codex-model-availability.ts +136 -0
- package/src/default-session-model.ts +656 -0
- package/src/dependencies.ts +97 -5
- package/src/developer-setup-credential-ceiling.ts +60 -0
- package/src/domain/agent-config-resolution.ts +148 -0
- package/src/domain/automations.ts +270 -0
- package/src/domain/capabilities.ts +244 -151
- package/src/domain/company-profile-agent-admin.ts +56 -0
- package/src/domain/connection-account-selection-error.ts +19 -0
- package/src/domain/connector-tool-permissions.ts +371 -0
- package/src/domain/direct-model-provider.ts +62 -0
- package/src/domain/editable-artifacts/agent-application.ts +61 -15
- package/src/domain/editable-artifacts/durable-export.ts +100 -5
- package/src/domain/editable-artifacts/in-memory.ts +6 -0
- package/src/domain/editable-artifacts/ports.ts +11 -0
- package/src/domain/editable-artifacts/service.ts +32 -1
- package/src/domain/editable-artifacts/snapshot-compaction.ts +9 -5
- package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +10 -8
- package/src/domain/editable-artifacts/snapshot-verifier.ts +10 -3
- package/src/domain/environments.ts +25 -45
- package/src/domain/external-creation-attribution.ts +22 -0
- package/src/domain/file-owner.ts +67 -0
- package/src/domain/github-action-policies.ts +169 -0
- package/src/domain/github-repository-bindings.ts +295 -0
- package/src/domain/github-skill-source.ts +233 -0
- package/src/domain/governed-learning-slack-publication.ts +157 -0
- package/src/domain/insights-timing.ts +95 -0
- package/src/domain/insights-usage.ts +67 -0
- package/src/domain/insights.ts +270 -169
- package/src/domain/knowledge-files.ts +46 -0
- package/src/domain/knowledge-messages.test.ts +91 -0
- package/src/domain/knowledge-messages.ts +106 -0
- package/src/domain/knowledge-preparation.test.ts +276 -0
- package/src/domain/knowledge-preparation.ts +147 -0
- package/src/domain/knowledge-search.test.ts +561 -0
- package/src/domain/knowledge-search.ts +256 -0
- package/src/domain/knowledge.ts +133 -0
- package/src/domain/mcp-account-bindings.ts +171 -0
- package/src/domain/mcp-account-routes.ts +121 -0
- package/src/domain/native-mcp-connection-admission.ts +14 -0
- package/src/domain/organization-integration-catalog.ts +88 -0
- package/src/domain/organization-membership-lifecycle.ts +10 -0
- package/src/domain/personal-connection-delegations.ts +758 -115
- package/src/domain/pr-review.ts +687 -0
- package/src/domain/resources.ts +182 -25
- package/src/domain/scheduled-task-access.ts +1052 -0
- package/src/domain/scheduled-tasks.ts +1952 -215
- package/src/domain/session-connection-accounts.ts +67 -0
- package/src/domain/session-file-access.ts +47 -0
- package/src/domain/session-native-connection-replacement.ts +64 -0
- package/src/domain/session-start-timing.ts +55 -0
- package/src/domain/session-tool-policy.ts +443 -19
- package/src/domain/sessions.ts +3417 -619
- package/src/domain/skill-imports.ts +137 -17
- package/src/domain/skill-search.ts +221 -0
- package/src/domain/skills.ts +104 -0
- package/src/domain/slack-bot.ts +128 -3
- package/src/domain/workspace-members.ts +34 -2
- package/src/editable-artifact-live/application.ts +29 -4
- package/src/editable-artifact-live/ports.ts +0 -1
- package/src/editable-artifact-live/server.ts +167 -13
- package/src/editable-artifact-live/ticket.ts +87 -6
- package/src/editable-artifact-live/types.ts +16 -2
- package/src/editable-artifact-live/wire.ts +0 -10
- package/src/index.ts +69 -4
- package/src/managed-auth-session-sets.ts +371 -0
- package/src/managed-session.ts +520 -2
- package/src/model-catalog.ts +873 -0
- package/src/product-usage-metrics.ts +101 -0
- package/src/rigs/index.ts +179 -63
- package/src/rigs/provider-images.ts +2 -3
- package/src/sandbox/fleet.ts +471 -59
- package/src/sandbox/routing.ts +160 -33
- package/src/sandbox/runtime-settings.ts +281 -0
- package/src/session-authorization.ts +262 -78
- package/src/site-session-origin.ts +22 -0
- package/src/transcription.ts +13 -1
- package/src/turn-surface.ts +45 -0
- package/src/user-presence.ts +134 -0
- package/dist/chunk-6WKPWE5S.js.map +0 -1
- package/dist/chunk-IBOEYG6N.js +0 -34
- package/dist/chunk-IBOEYG6N.js.map +0 -1
- package/dist/chunk-JJU6I5XD.js.map +0 -1
- package/dist/chunk-NYPMQ7NO.js.map +0 -1
- package/dist/domain/durable-learning-slack-publication.d.ts +0 -72
- package/dist/domain/packs.d.ts +0 -55
- package/src/domain/durable-learning-slack-publication.ts +0 -202
- package/src/domain/packs.ts +0 -556
package/src/domain/resources.ts
CHANGED
|
@@ -14,10 +14,18 @@ import {
|
|
|
14
14
|
ResourceRefConflictError,
|
|
15
15
|
ResourceMountPathError,
|
|
16
16
|
stableJson,
|
|
17
|
+
type RepositoryResourceRef,
|
|
17
18
|
type ResourceRef,
|
|
18
19
|
type ToolRef,
|
|
20
|
+
type WorkspaceSessionToolDefaults,
|
|
19
21
|
} from "@opengeni/contracts";
|
|
20
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
areGitHubRepositoriesAllowedForWorkspace,
|
|
24
|
+
requireFileForSubject,
|
|
25
|
+
withSessionRlsActorContext,
|
|
26
|
+
type SessionRlsActorContext,
|
|
27
|
+
type Database,
|
|
28
|
+
} from "@opengeni/db";
|
|
21
29
|
import { HTTPException } from "hono/http-exception";
|
|
22
30
|
|
|
23
31
|
export function validateToolRefs(tools: ToolRef[], settings: McpSettings): ToolRef[] {
|
|
@@ -36,17 +44,21 @@ export function validateToolRefs(tools: ToolRef[], settings: McpSettings): ToolR
|
|
|
36
44
|
}
|
|
37
45
|
throw new HTTPException(422, { message: `unknown MCP server id: ${tool.id}` });
|
|
38
46
|
}
|
|
39
|
-
|
|
47
|
+
|
|
40
48
|
// - bare / optional:false is STRICT: the id must be configured here and
|
|
41
|
-
// runtime connection failure fails
|
|
49
|
+
// runtime connection failure fails closed when preparation is demanded.
|
|
50
|
+
// Only an independent eager:true marker makes that a startup barrier.
|
|
42
51
|
// - optional:true + known id is preserved: runtime treats it like an
|
|
43
52
|
// auto-attached capability MCP and skips connect/list failures.
|
|
44
53
|
// - optional:true + unknown id is skipped above: the client explicitly
|
|
45
54
|
// opted into graceful degradation for MCPs (for example docs servers
|
|
46
55
|
// like context7) that only some deployments configure.
|
|
47
|
-
out.push(
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
out.push({
|
|
57
|
+
kind: "mcp",
|
|
58
|
+
id: tool.id,
|
|
59
|
+
...(optional ? { optional: true } : {}),
|
|
60
|
+
...(tool.eager === true ? { eager: true } : {}),
|
|
61
|
+
});
|
|
50
62
|
}
|
|
51
63
|
return mergeToolRefs([], out);
|
|
52
64
|
}
|
|
@@ -77,6 +89,38 @@ export function withDefaultEnabledCapabilityMcpTools(
|
|
|
77
89
|
return mergeToolRefs(tools, enabledCapabilityMcpToolRefs(settings, runtimeSettings));
|
|
78
90
|
}
|
|
79
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Apply the workspace's exact new-session MCP defaults when configured.
|
|
94
|
+
* Stale or currently unavailable ids are optional and disappear from the
|
|
95
|
+
* executable selection without making every new session fail during a rolling
|
|
96
|
+
* connector change. An absent workspace override preserves the legacy
|
|
97
|
+
* deployment + enabled-capability default.
|
|
98
|
+
*/
|
|
99
|
+
export function withWorkspaceDefaultMcpTools(
|
|
100
|
+
tools: ToolRef[],
|
|
101
|
+
settings: McpSettings,
|
|
102
|
+
runtimeSettings: McpSettings,
|
|
103
|
+
defaults: WorkspaceSessionToolDefaults | null,
|
|
104
|
+
): ToolRef[] {
|
|
105
|
+
if (!defaults?.mcpServerIds) {
|
|
106
|
+
return withDefaultEnabledCapabilityMcpTools(tools, settings, runtimeSettings);
|
|
107
|
+
}
|
|
108
|
+
return mergeToolRefs(
|
|
109
|
+
tools,
|
|
110
|
+
validateToolRefs(
|
|
111
|
+
[
|
|
112
|
+
...defaults.mcpServerIds,
|
|
113
|
+
...(defaults.inheritConnectedMcpServers
|
|
114
|
+
? runtimeSettings.mcpServers
|
|
115
|
+
.filter((server) => !["opengeni", "files", "docs"].includes(server.id))
|
|
116
|
+
.map((server) => server.id)
|
|
117
|
+
: []),
|
|
118
|
+
].map((id) => ({ kind: "mcp" as const, id, optional: true as const })),
|
|
119
|
+
runtimeSettings,
|
|
120
|
+
),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
80
124
|
/** Drop stored refs that are no longer present in the current runtime registry. */
|
|
81
125
|
export function availableToolRefs(tools: ToolRef[], settings: McpSettings): ToolRef[] {
|
|
82
126
|
const available = new Set(settings.mcpServers.map((server) => server.id));
|
|
@@ -161,6 +205,7 @@ export function normalizeResources(resources: ResourceRef[]): ResourceRef[] {
|
|
|
161
205
|
mountPath,
|
|
162
206
|
...(resource.subpath ? { subpath: normalizeRepositorySubpath(resource.subpath) } : {}),
|
|
163
207
|
...(resource.provider ? { provider: resource.provider } : {}),
|
|
208
|
+
...(resource.connectionType ? { connectionType: resource.connectionType } : {}),
|
|
164
209
|
...(resource.credentialBindingId
|
|
165
210
|
? { credentialBindingId: resource.credentialBindingId }
|
|
166
211
|
: {}),
|
|
@@ -175,6 +220,7 @@ export function normalizeResources(resources: ResourceRef[]): ResourceRef[] {
|
|
|
175
220
|
? { githubInstallationId: resource.githubInstallationId }
|
|
176
221
|
: {}),
|
|
177
222
|
...(resource.githubRepositoryId ? { githubRepositoryId: resource.githubRepositoryId } : {}),
|
|
223
|
+
...(resource.optional === true ? { optional: true } : {}),
|
|
178
224
|
};
|
|
179
225
|
}
|
|
180
226
|
const key = stableJson(normalized);
|
|
@@ -228,6 +274,97 @@ export function validateGitHubRepositorySelectionShapes(resources: ResourceRef[]
|
|
|
228
274
|
return [...new Set(selected.map((item) => item.installationId))];
|
|
229
275
|
}
|
|
230
276
|
|
|
277
|
+
export type PersonalGitHubRepositoryResource = RepositoryResourceRef & {
|
|
278
|
+
provider: "github";
|
|
279
|
+
connectionType: "github_personal";
|
|
280
|
+
credentialBindingId: string;
|
|
281
|
+
access: "read" | "write";
|
|
282
|
+
repositoryId: string;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const PERSONAL_GITHUB_BINDING_ID_PATTERN =
|
|
286
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
287
|
+
|
|
288
|
+
function isPersonalGitHubRepositoryCandidate(
|
|
289
|
+
resource: ResourceRef,
|
|
290
|
+
): resource is RepositoryResourceRef & { provider: "github"; credentialBindingId: string } {
|
|
291
|
+
if (resource.kind !== "repository" || resource.connectionType !== "github_personal") {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
return resource.provider === "github" && resource.credentialBindingId !== undefined;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Validate and return the dedicated personal-GitHub repository resource lane.
|
|
299
|
+
* A host-opaque binding is only a selector for the server-side authority
|
|
300
|
+
* snapshot; it never authorizes a repository on its own.
|
|
301
|
+
*/
|
|
302
|
+
export function personalGitHubRepositoryResources(
|
|
303
|
+
resources: ResourceRef[],
|
|
304
|
+
): PersonalGitHubRepositoryResource[] {
|
|
305
|
+
const selected: PersonalGitHubRepositoryResource[] = [];
|
|
306
|
+
for (const resource of resources) {
|
|
307
|
+
if (!isPersonalGitHubRepositoryCandidate(resource)) {
|
|
308
|
+
if (resource.kind === "repository" && resource.connectionType === "github_personal") {
|
|
309
|
+
throw new HTTPException(422, {
|
|
310
|
+
message: "personal GitHub repository resources require the dedicated GitHub provider",
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (
|
|
316
|
+
!PERSONAL_GITHUB_BINDING_ID_PATTERN.test(resource.credentialBindingId) ||
|
|
317
|
+
typeof resource.repositoryId !== "string" ||
|
|
318
|
+
!/^[1-9]\d*$/u.test(resource.repositoryId) ||
|
|
319
|
+
(resource.access !== "read" && resource.access !== "write") ||
|
|
320
|
+
resource.installationId !== undefined ||
|
|
321
|
+
resource.githubInstallationId !== undefined ||
|
|
322
|
+
resource.githubRepositoryId !== undefined ||
|
|
323
|
+
resource.connectionId !== undefined ||
|
|
324
|
+
resource.projectId !== undefined
|
|
325
|
+
) {
|
|
326
|
+
throw new HTTPException(422, {
|
|
327
|
+
message:
|
|
328
|
+
"personal GitHub repository resources require one opaque binding, provider repository id, and explicit read or write access",
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
let uri: URL;
|
|
332
|
+
try {
|
|
333
|
+
uri = new URL(resource.uri);
|
|
334
|
+
} catch {
|
|
335
|
+
throw new HTTPException(422, { message: "personal GitHub repository URI is invalid" });
|
|
336
|
+
}
|
|
337
|
+
if (
|
|
338
|
+
uri.protocol !== "https:" ||
|
|
339
|
+
uri.hostname !== "github.com" ||
|
|
340
|
+
uri.port !== "" ||
|
|
341
|
+
uri.username !== "" ||
|
|
342
|
+
uri.password !== "" ||
|
|
343
|
+
uri.search !== "" ||
|
|
344
|
+
uri.hash !== "" ||
|
|
345
|
+
uri.pathname.endsWith(".git") ||
|
|
346
|
+
uri.pathname.split("/").filter(Boolean).length !== 2 ||
|
|
347
|
+
resource.uri !== `${uri.origin}${uri.pathname.replace(/\/$/u, "")}`
|
|
348
|
+
) {
|
|
349
|
+
throw new HTTPException(422, {
|
|
350
|
+
message: "personal GitHub repository resources require a canonical GitHub HTTPS URI",
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
selected.push(resource as PersonalGitHubRepositoryResource);
|
|
354
|
+
}
|
|
355
|
+
const identities = new Set<string>();
|
|
356
|
+
for (const resource of selected) {
|
|
357
|
+
const key = `${resource.credentialBindingId}\0${resource.repositoryId}`;
|
|
358
|
+
if (identities.has(key)) {
|
|
359
|
+
throw new HTTPException(422, {
|
|
360
|
+
message: "personal GitHub repository resources must not contain duplicates",
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
identities.add(key);
|
|
364
|
+
}
|
|
365
|
+
return selected;
|
|
366
|
+
}
|
|
367
|
+
|
|
231
368
|
/** @deprecated Use validateGitHubRepositorySelectionShapes for multi-installation sessions. */
|
|
232
369
|
export function validateGitHubRepositorySelectionShape(resources: ResourceRef[]): number | null {
|
|
233
370
|
const installationIds = validateGitHubRepositorySelectionShapes(resources);
|
|
@@ -246,6 +383,9 @@ function gitHubRepositorySelections(
|
|
|
246
383
|
if (resource.kind !== "repository") {
|
|
247
384
|
return [];
|
|
248
385
|
}
|
|
386
|
+
if (isPersonalGitHubRepositoryCandidate(resource)) {
|
|
387
|
+
return [];
|
|
388
|
+
}
|
|
249
389
|
const installationRaw =
|
|
250
390
|
resource.githubInstallationId ??
|
|
251
391
|
(resource.provider === "github" ? resource.installationId : undefined);
|
|
@@ -275,6 +415,7 @@ export async function validateGitHubRepositorySelection(
|
|
|
275
415
|
workspaceId: string,
|
|
276
416
|
resources: ResourceRef[],
|
|
277
417
|
): Promise<void> {
|
|
418
|
+
personalGitHubRepositoryResources(resources);
|
|
278
419
|
const installationIds = validateGitHubRepositorySelectionShapes(resources);
|
|
279
420
|
if (installationIds.length === 0) {
|
|
280
421
|
return;
|
|
@@ -311,28 +452,44 @@ export function isAuthoritativeGitHubRepositorySelectionError(error: unknown): b
|
|
|
311
452
|
|
|
312
453
|
export async function validateFileResources(
|
|
313
454
|
db: Database,
|
|
455
|
+
accountId: string,
|
|
314
456
|
workspaceId: string,
|
|
457
|
+
subjectId: string | null,
|
|
315
458
|
resources: ResourceRef[],
|
|
459
|
+
privateFileContext?: SessionRlsActorContext,
|
|
316
460
|
): Promise<void> {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
461
|
+
return withSessionRlsActorContext(
|
|
462
|
+
privateFileContext ?? {
|
|
463
|
+
subjectId: subjectId ?? "service:file-resource-validation",
|
|
464
|
+
privateFileOwnerSubjectId: null,
|
|
465
|
+
},
|
|
466
|
+
async () => {
|
|
467
|
+
const fileIds = new Set<string>();
|
|
468
|
+
for (const resource of resources) {
|
|
469
|
+
if (resource.kind !== "file") {
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
if (fileIds.has(resource.fileId)) {
|
|
473
|
+
throw new HTTPException(422, { message: `duplicate file resource: ${resource.fileId}` });
|
|
474
|
+
}
|
|
475
|
+
fileIds.add(resource.fileId);
|
|
476
|
+
const file = await requireFileForSubject(db, {
|
|
477
|
+
accountId,
|
|
478
|
+
workspaceId,
|
|
479
|
+
subjectId: privateFileContext?.initiatingHumanSubjectId ?? subjectId,
|
|
480
|
+
fileId: resource.fileId,
|
|
481
|
+
}).catch(() => null);
|
|
482
|
+
if (!file) {
|
|
483
|
+
throw new HTTPException(422, { message: `unknown file resource: ${resource.fileId}` });
|
|
484
|
+
}
|
|
485
|
+
if (file.status !== "ready") {
|
|
486
|
+
throw new HTTPException(422, {
|
|
487
|
+
message: `file resource ${resource.fileId} is ${file.status}`,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
);
|
|
336
493
|
}
|
|
337
494
|
|
|
338
495
|
function normalizeMountPath(path: string): string {
|