gestalt-mobile 0.30.3 → 0.32.0

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.
@@ -294,9 +294,10 @@ export class CodexSessionRuntime {
294
294
  if (!owned)
295
295
  return [];
296
296
  const children = [];
297
+ const childIds = new Set();
297
298
  const cursors = new Set();
298
299
  let cursor;
299
- for (let page = 0; page < 4 && children.length < 64; page += 1) {
300
+ for (let page = 0; page < 4 && childIds.size < 64; page += 1) {
300
301
  const result = await owned.process.rpc.request('thread/list', {
301
302
  parentThreadId: session.threadId,
302
303
  ...(cursor ? { cursor } : {}),
@@ -320,6 +321,7 @@ export class CodexSessionRuntime {
320
321
  rawStatus === 'systemError'
321
322
  ? rawStatus
322
323
  : undefined;
324
+ childIds.add(value.id);
323
325
  return [
324
326
  {
325
327
  id: value.id,
@@ -339,19 +341,21 @@ export class CodexSessionRuntime {
339
341
  },
340
342
  ];
341
343
  }));
344
+ if (childIds.size > 64)
345
+ throw new Error('CODEX_CHILD_LIST_UNSUPPORTED');
342
346
  const next = typeof response?.nextCursor === 'string' && response.nextCursor.length <= 256
343
347
  ? response.nextCursor
344
348
  : undefined;
345
349
  if (!next)
346
- return this.withResolvedChildModels(owned, children);
347
- if (cursors.has(next) || children.length >= 64)
350
+ return this.withResolvedChildModels(owned, uniqueDirectChildren(children));
351
+ if (cursors.has(next) || childIds.size >= 64)
348
352
  throw new Error('CODEX_CHILD_LIST_UNSUPPORTED');
349
353
  cursors.add(next);
350
354
  cursor = next;
351
355
  }
352
356
  if (cursor)
353
357
  throw new Error('CODEX_CHILD_LIST_UNSUPPORTED');
354
- return this.withResolvedChildModels(owned, children);
358
+ return this.withResolvedChildModels(owned, uniqueDirectChildren(children));
355
359
  }
356
360
  async withResolvedChildModels(resource, children) {
357
361
  for (const child of children) {
@@ -784,6 +788,13 @@ export class CodexSessionRuntime {
784
788
  return origin;
785
789
  }
786
790
  }
791
+ /** `thread/list` pages can replay an id while a child transitions. Keep its newest row. */
792
+ function uniqueDirectChildren(children) {
793
+ const result = new Map();
794
+ for (const child of children)
795
+ result.set(child.id, child);
796
+ return [...result.values()].slice(0, 64);
797
+ }
787
798
  function isMethodNotFound(error) {
788
799
  return Boolean(error && typeof error === 'object' && error.code === -32601);
789
800
  }
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright (C) 2026 Dyne.org foundation
3
+ * Designed by Denis Roio <jaromil@dyne.org>
4
+ * SPDX-License-Identifier: AGPL-3.0-or-later
5
+ */
6
+ import { execFile } from 'node:child_process';
7
+ import { promisify } from 'node:util';
8
+ const runFile = promisify(execFile);
9
+ export class GestaltUpdateRestartScheduler {
10
+ run;
11
+ constructor(run = (command, args, options) => runFile(command, [...args], options)) {
12
+ this.run = run;
13
+ }
14
+ async schedule() {
15
+ try {
16
+ await this.run('gestalt', ['update-restart'], {
17
+ env: process.env,
18
+ timeout: 15_000,
19
+ maxBuffer: 64 * 1024,
20
+ });
21
+ }
22
+ catch {
23
+ throw new Error('Gestalt update and restart could not be scheduled');
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "component": "mobile",
4
+ "supervisionContract": 1,
5
+ "capabilities": [
6
+ "supervision-start",
7
+ "wait-lease-tool",
8
+ "checkpoint-tool",
9
+ "controller-status",
10
+ "canonical-agent-identity",
11
+ "session-verdict",
12
+ "acknowledgement-safe-composer",
13
+ "org-plan-contract"
14
+ ]
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gestalt-mobile",
3
- "version": "0.30.3",
3
+ "version": "0.32.0",
4
4
  "description": "Mobile-first web relay for durable Codex development sessions",
5
5
  "keywords": [
6
6
  "codex",
@@ -26,7 +26,8 @@
26
26
  "dist/server",
27
27
  "dist/client",
28
28
  "README.md",
29
- "LICENSE"
29
+ "LICENSE",
30
+ "gestalt-supervision-capabilities.json"
30
31
  ],
31
32
  "engines": {
32
33
  "node": ">=24.0.0"