@moxt-ai/mobius 0.0.336 → 0.0.338

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 (60) hide show
  1. package/dist/cli.js +1407 -1283
  2. package/dist/cli.js.map +4 -4
  3. package/dist/daemon/upgrades/upgrade.d.ts.map +1 -1
  4. package/dist/daemon/upgrades/upgrade.js +25 -2
  5. package/dist/daemon/upgrades/upgrade.js.map +1 -1
  6. package/dist/runtime.js +1091 -1021
  7. package/dist/runtime.js.map +4 -4
  8. package/dist/session/turn/runtime-turn-activity.d.ts +12 -1
  9. package/dist/session/turn/runtime-turn-activity.d.ts.map +1 -1
  10. package/dist/session/turn/runtime-turn-activity.js +52 -26
  11. package/dist/session/turn/runtime-turn-activity.js.map +1 -1
  12. package/dist/util/filesystem/private-path.js +6 -324
  13. package/dist/util/filesystem/private-path.js.map +4 -4
  14. package/dist/util/platform/contracts.d.ts +0 -26
  15. package/dist/util/platform/contracts.d.ts.map +1 -1
  16. package/dist/util/platform/index.d.ts.map +1 -1
  17. package/dist/util/platform/index.js +1 -4
  18. package/dist/util/platform/index.js.map +1 -1
  19. package/dist/util/platform/linux.d.ts.map +1 -1
  20. package/dist/util/platform/linux.js +1 -117
  21. package/dist/util/platform/linux.js.map +1 -1
  22. package/dist/util/platform/macos.d.ts.map +1 -1
  23. package/dist/util/platform/macos.js +1 -4
  24. package/dist/util/platform/macos.js.map +1 -1
  25. package/dist/util/platform/posix.d.ts +0 -21
  26. package/dist/util/platform/posix.d.ts.map +1 -1
  27. package/dist/util/platform/posix.js +1 -104
  28. package/dist/util/platform/posix.js.map +1 -1
  29. package/dist/util/platform/windows.d.ts.map +1 -1
  30. package/dist/util/platform/windows.js +1 -107
  31. package/dist/util/platform/windows.js.map +1 -1
  32. package/dist/util/process/executable.d.ts +2 -2
  33. package/dist/util/process/executable.d.ts.map +1 -1
  34. package/dist/util/process/executable.js +31 -222
  35. package/dist/util/process/executable.js.map +4 -4
  36. package/dist/util/process/platform/contracts.d.ts +29 -0
  37. package/dist/util/process/platform/contracts.d.ts.map +1 -0
  38. package/dist/util/process/platform/contracts.js +2 -0
  39. package/dist/util/process/platform/contracts.js.map +1 -0
  40. package/dist/util/process/platform/index.d.ts +3 -0
  41. package/dist/util/process/platform/index.d.ts.map +1 -0
  42. package/dist/util/process/platform/index.js +20 -0
  43. package/dist/util/process/platform/index.js.map +1 -0
  44. package/dist/util/process/platform/linux.d.ts +3 -0
  45. package/dist/util/process/platform/linux.d.ts.map +1 -0
  46. package/dist/util/process/platform/linux.js +122 -0
  47. package/dist/util/process/platform/linux.js.map +1 -0
  48. package/dist/util/process/platform/macos.d.ts +3 -0
  49. package/dist/util/process/platform/macos.d.ts.map +1 -0
  50. package/dist/util/process/platform/macos.js +8 -0
  51. package/dist/util/process/platform/macos.js.map +1 -0
  52. package/dist/util/process/platform/posix.d.ts +25 -0
  53. package/dist/util/process/platform/posix.d.ts.map +1 -0
  54. package/dist/util/process/platform/posix.js +107 -0
  55. package/dist/util/process/platform/posix.js.map +1 -0
  56. package/dist/util/process/platform/windows.d.ts +3 -0
  57. package/dist/util/process/platform/windows.d.ts.map +1 -0
  58. package/dist/util/process/platform/windows.js +114 -0
  59. package/dist/util/process/platform/windows.js.map +1 -0
  60. package/package.json +2 -2
package/dist/runtime.js CHANGED
@@ -55,30 +55,17 @@ import { realpathSync, statSync } from "node:fs";
55
55
  // src/util/process/executable.ts
56
56
  import { spawn } from "node:child_process";
57
57
  import { stat as stat2 } from "node:fs/promises";
58
- import { join as join6, resolve as resolve2 } from "node:path";
58
+ import { join as join3, resolve as resolve2 } from "node:path";
59
59
 
60
- // src/util/platform/linux.ts
60
+ // src/util/process/platform/linux.ts
61
61
  import { constants as constants2, readdirSync, readFileSync } from "node:fs";
62
62
  import { access as access2, readdir, readFile, realpath as realpath2, stat } from "node:fs/promises";
63
- import { isAbsolute, join as join2 } from "node:path";
63
+ import { join } from "node:path";
64
64
 
65
- // src/util/platform/posix.ts
65
+ // src/util/process/platform/posix.ts
66
66
  import { execFile } from "node:child_process";
67
67
  import { constants } from "node:fs";
68
- import { access, chmod, lstat, realpath, unlink } from "node:fs/promises";
69
- import { tmpdir } from "node:os";
70
- import { join } from "node:path";
71
-
72
- // src/util/filesystem/path-error.ts
73
- var LocalPathError = class extends Error {
74
- code = "unsafe_local_path";
75
- constructor(message, options = {}) {
76
- super(message, options);
77
- this.name = "LocalPathError";
78
- }
79
- };
80
-
81
- // src/util/platform/posix.ts
68
+ import { access, realpath } from "node:fs/promises";
82
69
  var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
83
70
  var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
84
71
  function parseProcessTable(output2) {
@@ -158,22 +145,7 @@ function terminateProcess(child, signal) {
158
145
  }
159
146
  child.kill(signal);
160
147
  }
