@adhdev/daemon-standalone 0.9.82-rc.215 → 0.9.82-rc.217

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/index.js CHANGED
@@ -57560,8 +57560,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
57560
57560
  const endRow = cursor.row;
57561
57561
  const currentSlice = curLines.slice(startRow, endRow).join("\n");
57562
57562
  const prevSlice = prevLines.slice(startRow, endRow).join("\n");
57563
- const result = currentSlice !== prevSlice;
57564
- trace.push({ kind: "section", text: `state[${stateId}] changed cond cursor_above=${cond.cursor_above} rows[${startRow},${endRow}) changed=${result}` });
57563
+ const didChange = currentSlice !== prevSlice;
57564
+ const result = cond.changed ? didChange : !didChange;
57565
+ trace.push({ kind: "section", text: `state[${stateId}] changed cond cursor_above=${cond.cursor_above} rows[${startRow},${endRow}) changed=${didChange} expected=${cond.changed} result=${result}` });
57565
57566
  return result;
57566
57567
  }
57567
57568
  if (isRegexCondition(cond)) {
@@ -58280,7 +58281,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
58280
58281
  "required": ["cursor_above", "changed"],
58281
58282
  "properties": {
58282
58283
  "cursor_above": { "type": "integer", "minimum": 1 },
58283
- "changed": { "type": "boolean", "const": true }
58284
+ "changed": { "type": "boolean" },
58285
+ "stable_ms": { "type": "integer", "minimum": 0 }
58284
58286
  }
58285
58287
  },
