@frockbot/plugin-computer 0.3.26 → 0.3.28

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-computer",
3
- "version": "0.3.26",
3
+ "version": "0.3.28",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -29,21 +29,21 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@cordisjs/client": "0.8.2",
32
- "@frockbot/client-core": "0.3.26",
33
- "@frockbot/client-ui": "0.3.26",
34
- "@frockbot/computer-core": "0.3.26",
35
- "@frockbot/computer-host-runtime": "0.3.26",
36
- "@frockbot/kernel-agent-loop": "0.3.26",
37
- "@frockbot/kernel-contracts": "0.3.26",
38
- "@frockbot/plugin-prompt": "0.3.26",
39
- "@frockbot/plugin-shell": "0.3.26",
40
- "@frockbot/plugin-tools": "0.3.26",
32
+ "@frockbot/client-core": "0.3.28",
33
+ "@frockbot/client-ui": "0.3.28",
34
+ "@frockbot/computer-core": "0.3.28",
35
+ "@frockbot/computer-host-runtime": "0.3.28",
36
+ "@frockbot/kernel-agent-loop": "0.3.28",
37
+ "@frockbot/kernel-contracts": "0.3.28",
38
+ "@frockbot/plugin-prompt": "0.3.28",
39
+ "@frockbot/plugin-shell": "0.3.28",
40
+ "@frockbot/plugin-tools": "0.3.28",
41
41
  "cordis": "4.0.0-rc.8",
42
42
  "vue": "3.5.41"
43
43
  },
44
44
  "devDependencies": {
45
- "@frockbot/plugin-models": "0.3.26",
46
- "@frockbot/plugin-testkit": "0.3.26",
45
+ "@frockbot/plugin-models": "0.3.28",
46
+ "@frockbot/plugin-testkit": "0.3.28",
47
47
  "@types/bun": "1.4.0",
48
48
  "@types/node": "26.2.0",
49
49
  "@vitejs/plugin-vue": "6.0.8",
package/src/agent.test.ts CHANGED
@@ -492,3 +492,48 @@ describe("computer agent contribution", () => {
492
492
  });
493
493
  });
494
494
  });
495
+
496
+ describe("the computer/sync event", () => {
497
+ test("records a publish sync without the per-path answers the caller asked for", async () => {
498
+ const { recordComputerSyncV1 } = await import("./agent.js");
499
+ const { decodeSessionEvent } = await import("@frockbot/kernel-contracts");
500
+ const appended: unknown[] = [];
501
+ const sessions = {
502
+ get: () => ({
503
+ disposed: false,
504
+ append: (event: unknown) => appended.push(event),
505
+ flush: () => Promise.resolve(),
506
+ }),
507
+ } as unknown as SessionStore;
508
+ await recordComputerSyncV1(sessions, "session-1", 3, "publish", {
509
+ status: "ok",
510
+ detail: "",
511
+ pulled: 0,
512
+ pushed: 1,
513
+ restored: 0,
514
+ removed: 0,
515
+ adopted: 0,
516
+ ignored: 5,
517
+ omitted: 0,
518
+ conflicts: 0,
519
+ failures: 0,
520
+ required: [
521
+ {
522
+ path: "dist/manifest.json",
523
+ contentHash: "a".repeat(64),
524
+ durable: true,
525
+ },
526
+ ],
527
+ } as never);
528
+ expect(appended).toHaveLength(1);
529
+ expect(appended[0]).not.toHaveProperty("required");
530
+ // The durable log's decoder has an exact field set; the event must pass it.
531
+ expect(() =>
532
+ decodeSessionEvent({
533
+ ...(appended[0] as object),
534
+ seq: 1,
535
+ timestamp: "2026-09-05T00:00:00.000Z",
536
+ }),
537
+ ).not.toThrow();
538
+ });
539
+ });
package/src/agent.ts CHANGED
@@ -488,7 +488,7 @@ function text(bytes: Uint8Array): string {
488
488
  * cannot record the same fact in two shapes. A Session that is gone or
489
489
  * disposed records nothing: a sync is never a reason to fail anything.
490
490
  */
491
- async function recordComputerSyncV1(
491
+ export async function recordComputerSyncV1(
492
492
  sessions: SessionStore,
493
493
  sessionId: string,
494
494
  turn: number,
@@ -497,11 +497,16 @@ async function recordComputerSyncV1(
497
497
  ): Promise<void> {
498
498
  const session = sessions.get(sessionId);
499
499
  if (!session || session.disposed) return;
500
+ // The per-path answers a publish asked for travel back to that caller, not
501
+ // into the durable log: the `computer/sync` event has an exact field set,
502
+ // and a summary spread with `required` on it made every publish Turn fail
503
+ // with "session event has invalid fields" (v0.3.27, 2026-09-05).
504
+ const { required: _required, ...recorded } = summary;
500
505
  session.append({
501
506
  type: "computer/sync",
502
507
  turn: Math.max(1, turn),
503
508
  reason,
504
- ...summary,
509
+ ...recorded,
505
510
  });
506
511
  // The record is durable before anything reports the sync happened.
507
512
  await session.flush();