161
- async function removeControlSocket(path7) {
162
- try {
163
- await unlink(path7);
164
- } catch (cause) {
165
- if (!(cause instanceof Error) || !("code" in cause) || cause.code !== "ENOENT") {
166
- throw cause;
167
- }
168
- }
169
- }
170
148
  var posixOperations = {
171
- controlSocketPath: (installationHash) => join(tmpdir(), `mobius-${installationHash}.sock`),
172
- prepareControlSocket: removeControlSocket,
173
- secureControlSocket: async (path7) => {
174
- await chmod(path7, 384);
175
- },
176
- removeControlSocket,
177
149
  pathDelimiter: ":",
178
150
  environmentValue: (environment, name2) => environment[name2],
179
151
  executableExtensions: () => [""],
@@ -185,21 +157,10 @@ var posixOperations = {
185
157
  executableLaunch: (command, args) => ({ command, arguments: args }),
186
158
  spawnOptions: { detached: true, windowsHide: true },
187
159
  signalCapturedProcesses,
188
- terminateProcess,
189
- validatePathPermissions: async (path7, directory, privateAccess, signal) => {
190
- signal.throwIfAborted();
191
- const metadata = await lstat(path7);
192
- if (process.getuid === void 0 || metadata.uid !== process.getuid()) {
193
- throw new LocalPathError("Path is not user-owned");
194
- }
195
- if (privateAccess) {
196
- await chmod(path7, directory ? 448 : 384);
197
- }
198
- signal.throwIfAborted();
199
- }
160
+ terminateProcess
200
161
  };
201
162
 
202
- // src/util/platform/linux.ts
163
+ // src/util/process/platform/linux.ts
203
164
  function appendLinuxProcessTableEntry(entries, processId, encoded) {
204
165
  const closingParenthesis = encoded.lastIndexOf(")");
205
166
  if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
@@ -229,7 +190,7 @@ async function readLinuxProcessTable() {
229
190
  appendLinuxProcessTableEntry(
230
191
  entries,
231
192
  processId,
232
- await readFile(join2("/proc", directory.name, "stat"), "utf8")
193
+ await readFile(join("/proc", directory.name, "stat"), "utf8")
233
194
  );
234
195
  } catch {
235
196
  }
@@ -254,7 +215,7 @@ function readLinuxProcessTableSynchronously() {
254
215
  appendLinuxProcessTableEntry(
255
216
  entries,
256
217
  processId,
257
- readFileSync(join2("/proc", directory.name, "stat"), "utf8")
218
+ readFileSync(join("/proc", directory.name, "stat"), "utf8")
258
219
  );
259
220
  } catch {
260
221
  }
@@ -287,7 +248,7 @@ async function readLinuxProcessTableWithFallback() {
287
248
  }
288
249
  function processExists2(processId) {
289
250
  try {
290
- const encoded = readFileSync(join2("/proc", processId.toString(), "stat"), "utf8");
251
+ const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
291
252
  const closingParenthesis = encoded.lastIndexOf(")");
292
253
  if (closingParenthesis >= 0) {
293
254
  const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
@@ -299,80 +260,25 @@ function processExists2(processId) {
299
260
  }
300
261
  return processExists(processId);
301
262
  }
302
- var linuxPlatform = {
263
+ var linuxProcessPlatform = {
303
264
  ...posixOperations,
304
265
  readProcessTable: readLinuxProcessTableWithFallback,
305
266
  readProcessTableSynchronously: readLinuxProcessTableSynchronously,
306
- processExists: processExists2,
307
- claudeCodeExecutablePaths: (environment) => {
308
- const homeDirectory = environment["HOME"];
309
- return homeDirectory !== void 0 && isAbsolute(homeDirectory) ? [join2(homeDirectory, ".local", "bin", "claude")] : [];
310
- }
267
+ processExists: processExists2
311
268
  };
312
269
 
313
- // src/util/platform/macos.ts
314
- import { isAbsolute as isAbsolute2, join as join4 } from "node:path";
315
-
316
- // src/util/platform/claude-desktop.ts
317
- import { readdirSync as readdirSync2 } from "node:fs";
318
- import { join as join3 } from "node:path";
319
- function installedDirectories(directory) {
320
- try {
321
- return readdirSync2(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
322
- } catch (cause) {
323
- if (cause instanceof Error && "code" in cause && (cause.code === "ENOENT" || cause.code === "ENOTDIR" || cause.code === "EACCES")) {
324
- return [];
325
- }
326
- throw cause;
327
- }
328
- }
329
- function claudeDesktopExecutablePaths(roots, executablePaths) {
330
- const paths = [];
331
- for (const root of roots) {
332
- const versions = installedDirectories(root).filter((version2) => /^\d+\.\d+\.\d+$/.test(version2)).toSorted((left, right) => right.localeCompare(left, "en", { numeric: true }));
333
- for (const version2 of versions) {
334
- const directory = join3(root, version2);
335
- const installations = [
336
- directory,
337
- ...installedDirectories(directory).map((build) => join3(directory, build))
338
- ];
339
- for (const installation of installations) {
340
- for (const executablePath of executablePaths) {
341
- paths.push(join3(installation, ...executablePath));
342
- }
343
- }
344
- }
345
- }
346
- return paths;
347
- }
348
-
349
- // src/util/platform/macos.ts
350
- var macosPlatform = {
270
+ // src/util/process/platform/macos.ts
271
+ var macosProcessPlatform = {
351
272
  ...posixOperations,
352
273
  readProcessTable: () => readProcessTableWithPs("/bin/ps"),
353
274
  readProcessTableSynchronously: () => [],
354
- processExists,
355
- claudeCodeExecutablePaths: (environment) => {
356
- const paths = ["/opt/homebrew/bin/claude", "/usr/local/bin/claude"];
357
- const homeDirectory = environment["HOME"];
358
- if (homeDirectory !== void 0 && isAbsolute2(homeDirectory)) {
359
- paths.unshift(join4(homeDirectory, ".local", "bin", "claude"));
360
- paths.push(
361
- ...claudeDesktopExecutablePaths(
362
- [join4(homeDirectory, "Library", "Application Support", "Claude", "claude-code")],
363
- [["claude.app", "Contents", "MacOS", "claude"], ["claude"]]
364
- )
365
- );
366
- }
367
- return paths;
368
- }
275
+ processExists
369
276
  };
370
277
 
371
- // src/util/platform/windows.ts
278
+ // src/util/process/platform/windows.ts
372
279
  import { execFile as execFile2 } from "node:child_process";
373
280
  import { readFile as readFile2, realpath as realpath3 } from "node:fs/promises";
374
- import { dirname, extname, isAbsolute as isAbsolute3, join as join5, resolve } from "node:path";
375
- import { promisify } from "node:util";
281
+ import { dirname, extname, join as join2, resolve } from "node:path";
376
282
 
377
283
  // src/util/process/process-error.ts
378
284
  var ProcessExecutionError = class extends Error {
@@ -384,28 +290,10 @@ var ProcessExecutionError = class extends Error {
384
290
  }
385
291
  };
386
292
 
387
- // src/util/platform/windows.ts
388
- var execute = promisify(execFile2);
293
+ // src/util/process/platform/windows.ts
389
294
  function environmentValue(environment, name2) {
390
295
  return Object.entries(environment).find(([key]) => key.toUpperCase() === name2.toUpperCase())?.[1];
391
296
  }
392
- function desktopClaudeExecutablePaths(environment) {
393
- const roots = [];
394
- const localAppData = environmentValue(environment, "LOCALAPPDATA");
395
- if (localAppData !== void 0 && isAbsolute3(localAppData)) {
396
- const dataDirectory = join5(localAppData, "Claude-Data");
397
- for (const installation of installedDirectories(dataDirectory)) {
398
- if (installation.startsWith("claude_")) {
399
- roots.push(join5(dataDirectory, installation, "claude-code"));
400
- }
401
- }
402
- }
403
- const appData = environmentValue(environment, "APPDATA");
404
- if (appData !== void 0 && isAbsolute3(appData)) {
405
- roots.push(join5(appData, "Claude", "claude-code"));
406
- }
407
- return claudeDesktopExecutablePaths(roots, [["claude.exe"]]);
408
- }
409
297
  function executableExtensions(executableName, environment) {
410
298
  if (/\.[a-zA-Z0-9]+$/.test(executableName)) {
411
299
  return [""];
@@ -464,7 +352,7 @@ function readProcessTable() {
464
352
  }
465
353
  return new Promise((resolveTable) => {
466
354
  execFile2(
467
- join5(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
355
+ join2(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
468
356
  [
469
357
  "-NoLogo",
470
358
  "-NoProfile",
@@ -497,71 +385,7 @@ function terminateProcess2(child, signal) {
497
385
  }
498
386
  child.kill(signal);
499
387
  }
500
- var windowsPermissions = `
501
- $ErrorActionPreference = 'Stop'
502
- $ProgressPreference = 'SilentlyContinue'
503
- $item = Get-Item -LiteralPath $env:MOBIUS_PERMISSION_PATH -Force
504
- if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'Unsafe path' }
505
- $sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
506
- $acl = $item.GetAccessControl()
507
- $owner = $acl.GetOwner([Security.Principal.SecurityIdentifier])
508
- if ($owner -ne $sid -and -not ($owner.Value -eq 'S-1-5-32-544' -and ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { throw 'Path is not user-owned' }
509
- if ($env:MOBIUS_PERMISSION_PRIVATE -eq '1') {
510
- if ($item.PSIsContainer) {
511
- $private = New-Object Security.AccessControl.DirectorySecurity
512
- $rule = New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
513
- } else {
514
- $private = New-Object Security.AccessControl.FileSecurity
515
- $rule = New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'Allow')
516
- }
517
- $private.SetOwner($sid)
518
- $private.SetAccessRuleProtection($true, $false)
519
- $private.AddAccessRule($rule)
520
- $item.SetAccessControl($private)
521
- }
522
- `;
523
- var windowsPermissionsTimeoutMs = 3e4;
524
- async function validatePathPermissions(path7, _directory, privateAccess, signal) {
525
- signal.throwIfAborted();
526
- const systemRoot = environmentValue(process.env, "SystemRoot");
527
- if (systemRoot === void 0) {
528
- throw new LocalPathError("Windows system directory is unavailable");
529
- }
530
- try {
531
- await execute(
532
- join5(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
533
- [
534
- "-NoLogo",
535
- "-NoProfile",
536
- "-NonInteractive",
537
- "-EncodedCommand",
538
- Buffer.from(windowsPermissions, "utf16le").toString("base64")
539
- ],
540
- {
541
- env: {
542
- ...process.env,
543
- MOBIUS_PERMISSION_PATH: path7,
544
- MOBIUS_PERMISSION_PRIVATE: privateAccess ? "1" : "0"
545
- },
546
- windowsHide: true,
547
- signal: AbortSignal.any([signal, AbortSignal.timeout(windowsPermissionsTimeoutMs)]),
548
- timeout: windowsPermissionsTimeoutMs,
549
- maxBuffer: 16384
550
- }
551
- );
552
- } catch (cause) {
553
- signal.throwIfAborted();
554
- throw new LocalPathError("The local path permissions could not be secured", { cause });
555
- }
556
- }
557
- var windowsPlatform = {
558
- controlSocketPath: (installationHash) => `\\\\.\\pipe\\mobius-${installationHash}`,
559
- prepareControlSocket: async () => {
560
- },
561
- secureControlSocket: async () => {
562
- },
563
- removeControlSocket: async () => {
564
- },
388
+ var windowsProcessPlatform = {
565
389
  pathDelimiter: ";",
566
390
  environmentValue,
567
391
  executableExtensions,
@@ -570,44 +394,29 @@ var windowsPlatform = {
570
394
  spawnOptions: { detached: false, windowsHide: true },
571
395
  signalCapturedProcesses: signalCapturedProcesses2,
572
396
  terminateProcess: terminateProcess2,
573
- validatePathPermissions,
574
397
  readProcessTable,
575
398
  readProcessTableSynchronously: () => [],
576
- processExists,
577
- claudeCodeExecutablePaths: (environment) => {
578
- const paths = [];
579
- const userProfile = environmentValue(environment, "USERPROFILE");
580
- if (userProfile !== void 0 && isAbsolute3(userProfile)) {
581
- paths.push(join5(userProfile, ".local", "bin", "claude.exe"));
582
- }
583
- const localAppData = environmentValue(environment, "LOCALAPPDATA");
584
- if (localAppData !== void 0 && isAbsolute3(localAppData)) {
585
- paths.push(join5(localAppData, "Microsoft", "WinGet", "Links", "claude.exe"));
586
- }
587
- paths.push(...desktopClaudeExecutablePaths(environment));
588
- return paths;
589
- }
399
+ processExists
590
400
  };
591
401
 
592
- // src/util/platform/index.ts
402
+ // src/util/process/platform/index.ts
593
403
  var fallbackPlatform = {
594
404
  ...posixOperations,
595
405
  readProcessTable: () => readProcessTableWithPs("/usr/bin/ps"),
596
406
  readProcessTableSynchronously: () => [],
597
- processExists,
598
- claudeCodeExecutablePaths: () => []
407
+ processExists
599
408
  };
600
409
  var platforms = /* @__PURE__ */ new Map([
601
- ["linux", linuxPlatform],
602
- ["darwin", macosPlatform],
603
- ["win32", windowsPlatform]
410
+ ["linux", linuxProcessPlatform],
411
+ ["darwin", macosProcessPlatform],
412
+ ["win32", windowsProcessPlatform]
604
413
  ]);
605
- function platformSupportFor(platform2) {
414
+ function processPlatformSupportFor(platform2) {
606
415
  return platforms.get(platform2) ?? fallbackPlatform;
607
416
  }
608
417
 
609
418
  // src/util/process/executable.ts
610
- var hostPlatform = platformSupportFor(process.platform);
419
+ var hostPlatform = processPlatformSupportFor(process.platform);
611
420
  var DEFAULT_OUTPUT_LIMIT_BYTES = 16 * 1024;
612
421
  var PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS = 1e3;
613
422
  var PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS = 5e3;
@@ -650,7 +459,7 @@ var ProcessResult = class {
650
459
  async function resolveExecutablePath(requestedPath2, platform2 = process.platform) {
651
460
  const absoluteRequestedPath = resolve2(requestedPath2);
652
461
  try {
653
- const resolvedPath = await platformSupportFor(platform2).resolveExecutableTarget(absoluteRequestedPath);
462
+ const resolvedPath = await processPlatformSupportFor(platform2).resolveExecutableTarget(absoluteRequestedPath);
654
463
  const metadata = await stat2(resolvedPath);
655
464
  if (!metadata.isFile()) {
656
465
  return null;
@@ -670,7 +479,7 @@ async function resolveExecutablePath(requestedPath2, platform2 = process.platfor
670
479
  }
671
480
  }
672
481
  async function findExecutableOnPath(executableName, environment, platform2 = process.platform) {
673
- const support = platformSupportFor(platform2);
482
+ const support = processPlatformSupportFor(platform2);
674
483
  const encodedPath = support.environmentValue(environment, "PATH") ?? "";
675
484
  const separator = support.pathDelimiter;
676
485
  const extensions = support.executableExtensions(executableName, environment);
@@ -679,7 +488,7 @@ async function findExecutableOnPath(executableName, environment, platform2 = pro
679
488
  continue;
680
489
  }
681
490
  for (const extension of extensions) {
682
- const requestedPath2 = resolve2(join6(entry, `${executableName}${extension}`));
491
+ const requestedPath2 = resolve2(join3(entry, `${executableName}${extension}`));
683
492
  const executable = await resolveExecutablePath(requestedPath2, platform2);
684
493
  if (executable !== null) {
685
494
  return executable;
@@ -20920,7 +20729,7 @@ async function runCleanup(...actions) {
20920
20729
  }
20921
20730
 
20922
20731
  // src/acp/adapter/live-sessions.ts
20923
- import { isAbsolute as isAbsolute4, resolve as resolve3 } from "node:path";
20732
+ import { isAbsolute, resolve as resolve3 } from "node:path";
20924
20733
  import { methods as methods3 } from "@agentclientprotocol/sdk";
20925
20734
 
20926
20735
  // ../mobius-sdk/src/protocol/platform/mobius-api.ts
@@ -21443,145 +21252,6 @@ var encodeSessionRenameCommand = (message) => encodeZodMessage(message, sessionR
21443
21252
  var decodeSessionRenamedEvent = (encoded) => decodeZodMessage(encoded, sessionRenamedEventSchema);
21444
21253
  var encodeSessionRenamedEvent = (message) => encodeZodMessage(message, sessionRenamedEventSchema);
21445
21254
 
21446
- // ../mobius-sdk/src/protocol/session/files/index.ts
21447
- var FILE_READ_KIND = "file.read";
21448
- var FILE_BEGIN_KIND = "file.begin";
21449
- var FILE_END_KIND = "file.end";
21450
- var FILE_FAILED_KIND = "file.failed";
21451
- var CONTENT_WRITE_KIND = "content.write";
21452
- var CONTENT_COMMIT_KIND = "content.commit";
21453
- var CONTENT_READY_KIND = "content.ready";
21454
- var CONTENT_AVAILABLE_KIND = "content.available";
21455
- var CONTENT_CHUNK_MAX_BYTES = 192 * 1024;
21456
- var CONTENT_WRITE_MAX_BYTES = 32 * 1024 * 1024;
21457
- var PROMPT_IMAGE_MAX_BYTES = 5e6;
21458
- var CONTENT_CHUNK_MAGIC = new Uint8Array([77, 66, 67, 49]);
21459
- var CONTENT_CHUNK_HEADER_BYTES = CONTENT_CHUNK_MAGIC.byteLength + 1 + 4;
21460
- var fileReadCommandSchema = external_exports.object({
21461
- kind: external_exports.literal(FILE_READ_KIND),
21462
- maxBytes: external_exports.number().int().positive().max(128 * 1024 * 1024),
21463
- requestId: identifierStringSchema,
21464
- sessionId: identifierStringSchema,
21465
- path: external_exports.string().min(1).max(4096)
21466
- }).readonly();
21467
- var fileBeginEventSchema = external_exports.object({
21468
- byteLength: external_exports.number().int().positive().max(128 * 1024 * 1024),
21469
- kind: external_exports.literal(FILE_BEGIN_KIND),
21470
- mediaType: external_exports.string().min(1).max(255),
21471
- modifiedAt: external_exports.iso.datetime({ offset: true }),
21472
- name: external_exports.string().min(1).max(500),
21473
- requestId: identifierStringSchema,
21474
- sessionId: identifierStringSchema
21475
- }).readonly();
21476
- var contentWriteCommandSchema = external_exports.object({
21477
- byteLength: external_exports.number().int().positive().max(CONTENT_WRITE_MAX_BYTES),
21478
- contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
21479
- contentKind: external_exports.enum(["image", "resource"]),
21480
- kind: external_exports.literal(CONTENT_WRITE_KIND),
21481
- mediaType: external_exports.string().min(1).max(255),
21482
- name: external_exports.string().min(1).max(500),
21483
- requestId: identifierStringSchema,
21484
- sessionId: identifierStringSchema
21485
- }).readonly();
21486
- var contentCommitCommandSchema = external_exports.object({
21487
- kind: external_exports.literal(CONTENT_COMMIT_KIND),
21488
- requestId: identifierStringSchema,
21489
- sessionId: identifierStringSchema
21490
- }).readonly();
21491
- var contentReadyEventSchema = external_exports.object({
21492
- kind: external_exports.literal(CONTENT_READY_KIND),
21493
- requestId: identifierStringSchema,
21494
- sessionId: identifierStringSchema
21495
- }).readonly();
21496
- var contentAvailableEventSchema = external_exports.object({
21497
- byteLength: external_exports.number().int().positive().max(CONTENT_WRITE_MAX_BYTES),
21498
- contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
21499
- kind: external_exports.literal(CONTENT_AVAILABLE_KIND),
21500
- requestId: identifierStringSchema,
21501
- sessionId: identifierStringSchema
21502
- }).readonly();
21503
- function binaryBytes(value) {
21504
- if (value instanceof ArrayBuffer) {
21505
- return new Uint8Array(value);
21506
- }
21507
- if (ArrayBuffer.isView(value)) {
21508
- return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
21509
- }
21510
- throw new Error("Content chunk must be a binary WebSocket frame");
21511
- }
21512
- function encodeContentChunkFrame(frame) {
21513
- if (!isIdentifier(frame.requestId)) {
21514
- throw new Error("Content chunk request identifier is invalid");
21515
- }
21516
- if (!Number.isSafeInteger(frame.sequence) || frame.sequence < 0 || frame.sequence > 4294967295) {
21517
- throw new Error("Content chunk sequence is invalid");
21518
- }
21519
- if (frame.bytes.byteLength < 1 || frame.bytes.byteLength > CONTENT_CHUNK_MAX_BYTES) {
21520
- throw new Error("Content chunk size is invalid");
21521
- }
21522
- const requestId = new TextEncoder().encode(frame.requestId);
21523
- if (requestId.byteLength > 255) {
21524
- throw new Error("Content chunk request identifier is too long");
21525
- }
21526
- const encoded = new Uint8Array(CONTENT_CHUNK_HEADER_BYTES + requestId.byteLength + frame.bytes.byteLength);
21527
- encoded.set(CONTENT_CHUNK_MAGIC, 0);
21528
- encoded[CONTENT_CHUNK_MAGIC.byteLength] = requestId.byteLength;
21529
- new DataView(encoded.buffer).setUint32(CONTENT_CHUNK_MAGIC.byteLength + 1, frame.sequence);
21530
- encoded.set(requestId, CONTENT_CHUNK_HEADER_BYTES);
21531
- encoded.set(frame.bytes, CONTENT_CHUNK_HEADER_BYTES + requestId.byteLength);
21532
- return encoded;
21533
- }
21534
- function decodeContentChunkFrame(value) {
21535
- const encoded = binaryBytes(value);
21536
- if (encoded.byteLength <= CONTENT_CHUNK_HEADER_BYTES || !CONTENT_CHUNK_MAGIC.every((byte, index2) => encoded[index2] === byte)) {
21537
- throw new Error("Content chunk frame header is invalid");
21538
- }
21539
- const requestIdLength = encoded[CONTENT_CHUNK_MAGIC.byteLength] ?? 0;
21540
- const payloadOffset = CONTENT_CHUNK_HEADER_BYTES + requestIdLength;
21541
- if (requestIdLength < 1 || payloadOffset >= encoded.byteLength) {
21542
- throw new Error("Content chunk frame length is invalid");
21543
- }
21544
- const requestId = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
21545
- encoded.subarray(CONTENT_CHUNK_HEADER_BYTES, payloadOffset)
21546
- );
21547
- const bytes = encoded.slice(payloadOffset);
21548
- const sequence = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength).getUint32(
21549
- CONTENT_CHUNK_MAGIC.byteLength + 1
21550
- );
21551
- if (!isIdentifier(requestId) || bytes.byteLength > CONTENT_CHUNK_MAX_BYTES) {
21552
- throw new Error("Content chunk frame is invalid");
21553
- }
21554
- return { bytes, requestId, sequence };
21555
- }
21556
- var fileEndEventSchema = external_exports.object({
21557
- kind: external_exports.literal(FILE_END_KIND),
21558
- requestId: identifierStringSchema,
21559
- sessionId: identifierStringSchema
21560
- }).readonly();
21561
- var fileFailedEventSchema = external_exports.object({
21562
- code: identifierStringSchema,
21563
- kind: external_exports.literal(FILE_FAILED_KIND),
21564
- message: external_exports.string().min(1).max(500),
21565
- requestId: identifierStringSchema,
21566
- sessionId: identifierStringSchema
21567
- }).readonly();
21568
- var decodeFileReadCommand = (encoded) => decodeZodMessage(encoded, fileReadCommandSchema);
21569
- var encodeFileReadCommand = (message) => encodeZodMessage(message, fileReadCommandSchema);
21570
- var decodeFileBeginEvent = (encoded) => decodeZodMessage(encoded, fileBeginEventSchema);
21571
- var encodeFileBeginEvent = (message) => encodeZodMessage(message, fileBeginEventSchema);
21572
- var decodeFileEndEvent = (encoded) => decodeZodMessage(encoded, fileEndEventSchema);
21573
- var encodeFileEndEvent = (message) => encodeZodMessage(message, fileEndEventSchema);
21574
- var decodeFileFailedEvent = (encoded) => decodeZodMessage(encoded, fileFailedEventSchema);
21575
- var encodeFileFailedEvent = (message) => encodeZodMessage(message, fileFailedEventSchema);
21576
- var decodeContentWriteCommand = (encoded) => decodeZodMessage(encoded, contentWriteCommandSchema);
21577
- var encodeContentWriteCommand = (message) => encodeZodMessage(message, contentWriteCommandSchema);
21578
- var decodeContentCommitCommand = (encoded) => decodeZodMessage(encoded, contentCommitCommandSchema);
21579
- var encodeContentCommitCommand = (message) => encodeZodMessage(message, contentCommitCommandSchema);
21580
- var decodeContentReadyEvent = (encoded) => decodeZodMessage(encoded, contentReadyEventSchema);
21581
- var encodeContentReadyEvent = (message) => encodeZodMessage(message, contentReadyEventSchema);
21582
- var decodeContentAvailableEvent = (encoded) => decodeZodMessage(encoded, contentAvailableEventSchema);
21583
- var encodeContentAvailableEvent = (message) => encodeZodMessage(message, contentAvailableEventSchema);
21584
-
21585
21255
  // ../mobius-sdk/src/protocol/shared/tool-input.ts
21586
21256
  var MAX_CONTENT_LENGTH = 1e6;
21587
21257
  var MAX_COLLECTION_SIZE = 1e3;
@@ -21738,433 +21408,7 @@ var encodeSessionPermissionRespondCommand = (message) => encodeZodMessage(messag
21738
21408
  var decodeSessionElicitationRespondCommand = (encoded) => decodeZodMessage(encoded, sessionElicitationRespondCommandSchema);
21739
21409
  var encodeSessionElicitationRespondCommand = (message) => encodeZodMessage(message, sessionElicitationRespondCommandSchema);
21740
21410
 
21741
- // ../mobius-sdk/src/protocol/session/lifecycle/index.ts
21742
- var SESSION_PREPARE_KIND = "session.prepare";
21743
- var SESSION_READY_KIND = "session.ready";
21744
- var SESSION_LIST_KIND = "session.list";
21745
- var SESSION_LISTED_KIND = "session.listed";
21746
- var SESSION_QUERY_KIND = "session.query";
21747
- var SESSION_QUERIED_KIND = "session.queried";
21748
- var SESSION_RESTORE_KIND = "session.restore";
21749
- var SESSION_RESTORED_KIND = "session.restored";
21750
- var SESSION_CLOSE_KIND = "session.close";
21751
- var SESSION_CLOSED_KIND = "session.closed";
21752
- var SESSION_CLOSE_NOTICE_KIND = "session.close.notice";
21753
- var SESSION_CLOSED_ERROR_CODE = "session_closed";
21754
- var SESSION_STATUS_CHANGED_KIND = "session.status.changed";
21755
- var SESSION_COMMANDS_UPDATED_KIND = "session.commands.updated";
21756
- var SESSION_INFO_UPDATED_KIND = "session.info.updated";
21757
- var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
21758
- var sessionStatusChangedEventSchema = external_exports.object({
21759
- kind: external_exports.literal(SESSION_STATUS_CHANGED_KIND),
21760
- sessionId: identifierStringSchema,
21761
- status: sessionStatusSchema
21762
- }).readonly();
21763
- var sessionMetadataSchema = external_exports.object({
21764
- additionalDirectories: external_exports.array(workspaceEntrySchema).max(16).readonly(),
21765
- agentId: identifierStringSchema,
21766
- directoryId: DIRECTORY_IDENTIFIER,
21767
- directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
21768
- prompted: external_exports.boolean(),
21769
- sessionId: identifierStringSchema,
21770
- status: sessionStatusSchema.default({ kind: "idle" }),
21771
- title: external_exports.string().max(500),
21772
- updatedAt: external_exports.iso.datetime({ offset: true })
21773
- }).readonly();
21774
- var sessionListCommandSchema = external_exports.object({
21775
- kind: external_exports.literal(SESSION_LIST_KIND),
21776
- limit: external_exports.number().int().positive().max(500),
21777
- requestId: identifierStringSchema
21778
- }).readonly();
21779
- var sessionsListedEventSchema = external_exports.object({
21780
- entries: external_exports.array(sessionMetadataSchema).max(500).readonly(),
21781
- kind: external_exports.literal(SESSION_LISTED_KIND),
21782
- requestId: identifierStringSchema
21783
- }).readonly();
21784
- var sessionQueryCommandSchema = external_exports.object({
21785
- kind: external_exports.literal(SESSION_QUERY_KIND),
21786
- requestId: identifierStringSchema,
21787
- sessionIds: external_exports.array(identifierStringSchema).min(1).max(500).readonly()
21788
- }).readonly();
21789
- var sessionsQueriedEventSchema = external_exports.object({
21790
- entries: external_exports.array(sessionMetadataSchema).max(500).readonly(),
21791
- kind: external_exports.literal(SESSION_QUERIED_KIND),
21792
- requestId: identifierStringSchema
21793
- }).readonly();
21794
- var sessionRestoreCommandSchema = external_exports.object({
21795
- kind: external_exports.literal(SESSION_RESTORE_KIND),
21796
- requestId: identifierStringSchema,
21797
- sessionId: identifierStringSchema
21798
- }).readonly();
21799
- var sessionCloseCommandSchema = external_exports.object({
21800
- kind: external_exports.literal(SESSION_CLOSE_KIND),
21801
- requestId: identifierStringSchema,
21802
- sessionId: identifierStringSchema
21803
- }).readonly();
21804
- var sessionPrepareCommandSchema = external_exports.object({
21805
- ...sessionIdentityFields,
21806
- configuration: external_exports.object({
21807
- booleanValue: external_exports.boolean(),
21808
- configId: external_exports.string().min(1).max(128),
21809
- value: external_exports.string().max(500),
21810
- valueType: external_exports.enum(["boolean", "select"])
21811
- }).readonly().optional(),
21812
- kind: external_exports.literal(SESSION_PREPARE_KIND),
21813
- requestId: identifierStringSchema,
21814
- sessionState: external_exports.literal("provisioned").optional(),
21815
- /** Marks an inspection-only Session preparation. */
21816
- transient: external_exports.boolean().optional()
21817
- }).superRefine((command, context) => {
21818
- if (command.transient === true && command.sessionState === "provisioned") {
21819
- context.addIssue({
21820
- code: "custom",
21821
- message: "A transient Session cannot already be provisioned",
21822
- path: ["sessionState"]
21823
- });
21824
- }
21825
- }).readonly();
21826
- var runtimeTimingsSchema = external_exports.array(
21827
- external_exports.object({
21828
- durationMilliseconds: external_exports.number().finite().nonnegative().max(12e4),
21829
- name: external_exports.string().regex(/^[a-z][a-z0-9-]{0,63}$/)
21830
- }).readonly()
21831
- ).max(16).readonly();
21832
- var sessionReadyEventSchema = external_exports.object({
21833
- additionalDirectories: external_exports.array(workspaceEntrySchema).max(16).readonly(),
21834
- agentId: identifierStringSchema,
21835
- agentName: external_exports.string().max(255),
21836
- agentVersion: external_exports.string().max(128),
21837
- capabilities: sessionCapabilitiesSchema,
21838
- commands: external_exports.array(sessionCommandSchema).max(500).readonly(),
21839
- configOptions: sessionConfigOptionsSchema,
21840
- configurationRevision: identifierStringSchema.optional(),
21841
- directoryId: DIRECTORY_IDENTIFIER,
21842
- directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
21843
- kind: external_exports.literal(SESSION_READY_KIND),
21844
- requestId: identifierStringSchema,
21845
- restored: external_exports.boolean(),
21846
- runtimeTimings: runtimeTimingsSchema.optional(),
21847
- sessionId: identifierStringSchema
21848
- }).readonly();
21849
- var sessionRestoredEventSchema = external_exports.object({
21850
- entry: sessionMetadataSchema,
21851
- kind: external_exports.literal(SESSION_RESTORED_KIND),
21852
- ready: sessionReadyEventSchema,
21853
- requestId: identifierStringSchema
21854
- }).readonly();
21855
- var sessionClosedEventSchema = external_exports.object({
21856
- kind: external_exports.literal(SESSION_CLOSED_KIND),
21857
- requestId: identifierStringSchema,
21858
- sessionId: identifierStringSchema
21859
- }).readonly();
21860
- var sessionCloseNoticeEventSchema = external_exports.object({
21861
- kind: external_exports.literal(SESSION_CLOSE_NOTICE_KIND),
21862
- reason: external_exports.string().min(1).max(500),
21863
- sessionId: identifierStringSchema
21864
- }).readonly();
21865
- var sessionCommandsUpdatedEventSchema = external_exports.object({
21866
- commands: external_exports.array(sessionCommandSchema).max(500).readonly(),
21867
- kind: external_exports.literal(SESSION_COMMANDS_UPDATED_KIND),
21868
- sessionId: identifierStringSchema
21869
- }).readonly();
21870
- var sessionInfoUpdatedEventSchema = external_exports.object({
21871
- kind: external_exports.literal(SESSION_INFO_UPDATED_KIND),
21872
- projectId: identifierStringSchema.optional(),
21873
- sessionId: identifierStringSchema,
21874
- title: external_exports.string().max(500).nullable(),
21875
- updatedAt: external_exports.string().max(128)
21876
- }).readonly();
21877
- var sessionOperationFailedEventSchema = external_exports.object({
21878
- code: identifierStringSchema,
21879
- kind: external_exports.literal(SESSION_OPERATION_FAILED_KIND),
21880
- message: external_exports.string().min(1).max(500),
21881
- requestId: identifierStringSchema,
21882
- runtimeTimings: runtimeTimingsSchema.optional(),
21883
- sessionId: external_exports.string().max(128)
21884
- }).readonly();
21885
- var decodeSessionListCommand = (encoded) => decodeZodMessage(encoded, sessionListCommandSchema);
21886
- var encodeSessionListCommand = (message) => encodeZodMessage(message, sessionListCommandSchema);
21887
- var decodeSessionsListedEvent = (encoded) => decodeZodMessage(encoded, sessionsListedEventSchema);
21888
- var encodeSessionsListedEvent = (message) => encodeZodMessage(message, sessionsListedEventSchema);
21889
- var decodeSessionQueryCommand = (encoded) => decodeZodMessage(encoded, sessionQueryCommandSchema);
21890
- var encodeSessionQueryCommand = (message) => encodeZodMessage(message, sessionQueryCommandSchema);
21891
- var decodeSessionsQueriedEvent = (encoded) => decodeZodMessage(encoded, sessionsQueriedEventSchema);
21892
- var encodeSessionsQueriedEvent = (message) => encodeZodMessage(message, sessionsQueriedEventSchema);
21893
- var decodeSessionRestoreCommand = (encoded) => decodeZodMessage(encoded, sessionRestoreCommandSchema);
21894
- var encodeSessionRestoreCommand = (message) => encodeZodMessage(message, sessionRestoreCommandSchema);
21895
- var decodeSessionRestoredEvent = (encoded) => decodeZodMessage(encoded, sessionRestoredEventSchema);
21896
- var encodeSessionRestoredEvent = (message) => encodeZodMessage(message, sessionRestoredEventSchema);
21897
- var decodeSessionCloseCommand = (encoded) => decodeZodMessage(encoded, sessionCloseCommandSchema);
21898
- var encodeSessionCloseCommand = (message) => encodeZodMessage(message, sessionCloseCommandSchema);
21899
- var decodeSessionClosedEvent = (encoded) => decodeZodMessage(encoded, sessionClosedEventSchema);
21900
- var encodeSessionClosedEvent = (message) => encodeZodMessage(message, sessionClosedEventSchema);
21901
- var decodeSessionCloseNoticeEvent = (encoded) => decodeZodMessage(encoded, sessionCloseNoticeEventSchema);
21902
- var encodeSessionCloseNoticeEvent = (message) => encodeZodMessage(message, sessionCloseNoticeEventSchema);
21903
- var decodeSessionStatusChangedEvent = (encoded) => decodeZodMessage(encoded, sessionStatusChangedEventSchema);
21904
- var encodeSessionStatusChangedEvent = (message) => encodeZodMessage(message, sessionStatusChangedEventSchema);
21905
- var decodeSessionPrepareCommand = (encoded) => decodeZodMessage(encoded, sessionPrepareCommandSchema);
21906
- var encodeSessionPrepareCommand = (message) => encodeZodMessage(message, sessionPrepareCommandSchema);
21907
- var decodeSessionReadyEvent = (encoded) => decodeZodMessage(encoded, sessionReadyEventSchema);
21908
- var encodeSessionReadyEvent = (message) => encodeZodMessage(message, sessionReadyEventSchema);
21909
- var decodeSessionInfoUpdatedEvent = (encoded) => decodeZodMessage(encoded, sessionInfoUpdatedEventSchema);
21910
- var encodeSessionInfoUpdatedEvent = (message) => encodeZodMessage(message, sessionInfoUpdatedEventSchema);
21911
- var decodeSessionOperationFailedEvent = (encoded) => decodeZodMessage(encoded, sessionOperationFailedEventSchema);
21912
- var encodeSessionOperationFailedEvent = (message) => encodeZodMessage(message, sessionOperationFailedEventSchema);
21913
-
21914
- // ../mobius-sdk/src/protocol/session/prompt/commands.ts
21915
- var SESSION_PROMPT_KIND = "session.prompt";
21916
- var SESSION_PROMPT_DISPOSITION_KIND = "session.prompt.disposition";
21917
- var SESSION_CANCEL_KIND = "session.cancel";
21918
- var SESSION_CANCEL_BEFORE_START_KIND = "session.cancel-before-start";
21919
- var SessionPromptDisposition = Object.freeze({
21920
- Queue: "queue",
21921
- Reject: "reject",
21922
- Steer: "steer"
21923
- });
21924
- var SessionHistoryPolicy = Object.freeze({
21925
- Eager: "eager",
21926
- ExecutionOnly: "execution-only"
21927
- });
21928
- var MAX_PROMPT_LENGTH = 1e5;
21929
- var MAX_PROMPT_ATTACHMENT_BYTES = 32 * 1024 * 1024;
21930
- function decodeSessionCancelBeforeStartCommand(encoded) {
21931
- const value = parseJson(encoded);
21932
- assertKind(value, SESSION_CANCEL_BEFORE_START_KIND);
21933
- return {
21934
- commandId: readIdentifier(value, "commandId"),
21935
- kind: SESSION_CANCEL_BEFORE_START_KIND,
21936
- sessionId: readIdentifier(value, "sessionId")
21937
- };
21938
- }
21939
- var encodeSessionCancelBeforeStartCommand = (message) => JSON.stringify(decodeSessionCancelBeforeStartCommand(JSON.stringify(message)));
21940
- var promptAttachmentSchema = external_exports.object({
21941
- byteLength: external_exports.number().int().positive().max(MAX_PROMPT_ATTACHMENT_BYTES),
21942
- contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
21943
- kind: external_exports.enum(["image", "resource"]),
21944
- mimeType: external_exports.string().min(1).max(255),
21945
- name: external_exports.string().min(1).max(500),
21946
- uri: external_exports.string().min(1).max(4096)
21947
- }).readonly();
21948
- var decodePromptAttachmentsValue = (value) => decodeZodValue(value, external_exports.array(promptAttachmentSchema).max(16).readonly());
21949
- function readPromptDisposition(value) {
21950
- const field = value["disposition"];
21951
- if (field === void 0 || field === SessionPromptDisposition.Reject) {
21952
- return SessionPromptDisposition.Reject;
21953
- }
21954
- if (field === SessionPromptDisposition.Queue) {
21955
- return SessionPromptDisposition.Queue;
21956
- }
21957
- if (field === SessionPromptDisposition.Steer) {
21958
- return SessionPromptDisposition.Steer;
21959
- }
21960
- throw new ProtocolMessageError("Invalid value field: disposition");
21961
- }
21962
- function decodeSessionPromptCommand(encoded) {
21963
- const value = parseJson(encoded);
21964
- const hasSessionConfigurations = Object.hasOwn(value, "sessionConfigurations");
21965
- assertKind(value, SESSION_PROMPT_KIND);
21966
- const prompt = readText(value, "prompt", MAX_PROMPT_LENGTH);
21967
- const attachments = !Object.hasOwn(value, "attachments") && Array.isArray(value["images"]) && Array.isArray(value["resources"]) ? [] : decodePromptAttachmentsValue(value["attachments"]);
21968
- const attachmentBytes = attachments.reduce((total, attachment) => total + attachment.byteLength, 0);
21969
- if (attachmentBytes > MAX_PROMPT_ATTACHMENT_BYTES) {
21970
- throw new ProtocolMessageError("Prompt attachments are too large");
21971
- }
21972
- if (prompt.trim().length === 0 && attachments.length === 0) {
21973
- throw new ProtocolMessageError("Prompt must contain content");
21974
- }
21975
- const disposition = readPromptDisposition(value);
21976
- const rawTargetCommandId = value["targetCommandId"];
21977
- const targetCommandId = rawTargetCommandId === void 0 ? "" : readText(value, "targetCommandId", 128);
21978
- if (disposition === SessionPromptDisposition.Reject && targetCommandId.length > 0 || disposition !== SessionPromptDisposition.Reject && !isIdentifier(targetCommandId)) {
21979
- throw new ProtocolMessageError("Prompt disposition has an invalid target command");
21980
- }
21981
- const sessionConfigurations = hasSessionConfigurations ? decodeSessionConfigurationSelections(value["sessionConfigurations"]) : [];
21982
- if (new Set(sessionConfigurations.map((selection) => selection.configId)).size !== sessionConfigurations.length) {
21983
- throw new ProtocolMessageError("Session configuration identifiers must be unique");
21984
- }
21985
- return {
21986
- additionalDirectoryIds: readDirectoryIdentifiers(value, "additionalDirectoryIds", 16),
21987
- agentId: readIdentifier(value, "agentId"),
21988
- bindingId: readIdentifier(value, "bindingId"),
21989
- commandId: readIdentifier(value, "commandId"),
21990
- directoryId: readDirectoryIdentifier(value, "directoryId"),
21991
- disposition,
21992
- attachments,
21993
- ...value["historyPolicy"] === void 0 ? {} : {
21994
- historyPolicy: readHistoryPolicy(value)
21995
- },
21996
- kind: SESSION_PROMPT_KIND,
21997
- prompt,
21998
- ...hasSessionConfigurations ? { sessionConfigurations } : {},
21999
- sessionId: readIdentifier(value, "sessionId"),
22000
- targetCommandId
22001
- };
22002
- }
22003
- function readHistoryPolicy(value) {
22004
- const field = value["historyPolicy"];
22005
- if (field === SessionHistoryPolicy.Eager || field === SessionHistoryPolicy.ExecutionOnly) {
22006
- return field;
22007
- }
22008
- throw new ProtocolMessageError("Invalid value field: historyPolicy");
22009
- }
22010
- function decodeSessionCancelCommand(encoded) {
22011
- const value = parseJson(encoded);
22012
- assertKind(value, SESSION_CANCEL_KIND);
22013
- return {
22014
- commandId: readIdentifier(value, "commandId"),
22015
- kind: SESSION_CANCEL_KIND,
22016
- sessionId: readIdentifier(value, "sessionId")
22017
- };
22018
- }
22019
- function decodeSessionPromptDispositionCommand(encoded) {
22020
- const value = parseJson(encoded);
22021
- assertKind(value, SESSION_PROMPT_DISPOSITION_KIND);
22022
- if (readPromptDisposition(value) !== SessionPromptDisposition.Steer) {
22023
- throw new ProtocolMessageError("Only queued prompts can be steered");
22024
- }
22025
- return {
22026
- commandId: readIdentifier(value, "commandId"),
22027
- disposition: SessionPromptDisposition.Steer,
22028
- kind: SESSION_PROMPT_DISPOSITION_KIND,
22029
- sessionId: readIdentifier(value, "sessionId")
22030
- };
22031
- }
22032
- function encodeSessionPromptCommand(message) {
22033
- const command = decodeSessionPromptCommand(JSON.stringify(message));
22034
- return JSON.stringify({
22035
- ...command,
22036
- // Keep text prompts compatible with the previous Runtime release while
22037
- // attachments move to the content-key protocol. Older Runtimes ignore
22038
- // `attachments` and require both legacy arrays to be present.
22039
- images: [],
22040
- resources: []
22041
- });
22042
- }
22043
- function encodeSessionCancelCommand(message) {
22044
- return JSON.stringify(decodeSessionCancelCommand(JSON.stringify(message)));
22045
- }
22046
- function encodeSessionPromptDispositionCommand(message) {
22047
- return JSON.stringify(decodeSessionPromptDispositionCommand(JSON.stringify(message)));
22048
- }
22049
-
22050
- // ../mobius-sdk/src/protocol/session/native/index.ts
22051
- var NATIVE_SESSION_REQUEST_KIND = "native.session.request";
22052
- var NATIVE_SESSION_RESULT_KIND = "native.session.result";
22053
- var NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
22054
- var envelope = {
22055
- requestId: identifierStringSchema,
22056
- sessionId: identifierStringSchema
22057
- };
22058
- var activeTurnSnapshotSchema = external_exports.object({
22059
- commandId: identifierStringSchema,
22060
- epoch: identifierStringSchema,
22061
- interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
22062
- sequence: external_exports.number().int().nonnegative(),
22063
- state: external_exports.literal("running")
22064
- }).readonly();
22065
- var identity = {
22066
- ...envelope,
22067
- kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
22068
- additionalDirectoryIds: external_exports.array(DIRECTORY_IDENTIFIER).max(16).readonly(),
22069
- agentId: identifierStringSchema,
22070
- bindingId: identifierStringSchema,
22071
- directoryId: DIRECTORY_IDENTIFIER
22072
- };
22073
- var nativeSessionRequestSchema = external_exports.discriminatedUnion("action", [
22074
- external_exports.object({ ...identity, action: external_exports.literal("active-turn"), targetSessionId: identifierStringSchema }).readonly(),
22075
- external_exports.object({ ...identity, action: external_exports.literal("find"), nativeSessionId: identifierStringSchema }).readonly(),
22076
- external_exports.object({
22077
- ...identity,
22078
- action: external_exports.literal("list"),
22079
- cursor: identifierStringSchema.nullable()
22080
- }).readonly(),
22081
- external_exports.object({
22082
- ...identity,
22083
- action: external_exports.enum(["import", "fork"]),
22084
- entryId: identifierStringSchema,
22085
- targetSessionId: identifierStringSchema
22086
- }).readonly()
22087
- ]);
22088
- var nativeSessionCommandSchema = external_exports.discriminatedUnion("action", [
22089
- external_exports.object({ ...identity, action: external_exports.literal("active-turn"), targetSessionId: identifierStringSchema }).readonly(),
22090
- external_exports.object({ ...identity, action: external_exports.literal("find"), nativeSessionId: identifierStringSchema }).readonly(),
22091
- external_exports.object({
22092
- ...identity,
22093
- action: external_exports.literal("list"),
22094
- cursor: identifierStringSchema.nullable()
22095
- }).readonly(),
22096
- external_exports.object({
22097
- ...identity,
22098
- action: external_exports.enum(["import", "fork"]),
22099
- entryId: identifierStringSchema,
22100
- targetSessionId: identifierStringSchema
22101
- }).readonly()
22102
- ]);
22103
- var nativeSessionEntrySchema = external_exports.object({
22104
- entryId: identifierStringSchema,
22105
- mobiusSessionIds: external_exports.array(identifierStringSchema).max(500).readonly(),
22106
- nativeSessionId: identifierStringSchema,
22107
- title: external_exports.string().max(500),
22108
- directoryId: DIRECTORY_IDENTIFIER,
22109
- directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
22110
- updatedAt: external_exports.iso.datetime({ offset: true }).nullable(),
22111
- additionalDirectories: external_exports.array(external_exports.object({ directoryId: DIRECTORY_IDENTIFIER, name: external_exports.string().min(1).max(255) }).readonly()).max(16).readonly()
22112
- }).readonly();
22113
- var resultEnvelope = {
22114
- ...envelope,
22115
- kind: external_exports.literal(NATIVE_SESSION_RESULT_KIND)
22116
- };
22117
- var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
22118
- external_exports.object({
22119
- ...resultEnvelope,
22120
- action: external_exports.literal("active-turn"),
22121
- targetSessionId: identifierStringSchema,
22122
- queued: external_exports.array(
22123
- external_exports.object({
22124
- commandId: identifierStringSchema,
22125
- prompt: external_exports.string().max(1e5),
22126
- attachments: external_exports.array(promptAttachmentSchema).max(16).readonly()
22127
- }).readonly()
22128
- ).readonly(),
22129
- turn: activeTurnSnapshotSchema.nullable()
22130
- }).readonly(),
22131
- external_exports.object({
22132
- ...resultEnvelope,
22133
- action: external_exports.literal("find"),
22134
- entry: nativeSessionEntrySchema
22135
- }).readonly(),
22136
- external_exports.object({
22137
- ...resultEnvelope,
22138
- action: external_exports.literal("list"),
22139
- capabilities: sessionCapabilitiesSchema,
22140
- entries: external_exports.array(nativeSessionEntrySchema).max(500).readonly(),
22141
- nextCursor: identifierStringSchema.nullable()
22142
- }).readonly(),
22143
- external_exports.object({
22144
- ...resultEnvelope,
22145
- action: external_exports.enum(["import", "fork"]),
22146
- targetSessionId: identifierStringSchema,
22147
- ready: sessionReadyEventSchema,
22148
- title: external_exports.string().max(500)
22149
- }).readonly()
22150
- ]);
22151
- var nativeSessionCancelSchema = external_exports.object({ ...envelope, kind: external_exports.literal(NATIVE_SESSION_CANCEL_KIND) }).readonly();
22152
- function decode3(schema, encoded) {
22153
- try {
22154
- const value = JSON.parse(encoded);
22155
- return schema.parse(value);
22156
- } catch (cause) {
22157
- throw new ProtocolMessageError("Invalid native session message", { cause });
22158
- }
22159
- }
22160
- var decodeNativeSessionCommand = (encoded) => decode3(nativeSessionCommandSchema, encoded);
22161
- var encodeNativeSessionCommand = (value) => JSON.stringify(nativeSessionCommandSchema.parse(value));
22162
- var decodeNativeSessionResult = (encoded) => decode3(nativeSessionResultSchema, encoded);
22163
- var encodeNativeSessionResult = (value) => JSON.stringify(nativeSessionResultSchema.parse(value));
22164
- var decodeNativeSessionCancel = (encoded) => decode3(nativeSessionCancelSchema, encoded);
22165
- var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSchema.parse(value));
22166
-
22167
- // ../mobius-sdk/src/protocol/session/observability/event-log.ts
21411
+ // ../mobius-sdk/src/protocol/session/events/index.ts
22168
21412
  var MAX_EVENT_COUNT = 1e4;
22169
21413
  var MAX_COLLECTION_SIZE2 = 1e3;
22170
21414
  var MAX_CONTENT_LENGTH2 = 1e6;
@@ -22595,137 +21839,702 @@ function isKnownSessionEventVariant(value) {
22595
21839
  if (!isRecord3(value)) {
22596
21840
  return true;
22597
21841
  }
22598
- const type = value["type"];
22599
- if (typeof type !== "string") {
22600
- return true;
21842
+ const type = value["type"];
21843
+ if (typeof type !== "string") {
21844
+ return true;
21845
+ }
21846
+ if (type === "acp") {
21847
+ const payload = value["payload"];
21848
+ return !isRecord3(payload) || !containsUnknownAcpVariant(payload);
21849
+ }
21850
+ if (type === "lifecycle-metadata") {
21851
+ const payload = value["payload"];
21852
+ if (!isRecord3(payload)) {
21853
+ return true;
21854
+ }
21855
+ const kind = payload["kind"];
21856
+ if (typeof kind === "string" && !knownLifecycleKinds.has(kind)) {
21857
+ return false;
21858
+ }
21859
+ return kind !== "prompt.requested" || !arrayContainsUnknown(payload["content"], containsUnknownContentBlock);
21860
+ }
21861
+ return false;
21862
+ }
21863
+ function filterKnownSessionEventVariants(events) {
21864
+ return Array.isArray(events) ? events.filter(isKnownSessionEventVariant) : events;
21865
+ }
21866
+ var sessionEventBatchSchema = external_exports.array(sessionEventSchema).min(1).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
21867
+ var sessionLiveEventBatchSchema = external_exports.array(sessionLiveEventSchema).min(1).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
21868
+ var sessionExportSchema = external_exports.object({
21869
+ binding: external_exports.object({
21870
+ bindingId: identifierStringSchema,
21871
+ runtimeId: identifierStringSchema
21872
+ }).readonly(),
21873
+ events: external_exports.array(sessionEventSchema).max(MAX_EVENT_COUNT).readonly(),
21874
+ sessionId: identifierStringSchema,
21875
+ truncated: external_exports.boolean()
21876
+ }).readonly().superRefine((session, context) => {
21877
+ const eventIds = /* @__PURE__ */ new Set();
21878
+ for (const [index2, event] of session.events.entries()) {
21879
+ if (event.sessionId !== session.sessionId) {
21880
+ context.addIssue({
21881
+ code: "custom",
21882
+ message: "Exported event belongs to a different Session",
21883
+ path: ["events", index2, "sessionId"]
21884
+ });
21885
+ }
21886
+ if (eventIds.has(event.eventId)) {
21887
+ context.addIssue({
21888
+ code: "custom",
21889
+ message: "Exported event identities are not unique",
21890
+ path: ["events", index2, "eventId"]
21891
+ });
21892
+ }
21893
+ eventIds.add(event.eventId);
21894
+ }
21895
+ });
21896
+ var mobiusSessionExportSchema = external_exports.object({
21897
+ formatVersion: external_exports.literal("2"),
21898
+ session: sessionExportSchema
21899
+ }).readonly();
21900
+ var sessionEventEnvelopeSchema = external_exports.object({ events: sessionLiveEventBatchSchema, kind: external_exports.literal(SESSION_EVENT_KIND) }).readonly();
21901
+ var sessionEventLogPageSchema = external_exports.object({
21902
+ events: external_exports.array(sessionEventSchema).max(MAX_EVENT_COUNT).readonly(),
21903
+ nextCursor: external_exports.string().min(1).max(512).nullable(),
21904
+ sessionGenerationId: identifierStringSchema,
21905
+ tailCursor: external_exports.string().max(512),
21906
+ // The generation-scoped live position covered by this snapshot, including
21907
+ // coalesced and omitted events. Absent only on older Runtime versions.
21908
+ throughPosition: positionSchema.optional(),
21909
+ truncated: external_exports.boolean(),
21910
+ version: external_exports.literal(2)
21911
+ }).readonly();
21912
+ var sessionEventOmissionSchema = external_exports.literal("agent-reasoning");
21913
+ var nativeEventPageRequestSchema = external_exports.object({
21914
+ cursor: external_exports.string().min(1).max(512).nullable(),
21915
+ eventLimit: external_exports.number().int().min(1).max(1e4),
21916
+ // Legacy callers may still send this option; readers must ignore it.
21917
+ omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional()
21918
+ }).readonly();
21919
+ var queuedPromptRequestEventLogSchema = external_exports.object({
21920
+ commandId: identifierStringSchema,
21921
+ content: external_exports.array(contentBlockSchema).min(1).max(100).readonly(),
21922
+ disposition: shortString.optional(),
21923
+ targetCommandId: identifierStringSchema.optional()
21924
+ }).readonly();
21925
+ var nativeSessionEventsSchema = external_exports.object({
21926
+ events: sessionEventLogPageSchema,
21927
+ queuedPromptRequests: external_exports.array(queuedPromptRequestEventLogSchema).max(MAX_COLLECTION_SIZE2).readonly()
21928
+ }).readonly();
21929
+ function inputValue(value) {
21930
+ if (typeof value !== "string") {
21931
+ return value;
21932
+ }
21933
+ try {
21934
+ return JSON.parse(value);
21935
+ } catch (cause) {
21936
+ throw new ProtocolMessageError("Session Event Log V2 message is not valid JSON", { cause });
21937
+ }
21938
+ }
21939
+ function decode3(value, schema) {
21940
+ const result = schema.safeParse(inputValue(value));
21941
+ if (!result.success) {
21942
+ throw new ProtocolMessageError("Session Event Log V2 message does not match its schema", {
21943
+ cause: result.error
21944
+ });
21945
+ }
21946
+ return result.data;
21947
+ }
21948
+ function encode3(value, schema) {
21949
+ return JSON.stringify(decode3(value, schema));
21950
+ }
21951
+ function sanitizeKnownNativeSessionEvents(value) {
21952
+ const input2 = inputValue(value);
21953
+ if (!isRecord3(input2)) {
21954
+ return input2;
21955
+ }
21956
+ const page = input2["events"];
21957
+ const queuedPromptRequests = input2["queuedPromptRequests"];
21958
+ return {
21959
+ ...input2,
21960
+ events: isRecord3(page) ? { ...page, events: filterKnownSessionEventVariants(page["events"]) } : page,
21961
+ queuedPromptRequests: Array.isArray(queuedPromptRequests) ? queuedPromptRequests.filter(
21962
+ (prompt) => !isRecord3(prompt) || !arrayContainsUnknown(prompt["content"], containsUnknownContentBlock)
21963
+ ) : queuedPromptRequests
21964
+ };
21965
+ }
21966
+ var knownSessionLiveEventBatchSchema = external_exports.array(sessionLiveEventSchema).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
21967
+ var decodeSessionEvent = (value) => decode3(value, sessionEventSchema);
21968
+ var decodeKnownSessionEventPayload = (value) => isKnownSessionEventVariant(value) ? decode3(value, sessionEventPayloadSchema) : null;
21969
+ var decodeSessionEventEnvelope = (value) => decode3(value, sessionEventEnvelopeSchema);
21970
+ var encodeSessionEventEnvelope = (value) => encode3(value, sessionEventEnvelopeSchema);
21971
+ var decodeAcpSessionUpdate = (value) => decode3(value, acpSessionUpdateSchema);
21972
+ var decodeKnownNativeSessionEvents = (value) => decode3(sanitizeKnownNativeSessionEvents(value), nativeSessionEventsSchema);
21973
+
21974
+ // ../mobius-sdk/src/protocol/session/files/index.ts
21975
+ var FILE_READ_KIND = "file.read";
21976
+ var FILE_BEGIN_KIND = "file.begin";
21977
+ var FILE_END_KIND = "file.end";
21978
+ var FILE_FAILED_KIND = "file.failed";
21979
+ var CONTENT_WRITE_KIND = "content.write";
21980
+ var CONTENT_COMMIT_KIND = "content.commit";
21981
+ var CONTENT_READY_KIND = "content.ready";
21982
+ var CONTENT_AVAILABLE_KIND = "content.available";
21983
+ var CONTENT_CHUNK_MAX_BYTES = 192 * 1024;
21984
+ var CONTENT_WRITE_MAX_BYTES = 32 * 1024 * 1024;
21985
+ var PROMPT_IMAGE_MAX_BYTES = 5e6;
21986
+ var CONTENT_CHUNK_MAGIC = new Uint8Array([77, 66, 67, 49]);
21987
+ var CONTENT_CHUNK_HEADER_BYTES = CONTENT_CHUNK_MAGIC.byteLength + 1 + 4;
21988
+ var fileReadCommandSchema = external_exports.object({
21989
+ kind: external_exports.literal(FILE_READ_KIND),
21990
+ maxBytes: external_exports.number().int().positive().max(128 * 1024 * 1024),
21991
+ requestId: identifierStringSchema,
21992
+ sessionId: identifierStringSchema,
21993
+ path: external_exports.string().min(1).max(4096)
21994
+ }).readonly();
21995
+ var fileBeginEventSchema = external_exports.object({
21996
+ byteLength: external_exports.number().int().positive().max(128 * 1024 * 1024),
21997
+ kind: external_exports.literal(FILE_BEGIN_KIND),
21998
+ mediaType: external_exports.string().min(1).max(255),
21999
+ modifiedAt: external_exports.iso.datetime({ offset: true }),
22000
+ name: external_exports.string().min(1).max(500),
22001
+ requestId: identifierStringSchema,
22002
+ sessionId: identifierStringSchema
22003
+ }).readonly();
22004
+ var contentWriteCommandSchema = external_exports.object({
22005
+ byteLength: external_exports.number().int().positive().max(CONTENT_WRITE_MAX_BYTES),
22006
+ contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
22007
+ contentKind: external_exports.enum(["image", "resource"]),
22008
+ kind: external_exports.literal(CONTENT_WRITE_KIND),
22009
+ mediaType: external_exports.string().min(1).max(255),
22010
+ name: external_exports.string().min(1).max(500),
22011
+ requestId: identifierStringSchema,
22012
+ sessionId: identifierStringSchema
22013
+ }).readonly();
22014
+ var contentCommitCommandSchema = external_exports.object({
22015
+ kind: external_exports.literal(CONTENT_COMMIT_KIND),
22016
+ requestId: identifierStringSchema,
22017
+ sessionId: identifierStringSchema
22018
+ }).readonly();
22019
+ var contentReadyEventSchema = external_exports.object({
22020
+ kind: external_exports.literal(CONTENT_READY_KIND),
22021
+ requestId: identifierStringSchema,
22022
+ sessionId: identifierStringSchema
22023
+ }).readonly();
22024
+ var contentAvailableEventSchema = external_exports.object({
22025
+ byteLength: external_exports.number().int().positive().max(CONTENT_WRITE_MAX_BYTES),
22026
+ contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
22027
+ kind: external_exports.literal(CONTENT_AVAILABLE_KIND),
22028
+ requestId: identifierStringSchema,
22029
+ sessionId: identifierStringSchema
22030
+ }).readonly();
22031
+ function binaryBytes(value) {
22032
+ if (value instanceof ArrayBuffer) {
22033
+ return new Uint8Array(value);
22034
+ }
22035
+ if (ArrayBuffer.isView(value)) {
22036
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
22037
+ }
22038
+ throw new Error("Content chunk must be a binary WebSocket frame");
22039
+ }
22040
+ function encodeContentChunkFrame(frame) {
22041
+ if (!isIdentifier(frame.requestId)) {
22042
+ throw new Error("Content chunk request identifier is invalid");
22043
+ }
22044
+ if (!Number.isSafeInteger(frame.sequence) || frame.sequence < 0 || frame.sequence > 4294967295) {
22045
+ throw new Error("Content chunk sequence is invalid");
22046
+ }
22047
+ if (frame.bytes.byteLength < 1 || frame.bytes.byteLength > CONTENT_CHUNK_MAX_BYTES) {
22048
+ throw new Error("Content chunk size is invalid");
22049
+ }
22050
+ const requestId = new TextEncoder().encode(frame.requestId);
22051
+ if (requestId.byteLength > 255) {
22052
+ throw new Error("Content chunk request identifier is too long");
22053
+ }
22054
+ const encoded = new Uint8Array(CONTENT_CHUNK_HEADER_BYTES + requestId.byteLength + frame.bytes.byteLength);
22055
+ encoded.set(CONTENT_CHUNK_MAGIC, 0);
22056
+ encoded[CONTENT_CHUNK_MAGIC.byteLength] = requestId.byteLength;
22057
+ new DataView(encoded.buffer).setUint32(CONTENT_CHUNK_MAGIC.byteLength + 1, frame.sequence);
22058
+ encoded.set(requestId, CONTENT_CHUNK_HEADER_BYTES);
22059
+ encoded.set(frame.bytes, CONTENT_CHUNK_HEADER_BYTES + requestId.byteLength);
22060
+ return encoded;
22061
+ }
22062
+ function decodeContentChunkFrame(value) {
22063
+ const encoded = binaryBytes(value);
22064
+ if (encoded.byteLength <= CONTENT_CHUNK_HEADER_BYTES || !CONTENT_CHUNK_MAGIC.every((byte, index2) => encoded[index2] === byte)) {
22065
+ throw new Error("Content chunk frame header is invalid");
22066
+ }
22067
+ const requestIdLength = encoded[CONTENT_CHUNK_MAGIC.byteLength] ?? 0;
22068
+ const payloadOffset = CONTENT_CHUNK_HEADER_BYTES + requestIdLength;
22069
+ if (requestIdLength < 1 || payloadOffset >= encoded.byteLength) {
22070
+ throw new Error("Content chunk frame length is invalid");
22071
+ }
22072
+ const requestId = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
22073
+ encoded.subarray(CONTENT_CHUNK_HEADER_BYTES, payloadOffset)
22074
+ );
22075
+ const bytes = encoded.slice(payloadOffset);
22076
+ const sequence = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength).getUint32(
22077
+ CONTENT_CHUNK_MAGIC.byteLength + 1
22078
+ );
22079
+ if (!isIdentifier(requestId) || bytes.byteLength > CONTENT_CHUNK_MAX_BYTES) {
22080
+ throw new Error("Content chunk frame is invalid");
22081
+ }
22082
+ return { bytes, requestId, sequence };
22083
+ }
22084
+ var fileEndEventSchema = external_exports.object({
22085
+ kind: external_exports.literal(FILE_END_KIND),
22086
+ requestId: identifierStringSchema,
22087
+ sessionId: identifierStringSchema
22088
+ }).readonly();
22089
+ var fileFailedEventSchema = external_exports.object({
22090
+ code: identifierStringSchema,
22091
+ kind: external_exports.literal(FILE_FAILED_KIND),
22092
+ message: external_exports.string().min(1).max(500),
22093
+ requestId: identifierStringSchema,
22094
+ sessionId: identifierStringSchema
22095
+ }).readonly();
22096
+ var decodeFileReadCommand = (encoded) => decodeZodMessage(encoded, fileReadCommandSchema);
22097
+ var encodeFileReadCommand = (message) => encodeZodMessage(message, fileReadCommandSchema);
22098
+ var decodeFileBeginEvent = (encoded) => decodeZodMessage(encoded, fileBeginEventSchema);
22099
+ var encodeFileBeginEvent = (message) => encodeZodMessage(message, fileBeginEventSchema);
22100
+ var decodeFileEndEvent = (encoded) => decodeZodMessage(encoded, fileEndEventSchema);
22101
+ var encodeFileEndEvent = (message) => encodeZodMessage(message, fileEndEventSchema);
22102
+ var decodeFileFailedEvent = (encoded) => decodeZodMessage(encoded, fileFailedEventSchema);
22103
+ var encodeFileFailedEvent = (message) => encodeZodMessage(message, fileFailedEventSchema);
22104
+ var decodeContentWriteCommand = (encoded) => decodeZodMessage(encoded, contentWriteCommandSchema);
22105
+ var encodeContentWriteCommand = (message) => encodeZodMessage(message, contentWriteCommandSchema);
22106
+ var decodeContentCommitCommand = (encoded) => decodeZodMessage(encoded, contentCommitCommandSchema);
22107
+ var encodeContentCommitCommand = (message) => encodeZodMessage(message, contentCommitCommandSchema);
22108
+ var decodeContentReadyEvent = (encoded) => decodeZodMessage(encoded, contentReadyEventSchema);
22109
+ var encodeContentReadyEvent = (message) => encodeZodMessage(message, contentReadyEventSchema);
22110
+ var decodeContentAvailableEvent = (encoded) => decodeZodMessage(encoded, contentAvailableEventSchema);
22111
+ var encodeContentAvailableEvent = (message) => encodeZodMessage(message, contentAvailableEventSchema);
22112
+
22113
+ // ../mobius-sdk/src/protocol/session/lifecycle/index.ts
22114
+ var SESSION_PREPARE_KIND = "session.prepare";
22115
+ var SESSION_READY_KIND = "session.ready";
22116
+ var SESSION_LIST_KIND = "session.list";
22117
+ var SESSION_LISTED_KIND = "session.listed";
22118
+ var SESSION_QUERY_KIND = "session.query";
22119
+ var SESSION_QUERIED_KIND = "session.queried";
22120
+ var SESSION_RESTORE_KIND = "session.restore";
22121
+ var SESSION_RESTORED_KIND = "session.restored";
22122
+ var SESSION_CLOSE_KIND = "session.close";
22123
+ var SESSION_CLOSED_KIND = "session.closed";
22124
+ var SESSION_CLOSE_NOTICE_KIND = "session.close.notice";
22125
+ var SESSION_CLOSED_ERROR_CODE = "session_closed";
22126
+ var SESSION_STATUS_CHANGED_KIND = "session.status.changed";
22127
+ var SESSION_COMMANDS_UPDATED_KIND = "session.commands.updated";
22128
+ var SESSION_INFO_UPDATED_KIND = "session.info.updated";
22129
+ var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
22130
+ var sessionStatusChangedEventSchema = external_exports.object({
22131
+ kind: external_exports.literal(SESSION_STATUS_CHANGED_KIND),
22132
+ sessionId: identifierStringSchema,
22133
+ status: sessionStatusSchema
22134
+ }).readonly();
22135
+ var sessionMetadataSchema = external_exports.object({
22136
+ additionalDirectories: external_exports.array(workspaceEntrySchema).max(16).readonly(),
22137
+ agentId: identifierStringSchema,
22138
+ directoryId: DIRECTORY_IDENTIFIER,
22139
+ directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
22140
+ prompted: external_exports.boolean(),
22141
+ sessionId: identifierStringSchema,
22142
+ status: sessionStatusSchema.default({ kind: "idle" }),
22143
+ title: external_exports.string().max(500),
22144
+ updatedAt: external_exports.iso.datetime({ offset: true })
22145
+ }).readonly();
22146
+ var sessionListCommandSchema = external_exports.object({
22147
+ kind: external_exports.literal(SESSION_LIST_KIND),
22148
+ limit: external_exports.number().int().positive().max(500),
22149
+ requestId: identifierStringSchema
22150
+ }).readonly();
22151
+ var sessionsListedEventSchema = external_exports.object({
22152
+ entries: external_exports.array(sessionMetadataSchema).max(500).readonly(),
22153
+ kind: external_exports.literal(SESSION_LISTED_KIND),
22154
+ requestId: identifierStringSchema
22155
+ }).readonly();
22156
+ var sessionQueryCommandSchema = external_exports.object({
22157
+ kind: external_exports.literal(SESSION_QUERY_KIND),
22158
+ requestId: identifierStringSchema,
22159
+ sessionIds: external_exports.array(identifierStringSchema).min(1).max(500).readonly()
22160
+ }).readonly();
22161
+ var sessionsQueriedEventSchema = external_exports.object({
22162
+ entries: external_exports.array(sessionMetadataSchema).max(500).readonly(),
22163
+ kind: external_exports.literal(SESSION_QUERIED_KIND),
22164
+ requestId: identifierStringSchema
22165
+ }).readonly();
22166
+ var sessionRestoreCommandSchema = external_exports.object({
22167
+ kind: external_exports.literal(SESSION_RESTORE_KIND),
22168
+ requestId: identifierStringSchema,
22169
+ sessionId: identifierStringSchema
22170
+ }).readonly();
22171
+ var sessionCloseCommandSchema = external_exports.object({
22172
+ kind: external_exports.literal(SESSION_CLOSE_KIND),
22173
+ requestId: identifierStringSchema,
22174
+ sessionId: identifierStringSchema
22175
+ }).readonly();
22176
+ var sessionPrepareCommandSchema = external_exports.object({
22177
+ ...sessionIdentityFields,
22178
+ configuration: external_exports.object({
22179
+ booleanValue: external_exports.boolean(),
22180
+ configId: external_exports.string().min(1).max(128),
22181
+ value: external_exports.string().max(500),
22182
+ valueType: external_exports.enum(["boolean", "select"])
22183
+ }).readonly().optional(),
22184
+ kind: external_exports.literal(SESSION_PREPARE_KIND),
22185
+ requestId: identifierStringSchema,
22186
+ sessionState: external_exports.literal("provisioned").optional(),
22187
+ /** Marks an inspection-only Session preparation. */
22188
+ transient: external_exports.boolean().optional()
22189
+ }).superRefine((command, context) => {
22190
+ if (command.transient === true && command.sessionState === "provisioned") {
22191
+ context.addIssue({
22192
+ code: "custom",
22193
+ message: "A transient Session cannot already be provisioned",
22194
+ path: ["sessionState"]
22195
+ });
22196
+ }
22197
+ }).readonly();
22198
+ var runtimeTimingsSchema = external_exports.array(
22199
+ external_exports.object({
22200
+ durationMilliseconds: external_exports.number().finite().nonnegative().max(12e4),
22201
+ name: external_exports.string().regex(/^[a-z][a-z0-9-]{0,63}$/)
22202
+ }).readonly()
22203
+ ).max(16).readonly();
22204
+ var sessionReadyEventSchema = external_exports.object({
22205
+ additionalDirectories: external_exports.array(workspaceEntrySchema).max(16).readonly(),
22206
+ agentId: identifierStringSchema,
22207
+ agentName: external_exports.string().max(255),
22208
+ agentVersion: external_exports.string().max(128),
22209
+ capabilities: sessionCapabilitiesSchema,
22210
+ commands: external_exports.array(sessionCommandSchema).max(500).readonly(),
22211
+ configOptions: sessionConfigOptionsSchema,
22212
+ configurationRevision: identifierStringSchema.optional(),
22213
+ directoryId: DIRECTORY_IDENTIFIER,
22214
+ directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
22215
+ kind: external_exports.literal(SESSION_READY_KIND),
22216
+ requestId: identifierStringSchema,
22217
+ restored: external_exports.boolean(),
22218
+ runtimeTimings: runtimeTimingsSchema.optional(),
22219
+ sessionId: identifierStringSchema
22220
+ }).readonly();
22221
+ var sessionRestoredEventSchema = external_exports.object({
22222
+ entry: sessionMetadataSchema,
22223
+ kind: external_exports.literal(SESSION_RESTORED_KIND),
22224
+ ready: sessionReadyEventSchema,
22225
+ requestId: identifierStringSchema
22226
+ }).readonly();
22227
+ var sessionClosedEventSchema = external_exports.object({
22228
+ kind: external_exports.literal(SESSION_CLOSED_KIND),
22229
+ requestId: identifierStringSchema,
22230
+ sessionId: identifierStringSchema
22231
+ }).readonly();
22232
+ var sessionCloseNoticeEventSchema = external_exports.object({
22233
+ kind: external_exports.literal(SESSION_CLOSE_NOTICE_KIND),
22234
+ reason: external_exports.string().min(1).max(500),
22235
+ sessionId: identifierStringSchema
22236
+ }).readonly();
22237
+ var sessionCommandsUpdatedEventSchema = external_exports.object({
22238
+ commands: external_exports.array(sessionCommandSchema).max(500).readonly(),
22239
+ kind: external_exports.literal(SESSION_COMMANDS_UPDATED_KIND),
22240
+ sessionId: identifierStringSchema
22241
+ }).readonly();
22242
+ var sessionInfoUpdatedEventSchema = external_exports.object({
22243
+ kind: external_exports.literal(SESSION_INFO_UPDATED_KIND),
22244
+ projectId: identifierStringSchema.optional(),
22245
+ sessionId: identifierStringSchema,
22246
+ title: external_exports.string().max(500).nullable(),
22247
+ updatedAt: external_exports.string().max(128)
22248
+ }).readonly();
22249
+ var sessionOperationFailedEventSchema = external_exports.object({
22250
+ code: identifierStringSchema,
22251
+ kind: external_exports.literal(SESSION_OPERATION_FAILED_KIND),
22252
+ message: external_exports.string().min(1).max(500),
22253
+ requestId: identifierStringSchema,
22254
+ runtimeTimings: runtimeTimingsSchema.optional(),
22255
+ sessionId: external_exports.string().max(128)
22256
+ }).readonly();
22257
+ var decodeSessionListCommand = (encoded) => decodeZodMessage(encoded, sessionListCommandSchema);
22258
+ var encodeSessionListCommand = (message) => encodeZodMessage(message, sessionListCommandSchema);
22259
+ var decodeSessionsListedEvent = (encoded) => decodeZodMessage(encoded, sessionsListedEventSchema);
22260
+ var encodeSessionsListedEvent = (message) => encodeZodMessage(message, sessionsListedEventSchema);
22261
+ var decodeSessionQueryCommand = (encoded) => decodeZodMessage(encoded, sessionQueryCommandSchema);
22262
+ var encodeSessionQueryCommand = (message) => encodeZodMessage(message, sessionQueryCommandSchema);
22263
+ var decodeSessionsQueriedEvent = (encoded) => decodeZodMessage(encoded, sessionsQueriedEventSchema);
22264
+ var encodeSessionsQueriedEvent = (message) => encodeZodMessage(message, sessionsQueriedEventSchema);
22265
+ var decodeSessionRestoreCommand = (encoded) => decodeZodMessage(encoded, sessionRestoreCommandSchema);
22266
+ var encodeSessionRestoreCommand = (message) => encodeZodMessage(message, sessionRestoreCommandSchema);
22267
+ var decodeSessionRestoredEvent = (encoded) => decodeZodMessage(encoded, sessionRestoredEventSchema);
22268
+ var encodeSessionRestoredEvent = (message) => encodeZodMessage(message, sessionRestoredEventSchema);
22269
+ var decodeSessionCloseCommand = (encoded) => decodeZodMessage(encoded, sessionCloseCommandSchema);
22270
+ var encodeSessionCloseCommand = (message) => encodeZodMessage(message, sessionCloseCommandSchema);
22271
+ var decodeSessionClosedEvent = (encoded) => decodeZodMessage(encoded, sessionClosedEventSchema);
22272
+ var encodeSessionClosedEvent = (message) => encodeZodMessage(message, sessionClosedEventSchema);
22273
+ var decodeSessionCloseNoticeEvent = (encoded) => decodeZodMessage(encoded, sessionCloseNoticeEventSchema);
22274
+ var encodeSessionCloseNoticeEvent = (message) => encodeZodMessage(message, sessionCloseNoticeEventSchema);
22275
+ var decodeSessionStatusChangedEvent = (encoded) => decodeZodMessage(encoded, sessionStatusChangedEventSchema);
22276
+ var encodeSessionStatusChangedEvent = (message) => encodeZodMessage(message, sessionStatusChangedEventSchema);
22277
+ var decodeSessionPrepareCommand = (encoded) => decodeZodMessage(encoded, sessionPrepareCommandSchema);
22278
+ var encodeSessionPrepareCommand = (message) => encodeZodMessage(message, sessionPrepareCommandSchema);
22279
+ var decodeSessionReadyEvent = (encoded) => decodeZodMessage(encoded, sessionReadyEventSchema);
22280
+ var encodeSessionReadyEvent = (message) => encodeZodMessage(message, sessionReadyEventSchema);
22281
+ var decodeSessionInfoUpdatedEvent = (encoded) => decodeZodMessage(encoded, sessionInfoUpdatedEventSchema);
22282
+ var encodeSessionInfoUpdatedEvent = (message) => encodeZodMessage(message, sessionInfoUpdatedEventSchema);
22283
+ var decodeSessionOperationFailedEvent = (encoded) => decodeZodMessage(encoded, sessionOperationFailedEventSchema);
22284
+ var encodeSessionOperationFailedEvent = (message) => encodeZodMessage(message, sessionOperationFailedEventSchema);
22285
+
22286
+ // ../mobius-sdk/src/protocol/session/prompt/commands.ts
22287
+ var SESSION_PROMPT_KIND = "session.prompt";
22288
+ var SESSION_PROMPT_DISPOSITION_KIND = "session.prompt.disposition";
22289
+ var SESSION_CANCEL_KIND = "session.cancel";
22290
+ var SESSION_CANCEL_BEFORE_START_KIND = "session.cancel-before-start";
22291
+ var SessionPromptDisposition = Object.freeze({
22292
+ Queue: "queue",
22293
+ Reject: "reject",
22294
+ Steer: "steer"
22295
+ });
22296
+ var SessionHistoryPolicy = Object.freeze({
22297
+ Eager: "eager",
22298
+ ExecutionOnly: "execution-only"
22299
+ });
22300
+ var MAX_PROMPT_LENGTH = 1e5;
22301
+ var MAX_PROMPT_ATTACHMENT_BYTES = 32 * 1024 * 1024;
22302
+ function decodeSessionCancelBeforeStartCommand(encoded) {
22303
+ const value = parseJson(encoded);
22304
+ assertKind(value, SESSION_CANCEL_BEFORE_START_KIND);
22305
+ return {
22306
+ commandId: readIdentifier(value, "commandId"),
22307
+ kind: SESSION_CANCEL_BEFORE_START_KIND,
22308
+ sessionId: readIdentifier(value, "sessionId")
22309
+ };
22310
+ }
22311
+ var encodeSessionCancelBeforeStartCommand = (message) => JSON.stringify(decodeSessionCancelBeforeStartCommand(JSON.stringify(message)));
22312
+ var promptAttachmentSchema = external_exports.object({
22313
+ byteLength: external_exports.number().int().positive().max(MAX_PROMPT_ATTACHMENT_BYTES),
22314
+ contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
22315
+ kind: external_exports.enum(["image", "resource"]),
22316
+ mimeType: external_exports.string().min(1).max(255),
22317
+ name: external_exports.string().min(1).max(500),
22318
+ uri: external_exports.string().min(1).max(4096)
22319
+ }).readonly();
22320
+ var decodePromptAttachmentsValue = (value) => decodeZodValue(value, external_exports.array(promptAttachmentSchema).max(16).readonly());
22321
+ function readPromptDisposition(value) {
22322
+ const field = value["disposition"];
22323
+ if (field === void 0 || field === SessionPromptDisposition.Reject) {
22324
+ return SessionPromptDisposition.Reject;
22325
+ }
22326
+ if (field === SessionPromptDisposition.Queue) {
22327
+ return SessionPromptDisposition.Queue;
22328
+ }
22329
+ if (field === SessionPromptDisposition.Steer) {
22330
+ return SessionPromptDisposition.Steer;
22331
+ }
22332
+ throw new ProtocolMessageError("Invalid value field: disposition");
22333
+ }
22334
+ function decodeSessionPromptCommand(encoded) {
22335
+ const value = parseJson(encoded);
22336
+ const hasSessionConfigurations = Object.hasOwn(value, "sessionConfigurations");
22337
+ assertKind(value, SESSION_PROMPT_KIND);
22338
+ const prompt = readText(value, "prompt", MAX_PROMPT_LENGTH);
22339
+ const attachments = !Object.hasOwn(value, "attachments") && Array.isArray(value["images"]) && Array.isArray(value["resources"]) ? [] : decodePromptAttachmentsValue(value["attachments"]);
22340
+ const attachmentBytes = attachments.reduce((total, attachment) => total + attachment.byteLength, 0);
22341
+ if (attachmentBytes > MAX_PROMPT_ATTACHMENT_BYTES) {
22342
+ throw new ProtocolMessageError("Prompt attachments are too large");
22343
+ }
22344
+ if (prompt.trim().length === 0 && attachments.length === 0) {
22345
+ throw new ProtocolMessageError("Prompt must contain content");
22601
22346
  }
22602
- if (type === "acp") {
22603
- const payload = value["payload"];
22604
- return !isRecord3(payload) || !containsUnknownAcpVariant(payload);
22347
+ const disposition = readPromptDisposition(value);
22348
+ const rawTargetCommandId = value["targetCommandId"];
22349
+ const targetCommandId = rawTargetCommandId === void 0 ? "" : readText(value, "targetCommandId", 128);
22350
+ if (disposition === SessionPromptDisposition.Reject && targetCommandId.length > 0 || disposition !== SessionPromptDisposition.Reject && !isIdentifier(targetCommandId)) {
22351
+ throw new ProtocolMessageError("Prompt disposition has an invalid target command");
22605
22352
  }
22606
- if (type === "lifecycle-metadata") {
22607
- const payload = value["payload"];
22608
- if (!isRecord3(payload)) {
22609
- return true;
22610
- }
22611
- const kind = payload["kind"];
22612
- if (typeof kind === "string" && !knownLifecycleKinds.has(kind)) {
22613
- return false;
22614
- }
22615
- return kind !== "prompt.requested" || !arrayContainsUnknown(payload["content"], containsUnknownContentBlock);
22353
+ const sessionConfigurations = hasSessionConfigurations ? decodeSessionConfigurationSelections(value["sessionConfigurations"]) : [];
22354
+ if (new Set(sessionConfigurations.map((selection) => selection.configId)).size !== sessionConfigurations.length) {
22355
+ throw new ProtocolMessageError("Session configuration identifiers must be unique");
22616
22356
  }
22617
- return false;
22357
+ return {
22358
+ additionalDirectoryIds: readDirectoryIdentifiers(value, "additionalDirectoryIds", 16),
22359
+ agentId: readIdentifier(value, "agentId"),
22360
+ bindingId: readIdentifier(value, "bindingId"),
22361
+ commandId: readIdentifier(value, "commandId"),
22362
+ directoryId: readDirectoryIdentifier(value, "directoryId"),
22363
+ disposition,
22364
+ attachments,
22365
+ ...value["historyPolicy"] === void 0 ? {} : {
22366
+ historyPolicy: readHistoryPolicy(value)
22367
+ },
22368
+ kind: SESSION_PROMPT_KIND,
22369
+ prompt,
22370
+ ...hasSessionConfigurations ? { sessionConfigurations } : {},
22371
+ sessionId: readIdentifier(value, "sessionId"),
22372
+ targetCommandId
22373
+ };
22618
22374
  }
22619
- function filterKnownSessionEventVariants(events) {
22620
- return Array.isArray(events) ? events.filter(isKnownSessionEventVariant) : events;
22375
+ function readHistoryPolicy(value) {
22376
+ const field = value["historyPolicy"];
22377
+ if (field === SessionHistoryPolicy.Eager || field === SessionHistoryPolicy.ExecutionOnly) {
22378
+ return field;
22379
+ }
22380
+ throw new ProtocolMessageError("Invalid value field: historyPolicy");
22621
22381
  }
22622
- var sessionEventBatchSchema = external_exports.array(sessionEventSchema).min(1).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
22623
- var sessionLiveEventBatchSchema = external_exports.array(sessionLiveEventSchema).min(1).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
22624
- var sessionExportSchema = external_exports.object({
22625
- binding: external_exports.object({
22626
- bindingId: identifierStringSchema,
22627
- runtimeId: identifierStringSchema
22628
- }).readonly(),
22629
- events: external_exports.array(sessionEventSchema).max(MAX_EVENT_COUNT).readonly(),
22630
- sessionId: identifierStringSchema,
22631
- truncated: external_exports.boolean()
22632
- }).readonly().superRefine((session, context) => {
22633
- const eventIds = /* @__PURE__ */ new Set();
22634
- for (const [index2, event] of session.events.entries()) {
22635
- if (event.sessionId !== session.sessionId) {
22636
- context.addIssue({
22637
- code: "custom",
22638
- message: "Exported event belongs to a different Session",
22639
- path: ["events", index2, "sessionId"]
22640
- });
22641
- }
22642
- if (eventIds.has(event.eventId)) {
22643
- context.addIssue({
22644
- code: "custom",
22645
- message: "Exported event identities are not unique",
22646
- path: ["events", index2, "eventId"]
22647
- });
22648
- }
22649
- eventIds.add(event.eventId);
22382
+ function decodeSessionCancelCommand(encoded) {
22383
+ const value = parseJson(encoded);
22384
+ assertKind(value, SESSION_CANCEL_KIND);
22385
+ return {
22386
+ commandId: readIdentifier(value, "commandId"),
22387
+ kind: SESSION_CANCEL_KIND,
22388
+ sessionId: readIdentifier(value, "sessionId")
22389
+ };
22390
+ }
22391
+ function decodeSessionPromptDispositionCommand(encoded) {
22392
+ const value = parseJson(encoded);
22393
+ assertKind(value, SESSION_PROMPT_DISPOSITION_KIND);
22394
+ if (readPromptDisposition(value) !== SessionPromptDisposition.Steer) {
22395
+ throw new ProtocolMessageError("Only queued prompts can be steered");
22650
22396
  }
22651
- });
22652
- var mobiusSessionExportSchema = external_exports.object({
22653
- formatVersion: external_exports.literal("2"),
22654
- session: sessionExportSchema
22655
- }).readonly();
22656
- var sessionEventEnvelopeSchema = external_exports.object({ events: sessionLiveEventBatchSchema, kind: external_exports.literal(SESSION_EVENT_KIND) }).readonly();
22657
- var sessionEventLogPageSchema = external_exports.object({
22658
- events: external_exports.array(sessionEventSchema).max(MAX_EVENT_COUNT).readonly(),
22659
- nextCursor: external_exports.string().min(1).max(512).nullable(),
22660
- sessionGenerationId: identifierStringSchema,
22661
- tailCursor: external_exports.string().max(512),
22662
- // The generation-scoped live position covered by this snapshot, including
22663
- // coalesced and omitted events. Absent only on older Runtime versions.
22664
- throughPosition: positionSchema.optional(),
22665
- truncated: external_exports.boolean(),
22666
- version: external_exports.literal(2)
22667
- }).readonly();
22668
- var sessionEventOmissionSchema = external_exports.literal("agent-reasoning");
22669
- var nativeEventPageRequestSchema = external_exports.object({
22670
- cursor: external_exports.string().min(1).max(512).nullable(),
22671
- eventLimit: external_exports.number().int().min(1).max(1e4),
22672
- // Legacy callers may still send this option; readers must ignore it.
22673
- omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional()
22674
- }).readonly();
22675
- var queuedPromptRequestEventLogSchema = external_exports.object({
22397
+ return {
22398
+ commandId: readIdentifier(value, "commandId"),
22399
+ disposition: SessionPromptDisposition.Steer,
22400
+ kind: SESSION_PROMPT_DISPOSITION_KIND,
22401
+ sessionId: readIdentifier(value, "sessionId")
22402
+ };
22403
+ }
22404
+ function encodeSessionPromptCommand(message) {
22405
+ const command = decodeSessionPromptCommand(JSON.stringify(message));
22406
+ return JSON.stringify({
22407
+ ...command,
22408
+ // Keep text prompts compatible with the previous Runtime release while
22409
+ // attachments move to the content-key protocol. Older Runtimes ignore
22410
+ // `attachments` and require both legacy arrays to be present.
22411
+ images: [],
22412
+ resources: []
22413
+ });
22414
+ }
22415
+ function encodeSessionCancelCommand(message) {
22416
+ return JSON.stringify(decodeSessionCancelCommand(JSON.stringify(message)));
22417
+ }
22418
+ function encodeSessionPromptDispositionCommand(message) {
22419
+ return JSON.stringify(decodeSessionPromptDispositionCommand(JSON.stringify(message)));
22420
+ }
22421
+
22422
+ // ../mobius-sdk/src/protocol/session/native/index.ts
22423
+ var NATIVE_SESSION_REQUEST_KIND = "native.session.request";
22424
+ var NATIVE_SESSION_RESULT_KIND = "native.session.result";
22425
+ var NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
22426
+ var envelope = {
22427
+ requestId: identifierStringSchema,
22428
+ sessionId: identifierStringSchema
22429
+ };
22430
+ var activeTurnSnapshotSchema = external_exports.object({
22676
22431
  commandId: identifierStringSchema,
22677
- content: external_exports.array(contentBlockSchema).min(1).max(100).readonly(),
22678
- disposition: shortString.optional(),
22679
- targetCommandId: identifierStringSchema.optional()
22432
+ epoch: identifierStringSchema,
22433
+ interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
22434
+ sequence: external_exports.number().int().nonnegative(),
22435
+ state: external_exports.literal("running")
22680
22436
  }).readonly();
22681
- var nativeSessionEventsSchema = external_exports.object({
22682
- events: sessionEventLogPageSchema,
22683
- queuedPromptRequests: external_exports.array(queuedPromptRequestEventLogSchema).max(MAX_COLLECTION_SIZE2).readonly()
22437
+ var identity = {
22438
+ ...envelope,
22439
+ kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
22440
+ additionalDirectoryIds: external_exports.array(DIRECTORY_IDENTIFIER).max(16).readonly(),
22441
+ agentId: identifierStringSchema,
22442
+ bindingId: identifierStringSchema,
22443
+ directoryId: DIRECTORY_IDENTIFIER
22444
+ };
22445
+ var nativeSessionRequestSchema = external_exports.discriminatedUnion("action", [
22446
+ external_exports.object({ ...identity, action: external_exports.literal("active-turn"), targetSessionId: identifierStringSchema }).readonly(),
22447
+ external_exports.object({ ...identity, action: external_exports.literal("find"), nativeSessionId: identifierStringSchema }).readonly(),
22448
+ external_exports.object({
22449
+ ...identity,
22450
+ action: external_exports.literal("list"),
22451
+ cursor: identifierStringSchema.nullable()
22452
+ }).readonly(),
22453
+ external_exports.object({
22454
+ ...identity,
22455
+ action: external_exports.enum(["import", "fork"]),
22456
+ entryId: identifierStringSchema,
22457
+ targetSessionId: identifierStringSchema
22458
+ }).readonly()
22459
+ ]);
22460
+ var nativeSessionCommandSchema = external_exports.discriminatedUnion("action", [
22461
+ external_exports.object({ ...identity, action: external_exports.literal("active-turn"), targetSessionId: identifierStringSchema }).readonly(),
22462
+ external_exports.object({ ...identity, action: external_exports.literal("find"), nativeSessionId: identifierStringSchema }).readonly(),
22463
+ external_exports.object({
22464
+ ...identity,
22465
+ action: external_exports.literal("list"),
22466
+ cursor: identifierStringSchema.nullable()
22467
+ }).readonly(),
22468
+ external_exports.object({
22469
+ ...identity,
22470
+ action: external_exports.enum(["import", "fork"]),
22471
+ entryId: identifierStringSchema,
22472
+ targetSessionId: identifierStringSchema
22473
+ }).readonly()
22474
+ ]);
22475
+ var nativeSessionEntrySchema = external_exports.object({
22476
+ entryId: identifierStringSchema,
22477
+ mobiusSessionIds: external_exports.array(identifierStringSchema).max(500).readonly(),
22478
+ nativeSessionId: identifierStringSchema,
22479
+ title: external_exports.string().max(500),
22480
+ directoryId: DIRECTORY_IDENTIFIER,
22481
+ directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
22482
+ updatedAt: external_exports.iso.datetime({ offset: true }).nullable(),
22483
+ additionalDirectories: external_exports.array(external_exports.object({ directoryId: DIRECTORY_IDENTIFIER, name: external_exports.string().min(1).max(255) }).readonly()).max(16).readonly()
22684
22484
  }).readonly();
22685
- function inputValue(value) {
22686
- if (typeof value !== "string") {
22687
- return value;
22688
- }
22485
+ var resultEnvelope = {
22486
+ ...envelope,
22487
+ kind: external_exports.literal(NATIVE_SESSION_RESULT_KIND)
22488
+ };
22489
+ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
22490
+ external_exports.object({
22491
+ ...resultEnvelope,
22492
+ action: external_exports.literal("active-turn"),
22493
+ targetSessionId: identifierStringSchema,
22494
+ queued: external_exports.array(
22495
+ external_exports.object({
22496
+ commandId: identifierStringSchema,
22497
+ prompt: external_exports.string().max(1e5),
22498
+ attachments: external_exports.array(promptAttachmentSchema).max(16).readonly()
22499
+ }).readonly()
22500
+ ).readonly(),
22501
+ turn: activeTurnSnapshotSchema.nullable()
22502
+ }).readonly(),
22503
+ external_exports.object({
22504
+ ...resultEnvelope,
22505
+ action: external_exports.literal("find"),
22506
+ entry: nativeSessionEntrySchema
22507
+ }).readonly(),
22508
+ external_exports.object({
22509
+ ...resultEnvelope,
22510
+ action: external_exports.literal("list"),
22511
+ capabilities: sessionCapabilitiesSchema,
22512
+ entries: external_exports.array(nativeSessionEntrySchema).max(500).readonly(),
22513
+ nextCursor: identifierStringSchema.nullable()
22514
+ }).readonly(),
22515
+ external_exports.object({
22516
+ ...resultEnvelope,
22517
+ action: external_exports.enum(["import", "fork"]),
22518
+ targetSessionId: identifierStringSchema,
22519
+ ready: sessionReadyEventSchema,
22520
+ title: external_exports.string().max(500)
22521
+ }).readonly()
22522
+ ]);
22523
+ var nativeSessionCancelSchema = external_exports.object({ ...envelope, kind: external_exports.literal(NATIVE_SESSION_CANCEL_KIND) }).readonly();
22524
+ function decode4(schema, encoded) {
22689
22525
  try {
22690
- return JSON.parse(value);
22526
+ const value = JSON.parse(encoded);
22527
+ return schema.parse(value);
22691
22528
  } catch (cause) {
22692
- throw new ProtocolMessageError("Session Event Log V2 message is not valid JSON", { cause });
22693
- }
22694
- }
22695
- function decode4(value, schema) {
22696
- const result = schema.safeParse(inputValue(value));
22697
- if (!result.success) {
22698
- throw new ProtocolMessageError("Session Event Log V2 message does not match its schema", {
22699
- cause: result.error
22700
- });
22701
- }
22702
- return result.data;
22703
- }
22704
- function encode3(value, schema) {
22705
- return JSON.stringify(decode4(value, schema));
22706
- }
22707
- function sanitizeKnownNativeSessionEvents(value) {
22708
- const input2 = inputValue(value);
22709
- if (!isRecord3(input2)) {
22710
- return input2;
22529
+ throw new ProtocolMessageError("Invalid native session message", { cause });
22711
22530
  }
22712
- const page = input2["events"];
22713
- const queuedPromptRequests = input2["queuedPromptRequests"];
22714
- return {
22715
- ...input2,
22716
- events: isRecord3(page) ? { ...page, events: filterKnownSessionEventVariants(page["events"]) } : page,
22717
- queuedPromptRequests: Array.isArray(queuedPromptRequests) ? queuedPromptRequests.filter(
22718
- (prompt) => !isRecord3(prompt) || !arrayContainsUnknown(prompt["content"], containsUnknownContentBlock)
22719
- ) : queuedPromptRequests
22720
- };
22721
22531
  }
22722
- var knownSessionLiveEventBatchSchema = external_exports.array(sessionLiveEventSchema).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
22723
- var decodeSessionEvent = (value) => decode4(value, sessionEventSchema);
22724
- var decodeKnownSessionEventPayload = (value) => isKnownSessionEventVariant(value) ? decode4(value, sessionEventPayloadSchema) : null;
22725
- var decodeSessionEventEnvelope = (value) => decode4(value, sessionEventEnvelopeSchema);
22726
- var encodeSessionEventEnvelope = (value) => encode3(value, sessionEventEnvelopeSchema);
22727
- var decodeAcpSessionUpdate = (value) => decode4(value, acpSessionUpdateSchema);
22728
- var decodeKnownNativeSessionEvents = (value) => decode4(sanitizeKnownNativeSessionEvents(value), nativeSessionEventsSchema);
22532
+ var decodeNativeSessionCommand = (encoded) => decode4(nativeSessionCommandSchema, encoded);
22533
+ var encodeNativeSessionCommand = (value) => JSON.stringify(nativeSessionCommandSchema.parse(value));
22534
+ var decodeNativeSessionResult = (encoded) => decode4(nativeSessionResultSchema, encoded);
22535
+ var encodeNativeSessionResult = (value) => JSON.stringify(nativeSessionResultSchema.parse(value));
22536
+ var decodeNativeSessionCancel = (encoded) => decode4(nativeSessionCancelSchema, encoded);
22537
+ var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSchema.parse(value));
22729
22538
 
22730
22539
  // ../mobius-sdk/src/protocol/session/observability/history.ts
22731
22540
  var SESSION_HISTORY_PAGE_LOAD_KIND = "session.live-history.v2.page.load";
@@ -23773,7 +23582,7 @@ var AcpSessionConnector = class {
23773
23582
  };
23774
23583
 
23775
23584
  // src/acp/adapter/live-sessions.ts
23776
- var absolutePathSchema = external_exports.string().min(1).refine(isAbsolute4);
23585
+ var absolutePathSchema = external_exports.string().min(1).refine(isAbsolute);
23777
23586
  var targetSchema = external_exports.object({
23778
23587
  nativeSessionId: nativeSessionIdSchema,
23779
23588
  cwd: absolutePathSchema,
@@ -25103,7 +24912,7 @@ import { createHash as createHash3 } from "node:crypto";
25103
24912
  import { spawn as spawn2 } from "node:child_process";
25104
24913
 
25105
24914
  // src/acp/harness/codex/app-server-protocol.ts
25106
- import { isAbsolute as isAbsolute5 } from "node:path";
24915
+ import { isAbsolute as isAbsolute2 } from "node:path";
25107
24916
  var boundedText = (maximum) => external_exports.string().max(maximum);
25108
24917
  var jsonValue = external_exports.lazy(() => external_exports.unknown());
25109
24918
  var requestIdSchema = external_exports.union([external_exports.number(), external_exports.string()]).refine((value) => typeof value === "number" || value.length <= 256);
@@ -25175,7 +24984,7 @@ var imageGenerationItemSchema = external_exports.object({
25175
24984
  });
25176
24985
  var threadItemSchema = external_exports.discriminatedUnion("type", [
25177
24986
  imageGenerationItemSchema,
25178
- external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute5) }),
24987
+ external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute2) }),
25179
24988
  external_exports.object({
25180
24989
  id: boundedText(256),
25181
24990
  text: boundedText(1e6),
@@ -25653,7 +25462,7 @@ var CodexAppServerClient = class {
25653
25462
  import { createHash } from "node:crypto";
25654
25463
 
25655
25464
  // src/acp/content/raster.ts
25656
- import { basename, isAbsolute as isAbsolute6, normalize } from "node:path";
25465
+ import { basename, isAbsolute as isAbsolute3, normalize } from "node:path";
25657
25466
  import { fileURLToPath } from "node:url";
25658
25467
 
25659
25468
  // src/storage/files/local-files.ts
@@ -25760,13 +25569,13 @@ function sniffRasterMime(bytes) {
25760
25569
  }
25761
25570
  async function resolveCanonicalPath(requested, signal) {
25762
25571
  signal.throwIfAborted();
25763
- if (!isAbsolute6(requested) || requested.includes("\0") || normalize(requested) !== requested) {
25572
+ if (!isAbsolute3(requested) || requested.includes("\0") || normalize(requested) !== requested) {
25764
25573
  return null;
25765
25574
  }
25766
25575
  try {
25767
25576
  const target = await canonicalPath(requested);
25768
25577
  signal.throwIfAborted();
25769
- if (!isAbsolute6(target) || normalize(target) !== target) {
25578
+ if (!isAbsolute3(target) || normalize(target) !== target) {
25770
25579
  return null;
25771
25580
  }
25772
25581
  return target;
@@ -25797,7 +25606,7 @@ function parseLocalImageUri(uri) {
25797
25606
  return null;
25798
25607
  }
25799
25608
  }
25800
- if (!isAbsolute6(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
25609
+ if (!isAbsolute3(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
25801
25610
  return null;
25802
25611
  }
25803
25612
  return trimmed;
@@ -27063,12 +26872,12 @@ async function replayCodexHistory(client2, threadId, emit, signal) {
27063
26872
 
27064
26873
  // src/storage/session/temporary-session-event-cache.ts
27065
26874
  import { mkdtempSync, rmSync } from "node:fs";
27066
- import { tmpdir as tmpdir2 } from "node:os";
27067
- import { join as join8 } from "node:path";
26875
+ import { tmpdir } from "node:os";
26876
+ import { join as join5 } from "node:path";
27068
26877
 
27069
26878
  // src/storage/sqlite/local-databases.ts
27070
26879
  import { createHash as createHash2 } from "node:crypto";
27071
- import { join as join7 } from "node:path";
26880
+ import { join as join4 } from "node:path";
27072
26881
 
27073
26882
  // src/generated/acp-session-store-migrations.ts
27074
26883
  var acpSessionStoreMigrations = [
@@ -27611,7 +27420,7 @@ function sql(strings, ...params) {
27611
27420
  return new SQL([new StringChunk(str)]);
27612
27421
  }
27613
27422
  _sql.raw = raw;
27614
- function join32(chunks, separator) {
27423
+ function join34(chunks, separator) {
27615
27424
  const result = [];
27616
27425
  for (const [i, chunk] of chunks.entries()) {
27617
27426
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -27619,7 +27428,7 @@ function sql(strings, ...params) {
27619
27428
  }
27620
27429
  return new SQL(result);
27621
27430
  }
27622
- _sql.join = join32;
27431
+ _sql.join = join34;
27623
27432
  function identifier2(value) {
27624
27433
  return new Name(value);
27625
27434
  }
@@ -29340,7 +29149,7 @@ var SQLiteSelectBase = class extends TypedQueryBuilder {
29340
29149
  const baseTableName = this.tableName;
29341
29150
  const tableName = getTableLikeName(table);
29342
29151
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
29343
- if (typeof tableName === "string" && this.config.joins?.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
29152
+ if (typeof tableName === "string" && this.config.joins?.some((join34) => join34.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
29344
29153
  if (!this.isPartialSelect) {
29345
29154
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
29346
29155
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -30886,7 +30695,7 @@ var SQLiteDialect = class {
30886
30695
  if (!joins2) return;
30887
30696
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
30888
30697
  if (!withEntries.length) return;
30889
- return sql.join(withEntries.map(([k2, join32]) => {
30698
+ return sql.join(withEntries.map(([k2, join34]) => {
30890
30699
  const relation = tableConfig.relations[k2];
30891
30700
  const isSingle2 = is(relation, One);
30892
30701
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -30897,7 +30706,7 @@ var SQLiteDialect = class {
30897
30706
  table: targetTable,
30898
30707
  mode: isSingle2 ? "first" : "many",
30899
30708
  schema,
30900
- queryConfig: join32,
30709
+ queryConfig: join34,
30901
30710
  tableConfig: schema[relation.targetTableName],
30902
30711
  relationWhere: filter,
30903
30712
  isNested: true,
@@ -30911,7 +30720,7 @@ var SQLiteDialect = class {
30911
30720
  key: k2,
30912
30721
  selection: innerQuery.selection,
30913
30722
  isArray: !isSingle2,
30914
- isOptional: (relation.optional ?? false) || join32 !== true && !!join32.where
30723
+ isOptional: (relation.optional ?? false) || join34 !== true && !!join34.where
30915
30724
  });
30916
30725
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
30917
30726
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -31265,7 +31074,7 @@ var SQLiteUpdateBase = class {
31265
31074
  createJoin(joinType) {
31266
31075
  return ((table, on2) => {
31267
31076
  const tableName = getTableLikeName(table);
31268
- if (typeof tableName === "string" && this.config.joins.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
31077
+ if (typeof tableName === "string" && this.config.joins.some((join34) => join34.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
31269
31078
  if (typeof on2 === "function") {
31270
31079
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
31271
31080
  on2 = on2(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -32049,8 +31858,8 @@ var LocalSqliteDatabase = class {
32049
31858
  function channelSessionDatabasePaths(stateDirectory, channelId) {
32050
31859
  const channelHash = createHash2("sha256").update(channelId).digest("hex");
32051
31860
  return {
32052
- events: join7(stateDirectory, "sessions", `${channelHash}.events.sqlite`),
32053
- sessions: join7(stateDirectory, "sessions", `${channelHash}.sqlite`)
31861
+ events: join4(stateDirectory, "sessions", `${channelHash}.events.sqlite`),
31862
+ sessions: join4(stateDirectory, "sessions", `${channelHash}.sqlite`)
32054
31863
  };
32055
31864
  }
32056
31865
  var openAcpSessionDatabase = (path7) => new LocalSqliteDatabase(path7, "ACP Session database", acpSessionStoreMigrations);
@@ -32228,11 +32037,11 @@ var SessionEventCacheTable = class {
32228
32037
 
32229
32038
  // src/storage/session/temporary-session-event-cache.ts
32230
32039
  function openTemporarySessionEventCache() {
32231
- const directory = mkdtempSync(join8(tmpdir2(), "mobius-preview-events-"));
32040
+ const directory = mkdtempSync(join5(tmpdir(), "mobius-preview-events-"));
32232
32041
  const removeFiles = () => rmSync(directory, { recursive: true, force: true });
32233
32042
  try {
32234
32043
  return {
32235
- table: new SessionEventCacheTable(openSessionEventCacheDatabase(join8(directory, "events.sqlite"))),
32044
+ table: new SessionEventCacheTable(openSessionEventCacheDatabase(join5(directory, "events.sqlite"))),
32236
32045
  removeFiles
32237
32046
  };
32238
32047
  } catch (error62) {
@@ -32742,13 +32551,13 @@ var RuntimeAgentDependencies = class {
32742
32551
 
32743
32552
  // src/daemon/pairing/pair-local-machine.ts
32744
32553
  import { hostname as hostname3 } from "node:os";
32745
- import { basename as basename6, join as join24, resolve as resolve16 } from "node:path";
32554
+ import { basename as basename6, join as join26, resolve as resolve16 } from "node:path";
32746
32555
  import { fetch as fetch3 } from "undici";
32747
32556
 
32748
32557
  // package.json
32749
32558
  var package_default = {
32750
32559
  name: "@moxt-ai/mobius",
32751
- version: "0.0.336",
32560
+ version: "0.0.338",
32752
32561
  description: "Mobius CLI for pairing and running local AI agent services.",
32753
32562
  type: "module",
32754
32563
  bin: {
@@ -32930,7 +32739,7 @@ import { existsSync as existsSync3 } from "node:fs";
32930
32739
  import * as fs3 from "node:fs/promises";
32931
32740
  import * as os3 from "node:os";
32932
32741
  import * as path6 from "node:path";
32933
- import { promisify as promisify2 } from "node:util";
32742
+ import { promisify } from "node:util";
32934
32743
  import { agent as acpAgent, CreateElicitationResponse as CreateElicitationResponse2, methods as methods7, ndJsonStream, RequestError as RequestError6 } from "@agentclientprotocol/sdk";
32935
32744
 
32936
32745
  // ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.3.257_@anthropic-ai+sdk@0.122.0_zod@4.6.5__@modelconte_b0b90ed00d211c5955785f7de7f8dbf4/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
@@ -72296,7 +72105,7 @@ var SessionModeManager = class {
72296
72105
 
72297
72106
  // src/acp/harness/claude/upstream/dist/acp-agent.js
72298
72107
  var CLAUDE_CONFIG_DIR = process.env.CLAUDE_CONFIG_DIR ?? path6.join(os3.homedir(), ".claude");
72299
- var execFileAsync = promisify2(execFile3);
72108
+ var execFileAsync = promisify(execFile3);
72300
72109
  var ZERO_USAGE = Object.freeze({
72301
72110
  input_tokens: 0,
72302
72111
  output_tokens: 0,
@@ -73925,16 +73734,20 @@ var ClaudeAcpAgent = class {
73925
73734
  }, message.tool_use_id !== void 0)
73926
73735
  });
73927
73736
  }
73928
- backgroundTasks.delete(message.task_id);
73929
73737
  if (message.skip_transcript) {
73738
+ backgroundTasks.delete(message.task_id);
73930
73739
  awaitingBackgroundResults.delete(message.task_id);
73931
- } else {
73740
+ } else if (backgroundTasks.delete(message.task_id)) {
73932
73741
  awaitingBackgroundResults.add(message.task_id);
73933
73742
  }
73934
73743
  reportBackgroundActivity();
73935
73744
  session.liveBackgroundTasks.delete(message.task_id);
73936
73745
  break;
73937
73746
  case "task_updated":
73747
+ if (!hasBackgroundLevel && message.patch.is_backgrounded === true) {
73748
+ backgroundTasks.add(message.task_id);
73749
+ reportBackgroundActivity();
73750
+ }
73938
73751
  if (message.patch.status === "completed" || message.patch.status === "failed" || message.patch.status === "killed") {
73939
73752
  session.liveBackgroundTasks.delete(message.task_id);
73940
73753
  if (backgroundTasks.delete(message.task_id)) {
@@ -77063,6 +76876,237 @@ var ClaudeAgentConnection = class extends EndpointAgentConnection {
77063
76876
  }
77064
76877
  };
77065
76878
 
76879
+ // src/util/platform/linux.ts
76880
+ import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
76881
+
76882
+ // src/util/platform/posix.ts
76883
+ import { chmod, lstat as lstat2, unlink as unlink2 } from "node:fs/promises";
76884
+ import { tmpdir as tmpdir2 } from "node:os";
76885
+ import { join as join12 } from "node:path";
76886
+
76887
+ // src/util/filesystem/path-error.ts
76888
+ var LocalPathError = class extends Error {
76889
+ code = "unsafe_local_path";
76890
+ constructor(message, options = {}) {
76891
+ super(message, options);
76892
+ this.name = "LocalPathError";
76893
+ }
76894
+ };
76895
+
76896
+ // src/util/platform/posix.ts
76897
+ async function removeControlSocket(path7) {
76898
+ try {
76899
+ await unlink2(path7);
76900
+ } catch (cause) {
76901
+ if (!(cause instanceof Error) || !("code" in cause) || cause.code !== "ENOENT") {
76902
+ throw cause;
76903
+ }
76904
+ }
76905
+ }
76906
+ var posixOperations2 = {
76907
+ controlSocketPath: (installationHash) => join12(tmpdir2(), `mobius-${installationHash}.sock`),
76908
+ prepareControlSocket: removeControlSocket,
76909
+ secureControlSocket: async (path7) => {
76910
+ await chmod(path7, 384);
76911
+ },
76912
+ removeControlSocket,
76913
+ validatePathPermissions: async (path7, directory, privateAccess, signal) => {
76914
+ signal.throwIfAborted();
76915
+ const metadata = await lstat2(path7);
76916
+ if (process.getuid === void 0 || metadata.uid !== process.getuid()) {
76917
+ throw new LocalPathError("Path is not user-owned");
76918
+ }
76919
+ if (privateAccess) {
76920
+ await chmod(path7, directory ? 448 : 384);
76921
+ }
76922
+ signal.throwIfAborted();
76923
+ }
76924
+ };
76925
+
76926
+ // src/util/platform/linux.ts
76927
+ var linuxPlatform = {
76928
+ ...posixOperations2,
76929
+ claudeCodeExecutablePaths: (environment) => {
76930
+ const homeDirectory = environment["HOME"];
76931
+ return homeDirectory !== void 0 && isAbsolute8(homeDirectory) ? [join13(homeDirectory, ".local", "bin", "claude")] : [];
76932
+ }
76933
+ };
76934
+
76935
+ // src/util/platform/macos.ts
76936
+ import { isAbsolute as isAbsolute9, join as join15 } from "node:path";
76937
+
76938
+ // src/util/platform/claude-desktop.ts
76939
+ import { readdirSync as readdirSync3 } from "node:fs";
76940
+ import { join as join14 } from "node:path";
76941
+ function installedDirectories(directory) {
76942
+ try {
76943
+ return readdirSync3(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
76944
+ } catch (cause) {
76945
+ if (cause instanceof Error && "code" in cause && (cause.code === "ENOENT" || cause.code === "ENOTDIR" || cause.code === "EACCES")) {
76946
+ return [];
76947
+ }
76948
+ throw cause;
76949
+ }
76950
+ }
76951
+ function claudeDesktopExecutablePaths(roots, executablePaths) {
76952
+ const paths = [];
76953
+ for (const root of roots) {
76954
+ const versions = installedDirectories(root).filter((version2) => /^\d+\.\d+\.\d+$/.test(version2)).toSorted((left, right) => right.localeCompare(left, "en", { numeric: true }));
76955
+ for (const version2 of versions) {
76956
+ const directory = join14(root, version2);
76957
+ const installations = [
76958
+ directory,
76959
+ ...installedDirectories(directory).map((build) => join14(directory, build))
76960
+ ];
76961
+ for (const installation of installations) {
76962
+ for (const executablePath of executablePaths) {
76963
+ paths.push(join14(installation, ...executablePath));
76964
+ }
76965
+ }
76966
+ }
76967
+ }
76968
+ return paths;
76969
+ }
76970
+
76971
+ // src/util/platform/macos.ts
76972
+ var macosPlatform = {
76973
+ ...posixOperations2,
76974
+ claudeCodeExecutablePaths: (environment) => {
76975
+ const paths = ["/opt/homebrew/bin/claude", "/usr/local/bin/claude"];
76976
+ const homeDirectory = environment["HOME"];
76977
+ if (homeDirectory !== void 0 && isAbsolute9(homeDirectory)) {
76978
+ paths.unshift(join15(homeDirectory, ".local", "bin", "claude"));
76979
+ paths.push(
76980
+ ...claudeDesktopExecutablePaths(
76981
+ [join15(homeDirectory, "Library", "Application Support", "Claude", "claude-code")],
76982
+ [["claude.app", "Contents", "MacOS", "claude"], ["claude"]]
76983
+ )
76984
+ );
76985
+ }
76986
+ return paths;
76987
+ }
76988
+ };
76989
+
76990
+ // src/util/platform/windows.ts
76991
+ import { execFile as execFile4 } from "node:child_process";
76992
+ import { isAbsolute as isAbsolute10, join as join16 } from "node:path";
76993
+ import { promisify as promisify2 } from "node:util";
76994
+ var execute = promisify2(execFile4);
76995
+ function environmentValue2(environment, name2) {
76996
+ return Object.entries(environment).find(([key]) => key.toUpperCase() === name2.toUpperCase())?.[1];
76997
+ }
76998
+ function desktopClaudeExecutablePaths(environment) {
76999
+ const roots = [];
77000
+ const localAppData = environmentValue2(environment, "LOCALAPPDATA");
77001
+ if (localAppData !== void 0 && isAbsolute10(localAppData)) {
77002
+ const dataDirectory = join16(localAppData, "Claude-Data");
77003
+ for (const installation of installedDirectories(dataDirectory)) {
77004
+ if (installation.startsWith("claude_")) {
77005
+ roots.push(join16(dataDirectory, installation, "claude-code"));
77006
+ }
77007
+ }
77008
+ }
77009
+ const appData = environmentValue2(environment, "APPDATA");
77010
+ if (appData !== void 0 && isAbsolute10(appData)) {
77011
+ roots.push(join16(appData, "Claude", "claude-code"));
77012
+ }
77013
+ return claudeDesktopExecutablePaths(roots, [["claude.exe"]]);
77014
+ }
77015
+ var windowsPermissions = `
77016
+ $ErrorActionPreference = 'Stop'
77017
+ $ProgressPreference = 'SilentlyContinue'
77018
+ $item = Get-Item -LiteralPath $env:MOBIUS_PERMISSION_PATH -Force
77019
+ if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'Unsafe path' }
77020
+ $sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
77021
+ $acl = $item.GetAccessControl()
77022
+ $owner = $acl.GetOwner([Security.Principal.SecurityIdentifier])
77023
+ if ($owner -ne $sid -and -not ($owner.Value -eq 'S-1-5-32-544' -and ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { throw 'Path is not user-owned' }
77024
+ if ($env:MOBIUS_PERMISSION_PRIVATE -eq '1') {
77025
+ if ($item.PSIsContainer) {
77026
+ $private = New-Object Security.AccessControl.DirectorySecurity
77027
+ $rule = New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
77028
+ } else {
77029
+ $private = New-Object Security.AccessControl.FileSecurity
77030
+ $rule = New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'Allow')
77031
+ }
77032
+ $private.SetOwner($sid)
77033
+ $private.SetAccessRuleProtection($true, $false)
77034
+ $private.AddAccessRule($rule)
77035
+ $item.SetAccessControl($private)
77036
+ }
77037
+ `;
77038
+ var windowsPermissionsTimeoutMs = 3e4;
77039
+ async function validatePathPermissions(path7, _directory, privateAccess, signal) {
77040
+ signal.throwIfAborted();
77041
+ const systemRoot = environmentValue2(process.env, "SystemRoot");
77042
+ if (systemRoot === void 0) {
77043
+ throw new LocalPathError("Windows system directory is unavailable");
77044
+ }
77045
+ try {
77046
+ await execute(
77047
+ join16(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
77048
+ [
77049
+ "-NoLogo",
77050
+ "-NoProfile",
77051
+ "-NonInteractive",
77052
+ "-EncodedCommand",
77053
+ Buffer.from(windowsPermissions, "utf16le").toString("base64")
77054
+ ],
77055
+ {
77056
+ env: {
77057
+ ...process.env,
77058
+ MOBIUS_PERMISSION_PATH: path7,
77059
+ MOBIUS_PERMISSION_PRIVATE: privateAccess ? "1" : "0"
77060
+ },
77061
+ windowsHide: true,
77062
+ signal: AbortSignal.any([signal, AbortSignal.timeout(windowsPermissionsTimeoutMs)]),
77063
+ timeout: windowsPermissionsTimeoutMs,
77064
+ maxBuffer: 16384
77065
+ }
77066
+ );
77067
+ } catch (cause) {
77068
+ signal.throwIfAborted();
77069
+ throw new LocalPathError("The local path permissions could not be secured", { cause });
77070
+ }
77071
+ }
77072
+ var windowsPlatform = {
77073
+ controlSocketPath: (installationHash) => `\\\\.\\pipe\\mobius-${installationHash}`,
77074
+ prepareControlSocket: async () => {
77075
+ },
77076
+ secureControlSocket: async () => {
77077
+ },
77078
+ removeControlSocket: async () => {
77079
+ },
77080
+ validatePathPermissions,
77081
+ claudeCodeExecutablePaths: (environment) => {
77082
+ const paths = [];
77083
+ const userProfile = environmentValue2(environment, "USERPROFILE");
77084
+ if (userProfile !== void 0 && isAbsolute10(userProfile)) {
77085
+ paths.push(join16(userProfile, ".local", "bin", "claude.exe"));
77086
+ }
77087
+ const localAppData = environmentValue2(environment, "LOCALAPPDATA");
77088
+ if (localAppData !== void 0 && isAbsolute10(localAppData)) {
77089
+ paths.push(join16(localAppData, "Microsoft", "WinGet", "Links", "claude.exe"));
77090
+ }
77091
+ paths.push(...desktopClaudeExecutablePaths(environment));
77092
+ return paths;
77093
+ }
77094
+ };
77095
+
77096
+ // src/util/platform/index.ts
77097
+ var fallbackPlatform2 = {
77098
+ ...posixOperations2,
77099
+ claudeCodeExecutablePaths: () => []
77100
+ };
77101
+ var platforms2 = /* @__PURE__ */ new Map([
77102
+ ["linux", linuxPlatform],
77103
+ ["darwin", macosPlatform],
77104
+ ["win32", windowsPlatform]
77105
+ ]);
77106
+ function platformSupportFor(platform2) {
77107
+ return platforms2.get(platform2) ?? fallbackPlatform2;
77108
+ }
77109
+
77066
77110
  // src/agent/discovery/version-output.ts
77067
77111
  function normalizeVersionOutput(output2) {
77068
77112
  return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
@@ -78160,7 +78204,7 @@ var CodexAgentSpecification = class extends InProcessAcpAgentSpecification {
78160
78204
 
78161
78205
  // src/agent/specification/vendors/pi-agent.ts
78162
78206
  import { createHash as createHash4 } from "node:crypto";
78163
- import { join as join20 } from "node:path";
78207
+ import { join as join22 } from "node:path";
78164
78208
  import {
78165
78209
  methods as methods11
78166
78210
  } from "@agentclientprotocol/sdk";
@@ -78175,7 +78219,7 @@ import {
78175
78219
  import { spawnSync } from "node:child_process";
78176
78220
  import { randomUUID as randomUUID10 } from "node:crypto";
78177
78221
  import { existsSync as existsSync7, readdirSync as readdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync4, statSync as statSync4, unlinkSync as unlinkSync2 } from "node:fs";
78178
- import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute13, join as join19 } from "node:path";
78222
+ import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute13, join as join21 } from "node:path";
78179
78223
  import { RequestError as RequestError10 } from "@agentclientprotocol/sdk";
78180
78224
 
78181
78225
  // src/acp/harness/pi/upstream/dist/pi-rpc/process.js
@@ -78633,7 +78677,7 @@ function maybeAuthRequiredError(err) {
78633
78677
  }
78634
78678
 
78635
78679
  // src/acp/harness/pi/upstream/dist/acp/paths.js
78636
- import { join as join15 } from "node:path";
78680
+ import { join as join17 } from "node:path";
78637
78681
 
78638
78682
  // src/acp/harness/pi/upstream/dist/acp/environment.js
78639
78683
  import { homedir as homedir2 } from "node:os";
@@ -78643,10 +78687,10 @@ function environmentHome(environment) {
78643
78687
 
78644
78688
  // src/acp/harness/pi/upstream/dist/acp/paths.js
78645
78689
  function getPiAcpDir(environment = process.env) {
78646
- return join15(environmentHome(environment), ".pi", "pi-acp");
78690
+ return join17(environmentHome(environment), ".pi", "pi-acp");
78647
78691
  }
78648
78692
  function getPiAcpSessionMapPath(environment = process.env) {
78649
- return join15(getPiAcpDir(environment), "session-map.json");
78693
+ return join17(getPiAcpDir(environment), "session-map.json");
78650
78694
  }
78651
78695
 
78652
78696
  // src/acp/harness/pi/upstream/dist/acp/pi-commands.js
@@ -78691,15 +78735,15 @@ function toAvailableCommandsFromPiGetCommands(data, opts) {
78691
78735
 
78692
78736
  // src/acp/harness/pi/upstream/dist/acp/pi-sessions.js
78693
78737
  import { closeSync as closeSync2, existsSync as existsSync4, openSync as openSync2, readdirSync as readdirSync4, readFileSync as readFileSync3, readSync as readSync2, statSync as statSync3 } from "node:fs";
78694
- import { isAbsolute as isAbsolute11, join as join16, resolve as resolve10 } from "node:path";
78738
+ import { isAbsolute as isAbsolute11, join as join18, resolve as resolve10 } from "node:path";
78695
78739
  var DEFAULT_TAIL_BYTES = 256 * 1024;
78696
78740
  var DEFAULT_HEAD_BYTES = 64 * 1024;
78697
78741
  function getPiAgentDir(environment) {
78698
78742
  const configured = environment["PI_CODING_AGENT_DIR"];
78699
- return configured ? resolve10(configured) : join16(environmentHome(environment), ".pi", "agent");
78743
+ return configured ? resolve10(configured) : join18(environmentHome(environment), ".pi", "agent");
78700
78744
  }
78701
78745
  function readSessionDirFromSettings(agentDir) {
78702
- const settingsPath = join16(agentDir, "settings.json");
78746
+ const settingsPath = join18(agentDir, "settings.json");
78703
78747
  try {
78704
78748
  if (!existsSync4(settingsPath)) {
78705
78749
  return null;
@@ -78720,7 +78764,7 @@ function readSessionDirFromSettings(agentDir) {
78720
78764
  }
78721
78765
  function getPiSessionsDir(environment = process.env) {
78722
78766
  const agentDir = getPiAgentDir(environment);
78723
- return readSessionDirFromSettings(agentDir) ?? join16(agentDir, "sessions");
78767
+ return readSessionDirFromSettings(agentDir) ?? join18(agentDir, "sessions");
78724
78768
  }
78725
78769
  function getPiSessionDiscoveryDirs(environment) {
78726
78770
  const discoveryDirectories = [getPiSessionsDir(environment)];
@@ -78731,7 +78775,7 @@ function getPiSessionDiscoveryDirs(environment) {
78731
78775
  if (!entry.isDirectory()) {
78732
78776
  continue;
78733
78777
  }
78734
- const directory = join16(mobiusSessionsRoot, entry.name);
78778
+ const directory = join18(mobiusSessionsRoot, entry.name);
78735
78779
  if (!discoveryDirectories.includes(directory)) {
78736
78780
  discoveryDirectories.push(directory);
78737
78781
  }
@@ -78748,7 +78792,7 @@ function walkJsonlFiles(dir, out2) {
78748
78792
  }
78749
78793
  for (const e of entries) {
78750
78794
  const name2 = typeof e.name === "string" ? e.name : String(e.name);
78751
- const p = join16(dir, name2);
78795
+ const p = join18(dir, name2);
78752
78796
  if (e.isDirectory()) {
78753
78797
  walkJsonlFiles(p, out2);
78754
78798
  } else if (e.isFile() && name2.endsWith(".jsonl")) {
@@ -79017,7 +79061,7 @@ function findPiSession(sessionId, environment = process.env) {
79017
79061
 
79018
79062
  // src/acp/harness/pi/upstream/dist/acp/pi-settings.js
79019
79063
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
79020
- import { join as join17, resolve as resolve11 } from "node:path";
79064
+ import { join as join19, resolve as resolve11 } from "node:path";
79021
79065
  function isObject2(x) {
79022
79066
  return Boolean(x) && typeof x === "object" && !Array.isArray(x);
79023
79067
  }
@@ -79046,7 +79090,7 @@ function readJsonFile(path7) {
79046
79090
  }
79047
79091
  }
79048
79092
  function getMergedSettings(cwd, environment) {
79049
- const globalSettingsPath = join17(getAgentDir(environment), "settings.json");
79093
+ const globalSettingsPath = join19(getAgentDir(environment), "settings.json");
79050
79094
  const projectSettingsPath = resolve11(cwd, ".pi", "settings.json");
79051
79095
  const global2 = readJsonFile(globalSettingsPath);
79052
79096
  const project = readJsonFile(projectSettingsPath);
@@ -79054,7 +79098,7 @@ function getMergedSettings(cwd, environment) {
79054
79098
  }
79055
79099
  function getAgentDir(environment = process.env) {
79056
79100
  const configured = environment["PI_CODING_AGENT_DIR"];
79057
- return configured ? resolve11(configured) : join17(environmentHome(environment), ".pi", "agent");
79101
+ return configured ? resolve11(configured) : join19(environmentHome(environment), ".pi", "agent");
79058
79102
  }
79059
79103
  function getEnableSkillCommands(cwd, environment = process.env) {
79060
79104
  const merged = getMergedSettings(cwd, environment);
@@ -79310,7 +79354,7 @@ var SessionStore = class {
79310
79354
 
79311
79355
  // src/acp/harness/pi/upstream/dist/acp/slash-commands.js
79312
79356
  import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync6 } from "node:fs";
79313
- import { join as join18, resolve as resolve12 } from "node:path";
79357
+ import { join as join20, resolve as resolve12 } from "node:path";
79314
79358
  function parseFrontmatter(content) {
79315
79359
  const frontmatter = {};
79316
79360
  if (!content.startsWith("---")) {
@@ -79338,7 +79382,7 @@ function loadCommandsFromDir(dir, source, subdir = "") {
79338
79382
  try {
79339
79383
  const entries = readdirSync5(dir, { withFileTypes: true });
79340
79384
  for (const entry of entries) {
79341
- const fullPath = join18(dir, entry.name);
79385
+ const fullPath = join20(dir, entry.name);
79342
79386
  if (entry.isDirectory()) {
79343
79387
  const newSubdir = subdir ? `${subdir}:${entry.name}` : entry.name;
79344
79388
  commands.push(...loadCommandsFromDir(fullPath, source, newSubdir));
@@ -79378,7 +79422,7 @@ function loadCommandsFromDir(dir, source, subdir = "") {
79378
79422
  }
79379
79423
  function loadSlashCommands(cwd, environment = process.env) {
79380
79424
  const commands = [];
79381
- const userDir = join18(environmentHome(environment), ".pi", "agent", "prompts");
79425
+ const userDir = join20(environmentHome(environment), ".pi", "agent", "prompts");
79382
79426
  const projectDir = resolve12(cwd, ".pi", "prompts");
79383
79427
  commands.push(...loadCommandsFromDir(userDir, "user"));
79384
79428
  commands.push(...loadCommandsFromDir(projectDir, "project"));
@@ -81025,7 +81069,7 @@ ${JSON.stringify(stats, null, 2)}`;
81025
81069
  if (piPath) {
81026
81070
  const resolved = realpathSync4(piPath);
81027
81071
  const pkgRoot = dirname8(dirname8(resolved));
81028
- const p = join19(pkgRoot, "CHANGELOG.md");
81072
+ const p = join21(pkgRoot, "CHANGELOG.md");
81029
81073
  if (existsSync7(p)) {
81030
81074
  return p;
81031
81075
  }
@@ -81036,7 +81080,7 @@ ${JSON.stringify(stats, null, 2)}`;
81036
81080
  const npmRoot = spawnSync("npm", ["root", "-g"], { encoding: "utf-8" });
81037
81081
  const root = String(npmRoot.stdout ?? "").trim();
81038
81082
  if (root) {
81039
- const p = join19(root, "@earendil-works", "pi-coding-agent", "CHANGELOG.md");
81083
+ const p = join21(root, "@earendil-works", "pi-coding-agent", "CHANGELOG.md");
81040
81084
  if (existsSync7(p)) {
81041
81085
  return p;
81042
81086
  }
@@ -81130,7 +81174,7 @@ ${JSON.stringify(stats, null, 2)}`;
81130
81174
  return { stopReason: "end_turn" };
81131
81175
  }
81132
81176
  const safeSessionId = session.sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
81133
- const outputPath = join19(session.cwd, `pi-session-${safeSessionId}.html`);
81177
+ const outputPath = join21(session.cwd, `pi-session-${safeSessionId}.html`);
81134
81178
  let resultPath = "";
81135
81179
  try {
81136
81180
  const result2 = await session.proc.exportHtml(outputPath);
@@ -81844,7 +81888,7 @@ function buildStartupInfo(opts) {
81844
81888
  md.push("");
81845
81889
  };
81846
81890
  const contextItems = [];
81847
- const contextPath = join19(opts.cwd, "AGENTS.md");
81891
+ const contextPath = join21(opts.cwd, "AGENTS.md");
81848
81892
  if (existsSync7(contextPath)) {
81849
81893
  contextItems.push(contextPath);
81850
81894
  }
@@ -81853,7 +81897,7 @@ function buildStartupInfo(opts) {
81853
81897
  const pushSkillFromRoot = (root) => {
81854
81898
  try {
81855
81899
  for (const e of readdirSync6(root)) {
81856
- const p = join19(root, e);
81900
+ const p = join21(root, e);
81857
81901
  try {
81858
81902
  const st2 = statSync4(p);
81859
81903
  if (st2.isFile() && e.toLowerCase().endsWith(".md")) {
@@ -81878,7 +81922,7 @@ function buildStartupInfo(opts) {
81878
81922
  if (name2 === "node_modules" || name2 === ".git") {
81879
81923
  continue;
81880
81924
  }
81881
- const p = join19(dir, name2);
81925
+ const p = join21(dir, name2);
81882
81926
  let st2;
81883
81927
  try {
81884
81928
  st2 = statSync4(p);
@@ -81895,16 +81939,16 @@ function buildStartupInfo(opts) {
81895
81939
  } catch {
81896
81940
  }
81897
81941
  };
81898
- const globalSkillsDir = join19(getAgentDir(opts.environment), "skills");
81942
+ const globalSkillsDir = join21(getAgentDir(opts.environment), "skills");
81899
81943
  pushSkillFromRoot(globalSkillsDir);
81900
81944
  const home = opts.environment["HOME"] ?? opts.environment["USERPROFILE"] ?? "";
81901
- const legacyAgentsSkillsDir = join19(home, ".agents", "skills");
81945
+ const legacyAgentsSkillsDir = join21(home, ".agents", "skills");
81902
81946
  pushSkillFromRoot(legacyAgentsSkillsDir);
81903
- const projectSkillsDir = join19(opts.cwd, ".pi", "skills");
81947
+ const projectSkillsDir = join21(opts.cwd, ".pi", "skills");
81904
81948
  pushSkillFromRoot(projectSkillsDir);
81905
81949
  addSection("Skills", skillsItems);
81906
81950
  const promptsItems = [];
81907
- const promptsDir = join19(home, ".pi", "agent", "prompts");
81951
+ const promptsDir = join21(home, ".pi", "agent", "prompts");
81908
81952
  try {
81909
81953
  const prompts = readdirSync6(promptsDir).filter((f) => f.endsWith(".md"));
81910
81954
  for (const f of prompts) {
@@ -81914,17 +81958,17 @@ function buildStartupInfo(opts) {
81914
81958
  }
81915
81959
  addSection("Prompts", promptsItems);
81916
81960
  const extItems = [];
81917
- const extDir = join19(home, ".pi", "agent", "extensions");
81961
+ const extDir = join21(home, ".pi", "agent", "extensions");
81918
81962
  try {
81919
81963
  const exts = readdirSync6(extDir).filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
81920
81964
  for (const f of exts) {
81921
- extItems.push(join19(extDir, f));
81965
+ extItems.push(join21(extDir, f));
81922
81966
  }
81923
81967
  } catch {
81924
81968
  }
81925
81969
  const settingsPaths = [
81926
- join19(getAgentDir(opts.environment), "settings.json"),
81927
- join19(opts.cwd, ".pi", "settings.json")
81970
+ join21(getAgentDir(opts.environment), "settings.json"),
81971
+ join21(opts.cwd, ".pi", "settings.json")
81928
81972
  ];
81929
81973
  for (const settingsPath of settingsPaths) {
81930
81974
  try {
@@ -82122,7 +82166,7 @@ var PiAgentSpecification = class extends InProcessAcpAgentSpecification {
82122
82166
  // keeps the adapter's opt-in capability flag enabled for every launch it owns.
82123
82167
  createLaunchEnvironment = async (_agent, context) => {
82124
82168
  const workspaceHash = createHash4("sha256").update(context.defaultWorkspace).digest("hex").slice(0, 24);
82125
- const sessionDirectory = join20(context.dataDirectory, "agents", "pi", "sessions", workspaceHash);
82169
+ const sessionDirectory = join22(context.dataDirectory, "agents", "pi", "sessions", workspaceHash);
82126
82170
  return Object.freeze({
82127
82171
  PI_ACP_ENABLE_EMBEDDED_CONTEXT: "true",
82128
82172
  MOBIUS_PI_SESSION_DIR: sessionDirectory
@@ -82855,7 +82899,7 @@ async function publishAgentCatalog(config2, signal) {
82855
82899
  }
82856
82900
 
82857
82901
  // src/runtime/config.ts
82858
- import { join as join22, resolve as resolve14 } from "node:path";
82902
+ import { join as join24, resolve as resolve14 } from "node:path";
82859
82903
 
82860
82904
  // src/util/serial-task-queue.ts
82861
82905
  var SerialTaskQueue = class {
@@ -82928,19 +82972,19 @@ var LocalAgentCatalog = class {
82928
82972
 
82929
82973
  // src/storage/state-directory.ts
82930
82974
  import { homedir as homedir3 } from "node:os";
82931
- import { join as join21, resolve as resolve13 } from "node:path";
82975
+ import { join as join23, resolve as resolve13 } from "node:path";
82932
82976
  var stateRootSchema = external_exports.string().brand();
82933
82977
  function readStateDirectory(environment = process.env) {
82934
82978
  const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
82935
82979
  return stateRootSchema.parse(
82936
- configured !== void 0 && configured.length > 0 ? resolve13(configured) : join21(homedir3(), ".mobius")
82980
+ configured !== void 0 && configured.length > 0 ? resolve13(configured) : join23(homedir3(), ".mobius")
82937
82981
  );
82938
82982
  }
82939
82983
 
82940
82984
  // src/runtime/config.ts
82941
82985
  function loadDefaultWorkspace(dataDirectory, environment = process.env) {
82942
82986
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
82943
- return configuredWorkspace ?? join22(dataDirectory, "workspace");
82987
+ return configuredWorkspace ?? join24(dataDirectory, "workspace");
82944
82988
  }
82945
82989
  var RuntimeLocalContext = class {
82946
82990
  environment;
@@ -83049,7 +83093,7 @@ import { resolve as resolve15 } from "node:path";
83049
83093
  // src/storage/installation/installation-files.ts
83050
83094
  import { createHash as createHash5, randomUUID as randomUUID12 } from "node:crypto";
83051
83095
  import { mkdir as mkdir4, open as open5, readdir as readdir5, rename as rename3, unlink as unlink3, writeFile } from "node:fs/promises";
83052
- import { dirname as dirname9, join as join23 } from "node:path";
83096
+ import { dirname as dirname9, join as join25 } from "node:path";
83053
83097
 
83054
83098
  // src/util/node-error.ts
83055
83099
  function isNodeError(error62, code) {
@@ -83072,23 +83116,23 @@ var STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
83072
83116
  // src/storage/installation/installation-files.ts
83073
83117
  var MAXIMUM_FILE_BYTES = 16 * 1024;
83074
83118
  function applicationDirectory(root, applicationId) {
83075
- return join23(root, STATE_ROOT_LAYOUT.installations, applicationId);
83119
+ return join25(root, STATE_ROOT_LAYOUT.installations, applicationId);
83076
83120
  }
83077
83121
  function installationPointerPath(applicationDirectory2) {
83078
- return join23(applicationDirectory2, "current.json");
83122
+ return join25(applicationDirectory2, "current.json");
83079
83123
  }
83080
83124
  var installationDirectorySchema = external_exports.string().brand();
83081
83125
  function installationDirectory(applicationDirectory2, installationId2) {
83082
- return installationDirectorySchema.parse(join23(applicationDirectory2, installationId2));
83126
+ return installationDirectorySchema.parse(join25(applicationDirectory2, installationId2));
83083
83127
  }
83084
83128
  function connectionDirectory(installationDirectory2) {
83085
- return join23(installationDirectory2, "connections");
83129
+ return join25(installationDirectory2, "connections");
83086
83130
  }
83087
83131
  function connectionFilePath(connectionDirectory2, connectionId2) {
83088
- return join23(connectionDirectory2, `${connectionId2}.json`);
83132
+ return join25(connectionDirectory2, `${connectionId2}.json`);
83089
83133
  }
83090
83134
  function channelIndexFilePath(installationDirectory2, channelId) {
83091
- return join23(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
83135
+ return join25(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
83092
83136
  }
83093
83137
  async function readInstallationFile(path7) {
83094
83138
  let handle;
@@ -83110,7 +83154,7 @@ async function readInstallationFile(path7) {
83110
83154
  async function writeInstallationFile(path7, text2, signal) {
83111
83155
  signal.throwIfAborted();
83112
83156
  const directory = dirname9(path7);
83113
- const temporaryPath = join23(directory, `.${randomUUID12()}.tmp`);
83157
+ const temporaryPath = join25(directory, `.${randomUUID12()}.tmp`);
83114
83158
  try {
83115
83159
  await mkdir4(directory, { mode: 448, recursive: true });
83116
83160
  signal.throwIfAborted();
@@ -87420,56 +87464,82 @@ var ExecutionReceipts = class {
87420
87464
  var RuntimeTurnActivity = class {
87421
87465
  #turns = /* @__PURE__ */ new Set();
87422
87466
  #backgroundSources = /* @__PURE__ */ new Set();
87423
- #admission = { kind: "open" };
87424
- acceptsPrompts = () => this.#admission.kind !== "reserved";
87467
+ #idleWaiters = /* @__PURE__ */ new Set();
87468
+ // When work last started or stopped; the quiet period is measured from here.
87469
+ #changedAt = Date.now();
87470
+ #reserved = false;
87471
+ acceptsPrompts = () => !this.#reserved;
87425
87472
  count = () => this.#turns.size + this.#backgroundSources.size;
87473
+ describe = () => ({
87474
+ turns: this.#turns.size,
87475
+ backgroundSources: this.#backgroundSources.size
87476
+ });
87426
87477
  setBackgroundActivity = (source, active) => {
87478
+ if (active === this.#backgroundSources.has(source)) {
87479
+ return;
87480
+ }
87427
87481
  if (active) {
87428
87482
  this.#backgroundSources.add(source);
87429
87483
  } else {
87430
87484
  this.#backgroundSources.delete(source);
87431
87485
  }
87432
- this.#reserveIfIdle();
87486
+ this.#changed();
87433
87487
  };
87434
- #reserveIfIdle() {
87435
- if (this.count() === 0 && this.#admission.kind === "waiting") {
87436
- this.#admission.reserve();
87437
- }
87438
- }
87439
87488
  start = (turn) => {
87440
87489
  this.#turns.add(turn);
87490
+ this.#changed();
87441
87491
  };
87442
87492
  finish = (turn) => {
87443
87493
  this.#turns.delete(turn);
87444
- this.#reserveIfIdle();
87494
+ this.#changed();
87445
87495
  };
87446
- reserveWhenIdle = (signal) => {
87496
+ #changed() {
87497
+ this.#changedAt = Date.now();
87498
+ if (this.count() === 0) {
87499
+ for (const resolve19 of this.#idleWaiters) {
87500
+ resolve19();
87501
+ }
87502
+ this.#idleWaiters.clear();
87503
+ }
87504
+ }
87505
+ whenIdle = (signal) => {
87447
87506
  signal.throwIfAborted();
87448
- if (this.#admission.kind !== "open") {
87449
- throw new Error("A daemon upgrade already owns admission");
87507
+ if (this.count() === 0) {
87508
+ return Promise.resolve();
87450
87509
  }
87451
87510
  return new Promise((resolve19, reject2) => {
87452
87511
  const abort = () => {
87453
- this.#admission = { kind: "open" };
87454
- signal.removeEventListener("abort", abort);
87512
+ this.#idleWaiters.delete(idle);
87455
87513
  reject2(signal.reason);
87456
87514
  };
87457
- const reserve = () => {
87458
- this.#admission = { kind: "reserved" };
87515
+ const idle = () => {
87459
87516
  signal.removeEventListener("abort", abort);
87460
- resolve19({
87461
- [Symbol.dispose]: () => {
87462
- this.#admission = { kind: "open" };
87463
- }
87464
- });
87517
+ resolve19();
87465
87518
  };
87466
- this.#admission = { kind: "waiting", reserve };
87519
+ this.#idleWaiters.add(idle);
87467
87520
  signal.addEventListener("abort", abort, { once: true });
87468
- if (this.count() === 0) {
87469
- reserve();
87470
- }
87471
87521
  });
87472
87522
  };
87523
+ /**
87524
+ * Close admission only after the Runtime has had no work for `quietMilliseconds`.
87525
+ * The moment a reply finishes is when a user is most likely to continue, so idle
87526
+ * alone is not an upgrade window. Checking and reserving happen synchronously, so
87527
+ * no prompt can be admitted between them.
87528
+ */
87529
+ reserveIfQuiet = (quietMilliseconds) => {
87530
+ if (this.#reserved) {
87531
+ throw new Error("A daemon upgrade already owns admission");
87532
+ }
87533
+ if (this.count() > 0 || Date.now() - this.#changedAt < quietMilliseconds) {
87534
+ return null;
87535
+ }
87536
+ this.#reserved = true;
87537
+ return {
87538
+ [Symbol.dispose]: () => {
87539
+ this.#reserved = false;
87540
+ }
87541
+ };
87542
+ };
87473
87543
  };
87474
87544
 
87475
87545
  // src/session/turn/active-turn.ts
@@ -87766,7 +87836,7 @@ var SessionTurns = class {
87766
87836
 
87767
87837
  // src/session/workspace/workspace-directory.ts
87768
87838
  import { homedir as homedir4 } from "node:os";
87769
- import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute15, join as join25, normalize as normalize2, relative as relative2 } from "node:path";
87839
+ import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute15, join as join27, normalize as normalize2, relative as relative2 } from "node:path";
87770
87840
  var WorkspaceDirectoryListing = class {
87771
87841
  directoryId;
87772
87842
  directoryLabel;
@@ -87888,7 +87958,7 @@ var WorkspaceDirectoryService = class {
87888
87958
  continue;
87889
87959
  }
87890
87960
  try {
87891
- const path7 = await this.resolvePath(join25(target, child.name), signal);
87961
+ const path7 = await this.resolvePath(join27(target, child.name), signal);
87892
87962
  entries.push({ directoryId: encodePath(path7), name: child.name });
87893
87963
  } catch (cause) {
87894
87964
  signal.throwIfAborted();
@@ -88036,12 +88106,12 @@ function buildSessionLayer(options) {
88036
88106
 
88037
88107
  // src/session/content/external-content-store.ts
88038
88108
  import { createHash as createHash7 } from "node:crypto";
88039
- import { join as join27 } from "node:path";
88109
+ import { join as join29 } from "node:path";
88040
88110
 
88041
88111
  // src/storage/files/scratch-directory.ts
88042
88112
  import { randomUUID as randomUUID17 } from "node:crypto";
88043
88113
  import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile6, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
88044
- import { dirname as dirname11, join as join26 } from "node:path";
88114
+ import { dirname as dirname11, join as join28 } from "node:path";
88045
88115
  async function atomicWrite(path7, bytes, signal) {
88046
88116
  const temporary = `${path7}.${randomUUID17()}.tmp`;
88047
88117
  try {
@@ -88055,7 +88125,7 @@ async function atomicWrite(path7, bytes, signal) {
88055
88125
  var ScratchDirectory = class {
88056
88126
  #root;
88057
88127
  constructor(parent) {
88058
- this.#root = join26(parent, randomUUID17());
88128
+ this.#root = join28(parent, randomUUID17());
88059
88129
  }
88060
88130
  /** Refreshes this directory's lease and removes sibling directories whose lease is older than `leaseMilliseconds`. */
88061
88131
  refreshLease = async (leaseMilliseconds) => {
@@ -88066,7 +88136,7 @@ var ScratchDirectory = class {
88066
88136
  if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
88067
88137
  continue;
88068
88138
  }
88069
- const path7 = join26(dirname11(this.#root), directory.name);
88139
+ const path7 = join28(dirname11(this.#root), directory.name);
88070
88140
  if (path7 === this.#root) {
88071
88141
  continue;
88072
88142
  }
@@ -88081,10 +88151,10 @@ var ScratchDirectory = class {
88081
88151
  };
88082
88152
  /** Writes `bytes` atomically to `<group>/<name>` with owner-only permissions and returns the path. */
88083
88153
  write = async (group, name2, bytes, signal) => {
88084
- const directory = join26(this.#root, group);
88154
+ const directory = join28(this.#root, group);
88085
88155
  await mkdir5(directory, { mode: 448, recursive: true });
88086
88156
  signal.throwIfAborted();
88087
- const path7 = join26(directory, name2);
88157
+ const path7 = join28(directory, name2);
88088
88158
  await atomicWrite(path7, bytes, signal);
88089
88159
  return path7;
88090
88160
  };
@@ -88131,7 +88201,7 @@ var LocalExternalContentStore = class {
88131
88201
  #expirationTimer;
88132
88202
  #cleanup = Promise.resolve();
88133
88203
  constructor(stateDirectory) {
88134
- this.#scratch = new ScratchDirectory(join27(stateDirectory, "tmp", "session-content"));
88204
+ this.#scratch = new ScratchDirectory(join29(stateDirectory, "tmp", "session-content"));
88135
88205
  this.#expirationTimer = setInterval(() => {
88136
88206
  void this.#expire().catch(() => void 0);
88137
88207
  }, 6e4);
@@ -88514,11 +88584,11 @@ var AgentProcessPool = class {
88514
88584
  };
88515
88585
 
88516
88586
  // src/runtime/observability/diagnostic-log.ts
88517
- import { join as join30 } from "node:path";
88587
+ import { join as join32 } from "node:path";
88518
88588
 
88519
88589
  // src/storage/logs/bounded-log.ts
88520
88590
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync as renameSync2, statSync as statSync5, writeFileSync as writeFileSync2 } from "node:fs";
88521
- import { join as join28 } from "node:path";
88591
+ import { join as join30 } from "node:path";
88522
88592
  var BoundedLineLog = class {
88523
88593
  #path;
88524
88594
  #maximumBytes;
@@ -88527,7 +88597,7 @@ var BoundedLineLog = class {
88527
88597
  #onWriteFailure;
88528
88598
  constructor(directory, filename, maximumBytes, onWriteFailure = () => void 0) {
88529
88599
  this.#directory = directory;
88530
- this.#path = join28(directory, filename);
88600
+ this.#path = join30(directory, filename);
88531
88601
  this.#maximumBytes = maximumBytes;
88532
88602
  this.#onWriteFailure = onWriteFailure;
88533
88603
  }
@@ -88578,21 +88648,21 @@ var BoundedLineLog = class {
88578
88648
 
88579
88649
  // src/storage/logs/log-files.ts
88580
88650
  import { readFileSync as readFileSync10 } from "node:fs";
88581
- import { join as join29, relative as relative3 } from "node:path";
88651
+ import { join as join31, relative as relative3 } from "node:path";
88582
88652
  var DAEMON_LOG_FILENAME = "daemon.log";
88583
88653
  var WORKER_LIFECYCLE_LOG_FILENAME = "worker-lifecycle.log";
88584
88654
  function unhandledRejectionLogFilename(role) {
88585
88655
  return `unhandled-rejections-${role}.log`;
88586
88656
  }
88587
88657
  function logDirectory(stateDirectory) {
88588
- return join29(stateDirectory, "logs");
88658
+ return join31(stateDirectory, "logs");
88589
88659
  }
88590
88660
  function processLogPaths(stateDirectory) {
88591
88661
  return [
88592
88662
  WORKER_LIFECYCLE_LOG_FILENAME,
88593
88663
  unhandledRejectionLogFilename("manager"),
88594
88664
  unhandledRejectionLogFilename("worker")
88595
- ].map((filename) => join29(logDirectory(stateDirectory), filename));
88665
+ ].map((filename) => join31(logDirectory(stateDirectory), filename));
88596
88666
  }
88597
88667
  function readLogText(path7) {
88598
88668
  try {
@@ -88648,7 +88718,7 @@ var RuntimeDiagnosticLog = class {
88648
88718
  this.#maximumBytes = maximumBytes;
88649
88719
  const processLogsDirectory = options.processLogsDirectory;
88650
88720
  this.#sources = [
88651
- { maximumBytes, path: join30(directory, DAEMON_LOG_FILENAME) },
88721
+ { maximumBytes, path: join32(directory, DAEMON_LOG_FILENAME) },
88652
88722
  // The process logs a Runtime does not own, but must read to explain its own deaths.
88653
88723
  ...processLogsDirectory === void 0 ? [] : processLogPaths(processLogsDirectory).map((path7) => ({ maximumBytes: null, path: path7 }))
88654
88724
  ];
@@ -89631,7 +89701,7 @@ function createContentWriteCommands(context) {
89631
89701
  import { WebSocket as WebSocket5 } from "undici";
89632
89702
 
89633
89703
  // src/session/content/session-files.ts
89634
- import { basename as basename8, extname as extname2, isAbsolute as isAbsolute16, join as join31, normalize as normalize3, resolve as resolve17 } from "node:path";
89704
+ import { basename as basename8, extname as extname2, isAbsolute as isAbsolute16, join as join33, normalize as normalize3, resolve as resolve17 } from "node:path";
89635
89705
  import { fileURLToPath as fileURLToPath2 } from "node:url";
89636
89706
  function requestedPath(value) {
89637
89707
  if (value.includes("\0")) {
@@ -89655,7 +89725,7 @@ async function resolveFile(value, workingDirectory, signal) {
89655
89725
  if (isAbsolute16(requested.path) && normalize3(requested.path) !== requested.path) {
89656
89726
  return null;
89657
89727
  }
89658
- const candidates = requested.explicitUrl || workingDirectory === null ? [requested.path] : isAbsolute16(requested.path) ? [join31(workingDirectory, requested.path), requested.path] : [resolve17(workingDirectory, requested.path)];
89728
+ const candidates = requested.explicitUrl || workingDirectory === null ? [requested.path] : isAbsolute16(requested.path) ? [join33(workingDirectory, requested.path), requested.path] : [resolve17(workingDirectory, requested.path)];
89659
89729
  for (const candidate of candidates) {
89660
89730
  if (!isAbsolute16(candidate) || normalize3(candidate) !== candidate) {
89661
89731
  continue;