@opengeni/core 0.28.1 → 2.1.0-canary.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.
Files changed (99) hide show
  1. package/dist/access/index.d.ts +37 -0
  2. package/dist/application/new-session-drafts.d.ts +8 -1
  3. package/dist/application/session-commands.d.ts +18 -11
  4. package/dist/application/session-tenancy.d.ts +18 -0
  5. package/dist/application/user-resource-grants.d.ts +20 -0
  6. package/dist/{chunk-6WKPWE5S.js → chunk-H7X52RI2.js} +27 -18
  7. package/dist/chunk-H7X52RI2.js.map +1 -0
  8. package/dist/{chunk-JJU6I5XD.js → chunk-VCZFFEPB.js} +21 -9
  9. package/dist/chunk-VCZFFEPB.js.map +1 -0
  10. package/dist/{chunk-NYPMQ7NO.js → chunk-ZYCNLYGH.js} +29 -27
  11. package/dist/chunk-ZYCNLYGH.js.map +1 -0
  12. package/dist/dependencies.d.ts +12 -1
  13. package/dist/domain/automations.d.ts +51 -0
  14. package/dist/domain/company-brain-governed-writes.d.ts +70 -0
  15. package/dist/domain/company-profile-agent-admin.d.ts +24 -0
  16. package/dist/domain/connection-authority.d.ts +97 -0
  17. package/dist/domain/connection-authority.js +169 -0
  18. package/dist/domain/connection-authority.js.map +1 -0
  19. package/dist/domain/editable-artifacts/service.d.ts +1 -2
  20. package/dist/domain/environments.d.ts +1 -1
  21. package/dist/domain/github-repository-bindings.d.ts +117 -0
  22. package/dist/domain/governed-learning-activation.d.ts +16 -0
  23. package/dist/domain/governed-learning-evaluator.d.ts +6 -0
  24. package/dist/domain/governed-learning-slack-publication.d.ts +45 -0
  25. package/dist/domain/memory-slack-delivery.d.ts +1 -4
  26. package/dist/domain/organization-membership-lifecycle.d.ts +1 -0
  27. package/dist/domain/packs.d.ts +5 -1
  28. package/dist/domain/personal-connection-delegations.d.ts +44 -2
  29. package/dist/domain/pr-review.d.ts +149 -0
  30. package/dist/domain/remember.d.ts +69 -0
  31. package/dist/domain/resources.d.ts +23 -2
  32. package/dist/domain/scheduled-tasks.d.ts +43 -2
  33. package/dist/domain/session-tool-policy.d.ts +1 -1
  34. package/dist/domain/sessions.d.ts +43 -9
  35. package/dist/editable-artifact-live/application.d.ts +10 -2
  36. package/dist/editable-artifact-live/ports.d.ts +0 -1
  37. package/dist/editable-artifact-live/server.d.ts +0 -1
  38. package/dist/editable-artifact-live/ticket.d.ts +0 -1
  39. package/dist/editable-artifact-live/types.d.ts +5 -2
  40. package/dist/editable-artifact-live.js +2 -2
  41. package/dist/editable-artifacts.js +2 -4
  42. package/dist/index.d.ts +13 -1
  43. package/dist/index.js +4973 -1243
  44. package/dist/index.js.map +1 -1
  45. package/dist/rigs/index.d.ts +22 -5
  46. package/dist/sandbox/fleet.d.ts +34 -6
  47. package/dist/sandbox/routing.d.ts +15 -1
  48. package/dist/sandbox/runtime-settings.d.ts +39 -0
  49. package/package.json +16 -11
  50. package/src/access/index.ts +151 -31
  51. package/src/application/new-session-drafts.ts +32 -5
  52. package/src/application/session-commands.ts +305 -71
  53. package/src/application/session-tenancy.ts +321 -0
  54. package/src/application/user-resource-grants.ts +140 -0
  55. package/src/billing/limits.ts +25 -15
  56. package/src/dependencies.ts +12 -1
  57. package/src/domain/automations.ts +196 -0
  58. package/src/domain/capabilities.ts +7 -1
  59. package/src/domain/company-brain-governed-writes.ts +330 -0
  60. package/src/domain/company-profile-agent-admin.ts +55 -0
  61. package/src/domain/connection-authority.ts +329 -0
  62. package/src/domain/editable-artifacts/agent-application.ts +17 -9
  63. package/src/domain/editable-artifacts/service.ts +12 -1
  64. package/src/domain/editable-artifacts/snapshot-compaction.ts +9 -5
  65. package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +10 -8
  66. package/src/domain/editable-artifacts/snapshot-verifier.ts +10 -3
  67. package/src/domain/environments.ts +16 -3
  68. package/src/domain/github-repository-bindings.ts +295 -0
  69. package/src/domain/governed-learning-activation.ts +44 -0
  70. package/src/domain/governed-learning-evaluator.ts +49 -0
  71. package/src/domain/governed-learning-slack-publication.ts +157 -0
  72. package/src/domain/insights.ts +9 -0
  73. package/src/domain/memory-slack-delivery.ts +0 -30
  74. package/src/domain/organization-membership-lifecycle.ts +9 -0
  75. package/src/domain/packs.ts +106 -3
  76. package/src/domain/personal-connection-delegations.ts +597 -42
  77. package/src/domain/pr-review.ts +671 -0
  78. package/src/domain/remember.ts +549 -0
  79. package/src/domain/resources.ts +144 -6
  80. package/src/domain/scheduled-tasks.ts +504 -77
  81. package/src/domain/session-tool-policy.ts +12 -9
  82. package/src/domain/sessions.ts +629 -176
  83. package/src/editable-artifact-live/application.ts +21 -3
  84. package/src/editable-artifact-live/ports.ts +0 -1
  85. package/src/editable-artifact-live/server.ts +13 -7
  86. package/src/editable-artifact-live/ticket.ts +1 -5
  87. package/src/editable-artifact-live/types.ts +6 -2
  88. package/src/editable-artifact-live/wire.ts +0 -10
  89. package/src/index.ts +13 -1
  90. package/src/rigs/index.ts +165 -48
  91. package/src/sandbox/fleet.ts +376 -30
  92. package/src/sandbox/routing.ts +91 -29
  93. package/src/sandbox/runtime-settings.ts +274 -0
  94. package/src/session-authorization.ts +17 -49
  95. package/dist/chunk-6WKPWE5S.js.map +0 -1
  96. package/dist/chunk-JJU6I5XD.js.map +0 -1
  97. package/dist/chunk-NYPMQ7NO.js.map +0 -1
  98. package/dist/domain/durable-learning-slack-publication.d.ts +0 -72
  99. package/src/domain/durable-learning-slack-publication.ts +0 -202
