@moxt-ai/mobius 0.0.390 → 0.0.391

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 (36) hide show
  1. package/dist/{chunk-KWRP3J26.js → chunk-4VUCI4MS.js} +2 -2
  2. package/dist/{chunk-KWRP3J26.js.map → chunk-4VUCI4MS.js.map} +1 -1
  3. package/dist/{chunk-ZW763PCS.js → chunk-TQJ2GJH7.js} +113 -22
  4. package/dist/{chunk-ZW763PCS.js.map → chunk-TQJ2GJH7.js.map} +4 -4
  5. package/dist/{cli-K2JBHPL5.js → cli-FNJ2BQAZ.js} +3 -3
  6. package/dist/cli.js +2 -2
  7. package/dist/engine/generated/command-cancellation-migrations.d.ts +5 -0
  8. package/dist/engine/generated/command-cancellation-migrations.d.ts.map +1 -0
  9. package/dist/engine/generated/command-cancellation-migrations.js +9 -0
  10. package/dist/engine/generated/command-cancellation-migrations.js.map +1 -0
  11. package/dist/engine/schema/command-cancellation/cancelled-command.d.ts +41 -0
  12. package/dist/engine/schema/command-cancellation/cancelled-command.d.ts.map +1 -0
  13. package/dist/engine/schema/command-cancellation/cancelled-command.js +7 -0
  14. package/dist/engine/schema/command-cancellation/cancelled-command.js.map +1 -0
  15. package/dist/engine/schema/command-cancellation/index.d.ts +2 -0
  16. package/dist/engine/schema/command-cancellation/index.d.ts.map +1 -0
  17. package/dist/engine/schema/command-cancellation/index.js +2 -0
  18. package/dist/engine/schema/command-cancellation/index.js.map +1 -0
  19. package/dist/engine/session/api/session-layer.d.ts.map +1 -1
  20. package/dist/engine/session/api/session-layer.js +6 -2
  21. package/dist/engine/session/api/session-layer.js.map +1 -1
  22. package/dist/engine/session/turn/execution-receipts.d.ts +2 -1
  23. package/dist/engine/session/turn/execution-receipts.d.ts.map +1 -1
  24. package/dist/engine/session/turn/execution-receipts.js +91 -33
  25. package/dist/engine/session/turn/execution-receipts.js.map +1 -1
  26. package/dist/engine/storage/session/command-cancellation-table.d.ts +17 -0
  27. package/dist/engine/storage/session/command-cancellation-table.d.ts.map +1 -0
  28. package/dist/engine/storage/session/command-cancellation-table.js +28 -0
  29. package/dist/engine/storage/session/command-cancellation-table.js.map +1 -0
  30. package/dist/engine/storage/sqlite/local-databases.d.ts +3 -0
  31. package/dist/engine/storage/sqlite/local-databases.d.ts.map +1 -1
  32. package/dist/engine/storage/sqlite/local-databases.js +4 -0
  33. package/dist/engine/storage/sqlite/local-databases.js.map +1 -1
  34. package/dist/engine.js +2 -2
  35. package/package.json +1 -1
  36. /package/dist/{cli-K2JBHPL5.js.map → cli-FNJ2BQAZ.js.map} +0 -0
