adhdev 0.6.47 → 0.6.49

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
@@ -2084,6 +2084,9 @@ var init_status_monitor = __esm({
2084
2084
  config;
2085
2085
  lastAlertTime = /* @__PURE__ */ new Map();
2086
2086
  generatingStartTimes = /* @__PURE__ */ new Map();
2087
+ longGeneratingAlerted = /* @__PURE__ */ new Map();
2088
+ lastProgressFingerprint = /* @__PURE__ */ new Map();
2089
+ lastProgressChangeAt = /* @__PURE__ */ new Map();
2087
2090
  constructor(config2) {
2088
2091
  this.config = { ...DEFAULT_MONITOR_CONFIG, ...config2 };
2089
2092
  }
@@ -2099,7 +2102,7 @@ var init_status_monitor = __esm({
2099
2102
  * Check status transition → return notification event array.
2100
2103
  * Called from each onTick() or detectStatusTransition().
2101
2104
  */
2102
- check(agentKey, status, now) {
2105
+ check(agentKey, status, now, progressFingerprint) {
2103
2106
  const events = [];
2104
2107
  if (this.config.approvalAlert && status === "waiting_approval") {
2105
2108
  if (this.shouldAlert(agentKey + ":approval", now)) {
@@ -2114,24 +2117,40 @@ var init_status_monitor = __esm({
2114
2117
  if (status === "generating" || status === "streaming") {
2115
2118
  if (!this.generatingStartTimes.has(agentKey)) {
2116
2119
  this.generatingStartTimes.set(agentKey, now);
2120
+ this.longGeneratingAlerted.set(agentKey, false);
2121
+ const initialFingerprint = progressFingerprint ?? "";
2122
+ this.lastProgressFingerprint.set(agentKey, initialFingerprint);
2123
+ this.lastProgressChangeAt.set(agentKey, now);
2124
+ }
2125
+ const currentFingerprint = progressFingerprint ?? "";
2126
+ const previousFingerprint = this.lastProgressFingerprint.get(agentKey);
2127
+ if (previousFingerprint !== currentFingerprint) {
2128
+ this.lastProgressFingerprint.set(agentKey, currentFingerprint);
2129
+ this.lastProgressChangeAt.set(agentKey, now);
2130
+ this.longGeneratingAlerted.set(agentKey, false);
2117
2131
  }
2118
2132
  if (this.config.longGeneratingAlert) {
2119
- const startedAt = this.generatingStartTimes.get(agentKey);
2120
- const elapsedSec = Math.round((now - startedAt) / 1e3);
2121
- if (elapsedSec > this.config.longGeneratingThresholdSec) {
2133
+ const progressChangedAt = this.lastProgressChangeAt.get(agentKey) || this.generatingStartTimes.get(agentKey);
2134
+ const elapsedSec = Math.round((now - progressChangedAt) / 1e3);
2135
+ const alreadyAlerted = this.longGeneratingAlerted.get(agentKey) === true;
2136
+ if (elapsedSec > this.config.longGeneratingThresholdSec && !alreadyAlerted) {
2122
2137
  if (this.shouldAlert(agentKey + ":long_gen", now)) {
2138
+ this.longGeneratingAlerted.set(agentKey, true);
2123
2139
  events.push({
2124
2140
  type: "monitor:long_generating",
2125
2141
  agentKey,
2126
2142
  elapsedSec,
2127
2143
  timestamp: now,
2128
- message: `${agentKey} has been generating for ${Math.round(elapsedSec / 60)}min`
2144
+ message: `${agentKey} output appears stuck for ${Math.round(elapsedSec / 60)}min`
2129
2145
  });
2130
2146
  }
2131
2147
  }
2132
2148
  }
2133
2149
  } else {
2134
2150
  this.generatingStartTimes.delete(agentKey);
2151
+ this.longGeneratingAlerted.delete(agentKey);
2152
+ this.lastProgressFingerprint.delete(agentKey);
2153
+ this.lastProgressChangeAt.delete(agentKey);
2135
2154
  }
2136
2155
  return events;
2137
2156
  }
@@ -2148,11 +2167,17 @@ var init_status_monitor = __esm({
2148
2167
  reset(agentKey) {
2149
2168
  if (agentKey) {
2150
2169
  this.generatingStartTimes.delete(agentKey);
2170
+ this.longGeneratingAlerted.delete(agentKey);
2171
+ this.lastProgressFingerprint.delete(agentKey);
2172
+ this.lastProgressChangeAt.delete(agentKey);
2151
2173
  for (const k of this.lastAlertTime.keys()) {
2152
2174
  if (k.startsWith(agentKey)) this.lastAlertTime.delete(k);
2153
2175
  }
2154
2176
  } else {
2155
2177
  this.generatingStartTimes.clear();
2178
+ this.longGeneratingAlerted.clear();
2179
+ this.lastProgressFingerprint.clear();
2180
+ this.lastProgressChangeAt.clear();
2156
2181
  this.lastAlertTime.clear();
2157
2182
  }
2158
2183
  }
@@ -2259,9 +2284,11 @@ var init_extension_provider_instance = __esm({
2259
2284
  // (generating_started, generating_completed, waiting_approval)
2260
2285
  // via its own detectAgentTransitions(). Emitting here would cause
2261
2286
  // duplicate toasts with slightly different content.
2262
- detectTransition(newStatus, _data) {
2287
+ detectTransition(newStatus, data) {
2263
2288
  const now = Date.now();
2264
2289
  const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
2290
+ const lastMsg = Array.isArray(data?.messages) && data.messages.length > 0 ? data.messages[data.messages.length - 1] : null;
2291
+ const progressFingerprint = agentStatus === "generating" ? `${lastMsg?.role || ""}:${typeof lastMsg?.content === "string" ? lastMsg.content : JSON.stringify(lastMsg?.content || "")}`.slice(-2e3) : void 0;
2265
2292
  if (agentStatus !== this.lastAgentStatus) {
2266
2293
  if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
2267
2294
  this.generatingStartedAt = now;
@@ -2271,7 +2298,7 @@ var init_extension_provider_instance = __esm({
2271
2298
  this.lastAgentStatus = agentStatus;
2272
2299
  }
2273
2300
  const agentKey = `${this.type}:ext`;
2274
- const monitorEvents = this.monitor.check(agentKey, agentStatus, now);
2301
+ const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
2275
2302
  for (const me of monitorEvents) {
2276
2303
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
2277
2304
  }
@@ -2705,6 +2732,8 @@ var init_ide_provider_instance = __esm({
2705
2732
  if (!chatStatus) return;
2706
2733
  const agentKey = `${this.type}:native`;
2707
2734
  const agentStatus = chatStatus === "streaming" || chatStatus === "generating" ? "generating" : chatStatus === "waiting_approval" ? "waiting_approval" : "idle";
2735
+ const lastMsg = Array.isArray(chatData?.messages) && chatData.messages.length > 0 ? chatData.messages[chatData.messages.length - 1] : null;
2736
+ const progressFingerprint = agentStatus === "generating" ? `${lastMsg?.role || ""}:${typeof lastMsg?.content === "string" ? lastMsg.content : JSON.stringify(lastMsg?.content || "")}`.slice(-2e3) : void 0;
2708
2737
  this.currentStatus = agentStatus;
2709
2738
  const lastStatus = this.lastAgentStatuses.get(agentKey) || "idle";
2710
2739
  if (agentStatus !== lastStatus) {
@@ -2734,7 +2763,7 @@ var init_ide_provider_instance = __esm({
2734
2763
  if (agentStatus === "waiting_approval" && this.settings.autoApprove && !this.autoApproveBusy) {
2735
2764
  this.autoApproveViaScript(chatData);
2736
2765
  }
2737
- const monitorEvents = this.monitor.check(agentKey, agentStatus, now);
2766
+ const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
2738
2767
  for (const me of monitorEvents) {
2739
2768
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
2740
2769
  }
@@ -7041,16 +7070,15 @@ var init_provider_cli_adapter = __esm({
7041
7070
  }
7042
7071
  FALLBACK_PROMPT = [
7043
7072
  /Type your message/i,
7044
- /^>\s*$/m,
7045
- // '>' alone on its own line
7046
- /[›❯]\s*[\r\n]/,
7047
- // prompt char followed by line ending (ANSI-stripped may not have $ at end)
7048
- /[›❯]\s*$/m,
7049
- // prompt char at end of line (multiline)
7050
7073
  /for\s*shortcuts/i,
7051
- // Claude Code prompt (ANSI strip may remove spaces → 'forshortcuts')
7074
+ // Claude Code prompt
7052
7075
  /\?\s*for\s*help/i,
7053
- /Press enter/i
7076
+ // Claude Code help prompt
7077
+ /Press enter/i,
7078
+ /^[>›❯]\s*$/i,
7079
+ // Prompt char as the complete evaluated string
7080
+ /[>›❯]\s*$/
7081
+ // Prompt char at the very end of evaluated string
7054
7082
  ];
7055
7083
  FALLBACK_GENERATING = [
7056
7084
  /[\u2800-\u28ff]/,
@@ -7067,12 +7095,8 @@ var init_provider_cli_adapter = __esm({
7067
7095
  /Always\s*allow/i,
7068
7096
  /\(y\/n\)/i,
7069
7097
  /\[Y\/n\]/i,
7070
- /Run\s+\w+\s+command/i,
7071
- // "Run bash command" etc — requires surrounding words to avoid false matches
7072
- /Yes,?\s*don'?t\s*ask/i,
7098
+ /Yes,?\s*don'?t\s*ask/i
7073
7099
  // "Yes, don't ask again" (Claude Code)
7074
- /\bDeny\b/i
7075
- // Word-boundary match — avoids "allow & deny" in /permissions menu text
7076
7100
  ];
7077
7101
  ProviderCliAdapter = class {
7078
7102
  constructor(provider, workingDir, extraArgs = []) {
@@ -7680,6 +7704,8 @@ var init_cli_provider_instance = __esm({
7680
7704
  const newStatus = adapterStatus.status;
7681
7705
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
7682
7706
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
7707
+ const partial2 = this.adapter.getPartialResponse();
7708
+ const progressFingerprint = newStatus === "generating" ? `${partial2 || ""}::${adapterStatus.messages.at(-1)?.content || ""}`.slice(-2e3) : void 0;
7683
7709
  if (newStatus !== this.lastStatus) {
7684
7710
  LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
7685
7711
  if (this.lastStatus === "idle" && newStatus === "generating") {
@@ -7768,7 +7794,7 @@ var init_cli_provider_instance = __esm({
7768
7794
  this.lastStatus = newStatus;
7769
7795
  }
7770
7796
  const agentKey = `${this.type}:cli`;
7771
- const monitorEvents = this.monitor.check(agentKey, newStatus, now);
7797
+ const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
7772
7798
  for (const me of monitorEvents) {
7773
7799
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
7774
7800
  }
@@ -24945,6 +24971,7 @@ var init_acp_provider_instance = __esm({
24945
24971
  const newStatus = this.currentStatus;
24946
24972
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
24947
24973
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
24974
+ const progressFingerprint = newStatus === "generating" ? `${this.partialContent}::${JSON.stringify(this.partialBlocks)}::${JSON.stringify(this.activeToolCalls.map((t) => ({ name: t.name, status: t.status })))}`.slice(-2e3) : void 0;
24948
24975
  if (newStatus !== this.lastStatus) {
24949
24976
  if (this.lastStatus === "idle" && newStatus === "generating") {
24950
24977
  this.generatingStartedAt = now;
@@ -24967,7 +24994,7 @@ var init_acp_provider_instance = __esm({
24967
24994
  this.lastStatus = newStatus;
24968
24995
  }
24969
24996
  const agentKey = `${this.type}:acp`;
24970
- const monitorEvents = this.monitor.check(agentKey, newStatus, now);
24997
+ const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
24971
24998
  for (const me of monitorEvents) {
24972
24999
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
24973
25000
  }
@@ -30862,7 +30889,7 @@ var init_adhdev_daemon = __esm({
30862
30889
  fs11 = __toESM(require("fs"));
30863
30890
  path14 = __toESM(require("path"));
30864
30891
  import_chalk2 = __toESM(require("chalk"));
30865
- pkgVersion = "0.6.47";
30892
+ pkgVersion = "0.6.49";
30866
30893
  if (pkgVersion === "unknown") {
30867
30894
  try {
30868
30895
  const possiblePaths = [