@@ -14,10 +14,16 @@ 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 { areGitHubRepositoriesAllowedForWorkspace, requireFile, type Database } from "@opengeni/db";
22
+ import {
23
+ areGitHubRepositoriesAllowedForWorkspace,
24
+ requireFileForSubject,
25
+ type Database,
26
+ } from "@opengeni/db";
21
27
  import { HTTPException } from "hono/http-exception";
22
28
 
23
29
  export function validateToolRefs(tools: ToolRef[], settings: McpSettings): ToolRef[] {
@@ -38,15 +44,19 @@ export function validateToolRefs(tools: ToolRef[], settings: McpSettings): ToolR
38
44
  }
39
45
  // Tool refs are tri-state for pack portability across deployments:
40
46
  // - bare / optional:false is STRICT: the id must be configured here and
41
- // runtime connection failure fails the turn.
47
+ // runtime connection failure fails closed when preparation is demanded.
48
+ // Only an independent eager:true marker makes that a startup barrier.
42
49
  // - optional:true + known id is preserved: runtime treats it like an
43
50
  // auto-attached capability MCP and skips connect/list failures.
44
51
  // - optional:true + unknown id is skipped above: the client explicitly
45
52
  // opted into graceful degradation for MCPs (for example docs servers
46
53
  // like context7) that only some deployments configure.
47
- out.push(
48
- optional ? { kind: "mcp", id: tool.id, optional: true } : { kind: "mcp", id: tool.id },
49
- );
54
+ out.push({
55
+ kind: "mcp",
56
+ id: tool.id,
57
+ ...(optional ? { optional: true } : {}),
58
+ ...(tool.eager === true ? { eager: true } : {}),
59
+ });
50
60
  }
51
61
  return mergeToolRefs([], out);
52
62
  }
