@moxt-ai/mobius 0.0.328 → 0.0.331

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 (92) hide show
  1. package/dist/acp/adapter/pi/agent-connection.d.ts.map +1 -1
  2. package/dist/acp/adapter/pi/agent-connection.js +5 -0
  3. package/dist/acp/adapter/pi/agent-connection.js.map +1 -1
  4. package/dist/acp/harness/pi/endpoint.d.ts +1 -0
  5. package/dist/acp/harness/pi/endpoint.d.ts.map +1 -1
  6. package/dist/acp/harness/pi/endpoint.js +1 -1
  7. package/dist/acp/harness/pi/endpoint.js.map +1 -1
  8. package/dist/cli.js +377 -243
  9. package/dist/cli.js.map +4 -4
  10. package/dist/daemon/control/local-client.d.ts +3 -2
  11. package/dist/daemon/control/local-client.d.ts.map +1 -1
  12. package/dist/daemon/control/local-client.js.map +1 -1
  13. package/dist/daemon/control/local-server.d.ts +2 -1
  14. package/dist/daemon/control/local-server.d.ts.map +1 -1
  15. package/dist/daemon/control/local-server.js.map +1 -1
  16. package/dist/daemon/control/switch-status.d.ts +2 -1
  17. package/dist/daemon/control/switch-status.d.ts.map +1 -1
  18. package/dist/daemon/control/switch-status.js.map +1 -1
  19. package/dist/daemon/lifecycle/manager-client.d.ts +4 -3
  20. package/dist/daemon/lifecycle/manager-client.d.ts.map +1 -1
  21. package/dist/daemon/lifecycle/manager-client.js.map +1 -1
  22. package/dist/daemon/lifecycle/manager.d.ts +2 -1
  23. package/dist/daemon/lifecycle/manager.d.ts.map +1 -1
  24. package/dist/daemon/lifecycle/manager.js.map +1 -1
  25. package/dist/daemon/lifecycle/unhandled-rejection.d.ts +2 -1
  26. package/dist/daemon/lifecycle/unhandled-rejection.d.ts.map +1 -1
  27. package/dist/daemon/lifecycle/unhandled-rejection.js.map +1 -1
  28. package/dist/daemon/lifecycle/worker-lifecycle-log.d.ts +2 -1
  29. package/dist/daemon/lifecycle/worker-lifecycle-log.d.ts.map +1 -1
  30. package/dist/daemon/lifecycle/worker-lifecycle-log.js.map +1 -1
  31. package/dist/daemon/lifecycle/worker.d.ts +2 -1
  32. package/dist/daemon/lifecycle/worker.d.ts.map +1 -1
  33. package/dist/daemon/lifecycle/worker.js.map +1 -1
  34. package/dist/daemon/upgrades/data.d.ts +2 -1
  35. package/dist/daemon/upgrades/data.d.ts.map +1 -1
  36. package/dist/daemon/upgrades/data.js +17 -6
  37. package/dist/daemon/upgrades/data.js.map +1 -1
  38. package/dist/daemon/upgrades/upgrade.d.ts +3 -2
  39. package/dist/daemon/upgrades/upgrade.d.ts.map +1 -1
  40. package/dist/daemon/upgrades/upgrade.js.map +1 -1
  41. package/dist/runtime/command/registry/index.d.ts.map +1 -1
  42. package/dist/runtime/command/registry/index.js +2 -1
  43. package/dist/runtime/command/registry/index.js.map +1 -1
  44. package/dist/runtime/command/registry/interactions.d.ts +1 -0
  45. package/dist/runtime/command/registry/interactions.d.ts.map +1 -1
  46. package/dist/runtime/command/registry/interactions.js +28 -1
  47. package/dist/runtime/command/registry/interactions.js.map +1 -1
  48. package/dist/runtime/command/registry/session.d.ts +1 -1
  49. package/dist/runtime/command/registry/session.d.ts.map +1 -1
  50. package/dist/runtime/command/registry/session.js +14 -3
  51. package/dist/runtime/command/registry/session.js.map +1 -1
  52. package/dist/runtime/connection/runtime-installation-store.d.ts +2 -1
  53. package/dist/runtime/connection/runtime-installation-store.d.ts.map +1 -1
  54. package/dist/runtime/connection/runtime-installation-store.js.map +1 -1
  55. package/dist/runtime.js +163 -58
  56. package/dist/runtime.js.map +3 -3
  57. package/dist/session/manager/session-manager.d.ts +5 -5
  58. package/dist/session/manager/session-manager.d.ts.map +1 -1
  59. package/dist/session/manager/session-manager.js +10 -12
  60. package/dist/session/manager/session-manager.js.map +1 -1
  61. package/dist/session/prompt/apply-session-configuration.d.ts +0 -1
  62. package/dist/session/prompt/apply-session-configuration.d.ts.map +1 -1
  63. package/dist/session/prompt/apply-session-configuration.js +1 -1
  64. package/dist/session/prompt/apply-session-configuration.js.map +1 -1
  65. package/dist/session/prompt/execute-prompt.d.ts.map +1 -1
  66. package/dist/session/prompt/execute-prompt.js +9 -13
  67. package/dist/session/prompt/execute-prompt.js.map +1 -1
  68. package/dist/session/prompt/prompt-lifecycle.d.ts.map +1 -1
  69. package/dist/session/prompt/prompt-lifecycle.js +5 -0
  70. package/dist/session/prompt/prompt-lifecycle.js.map +1 -1
  71. package/dist/session/turn/execution-receipts.d.ts +2 -0
  72. package/dist/session/turn/execution-receipts.d.ts.map +1 -1
  73. package/dist/session/turn/execution-receipts.js +29 -1
  74. package/dist/session/turn/execution-receipts.js.map +1 -1
  75. package/dist/storage/daemon/control-token.d.ts +2 -1
  76. package/dist/storage/daemon/control-token.d.ts.map +1 -1
  77. package/dist/storage/daemon/control-token.js.map +1 -1
  78. package/dist/storage/daemon/manager-lock.d.ts +3 -2
  79. package/dist/storage/daemon/manager-lock.d.ts.map +1 -1
  80. package/dist/storage/daemon/manager-lock.js.map +1 -1
  81. package/dist/storage/daemon/version-data.d.ts +6 -5
  82. package/dist/storage/daemon/version-data.d.ts.map +1 -1
  83. package/dist/storage/daemon/version-data.js.map +1 -1
  84. package/dist/storage/installation/installation-files.d.ts +6 -1
  85. package/dist/storage/installation/installation-files.d.ts.map +1 -1
  86. package/dist/storage/installation/installation-files.js +3 -1
  87. package/dist/storage/installation/installation-files.js.map +1 -1
  88. package/dist/storage/state-directory.d.ts +9 -1
  89. package/dist/storage/state-directory.d.ts.map +1 -1
  90. package/dist/storage/state-directory.js +3 -4
  91. package/dist/storage/state-directory.js.map +1 -1
  92. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -2086,7 +2086,7 @@ var init_package = __esm({
2086
2086
  "package.json"() {
2087
2087
  package_default = {
2088
2088
  name: "@moxt-ai/mobius",
2089
- version: "0.0.328",
2089
+ version: "0.0.331",
2090
2090
  description: "Mobius CLI for pairing and running local AI agent services.",
2091
2091
  type: "module",
2092
2092
  bin: {
@@ -5605,182 +5605,6 @@ var init_commander = __esm({
5605
5605
  }
5606
5606
  });
5607
5607
 
5608
- // src/util/node-error.ts
5609
- function isNodeError(error62, code) {
5610
- return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === code;
5611
- }
5612
- var init_node_error = __esm({
5613
- "src/util/node-error.ts"() {
5614
- "use strict";
5615
- }
5616
- });
5617
-
5618
- // src/storage/state-root-layout.ts
5619
- var STATE_ROOT_LAYOUT, STATE_ROOT_ENTRY_NAMES;
5620
- var init_state_root_layout = __esm({
5621
- "src/storage/state-root-layout.ts"() {
5622
- "use strict";
5623
- STATE_ROOT_LAYOUT = Object.freeze({
5624
- /** Names the version whose data is current. */
5625
- currentData: "current-data.txt",
5626
- /** Applications' installations: `installations/<application>/<installation>`. */
5627
- installations: "installations",
5628
- /** Managed CLI releases: `npm/<version>`. */
5629
- releases: "npm",
5630
- /** Each CLI version's data: `versions/<version>`. */
5631
- versions: "versions"
5632
- });
5633
- STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
5634
- }
5635
- });
5636
-
5637
- // src/storage/installation/installation-files.ts
5638
- import { createHash, randomUUID } from "node:crypto";
5639
- import { mkdir, open, readdir, rename, unlink, writeFile } from "node:fs/promises";
5640
- import { dirname, join } from "node:path";
5641
- function applicationDirectory(root, applicationId) {
5642
- return join(root, STATE_ROOT_LAYOUT.installations, applicationId);
5643
- }
5644
- function installationPointerPath(applicationDirectory2) {
5645
- return join(applicationDirectory2, "current.json");
5646
- }
5647
- function installationDirectory(applicationDirectory2, installationId2) {
5648
- return join(applicationDirectory2, installationId2);
5649
- }
5650
- function connectionDirectory(installationDirectory2) {
5651
- return join(installationDirectory2, "connections");
5652
- }
5653
- function connectionFilePath(connectionDirectory2, connectionId2) {
5654
- return join(connectionDirectory2, `${connectionId2}.json`);
5655
- }
5656
- function channelIndexFilePath(installationDirectory2, channelId) {
5657
- return join(installationDirectory2, "channels", `mci_${createHash("sha256").update(channelId).digest("hex")}.json`);
5658
- }
5659
- async function readInstallationFile(path8) {
5660
- let handle;
5661
- try {
5662
- handle = await open(path8, "r");
5663
- } catch (cause) {
5664
- return isNodeError(cause, "ENOENT") ? { kind: "missing", cause } : { kind: "unopenable", cause };
5665
- }
5666
- try {
5667
- const metadata = await handle.stat();
5668
- if (!metadata.isFile() || metadata.size > MAXIMUM_FILE_BYTES) {
5669
- return { kind: "not-a-small-file" };
5670
- }
5671
- return { kind: "read", text: await handle.readFile({ encoding: "utf8" }) };
5672
- } finally {
5673
- await handle.close();
5674
- }
5675
- }
5676
- async function writeInstallationFile(path8, text2, signal) {
5677
- signal.throwIfAborted();
5678
- const directory = dirname(path8);
5679
- const temporaryPath = join(directory, `.${randomUUID()}.tmp`);
5680
- try {
5681
- await mkdir(directory, { mode: 448, recursive: true });
5682
- signal.throwIfAborted();
5683
- await writeFile(temporaryPath, text2, { flag: "wx", mode: 384 });
5684
- signal.throwIfAborted();
5685
- await rename(temporaryPath, path8);
5686
- } catch (cause) {
5687
- await unlink(temporaryPath).catch(() => void 0);
5688
- throw cause;
5689
- }
5690
- }
5691
- async function createInstallationFile(path8, text2) {
5692
- await writeFile(path8, text2, { flag: "wx", mode: 384 });
5693
- }
5694
- async function listInstallationFiles(directory) {
5695
- return await readdir(directory);
5696
- }
5697
- async function removeInstallationFile(path8) {
5698
- await unlink(path8);
5699
- }
5700
- var MAXIMUM_FILE_BYTES;
5701
- var init_installation_files = __esm({
5702
- "src/storage/installation/installation-files.ts"() {
5703
- "use strict";
5704
- init_node_error();
5705
- init_state_root_layout();
5706
- MAXIMUM_FILE_BYTES = 16 * 1024;
5707
- }
5708
- });
5709
-
5710
- // src/storage/state-directory.ts
5711
- import { homedir } from "node:os";
5712
- import { join as join2, resolve } from "node:path";
5713
- function readStateDirectory(environment = process.env) {
5714
- const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
5715
- if (configured !== void 0 && configured.length > 0) {
5716
- return resolve(configured);
5717
- }
5718
- return join2(homedir(), ".mobius");
5719
- }
5720
- var init_state_directory = __esm({
5721
- "src/storage/state-directory.ts"() {
5722
- "use strict";
5723
- }
5724
- });
5725
-
5726
- // src/storage/state-root.ts
5727
- import { readFile, stat } from "node:fs/promises";
5728
- import { basename, dirname as dirname2, join as join3 } from "node:path";
5729
- async function exists(path8) {
5730
- return await stat(path8).then(
5731
- () => true,
5732
- () => false
5733
- );
5734
- }
5735
- async function owningRoot(directory) {
5736
- const application = dirname2(directory);
5737
- const installations = dirname2(application);
5738
- if (basename(installations) !== STATE_ROOT_LAYOUT.installations) {
5739
- return null;
5740
- }
5741
- let pointer;
5742
- try {
5743
- pointer = JSON.parse(await readFile(installationPointerPath(application), "utf8"));
5744
- } catch {
5745
- return null;
5746
- }
5747
- if (typeof pointer !== "object" || pointer === null || !("installationId" in pointer) || pointer.installationId !== basename(directory)) {
5748
- return null;
5749
- }
5750
- const container = dirname2(installations);
5751
- return basename(dirname2(container)) === STATE_ROOT_LAYOUT.versions ? dirname2(dirname2(container)) : container;
5752
- }
5753
- async function validateStateRoot(environment) {
5754
- const directory = readStateDirectory(environment);
5755
- if (await exists(join3(directory, STATE_ROOT_LAYOUT.currentData)) || await exists(join3(directory, STATE_ROOT_LAYOUT.versions))) {
5756
- return;
5757
- }
5758
- const root = await owningRoot(directory);
5759
- if (root !== null) {
5760
- throw new StateRootError(directory, root);
5761
- }
5762
- }
5763
- var StateRootError;
5764
- var init_state_root = __esm({
5765
- "src/storage/state-root.ts"() {
5766
- "use strict";
5767
- init_installation_files();
5768
- init_state_directory();
5769
- init_state_root_layout();
5770
- StateRootError = class extends Error {
5771
- code = "state_root_is_installation_data";
5772
- owningRoot;
5773
- constructor(stateDirectory, owningRoot2) {
5774
- super(
5775
- `MOBIUS_STATE_DIRECTORY (${stateDirectory}) is Mobius installation data, not a state root. Use the state root that owns it: MOBIUS_STATE_DIRECTORY=${owningRoot2}`
5776
- );
5777
- this.name = "StateRootError";
5778
- this.owningRoot = owningRoot2;
5779
- }
5780
- };
5781
- }
5782
- });
5783
-
5784
5608
  // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/util.js
5785
5609
  var util_exports = {};
5786
5610
  __export(util_exports, {
@@ -10432,7 +10256,7 @@ function isBackEdge(ctx, value) {
10432
10256
  const backEdges = ctx[STATE]?.backEdges;
10433
10257
  return backEdges !== void 0 && isRef(value) && backEdges.has(value);
10434
10258
  }
10435
- var $ZodCyclicError, STATE, NO_ISSUES, recursive, NONE, ASSUMED, PROVEN, handoff, open2, memo;
10259
+ var $ZodCyclicError, STATE, NO_ISSUES, recursive, NONE, ASSUMED, PROVEN, handoff, open, memo;
10436
10260
  var init_memoizer = __esm({
10437
10261
  "../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/memoizer.js"() {
10438
10262
  init_util();
@@ -10448,7 +10272,7 @@ var init_memoizer = __esm({
10448
10272
  NONE = 0;
10449
10273
  ASSUMED = 1;
10450
10274
  PROVEN = 2;
10451
- open2 = [];
10275
+ open = [];
10452
10276
  memo = {
10453
10277
  alloc(_inst, payload, empty) {
10454
10278
  const bucket = handoff;
@@ -10457,7 +10281,7 @@ var init_memoizer = __esm({
10457
10281
  handoff = void 0;
10458
10282
  const entry = { value: empty, issues: null };
10459
10283
  bucket.set(payload.value, entry);
10460
- open2.push(entry);
10284
+ open.push(entry);
10461
10285
  return empty;
10462
10286
  },
10463
10287
  guard(inst) {
@@ -10528,10 +10352,10 @@ var init_memoizer = __esm({
10528
10352
  return payload;
10529
10353
  }
10530
10354
  handoff = bucket;
10531
- const depth = open2.length;
10355
+ const depth = open.length;
10532
10356
  const result = base(payload, ctx);
10533
10357
  handoff = void 0;
10534
- const entry = open2.length > depth ? open2.pop() : void 0;
10358
+ const entry = open.length > depth ? open.pop() : void 0;
10535
10359
  if (result instanceof Promise) {
10536
10360
  return result.then((r) => {
10537
10361
  if (entry)
@@ -26140,6 +25964,186 @@ var init_zod = __esm({
26140
25964
  }
26141
25965
  });
26142
25966
 
25967
+ // src/util/node-error.ts
25968
+ function isNodeError(error62, code) {
25969
+ return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === code;
25970
+ }
25971
+ var init_node_error = __esm({
25972
+ "src/util/node-error.ts"() {
25973
+ "use strict";
25974
+ }
25975
+ });
25976
+
25977
+ // src/storage/state-root-layout.ts
25978
+ var STATE_ROOT_LAYOUT, STATE_ROOT_ENTRY_NAMES;
25979
+ var init_state_root_layout = __esm({
25980
+ "src/storage/state-root-layout.ts"() {
25981
+ "use strict";
25982
+ STATE_ROOT_LAYOUT = Object.freeze({
25983
+ /** Names the version whose data is current. */
25984
+ currentData: "current-data.txt",
25985
+ /** Applications' installations: `installations/<application>/<installation>`. */
25986
+ installations: "installations",
25987
+ /** Managed CLI releases: `npm/<version>`. */
25988
+ releases: "npm",
25989
+ /** Each CLI version's data: `versions/<version>`. */
25990
+ versions: "versions"
25991
+ });
25992
+ STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
25993
+ }
25994
+ });
25995
+
25996
+ // src/storage/installation/installation-files.ts
25997
+ import { createHash, randomUUID } from "node:crypto";
25998
+ import { mkdir, open as open2, readdir, rename, unlink, writeFile } from "node:fs/promises";
25999
+ import { dirname, join } from "node:path";
26000
+ function applicationDirectory(root, applicationId) {
26001
+ return join(root, STATE_ROOT_LAYOUT.installations, applicationId);
26002
+ }
26003
+ function installationPointerPath(applicationDirectory2) {
26004
+ return join(applicationDirectory2, "current.json");
26005
+ }
26006
+ function installationDirectory(applicationDirectory2, installationId2) {
26007
+ return installationDirectorySchema.parse(join(applicationDirectory2, installationId2));
26008
+ }
26009
+ function connectionDirectory(installationDirectory2) {
26010
+ return join(installationDirectory2, "connections");
26011
+ }
26012
+ function connectionFilePath(connectionDirectory2, connectionId2) {
26013
+ return join(connectionDirectory2, `${connectionId2}.json`);
26014
+ }
26015
+ function channelIndexFilePath(installationDirectory2, channelId) {
26016
+ return join(installationDirectory2, "channels", `mci_${createHash("sha256").update(channelId).digest("hex")}.json`);
26017
+ }
26018
+ async function readInstallationFile(path8) {
26019
+ let handle;
26020
+ try {
26021
+ handle = await open2(path8, "r");
26022
+ } catch (cause) {
26023
+ return isNodeError(cause, "ENOENT") ? { kind: "missing", cause } : { kind: "unopenable", cause };
26024
+ }
26025
+ try {
26026
+ const metadata = await handle.stat();
26027
+ if (!metadata.isFile() || metadata.size > MAXIMUM_FILE_BYTES) {
26028
+ return { kind: "not-a-small-file" };
26029
+ }
26030
+ return { kind: "read", text: await handle.readFile({ encoding: "utf8" }) };
26031
+ } finally {
26032
+ await handle.close();
26033
+ }
26034
+ }
26035
+ async function writeInstallationFile(path8, text2, signal) {
26036
+ signal.throwIfAborted();
26037
+ const directory = dirname(path8);
26038
+ const temporaryPath = join(directory, `.${randomUUID()}.tmp`);
26039
+ try {
26040
+ await mkdir(directory, { mode: 448, recursive: true });
26041
+ signal.throwIfAborted();
26042
+ await writeFile(temporaryPath, text2, { flag: "wx", mode: 384 });
26043
+ signal.throwIfAborted();
26044
+ await rename(temporaryPath, path8);
26045
+ } catch (cause) {
26046
+ await unlink(temporaryPath).catch(() => void 0);
26047
+ throw cause;
26048
+ }
26049
+ }
26050
+ async function createInstallationFile(path8, text2) {
26051
+ await writeFile(path8, text2, { flag: "wx", mode: 384 });
26052
+ }
26053
+ async function listInstallationFiles(directory) {
26054
+ return await readdir(directory);
26055
+ }
26056
+ async function removeInstallationFile(path8) {
26057
+ await unlink(path8);
26058
+ }
26059
+ var MAXIMUM_FILE_BYTES, installationDirectorySchema;
26060
+ var init_installation_files = __esm({
26061
+ "src/storage/installation/installation-files.ts"() {
26062
+ "use strict";
26063
+ init_zod();
26064
+ init_node_error();
26065
+ init_state_root_layout();
26066
+ MAXIMUM_FILE_BYTES = 16 * 1024;
26067
+ installationDirectorySchema = external_exports.string().brand();
26068
+ }
26069
+ });
26070
+
26071
+ // src/storage/state-directory.ts
26072
+ import { homedir } from "node:os";
26073
+ import { join as join2, resolve } from "node:path";
26074
+ function readStateDirectory(environment = process.env) {
26075
+ const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
26076
+ return stateRootSchema.parse(
26077
+ configured !== void 0 && configured.length > 0 ? resolve(configured) : join2(homedir(), ".mobius")
26078
+ );
26079
+ }
26080
+ var stateRootSchema;
26081
+ var init_state_directory = __esm({
26082
+ "src/storage/state-directory.ts"() {
26083
+ "use strict";
26084
+ init_zod();
26085
+ stateRootSchema = external_exports.string().brand();
26086
+ }
26087
+ });
26088
+
26089
+ // src/storage/state-root.ts
26090
+ import { readFile, stat } from "node:fs/promises";
26091
+ import { basename, dirname as dirname2, join as join3 } from "node:path";
26092
+ async function exists(path8) {
26093
+ return await stat(path8).then(
26094
+ () => true,
26095
+ () => false
26096
+ );
26097
+ }
26098
+ async function owningRoot(directory) {
26099
+ const application = dirname2(directory);
26100
+ const installations = dirname2(application);
26101
+ if (basename(installations) !== STATE_ROOT_LAYOUT.installations) {
26102
+ return null;
26103
+ }
26104
+ let pointer;
26105
+ try {
26106
+ pointer = JSON.parse(await readFile(installationPointerPath(application), "utf8"));
26107
+ } catch {
26108
+ return null;
26109
+ }
26110
+ if (typeof pointer !== "object" || pointer === null || !("installationId" in pointer) || pointer.installationId !== basename(directory)) {
26111
+ return null;
26112
+ }
26113
+ const container = dirname2(installations);
26114
+ return basename(dirname2(container)) === STATE_ROOT_LAYOUT.versions ? dirname2(dirname2(container)) : container;
26115
+ }
26116
+ async function validateStateRoot(environment) {
26117
+ const directory = readStateDirectory(environment);
26118
+ if (await exists(join3(directory, STATE_ROOT_LAYOUT.currentData)) || await exists(join3(directory, STATE_ROOT_LAYOUT.versions))) {
26119
+ return;
26120
+ }
26121
+ const root = await owningRoot(directory);
26122
+ if (root !== null) {
26123
+ throw new StateRootError(directory, root);
26124
+ }
26125
+ }
26126
+ var StateRootError;
26127
+ var init_state_root = __esm({
26128
+ "src/storage/state-root.ts"() {
26129
+ "use strict";
26130
+ init_installation_files();
26131
+ init_state_directory();
26132
+ init_state_root_layout();
26133
+ StateRootError = class extends Error {
26134
+ code = "state_root_is_installation_data";
26135
+ owningRoot;
26136
+ constructor(stateDirectory, owningRoot2) {
26137
+ super(
26138
+ `MOBIUS_STATE_DIRECTORY (${stateDirectory}) is Mobius installation data, not a state root. Use the state root that owns it: MOBIUS_STATE_DIRECTORY=${owningRoot2}`
26139
+ );
26140
+ this.name = "StateRootError";
26141
+ this.owningRoot = owningRoot2;
26142
+ }
26143
+ };
26144
+ }
26145
+ });
26146
+
26143
26147
  // src/util/value-utils.ts
26144
26148
  function truncate(value, maximumLength) {
26145
26149
  return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
@@ -74997,6 +75001,15 @@ var init_lifecycle = __esm({
74997
75001
  });
74998
75002
 
74999
75003
  // ../mobius-sdk/src/protocol/session/prompt/commands.ts
75004
+ function decodeSessionCancelBeforeStartCommand(encoded) {
75005
+ const value = parseJson(encoded);
75006
+ assertKind(value, SESSION_CANCEL_BEFORE_START_KIND);
75007
+ return {
75008
+ commandId: readIdentifier(value, "commandId"),
75009
+ kind: SESSION_CANCEL_BEFORE_START_KIND,
75010
+ sessionId: readIdentifier(value, "sessionId")
75011
+ };
75012
+ }
75000
75013
  function readPromptDisposition(value) {
75001
75014
  const field = value["disposition"];
75002
75015
  if (field === void 0 || field === SessionPromptDisposition.Reject) {
@@ -75097,7 +75110,7 @@ function encodeSessionCancelCommand(message) {
75097
75110
  function encodeSessionPromptDispositionCommand(message) {
75098
75111
  return JSON.stringify(decodeSessionPromptDispositionCommand(JSON.stringify(message)));
75099
75112
  }
75100
- var SESSION_PROMPT_KIND, SESSION_PROMPT_DISPOSITION_KIND, SESSION_CANCEL_KIND, SessionPromptDisposition, SessionHistoryPolicy, MAX_PROMPT_LENGTH, MAX_PROMPT_ATTACHMENT_BYTES, promptAttachmentSchema, decodePromptAttachmentsValue;
75113
+ var SESSION_PROMPT_KIND, SESSION_PROMPT_DISPOSITION_KIND, SESSION_CANCEL_KIND, SESSION_CANCEL_BEFORE_START_KIND, SessionPromptDisposition, SessionHistoryPolicy, MAX_PROMPT_LENGTH, MAX_PROMPT_ATTACHMENT_BYTES, encodeSessionCancelBeforeStartCommand, promptAttachmentSchema, decodePromptAttachmentsValue;
75101
75114
  var init_commands = __esm({
75102
75115
  "../mobius-sdk/src/protocol/session/prompt/commands.ts"() {
75103
75116
  "use strict";
@@ -75108,6 +75121,7 @@ var init_commands = __esm({
75108
75121
  SESSION_PROMPT_KIND = "session.prompt";
75109
75122
  SESSION_PROMPT_DISPOSITION_KIND = "session.prompt.disposition";
75110
75123
  SESSION_CANCEL_KIND = "session.cancel";
75124
+ SESSION_CANCEL_BEFORE_START_KIND = "session.cancel-before-start";
75111
75125
  SessionPromptDisposition = Object.freeze({
75112
75126
  Queue: "queue",
75113
75127
  Reject: "reject",
@@ -75119,6 +75133,7 @@ var init_commands = __esm({
75119
75133
  });
75120
75134
  MAX_PROMPT_LENGTH = 1e5;
75121
75135
  MAX_PROMPT_ATTACHMENT_BYTES = 32 * 1024 * 1024;
75136
+ encodeSessionCancelBeforeStartCommand = (message) => JSON.stringify(decodeSessionCancelBeforeStartCommand(JSON.stringify(message)));
75122
75137
  promptAttachmentSchema = external_exports.object({
75123
75138
  byteLength: external_exports.number().int().positive().max(MAX_PROMPT_ATTACHMENT_BYTES),
75124
75139
  contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
@@ -75868,7 +75883,7 @@ var init_recording = __esm({
75868
75883
  });
75869
75884
 
75870
75885
  // ../mobius-sdk/src/protocol/session/recording/turn-history.ts
75871
- var SESSION_RECORDING_TURN_PAGE_DECODE_MAX_ELEMENTS, SESSION_RECORDING_TURN_ITEM_ID_MAX_LENGTH, isoTimestamp, shortText, itemText, turnCursorSchema, turnItemCursorSchema, attemptTiming, promptSucceededOutcome, promptCancelledOutcome, promptFailedOutcome, sessionRecordingTurnAttemptSchema, turnItemBase, textItemFields, sessionRecordingToolDetailSchema, sessionRecordingTurnItemSchema, sessionRecordingTurnPromptSchema, sessionRecordingTurnPrecedingSchema, sessionRecordingTurnSchema, sessionRecordingInteractionSchema, sessionRecordingTurnPageSchema, sessionRecordingTurnItemPageSchema, sessionRecordingTurnItemDetailSchema;
75886
+ var SESSION_RECORDING_TURN_PAGE_DECODE_MAX_ELEMENTS, SESSION_RECORDING_TURN_ITEM_ID_MAX_LENGTH, isoTimestamp, shortText, itemText, turnCursorSchema, turnItemCursorSchema, attemptTiming, promptSucceededOutcome, promptCancelledOutcome, promptFailedOutcome, sessionRecordingTurnAttemptSchema, turnItemBase, textItemFields, sessionRecordingToolDetailSchema, sessionRecordingTurnItemSchema, sessionRecordingTurnPromptSchema, sessionRecordingTurnPrecedingSchema, sessionRecordingTurnSchema, sessionRecordingInteractionSchema, SESSION_RECORDING_EXECUTION_COMMAND_MAX_LIMIT, recordingActiveCommandsSchema, sessionRecordingExecutionSchema, sessionRecordingTurnPageSchema, sessionRecordingTurnItemPageSchema, sessionRecordingTurnItemDetailSchema;
75872
75887
  var init_turn_history = __esm({
75873
75888
  "../mobius-sdk/src/protocol/session/recording/turn-history.ts"() {
75874
75889
  "use strict";
@@ -75995,6 +76010,24 @@ var init_turn_history = __esm({
75995
76010
  kind: external_exports.literal("elicitation")
75996
76011
  }).readonly()
75997
76012
  ]);
76013
+ SESSION_RECORDING_EXECUTION_COMMAND_MAX_LIMIT = 100;
76014
+ recordingActiveCommandsSchema = external_exports.object({
76015
+ commandIds: external_exports.array(identifierStringSchema).max(1e3).readonly(),
76016
+ generationId: identifierStringSchema
76017
+ }).readonly().nullable();
76018
+ sessionRecordingExecutionSchema = external_exports.object({
76019
+ activeCommands: recordingActiveCommandsSchema,
76020
+ commands: external_exports.array(
76021
+ external_exports.object({
76022
+ attempt: sessionRecordingTurnAttemptSchema,
76023
+ commandId: identifierStringSchema,
76024
+ generationId: identifierStringSchema
76025
+ }).readonly()
76026
+ ).max(SESSION_RECORDING_EXECUTION_COMMAND_MAX_LIMIT).readonly(),
76027
+ sessionId: identifierStringSchema,
76028
+ tailCursor: recordingCursorSchema,
76029
+ version: external_exports.literal(1)
76030
+ }).readonly();
75998
76031
  sessionRecordingTurnPageSchema = external_exports.object({
75999
76032
  // Commands that own Agent output in the newest Session generation, innermost last.
76000
76033
  activeCommands: external_exports.object({
@@ -76289,6 +76322,11 @@ var init_daemon_transport = __esm({
76289
76322
  decodeRuntimeDiagnosticsRequest
76290
76323
  ),
76291
76324
  [RUNTIME_PING_KIND]: defineMessageSignature(RUNTIME_PING_KIND, encodeRuntimePingCommand, decodeRuntimePingCommand),
76325
+ [SESSION_CANCEL_BEFORE_START_KIND]: defineMessageSignature(
76326
+ SESSION_CANCEL_BEFORE_START_KIND,
76327
+ encodeSessionCancelBeforeStartCommand,
76328
+ decodeSessionCancelBeforeStartCommand
76329
+ ),
76292
76330
  [SESSION_CANCEL_KIND]: defineMessageSignature(
76293
76331
  SESSION_CANCEL_KIND,
76294
76332
  encodeSessionCancelCommand,
@@ -80348,6 +80386,7 @@ var init_agent2 = __esm({
80348
80386
  }
80349
80387
  async promptSubmission(params, submission) {
80350
80388
  const session = await this.restoreSession(params.sessionId);
80389
+ this.conn.startUserMessage();
80351
80390
  for (const content of params.prompt) {
80352
80391
  if (submission.aborted) {
80353
80392
  return { stopReason: "cancelled" };
@@ -80807,6 +80846,7 @@ ${JSON.stringify(stats, null, 2)}`;
80807
80846
  case "idle":
80808
80847
  return { outcome: "promptRequired", reason: "noRunningTurn" };
80809
80848
  case "injected": {
80849
+ this.conn.startUserMessage();
80810
80850
  for (const content of parsed.data.prompt) {
80811
80851
  signal.throwIfAborted();
80812
80852
  await this.conn.sessionUpdate({
@@ -81201,11 +81241,12 @@ ${JSON.stringify(stats, null, 2)}`;
81201
81241
 
81202
81242
  // src/acp/harness/pi/upstream/dist/acp/client.js
81203
81243
  import { methods as methods5 } from "@agentclientprotocol/sdk";
81204
- function createPiAcpClient(connection, onSessionUpdate) {
81244
+ function createPiAcpClient(connection, onSessionUpdate, onUserMessageStart = () => void 0) {
81205
81245
  return {
81206
81246
  requestElicitation: async (request, signal) => await connection.client.request(methods5.client.elicitation.create, request, { cancellationSignal: signal }),
81207
81247
  requestPermission: async (request) => await connection.client.request(methods5.client.session.requestPermission, request),
81208
- sessionUpdate: onSessionUpdate
81248
+ sessionUpdate: onSessionUpdate,
81249
+ startUserMessage: onUserMessageStart
81209
81250
  };
81210
81251
  }
81211
81252
  var init_client = __esm({
@@ -81250,7 +81291,10 @@ var init_endpoint2 = __esm({
81250
81291
  let piAgent = null;
81251
81292
  this.#app = createAgentApp2({ name: "mobius-pi" }).onConnect((connection) => {
81252
81293
  this.#connection = connection;
81253
- piAgent = new PiAcpAgent(createPiAcpClient(connection, options.onSessionUpdate), { environment });
81294
+ piAgent = new PiAcpAgent(
81295
+ createPiAcpClient(connection, options.onSessionUpdate, options.onUserMessageStart),
81296
+ { environment }
81297
+ );
81254
81298
  this.#agent = piAgent;
81255
81299
  }).onRequest(
81256
81300
  methods6.agent.initialize,
@@ -81337,6 +81381,11 @@ var init_agent_connection3 = __esm({
81337
81381
  command: options.command,
81338
81382
  cwd: options.cwd,
81339
81383
  environment: options.environment,
81384
+ // Raw Pi owns submission boundaries, while synthetic identity stays here.
81385
+ // Adjacent blocks within one submission still share the allocated ID.
81386
+ onUserMessageStart: () => {
81387
+ message = { kind: "none" };
81388
+ },
81340
81389
  onSessionUpdate: async (notification) => {
81341
81390
  const update = notification.update;
81342
81391
  switch (update.sessionUpdate) {
@@ -92477,12 +92526,19 @@ async function prepareVersionData(version2, signal, environment = process.env, f
92477
92526
  signal.throwIfAborted();
92478
92527
  const root = readStateDirectory(environment);
92479
92528
  const targetVersion = runtimeUpgradeVersionSchema.parse(version2);
92480
- if (await versionDataExists(root, targetVersion, signal)) {
92481
- return;
92482
- }
92483
- const previous = await readCurrentDataVersion(root, signal) ?? fallbackVersion;
92484
- if (previous === null) {
92485
- return;
92529
+ const current = await readCurrentDataVersion(root, signal);
92530
+ let previous;
92531
+ if (current !== null) {
92532
+ if (current === targetVersion) {
92533
+ return;
92534
+ }
92535
+ await discardVersionData(root, targetVersion, signal);
92536
+ previous = current;
92537
+ } else {
92538
+ if (fallbackVersion === null || await versionDataExists(root, targetVersion, signal)) {
92539
+ return;
92540
+ }
92541
+ previous = fallbackVersion;
92486
92542
  }
92487
92543
  const leftBehind = await copyVersionData(root, runtimeUpgradeVersionSchema.parse(previous), targetVersion, signal);
92488
92544
  for (const entry of leftBehind) {
@@ -96215,34 +96271,18 @@ var init_session_manager = __esm({
96215
96271
  return await runtime.configure(options2);
96216
96272
  });
96217
96273
  });
96218
- renameSession = async (sessionId, title2, signal) => await this.#executionProcesses.use(
96219
- sessionId,
96220
- async () => this.#operations.run({ sessionId, signal }, async (options) => {
96221
- this.#assertOpen(options.sessionId);
96222
- const runtime = this.#executionProcesses.get(options.sessionId);
96223
- if (runtime !== void 0) {
96224
- return await runtime.renameSession(title2, options.signal);
96225
- }
96226
- const stored = this.#store.read(options.sessionId);
96227
- if (!(stored instanceof FoundStoredSession)) {
96228
- throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
96229
- }
96230
- const normalized = title2.slice(0, 500);
96231
- const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
96232
- this.#store.write(
96233
- new StoredSession(
96234
- stored.session.sessionId,
96235
- stored.session.agentId,
96236
- stored.session.nativeSessionId,
96237
- stored.session.cwd,
96238
- stored.session.additionalDirectories,
96239
- stored.session.prompted,
96240
- normalized,
96241
- updatedAt,
96242
- stored.session.configurations
96243
- )
96244
- );
96245
- return { title: normalized, updatedAt };
96274
+ renameSession = async (options, title2) => await this.#executionProcesses.use(
96275
+ options.sessionId,
96276
+ async () => this.#operations.run(options, async (options2) => {
96277
+ this.#assertOpen(options2.sessionId);
96278
+ if (this.#executionProcesses.get(options2.sessionId) === void 0) {
96279
+ await this.#prepareSession(options2, { kind: "interactive-only" }, "keep-closed");
96280
+ }
96281
+ const runtime = this.#executionProcesses.get(options2.sessionId);
96282
+ if (runtime === void 0) {
96283
+ throw new AcpExecutionError("ACP session did not start");
96284
+ }
96285
+ return await runtime.renameSession(title2, options2.signal);
96246
96286
  })
96247
96287
  );
96248
96288
  cancelPrompt = async (sessionId, signal = AbortSignal.timeout(3e4)) => this.#operations.run({ signal }, async ({ signal: signal2 }) => {
@@ -97013,6 +97053,11 @@ function promptContent(command) {
97013
97053
  return content;
97014
97054
  }
97015
97055
  async function settleAbandonedTurn(projection, operations, cancellation) {
97056
+ const outcome = operations.recordCancellationBeforeAdmission(cancellation.commandId, cancellation.sessionId);
97057
+ if (outcome !== void 0) {
97058
+ await projection.replayOutcome(cancellation.sessionId, outcome);
97059
+ return;
97060
+ }
97016
97061
  const attemptId = operations.findUnsettledAttemptId(cancellation.commandId, cancellation.sessionId);
97017
97062
  if (attemptId === null) {
97018
97063
  console.warn("Mobius daemon ignored cancellation for an inactive turn");
@@ -97233,6 +97278,33 @@ var init_execution_receipts = __esm({
97233
97278
  const receipt = this.#executions.get(commandId);
97234
97279
  return receipt?.outcome === null || receipt === void 0 ? void 0 : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
97235
97280
  };
97281
+ /** Reserves an unseen command for cancellation before a delayed prompt can claim its identity. */
97282
+ recordCancellationBeforeAdmission = (commandId, sessionId) => {
97283
+ const existing = this.#executions.get(commandId);
97284
+ if (existing !== void 0) {
97285
+ return existing.sessionId === sessionId && isTerminal(existing.state) ? this.outcome(commandId) : void 0;
97286
+ }
97287
+ const outcome = {
97288
+ type: "lifecycle-metadata",
97289
+ payload: { kind: "prompt.completed", commandId, stopReason: "cancelled" }
97290
+ };
97291
+ const commandHash = createHash7("sha256").update(
97292
+ encodeSessionCancelBeforeStartCommand({
97293
+ commandId,
97294
+ kind: "session.cancel-before-start",
97295
+ sessionId
97296
+ })
97297
+ ).digest("hex");
97298
+ this.#save(commandId, {
97299
+ attemptId: randomUUID16(),
97300
+ commandHash,
97301
+ sessionId,
97302
+ state: "cancelled",
97303
+ started: false,
97304
+ outcome: JSON.stringify({ ...outcome, recordedAt: (/* @__PURE__ */ new Date()).toISOString() })
97305
+ });
97306
+ return outcome;
97307
+ };
97236
97308
  recordOutcome = (event) => {
97237
97309
  if (event.type !== "lifecycle-metadata") {
97238
97310
  return;
@@ -100045,11 +100117,12 @@ var init_history3 = __esm({
100045
100117
  });
100046
100118
 
100047
100119
  // src/runtime/command/registry/interactions.ts
100048
- var sessionCancelCommand, sessionCloseCommand, promptDispositionCommand, permissionRespondCommand, elicitationRespondCommand;
100120
+ var sessionCancelCommand, sessionCancelBeforeStartCommand, sessionCloseCommand, promptDispositionCommand, permissionRespondCommand, elicitationRespondCommand;
100049
100121
  var init_interactions2 = __esm({
100050
100122
  "src/runtime/command/registry/interactions.ts"() {
100051
100123
  "use strict";
100052
100124
  init_protocol();
100125
+ init_session_error();
100053
100126
  init_prompt_lifecycle();
100054
100127
  init_transport();
100055
100128
  sessionCancelCommand = {
@@ -100074,6 +100147,41 @@ var init_interactions2 = __esm({
100074
100147
  });
100075
100148
  }
100076
100149
  };
100150
+ sessionCancelBeforeStartCommand = {
100151
+ kind: SESSION_CANCEL_BEFORE_START_KIND,
100152
+ handle: ({ eventProjection, operations, sessionTurns, socket }, message) => {
100153
+ if (message.kind !== SESSION_CANCEL_BEFORE_START_KIND) {
100154
+ throw new Error("Command kind mismatch");
100155
+ }
100156
+ const turn = sessionTurns.get(message.commandId, message.sessionId);
100157
+ if (turn === void 0) {
100158
+ const outcome = operations.recordCancellationBeforeAdmission(message.commandId, message.sessionId);
100159
+ if (outcome !== void 0) {
100160
+ void eventProjection.replayOutcome(message.sessionId, outcome).catch((error62) => {
100161
+ reportOperationFailure(socket, message.commandId, message.sessionId, error62);
100162
+ });
100163
+ return;
100164
+ }
100165
+ reportOperationFailure(
100166
+ socket,
100167
+ message.commandId,
100168
+ message.sessionId,
100169
+ new SessionError("turn_not_active", "The command is not waiting to start")
100170
+ );
100171
+ return;
100172
+ }
100173
+ if (turn.snapshot() !== null) {
100174
+ reportOperationFailure(
100175
+ socket,
100176
+ message.commandId,
100177
+ message.sessionId,
100178
+ new SessionError("turn_already_started", "The command already started")
100179
+ );
100180
+ return;
100181
+ }
100182
+ turn.requestCancellation();
100183
+ }
100184
+ };
100077
100185
  sessionCloseCommand = {
100078
100186
  kind: SESSION_CLOSE_KIND,
100079
100187
  handle: ({ sessions, signal, socket }, message) => {
@@ -100613,24 +100721,20 @@ async function executePrompt({
100613
100721
  recovery
100614
100722
  };
100615
100723
  let prepared = await sessions.prepareExecutionSession(preparation);
100616
- if (command.sessionConfigurations !== void 0) {
100617
- if (availability.disposition === SessionPromptDisposition.Steer) {
100618
- assertAppliedSessionConfiguration(prepared.configOptions, sessionConfigurations ?? []);
100619
- } else {
100620
- await applyCompleteSessionConfiguration(
100621
- sessions,
100622
- prepared.configOptions,
100623
- sessionConfigurations ?? [],
100624
- executionAgent,
100625
- adapter,
100626
- resolved.cwd,
100627
- resolved.additionalDirectories,
100628
- command.commandId,
100629
- command.sessionId,
100630
- signal
100631
- );
100632
- prepared = await sessions.prepareExecutionSession(preparation);
100633
- }
100724
+ if (command.sessionConfigurations !== void 0 && availability.disposition !== SessionPromptDisposition.Steer) {
100725
+ await applyCompleteSessionConfiguration(
100726
+ sessions,
100727
+ prepared.configOptions,
100728
+ sessionConfigurations ?? [],
100729
+ executionAgent,
100730
+ adapter,
100731
+ resolved.cwd,
100732
+ resolved.additionalDirectories,
100733
+ command.commandId,
100734
+ command.sessionId,
100735
+ signal
100736
+ );
100737
+ prepared = await sessions.prepareExecutionSession(preparation);
100634
100738
  }
100635
100739
  operations.transitionExecution(command.commandId, "running");
100636
100740
  if (availability.disposition === SessionPromptDisposition.Steer) {
@@ -101020,9 +101124,29 @@ async function executeSessionRestore(socket, command, config2, resolveAgent, dir
101020
101124
  reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
101021
101125
  }
101022
101126
  }
101023
- async function executeSessionRename(socket, command, sessions, signal) {
101127
+ async function executeSessionRename(socket, command, config2, resolveAgent, directories, sessions, nativeSessions, signal) {
101024
101128
  try {
101025
- const renamed = await sessions.renameSession(command.sessionId, command.title, signal);
101129
+ const [entry] = await nativeSessions.querySessions([command.sessionId], signal);
101130
+ if (entry === void 0) {
101131
+ throw new SessionError("session_not_found", "The Session was not found");
101132
+ }
101133
+ const resolved = await resolveSessionDirectories(
101134
+ directories,
101135
+ config2.bindingId,
101136
+ entry.directoryId,
101137
+ entry.additionalDirectories.map((directory) => directory.directoryId),
101138
+ signal
101139
+ );
101140
+ const renamed = await sessions.renameSession(
101141
+ {
101142
+ additionalDirectories: resolved.additionalDirectories,
101143
+ ...await resolveAgent(entry.agentId, signal, command.sessionId),
101144
+ cwd: resolved.cwd,
101145
+ sessionId: command.sessionId,
101146
+ signal
101147
+ },
101148
+ command.title
101149
+ );
101026
101150
  send(socket, {
101027
101151
  kind: "session.renamed",
101028
101152
  requestId: command.requestId,
@@ -101205,7 +101329,16 @@ var init_session5 = __esm({
101205
101329
  if (message.kind !== SESSION_RENAME_KIND) {
101206
101330
  throw new Error("Command kind mismatch");
101207
101331
  }
101208
- void executeSessionRename(context.socket, message, context.sessions, context.signal);
101332
+ void executeSessionRename(
101333
+ context.socket,
101334
+ message,
101335
+ context.config,
101336
+ context.resolveAgent,
101337
+ context.directories,
101338
+ context.sessions,
101339
+ context.nativeSessions,
101340
+ context.signal
101341
+ );
101209
101342
  }
101210
101343
  };
101211
101344
  sessionConfigReadCommand = {
@@ -101243,6 +101376,7 @@ function createCommandRegistry(context) {
101243
101376
  ...createAgentSettingsCommands(context),
101244
101377
  ...contentWrites.commands,
101245
101378
  fileReadCommand,
101379
+ sessionCancelBeforeStartCommand,
101246
101380
  sessionCancelCommand,
101247
101381
  sessionCloseCommand,
101248
101382
  promptDispositionCommand,