@cydm/pie 2.7.4 → 2.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  logTransportLifecycle,
24
24
  migrateConfigFromAgentDir,
25
25
  truncateHeadTail
26
- } from "./chunks/chunk-VGVCDW7P.js";
26
+ } from "./chunks/chunk-OOUL3DRE.js";
27
27
  import {
28
28
  resolveCliProjectRoot
29
29
  } from "./chunks/chunk-WLFOBECN.js";
@@ -45,7 +45,6 @@ import {
45
45
  continueExecutionState,
46
46
  createCompactionSummary,
47
47
  createEmptyExecutionState,
48
- createExecutionStateFromTodos,
49
48
  createExecutionStateStore,
50
49
  createFileObservationState,
51
50
  createPolicyEnforcedTools,
@@ -55,9 +54,9 @@ import {
55
54
  createSharedFileSystemTools,
56
55
  createSharedWebSearchTool,
57
56
  createTodoWidgetView,
57
+ createTwoFilesPatch,
58
58
  estimateContextTokens,
59
59
  estimateTokens,
60
- evaluateTodoClosureAfterAbort,
61
60
  evaluateTodoClosureAfterCompletedTurn,
62
61
  evaluateTodoClosureAfterFailedTurn,
63
62
  extensionFallbackName,
@@ -86,8 +85,8 @@ import {
86
85
  shouldPreserveExecutionStateForUserText,
87
86
  supersedeExecutionState,
88
87
  verifyPreparedCompactionCommit
89
- } from "./chunks/chunk-FIE3SSLW.js";
90
- import "./chunks/chunk-P2B62ZPU.js";
88
+ } from "./chunks/chunk-BFHCZVNO.js";
89
+ import "./chunks/chunk-MLRF72MK.js";
91
90
  import {
92
91
  Deref,
93
92
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -112,7 +111,7 @@ import {
112
111
  sortToolModelCandidatesByCapability,
113
112
  streamSimple,
114
113
  type_exports
115
- } from "./chunks/chunk-Z4EIBY2E.js";
114
+ } from "./chunks/chunk-SUPAWIKP.js";
116
115
  import {
117
116
  IsArray,
118
117
  IsBigInt,
@@ -48383,7 +48382,7 @@ var require_resolve_block_scalar = __commonJS({
48383
48382
  if (!header)
48384
48383
  return { value: "", type: null, comment: "", range: [start, start, start] };
48385
48384
  const type = header.mode === ">" ? Scalar.Scalar.BLOCK_FOLDED : Scalar.Scalar.BLOCK_LITERAL;
48386
- const lines = scalar.source ? splitLines2(scalar.source) : [];
48385
+ const lines = scalar.source ? splitLines(scalar.source) : [];
48387
48386
  let chompStart = lines.length;
48388
48387
  for (let i = lines.length - 1; i >= 0; --i) {
48389
48388
  const content = lines[i][1];
@@ -48541,7 +48540,7 @@ var require_resolve_block_scalar = __commonJS({
48541
48540
  }
48542
48541
  return { mode, indent, chomp, comment, length };
48543
48542
  }
48544
- function splitLines2(source) {
48543
+ function splitLines(source) {
48545
48544
  const split = source.split(/\n( *)/);
48546
48545
  const first = split[0];
48547
48546
  const m2 = first.match(/^( *)/);
@@ -52591,7 +52590,8 @@ function validateRemoteModel(profileId, model) {
52591
52590
  }
52592
52591
  if (!isPlainRecord(model.cost)) throw new Error(`Remote profile "${profileId}" model "${model.id}" has invalid cost values`);
52593
52592
  assertOnlyKeys(model.cost, ["input", "output", "cacheRead", "cacheWrite", "cacheWriteLong"], `Remote profile "${profileId}" model "${model.id}" cost`);
52594
- if ([model.cost.input, model.cost.output, model.cost.cacheRead, model.cost.cacheWrite, model.cost.cacheWriteLong].some((value) => value !== void 0 && (typeof value !== "number" || !Number.isFinite(value) || value < 0))) {
52593
+ const invalidRate = (value) => typeof value !== "number" || !Number.isFinite(value) || value < 0;
52594
+ if ([model.cost.input, model.cost.output, model.cost.cacheRead, model.cost.cacheWrite].some(invalidRate) || model.cost.cacheWriteLong !== void 0 && invalidRate(model.cost.cacheWriteLong)) {
52595
52595
  throw new Error(`Remote profile "${profileId}" model "${model.id}" has invalid cost values`);
52596
52596
  }
52597
52597
  if (!Number.isSafeInteger(model.contextWindow) || Number(model.contextWindow) <= 0 || !Number.isSafeInteger(model.maxTokens) || Number(model.maxTokens) <= 0 || Number(model.maxTokens) > Number(model.contextWindow)) {
@@ -56524,11 +56524,12 @@ function createExtensionContext(extension, cwd, uiContext, abortFn, isIdleFn, ha
56524
56524
  setExecutionReminder(text) {
56525
56525
  actions?.setExecutionReminder(text);
56526
56526
  },
56527
+ getExecutionStateExplanation: () => actions?.getExecutionStateExplanation?.(),
56527
56528
  getExecutionState() {
56528
56529
  return actions?.getExecutionState?.() ?? createEmptyExecutionState();
56529
56530
  },
56530
- setExecutionState(state) {
56531
- return actions?.setExecutionState?.(state) ?? createEmptyExecutionState();
56531
+ setExecutionState(state, reason) {
56532
+ return actions?.setExecutionState?.(state, reason) ?? createEmptyExecutionState();
56532
56533
  },
56533
56534
  // Extended properties for subagent creation
56534
56535
  get apiKey() {
@@ -59306,11 +59307,11 @@ var TUI = class extends Container {
59306
59307
  this.stopped = true;
59307
59308
  if (this.previousLines.length > 0) {
59308
59309
  const targetRow = this.previousLines.length;
59309
- const lineDiff2 = targetRow - this.hardwareCursorRow;
59310
- if (lineDiff2 > 0) {
59311
- this.terminal.write(`\x1B[${lineDiff2}B`);
59312
- } else if (lineDiff2 < 0) {
59313
- this.terminal.write(`\x1B[${-lineDiff2}A`);
59310
+ const lineDiff = targetRow - this.hardwareCursorRow;
59311
+ if (lineDiff > 0) {
59312
+ this.terminal.write(`\x1B[${lineDiff}B`);
59313
+ } else if (lineDiff < 0) {
59314
+ this.terminal.write(`\x1B[${-lineDiff}A`);
59314
59315
  }
59315
59316
  this.terminal.write("\r\n");
59316
59317
  }
@@ -59435,9 +59436,9 @@ var TUI = class extends Container {
59435
59436
  if (this.previousLines.length > newLines.length) {
59436
59437
  let buffer2 = "\x1B[?2026h";
59437
59438
  const targetRow = Math.max(0, newLines.length - 1);
59438
- const lineDiff3 = computeLineDiff(targetRow);
59439
- if (lineDiff3 > 0) buffer2 += `\x1B[${lineDiff3}B`;
59440
- else if (lineDiff3 < 0) buffer2 += `\x1B[${-lineDiff3}A`;
59439
+ const lineDiff2 = computeLineDiff(targetRow);
59440
+ if (lineDiff2 > 0) buffer2 += `\x1B[${lineDiff2}B`;
59441
+ else if (lineDiff2 < 0) buffer2 += `\x1B[${-lineDiff2}A`;
59441
59442
  buffer2 += "\r";
59442
59443
  const extraLines = this.previousLines.length - newLines.length;
59443
59444
  if (extraLines > height) {
@@ -59487,11 +59488,11 @@ var TUI = class extends Container {
59487
59488
  viewportTop += scroll;
59488
59489
  hardwareCursorRow = moveTargetRow;
59489
59490
  }
59490
- const lineDiff2 = computeLineDiff(moveTargetRow);
59491
- if (lineDiff2 > 0) {
59492
- buffer += `\x1B[${lineDiff2}B`;
59493
- } else if (lineDiff2 < 0) {
59494
- buffer += `\x1B[${-lineDiff2}A`;
59491
+ const lineDiff = computeLineDiff(moveTargetRow);
59492
+ if (lineDiff > 0) {
59493
+ buffer += `\x1B[${lineDiff}B`;
59494
+ } else if (lineDiff < 0) {
59495
+ buffer += `\x1B[${-lineDiff}A`;
59495
59496
  }
59496
59497
  buffer += appendStart ? "\r\n" : "\r";
59497
59498
  const renderEnd = Math.min(lastChanged, newLines.length - 1);
@@ -59549,7 +59550,7 @@ var TUI = class extends Container {
59549
59550
  `viewportTop: ${viewportTop}`,
59550
59551
  `cursorRow: ${this.cursorRow}`,
59551
59552
  `height: ${height}`,
59552
- `lineDiff: ${lineDiff2}`,
59553
+ `lineDiff: ${lineDiff}`,
59553
59554
  `hardwareCursorRow: ${hardwareCursorRow}`,
59554
59555
  `renderEnd: ${renderEnd}`,
59555
59556
  `finalCursorRow: ${finalCursorRow}`,
@@ -64302,7 +64303,8 @@ var ExtensionRunner = class {
64302
64303
  setPlanMode: (enabled, options) => this.actions.setPlanMode(enabled, options),
64303
64304
  setExecutionReminder: (text) => this.actions.setExecutionReminder(text),
64304
64305
  getExecutionState: () => this.actions.getExecutionState(),
64305
- setExecutionState: (state) => this.actions.setExecutionState(state),
64306
+ getExecutionStateExplanation: () => this.actions.getExecutionStateExplanation?.(),
64307
+ setExecutionState: (state, reason) => this.actions.setExecutionState(state, reason),
64306
64308
  get apiKey() {
64307
64309
  return runner.actions.apiKey;
64308
64310
  },
@@ -69997,16 +69999,42 @@ function getTextFromMessageContent(content) {
69997
69999
  }
69998
70000
  var ExecutionStateManager = class {
69999
70001
  store = createExecutionStateStore();
70002
+ work;
70003
+ beginWork() {
70004
+ const token = { identity: {} };
70005
+ this.work = { token, fence: this.capture() };
70006
+ return token;
70007
+ }
70008
+ isWorkCurrent(token) {
70009
+ return this.work?.token === token && this.isCurrent(this.work.fence);
70010
+ }
70011
+ completeWork(token, message, toolResults = []) {
70012
+ if (!this.isWorkCurrent(token)) return { changed: false };
70013
+ return this.advanceFromCompletedTurn(message, toolResults, this.work.fence);
70014
+ }
70015
+ failWork(token) {
70016
+ if (!this.isWorkCurrent(token)) return { changed: false };
70017
+ return this.handleTurnFailed(this.work.fence);
70018
+ }
70019
+ /** Only synchronous tool mutations may move the current work to a newly-created list. */
70020
+ applyToolState(state, reason) {
70021
+ const work = this.work;
70022
+ const current = work && this.isWorkCurrent(work.token);
70023
+ const mutation = { source: "todo_tool", reason };
70024
+ const next = reason === "advance" ? this.store.write({ ...state, loop: this.read().loop }, mutation) : state ? this.store.replace(state, mutation) : this.store.clear(mutation);
70025
+ if (current && work && reason !== "session_restore") work.fence = this.capture();
70026
+ return next;
70027
+ }
70000
70028
  completeCount(state) {
70001
70029
  return state.steps.filter((step) => step.status === "completed").length;
70002
70030
  }
70003
70031
  isCompletionText(text) {
70004
70032
  return /完成|已完成|done|finished|completed|wrap[\s-]?up|all set|success/i.test(text);
70005
70033
  }
70006
- clearWithSummary(summary = null) {
70034
+ clearWithSummary(summary = null, reason = summary ? "failed_clear" : "completed_clear") {
70007
70035
  const cleared = createEmptyExecutionState();
70008
70036
  cleared.failureSummary = summary;
70009
- return this.store.replace(cleared);
70037
+ return this.store.replace(cleared, { source: "runtime", reason });
70010
70038
  }
70011
70039
  summarizeFailure(reason) {
70012
70040
  switch (reason) {
@@ -70027,7 +70055,7 @@ var ExecutionStateManager = class {
70027
70055
  }
70028
70056
  evaluateCompletedTurnLoop(previous, next, toolResults, assistantText) {
70029
70057
  if (next.mode !== "todo" || !next.loop) {
70030
- this.store.replace(next);
70058
+ this.store.write(next);
70031
70059
  return { changed: !this.unchanged(previous, next) };
70032
70060
  }
70033
70061
  const decision = evaluateTodoClosureAfterCompletedTurn(next, next.loop, {
@@ -70055,11 +70083,26 @@ var ExecutionStateManager = class {
70055
70083
  ...next,
70056
70084
  loop: decision.loop
70057
70085
  };
70058
- this.store.replace(updated);
70086
+ this.store.write(updated);
70059
70087
  return {
70060
70088
  changed: !this.unchanged(previous, updated)
70061
70089
  };
70062
70090
  }
70091
+ capture() {
70092
+ return this.store.capture();
70093
+ }
70094
+ isCurrent(fence) {
70095
+ return this.store.isCurrent(fence);
70096
+ }
70097
+ diagnostics() {
70098
+ return this.store.diagnostics();
70099
+ }
70100
+ inactiveExplanation() {
70101
+ if (this.read().steps.length) return void 0;
70102
+ const last = this.diagnostics().audit.at(-1);
70103
+ if (!last || !["explicit_clear", "completed_clear", "failed_clear", "stalled_clear", "topic_switch"].includes(last.reason)) return void 0;
70104
+ return `Last known clear: ${last.reason} (revision ${last.revision}).`;
70105
+ }
70063
70106
  read() {
70064
70107
  return this.store.read();
70065
70108
  }
@@ -70084,9 +70127,9 @@ var ExecutionStateManager = class {
70084
70127
  return this.store.replace(pauseExecutionState({
70085
70128
  ...restored,
70086
70129
  awaitingContinuation: false
70087
- }, "Previous todo turn was interrupted while a tool was running. Send 'continue' to resume the remaining items."));
70130
+ }, "Previous todo turn was interrupted while a tool was running. Send 'continue' to resume the remaining items."), { source: "session", reason: "session_restore" });
70088
70131
  }
70089
- return this.store.replace(restored);
70132
+ return this.store.replace(restored, { source: "session", reason: "session_restore" });
70090
70133
  }
70091
70134
  getReminder() {
70092
70135
  return buildExecutionReminder(this.store.read());
@@ -70102,17 +70145,18 @@ var ExecutionStateManager = class {
70102
70145
  if (previous.awaitingContinuation) {
70103
70146
  return false;
70104
70147
  }
70105
- this.store.replace({
70148
+ this.store.write({
70106
70149
  ...previous,
70107
70150
  awaitingContinuation: true
70108
70151
  });
70109
70152
  return true;
70110
70153
  }
70111
- advanceFromCompletedTurn(message, toolResults = []) {
70112
- if (!message || message.role !== "assistant") {
70154
+ advanceFromCompletedTurn(message, toolResults = [], fence) {
70155
+ if (!this.store.isCurrent(fence) || !message || message.role !== "assistant") {
70113
70156
  return { changed: false };
70114
70157
  }
70115
70158
  const previous = this.store.read();
70159
+ if (previous.steps.length === 0) return { changed: false };
70116
70160
  const assistantText = getTextFromMessageContent(message.content);
70117
70161
  const next = maybeAdvanceTodoExecutionState(previous, {
70118
70162
  assistantText,
@@ -70132,7 +70176,8 @@ var ExecutionStateManager = class {
70132
70176
  }
70133
70177
  return state.loop.continuePrompt || void 0;
70134
70178
  }
70135
- handleTurnFailed() {
70179
+ handleTurnFailed(fence) {
70180
+ if (!this.store.isCurrent(fence)) return { changed: false };
70136
70181
  const previous = this.store.read();
70137
70182
  if (previous.mode !== "todo" || !previous.loop && previous.steps.length === 0) {
70138
70183
  return { changed: false };
@@ -70143,7 +70188,7 @@ var ExecutionStateManager = class {
70143
70188
  ...previous,
70144
70189
  loop: decision.loop
70145
70190
  }, this.summarizeFailure(decision.reason));
70146
- this.store.replace(paused);
70191
+ this.store.write(paused, { source: "runtime", reason: "pause_failed" });
70147
70192
  return {
70148
70193
  changed: true,
70149
70194
  terminalStatus: "paused",
@@ -70166,7 +70211,7 @@ var ExecutionStateManager = class {
70166
70211
  if (previous.mode !== "todo" || previous.lifecycle !== "paused" || previous.steps.length === 0) {
70167
70212
  return { changed: false };
70168
70213
  }
70169
- const next = this.store.replace(continueExecutionState(previous));
70214
+ const next = this.store.write(continueExecutionState(previous), { source: "runtime", reason: "advance" });
70170
70215
  return { changed: !this.unchanged(previous, next) };
70171
70216
  }
70172
70217
  markAwaitingContinuationStalled() {
@@ -70174,7 +70219,7 @@ var ExecutionStateManager = class {
70174
70219
  if (previous.mode !== "todo" || !previous.awaitingContinuation) {
70175
70220
  return { changed: false };
70176
70221
  }
70177
- this.clearWithSummary(this.summarizeFailure("stagnated"));
70222
+ this.clearWithSummary(this.summarizeFailure("stagnated"), "stalled_clear");
70178
70223
  return {
70179
70224
  changed: true,
70180
70225
  cleared: true,
@@ -70184,20 +70229,14 @@ var ExecutionStateManager = class {
70184
70229
  }
70185
70230
  abort() {
70186
70231
  const previous = this.store.read();
70187
- const decision = evaluateTodoClosureAfterAbort(previous.loop);
70188
- if (decision.action === "clear_aborted") {
70189
- return {
70190
- state: this.clearWithSummary(this.summarizeFailure(decision.reason)),
70191
- cleared: true,
70192
- terminalSummary: this.read().failureSummary || void 0
70193
- };
70194
- }
70195
- return { state: this.store.replace(abortExecutionState(previous)), cleared: false };
70232
+ return { state: this.store.replace(abortExecutionState(previous), { source: "runtime", reason: "abort" }), cleared: false };
70196
70233
  }
70197
70234
  continue() {
70198
70235
  return this.store.replace(continueExecutionState(this.store.read()));
70199
70236
  }
70200
70237
  applyUserTextLifecycle(text) {
70238
+ const work = this.work;
70239
+ const current = work && this.isWorkCurrent(work.token);
70201
70240
  const state = this.store.read();
70202
70241
  if (state.steps.length === 0) {
70203
70242
  return null;
@@ -70208,11 +70247,13 @@ var ExecutionStateManager = class {
70208
70247
  if (shouldPreserveExecutionStateForUserText(text)) {
70209
70248
  if (state.lifecycle === "paused" || state.lifecycle === "aborted") {
70210
70249
  this.store.replace(continueExecutionState(state));
70250
+ if (current && work) work.fence = this.capture();
70211
70251
  return "continued";
70212
70252
  }
70213
70253
  return null;
70214
70254
  }
70215
- this.store.replace(supersedeExecutionState());
70255
+ this.store.replace(supersedeExecutionState(), { source: "user", reason: "topic_switch" });
70256
+ if (current && work) work.fence = this.capture();
70216
70257
  return "cleared";
70217
70258
  }
70218
70259
  clearIfSupersededByUserMessage(messages) {
@@ -71711,436 +71752,6 @@ var AssistantMessageComponent = class extends Container {
71711
71752
  // src/components/tool-execution.ts
71712
71753
  import * as os5 from "node:os";
71713
71754
 
71714
- // ../../node_modules/diff/libesm/diff/base.js
71715
- var Diff = class {
71716
- diff(oldStr, newStr, options = {}) {
71717
- let callback;
71718
- if (typeof options === "function") {
71719
- callback = options;
71720
- options = {};
71721
- } else if ("callback" in options) {
71722
- callback = options.callback;
71723
- }
71724
- const oldString = this.castInput(oldStr, options);
71725
- const newString = this.castInput(newStr, options);
71726
- const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
71727
- const newTokens = this.removeEmpty(this.tokenize(newString, options));
71728
- return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
71729
- }
71730
- diffWithOptionsObj(oldTokens, newTokens, options, callback) {
71731
- var _a;
71732
- const done = (value) => {
71733
- value = this.postProcess(value, options);
71734
- if (callback) {
71735
- setTimeout(function() {
71736
- callback(value);
71737
- }, 0);
71738
- return void 0;
71739
- } else {
71740
- return value;
71741
- }
71742
- };
71743
- const newLen = newTokens.length, oldLen = oldTokens.length;
71744
- let editLength = 1;
71745
- let maxEditLength = newLen + oldLen;
71746
- if (options.maxEditLength != null) {
71747
- maxEditLength = Math.min(maxEditLength, options.maxEditLength);
71748
- }
71749
- const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;
71750
- const abortAfterTimestamp = Date.now() + maxExecutionTime;
71751
- const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
71752
- let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
71753
- if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
71754
- return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
71755
- }
71756
- let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
71757
- const execEditLength = () => {
71758
- for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
71759
- let basePath;
71760
- const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
71761
- if (removePath) {
71762
- bestPath[diagonalPath - 1] = void 0;
71763
- }
71764
- let canAdd = false;
71765
- if (addPath) {
71766
- const addPathNewPos = addPath.oldPos - diagonalPath;
71767
- canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
71768
- }
71769
- const canRemove = removePath && removePath.oldPos + 1 < oldLen;
71770
- if (!canAdd && !canRemove) {
71771
- bestPath[diagonalPath] = void 0;
71772
- continue;
71773
- }
71774
- if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
71775
- basePath = this.addToPath(addPath, true, false, 0, options);
71776
- } else {
71777
- basePath = this.addToPath(removePath, false, true, 1, options);
71778
- }
71779
- newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
71780
- if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
71781
- return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
71782
- } else {
71783
- bestPath[diagonalPath] = basePath;
71784
- if (basePath.oldPos + 1 >= oldLen) {
71785
- maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
71786
- }
71787
- if (newPos + 1 >= newLen) {
71788
- minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
71789
- }
71790
- }
71791
- }
71792
- editLength++;
71793
- };
71794
- if (callback) {
71795
- (function exec() {
71796
- setTimeout(function() {
71797
- if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
71798
- return callback(void 0);
71799
- }
71800
- if (!execEditLength()) {
71801
- exec();
71802
- }
71803
- }, 0);
71804
- })();
71805
- } else {
71806
- while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
71807
- const ret = execEditLength();
71808
- if (ret) {
71809
- return ret;
71810
- }
71811
- }
71812
- }
71813
- }
71814
- addToPath(path34, added, removed, oldPosInc, options) {
71815
- const last = path34.lastComponent;
71816
- if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
71817
- return {
71818
- oldPos: path34.oldPos + oldPosInc,
71819
- lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
71820
- };
71821
- } else {
71822
- return {
71823
- oldPos: path34.oldPos + oldPosInc,
71824
- lastComponent: { count: 1, added, removed, previousComponent: last }
71825
- };
71826
- }
71827
- }
71828
- extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
71829
- const newLen = newTokens.length, oldLen = oldTokens.length;
71830
- let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
71831
- while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
71832
- newPos++;
71833
- oldPos++;
71834
- commonCount++;
71835
- if (options.oneChangePerToken) {
71836
- basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
71837
- }
71838
- }
71839
- if (commonCount && !options.oneChangePerToken) {
71840
- basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
71841
- }
71842
- basePath.oldPos = oldPos;
71843
- return newPos;
71844
- }
71845
- equals(left, right, options) {
71846
- if (options.comparator) {
71847
- return options.comparator(left, right);
71848
- } else {
71849
- return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
71850
- }
71851
- }
71852
- removeEmpty(array) {
71853
- const ret = [];
71854
- for (let i = 0; i < array.length; i++) {
71855
- if (array[i]) {
71856
- ret.push(array[i]);
71857
- }
71858
- }
71859
- return ret;
71860
- }
71861
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
71862
- castInput(value, options) {
71863
- return value;
71864
- }
71865
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
71866
- tokenize(value, options) {
71867
- return Array.from(value);
71868
- }
71869
- join(chars) {
71870
- return chars.join("");
71871
- }
71872
- postProcess(changeObjects, options) {
71873
- return changeObjects;
71874
- }
71875
- get useLongestToken() {
71876
- return false;
71877
- }
71878
- buildValues(lastComponent, newTokens, oldTokens) {
71879
- const components = [];
71880
- let nextComponent;
71881
- while (lastComponent) {
71882
- components.push(lastComponent);
71883
- nextComponent = lastComponent.previousComponent;
71884
- delete lastComponent.previousComponent;
71885
- lastComponent = nextComponent;
71886
- }
71887
- components.reverse();
71888
- const componentLen = components.length;
71889
- let componentPos = 0, newPos = 0, oldPos = 0;
71890
- for (; componentPos < componentLen; componentPos++) {
71891
- const component = components[componentPos];
71892
- if (!component.removed) {
71893
- if (!component.added && this.useLongestToken) {
71894
- let value = newTokens.slice(newPos, newPos + component.count);
71895
- value = value.map(function(value2, i) {
71896
- const oldValue = oldTokens[oldPos + i];
71897
- return oldValue.length > value2.length ? oldValue : value2;
71898
- });
71899
- component.value = this.join(value);
71900
- } else {
71901
- component.value = this.join(newTokens.slice(newPos, newPos + component.count));
71902
- }
71903
- newPos += component.count;
71904
- if (!component.added) {
71905
- oldPos += component.count;
71906
- }
71907
- } else {
71908
- component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
71909
- oldPos += component.count;
71910
- }
71911
- }
71912
- return components;
71913
- }
71914
- };
71915
-
71916
- // ../../node_modules/diff/libesm/diff/line.js
71917
- var LineDiff = class extends Diff {
71918
- constructor() {
71919
- super(...arguments);
71920
- this.tokenize = tokenize;
71921
- }
71922
- equals(left, right, options) {
71923
- if (options.ignoreWhitespace) {
71924
- if (!options.newlineIsToken || !left.includes("\n")) {
71925
- left = left.trim();
71926
- }
71927
- if (!options.newlineIsToken || !right.includes("\n")) {
71928
- right = right.trim();
71929
- }
71930
- } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
71931
- if (left.endsWith("\n")) {
71932
- left = left.slice(0, -1);
71933
- }
71934
- if (right.endsWith("\n")) {
71935
- right = right.slice(0, -1);
71936
- }
71937
- }
71938
- return super.equals(left, right, options);
71939
- }
71940
- };
71941
- var lineDiff = new LineDiff();
71942
- function diffLines(oldStr, newStr, options) {
71943
- return lineDiff.diff(oldStr, newStr, options);
71944
- }
71945
- function tokenize(value, options) {
71946
- if (options.stripTrailingCr) {
71947
- value = value.replace(/\r\n/g, "\n");
71948
- }
71949
- const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
71950
- if (!linesAndNewlines[linesAndNewlines.length - 1]) {
71951
- linesAndNewlines.pop();
71952
- }
71953
- for (let i = 0; i < linesAndNewlines.length; i++) {
71954
- const line = linesAndNewlines[i];
71955
- if (i % 2 && !options.newlineIsToken) {
71956
- retLines[retLines.length - 1] += line;
71957
- } else {
71958
- retLines.push(line);
71959
- }
71960
- }
71961
- return retLines;
71962
- }
71963
-
71964
- // ../../node_modules/diff/libesm/patch/create.js
71965
- var INCLUDE_HEADERS = {
71966
- includeIndex: true,
71967
- includeUnderline: true,
71968
- includeFileHeaders: true
71969
- };
71970
- function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
71971
- let optionsObj;
71972
- if (!options) {
71973
- optionsObj = {};
71974
- } else if (typeof options === "function") {
71975
- optionsObj = { callback: options };
71976
- } else {
71977
- optionsObj = options;
71978
- }
71979
- if (typeof optionsObj.context === "undefined") {
71980
- optionsObj.context = 4;
71981
- }
71982
- const context = optionsObj.context;
71983
- if (optionsObj.newlineIsToken) {
71984
- throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
71985
- }
71986
- if (!optionsObj.callback) {
71987
- return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
71988
- } else {
71989
- const { callback } = optionsObj;
71990
- diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
71991
- const patch = diffLinesResultToPatch(diff);
71992
- callback(patch);
71993
- } }));
71994
- }
71995
- function diffLinesResultToPatch(diff) {
71996
- if (!diff) {
71997
- return;
71998
- }
71999
- diff.push({ value: "", lines: [] });
72000
- function contextLines(lines) {
72001
- return lines.map(function(entry) {
72002
- return " " + entry;
72003
- });
72004
- }
72005
- const hunks = [];
72006
- let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
72007
- for (let i = 0; i < diff.length; i++) {
72008
- const current = diff[i], lines = current.lines || splitLines(current.value);
72009
- current.lines = lines;
72010
- if (current.added || current.removed) {
72011
- if (!oldRangeStart) {
72012
- const prev = diff[i - 1];
72013
- oldRangeStart = oldLine;
72014
- newRangeStart = newLine;
72015
- if (prev) {
72016
- curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
72017
- oldRangeStart -= curRange.length;
72018
- newRangeStart -= curRange.length;
72019
- }
72020
- }
72021
- for (const line of lines) {
72022
- curRange.push((current.added ? "+" : "-") + line);
72023
- }
72024
- if (current.added) {
72025
- newLine += lines.length;
72026
- } else {
72027
- oldLine += lines.length;
72028
- }
72029
- } else {
72030
- if (oldRangeStart) {
72031
- if (lines.length <= context * 2 && i < diff.length - 2) {
72032
- for (const line of contextLines(lines)) {
72033
- curRange.push(line);
72034
- }
72035
- } else {
72036
- const contextSize = Math.min(lines.length, context);
72037
- for (const line of contextLines(lines.slice(0, contextSize))) {
72038
- curRange.push(line);
72039
- }
72040
- const hunk = {
72041
- oldStart: oldRangeStart,
72042
- oldLines: oldLine - oldRangeStart + contextSize,
72043
- newStart: newRangeStart,
72044
- newLines: newLine - newRangeStart + contextSize,
72045
- lines: curRange
72046
- };
72047
- hunks.push(hunk);
72048
- oldRangeStart = 0;
72049
- newRangeStart = 0;
72050
- curRange = [];
72051
- }
72052
- }
72053
- oldLine += lines.length;
72054
- newLine += lines.length;
72055
- }
72056
- }
72057
- for (const hunk of hunks) {
72058
- for (let i = 0; i < hunk.lines.length; i++) {
72059
- if (hunk.lines[i].endsWith("\n")) {
72060
- hunk.lines[i] = hunk.lines[i].slice(0, -1);
72061
- } else {
72062
- hunk.lines.splice(i + 1, 0, "\");
72063
- i++;
72064
- }
72065
- }
72066
- }
72067
- return {
72068
- oldFileName,
72069
- newFileName,
72070
- oldHeader,
72071
- newHeader,
72072
- hunks
72073
- };
72074
- }
72075
- }
72076
- function formatPatch(patch, headerOptions) {
72077
- if (!headerOptions) {
72078
- headerOptions = INCLUDE_HEADERS;
72079
- }
72080
- if (Array.isArray(patch)) {
72081
- if (patch.length > 1 && !headerOptions.includeFileHeaders) {
72082
- throw new Error("Cannot omit file headers on a multi-file patch. (The result would be unparseable; how would a tool trying to apply the patch know which changes are to which file?)");
72083
- }
72084
- return patch.map((p) => formatPatch(p, headerOptions)).join("\n");
72085
- }
72086
- const ret = [];
72087
- if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) {
72088
- ret.push("Index: " + patch.oldFileName);
72089
- }
72090
- if (headerOptions.includeUnderline) {
72091
- ret.push("===================================================================");
72092
- }
72093
- if (headerOptions.includeFileHeaders) {
72094
- ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
72095
- ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
72096
- }
72097
- for (let i = 0; i < patch.hunks.length; i++) {
72098
- const hunk = patch.hunks[i];
72099
- if (hunk.oldLines === 0) {
72100
- hunk.oldStart -= 1;
72101
- }
72102
- if (hunk.newLines === 0) {
72103
- hunk.newStart -= 1;
72104
- }
72105
- ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
72106
- for (const line of hunk.lines) {
72107
- ret.push(line);
72108
- }
72109
- }
72110
- return ret.join("\n") + "\n";
72111
- }
72112
- function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
72113
- if (typeof options === "function") {
72114
- options = { callback: options };
72115
- }
72116
- if (!(options === null || options === void 0 ? void 0 : options.callback)) {
72117
- const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
72118
- if (!patchObj) {
72119
- return;
72120
- }
72121
- return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions);
72122
- } else {
72123
- const { callback } = options;
72124
- structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
72125
- if (!patchObj) {
72126
- callback(void 0);
72127
- } else {
72128
- callback(formatPatch(patchObj, options.headerOptions));
72129
- }
72130
- } }));
72131
- }
72132
- }
72133
- function splitLines(text) {
72134
- const hasTrailingNl = text.endsWith("\n");
72135
- const result = text.split("\n").map((line) => line + "\n");
72136
- if (hasTrailingNl) {
72137
- result.pop();
72138
- } else {
72139
- result.push(result.pop().slice(0, -1));
72140
- }
72141
- return result;
72142
- }
72143
-
72144
71755
  // src/utils/edit-diff.ts
72145
71756
  function generateEditDiff(oldText, newText, filePath) {
72146
71757
  const patch = createTwoFilesPatch(
@@ -74052,7 +73663,9 @@ function takeAttentionRing(host) {
74052
73663
  return attention;
74053
73664
  }
74054
73665
  function bindInteractiveRuntimeEvents(host) {
73666
+ let executionWork;
74055
73667
  host.agent.subscribe((event) => {
73668
+ if (event.type === "agent_start" && !hasControllerTurnAuthority(host)) executionWork = host.executionState.beginWork();
74056
73669
  switch (event.type) {
74057
73670
  case "message_start":
74058
73671
  host.logDebug("message:start", { role: event.message?.role });
@@ -74172,10 +73785,10 @@ function bindInteractiveRuntimeEvents(host) {
74172
73785
  }
74173
73786
  });
74174
73787
  host.agent.subscribeSemantic((event) => {
74175
- handleSemanticAgentEvent(host, event);
73788
+ handleSemanticAgentEvent(host, event, executionWork);
74176
73789
  });
74177
73790
  }
74178
- function handleSemanticAgentEvent(host, event) {
73791
+ function handleSemanticAgentEvent(host, event, work) {
74179
73792
  switch (event.type) {
74180
73793
  case "turn_continues": {
74181
73794
  host.emitExtensionEvent({
@@ -74216,7 +73829,7 @@ function handleSemanticAgentEvent(host, event) {
74216
73829
  message: event.message,
74217
73830
  toolResults: event.toolResults
74218
73831
  });
74219
- const outcome = host.executionState.advanceFromCompletedTurn(event.message, event.toolResults || []);
73832
+ const outcome = work ? host.executionState.completeWork(work, event.message, event.toolResults || []) : { changed: false };
74220
73833
  host.logDebug("execution:turn_completed", {
74221
73834
  turnIndex: host._semanticTurnIndex,
74222
73835
  changed: outcome.changed,
@@ -74251,7 +73864,7 @@ function handleSemanticAgentEvent(host, event) {
74251
73864
  message: event.message,
74252
73865
  toolResults: event.toolResults
74253
73866
  });
74254
- const outcome = host.executionState.handleTurnFailed();
73867
+ const outcome = work ? host.executionState.failWork(work) : { changed: false };
74255
73868
  host.logDebug("execution:turn_failed", {
74256
73869
  turnIndex: host._semanticTurnIndex,
74257
73870
  changed: outcome.changed,
@@ -74496,14 +74109,6 @@ function handleToolEnd(host, event) {
74496
74109
  false
74497
74110
  );
74498
74111
  }
74499
- if (event.toolName === "manage_todo_list") {
74500
- const details = event.result?.details;
74501
- if (details?.todos) {
74502
- host.executionState.replace(createExecutionStateFromTodos(details.todos));
74503
- host.persistExecutionState();
74504
- void host.refreshTodoWidget();
74505
- }
74506
- }
74507
74112
  host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
74508
74113
  host.emitExtensionEvent({
74509
74114
  type: "tool:execution:end",
@@ -76836,8 +76441,9 @@ function createExtensionContextForCommands(host) {
76836
76441
  host.executionReminder = text || null;
76837
76442
  },
76838
76443
  getExecutionState: () => host.executionState.read(),
76839
- setExecutionState: (state) => {
76840
- const next = state ? host.executionState.replace(state) : host.executionState.clear();
76444
+ getExecutionStateExplanation: () => host.executionState.inactiveExplanation(),
76445
+ setExecutionState: (state, reason) => {
76446
+ const next = reason ? host.executionState.applyToolState(state, reason) : host.executionState.replace(state);
76841
76447
  host.persistExecutionState();
76842
76448
  void host.refreshTodoWidget();
76843
76449
  return next;
@@ -79647,7 +79253,7 @@ function buildCodingAgentGuidelinesSection(tools = []) {
79647
79253
  const guidelines = [
79648
79254
  "Handle coding tasks by analyzing, planning, or making changes as the available tools and user request allow; do not stop at analysis when execution is expected.",
79649
79255
  `Keep going until the user's task is completely resolved before ending your turn. If you announce a next step (for example, "now run the tests"), execute it in the same turn instead of describing it; only end your turn when the task is done or you genuinely need user input.`,
79650
- ...hasTodoTool ? ["For multi-step tasks, set up progress tracking with manage_todo_list before starting, and keep exactly one step in progress until every step is complete."] : [],
79256
+ ...hasTodoTool ? ["Use manage_todo_list only when the user explicitly requests todo/task tracking, never for internal planning or runtime subagent progress."] : [],
79651
79257
  "Work in the current workspace, preserve user changes, and keep edits focused.",
79652
79258
  "Inspect the relevant code before changing it. Use file tools for workspace writes; do not use shell redirection or heredocs to bypass write_file/edit_file guards.",
79653
79259
  "Run the most relevant existing test, build, or check after file changes when practical.",
@@ -79739,10 +79345,14 @@ function shouldCliAutoCompactTokens(params) {
79739
79345
  const tokenLimit = getAutoCompactTokenLimit(params.contextWindow, params.reserveTokens);
79740
79346
  return tokenLimit !== void 0 && params.tokens > tokenLimit;
79741
79347
  }
79742
- function createCliCompactionBudget(params) {
79743
- const contextWindow = params.contextWindow ?? 0;
79744
- const reserveTokens = params.reserveTokens ?? DEFAULT_COMPACTION_CONFIG.reserveTokens;
79745
- return () => getAutoCompactTokenLimit(contextWindow, reserveTokens);
79348
+ function createCliCompactionBudget(getCurrent) {
79349
+ return () => {
79350
+ const current = getCurrent();
79351
+ return getAutoCompactTokenLimit(
79352
+ current.contextWindow ?? 0,
79353
+ current.reserveTokens ?? DEFAULT_COMPACTION_CONFIG.reserveTokens
79354
+ );
79355
+ };
79746
79356
  }
79747
79357
  async function createCliAutoCompactionResult(params) {
79748
79358
  if (params.context.signal?.aborted) {
@@ -80539,9 +80149,12 @@ function appendWarningSummary(host, message) {
80539
80149
  host.safeRequestRender();
80540
80150
  }
80541
80151
  async function recoverHardStalledTurn(host, stalledMs) {
80152
+ const controller = host.agentSessionController;
80542
80153
  host.continuationStallSinceMs = void 0;
80543
80154
  host.logDebug("continuation_timeout:hard_stall_recovery", { stalledMs });
80544
- host.agentSessionController?.abort();
80155
+ controller?.abort();
80156
+ const work = controller?.workIdentity;
80157
+ const fence = host.executionState.capture();
80545
80158
  try {
80546
80159
  await Promise.race([
80547
80160
  host.agentSessionController?.waitForIdle() ?? Promise.resolve(),
@@ -80552,6 +80165,9 @@ async function recoverHardStalledTurn(host, stalledMs) {
80552
80165
  error: error instanceof Error ? error.message : String(error)
80553
80166
  });
80554
80167
  }
80168
+ if (host.agentSessionController !== controller || !host.executionState.isCurrent(fence)) return;
80169
+ const currentWork = controller?.workIdentity;
80170
+ if (work?.sessionId !== currentWork?.sessionId || work?.generation !== currentWork?.generation) return;
80555
80171
  host.agent.resetProcessingState();
80556
80172
  host.isProcessing = false;
80557
80173
  host.setSubmitLock(false);
@@ -80572,6 +80188,7 @@ async function recoverHardStalledTurn(host, stalledMs) {
80572
80188
  }
80573
80189
  function scheduleContinuationTimeout(host) {
80574
80190
  host.clearContinuationTimeout("reschedule");
80191
+ const fence = host.executionState.capture();
80575
80192
  const timeoutMs = getContinuationTimeoutMs();
80576
80193
  host.logDebug("continuation_timeout:start", {
80577
80194
  timeoutMs,
@@ -80579,6 +80196,7 @@ function scheduleContinuationTimeout(host) {
80579
80196
  queueLength: host.agentSessionController?.pendingMessageCount ?? 0
80580
80197
  });
80581
80198
  const check = () => {
80199
+ if (!host.executionState.isCurrent(fence)) return;
80582
80200
  host.continuationTimeoutHandle = void 0;
80583
80201
  const state = host.executionState.read();
80584
80202
  if (!state.awaitingContinuation || isWaitingForUserInteraction(host)) {
@@ -80665,6 +80283,7 @@ function createInteractiveAgentSessionController(host) {
80665
80283
  }
80666
80284
  let retryElapsedTicker;
80667
80285
  let retryElapsedStartedAt = 0;
80286
+ let executionWork;
80668
80287
  let autoCompactBeforeStats = null;
80669
80288
  const attention = cliAttention(host);
80670
80289
  const stopRetryElapsedTicker = () => {
@@ -80712,7 +80331,10 @@ function createInteractiveAgentSessionController(host) {
80712
80331
  },
80713
80332
  // Same auto-compact limit the threshold decision uses; a checkpoint whose
80714
80333
  // summary + retained tail would still exceed it is refused.
80715
- getCompactionBudgetTokens: createCliCompactionBudget({ contextWindow: host.options.model?.contextWindow }),
80334
+ getCompactionBudgetTokens: createCliCompactionBudget(() => ({
80335
+ contextWindow: host.options.model?.contextWindow,
80336
+ reserveTokens: host.options.settingsManager.getAutoCompactReserveTokens()
80337
+ })),
80716
80338
  getAutoContinueMessage: () => host.getTodoAutoContinueMessage(),
80717
80339
  classifyFailure: (context) => classifyCliFailure(context),
80718
80340
  retry: createCliRetryPolicy(
@@ -80752,6 +80374,8 @@ function createInteractiveAgentSessionController(host) {
80752
80374
  },
80753
80375
  onEvent: (event) => {
80754
80376
  stopRetryElapsedTicker();
80377
+ if (event.type === "session_work_started") executionWork = host.executionState.beginWork();
80378
+ if (event.type === "session_invalidated") executionWork = void 0;
80755
80379
  host.sessionTrace.noteRuntimeEvent(event.type, event);
80756
80380
  if (event.type === "session_work_started" || event.type === "session_invalidated" || event.type === "session_quiescent") {
80757
80381
  if (event.type === "session_quiescent") host.setControllerBusy(false);
@@ -80811,7 +80435,7 @@ function createInteractiveAgentSessionController(host) {
80811
80435
  message: event.message,
80812
80436
  toolResults: event.toolResults
80813
80437
  });
80814
- const outcome = host.executionState.advanceFromCompletedTurn(event.message, event.toolResults || []);
80438
+ const outcome = executionWork ? host.executionState.completeWork(executionWork, event.message, event.toolResults || []) : { changed: false };
80815
80439
  host.logDebug("execution:turn_completed", {
80816
80440
  turnIndex: host._semanticTurnIndex,
80817
80441
  changed: outcome.changed,
@@ -80840,7 +80464,7 @@ function createInteractiveAgentSessionController(host) {
80840
80464
  toolResults: []
80841
80465
  });
80842
80466
  }
80843
- const outcome = host.executionState.handleTurnFailed();
80467
+ const outcome = executionWork ? host.executionState.failWork(executionWork) : { changed: false };
80844
80468
  host.logDebug("execution:turn_failed_terminal", {
80845
80469
  turnIndex: host._semanticTurnIndex,
80846
80470
  changed: outcome.changed,
@@ -80873,10 +80497,8 @@ function createInteractiveAgentSessionController(host) {
80873
80497
  lifecycle: host.executionState.read().lifecycle,
80874
80498
  reason: event.reason
80875
80499
  });
80876
- if (outcome.cleared || outcome.terminalSummary) {
80877
- host.persistExecutionState();
80878
- void host.refreshTodoWidget();
80879
- }
80500
+ host.persistExecutionState();
80501
+ void host.refreshTodoWidget();
80880
80502
  if (outcome.terminalSummary) {
80881
80503
  host.appendWarningSummary(outcome.terminalSummary);
80882
80504
  }
@@ -81179,6 +80801,8 @@ var RuntimeModeBlockInjector = class {
81179
80801
  }
81180
80802
  options;
81181
80803
  lastKey = null;
80804
+ /** Exact frozen block, including its consumed one-shot transition. */
80805
+ lastFrozenBlock = null;
81182
80806
  /**
81183
80807
  * Request-view overlay. While active, the CURRENT block is re-derived on
81184
80808
  * every request from the live message snapshot and applied to the latest
@@ -81190,6 +80814,7 @@ var RuntimeModeBlockInjector = class {
81190
80814
  overlayActive = false;
81191
80815
  reset() {
81192
80816
  this.lastKey = null;
80817
+ this.lastFrozenBlock = null;
81193
80818
  this.overlayActive = true;
81194
80819
  }
81195
80820
  /**
@@ -81222,7 +80847,8 @@ var RuntimeModeBlockInjector = class {
81222
80847
  if (!this.overlayActive) return null;
81223
80848
  const state = this.options.getState();
81224
80849
  const block = buildRuntimeModeContext(state);
81225
- if (messages && lastUserMessageCarriesRuntimeBlock(messages, block)) {
80850
+ const frozenCurrent = this.lastKey === runtimeModeBlockKey(state) ? this.lastFrozenBlock : null;
80851
+ if (messages && (lastUserMessageCarriesRuntimeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesRuntimeBlock(messages, frozenCurrent))) {
81226
80852
  this.overlayActive = false;
81227
80853
  return null;
81228
80854
  }
@@ -81234,7 +80860,8 @@ var RuntimeModeBlockInjector = class {
81234
80860
  this.lastKey = runtimeModeBlockKey(state);
81235
80861
  if (state.pendingTransition) this.options.consumeTransition();
81236
80862
  this.options.noteTrace(state);
81237
- return buildRuntimeModeContext(state);
80863
+ this.lastFrozenBlock = buildRuntimeModeContext(state);
80864
+ return this.lastFrozenBlock;
81238
80865
  }
81239
80866
  };
81240
80867
 
@@ -82047,8 +81674,9 @@ async function loadInteractiveExtensions(host) {
82047
81674
  host.executionReminder = text || null;
82048
81675
  },
82049
81676
  getExecutionState: () => host.executionState.read(),
82050
- setExecutionState: (state) => {
82051
- const next = state ? host.executionState.replace(state) : host.executionState.clear();
81677
+ getExecutionStateExplanation: () => host.executionState.inactiveExplanation(),
81678
+ setExecutionState: (state, reason) => {
81679
+ const next = reason ? host.executionState.applyToolState(state, reason) : host.executionState.replace(state);
82052
81680
  host.persistExecutionState();
82053
81681
  void host.refreshTodoWidget();
82054
81682
  return next;
@@ -82562,7 +82190,7 @@ var InteractiveMode = class {
82562
82190
  async init() {
82563
82191
  const activeSession = this.sessionManager.getActiveSession();
82564
82192
  this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
82565
- const { Agent } = await import("./chunks/src-EVCOTFBU.js");
82193
+ const { Agent } = await import("./chunks/src-DV4UYUNJ.js");
82566
82194
  this.agent = new Agent({
82567
82195
  initialState: {
82568
82196
  systemPrompt: this.buildSystemPrompt(),
@@ -83333,8 +82961,9 @@ async function loadPrintModeExtensions(params) {
83333
82961
  }
83334
82962
  },
83335
82963
  getExecutionState: () => executionState.read(),
83336
- setExecutionState: (state) => {
83337
- const nextState = executionState.replace(state);
82964
+ getExecutionStateExplanation: () => executionState.inactiveExplanation(),
82965
+ setExecutionState: (state, reason) => {
82966
+ const nextState = reason ? executionState.applyToolState(state, reason) : executionState.replace(state);
83338
82967
  const session = params.sessionManager.getActiveSession();
83339
82968
  if (session) {
83340
82969
  session.metadata.executionState = executionState.createMetadata();
@@ -83420,7 +83049,7 @@ async function runPrintMode(params) {
83420
83049
  `);
83421
83050
  console.log("Assistant: ");
83422
83051
  }
83423
- const { Agent: AgentClass } = await import("./chunks/src-EVCOTFBU.js");
83052
+ const { Agent: AgentClass } = await import("./chunks/src-DV4UYUNJ.js");
83424
83053
  let agent;
83425
83054
  const printModeExtensions = await loadPrintModeExtensions({
83426
83055
  cwd: runtime.cwd,
@@ -83499,10 +83128,10 @@ async function runPrintMode(params) {
83499
83128
  latestCompactionTimestamp: runtime.sessionManager.getLatestCompactionTimestamp(),
83500
83129
  isContextOverflowError: isCliContextOverflowError
83501
83130
  }),
83502
- getCompactionBudgetTokens: createCliCompactionBudget({
83131
+ getCompactionBudgetTokens: createCliCompactionBudget(() => ({
83503
83132
  contextWindow: runtime.model.contextWindow,
83504
83133
  reserveTokens: runtime.settingsManager.getAutoCompactReserveTokens()
83505
- }),
83134
+ })),
83506
83135
  compaction: createPrintModeCompactionHandler({
83507
83136
  runner: printModeExtensions.runner,
83508
83137
  model: runtime.model,
@@ -83807,8 +83436,9 @@ async function loadJsonModeExtensions(params) {
83807
83436
  }
83808
83437
  },
83809
83438
  getExecutionState: () => executionState.read(),
83810
- setExecutionState: (state) => {
83811
- const nextState = executionState.replace(state);
83439
+ getExecutionStateExplanation: () => executionState.inactiveExplanation(),
83440
+ setExecutionState: (state, reason) => {
83441
+ const nextState = reason ? executionState.applyToolState(state, reason) : executionState.replace(state);
83812
83442
  const session = params.runtime.sessionManager.getActiveSession();
83813
83443
  if (session) {
83814
83444
  session.metadata.executionState = executionState.createMetadata();
@@ -83861,14 +83491,15 @@ async function loadJsonModeExtensions(params) {
83861
83491
  false
83862
83492
  );
83863
83493
  runner.setUIContext(uiContext);
83864
- await restoreExtensionProviderCredentials(params.runtime.modelRegistry);
83865
- const extensionTools = filterEnabledTools(convertExtensionTools(extensions), params.runtime.settingsManager);
83866
- availableTools = [...availableTools, ...extensionTools];
83867
- return {
83868
- runner,
83869
- extensionTools,
83870
- extensionCount: extensions.length
83871
- };
83494
+ try {
83495
+ await restoreExtensionProviderCredentials(params.runtime.modelRegistry);
83496
+ const extensionTools = filterEnabledTools(convertExtensionTools(extensions), params.runtime.settingsManager);
83497
+ availableTools = [...availableTools, ...extensionTools];
83498
+ return { runner, extensionTools, extensionCount: extensions.length };
83499
+ } catch (error) {
83500
+ await runner.dispose("shutdown");
83501
+ throw error;
83502
+ }
83872
83503
  }
83873
83504
  function createJsonEventsTransportStreamFn(streamFn) {
83874
83505
  return createTransportDiagnosticsStreamFn(streamFn ?? streamSimple, logTransportLifecycle);
@@ -83895,6 +83526,7 @@ async function runJsonEventsMode(params) {
83895
83526
  const completedSessionControlRequests = /* @__PURE__ */ new Map();
83896
83527
  const completedSidechatRequests = /* @__PURE__ */ new Map();
83897
83528
  const ensureRuntimeInFlight = /* @__PURE__ */ new Map();
83529
+ let runtimeClosing = false;
83898
83530
  let activeSidechat = null;
83899
83531
  let activeSidechatPromise = null;
83900
83532
  let sidechatChainStopped = false;
@@ -84273,7 +83905,7 @@ async function runJsonEventsMode(params) {
84273
83905
  return;
84274
83906
  }
84275
83907
  const parent = agent;
84276
- const { Agent: AgentClass } = await import("./chunks/src-EVCOTFBU.js");
83908
+ const { Agent: AgentClass } = await import("./chunks/src-DV4UYUNJ.js");
84277
83909
  const sideAgent = new AgentClass({
84278
83910
  initialState: {
84279
83911
  systemPrompt: parent.state.systemPrompt,
@@ -84564,6 +84196,11 @@ async function runJsonEventsMode(params) {
84564
84196
  disposeSemanticSubscription = void 0;
84565
84197
  controller?.dispose();
84566
84198
  controller = void 0;
84199
+ if (agent) {
84200
+ agent.abort();
84201
+ await agent.waitForIdle();
84202
+ agent.releaseTransport();
84203
+ }
84567
84204
  agent = void 0;
84568
84205
  try {
84569
84206
  await runtime?.sessionManager.save();
@@ -84586,6 +84223,7 @@ async function runJsonEventsMode(params) {
84586
84223
  }
84587
84224
  }
84588
84225
  async function ensureRuntime(requestedCwd) {
84226
+ if (runtimeClosing) throw new Error("JSON events runtime is shutting down");
84589
84227
  if (params.mockResponse !== void 0) return;
84590
84228
  const effectiveCwd = requestedCwd ?? process.cwd();
84591
84229
  const inFlight = ensureRuntimeInFlight.get(effectiveCwd);
@@ -84621,8 +84259,13 @@ async function runJsonEventsMode(params) {
84621
84259
  if (runtime.initialModel.unconfigured || controller) {
84622
84260
  return;
84623
84261
  }
84624
- const { Agent: AgentClass } = await import("./chunks/src-EVCOTFBU.js");
84262
+ const { Agent: AgentClass } = await import("./chunks/src-DV4UYUNJ.js");
84263
+ if (runtimeClosing) return;
84625
84264
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
84265
+ if (runtimeClosing) {
84266
+ await jsonModeExtensions.runner.dispose("shutdown");
84267
+ return;
84268
+ }
84626
84269
  extensionRunner = jsonModeExtensions.runner;
84627
84270
  const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
84628
84271
  const restoredApiKey = runtime.modelRegistry.getApiKey(runtime.model);
@@ -84683,10 +84326,10 @@ async function runJsonEventsMode(params) {
84683
84326
  latestCompactionTimestamp: runtime.sessionManager.getLatestCompactionTimestamp(),
84684
84327
  isContextOverflowError: isCliContextOverflowError
84685
84328
  }),
84686
- getCompactionBudgetTokens: createCliCompactionBudget({
84329
+ getCompactionBudgetTokens: createCliCompactionBudget(() => ({
84687
84330
  contextWindow: runtime.model.contextWindow,
84688
84331
  reserveTokens: runtime.settingsManager.getAutoCompactReserveTokens()
84689
- }),
84332
+ })),
84690
84333
  compaction: {
84691
84334
  compact: async (context) => createCliAutoCompactionResult({
84692
84335
  context,
@@ -85034,6 +84677,7 @@ async function runJsonEventsMode(params) {
85034
84677
  continue;
85035
84678
  }
85036
84679
  if (message.type === "shutdown") {
84680
+ runtimeClosing = true;
85037
84681
  shutdownActiveTurn(message.reason);
85038
84682
  sidechatChainStopped = true;
85039
84683
  activeSidechat?.abort();
@@ -85089,6 +84733,8 @@ async function runJsonEventsMode(params) {
85089
84733
  } finally {
85090
84734
  await activeTurnPromise;
85091
84735
  await activeSidechatPromise;
84736
+ runtimeClosing = true;
84737
+ await Promise.allSettled([...ensureRuntimeInFlight.values()]);
85092
84738
  await disposeRuntime("shutdown");
85093
84739
  }
85094
84740
  }
@@ -85220,7 +84866,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
85220
84866
  }
85221
84867
  async function createCliTestStreamFnFromEnv() {
85222
84868
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
85223
- return (await import("./chunks/test-stream-24BCZPP5.js")).createTestStreamFnFromSequenceEnv();
84869
+ return (await import("./chunks/test-stream-SWO34GSS.js")).createTestStreamFnFromSequenceEnv();
85224
84870
  }
85225
84871
  function resolveJsonEventsDetailFlag() {
85226
84872
  for (let index = 0; index < process.argv.length; index += 1) {