@runuai/host 0.9.125 → 0.9.127

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/main.ts +42 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runuai/host",
3
- "version": "0.9.125",
3
+ "version": "0.9.127",
4
4
  "description": "Uai host — runs ephemeral AI tasks in containers on a machine you control.",
5
5
  "license": "MIT",
6
6
  "author": "Uai Tech <team@runuai.com>",
package/src/main.ts CHANGED
@@ -243,6 +243,7 @@ import {
243
243
  type TaskDiffInput,
244
244
  type TaskDownInput,
245
245
  type TaskLaunchInput,
246
+ type TaskLease,
246
247
  type FilesOpInput,
247
248
  engineAccountScopeFromWire,
248
249
  isEngineAccountLabel,
@@ -1272,7 +1273,6 @@ async function connect(): Promise<void> {
1272
1273
  reconnectAttempt = 0;
1273
1274
  markConnected();
1274
1275
  console.log(`[host-agent] connected as ${hostId}`);
1275
- leaseManager?.reconnected();
1276
1276
  setHostObsTag(hostId);
1277
1277
  addHostBreadcrumb("bridge", "connected");
1278
1278
 
@@ -1322,6 +1322,12 @@ async function connect(): Promise<void> {
1322
1322
  case "pong":
1323
1323
  break;
1324
1324
  case "event.resume":
1325
+ // ADR-133: the cloud's first frame after a verified auth. A lease
1326
+ // request sent any earlier lands in the bridge's pre-verdict window,
1327
+ // where only auth/ping/result frames survive (live 2026-09-10,
1328
+ // hostless smoke 5: the first request vanished, the machine sat
1329
+ // three minutes without credentials).
1330
+ leaseManager?.reconnected();
1325
1331
  // ADR-103: the cloud named its watermark — rewind the transmit
1326
1332
  // cursor to it (null = no state, replay nothing) and start draining.
1327
1333
  if (resumeFallbackTimer) {
@@ -2704,6 +2710,24 @@ function expectNumberArg(args: unknown[], index: number): number {
2704
2710
  return value;
2705
2711
  }
2706
2712
 
2713
+ function isTaskLease(value: unknown): value is TaskLease {
2714
+ if (!value || typeof value !== "object") return false;
2715
+ const lease = value as Record<string, unknown>;
2716
+ const files = lease.files as Record<string, unknown> | undefined;
2717
+ return (
2718
+ typeof lease.accessKeyId === "string" &&
2719
+ typeof lease.secretAccessKey === "string" &&
2720
+ typeof lease.sessionToken === "string" &&
2721
+ typeof lease.expiresAt === "number" &&
2722
+ typeof lease.region === "string" &&
2723
+ !!files &&
2724
+ typeof files === "object" &&
2725
+ typeof files.bucket === "string" &&
2726
+ (files.orgPrefix === null || typeof files.orgPrefix === "string") &&
2727
+ typeof files.userPrefix === "string"
2728
+ );
2729
+ }
2730
+
2707
2731
  function parseCloudFrame(data: RawData): CloudToHost | null {
2708
2732
  let parsed: unknown;
2709
2733
  try {
@@ -2931,6 +2955,23 @@ function parseCloudFrame(data: RawData): CloudToHost | null {
2931
2955
  ) {
2932
2956
  return { kind: "mcp.op", opId: frame.opId, op: frame.op };
2933
2957
  }
2958
+ // ADR-133: the cloud's answers to a sidecar's lease request. Without these
2959
+ // two clauses the sidecar logs "dropping unknown frame kind=lease.grant"
2960
+ // and the task dies after the 3-minute credentials gate.
2961
+ if (
2962
+ frame.kind === "lease.grant" &&
2963
+ typeof frame.opId === "string" &&
2964
+ isTaskLease(frame.lease)
2965
+ ) {
2966
+ return { kind: "lease.grant", opId: frame.opId, lease: frame.lease };
2967
+ }
2968
+ if (
2969
+ frame.kind === "lease.deny" &&
2970
+ typeof frame.opId === "string" &&
2971
+ typeof frame.error === "string"
2972
+ ) {
2973
+ return { kind: "lease.deny", opId: frame.opId, error: frame.error };
2974
+ }
2934
2975
  // Names only — never payloads (frames can carry tokens).
2935
2976
  console.warn(
2936
2977
  `[host-agent] dropping unknown frame kind=${String(frame.kind)}` +