@@ -77,6 +87,31 @@ export function withDefaultEnabledCapabilityMcpTools(
77
87
  return mergeToolRefs(tools, enabledCapabilityMcpToolRefs(settings, runtimeSettings));
78
88
  }
79
89
 
90
+ /**
91
+ * Apply the workspace's exact new-session MCP defaults when configured.
92
+ * Stale or currently unavailable ids are optional and disappear from the
93
+ * executable selection without making every new session fail during a rolling
94
+ * connector change. An absent workspace override preserves the legacy
95
+ * deployment + enabled-capability default.
96
+ */
97
+ export function withWorkspaceDefaultMcpTools(
98
+ tools: ToolRef[],
99
+ settings: McpSettings,
100
+ runtimeSettings: McpSettings,
101
+ defaults: WorkspaceSessionToolDefaults | null,
102
+ ): ToolRef[] {
103
+ if (!defaults) {
104
+ return withDefaultEnabledCapabilityMcpTools(tools, settings, runtimeSettings);
105
+ }
106
+ return mergeToolRefs(
107
+ tools,
108
+ validateToolRefs(
109
+ defaults.mcpServerIds.map((id) => ({ kind: "mcp" as const, id, optional: true as const })),
110
+ runtimeSettings,
111
+ ),
112
+ );
113
+ }
114
+
80
115
  /** Drop stored refs that are no longer present in the current runtime registry. */
