@runuai/host 0.9.13 → 0.9.42
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 +22 -5
- 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/meta/_journal.json +21 -0
- package/db/schema.ts +80 -30
- package/images/standard/Dockerfile +36 -10
- package/images/standard/README.md +63 -18
- package/images/standard/container/corepack-version +1 -0
- package/images/standard/container/uai-init +308 -38
- package/images/standard/container/uai-materialize-runtimes +1527 -0
- package/lib/agent-cli.ts +69 -4
- package/lib/agent.ts +46 -7
- package/lib/agents/claude.ts +13 -8
- package/lib/agents/codex.ts +11 -6
- package/lib/agents/cursor.ts +39 -29
- package/lib/agents/durable-proc.ts +20 -27
- package/lib/agents/factory.ts +9 -25
- package/lib/agents/grok.ts +43 -30
- package/lib/agents/kimi.ts +44 -29
- package/lib/agents/opencode.ts +43 -31
- package/lib/agents/proc.ts +149 -114
- package/lib/agents/transport.ts +62 -50
- package/lib/agents/types.ts +6 -4
- package/lib/apple-runtime-recycle.ts +236 -0
- package/lib/apple-uninstall-teardown.ts +224 -0
- package/lib/browser-testing.ts +233 -93
- package/lib/codex-auth.ts +40 -6
- package/lib/command-db.ts +20 -0
- package/lib/container-runtime.ts +1338 -0
- package/lib/db.ts +1 -0
- package/lib/docker-exec.ts +87 -5
- package/lib/engine-accounts.ts +68 -5
- package/lib/engine-login.ts +1952 -0
- package/lib/enrollment-state.ts +251 -0
- package/lib/env-file.ts +155 -0
- package/lib/env.ts +4 -0
- package/lib/git-diff.ts +98 -32
- package/lib/git-identity.ts +199 -87
- package/lib/github-tokens.ts +202 -91
- package/lib/host-cloud-url.ts +62 -0
- package/lib/host-config.ts +279 -0
- package/lib/host-logs.ts +962 -0
- package/lib/keyed-promise-tail.ts +23 -0
- package/lib/legacy-runtime-v1.fixture.ts +627 -0
- package/lib/managed-activation-watcher.ts +72 -0
- package/lib/managed-install-owner-watcher.ts +55 -0
- package/lib/managed-operation-drain.ts +49 -0
- package/lib/managed-runtime.ts +3644 -0
- package/lib/managed-update-scheduler.ts +125 -0
- package/lib/mcp-gateway.ts +450 -23
- package/lib/orchestrator.ts +3070 -223
- package/lib/preview-sidecar.ts +57 -13
- package/lib/release-manifest.ts +708 -0
- package/lib/release-trust.ts +28 -0
- package/lib/runtime-activation-tail.ts +232 -0
- package/lib/runtime-archive.ts +1086 -0
- package/lib/runtime-authority.ts +79 -0
- package/lib/runtime-guard.ts +36 -0
- package/lib/runtime-provider-state.ts +169 -0
- package/lib/runtime-state.ts +232 -12
- package/lib/skills.ts +24 -3
- package/lib/ssh.ts +18 -0
- package/lib/standard-image.ts +1104 -141
- package/lib/stopped-task-status-queue.ts +44 -0
- package/lib/task-container-cli.ts +269 -0
- package/lib/task-diff.ts +66 -46
- package/lib/task-environment/apple-container.ts +757 -0
- package/lib/task-environment/docker.ts +945 -0
- package/lib/task-environment/index.ts +364 -0
- package/lib/task-environment/legacy-adoption.ts +443 -0
- package/lib/task-environment/registry.ts +58 -0
- package/lib/task-environment/types.ts +408 -0
- package/lib/task-identity.ts +19 -0
- package/lib/task-inventory.ts +585 -0
- package/lib/tunnel-registry.ts +135 -19
- package/lib/tunnel-runtime.ts +235 -0
- package/package.json +1 -1
- package/scripts/agent/_common.sh +123 -3
- package/scripts/agent/task-down.sh +146 -38
- package/scripts/agent/task-status.sh +19 -3
- package/scripts/agent/task-up.sh +1463 -109
- package/scripts/install/darwin.ts +848 -50
- package/scripts/install/linux.ts +838 -35
- package/scripts/install/types.ts +43 -0
- package/scripts/install/util.ts +215 -8
- package/scripts/install/win.ts +12 -0
- package/src/apple-tunnel-route.ts +104 -0
- package/src/cli.ts +1464 -72
- package/src/event-outbox.ts +83 -4
- package/src/index.ts +871 -50
- package/src/main.ts +1398 -255
- package/src/paths.ts +17 -1
- package/src/protocol.ts +695 -1
- package/src/runtime-bootstrap.ts +165 -0
- package/src/ui/server.ts +46 -10
- package/src/ui/types.ts +37 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export const MANAGED_ACTIVATION_POLL_MS = 5_000;
|
|
2
|
+
|
|
3
|
+
export interface ManagedActivationWatcherOptions {
|
|
4
|
+
readonly restartRequired: () => boolean | Promise<boolean>;
|
|
5
|
+
readonly isIdle: () => boolean;
|
|
6
|
+
readonly onReady: () => void;
|
|
7
|
+
readonly onError?: (error: unknown) => void;
|
|
8
|
+
readonly pollMs?: number;
|
|
9
|
+
readonly setTimer?: (callback: () => void, delayMs: number) => NodeJS.Timeout;
|
|
10
|
+
readonly clearTimer?: (timer: NodeJS.Timeout) => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Watches the durable activation marker left by another CLI process. New work
|
|
15
|
+
* is rejected while that marker exists; this loop waits for the selected
|
|
16
|
+
* runtime to be current and all existing work to finish before asking the
|
|
17
|
+
* service supervisor to exec the stable launcher.
|
|
18
|
+
*/
|
|
19
|
+
export class ManagedActivationWatcher {
|
|
20
|
+
private timer: NodeJS.Timeout | null = null;
|
|
21
|
+
private running = false;
|
|
22
|
+
private stopped = false;
|
|
23
|
+
private readonly pollMs: number;
|
|
24
|
+
private readonly setTimer: NonNullable<ManagedActivationWatcherOptions["setTimer"]>;
|
|
25
|
+
private readonly clearTimer: NonNullable<ManagedActivationWatcherOptions["clearTimer"]>;
|
|
26
|
+
|
|
27
|
+
constructor(private readonly options: ManagedActivationWatcherOptions) {
|
|
28
|
+
this.pollMs = options.pollMs ?? MANAGED_ACTIVATION_POLL_MS;
|
|
29
|
+
if (!Number.isSafeInteger(this.pollMs) || this.pollMs <= 0) {
|
|
30
|
+
throw new Error("managed activation poll interval is invalid");
|
|
31
|
+
}
|
|
32
|
+
this.setTimer = options.setTimer ?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
33
|
+
this.clearTimer = options.clearTimer ?? clearTimeout;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
start(): void {
|
|
37
|
+
if (this.stopped || this.timer || this.running) return;
|
|
38
|
+
this.schedule();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
stop(): void {
|
|
42
|
+
this.stopped = true;
|
|
43
|
+
if (this.timer) this.clearTimer(this.timer);
|
|
44
|
+
this.timer = null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private schedule(): void {
|
|
48
|
+
if (this.stopped) return;
|
|
49
|
+
this.timer = this.setTimer(() => {
|
|
50
|
+
this.timer = null;
|
|
51
|
+
void this.run();
|
|
52
|
+
}, this.pollMs);
|
|
53
|
+
this.timer.unref?.();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async run(): Promise<void> {
|
|
57
|
+
if (this.stopped || this.running) return;
|
|
58
|
+
this.running = true;
|
|
59
|
+
try {
|
|
60
|
+
if ((await this.options.restartRequired()) && this.options.isIdle()) {
|
|
61
|
+
this.stop();
|
|
62
|
+
this.options.onReady();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
this.options.onError?.(error);
|
|
67
|
+
} finally {
|
|
68
|
+
this.running = false;
|
|
69
|
+
}
|
|
70
|
+
this.schedule();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ManagedRuntimeInstallStartupState } from "./managed-runtime";
|
|
2
|
+
|
|
3
|
+
export interface ManagedInstallOwnerWatcherOptions {
|
|
4
|
+
readonly check: () => Promise<ManagedRuntimeInstallStartupState>;
|
|
5
|
+
readonly onRestart: (state: "stale" | "attested") => void;
|
|
6
|
+
readonly onUnsafe: (error: unknown) => void;
|
|
7
|
+
readonly intervalMs?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Watches only a daemon that started provisionally under an install intent.
|
|
12
|
+
* `unknown` is a transient process-identity result and must never authorize a
|
|
13
|
+
* rollback or restart. `none` means completion removed the admission fence and
|
|
14
|
+
* permanently disarms this watcher for the ordinary steady-state daemon.
|
|
15
|
+
*/
|
|
16
|
+
export class ManagedInstallOwnerWatcher {
|
|
17
|
+
private timer: NodeJS.Timeout | null = null;
|
|
18
|
+
private checking = false;
|
|
19
|
+
|
|
20
|
+
constructor(private readonly options: ManagedInstallOwnerWatcherOptions) {}
|
|
21
|
+
|
|
22
|
+
start(): void {
|
|
23
|
+
if (this.timer) return;
|
|
24
|
+
this.timer = setInterval(
|
|
25
|
+
() => void this.tick(),
|
|
26
|
+
this.options.intervalMs ?? 1_000,
|
|
27
|
+
);
|
|
28
|
+
this.timer.unref?.();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
stop(): void {
|
|
32
|
+
if (!this.timer) return;
|
|
33
|
+
clearInterval(this.timer);
|
|
34
|
+
this.timer = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private async tick(): Promise<void> {
|
|
38
|
+
if (this.checking || !this.timer) return;
|
|
39
|
+
this.checking = true;
|
|
40
|
+
try {
|
|
41
|
+
const state = await this.options.check();
|
|
42
|
+
if (state === "none") {
|
|
43
|
+
this.stop();
|
|
44
|
+
} else if (state === "stale" || state === "attested") {
|
|
45
|
+
this.stop();
|
|
46
|
+
this.options.onRestart(state);
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
this.stop();
|
|
50
|
+
this.options.onUnsafe(error);
|
|
51
|
+
} finally {
|
|
52
|
+
this.checking = false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts asynchronous host mutations that must settle before a managed-runtime
|
|
3
|
+
* restart may terminate the process. The factory form increments first, so no
|
|
4
|
+
* synchronous setup performed by the operation can escape the drain.
|
|
5
|
+
*/
|
|
6
|
+
export class ManagedOperationDrain {
|
|
7
|
+
private active = 0;
|
|
8
|
+
private accepting = true;
|
|
9
|
+
|
|
10
|
+
constructor(private readonly onSettled: () => void) {}
|
|
11
|
+
|
|
12
|
+
get activeCount(): number {
|
|
13
|
+
return this.active;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Refuse factories that arrive after managed shutdown has begun. Existing
|
|
18
|
+
* operations remain counted until their full promise chains (including the
|
|
19
|
+
* bridge acknowledgement) settle.
|
|
20
|
+
*/
|
|
21
|
+
stopAccepting(): void {
|
|
22
|
+
this.accepting = false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
track<T>(operation: () => Promise<T>): Promise<T> {
|
|
26
|
+
if (!this.accepting) {
|
|
27
|
+
return Promise.reject(
|
|
28
|
+
new Error("managed host is shutting down; retry the operation"),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
this.active += 1;
|
|
32
|
+
let result: Promise<T>;
|
|
33
|
+
try {
|
|
34
|
+
result = operation();
|
|
35
|
+
} catch (error) {
|
|
36
|
+
this.settle();
|
|
37
|
+
return Promise.reject(error);
|
|
38
|
+
}
|
|
39
|
+
return Promise.resolve(result).finally(() => this.settle());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private settle(): void {
|
|
43
|
+
this.active -= 1;
|
|
44
|
+
if (this.active < 0) {
|
|
45
|
+
throw new Error("managed operation drain settled more work than it tracked");
|
|
46
|
+
}
|
|
47
|
+
this.onSettled();
|
|
48
|
+
}
|
|
49
|
+
}
|