@@ -80,7 +80,7 @@ var __callDispose = (stack, error, hasError) => {
80
80
  // package.json
81
81
  var package_default = {
82
82
  name: "@moxt-ai/mobius",
83
- version: "0.0.390",
83
+ version: "0.0.391",
84
84
  description: "Mobius CLI for pairing and running local AI agent services.",
85
85
  type: "module",
86
86
  bin: {
@@ -171,4 +171,4 @@ export {
171
171
  __callDispose,
172
172
  package_default
173
173
  };
174
- //# sourceMappingURL=chunk-KWRP3J26.js.map
174
+ //# sourceMappingURL=chunk-4VUCI4MS.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../package.json"],
4
- "sourcesContent": ["{\n \"name\": \"@moxt-ai/mobius\",\n \"version\": \"0.0.390\",\n \"description\": \"Mobius CLI for pairing and running local AI agent services.\",\n \"type\": \"module\",\n \"bin\": {\n \"mobius\": \"dist/cli.js\"\n },\n \"exports\": {\n \"./engine\": {\n \"mobius-source\": \"./src/exports/engine.ts\",\n \"types\": \"./dist/exports/engine.d.ts\",\n \"default\": \"./dist/engine.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"NOTICE\",\n \"THIRD-PARTY-NOTICES.txt\"\n ],\n \"engines\": {\n \"node\": \">=22.19.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"exports\": {\n \"./engine\": {\n \"types\": \"./dist/exports/engine.d.ts\",\n \"import\": \"./dist/engine.js\",\n \"default\": \"./dist/engine.js\"\n }\n }\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/moxt-ai/mobius.git\",\n \"directory\": \"packages/cli\"\n },\n \"scripts\": {\n \"prebuild\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"build\": \"node scripts/build.ts && tsc --project tsconfig.build.json\",\n \"dev\": \"node --watch src/cli/entrypoint.ts\",\n \"pretypecheck\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"prepack\": \"pnpm build\",\n \"start\": \"node dist/cli.js\",\n \"typecheck\": \"tsc --project tsconfig.json && tsc --project tests/tsconfig.json\",\n \"pretest:controlled\": \"pnpm build\",\n \"test:controlled\": \"vitest run tests/sessions tests/runtime\",\n \"pretest:manual\": \"pnpm pretest:controlled\",\n \"test:manual\": \"vitest run tests/manual\",\n \"pretest:agents\": \"pnpm build\",\n \"test:agents\": \"vitest run tests/agents --maxWorkers=2\",\n \"pretest:pressure\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"test:pressure\": \"node tests/pressure/concurrent-sessions.mjs\"\n },\n \"dependencies\": {\n \"@agentclientprotocol/sdk\": \"^1.4.0\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.3.257\",\n \"commander\": \"15.0.0\",\n \"semver\": \"^7.8.5\",\n \"undici\": \"8.12.2\",\n \"zod\": \"^4.6.7\"\n },\n \"devDependencies\": {\n \"@anthropic-ai/sdk\": \"0.122.0\",\n \"@moxt-ai/mobius-sdk\": \"workspace:*\",\n \"@moxt-ai/mobius-test\": \"workspace:*\",\n \"@types/node\": \"^24.13.5\",\n \"@types/semver\": \"^7.8.0\",\n \"@types/ws\": \"^8.18.1\",\n \"drizzle-kit\": \"1.0.0-rc.4\",\n \"drizzle-orm\": \"1.0.0-rc.4\",\n \"esbuild\": \"0.28.2\",\n \"valibot\": \"1.5.0\",\n \"ws\": \"^8.21.3\"\n },\n \"keywords\": [],\n \"author\": \"Moxt\",\n \"license\": \"Apache-2.0\",\n \"bugs\": {\n \"url\": \"https://github.com/moxt-ai/mobius/issues\"\n },\n \"homepage\": \"https://github.com/moxt-ai/mobius#readme\"\n}\n"],
4
+ "sourcesContent": ["{\n \"name\": \"@moxt-ai/mobius\",\n \"version\": \"0.0.391\",\n \"description\": \"Mobius CLI for pairing and running local AI agent services.\",\n \"type\": \"module\",\n \"bin\": {\n \"mobius\": \"dist/cli.js\"\n },\n \"exports\": {\n \"./engine\": {\n \"mobius-source\": \"./src/exports/engine.ts\",\n \"types\": \"./dist/exports/engine.d.ts\",\n \"default\": \"./dist/engine.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"NOTICE\",\n \"THIRD-PARTY-NOTICES.txt\"\n ],\n \"engines\": {\n \"node\": \">=22.19.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"exports\": {\n \"./engine\": {\n \"types\": \"./dist/exports/engine.d.ts\",\n \"import\": \"./dist/engine.js\",\n \"default\": \"./dist/engine.js\"\n }\n }\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/moxt-ai/mobius.git\",\n \"directory\": \"packages/cli\"\n },\n \"scripts\": {\n \"prebuild\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"build\": \"node scripts/build.ts && tsc --project tsconfig.build.json\",\n \"dev\": \"node --watch src/cli/entrypoint.ts\",\n \"pretypecheck\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"prepack\": \"pnpm build\",\n \"start\": \"node dist/cli.js\",\n \"typecheck\": \"tsc --project tsconfig.json && tsc --project tests/tsconfig.json\",\n \"pretest:controlled\": \"pnpm build\",\n \"test:controlled\": \"vitest run tests/sessions tests/runtime\",\n \"pretest:manual\": \"pnpm pretest:controlled\",\n \"test:manual\": \"vitest run tests/manual\",\n \"pretest:agents\": \"pnpm build\",\n \"test:agents\": \"vitest run tests/agents --maxWorkers=2\",\n \"pretest:pressure\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"test:pressure\": \"node tests/pressure/concurrent-sessions.mjs\"\n },\n \"dependencies\": {\n \"@agentclientprotocol/sdk\": \"^1.4.0\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.3.257\",\n \"commander\": \"15.0.0\",\n \"semver\": \"^7.8.5\",\n \"undici\": \"8.12.2\",\n \"zod\": \"^4.6.7\"\n },\n \"devDependencies\": {\n \"@anthropic-ai/sdk\": \"0.122.0\",\n \"@moxt-ai/mobius-sdk\": \"workspace:*\",\n \"@moxt-ai/mobius-test\": \"workspace:*\",\n \"@types/node\": \"^24.13.5\",\n \"@types/semver\": \"^7.8.0\",\n \"@types/ws\": \"^8.18.1\",\n \"drizzle-kit\": \"1.0.0-rc.4\",\n \"drizzle-orm\": \"1.0.0-rc.4\",\n \"esbuild\": \"0.28.2\",\n \"valibot\": \"1.5.0\",\n \"ws\": \"^8.21.3\"\n },\n \"keywords\": [],\n \"author\": \"Moxt\",\n \"license\": \"Apache-2.0\",\n \"bugs\": {\n \"url\": \"https://github.com/moxt-ai/mobius/issues\"\n },\n \"homepage\": \"https://github.com/moxt-ai/mobius#readme\"\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACI,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,MAAQ;AAAA,EACR,KAAO;AAAA,IACH,QAAU;AAAA,EACd;AAAA,EACA,SAAW;AAAA,IACP,YAAY;AAAA,MACR,iBAAiB;AAAA,MACjB,OAAS;AAAA,MACT,SAAW;AAAA,IACf;AAAA,EACJ;AAAA,EACA,OAAS;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,SAAW;AAAA,IACP,MAAQ;AAAA,EACZ;AAAA,EACA,eAAiB;AAAA,IACb,QAAU;AAAA,IACV,SAAW;AAAA,MACP,YAAY;AAAA,QACR,OAAS;AAAA,QACT,QAAU;AAAA,QACV,SAAW;AAAA,MACf;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,YAAc;AAAA,IACV,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,WAAa;AAAA,EACjB;AAAA,EACA,SAAW;AAAA,IACP,UAAY;AAAA,IACZ,OAAS;AAAA,IACT,KAAO;AAAA,IACP,cAAgB;AAAA,IAChB,SAAW;AAAA,IACX,OAAS;AAAA,IACT,WAAa;AAAA,IACb,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,EACrB;AAAA,EACA,cAAgB;AAAA,IACZ,4BAA4B;AAAA,IAC5B,kCAAkC;AAAA,IAClC,WAAa;AAAA,IACb,QAAU;AAAA,IACV,QAAU;AAAA,IACV,KAAO;AAAA,EACX;AAAA,EACA,iBAAmB;AAAA,IACf,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,wBAAwB;AAAA,IACxB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,eAAe;AAAA,IACf,eAAe;AAAA,IACf,SAAW;AAAA,IACX,SAAW;AAAA,IACX,IAAM;AAAA,EACV;AAAA,EACA,UAAY,CAAC;AAAA,EACb,QAAU;AAAA,EACV,SAAW;AAAA,EACX,MAAQ;AAAA,IACJ,KAAO;AAAA,EACX;AAAA,EACA,UAAY;AAChB;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@ import {
3
3
  __export,
4
4
  __using,
5
5
  package_default
6
- } from "./chunk-KWRP3J26.js";
6
+ } from "./chunk-4VUCI4MS.js";
7
7
 
8
8
  // src/engine/runtime/relay/runtime-revocation.ts
9
9
  var runtimeRevocationCloseCode = 1008;
@@ -78293,6 +78293,14 @@ var acpSessionStoreMigrations = [
78293
78293
  }
78294
78294
  ];
78295
78295
 
78296
+ // src/engine/generated/command-cancellation-migrations.ts
78297
+ var commandCancellationMigrations = [
78298
+ {
78299
+ "name": "0000_tired_cardiac.sql",
78300
+ "sql": "CREATE TABLE `cancelled_command` (\n `command_id` text PRIMARY KEY NOT NULL,\n `session_id` text NOT NULL\n);\n"
78301
+ }
78302
+ ];
78303
+
78296
78304
  // src/engine/generated/session-event-cache-migrations.ts
78297
78305
  var sessionEventCacheMigrations = [
78298
78306
  {
@@ -83232,6 +83240,7 @@ var LocalSqliteDatabase = class {
83232
83240
  function channelSessionDatabasePaths(stateDirectory, channelId) {
83233
83241
  const channelHash = createHash4("sha256").update(channelId).digest("hex");
83234
83242
  return {
83243
+ cancellations: join22(stateDirectory, "sessions", `${channelHash}.cancellations.sqlite`),
83235
83244
  events: join22(stateDirectory, "sessions", `${channelHash}.events.sqlite`),
83236
83245
  sessions: join22(stateDirectory, "sessions", `${channelHash}.sqlite`)
83237
83246
  };
@@ -83255,6 +83264,7 @@ var openAcpSessionDatabase = (path7) => {
83255
83264
  recordAppliedAdmissionOrder(path7);
83256
83265
  return new LocalSqliteDatabase(path7, "ACP Session database", acpSessionStoreMigrations);
83257
83266
  };
83267
+ var openCommandCancellationDatabase = (path7) => new LocalSqliteDatabase(path7, "Command cancellation database", commandCancellationMigrations);
83258
83268
  var openSessionEventCacheDatabase = (path7) => new LocalSqliteDatabase(path7, "V2 Session event cache", sessionEventCacheMigrations, [
83259
83269
  "PRAGMA journal_mode = WAL",
83260
83270
  "PRAGMA synchronous = OFF",
@@ -85045,6 +85055,33 @@ var AcpSessionTable = class {
85045
85055
  };
85046
85056
  };
85047
85057
 
85058
+ // src/engine/schema/command-cancellation/cancelled-command.ts
85059
+ var cancelledCommand = sqliteTable("cancelled_command", {
85060
+ commandId: text("command_id").primaryKey(),
85061
+ sessionId: text("session_id").notNull()
85062
+ });
85063
+
85064
+ // src/engine/storage/session/command-cancellation-table.ts
85065
+ var cancellationSchema = external_exports.object({ commandId: external_exports.string(), sessionId: external_exports.string() }).readonly();
85066
+ var CommandCancellationTable = class {
85067
+ #database;
85068
+ constructor(database) {
85069
+ this.#database = database;
85070
+ }
85071
+ close = () => this.#database.close();
85072
+ read = (commandId) => {
85073
+ const row = this.#database.orm.select().from(cancelledCommand).where(eq2(cancelledCommand.commandId, commandId)).get();
85074
+ return row === void 0 ? void 0 : cancellationSchema.parse(row);
85075
+ };
85076
+ retain = (cancellations) => {
85077
+ this.#database.transaction(() => {
85078
+ for (const cancellation of cancellations) {
85079
+ this.#database.orm.insert(cancelledCommand).values(cancellation).onConflictDoNothing().run();
85080
+ }
85081
+ });
85082
+ };
85083
+ };
85084
+
85048
85085
  // src/engine/storage/session/execution-receipt-table.ts
85049
85086
  var receiptSchema = external_exports.object({
85050
85087
  commandId: external_exports.string(),
@@ -88616,6 +88653,13 @@ function executionStarted(state) {
88616
88653
  }
88617
88654
  }
88618
88655
  }
88656
+ function cancelledBeforeStart(state) {
88657
+ if (state.kind !== "settled-before-start") {
88658
+ return false;
88659
+ }
88660
+ const outcome = decodeKnownSessionEventPayload(JSON.parse(state.outcome));
88661
+ return outcome?.type === "lifecycle-metadata" && outcome.payload.kind === "prompt.completed" && outcome.payload.stopReason === "cancelled";
88662
+ }
88619
88663
  function executionOutcome(state) {
88620
88664
  switch (state.kind) {
88621
88665
  case "pending":
@@ -88637,32 +88681,29 @@ var ExecutionReceipts = class {
88637
88681
  #executions = /* @__PURE__ */ new Map();
88638
88682
  #recoveredCommands = /* @__PURE__ */ new Set();
88639
88683
  #table;
88684
+ #cancellations;
88640
88685
  #closing = false;
88641
88686
  #onCount;
88642
- constructor(table, onCount = () => void 0) {
88687
+ constructor(table, cancellations, onCount = () => void 0) {
88643
88688
  this.#onCount = onCount;
88644
88689
  this.#table = table;
88690
+ this.#cancellations = cancellations;
88691
+ const retained = [];
88645
88692
  for (const { commandId, started, outcome, updatedAt: _updatedAt, ...identity2 } of table.list()) {
88646
- const state = { kind: started ? "started" : "pending" };
88693
+ const pending = { kind: started ? "started" : "pending" };
88694
+ const state = outcome === null ? pending : settledExecution(pending, outcome);
88647
88695
  this.#executions.set(commandId, {
88648
88696
  ...identity2,
88649
- state: outcome === null ? state : settledExecution(state, outcome)
88697
+ state
88650
88698
  });
88699
+ if (cancelledBeforeStart(state)) {
88700
+ retained.push({ commandId, sessionId: identity2.sessionId });
88701
+ }
88651
88702
  this.#recoveredCommands.add(commandId);
88652
88703
  }
88704
+ cancellations.retain(retained);
88653
88705
  }
88654
- #save = (commandId, receipt, durableOutcome = executionOutcome(receipt.state)) => {
88655
- const { state, ...identity2 } = receipt;
88656
- const evicted = this.#closing ? [] : this.#table.save(
88657
- {
88658
- ...identity2,
88659
- commandId,
88660
- started: executionStarted(state),
88661
- outcome: durableOutcome,
88662
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
88663
- },
88664
- MAX_TERMINAL_RECEIPTS
88665
- );
88706
+ #remember = (commandId, receipt, evicted) => {
88666
88707
  this.#executions.set(commandId, receipt);
88667
88708
  for (const evictedCommandId of evicted) {
88668
88709
  this.#executions.delete(evictedCommandId);
@@ -88676,6 +88717,24 @@ var ExecutionReceipts = class {
88676
88717
  }
88677
88718
  this.#onCount(activeCount);
88678
88719
  };
88720
+ #save = (commandId, receipt, durableOutcome = executionOutcome(receipt.state)) => {
88721
+ const { state, ...identity2 } = receipt;
88722
+ if (!this.#closing && cancelledBeforeStart(state)) {
88723
+ this.#cancellations.retain([{ commandId, sessionId: receipt.sessionId }]);
88724
+ this.#remember(commandId, receipt, []);
88725
+ }
88726
+ const evicted = this.#closing ? [] : this.#table.save(
88727
+ {
88728
+ ...identity2,
88729
+ commandId,
88730
+ started: executionStarted(state),
88731
+ outcome: durableOutcome,
88732
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
88733
+ },
88734
+ MAX_TERMINAL_RECEIPTS
88735
+ );
88736
+ this.#remember(commandId, receipt, evicted);
88737
+ };
88679
88738
  #nextAdmissionOrder = () => {
88680
88739
  let latest = 0;
88681
88740
  for (const receipt of this.#executions.values()) {
@@ -88695,7 +88754,7 @@ var ExecutionReceipts = class {
88695
88754
  delivery = (commandId, sessionId) => {
88696
88755
  const receipt = this.#executions.get(commandId);
88697
88756
  if (receipt === void 0) {
88698
- return this.#table.identity(commandId)?.sessionId === sessionId ? { state: "expired" } : { state: "unknown" };
88757
+ return this.#table.identity(commandId)?.sessionId === sessionId || this.#cancellations.read(commandId)?.sessionId === sessionId ? { state: "expired" } : { state: "unknown" };
88699
88758
  }
88700
88759
  if (receipt.sessionId !== sessionId) {
88701
88760
  return { state: "unknown" };
@@ -88769,6 +88828,18 @@ var ExecutionReceipts = class {
88769
88828
  payload: { kind: "prompt.completed", commandId, stopReason: "cancelled" }
88770
88829
  } : void 0;
88771
88830
  }
88831
+ const cancellation = this.#cancellations.read(commandId);
88832
+ if (cancellation !== void 0) {
88833
+ return cancellation.sessionId === sessionId ? {
88834
+ type: "lifecycle-metadata",
88835
+ payload: {
88836
+ kind: "prompt.completed",
88837
+ commandId,
88838
+ stopReason: "cancelled",
88839
+ execution: "not-started"
88840
+ }
88841
+ } : void 0;
88842
+ }
88772
88843
  const outcome = {
88773
88844
  type: "lifecycle-metadata",
88774
88845
  payload: { kind: "prompt.completed", commandId, stopReason: "cancelled", execution: "not-started" }
@@ -88828,7 +88899,16 @@ var ExecutionReceipts = class {
88828
88899
  const recovered = [];
88829
88900
  for (const [commandId, receipt] of [...this.#executions]) {
88830
88901
  const outcome = executionOutcome(receipt.state);
88831
- const event = outcome === null ? {
88902
+ const restoreCancellation = !this.hasStarted(commandId, receipt.sessionId) && !cancelledBeforeStart(receipt.state) && this.#cancellations.read(commandId)?.sessionId === receipt.sessionId;
88903
+ const event = restoreCancellation ? {
88904
+ type: "lifecycle-metadata",
88905
+ payload: {
88906
+ kind: "prompt.completed",
88907
+ commandId,
88908
+ stopReason: "cancelled",
88909
+ execution: "not-started"
88910
+ }
88911
+ } : outcome === null ? {
88832
88912
  type: "lifecycle-metadata",
88833
88913
  payload: executionStarted(receipt.state) ? {
88834
88914
  kind: "prompt.failed",
@@ -88846,9 +88926,9 @@ var ExecutionReceipts = class {
88846
88926
  if (event === null) {
88847
88927
  continue;
88848
88928
  }
88849
- const recordedAt = outcome === null ? (/* @__PURE__ */ new Date()).toISOString() : external_exports.object({ recordedAt: external_exports.string() }).parse(JSON.parse(outcome)).recordedAt;
88929
+ const recordedAt = restoreCancellation || outcome === null ? (/* @__PURE__ */ new Date()).toISOString() : external_exports.object({ recordedAt: external_exports.string() }).parse(JSON.parse(outcome)).recordedAt;
88850
88930
  recovered.push({ sessionId: receipt.sessionId, event, recordedAt });
88851
- if (outcome === null) {
88931
+ if (restoreCancellation || outcome === null) {
88852
88932
  this.#save(commandId, {
88853
88933
  ...receipt,
88854
88934
  state: settledExecution(receipt.state, JSON.stringify({ ...event, recordedAt }))
@@ -88882,6 +88962,9 @@ var ExecutionReceipts = class {
88882
88962
  if (identity2 !== void 0) {
88883
88963
  return identity2.sessionId === sessionId && identity2.commandHash === commandHash ? { kind: "expired" } : { kind: "conflict" };
88884
88964
  }
88965
+ if (this.#cancellations.read(commandId) !== void 0) {
88966
+ return { kind: "conflict" };
88967
+ }
88885
88968
  const attemptId = randomUUID15();
88886
88969
  this.#save(commandId, {
88887
88970
  admissionOrder: this.#nextAdmissionOrder(),
@@ -88904,6 +88987,7 @@ var ExecutionReceipts = class {
88904
88987
  close = () => {
88905
88988
  this.#executions.clear();
88906
88989
  this.#recoveredCommands.clear();
88990
+ this.#cancellations.close();
88907
88991
  };
88908
88992
  };
88909
88993
 
@@ -89499,13 +89583,20 @@ function buildSessionLayer(options) {
89499
89583
  const sessionDatabase = openAcpSessionDatabase(databases.sessions);
89500
89584
  let events;
89501
89585
  let operations;
89586
+ let cancellations;
89502
89587
  try {
89503
- operations = new ExecutionReceipts(new ExecutionReceiptTable(sessionDatabase), options.onExecutionCountChange);
89588
+ cancellations = new CommandCancellationTable(openCommandCancellationDatabase(databases.cancellations));
89589
+ operations = new ExecutionReceipts(
89590
+ new ExecutionReceiptTable(sessionDatabase),
89591
+ cancellations,
89592
+ options.onExecutionCountChange
89593
+ );
89504
89594
  events = new CachedSessionEventStore(
89505
89595
  new SessionEventCacheTable(openSessionEventCacheDatabase(databases.events)),
89506
89596
  new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase))
89507
89597
  );
89508
89598
  } catch (error62) {
89599
+ cancellations?.close();
89509
89600
  sessionDatabase.close();
89510
89601
  throw error62;
89511
89602
  }
@@ -93655,4 +93746,4 @@ export {
93655
93746
  * MIT Licensed
93656
93747
  *)
93657
93748
  */
93658
- //# sourceMappingURL=chunk-ZW763PCS.js.map
93749
+ //# sourceMappingURL=chunk-TQJ2GJH7.js.map