81
116
  export function availableToolRefs(tools: ToolRef[], settings: McpSettings): ToolRef[] {
82
117
  const available = new Set(settings.mcpServers.map((server) => server.id));
@@ -161,6 +196,7 @@ export function normalizeResources(resources: ResourceRef[]): ResourceRef[] {
161
196
  mountPath,
162
197
  ...(resource.subpath ? { subpath: normalizeRepositorySubpath(resource.subpath) } : {}),
163
198
  ...(resource.provider ? { provider: resource.provider } : {}),
199
+ ...(resource.connectionType ? { connectionType: resource.connectionType } : {}),
164
200
  ...(resource.credentialBindingId
165
201
  ? { credentialBindingId: resource.credentialBindingId }
166
202
  : {}),
@@ -228,6 +264,97 @@ export function validateGitHubRepositorySelectionShapes(resources: ResourceRef[]
228
264
  return [...new Set(selected.map((item) => item.installationId))];
229
265
  }
230
266
 
267
+ export type PersonalGitHubRepositoryResource = RepositoryResourceRef & {
268
+ provider: "github";
269
+ connectionType: "github_personal";
270
+ credentialBindingId: string;
271
+ access: "read" | "write";
272
+ repositoryId: string;
273
+ };
274
+
275
+ const PERSONAL_GITHUB_BINDING_ID_PATTERN =
276
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
277
+
278
+ function isPersonalGitHubRepositoryCandidate(
279
+ resource: ResourceRef,
280
+ ): resource is RepositoryResourceRef & { provider: "github"; credentialBindingId: string } {
281
+ if (resource.kind !== "repository" || resource.connectionType !== "github_personal") {
282
+ return false;
283
+ }
284
+ return resource.provider === "github" && resource.credentialBindingId !== undefined;
285
+ }
286
+
287
+ /**
288
+ * Validate and return the dedicated personal-GitHub repository resource lane.
289
+ * A host-opaque binding is only a selector for the server-side authority
290
+ * snapshot; it never authorizes a repository on its own.
291
+ */
292
+ export function personalGitHubRepositoryResources(
293
+ resources: ResourceRef[],
294
+ ): PersonalGitHubRepositoryResource[] {
295
+ const selected: PersonalGitHubRepositoryResource[] = [];
296
+ for (const resource of resources) {
297
+ if (!isPersonalGitHubRepositoryCandidate(resource)) {
298
+ if (resource.kind === "repository" && resource.connectionType === "github_personal") {
299
+ throw new HTTPException(422, {
300
+ message: "personal GitHub repository resources require the dedicated GitHub provider",
301
+ });
302
+ }
303
+ continue;
304
+ }
305
+ if (
306
+ !PERSONAL_GITHUB_BINDING_ID_PATTERN.test(resource.credentialBindingId) ||
307
+ typeof resource.repositoryId !== "string" ||
308
+ !/^[1-9]\d*$/u.test(resource.repositoryId) ||
309
+ (resource.access !== "read" && resource.access !== "write") ||
310
+ resource.installationId !== undefined ||
311
+ resource.githubInstallationId !== undefined ||
312
+ resource.githubRepositoryId !== undefined ||
313
+ resource.connectionId !== undefined ||
314
+ resource.projectId !== undefined
315
+ ) {
316
+ throw new HTTPException(422, {
317
+ message:
318
+ "personal GitHub repository resources require one opaque binding, provider repository id, and explicit read or write access",
319
+ });
320
+ }
321
+ let uri: URL;
322
+ try {
323
+ uri = new URL(resource.uri);
324
+ } catch {
325
+ throw new HTTPException(422, { message: "personal GitHub repository URI is invalid" });
326
+ }
327
+ if (
328
+ uri.protocol !== "https:" ||
329
+ uri.hostname !== "github.com" ||
330
+ uri.port !== "" ||
331
+ uri.username !== "" ||
332
+ uri.password !== "" ||
333
+ uri.search !== "" ||
334
+ uri.hash !== "" ||
335
+ uri.pathname.endsWith(".git") ||
336
+ uri.pathname.split("/").filter(Boolean).length !== 2 ||
337
+ resource.uri !== `${uri.origin}${uri.pathname.replace(/\/$/u, "")}`
338
+ ) {
339
+ throw new HTTPException(422, {
340
+ message: "personal GitHub repository resources require a canonical GitHub HTTPS URI",
341
+ });
342
+ }
343
+ selected.push(resource as PersonalGitHubRepositoryResource);
344
+ }
345
+ const identities = new Set<string>();
346
+ for (const resource of selected) {
347
+ const key = `${resource.credentialBindingId}\0${resource.repositoryId}`;
348
+ if (identities.has(key)) {
349
+ throw new HTTPException(422, {
350
+ message: "personal GitHub repository resources must not contain duplicates",
351
+ });
352
+ }
353
+ identities.add(key);
354
+ }
355
+ return selected;
356
+ }
357
+
231
358
  /** @deprecated Use validateGitHubRepositorySelectionShapes for multi-installation sessions. */
232
359
  export function validateGitHubRepositorySelectionShape(resources: ResourceRef[]): number | null {
233
360
  const installationIds = validateGitHubRepositorySelectionShapes(resources);
@@ -246,6 +373,9 @@ function gitHubRepositorySelections(
246
373
  if (resource.kind !== "repository") {
247
374
  return [];
248
375
  }
376
+ if (isPersonalGitHubRepositoryCandidate(resource)) {
377
+ return [];
378
+ }
249
379
  const installationRaw =
250
380
  resource.githubInstallationId ??
251
381
  (resource.provider === "github" ? resource.installationId : undefined);
@@ -275,6 +405,7 @@ export async function validateGitHubRepositorySelection(
275
405
  workspaceId: string,
276
406
  resources: ResourceRef[],
277
407
  ): Promise<void> {
408
+ personalGitHubRepositoryResources(resources);
278
409
  const installationIds = validateGitHubRepositorySelectionShapes(resources);
279
410
  if (installationIds.length === 0) {
280
411
  return;
@@ -311,7 +442,9 @@ export function isAuthoritativeGitHubRepositorySelectionError(error: unknown): b
311
442
 
312
443
  export async function validateFileResources(
313
444
  db: Database,
445
+ accountId: string,
314
446
  workspaceId: string,
447
+ subjectId: string,
315
448
  resources: ResourceRef[],
316
449
  ): Promise<void> {
317
450
  const fileIds = new Set<string>();
@@ -323,7 +456,12 @@ export async function validateFileResources(
323
456
  throw new HTTPException(422, { message: `duplicate file resource: ${resource.fileId}` });
324
457
  }
325
458
  fileIds.add(resource.fileId);
326
- const file = await requireFile(db, workspaceId, resource.fileId).catch(() => null);
459
+ const file = await requireFileForSubject(db, {
460
+ accountId,
461
+ workspaceId,
462
+ subjectId,
463
+ fileId: resource.fileId,
464
+ }).catch(() => null);
327
465
  if (!file) {
328
466
  throw new HTTPException(422, { message: `unknown file resource: ${resource.fileId}` });
329
467
  }