@cydm/pie 2.7.3 → 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-WLLZTG4W.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-F3U2TYDT.js";
90
- import "./chunks/chunk-MPTME6HX.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-E5JQ5SVA.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(/^( *)/);
@@ -52542,7 +52541,6 @@ function validateCompat(value, label) {
52542
52541
  "supportsEncryptedReasoning",
52543
52542
  "responsesContinuation",
52544
52543
  "supportsReasoningSummary",
52545
- "reasoningSummary",
52546
52544
  "timeoutReplay",
52547
52545
  "supportsStore",
52548
52546
  "supportsDeveloperRole",
@@ -52592,7 +52590,8 @@ function validateRemoteModel(profileId, model) {
52592
52590
  }
52593
52591
  if (!isPlainRecord(model.cost)) throw new Error(`Remote profile "${profileId}" model "${model.id}" has invalid cost values`);
52594
52592
  assertOnlyKeys(model.cost, ["input", "output", "cacheRead", "cacheWrite", "cacheWriteLong"], `Remote profile "${profileId}" model "${model.id}" cost`);
52595
- 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)) {
52596
52595
  throw new Error(`Remote profile "${profileId}" model "${model.id}" has invalid cost values`);
52597
52596
  }
52598
52597
  if (!Number.isSafeInteger(model.contextWindow) || Number(model.contextWindow) <= 0 || !Number.isSafeInteger(model.maxTokens) || Number(model.maxTokens) <= 0 || Number(model.maxTokens) > Number(model.contextWindow)) {
@@ -56525,11 +56524,12 @@ function createExtensionContext(extension, cwd, uiContext, abortFn, isIdleFn, ha
56525
56524
  setExecutionReminder(text) {
56526
56525
  actions?.setExecutionReminder(text);
56527
56526
  },
56527
+ getExecutionStateExplanation: () => actions?.getExecutionStateExplanation?.(),
56528
56528
  getExecutionState() {
56529
56529
  return actions?.getExecutionState?.() ?? createEmptyExecutionState();
56530
56530
  },
56531
- setExecutionState(state) {
56532
- return actions?.setExecutionState?.(state) ?? createEmptyExecutionState();
56531
+ setExecutionState(state, reason) {
56532
+ return actions?.setExecutionState?.(state, reason) ?? createEmptyExecutionState();
56533
56533
  },
56534
56534
  // Extended properties for subagent creation
56535
56535
  get apiKey() {
@@ -59307,11 +59307,11 @@ var TUI = class extends Container {
59307
59307
  this.stopped = true;
59308
59308
  if (this.previousLines.length > 0) {
59309
59309
  const targetRow = this.previousLines.length;
59310
- const lineDiff2 = targetRow - this.hardwareCursorRow;
59311
- if (lineDiff2 > 0) {
59312
- this.terminal.write(`\x1B[${lineDiff2}B`);
59313
- } else if (lineDiff2 < 0) {
59314
- 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`);
59315
59315
  }
59316
59316
  this.terminal.write("\r\n");
59317
59317
  }
@@ -59436,9 +59436,9 @@ var TUI = class extends Container {
59436
59436
  if (this.previousLines.length > newLines.length) {
59437
59437
  let buffer2 = "\x1B[?2026h";
59438
59438
  const targetRow = Math.max(0, newLines.length - 1);
59439
- const lineDiff3 = computeLineDiff(targetRow);
59440
- if (lineDiff3 > 0) buffer2 += `\x1B[${lineDiff3}B`;
59441
- 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`;
59442
59442
  buffer2 += "\r";
59443
59443
  const extraLines = this.previousLines.length - newLines.length;
59444
59444
  if (extraLines > height) {
@@ -59488,11 +59488,11 @@ var TUI = class extends Container {
59488
59488
  viewportTop += scroll;
59489
59489
  hardwareCursorRow = moveTargetRow;
59490
59490
  }
59491
- const lineDiff2 = computeLineDiff(moveTargetRow);
59492
- if (lineDiff2 > 0) {
59493
- buffer += `\x1B[${lineDiff2}B`;
59494
- } else if (lineDiff2 < 0) {
59495
- 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`;
59496
59496
  }
59497
59497
  buffer += appendStart ? "\r\n" : "\r";
59498
59498
  const renderEnd = Math.min(lastChanged, newLines.length - 1);
@@ -59550,7 +59550,7 @@ var TUI = class extends Container {
59550
59550
  `viewportTop: ${viewportTop}`,
59551
59551
  `cursorRow: ${this.cursorRow}`,
59552
59552
  `height: ${height}`,
59553
- `lineDiff: ${lineDiff2}`,
59553
+ `lineDiff: ${lineDiff}`,
59554
59554
  `hardwareCursorRow: ${hardwareCursorRow}`,
59555
59555
  `renderEnd: ${renderEnd}`,
59556
59556
  `finalCursorRow: ${finalCursorRow}`,
@@ -64303,7 +64303,8 @@ var ExtensionRunner = class {
64303
64303
  setPlanMode: (enabled, options) => this.actions.setPlanMode(enabled, options),
64304
64304
  setExecutionReminder: (text) => this.actions.setExecutionReminder(text),
64305
64305
  getExecutionState: () => this.actions.getExecutionState(),
64306
- setExecutionState: (state) => this.actions.setExecutionState(state),
64306
+ getExecutionStateExplanation: () => this.actions.getExecutionStateExplanation?.(),
64307
+ setExecutionState: (state, reason) => this.actions.setExecutionState(state, reason),
64307
64308
  get apiKey() {
64308
64309
  return runner.actions.apiKey;
64309
64310
  },
@@ -69998,16 +69999,42 @@ function getTextFromMessageContent(content) {
69998
69999
  }
69999
70000
  var ExecutionStateManager = class {
70000
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
+ }
70001
70028
  completeCount(state) {
70002
70029
  return state.steps.filter((step) => step.status === "completed").length;
70003
70030
  }
70004
70031
  isCompletionText(text) {
70005
70032
  return /完成|已完成|done|finished|completed|wrap[\s-]?up|all set|success/i.test(text);
70006
70033
  }
70007
- clearWithSummary(summary = null) {
70034
+ clearWithSummary(summary = null, reason = summary ? "failed_clear" : "completed_clear") {
70008
70035
  const cleared = createEmptyExecutionState();
70009
70036
  cleared.failureSummary = summary;
70010
- return this.store.replace(cleared);
70037
+ return this.store.replace(cleared, { source: "runtime", reason });
70011
70038
  }
70012
70039
  summarizeFailure(reason) {
70013
70040
  switch (reason) {
@@ -70028,7 +70055,7 @@ var ExecutionStateManager = class {
70028
70055
  }
70029
70056
  evaluateCompletedTurnLoop(previous, next, toolResults, assistantText) {
70030
70057
  if (next.mode !== "todo" || !next.loop) {
70031
- this.store.replace(next);
70058
+ this.store.write(next);
70032
70059
  return { changed: !this.unchanged(previous, next) };
70033
70060
  }
70034
70061
  const decision = evaluateTodoClosureAfterCompletedTurn(next, next.loop, {
@@ -70056,11 +70083,26 @@ var ExecutionStateManager = class {
70056
70083
  ...next,
70057
70084
  loop: decision.loop
70058
70085
  };
70059
- this.store.replace(updated);
70086
+ this.store.write(updated);
70060
70087
  return {
70061
70088
  changed: !this.unchanged(previous, updated)
70062
70089
  };
70063
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
+ }
70064
70106
  read() {
70065
70107
  return this.store.read();
70066
70108
  }
@@ -70085,9 +70127,9 @@ var ExecutionStateManager = class {
70085
70127
  return this.store.replace(pauseExecutionState({
70086
70128
  ...restored,
70087
70129
  awaitingContinuation: false
70088
- }, "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" });
70089
70131
  }
70090
- return this.store.replace(restored);
70132
+ return this.store.replace(restored, { source: "session", reason: "session_restore" });
70091
70133
  }
70092
70134
  getReminder() {
70093
70135
  return buildExecutionReminder(this.store.read());
@@ -70103,17 +70145,18 @@ var ExecutionStateManager = class {
70103
70145
  if (previous.awaitingContinuation) {
70104
70146
  return false;
70105
70147
  }
70106
- this.store.replace({
70148
+ this.store.write({
70107
70149
  ...previous,
70108
70150
  awaitingContinuation: true
70109
70151
  });
70110
70152
  return true;
70111
70153
  }
70112
- advanceFromCompletedTurn(message, toolResults = []) {
70113
- if (!message || message.role !== "assistant") {
70154
+ advanceFromCompletedTurn(message, toolResults = [], fence) {
70155
+ if (!this.store.isCurrent(fence) || !message || message.role !== "assistant") {
70114
70156
  return { changed: false };
70115
70157
  }
70116
70158
  const previous = this.store.read();
70159
+ if (previous.steps.length === 0) return { changed: false };
70117
70160
  const assistantText = getTextFromMessageContent(message.content);
70118
70161
  const next = maybeAdvanceTodoExecutionState(previous, {
70119
70162
  assistantText,
@@ -70133,7 +70176,8 @@ var ExecutionStateManager = class {
70133
70176
  }
70134
70177
  return state.loop.continuePrompt || void 0;
70135
70178
  }
70136
- handleTurnFailed() {
70179
+ handleTurnFailed(fence) {
70180
+ if (!this.store.isCurrent(fence)) return { changed: false };
70137
70181
  const previous = this.store.read();
70138
70182
  if (previous.mode !== "todo" || !previous.loop && previous.steps.length === 0) {
70139
70183
  return { changed: false };
@@ -70144,7 +70188,7 @@ var ExecutionStateManager = class {
70144
70188
  ...previous,
70145
70189
  loop: decision.loop
70146
70190
  }, this.summarizeFailure(decision.reason));
70147
- this.store.replace(paused);
70191
+ this.store.write(paused, { source: "runtime", reason: "pause_failed" });
70148
70192
  return {
70149
70193
  changed: true,
70150
70194
  terminalStatus: "paused",
@@ -70167,7 +70211,7 @@ var ExecutionStateManager = class {
70167
70211
  if (previous.mode !== "todo" || previous.lifecycle !== "paused" || previous.steps.length === 0) {
70168
70212
  return { changed: false };
70169
70213
  }
70170
- const next = this.store.replace(continueExecutionState(previous));
70214
+ const next = this.store.write(continueExecutionState(previous), { source: "runtime", reason: "advance" });
70171
70215
  return { changed: !this.unchanged(previous, next) };
70172
70216
  }
70173
70217
  markAwaitingContinuationStalled() {
@@ -70175,7 +70219,7 @@ var ExecutionStateManager = class {
70175
70219
  if (previous.mode !== "todo" || !previous.awaitingContinuation) {
70176
70220
  return { changed: false };
70177
70221
  }
70178
- this.clearWithSummary(this.summarizeFailure("stagnated"));
70222
+ this.clearWithSummary(this.summarizeFailure("stagnated"), "stalled_clear");
70179
70223
  return {
70180
70224
  changed: true,
70181
70225
  cleared: true,
@@ -70185,20 +70229,14 @@ var ExecutionStateManager = class {
70185
70229
  }
70186
70230
  abort() {
70187
70231
  const previous = this.store.read();
70188
- const decision = evaluateTodoClosureAfterAbort(previous.loop);
70189
- if (decision.action === "clear_aborted") {
70190
- return {
70191
- state: this.clearWithSummary(this.summarizeFailure(decision.reason)),
70192
- cleared: true,
70193
- terminalSummary: this.read().failureSummary || void 0
70194
- };
70195
- }
70196
- return { state: this.store.replace(abortExecutionState(previous)), cleared: false };
70232
+ return { state: this.store.replace(abortExecutionState(previous), { source: "runtime", reason: "abort" }), cleared: false };
70197
70233
  }
70198
70234
  continue() {
70199
70235
  return this.store.replace(continueExecutionState(this.store.read()));
70200
70236
  }
70201
70237
  applyUserTextLifecycle(text) {
70238
+ const work = this.work;
70239
+ const current = work && this.isWorkCurrent(work.token);
70202
70240
  const state = this.store.read();
70203
70241
  if (state.steps.length === 0) {
70204
70242
  return null;
@@ -70209,11 +70247,13 @@ var ExecutionStateManager = class {
70209
70247
  if (shouldPreserveExecutionStateForUserText(text)) {
70210
70248
  if (state.lifecycle === "paused" || state.lifecycle === "aborted") {
70211
70249
  this.store.replace(continueExecutionState(state));
70250
+ if (current && work) work.fence = this.capture();
70212
70251
  return "continued";
70213
70252
  }
70214
70253
  return null;
70215
70254
  }
70216
- this.store.replace(supersedeExecutionState());
70255
+ this.store.replace(supersedeExecutionState(), { source: "user", reason: "topic_switch" });
70256
+ if (current && work) work.fence = this.capture();
70217
70257
  return "cleared";
70218
70258
  }
70219
70259
  clearIfSupersededByUserMessage(messages) {
@@ -71712,436 +71752,6 @@ var AssistantMessageComponent = class extends Container {
71712
71752
  // src/components/tool-execution.ts
71713
71753
  import * as os5 from "node:os";
71714
71754
 
71715
- // ../../node_modules/diff/libesm/diff/base.js
71716
- var Diff = class {
71717
- diff(oldStr, newStr, options = {}) {
71718
- let callback;
71719
- if (typeof options === "function") {
71720
- callback = options;
71721
- options = {};
71722
- } else if ("callback" in options) {
71723
- callback = options.callback;
71724
- }
71725
- const oldString = this.castInput(oldStr, options);
71726
- const newString = this.castInput(newStr, options);
71727
- const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
71728
- const newTokens = this.removeEmpty(this.tokenize(newString, options));
71729
- return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
71730
- }
71731
- diffWithOptionsObj(oldTokens, newTokens, options, callback) {
71732
- var _a;
71733
- const done = (value) => {
71734
- value = this.postProcess(value, options);
71735
- if (callback) {
71736
- setTimeout(function() {
71737
- callback(value);
71738
- }, 0);
71739
- return void 0;
71740
- } else {
71741
- return value;
71742
- }
71743
- };
71744
- const newLen = newTokens.length, oldLen = oldTokens.length;
71745
- let editLength = 1;
71746
- let maxEditLength = newLen + oldLen;
71747
- if (options.maxEditLength != null) {
71748
- maxEditLength = Math.min(maxEditLength, options.maxEditLength);
71749
- }
71750
- const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;
71751
- const abortAfterTimestamp = Date.now() + maxExecutionTime;
71752
- const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
71753
- let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
71754
- if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
71755
- return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
71756
- }
71757
- let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
71758
- const execEditLength = () => {
71759
- for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
71760
- let basePath;
71761
- const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
71762
- if (removePath) {
71763
- bestPath[diagonalPath - 1] = void 0;
71764
- }
71765
- let canAdd = false;
71766
- if (addPath) {
71767
- const addPathNewPos = addPath.oldPos - diagonalPath;
71768
- canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
71769
- }
71770
- const canRemove = removePath && removePath.oldPos + 1 < oldLen;
71771
- if (!canAdd && !canRemove) {
71772
- bestPath[diagonalPath] = void 0;
71773
- continue;
71774
- }
71775
- if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
71776
- basePath = this.addToPath(addPath, true, false, 0, options);
71777
- } else {
71778
- basePath = this.addToPath(removePath, false, true, 1, options);
71779
- }
71780
- newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
71781
- if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
71782
- return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
71783
- } else {
71784
- bestPath[diagonalPath] = basePath;
71785
- if (basePath.oldPos + 1 >= oldLen) {
71786
- maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
71787
- }
71788
- if (newPos + 1 >= newLen) {
71789
- minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
71790
- }
71791
- }
71792
- }
71793
- editLength++;
71794
- };
71795
- if (callback) {
71796
- (function exec() {
71797
- setTimeout(function() {
71798
- if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
71799
- return callback(void 0);
71800
- }
71801
- if (!execEditLength()) {
71802
- exec();
71803
- }
71804
- }, 0);
71805
- })();
71806
- } else {
71807
- while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
71808
- const ret = execEditLength();
71809
- if (ret) {
71810
- return ret;
71811
- }
71812
- }
71813
- }
71814
- }
71815
- addToPath(path34, added, removed, oldPosInc, options) {
71816
- const last = path34.lastComponent;
71817
- if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
71818
- return {
71819
- oldPos: path34.oldPos + oldPosInc,
71820
- lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
71821
- };
71822
- } else {
71823
- return {
71824
- oldPos: path34.oldPos + oldPosInc,
71825
- lastComponent: { count: 1, added, removed, previousComponent: last }
71826
- };
71827
- }
71828
- }
71829
- extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
71830
- const newLen = newTokens.length, oldLen = oldTokens.length;
71831
- let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
71832
- while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
71833
- newPos++;
71834
- oldPos++;
71835
- commonCount++;
71836
- if (options.oneChangePerToken) {
71837
- basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
71838
- }
71839
- }
71840
- if (commonCount && !options.oneChangePerToken) {
71841
- basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
71842
- }
71843
- basePath.oldPos = oldPos;
71844
- return newPos;
71845
- }
71846
- equals(left, right, options) {
71847
- if (options.comparator) {
71848
- return options.comparator(left, right);
71849
- } else {
71850
- return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
71851
- }
71852
- }
71853
- removeEmpty(array) {
71854
- const ret = [];
71855
- for (let i = 0; i < array.length; i++) {
71856
- if (array[i]) {
71857
- ret.push(array[i]);
71858
- }
71859
- }
71860
- return ret;
71861
- }
71862
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
71863
- castInput(value, options) {
71864
- return value;
71865
- }
71866
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
71867
- tokenize(value, options) {
71868
- return Array.from(value);
71869
- }
71870
- join(chars) {
71871
- return chars.join("");
71872
- }
71873
- postProcess(changeObjects, options) {
71874
- return changeObjects;
71875
- }
71876
- get useLongestToken() {
71877
- return false;
71878
- }
71879
- buildValues(lastComponent, newTokens, oldTokens) {
71880
- const components = [];
71881
- let nextComponent;
71882
- while (lastComponent) {
71883
- components.push(lastComponent);
71884
- nextComponent = lastComponent.previousComponent;
71885
- delete lastComponent.previousComponent;
71886
- lastComponent = nextComponent;
71887
- }
71888
- components.reverse();
71889
- const componentLen = components.length;
71890
- let componentPos = 0, newPos = 0, oldPos = 0;
71891
- for (; componentPos < componentLen; componentPos++) {
71892
- const component = components[componentPos];
71893
- if (!component.removed) {
71894
- if (!component.added && this.useLongestToken) {
71895
- let value = newTokens.slice(newPos, newPos + component.count);
71896
- value = value.map(function(value2, i) {
71897
- const oldValue = oldTokens[oldPos + i];
71898
- return oldValue.length > value2.length ? oldValue : value2;
71899
- });
71900
- component.value = this.join(value);
71901
- } else {
71902
- component.value = this.join(newTokens.slice(newPos, newPos + component.count));
71903
- }
71904
- newPos += component.count;
71905
- if (!component.added) {
71906
- oldPos += component.count;
71907
- }
71908
- } else {
71909
- component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
71910
- oldPos += component.count;
71911
- }
71912
- }
71913
- return components;
71914
- }
71915
- };
71916
-
71917
- // ../../node_modules/diff/libesm/diff/line.js
71918
- var LineDiff = class extends Diff {
71919
- constructor() {
71920
- super(...arguments);
71921
- this.tokenize = tokenize;
71922
- }
71923
- equals(left, right, options) {
71924
- if (options.ignoreWhitespace) {
71925
- if (!options.newlineIsToken || !left.includes("\n")) {
71926
- left = left.trim();
71927
- }
71928
- if (!options.newlineIsToken || !right.includes("\n")) {
71929
- right = right.trim();
71930
- }
71931
- } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
71932
- if (left.endsWith("\n")) {
71933
- left = left.slice(0, -1);
71934
- }
71935
- if (right.endsWith("\n")) {
71936
- right = right.slice(0, -1);
71937
- }
71938
- }
71939
- return super.equals(left, right, options);
71940
- }
71941
- };
71942
- var lineDiff = new LineDiff();
71943
- function diffLines(oldStr, newStr, options) {
71944
- return lineDiff.diff(oldStr, newStr, options);
71945
- }
71946
- function tokenize(value, options) {
71947
- if (options.stripTrailingCr) {
71948
- value = value.replace(/\r\n/g, "\n");
71949
- }
71950
- const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
71951
- if (!linesAndNewlines[linesAndNewlines.length - 1]) {
71952
- linesAndNewlines.pop();
71953
- }
71954
- for (let i = 0; i < linesAndNewlines.length; i++) {
71955
- const line = linesAndNewlines[i];
71956
- if (i % 2 && !options.newlineIsToken) {
71957
- retLines[retLines.length - 1] += line;
71958
- } else {
71959
- retLines.push(line);
71960
- }
71961
- }
71962
- return retLines;
71963
- }
71964
-
71965
- // ../../node_modules/diff/libesm/patch/create.js
71966
- var INCLUDE_HEADERS = {
71967
- includeIndex: true,
71968
- includeUnderline: true,
71969
- includeFileHeaders: true
71970
- };
71971
- function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
71972
- let optionsObj;
71973
- if (!options) {
71974
- optionsObj = {};
71975
- } else if (typeof options === "function") {
71976
- optionsObj = { callback: options };
71977
- } else {
71978
- optionsObj = options;
71979
- }
71980
- if (typeof optionsObj.context === "undefined") {
71981
- optionsObj.context = 4;
71982
- }
71983
- const context = optionsObj.context;
71984
- if (optionsObj.newlineIsToken) {
71985
- throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
71986
- }
71987
- if (!optionsObj.callback) {
71988
- return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
71989
- } else {
71990
- const { callback } = optionsObj;
71991
- diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
71992
- const patch = diffLinesResultToPatch(diff);
71993
- callback(patch);
71994
- } }));
71995
- }
71996
- function diffLinesResultToPatch(diff) {
71997
- if (!diff) {
71998
- return;
71999
- }
72000
- diff.push({ value: "", lines: [] });
72001
- function contextLines(lines) {
72002
- return lines.map(function(entry) {
72003
- return " " + entry;
72004
- });
72005
- }
72006
- const hunks = [];
72007
- let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
72008
- for (let i = 0; i < diff.length; i++) {
72009
- const current = diff[i], lines = current.lines || splitLines(current.value);
72010
- current.lines = lines;
72011
- if (current.added || current.removed) {
72012
- if (!oldRangeStart) {
72013
- const prev = diff[i - 1];
72014
- oldRangeStart = oldLine;
72015
- newRangeStart = newLine;
72016
- if (prev) {
72017
- curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
72018
- oldRangeStart -= curRange.length;
72019
- newRangeStart -= curRange.length;
72020
- }
72021
- }
72022
- for (const line of lines) {
72023
- curRange.push((current.added ? "+" : "-") + line);
72024
- }
72025
- if (current.added) {
72026
- newLine += lines.length;
72027
- } else {
72028
- oldLine += lines.length;
72029
- }
72030
- } else {
72031
- if (oldRangeStart) {
72032
- if (lines.length <= context * 2 && i < diff.length - 2) {
72033
- for (const line of contextLines(lines)) {
72034
- curRange.push(line);
72035
- }
72036
- } else {
72037
- const contextSize = Math.min(lines.length, context);
72038
- for (const line of contextLines(lines.slice(0, contextSize))) {
72039
- curRange.push(line);
72040
- }
72041
- const hunk = {
72042
- oldStart: oldRangeStart,
72043
- oldLines: oldLine - oldRangeStart + contextSize,
72044
- newStart: newRangeStart,
72045
- newLines: newLine - newRangeStart + contextSize,
72046
- lines: curRange
72047
- };
72048
- hunks.push(hunk);
72049
- oldRangeStart = 0;
72050
- newRangeStart = 0;
72051
- curRange = [];
72052
- }
72053
- }
72054
- oldLine += lines.length;
72055
- newLine += lines.length;
72056
- }
72057
- }
72058
- for (const hunk of hunks) {
72059
- for (let i = 0; i < hunk.lines.length; i++) {
72060
- if (hunk.lines[i].endsWith("\n")) {
72061
- hunk.lines[i] = hunk.lines[i].slice(0, -1);
72062
- } else {
72063
- hunk.lines.splice(i + 1, 0, "\");
72064
- i++;
72065
- }
72066
- }
72067
- }
72068
- return {
72069
- oldFileName,
72070
- newFileName,
72071
- oldHeader,
72072
- newHeader,
72073
- hunks
72074
- };
72075
- }
72076
- }
72077
- function formatPatch(patch, headerOptions) {
72078
- if (!headerOptions) {
72079
- headerOptions = INCLUDE_HEADERS;
72080
- }
72081
- if (Array.isArray(patch)) {
72082
- if (patch.length > 1 && !headerOptions.includeFileHeaders) {
72083
- 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?)");
72084
- }
72085
- return patch.map((p) => formatPatch(p, headerOptions)).join("\n");
72086
- }
72087
- const ret = [];
72088
- if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) {
72089
- ret.push("Index: " + patch.oldFileName);
72090
- }
72091
- if (headerOptions.includeUnderline) {
72092
- ret.push("===================================================================");
72093
- }
72094
- if (headerOptions.includeFileHeaders) {
72095
- ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
72096
- ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
72097
- }
72098
- for (let i = 0; i < patch.hunks.length; i++) {
72099
- const hunk = patch.hunks[i];
72100
- if (hunk.oldLines === 0) {
72101
- hunk.oldStart -= 1;
72102
- }
72103
- if (hunk.newLines === 0) {
72104
- hunk.newStart -= 1;
72105
- }
72106
- ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
72107
- for (const line of hunk.lines) {
72108
- ret.push(line);
72109
- }
72110
- }
72111
- return ret.join("\n") + "\n";
72112
- }
72113
- function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
72114
- if (typeof options === "function") {
72115
- options = { callback: options };
72116
- }
72117
- if (!(options === null || options === void 0 ? void 0 : options.callback)) {
72118
- const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
72119
- if (!patchObj) {
72120
- return;
72121
- }
72122
- return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions);
72123
- } else {
72124
- const { callback } = options;
72125
- structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
72126
- if (!patchObj) {
72127
- callback(void 0);
72128
- } else {
72129
- callback(formatPatch(patchObj, options.headerOptions));
72130
- }
72131
- } }));
72132
- }
72133
- }
72134
- function splitLines(text) {
72135
- const hasTrailingNl = text.endsWith("\n");
72136
- const result = text.split("\n").map((line) => line + "\n");
72137
- if (hasTrailingNl) {
72138
- result.pop();
72139
- } else {
72140
- result.push(result.pop().slice(0, -1));
72141
- }
72142
- return result;
72143
- }
72144
-
72145
71755
  // src/utils/edit-diff.ts
72146
71756
  function generateEditDiff(oldText, newText, filePath) {
72147
71757
  const patch = createTwoFilesPatch(
@@ -74053,7 +73663,9 @@ function takeAttentionRing(host) {
74053
73663
  return attention;
74054
73664
  }
74055
73665
  function bindInteractiveRuntimeEvents(host) {
73666
+ let executionWork;
74056
73667
  host.agent.subscribe((event) => {
73668
+ if (event.type === "agent_start" && !hasControllerTurnAuthority(host)) executionWork = host.executionState.beginWork();
74057
73669
  switch (event.type) {
74058
73670
  case "message_start":
74059
73671
  host.logDebug("message:start", { role: event.message?.role });
@@ -74173,10 +73785,10 @@ function bindInteractiveRuntimeEvents(host) {
74173
73785
  }
74174
73786
  });
74175
73787
  host.agent.subscribeSemantic((event) => {
74176
- handleSemanticAgentEvent(host, event);
73788
+ handleSemanticAgentEvent(host, event, executionWork);
74177
73789
  });
74178
73790
  }
74179
- function handleSemanticAgentEvent(host, event) {
73791
+ function handleSemanticAgentEvent(host, event, work) {
74180
73792
  switch (event.type) {
74181
73793
  case "turn_continues": {
74182
73794
  host.emitExtensionEvent({
@@ -74217,7 +73829,7 @@ function handleSemanticAgentEvent(host, event) {
74217
73829
  message: event.message,
74218
73830
  toolResults: event.toolResults
74219
73831
  });
74220
- const outcome = host.executionState.advanceFromCompletedTurn(event.message, event.toolResults || []);
73832
+ const outcome = work ? host.executionState.completeWork(work, event.message, event.toolResults || []) : { changed: false };
74221
73833
  host.logDebug("execution:turn_completed", {
74222
73834
  turnIndex: host._semanticTurnIndex,
74223
73835
  changed: outcome.changed,
@@ -74252,7 +73864,7 @@ function handleSemanticAgentEvent(host, event) {
74252
73864
  message: event.message,
74253
73865
  toolResults: event.toolResults
74254
73866
  });
74255
- const outcome = host.executionState.handleTurnFailed();
73867
+ const outcome = work ? host.executionState.failWork(work) : { changed: false };
74256
73868
  host.logDebug("execution:turn_failed", {
74257
73869
  turnIndex: host._semanticTurnIndex,
74258
73870
  changed: outcome.changed,
@@ -74497,14 +74109,6 @@ function handleToolEnd(host, event) {
74497
74109
  false
74498
74110
  );
74499
74111
  }
74500
- if (event.toolName === "manage_todo_list") {
74501
- const details = event.result?.details;
74502
- if (details?.todos) {
74503
- host.executionState.replace(createExecutionStateFromTodos(details.todos));
74504
- host.persistExecutionState();
74505
- void host.refreshTodoWidget();
74506
- }
74507
- }
74508
74112
  host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
74509
74113
  host.emitExtensionEvent({
74510
74114
  type: "tool:execution:end",
@@ -76837,8 +76441,9 @@ function createExtensionContextForCommands(host) {
76837
76441
  host.executionReminder = text || null;
76838
76442
  },
76839
76443
  getExecutionState: () => host.executionState.read(),
76840
- setExecutionState: (state) => {
76841
- 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);
76842
76447
  host.persistExecutionState();
76843
76448
  void host.refreshTodoWidget();
76844
76449
  return next;
@@ -77124,6 +76729,7 @@ async function handleCompactCommand(host) {
77124
76729
  }
77125
76730
  host.sessionManager.appendCompactionCheckpoint({
77126
76731
  summary,
76732
+ checkpointSummary: verified.checkpointSummary,
77127
76733
  retainedTail: verified.retainedTail,
77128
76734
  tokensBefore,
77129
76735
  excludeFailure: preparation.excludedFailure
@@ -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) {
@@ -79797,7 +79407,7 @@ function stripStaleUsageBeforeCompaction(messages, latestCompactionTimestamp) {
79797
79407
  }
79798
79408
 
79799
79409
  // src/runtime/retry-policy.ts
79800
- var TRANSIENT_NETWORK_ERROR_PATTERN = /sse stream aborted|sse stream closed before end|sse stream ended before response completed|(?:read\s+)?ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNREFUSED|(?:read\s+|write\s+)?EPIPE|socket hang up|request timeout|client network socket disconnected before secure TLS connection was established|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated/i;
79410
+ var TRANSIENT_NETWORK_ERROR_PATTERN = /sse stream aborted|sse stream closed before end|sse stream ended before response completed|responses stream ended without a terminal event|(?:read\s+)?ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNREFUSED|(?:read\s+|write\s+)?EPIPE|socket hang up|request timeout|websocket upgrade refused|websocket handshake|websocket connection failed|websocket transport failed|connection closed before opening|client network socket disconnected before secure TLS connection was established|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated/i;
79801
79411
  var TLS_VALIDATION_ERROR_PATTERN = /certificate (?:has )?expired|certificate is not yet valid|unable to verify (?:the first certificate|certificate)|unable to get (?:local )?issuer certificate|self[-_ ]signed cert(?:ificate)?|CERT_HAS_EXPIRED|SELF_SIGNED_CERT|does not match certificate's altnames|ERR_TLS_CERT_ALTNAME_INVALID/i;
79802
79412
  var PROVIDER_TRANSIENT_ERROR_PATTERN = /overloaded|rate.?limit|too many requests|\b429\b|\b500\b|\b502\b|\b503\b|\b504\b|service.?unavailable|server error|internal error|retry delay|quota (?:has been |is )?exhausted/i;
79803
79413
  var USER_ABORT_PATTERN = /request was aborted|local abort signal|user abort|user_interrupt|interrupted by user|esc pressed|ctrl\+c/i;
@@ -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-TOJ3HCEX.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-TOJ3HCEX.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-TOJ3HCEX.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-TOJ3HCEX.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-6426JXLY.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) {