@moondeck/station 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +149 -2
- package/bin/uai-host.mjs +130 -0
- package/db/migrations/0000_host_tasks.sql +12 -0
- package/db/migrations/0001_host_ui.sql +11 -0
- package/db/migrations/0002_host_github_tokens.sql +8 -0
- package/db/migrations/0003_host_ssh_keys.sql +8 -0
- package/db/migrations/0004_host_owner_name.sql +1 -0
- package/db/migrations/0005_host_env_vars.sql +5 -0
- package/db/migrations/0006_host_project_env.sql +9 -0
- package/db/migrations/0007_host_github_token_kind.sql +7 -0
- package/db/migrations/0008_host_mcp_connections.sql +18 -0
- package/db/migrations/0009_host_agent_sessions.sql +15 -0
- package/db/migrations/0010_host_engine_accounts.sql +13 -0
- package/db/migrations/0011_codex_thread_id.sql +5 -0
- package/db/migrations/0012_agent_session_attach_key.sql +4 -0
- package/db/migrations/0013_github_credential_generations.sql +11 -0
- package/db/migrations/0014_host_inventory_event_index.sql +1 -0
- package/db/migrations/0015_host_settings.sql +9 -0
- package/db/migrations/0016_task_environment.sql +2 -0
- package/db/migrations/0017_engine_account_scope.sql +7 -0
- package/db/migrations/0018_engine_account_position.sql +3 -0
- package/db/migrations/0019_engine_account_store_ref.sql +3 -0
- package/db/migrations/0020_user_credential_store_ref.sql +6 -0
- package/db/migrations/0021_project_env_store_ref.sql +3 -0
- package/db/migrations/0022_task_project_ids.sql +5 -0
- package/db/migrations/0023_project_env_org.sql +4 -0
- package/db/migrations/0024_task_env_mode.sql +9 -0
- package/db/migrations/0025_project_env_authority.sql +147 -0
- package/db/migrations/0026_project_env_replica.sql +150 -0
- package/db/migrations/0027_cloud_credential_foundation.sql +51 -0
- package/db/migrations/0028_leased_engine_runtimes.sql +11 -0
- package/db/migrations/0029_task_shared_files_mode.sql +5 -0
- package/db/migrations/0030_credential_cleanup_restops.sql +12 -0
- package/db/migrations/meta/_journal.json +223 -0
- package/db/schema.ts +850 -0
- package/images/standard/Dockerfile +347 -0
- package/images/standard/README.md +167 -0
- package/images/standard/container/code-server-settings.json +63 -0
- package/images/standard/container/corepack-version +1 -0
- package/images/standard/container/uai-init +704 -0
- package/images/standard/container/uai-materialize-runtimes +1527 -0
- package/images/standard/container/uai-task-forwarder.mjs +303 -0
- package/images/standard/tool-versions +2 -0
- package/lib/__fixtures__/skill-index/SKILL.md +10 -0
- package/lib/__fixtures__/skill-index/skills/accessibility-checklist.md +7 -0
- package/lib/__fixtures__/skill-index/skills/brand-voice.md +9 -0
- package/lib/__fixtures__/skill-index/skills/design-tokens.md +9 -0
- package/lib/agent-cli.ts +1507 -0
- package/lib/agent-errors.ts +22 -0
- package/lib/agent.ts +672 -0
- package/lib/agents/attach-compatibility.ts +51 -0
- package/lib/agents/claude.ts +918 -0
- package/lib/agents/codex-token-usage.fixture.json +130 -0
- package/lib/agents/codex.ts +1392 -0
- package/lib/agents/cursor-period-usage.ts +253 -0
- package/lib/agents/cursor.ts +562 -0
- package/lib/agents/dispatch.ts +78 -0
- package/lib/agents/durable-proc.ts +334 -0
- package/lib/agents/factory.ts +57 -0
- package/lib/agents/grok.ts +381 -0
- package/lib/agents/kimi.ts +329 -0
- package/lib/agents/machine-durable.ts +604 -0
- package/lib/agents/mock.ts +133 -0
- package/lib/agents/mode.ts +64 -0
- package/lib/agents/opencode.ts +508 -0
- package/lib/agents/output-source.ts +3 -0
- package/lib/agents/proc.ts +221 -0
- package/lib/agents/rate-limit.ts +337 -0
- package/lib/agents/registry.ts +182 -0
- package/lib/agents/session-state.ts +197 -0
- package/lib/agents/skill-index-preamble.fixture.ts +26 -0
- package/lib/agents/transport.ts +741 -0
- package/lib/agents/types.ts +254 -0
- package/lib/agents/uai.ts +106 -0
- package/lib/agents/usage.ts +44 -0
- package/lib/apple-one-off.ts +277 -0
- package/lib/apple-runtime-recycle.ts +237 -0
- package/lib/apple-uninstall-teardown.ts +224 -0
- package/lib/assignment-evidence.ts +94 -0
- package/lib/attachments.ts +48 -0
- package/lib/browser-testing.ts +1537 -0
- package/lib/capture-flow.ts +332 -0
- package/lib/cloud-credential-cleanup-adapter.ts +123 -0
- package/lib/cloud-credential-host.ts +512 -0
- package/lib/cloud-credential-leases.ts +2587 -0
- package/lib/cloud-credential-runtime.ts +1357 -0
- package/lib/cloud-state.ts +56 -0
- package/lib/codex-auth.ts +456 -0
- package/lib/command-db.ts +310 -0
- package/lib/compose-network-recovery.ts +283 -0
- package/lib/connection-secret-redaction.ts +25 -0
- package/lib/container-runtime.ts +1453 -0
- package/lib/credential-cleanup-inventory.ts +490 -0
- package/lib/credential-consumers/engine-anchor.ts +1880 -0
- package/lib/credential-consumers/engines.ts +797 -0
- package/lib/credential-consumers/files.ts +934 -0
- package/lib/credential-consumers/github.ts +702 -0
- package/lib/credential-consumers/mcp.ts +389 -0
- package/lib/credential-consumers/task-files.ts +127 -0
- package/lib/credential-consumers/task-secrets.ts +10 -0
- package/lib/credential-store-pickup.ts +149 -0
- package/lib/credential-store-scope.ts +112 -0
- package/lib/credential-store.ts +932 -0
- package/lib/credentials-activation-authority.ts +709 -0
- package/lib/credentials-purge.ts +1006 -0
- package/lib/custom-connection-capture.ts +395 -0
- package/lib/custom-connection-launch.ts +384 -0
- package/lib/custom-connection-runtime.ts +141 -0
- package/lib/db.ts +80 -0
- package/lib/disk-pressure.ts +42 -0
- package/lib/docker-exec.ts +156 -0
- package/lib/engine-accounts.ts +1970 -0
- package/lib/engine-connect.ts +321 -0
- package/lib/engine-credential-env.ts +52 -0
- package/lib/engine-login.ts +2933 -0
- package/lib/engines.ts +1342 -0
- package/lib/enrollment-state.ts +251 -0
- package/lib/env-file.ts +246 -0
- package/lib/env-schema.ts +891 -0
- package/lib/env.ts +195 -0
- package/lib/fs-aliases.ts +49 -0
- package/lib/git-clone-credentials.ts +334 -0
- package/lib/git-diff.ts +530 -0
- package/lib/git-identity.ts +715 -0
- package/lib/github-git-auth.ts +207 -0
- package/lib/github-origin.ts +28 -0
- package/lib/github-tokens.ts +2439 -0
- package/lib/host-cloud-url.ts +62 -0
- package/lib/host-config.ts +279 -0
- package/lib/host-env.ts +424 -0
- package/lib/host-logs.ts +965 -0
- package/lib/internal-connections.ts +5 -0
- package/lib/keyed-promise-tail.ts +23 -0
- package/lib/launch-mode.ts +25 -0
- package/lib/lease.ts +239 -0
- package/lib/legacy-host.ts +769 -0
- package/lib/legacy-runtime-retirement.ts +424 -0
- package/lib/legacy-runtime-v1.fixture.ts +627 -0
- package/lib/machine-exec.ts +238 -0
- package/lib/machine-gateway-tunnel.ts +344 -0
- package/lib/machine-keys.ts +65 -0
- package/lib/machine-project-env-loader.ts +152 -0
- package/lib/machine-provider-aws.ts +923 -0
- package/lib/machine-provider-local.ts +338 -0
- package/lib/machine-provider.ts +90 -0
- package/lib/managed-activation-watcher.ts +72 -0
- package/lib/managed-install-owner-watcher.ts +55 -0
- package/lib/managed-operation-drain.ts +57 -0
- package/lib/managed-runtime.ts +4296 -0
- package/lib/managed-update-scheduler.ts +125 -0
- package/lib/mcp-capture.ts +865 -0
- package/lib/mcp-config-lock.ts +2 -0
- package/lib/mcp-connections.ts +959 -0
- package/lib/mcp-gateway.ts +2594 -0
- package/lib/obs.ts +512 -0
- package/lib/openrouter-budget.ts +247 -0
- package/lib/orchestrator.ts +11409 -0
- package/lib/person-capture.ts +327 -0
- package/lib/preview-ports.ts +85 -0
- package/lib/preview-sidecar.ts +331 -0
- package/lib/project-env-authority.ts +1319 -0
- package/lib/project-env-feature.ts +74 -0
- package/lib/project-env-legacy-tags.ts +130 -0
- package/lib/project-env-loader.ts +242 -0
- package/lib/project-env-replica.ts +2094 -0
- package/lib/project-env-schema-capture.ts +342 -0
- package/lib/project-env-staging.ts +148 -0
- package/lib/project-env-task-policy.ts +176 -0
- package/lib/project-env-task-replica.ts +1752 -0
- package/lib/release-feed.ts +61 -0
- package/lib/release-manifest.ts +710 -0
- package/lib/release-trust.ts +46 -0
- package/lib/repo-clone.ts +38 -0
- package/lib/routing/shadow.ts +261 -0
- package/lib/runner-boot.ts +10 -0
- package/lib/runtime-activation-tail.ts +279 -0
- package/lib/runtime-archive.ts +1216 -0
- package/lib/runtime-authority.ts +166 -0
- package/lib/runtime-guard.ts +36 -0
- package/lib/runtime-provider-state.ts +169 -0
- package/lib/runtime-reconnect.ts +86 -0
- package/lib/runtime-state.ts +1033 -0
- package/lib/safe-http.ts +364 -0
- package/lib/secrets-proxy/address.ts +95 -0
- package/lib/secrets-proxy/audit.ts +30 -0
- package/lib/secrets-proxy/ca-store.ts +200 -0
- package/lib/secrets-proxy/ca.ts +470 -0
- package/lib/secrets-proxy/container-steps.ts +138 -0
- package/lib/secrets-proxy/der.ts +273 -0
- package/lib/secrets-proxy/engine.ts +1633 -0
- package/lib/secrets-proxy/host.ts +93 -0
- package/lib/secrets-proxy/hostname.ts +57 -0
- package/lib/secrets-proxy/placeholders.ts +196 -0
- package/lib/secrets-proxy/policy.ts +150 -0
- package/lib/secrets-proxy/readiness.ts +148 -0
- package/lib/secrets-proxy/runtime.ts +582 -0
- package/lib/secrets-proxy/scrub.ts +559 -0
- package/lib/secrets-proxy/sidecar-view.ts +139 -0
- package/lib/secrets-proxy/task-scripts.ts +262 -0
- package/lib/secrets-proxy/task-trust.ts +605 -0
- package/lib/secrets-proxy/trust-watch.ts +80 -0
- package/lib/secrets.ts +71 -0
- package/lib/shared-files-s3.ts +976 -0
- package/lib/shared-files.ts +156 -0
- package/lib/sidecar-assign.ts +49 -0
- package/lib/sidecar-guard.ts +58 -0
- package/lib/sidecar-resume.ts +178 -0
- package/lib/sidecar.ts +69 -0
- package/lib/signin-box-credentials.ts +465 -0
- package/lib/signin-box.ts +114 -0
- package/lib/skill-index-example.fixture.ts +56 -0
- package/lib/skill-layout.ts +417 -0
- package/lib/skills.ts +489 -0
- package/lib/ssh.ts +401 -0
- package/lib/standard-image-cleanup.ts +117 -0
- package/lib/standard-image-pin.ts +207 -0
- package/lib/standard-image.ts +1697 -0
- package/lib/stopped-task-status-queue.ts +120 -0
- package/lib/task-container-cli.ts +269 -0
- package/lib/task-credential-cleanup.ts +752 -0
- package/lib/task-diff-sandbox.ts +464 -0
- package/lib/task-diff.ts +91 -0
- package/lib/task-env-forwarder.ts +228 -0
- package/lib/task-env-source.ts +249 -0
- package/lib/task-environment/anchor.ts +31 -0
- package/lib/task-environment/apple-container.ts +860 -0
- package/lib/task-environment/docker.ts +1344 -0
- package/lib/task-environment/index.ts +466 -0
- package/lib/task-environment/legacy-adoption.ts +467 -0
- package/lib/task-environment/machine-environment.ts +61 -0
- package/lib/task-environment/machine-task-up.ts +1227 -0
- package/lib/task-environment/machine.ts +974 -0
- package/lib/task-environment/registry.ts +59 -0
- package/lib/task-environment/self-identity.ts +20 -0
- package/lib/task-environment/self.ts +566 -0
- package/lib/task-environment/types.ts +642 -0
- package/lib/task-environment/workspace-files.ts +685 -0
- package/lib/task-environment/workspace-runtime.fixture.ts +50 -0
- package/lib/task-files-machine-retirement-outbox.ts +592 -0
- package/lib/task-files-machine-retirement.ts +116 -0
- package/lib/task-files-readiness.ts +127 -0
- package/lib/task-gateway-port.ts +22 -0
- package/lib/task-gateway-protocol.ts +190 -0
- package/lib/task-gateway-recovery.ts +47 -0
- package/lib/task-gateway-state.ts +512 -0
- package/lib/task-identity.ts +19 -0
- package/lib/task-inventory.ts +682 -0
- package/lib/task-machine-credentials-activation.ts +95 -0
- package/lib/task-machine-swap-safety.ts +729 -0
- package/lib/task-person-credentials.ts +76 -0
- package/lib/task-project-ops-host.ts +147 -0
- package/lib/task-project-ops.ts +1062 -0
- package/lib/task-secret-staging.ts +16 -0
- package/lib/task-status.ts +46 -0
- package/lib/task-token.ts +46 -0
- package/lib/token-broker-adopt.ts +344 -0
- package/lib/token-broker-lambda.ts +105 -0
- package/lib/token-broker-local.ts +392 -0
- package/lib/token-broker-revision.ts +310 -0
- package/lib/token-broker-ssm.ts +525 -0
- package/lib/token-broker.ts +218 -0
- package/lib/token-lanes/openai-oauth.ts +123 -0
- package/lib/token-lanes/registry.ts +45 -0
- package/lib/token-lanes/types.ts +163 -0
- package/lib/token-lanes/xai-oauth.ts +165 -0
- package/lib/transcript.ts +128 -0
- package/lib/tunnel-registry.ts +220 -0
- package/lib/tunnel-runtime.ts +235 -0
- package/lib/ulid.ts +16 -0
- package/lib/user-bus-env.ts +116 -0
- package/lib/user-credentials-store.ts +435 -0
- package/lib/vnode-pressure.ts +142 -0
- package/package.json +131 -4
- package/runner/runner.mjs +442 -0
- package/scripts/agent/_common.sh +633 -0
- package/scripts/agent/env-hook.sh +626 -0
- package/scripts/agent/moondeck-cli.sh +5 -0
- package/scripts/agent/task-down.sh +291 -0
- package/scripts/agent/task-status.sh +70 -0
- package/scripts/agent/task-up.sh +3761 -0
- package/scripts/agent/uai-env-exec.sh +26 -0
- package/scripts/install/darwin.ts +1048 -0
- package/scripts/install/linux.ts +958 -0
- package/scripts/install/types.ts +78 -0
- package/scripts/install/util.ts +254 -0
- package/scripts/install/win.ts +143 -0
- package/src/activation-respawn.ts +155 -0
- package/src/apple-tunnel-route.ts +104 -0
- package/src/capture-wire.ts +102 -0
- package/src/cli.ts +2583 -0
- package/src/cloud-credentials.ts +2144 -0
- package/src/cloud-origins.ts +23 -0
- package/src/credential-location.ts +248 -0
- package/src/credential-wire-validation.ts +25 -0
- package/src/custom-connections.ts +237 -0
- package/src/engine-account-paths.ts +11 -0
- package/src/engine-models.ts +39 -0
- package/src/engine-usage.ts +104 -0
- package/src/event-outbox.ts +185 -0
- package/src/index.ts +2899 -0
- package/src/load-env.ts +97 -0
- package/src/machine-tunnel-route.ts +156 -0
- package/src/main.ts +6349 -0
- package/src/never-proxied-domains.ts +31 -0
- package/src/outbound-frame.ts +31 -0
- package/src/paths.ts +81 -0
- package/src/project-env-latest.ts +130 -0
- package/src/project-env-policy.ts +396 -0
- package/src/project-env-wording.ts +53 -0
- package/src/protocol.ts +5545 -0
- package/src/runtime-bootstrap.ts +165 -0
- package/src/station-identity.ts +96 -0
- package/src/task-env-names.ts +28 -0
- package/src/task-secrets.ts +75 -0
- package/src/tunnel-dial.ts +102 -0
- package/src/ui/server.ts +852 -0
- package/src/ui/types.ts +173 -0
- package/src/workspace-path-policy.ts +41 -0
- package/ui/app.js +1102 -0
- package/ui/index.html +90 -0
- package/ui/style.css +685 -0
- package/ui/uai-favicon.svg +21 -0
- package/ui/uai-logo-black.svg +9 -0
- package/ui/uai-wheel.svg +9 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-106 Apple tunnel routing, extracted from main.ts so its two safety
|
|
3
|
+
* properties are directly testable: the identity proof and the TCP connect
|
|
4
|
+
* both happen inside the task's lifecycle slot (a concurrent
|
|
5
|
+
* taskDown/recreate cannot free and reuse the address between proof and
|
|
6
|
+
* connection), and a readiness-epoch change during the awaited connect
|
|
7
|
+
* destroys the socket rather than carrying a dead generation's proof out.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface AppleRouteSocket {
|
|
11
|
+
connect(port: number, host: string): void;
|
|
12
|
+
once(event: "connect" | "error", listener: () => void): void;
|
|
13
|
+
destroy(): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface AppleTunnelRouteDeps {
|
|
17
|
+
getTask(taskId: string): { statusMirror: string | null } | undefined;
|
|
18
|
+
reconstruct(task: unknown): Promise<{
|
|
19
|
+
inspectRoute?: () => Promise<
|
|
20
|
+
| { kind: "running"; ipv4Address: string }
|
|
21
|
+
| { kind: "unavailable" }
|
|
22
|
+
| { kind: "unknown"; detail: string }
|
|
23
|
+
>;
|
|
24
|
+
} | null>;
|
|
25
|
+
runTaskLifecycle<T>(taskId: string, work: () => Promise<T>): Promise<T>;
|
|
26
|
+
runtimeProblem(): unknown;
|
|
27
|
+
readinessEpoch(): number;
|
|
28
|
+
epochIsCurrent(epoch: number): boolean;
|
|
29
|
+
poison(detail: string): void;
|
|
30
|
+
createSocket(): AppleRouteSocket;
|
|
31
|
+
connectTimeoutMs?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface AppleTunnelRouteRequest {
|
|
35
|
+
taskId: string;
|
|
36
|
+
target: string;
|
|
37
|
+
containerPort?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function resolveAppleTunnelRoute(
|
|
41
|
+
request: AppleTunnelRouteRequest,
|
|
42
|
+
deps: AppleTunnelRouteDeps,
|
|
43
|
+
): Promise<{ host: string; port: number; socket: AppleRouteSocket } | null> {
|
|
44
|
+
const applePort =
|
|
45
|
+
request.target === "editor" ? 8080 : request.containerPort;
|
|
46
|
+
if (!applePort) return null;
|
|
47
|
+
if (deps.getTask(request.taskId)?.statusMirror !== "running") return null;
|
|
48
|
+
return deps.runTaskLifecycle(request.taskId, async () => {
|
|
49
|
+
const current = deps.getTask(request.taskId);
|
|
50
|
+
if (!current || current.statusMirror !== "running") return null;
|
|
51
|
+
let route:
|
|
52
|
+
| { kind: "running"; ipv4Address: string }
|
|
53
|
+
| { kind: "unavailable" }
|
|
54
|
+
| { kind: "unknown"; detail: string }
|
|
55
|
+
| null = null;
|
|
56
|
+
try {
|
|
57
|
+
const handle = await deps.reconstruct(current);
|
|
58
|
+
if (handle === null || handle.inspectRoute === undefined) return null;
|
|
59
|
+
route = await handle.inspectRoute();
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (route === null) return null;
|
|
64
|
+
if (route.kind === "unknown") {
|
|
65
|
+
// The CLI answered with neither presence nor absence — the same signal
|
|
66
|
+
// class as a Docker daemon that stopped responding mid-tunnel.
|
|
67
|
+
deps.poison(route.detail);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
if (route.kind !== "running") return null;
|
|
71
|
+
if (deps.runtimeProblem()) return null;
|
|
72
|
+
const routeEpoch = deps.readinessEpoch();
|
|
73
|
+
const upstream = deps.createSocket();
|
|
74
|
+
const connected = await new Promise<boolean>((resolveConnect) => {
|
|
75
|
+
let settled = false;
|
|
76
|
+
const settle = (ok: boolean): void => {
|
|
77
|
+
if (settled) return;
|
|
78
|
+
settled = true;
|
|
79
|
+
clearTimeout(deadline);
|
|
80
|
+
resolveConnect(ok);
|
|
81
|
+
};
|
|
82
|
+
const deadline = setTimeout(() => {
|
|
83
|
+
upstream.destroy();
|
|
84
|
+
settle(false);
|
|
85
|
+
}, deps.connectTimeoutMs ?? 10_000);
|
|
86
|
+
deadline.unref?.();
|
|
87
|
+
upstream.once("connect", () => settle(true));
|
|
88
|
+
upstream.once("error", () => settle(false));
|
|
89
|
+
upstream.connect(applePort, route.ipv4Address);
|
|
90
|
+
});
|
|
91
|
+
if (
|
|
92
|
+
!connected ||
|
|
93
|
+
// The awaited connect is a window: a forced recheck can invalidate the
|
|
94
|
+
// runtime mid-wait, and a proof from a dead generation must not carry
|
|
95
|
+
// a live socket out of the slot.
|
|
96
|
+
!deps.epochIsCurrent(routeEpoch) ||
|
|
97
|
+
deps.runtimeProblem()
|
|
98
|
+
) {
|
|
99
|
+
upstream.destroy();
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return { host: route.ipv4Address, port: applePort, socket: upstream };
|
|
103
|
+
});
|
|
104
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** Pure capture contract, independent of leases and custom connections. */
|
|
2
|
+
import { parseLeaseParameterName, parseBrokerParameterName, sameLocation, isIdValue, isTagValue, type CredentialLocation } from "./credential-location";
|
|
3
|
+
import { exactObject, isPositiveInteger, isEpochMs } from "./credential-wire-validation";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What the cloud tells the sign-in box to write for one capture: the
|
|
7
|
+
* revision's parameters (the box never chooses a name) and the ids it tags
|
|
8
|
+
* them with. The box checks every field against the others before it writes.
|
|
9
|
+
*/
|
|
10
|
+
export interface CaptureFlowWire {
|
|
11
|
+
credentialId: string;
|
|
12
|
+
revision: string;
|
|
13
|
+
leaseParameter: string;
|
|
14
|
+
/** Null for a static credential. */
|
|
15
|
+
brokerParameter: string | null;
|
|
16
|
+
/** The workspace tag: required except for GitHub and SSH. */
|
|
17
|
+
orgId: string | null;
|
|
18
|
+
/** The person, for a personal credential. */
|
|
19
|
+
userId: string | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** What the box answers once both parts are written: never material. */
|
|
23
|
+
export interface CaptureResultWire {
|
|
24
|
+
credentialId: string;
|
|
25
|
+
revision: string;
|
|
26
|
+
/** The lease-readable parameter's Parameter Store version. */
|
|
27
|
+
leaseVersion: number;
|
|
28
|
+
/** The access token's expiry when the box could read it. */
|
|
29
|
+
expiresAt: number | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A capture flow, rebuilt and checked, with the location its parameters name,
|
|
34
|
+
* or null. The two parameters must name the same credential and revision under
|
|
35
|
+
* their own roots, and the tags must be the parameter's owner: a workspace
|
|
36
|
+
* credential's `orgId` is its owner and it has no `userId`; a personal AI
|
|
37
|
+
* account or MCP connection names both its person and its workspace; GitHub
|
|
38
|
+
* and SSH name their person alone.
|
|
39
|
+
*/
|
|
40
|
+
export function parseCaptureFlowWire(
|
|
41
|
+
value: unknown,
|
|
42
|
+
): (CaptureFlowWire & { location: CredentialLocation }) | null {
|
|
43
|
+
const o = exactObject(value, [
|
|
44
|
+
"credentialId",
|
|
45
|
+
"revision",
|
|
46
|
+
"leaseParameter",
|
|
47
|
+
"brokerParameter",
|
|
48
|
+
"orgId",
|
|
49
|
+
"userId",
|
|
50
|
+
]);
|
|
51
|
+
if (
|
|
52
|
+
!o ||
|
|
53
|
+
!isIdValue(o.credentialId) ||
|
|
54
|
+
!isIdValue(o.revision) ||
|
|
55
|
+
typeof o.leaseParameter !== "string" ||
|
|
56
|
+
!(o.brokerParameter === null || typeof o.brokerParameter === "string") ||
|
|
57
|
+
!(o.orgId === null || (isIdValue(o.orgId) && isTagValue(o.orgId))) ||
|
|
58
|
+
!(o.userId === null || (isIdValue(o.userId) && isTagValue(o.userId)))
|
|
59
|
+
) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const location = parseLeaseParameterName(o.leaseParameter);
|
|
63
|
+
if (!location || location.revision !== o.revision) return null;
|
|
64
|
+
const isPerson = location.class === "github" || location.class === "ssh";
|
|
65
|
+
if (!isPerson && location.credentialId !== o.credentialId) return null;
|
|
66
|
+
if (o.brokerParameter !== null) {
|
|
67
|
+
const broker = parseBrokerParameterName(o.brokerParameter);
|
|
68
|
+
if (!broker || !sameLocation(broker, location)) return null;
|
|
69
|
+
}
|
|
70
|
+
if (isPerson && o.brokerParameter !== null) return null;
|
|
71
|
+
const ownerOk =
|
|
72
|
+
location.scope === "org"
|
|
73
|
+
? o.orgId === location.ownerId && o.userId === null
|
|
74
|
+
: o.userId === location.ownerId && (isPerson ? o.orgId === null : o.orgId !== null);
|
|
75
|
+
if (!ownerOk) return null;
|
|
76
|
+
return {
|
|
77
|
+
credentialId: o.credentialId,
|
|
78
|
+
revision: o.revision,
|
|
79
|
+
leaseParameter: o.leaseParameter,
|
|
80
|
+
brokerParameter: o.brokerParameter,
|
|
81
|
+
orgId: o.orgId,
|
|
82
|
+
userId: o.userId,
|
|
83
|
+
location,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function parseCaptureResultWire(value: unknown): CaptureResultWire | null {
|
|
88
|
+
const o = exactObject(value, ["credentialId", "revision", "leaseVersion", "expiresAt"]);
|
|
89
|
+
return o &&
|
|
90
|
+
isIdValue(o.credentialId) &&
|
|
91
|
+
isIdValue(o.revision) &&
|
|
92
|
+
isPositiveInteger(o.leaseVersion) &&
|
|
93
|
+
(o.expiresAt === null || isEpochMs(o.expiresAt))
|
|
94
|
+
? {
|
|
95
|
+
credentialId: o.credentialId,
|
|
96
|
+
revision: o.revision,
|
|
97
|
+
leaseVersion: o.leaseVersion,
|
|
98
|
+
expiresAt: o.expiresAt,
|
|
99
|
+
}
|
|
100
|
+
: null;
|
|
101
|
+
}
|
|
102
|
+
|