@frockbot/plugin-fly-sprite 0.2.3 → 0.2.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frockbot/plugin-fly-sprite",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -25,16 +25,16 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@cordisjs/plugin-webui": "0.8.2",
28
- "@frockbot/computer-core": "0.2.3",
29
- "@frockbot/computer-host-protocol": "0.2.3",
30
- "@frockbot/computer-host-runtime": "0.2.3",
31
- "@frockbot/kernel-contracts": "0.2.3",
32
- "@frockbot/plugin-computer": "0.2.3",
28
+ "@frockbot/computer-core": "0.2.5",
29
+ "@frockbot/computer-host-protocol": "0.2.5",
30
+ "@frockbot/computer-host-runtime": "0.2.5",
31
+ "@frockbot/kernel-contracts": "0.2.5",
32
+ "@frockbot/plugin-computer": "0.2.5",
33
33
  "cordis": "4.0.0-rc.8"
34
34
  },
35
35
  "devDependencies": {
36
- "@frockbot/plugin-testkit": "0.2.3",
37
- "@frockbot/workspace-store": "0.2.3",
36
+ "@frockbot/plugin-testkit": "0.2.5",
37
+ "@frockbot/workspace-store": "0.2.5",
38
38
  "@types/bun": "1.4.0",
39
39
  "@types/node": "26.2.0",
40
40
  "typescript": "5.9.3"
@@ -227,6 +227,30 @@ describe("Fly Sprite computer", () => {
227
227
  expect(connected?.message).toBeUndefined();
228
228
  });
229
229
 
230
+ test("reports provider-neutral connection boundaries around the host calls", async () => {
231
+ const host = fakeHost();
232
+ const provider = new FlySpriteComputerProvider(attach(host));
233
+ const computer = await provider.open(
234
+ { userId: "owner" },
235
+ { botId: "general" },
236
+ { providerId: "fly-sprite", generation: 1 },
237
+ );
238
+ const progress: string[] = [];
239
+
240
+ await computer.presence?.connect({
241
+ onProgress: (step) => {
242
+ progress.push(step.step);
243
+ },
244
+ });
245
+
246
+ expect(progress).toEqual([
247
+ "attaching",
248
+ "starting-desktop",
249
+ "minting-viewer",
250
+ "connecting",
251
+ ]);
252
+ });
253
+
230
254
  test("an unconfigured Computer refuses rather than pretending", async () => {
231
255
  const computer = new FlySpriteComputer({ spriteName: "frockbot-test" });
232
256
  expect(computer.configured).toBe(false);
package/src/computer.ts CHANGED
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import {
3
3
  ComputerError,
4
4
  decodeComputerDoctorReportV1,
5
+ type ComputerConnectionOptionsV1,
5
6
  type ComputerControlRequestV1,
6
7
  type ComputerDoctorReportV1,
7
8
  type ComputerOperationOptions,
@@ -329,7 +330,7 @@ export class FlySpriteAgentComputer {
329
330
  return this.computer.ensureAgent(this.layout, signal);
330
331
  }
331
332
 
332
- connect(options?: ComputerOperationOptions): Promise<ComputerConnection> {
333
+ connect(options?: ComputerConnectionOptionsV1): Promise<ComputerConnection> {
333
334
  return this.computer.connectAgent(this.layout, options);
334
335
  }
335
336
 
@@ -581,7 +582,7 @@ export class FlySpriteComputer {
581
582
 
582
583
  connectAgent(
583
584
  layout: AgentLayout,
584
- options?: ComputerOperationOptions,
585
+ options?: ComputerConnectionOptionsV1,
585
586
  ): Promise<ComputerConnection> {
586
587
  this.hostFor(layout);
587
588
  return this.openAgent(layout, options);
@@ -1208,7 +1209,7 @@ export class FlySpriteComputer {
1208
1209
  */
1209
1210
  private async openAgent(
1210
1211
  layout: AgentLayout,
1211
- options?: ComputerOperationOptions,
1212
+ options?: ComputerConnectionOptionsV1,
1212
1213
  ): Promise<ComputerConnection> {
1213
1214
  const signal = options?.signal;
1214
1215
  const effectId = options?.effectId;
@@ -1238,6 +1239,39 @@ export class FlySpriteComputer {
1238
1239
  this.expectedSpriteName = opened.spriteName;
1239
1240
  this.generations.set(layout.key, opened.generation);
1240
1241
  if (opened.display) this.displays.set(layout.key, opened.display);
1242
+ const updating =
1243
+ opened.provisioning?.kind === "update" &&
1244
+ opened.provisioning.status === "running";
1245
+ if (updating && opened.provisioning) {
1246
+ await options?.onProgress?.({
1247
+ version: 1,
1248
+ kind: "update",
1249
+ step: opened.provisioning.phase,
1250
+ label: opened.provisioning.label,
1251
+ index: opened.provisioning.index,
1252
+ total: opened.provisioning.total,
1253
+ });
1254
+ } else {
1255
+ // `host.open` owns the wake, tenant attachment and declared desktop
1256
+ // start. Keep the durable wake step active while that long call is in
1257
+ // flight, then record both boundaries before moving to viewer minting.
1258
+ await options?.onProgress?.({
1259
+ version: 1,
1260
+ kind: "connect",
1261
+ step: "attaching",
1262
+ label: "Attaching the Bot",
1263
+ index: 2,
1264
+ total: 5,
1265
+ });
1266
+ await options?.onProgress?.({
1267
+ version: 1,
1268
+ kind: "connect",
1269
+ step: "starting-desktop",
1270
+ label: "Starting the desktop",
1271
+ index: 3,
1272
+ total: 5,
1273
+ });
1274
+ }
1241
1275
  if (this.respectHumanControl) {
1242
1276
  await this.assertAgentControl(
1243
1277
  host,
@@ -1246,6 +1280,16 @@ export class FlySpriteComputer {
1246
1280
  effectId ? `${effectId}:assert-control` : undefined,
1247
1281
  );
1248
1282
  }
1283
+ if (!updating) {
1284
+ await options?.onProgress?.({
1285
+ version: 1,
1286
+ kind: "connect",
1287
+ step: "minting-viewer",
1288
+ label: "Minting the secure viewer",
1289
+ index: 4,
1290
+ total: 5,
1291
+ });
1292
+ }
1249
1293
  const viewer = await host.viewer("open", {
1250
1294
  signal,
1251
1295
  timeoutMs: TIMEOUTS.viewer,
@@ -1258,6 +1302,16 @@ export class FlySpriteComputer {
1258
1302
  true,
1259
1303
  );
1260
1304
  }
1305
+ if (!updating) {
1306
+ await options?.onProgress?.({
1307
+ version: 1,
1308
+ kind: "connect",
1309
+ step: "connecting",
1310
+ label: "Connecting to the desktop",
1311
+ index: 5,
1312
+ total: 5,
1313
+ });
1314
+ }
1261
1315
  return {
1262
1316
  botId: layout.identity.id,
1263
1317
  botKey: layout.key,