@opengeni/core 2.6.4 → 2.7.5-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.
- package/dist/access/index.d.ts +10 -0
- package/dist/application/api-integration-servers.d.ts +20 -0
- package/dist/billing/limits.d.ts +5 -0
- package/dist/dependencies.d.ts +12 -1
- package/dist/domain/host-mcp-authority-source-admission.d.ts +10 -0
- package/dist/domain/packs.d.ts +1 -0
- package/dist/domain/pr-review.d.ts +1 -1
- package/dist/domain/product-integration-pack.d.ts +50 -0
- package/dist/domain/sessions.d.ts +25 -11
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2360 -687
- package/dist/index.js.map +1 -1
- package/dist/model-catalog.d.ts +105 -0
- package/dist/sandbox/fleet.d.ts +19 -0
- package/package.json +12 -10
- package/src/access/index.ts +25 -0
- package/src/application/api-integration-servers.ts +215 -0
- package/src/application/session-commands.ts +2 -2
- package/src/billing/limits.ts +52 -22
- package/src/dependencies.ts +17 -1
- package/src/domain/capabilities.ts +19 -3
- package/src/domain/host-mcp-authority-source-admission.ts +25 -0
- package/src/domain/insights.ts +32 -0
- package/src/domain/packs.ts +48 -18
- package/src/domain/personal-connection-delegations.ts +14 -6
- package/src/domain/product-integration-pack.ts +494 -0
- package/src/domain/scheduled-tasks.ts +43 -1
- package/src/domain/sessions.ts +964 -386
- package/src/index.ts +4 -0
- package/src/model-catalog.ts +742 -0
- package/src/sandbox/fleet.ts +85 -23
- package/src/sandbox/routing.ts +6 -9
package/src/sandbox/fleet.ts
CHANGED
|
@@ -454,31 +454,18 @@ export async function listFleet(
|
|
|
454
454
|
};
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
457
|
+
type FleetResourceContext = Pick<FleetContext, "accountId" | "workspaceId" | "subjectId">;
|
|
458
|
+
|
|
459
|
+
type ResolvedNamedSandboxTarget =
|
|
460
|
+
| { ok: true; targetSandboxId: string; workspaceRoot?: string }
|
|
461
|
+
| { ok: false; reason: string; code: BackendUnresolvableCode };
|
|
462
|
+
|
|
463
|
+
/** Resolve one named sandbox, independent of any existing session pointer. */
|
|
464
|
+
async function resolveNamedSandboxTarget(
|
|
461
465
|
services: FleetServices,
|
|
462
|
-
ctx:
|
|
466
|
+
ctx: FleetResourceContext,
|
|
463
467
|
target: string,
|
|
464
|
-
): Promise<
|
|
465
|
-
| { ok: true; targetSandboxId: string | null; workspaceRoot?: string }
|
|
466
|
-
| { ok: false; reason: string; code: BackendUnresolvableCode }
|
|
467
|
-
> {
|
|
468
|
-
// The session's own group box → the default pointer (null).
|
|
469
|
-
if (target === ctx.sessionGroupId || target === "session" || target === "default") {
|
|
470
|
-
if (!managedSessionGroupBackend(services.settings.sandboxBackend, ctx.sessionBackend)) {
|
|
471
|
-
return {
|
|
472
|
-
ok: false,
|
|
473
|
-
reason:
|
|
474
|
-
ctx.sessionBackend === "none"
|
|
475
|
-
? "this session has no home sandbox; attach a Connected Machine"
|
|
476
|
-
: "this deployment has no managed session sandbox; select an enrolled machine",
|
|
477
|
-
code: "unsupported_backend_context",
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
return { ok: true, targetSandboxId: null };
|
|
481
|
-
}
|
|
468
|
+
): Promise<ResolvedNamedSandboxTarget> {
|
|
482
469
|
const sandbox = await getSandbox(
|
|
483
470
|
services.db,
|
|
484
471
|
ctx.subjectId
|
|
@@ -566,6 +553,81 @@ async function resolveTarget(
|
|
|
566
553
|
};
|
|
567
554
|
}
|
|
568
555
|
|
|
556
|
+
export type CreateTimeSandboxTargetPreflight =
|
|
557
|
+
| { ok: true; targetSandboxId: string; workingDir: string | null }
|
|
558
|
+
| {
|
|
559
|
+
ok: false;
|
|
560
|
+
reason: string;
|
|
561
|
+
code: BackendUnresolvableCode | "invalid_working_directory";
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Validate a named create-time machine target before any session row exists.
|
|
566
|
+
* The caller still commits the pointer with `setActiveSandbox` inside the
|
|
567
|
+
* session-create transaction, which rechecks durable ownership/enrollment
|
|
568
|
+
* authority and closes the remove/revoke race without holding database locks
|
|
569
|
+
* across the liveness probe.
|
|
570
|
+
*/
|
|
571
|
+
export async function preflightCreateTimeSandboxTarget(
|
|
572
|
+
services: FleetServices,
|
|
573
|
+
ctx: FleetResourceContext,
|
|
574
|
+
target: string,
|
|
575
|
+
workingDir: string | null,
|
|
576
|
+
): Promise<CreateTimeSandboxTargetPreflight> {
|
|
577
|
+
const resolved = await resolveNamedSandboxTarget(services, ctx, target);
|
|
578
|
+
if (!resolved.ok) return resolved;
|
|
579
|
+
if (!resolved.workspaceRoot) {
|
|
580
|
+
return {
|
|
581
|
+
ok: true,
|
|
582
|
+
targetSandboxId: resolved.targetSandboxId,
|
|
583
|
+
workingDir,
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
try {
|
|
587
|
+
return {
|
|
588
|
+
ok: true,
|
|
589
|
+
targetSandboxId: resolved.targetSandboxId,
|
|
590
|
+
workingDir:
|
|
591
|
+
resolveConnectedMachineWorkspaceRoot(resolved.workspaceRoot, workingDir) ??
|
|
592
|
+
resolved.workspaceRoot,
|
|
593
|
+
};
|
|
594
|
+
} catch (error) {
|
|
595
|
+
return {
|
|
596
|
+
ok: false,
|
|
597
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
598
|
+
code: "invalid_working_directory",
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/** Resolve a swap target id → the value `setActiveSandbox` writes. The session's
|
|
604
|
+
* own group id maps to NULL (the default pointer); a first-class sandbox id is
|
|
605
|
+
* validated (workspace ownership + liveness) and written verbatim. */
|
|
606
|
+
async function resolveTarget(
|
|
607
|
+
services: FleetServices,
|
|
608
|
+
ctx: FleetContext,
|
|
609
|
+
target: string,
|
|
610
|
+
): Promise<
|
|
611
|
+
| { ok: true; targetSandboxId: string | null; workspaceRoot?: string }
|
|
612
|
+
| { ok: false; reason: string; code: BackendUnresolvableCode }
|
|
613
|
+
> {
|
|
614
|
+
// The session's own group box → the default pointer (null).
|
|
615
|
+
if (target === ctx.sessionGroupId || target === "session" || target === "default") {
|
|
616
|
+
if (!managedSessionGroupBackend(services.settings.sandboxBackend, ctx.sessionBackend)) {
|
|
617
|
+
return {
|
|
618
|
+
ok: false,
|
|
619
|
+
reason:
|
|
620
|
+
ctx.sessionBackend === "none"
|
|
621
|
+
? "this session has no home sandbox; attach a Connected Machine"
|
|
622
|
+
: "this deployment has no managed session sandbox; select an enrolled machine",
|
|
623
|
+
code: "unsupported_backend_context",
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
return { ok: true, targetSandboxId: null };
|
|
627
|
+
}
|
|
628
|
+
return await resolveNamedSandboxTarget(services, ctx, target);
|
|
629
|
+
}
|
|
630
|
+
|
|
569
631
|
/**
|
|
570
632
|
* THE SWAP (and attach — identical mechanic). Validate the target's ownership +
|
|
571
633
|
* liveness, then repoint the session via the epoch-fenced CAS `setActiveSandbox`:
|
package/src/sandbox/routing.ts
CHANGED
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
type SandboxRetainedProcess,
|
|
30
30
|
type SandboxWorkspaceMutationAdmission,
|
|
31
31
|
} from "@opengeni/db";
|
|
32
|
-
import { settleSessionBackgroundCommandForRetainedProcess } from "@opengeni/db/session-background-commands";
|
|
33
32
|
import { appendAndPublishEvents, type EventBus } from "@opengeni/events";
|
|
34
33
|
import {
|
|
35
34
|
isProviderSandboxGoneDuringRoutedOperation,
|
|
@@ -449,14 +448,11 @@ export function wrapChannelABoxWithRouting(
|
|
|
449
448
|
reason: proof.reason,
|
|
450
449
|
idleGraceMs: settings.sandboxIdleGraceMs,
|
|
451
450
|
});
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
retainedProcessId: process.id,
|
|
458
|
-
...backgroundSettlement,
|
|
459
|
-
});
|
|
451
|
+
if (settlement.backgroundCommandEvents.length > 0 && bus) {
|
|
452
|
+
await bus
|
|
453
|
+
.publish(ids.workspaceId, ids.sessionId, settlement.backgroundCommandEvents)
|
|
454
|
+
.catch(() => undefined);
|
|
455
|
+
}
|
|
460
456
|
}
|
|
461
457
|
: undefined;
|
|
462
458
|
const resolver = makeActiveBackendResolver({
|
|
@@ -520,6 +516,7 @@ export function wrapChannelABoxWithRouting(
|
|
|
520
516
|
});
|
|
521
517
|
|
|
522
518
|
const proxy = new RoutingSandboxSession({
|
|
519
|
+
bindActiveRouteOnFirstResolve: true,
|
|
523
520
|
defaultResolved: {
|
|
524
521
|
session: established.session as RoutableBackendSession,
|
|
525
522
|
sandboxId: null,
|