58286
58288
  "allCondition": {
@@ -58752,6 +58754,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
58752
58754
  var STARTUP_GRACE_MS = 2500;
58753
58755
  var BUSY_HOLD_MS = 6e3;
58754
58756
  var SUBMIT_DELAY_FLOOR_MS = 200;
58757
+ function collectChangedConditions(when) {
58758
+ if (!when) return [];
58759
+ if ("cursor_above" in when && "changed" in when) return [when];
58760
+ if ("all" in when) return when.all.flatMap((c) => collectChangedConditions(c));
58761
+ if ("any" in when) return when.any.flatMap((c) => collectChangedConditions(c));
58762
+ return [];
58763
+ }
58755
58764
  function countNewlines(s) {
58756
58765
  let n = 0;
58757
58766
  for (let i = 0; i < s.length; i += 1) if (s.charCodeAt(i) === 10) n += 1;
@@ -58857,6 +58866,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
58857
58866
  * Used by screen_active_hold_ms to suppress idle downshifts while
58858
58867
  * the terminal is still actively updating. */
58859
58868
  lastScreenChangedAt = 0;
58869
+ /** Per-cursor_above region last-changed timestamps for stable_ms tracking.
58870
+ * Key: cursor_above value. Value: last time that region changed. */
58871
+ regionLastChangedAt = /* @__PURE__ */ new Map();
58860
58872
  /** Timer that re-runs evaluate() once the hold window expires. Needed
58861
58873
  * because the PTY stops emitting once the agent finishes; without an
58862
58874
  * explicit wake-up there's nothing to trigger the busy → idle
@@ -59061,18 +59073,47 @@ ${formatManifestValidationIssues2(validation.issues)}`,
59061
59073
  const cursor = this.adapter.getCursorPosition();
59062
59074
  const currentLines = screen.split("\n").map((l) => l.endsWith("\r") ? l.slice(0, -1) : l);
59063
59075
  const ev = evaluate(this.spec, screen, cursor, this.prevScreenLines.length > 0 ? this.prevScreenLines : void 0);
59076
+ const now = Date.now();
59064
59077
  if (this.prevScreenLines.length > 0 && currentLines.join("\n") !== this.prevScreenLines.join("\n")) {
59065
- this.lastScreenChangedAt = Date.now();
59078
+ this.lastScreenChangedAt = now;
59079
+ }
59080
+ if (cursor && this.prevScreenLines.length > 0) {
59081
+ for (const state of this.spec.states) {
59082
+ const conditions = collectChangedConditions(state.when);
59083
+ for (const cond of conditions) {
59084
+ if (cond.stable_ms == null) continue;
59085
+ const startRow = Math.max(0, cursor.row - cond.cursor_above);
59086
+ const endRow = cursor.row;
59087
+ const cur = currentLines.slice(startRow, endRow).join("\n");
59088
+ const prev = this.prevScreenLines.slice(startRow, endRow).join("\n");
59089
+ if (cur !== prev) this.regionLastChangedAt.set(cond.cursor_above, now);
59090
+ }
59091
+ }
59066
59092
  }
59067
59093
  this.prevScreenLines = currentLines;
59068
59094
  let evState = ev.state;
59069
59095
  const busyHoldMs = this.spec.debounce?.busy_hold_ms ?? BUSY_HOLD_MS;
59070
59096
  if (this.currentStateId === "busy" && evState.id === "idle") {
59071
- const ageMs = Date.now() - this.lastBusyAt;
59097
+ const ageMs = now - this.lastBusyAt;
59072
59098
  if (ageMs < busyHoldMs) {
59073
59099
  evState = this.lastBusyState ?? evState;
59074
59100
  }
59075
59101
  }
59102
+ if (evState.id === (this.spec.default_state ?? "idle") && cursor) {
59103
+ const stableConditions = collectChangedConditions(
59104
+ this.spec.states.find((s) => s.id === evState.id)?.when
59105
+ ).filter((c) => c.changed === false && c.stable_ms != null);
59106
+ for (const cond of stableConditions) {
59107
+ const lastChanged = this.regionLastChangedAt.get(cond.cursor_above) ?? 0;
59108
+ const stableMs = cond.stable_ms;
59109
+ const stableAge = lastChanged > 0 ? now - lastChanged : Infinity;
59110
+ if (stableAge < stableMs) {
59111
+ evState = this.lastBusyState ?? { id: "busy", label: "Generating", title: null };
59112
+ this.scheduleBusyExpiry(stableMs - stableAge + 50);
59113
+ break;
59114
+ }
59115
+ }
59116
+ }
59076
59117
  const idleStateId = this.spec.default_state ?? "idle";
59077
59118
  const isModalState = (id) => id !== null && id !== "busy" && id !== idleStateId;
59078
59119
  if (isModalState(this.currentStateId) && evState.id === "busy") {
@@ -59085,7 +59126,6 @@ ${formatManifestValidationIssues2(validation.issues)}`,
59085
59126
  const screenActiveHoldMs = this.spec.debounce?.screen_active_hold_ms;
59086
59127
  let busyWakeMs = busyHoldMs;
59087
59128
  const postModalGraceMs = busyHoldMs;
59088
- const now = Date.now();
59089
59129
  const recentlyInModal = isModalState(this.currentStateId) || this.lastModalAt > 0 && now - this.lastModalAt < postModalGraceMs;
59090
59130
  const recentlyLeftModal = !recentlyInModal && this.lastModalExitAt > 0 && now - this.lastModalExitAt < postModalGraceMs;
59091
59131
  const screenActiveMs = screenActiveHoldMs ?? 0;
@@ -59097,15 +59137,14 @@ ${formatManifestValidationIssues2(validation.issues)}`,
59097
59137
  if (evState.id === "busy" && completionIdleRule && !recentlyInModal && !recentlyLeftModal && !screenIsActive) {
59098
59138
  const completionKey = matchesCompletionIdleRule(this.spec, ev, screen);
59099
59139
  if (completionKey) {
59100
- const now2 = Date.now();
59101
59140
  if (completionKey !== this.completionIdleKey) {
59102
59141
  this.completionIdleKey = completionKey;
59103
- this.completionIdleFirstSeenAt = now2;
59142
+ this.completionIdleFirstSeenAt = now;
59104
59143
  LOG2.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] completion_idle_after matched: key="${completionKey}"`);
59105
59144
  }
59106
59145
  const holdMs = Math.max(0, completionIdleRule.hold_ms || 0);
59107
59146
  const forceAfterMs = typeof completionIdleRule.force_after_ms === "number" ? completionIdleRule.force_after_ms : null;
59108
- const ageMs = now2 - this.completionIdleFirstSeenAt;
59147
+ const ageMs = now - this.completionIdleFirstSeenAt;
59109
59148
  if (ageMs >= holdMs) {
59110
59149
  const targetMatches = matchesCompletionIdleTargetState(this.spec, ev, screen, cursor);
59111
59150
  const forced = !targetMatches && forceAfterMs !== null && ageMs >= holdMs + forceAfterMs;