@runuai/host 0.9.88 → 0.9.89

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 +33 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runuai/host",
3
- "version": "0.9.88",
3
+ "version": "0.9.89",
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
@@ -2614,7 +2614,11 @@ function parseCloudFrame(data: RawData): CloudToHost | null {
2614
2614
  ) {
2615
2615
  return { kind: "mcp.op", opId: frame.opId, op: frame.op };
2616
2616
  }
2617
- console.warn("[host-agent] dropping unknown frame");
2617
+ // Names only — never payloads (frames can carry tokens).
2618
+ console.warn(
2619
+ `[host-agent] dropping unknown frame kind=${String(frame.kind)}` +
2620
+ (frame.kind === "command" ? ` command=${String(frame.command)}` : ""),
2621
+ );
2618
2622
  return null;
2619
2623
  }
2620
2624
 
@@ -2861,28 +2865,35 @@ function rawDataToBuffer(data: RawData): Buffer {
2861
2865
  return Buffer.from(data);
2862
2866
  }
2863
2867
 
2868
+ // Exhaustive BY TYPE: `satisfies Record<keyof HostCommands, true>` makes a
2869
+ // command missing from this map a compile error. The previous hand-written
2870
+ // array silently dropped any frame it lagged behind on — hostUpdate and
2871
+ // hostRestart shipped in 0.9.62 and every remote Update/Restart click since
2872
+ // died here as "dropping unknown frame" / a cloud-side command timeout.
2873
+ const HOST_COMMAND_NAMES = {
2874
+ hostUpdate: true,
2875
+ hostRestart: true,
2876
+ taskUp: true,
2877
+ taskDown: true,
2878
+ taskStatus: true,
2879
+ taskStop: true,
2880
+ channelEnsure: true,
2881
+ channelTeardown: true,
2882
+ channelDeliver: true,
2883
+ channelResolvePermission: true,
2884
+ cloneRepo: true,
2885
+ taskDiff: true,
2886
+ attachmentWrite: true,
2887
+ attachmentRead: true,
2888
+ filesOp: true,
2889
+ channelInterrupt: true,
2890
+ appendTranscript: true,
2891
+ previewEnsure: true,
2892
+ engineAccountRemove: true,
2893
+ } satisfies Record<keyof HostCommands, true>;
2894
+
2864
2895
  function isHostCommand(command: string): command is keyof HostCommands {
2865
- // ⚠️ Keep in sync with the HostCommands interface + dispatchCommand. This is a
2866
- // manual allow-list (TS can't derive it from the type), so a missing entry
2867
- // silently drops the frame and hangs the cloud command.
2868
- return [
2869
- "taskUp",
2870
- "taskDown",
2871
- "taskStatus",
2872
- "channelEnsure",
2873
- "channelTeardown",
2874
- "channelDeliver",
2875
- "channelResolvePermission",
2876
- "cloneRepo",
2877
- "taskDiff",
2878
- "attachmentWrite",
2879
- "attachmentRead",
2880
- "filesOp",
2881
- "channelInterrupt",
2882
- "appendTranscript",
2883
- "previewEnsure",
2884
- "engineAccountRemove",
2885
- ].includes(command);
2896
+ return Object.hasOwn(HOST_COMMAND_NAMES, command);
2886
2897
  }
2887
2898
 
2888
2899
  function expectString(args: unknown[], index: number): string {