adhdev 0.6.57 → 0.6.58

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/index.js CHANGED
@@ -2386,6 +2386,8 @@ var init_chat_history = __esm({
2386
2386
  lastSeenCounts = /* @__PURE__ */ new Map();
2387
2387
  /** Last seen message hash per agent (deduplication) */
2388
2388
  lastSeenHashes = /* @__PURE__ */ new Map();
2389
+ /** Last seen append-only terminal transcript per agent */
2390
+ lastSeenTerminal = /* @__PURE__ */ new Map();
2389
2391
  rotated = false;
2390
2392
  /**
2391
2393
  * Append new messages to history
@@ -2443,10 +2445,51 @@ var init_chat_history = __esm({
2443
2445
  } catch {
2444
2446
  }
2445
2447
  }
2448
+ appendTerminalHistory(agentType, terminalHistory, sessionTitle, instanceId) {
2449
+ const next = String(terminalHistory || "");
2450
+ if (!next.trim()) return;
2451
+ try {
2452
+ const dedupKey = instanceId ? `${agentType}:${instanceId}:terminal` : `${agentType}:terminal`;
2453
+ const prev = this.lastSeenTerminal.get(dedupKey) || "";
2454
+ if (prev === next) return;
2455
+ let delta = "";
2456
+ if (!prev) {
2457
+ delta = next;
2458
+ } else if (next.startsWith(prev)) {
2459
+ delta = next.slice(prev.length);
2460
+ } else if (prev.includes(next)) {
2461
+ this.lastSeenTerminal.set(dedupKey, next);
2462
+ return;
2463
+ } else {
2464
+ delta = `
2465
+
2466
+ [terminal snapshot reset ${(/* @__PURE__ */ new Date()).toISOString()} | ${sessionTitle || agentType}]
2467
+ ${next}`;
2468
+ }
2469
+ if (!delta) {
2470
+ this.lastSeenTerminal.set(dedupKey, next);
2471
+ return;
2472
+ }
2473
+ const dir = path4.join(HISTORY_DIR, this.sanitize(agentType));
2474
+ fs3.mkdirSync(dir, { recursive: true });
2475
+ const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2476
+ const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
2477
+ const filePath = path4.join(dir, `${filePrefix}${date5}.terminal.log`);
2478
+ fs3.appendFileSync(filePath, delta, "utf-8");
2479
+ this.lastSeenTerminal.set(dedupKey, next);
2480
+ if (!this.rotated) {
2481
+ this.rotated = true;
2482
+ this.rotateOldFiles().catch(() => {
2483
+ });
2484
+ }
2485
+ } catch {
2486
+ }
2487
+ }
2446
2488
  /** Called when agent session is explicitly changed */
2447
2489
  onSessionChange(agentType) {
2448
2490
  this.lastSeenHashes.delete(agentType);
2449
2491
  this.lastSeenCounts.delete(agentType);
2492
+ this.lastSeenTerminal.delete(`${agentType}:terminal`);
2450
2493
  }
2451
2494
  /** Delete history files older than 30 days */
2452
2495
  async rotateOldFiles() {
@@ -2456,7 +2499,7 @@ var init_chat_history = __esm({
2456
2499
  const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
2457
2500
  for (const dir of agentDirs) {
2458
2501
  const dirPath = path4.join(HISTORY_DIR, dir.name);
2459
- const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl"));
2502
+ const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
2460
2503
  for (const file2 of files) {
2461
2504
  const filePath = path4.join(dirPath, file2);
2462
2505
  const stat = fs3.statSync(filePath);
@@ -3364,7 +3407,13 @@ async function handleReadChat(h, args) {
3364
3407
  _log(`${provider.category} adapter: ${adapter.cliType}`);
3365
3408
  const status = adapter.getStatus?.();
3366
3409
  if (status) {
3367
- return { success: true, messages: status.messages || [], status: status.status, activeModal: status.activeModal };
3410
+ return {
3411
+ success: true,
3412
+ messages: status.messages || [],
3413
+ status: status.status,
3414
+ activeModal: status.activeModal,
3415
+ terminalHistory: status.terminalHistory || ""
3416
+ };
3368
3417
  }
3369
3418
  }
3370
3419
  return { success: false, error: `${provider.category} adapter not found` };
@@ -16512,6 +16561,36 @@ function promptLikelyVisible(screenText, promptSnippet) {
16512
16561
  ).length;
16513
16562
  return matched >= required2;
16514
16563
  }
16564
+ function splitHistoryLines(text) {
16565
+ return String(text || "").split("\n").map((line) => line.replace(/\s+$/, ""));
16566
+ }
16567
+ function normalizeHistoryLine(line) {
16568
+ return String(line || "").replace(/\s+/g, " ").trim();
16569
+ }
16570
+ function mergeTerminalHistory(existing, snapshot) {
16571
+ const next = String(snapshot || "").trim();
16572
+ if (!next) return existing;
16573
+ const prev = String(existing || "").trim();
16574
+ if (!prev) return next;
16575
+ if (prev === next || prev.endsWith(next)) return prev;
16576
+ const prevLines = splitHistoryLines(prev);
16577
+ const nextLines = splitHistoryLines(next);
16578
+ const prevNorm = prevLines.map(normalizeHistoryLine);
16579
+ const nextNorm = nextLines.map(normalizeHistoryLine);
16580
+ const maxOverlap = Math.min(prevLines.length, nextLines.length);
16581
+ for (let overlap = maxOverlap; overlap >= 1; overlap -= 1) {
16582
+ const prevTail = prevNorm.slice(prevNorm.length - overlap);
16583
+ const nextHead = nextNorm.slice(0, overlap);
16584
+ if (prevTail.every((line, index) => line === nextHead[index])) {
16585
+ return [...prevLines, ...nextLines.slice(overlap)].join("\n").trim();
16586
+ }
16587
+ }
16588
+ const compactPrev = prevNorm.join("\n");
16589
+ const compactNext = nextNorm.join("\n");
16590
+ if (compactPrev.includes(compactNext)) return prev;
16591
+ return `${prev}
16592
+ ${next}`.trim();
16593
+ }
16515
16594
  function parsePatternEntry(x) {
16516
16595
  if (x instanceof RegExp) return x;
16517
16596
  if (x && typeof x === "object" && typeof x.source === "string") {
@@ -16588,6 +16667,7 @@ var init_provider_cli_adapter = __esm({
16588
16667
  this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
16589
16668
  this.sendDelayMs = typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0;
16590
16669
  this.sendKey = typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r";
16670
+ this.submitStrategy = provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo";
16591
16671
  this.cliScripts = provider.scripts || {};
16592
16672
  const scriptNames = Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function");
16593
16673
  if (scriptNames.length > 0) {
@@ -16602,6 +16682,7 @@ var init_provider_cli_adapter = __esm({
16602
16682
  provider;
16603
16683
  ptyProcess = null;
16604
16684
  messages = [];
16685
+ committedMessages = [];
16605
16686
  structuredMessages = [];
16606
16687
  currentStatus = "starting";
16607
16688
  onStatusChange = null;
@@ -16648,8 +16729,35 @@ var init_provider_cli_adapter = __esm({
16648
16729
  accumulatedRawBuffer = "";
16649
16730
  /** Current visible terminal screen snapshot */
16650
16731
  terminalScreen = new TerminalScreen(40, 120);
16732
+ /** Rolling append-only terminal transcript built from screen snapshots */
16733
+ terminalHistory = "";
16651
16734
  /** Max accumulated buffer size (last 50KB) */
16652
16735
  static MAX_ACCUMULATED_BUFFER = 5e4;
16736
+ currentTurnScope = null;
16737
+ syncMessageViews() {
16738
+ this.messages = [...this.committedMessages];
16739
+ this.structuredMessages = [...this.committedMessages];
16740
+ }
16741
+ sliceFromOffset(text, start) {
16742
+ if (!text) return "";
16743
+ if (!Number.isFinite(start) || start <= 0) return text;
16744
+ if (start >= text.length) return "";
16745
+ return text.slice(start);
16746
+ }
16747
+ buildParseInput(baseMessages, partialResponse, scope) {
16748
+ const buffer = scope ? this.sliceFromOffset(this.terminalHistory, scope.terminalHistoryStart) || this.sliceFromOffset(this.accumulatedBuffer, scope.bufferStart) || this.accumulatedBuffer : this.accumulatedBuffer;
16749
+ const rawBuffer = scope ? this.sliceFromOffset(this.accumulatedRawBuffer, scope.rawBufferStart) || this.accumulatedRawBuffer : this.accumulatedRawBuffer;
16750
+ const terminalHistory = scope ? this.sliceFromOffset(this.terminalHistory, scope.terminalHistoryStart) || this.terminalHistory : this.terminalHistory;
16751
+ return {
16752
+ buffer,
16753
+ rawBuffer,
16754
+ recentBuffer: buffer.slice(-1e3) || this.recentOutputBuffer,
16755
+ screenText: this.terminalScreen.getText(),
16756
+ terminalHistory,
16757
+ messages: [...baseMessages],
16758
+ partialResponse
16759
+ };
16760
+ }
16653
16761
  setStatus(status, trigger) {
16654
16762
  const prev = this.currentStatus;
16655
16763
  if (prev === status) return;
@@ -16664,6 +16772,7 @@ var init_provider_cli_adapter = __esm({
16664
16772
  approvalKeys;
16665
16773
  sendDelayMs;
16666
16774
  sendKey;
16775
+ submitStrategy;
16667
16776
  /** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
16668
16777
  setCliScripts(scripts) {
16669
16778
  this.cliScripts = scripts;
@@ -16759,6 +16868,8 @@ var init_provider_cli_adapter = __esm({
16759
16868
  this.startupParseGate = true;
16760
16869
  this.startupBuffer = "";
16761
16870
  this.terminalScreen.reset(40, 120);
16871
+ this.terminalHistory = "";
16872
+ this.currentTurnScope = null;
16762
16873
  this.ready = false;
16763
16874
  this.setStatus("idle", "pty_ready");
16764
16875
  this.onStatusChange?.();
@@ -16770,6 +16881,7 @@ var init_provider_cli_adapter = __esm({
16770
16881
  this.ptyProcess?.write("\x1B[1;1R");
16771
16882
  }
16772
16883
  this.terminalScreen.write(rawData);
16884
+ this.terminalHistory = mergeTerminalHistory(this.terminalHistory, this.terminalScreen.getText());
16773
16885
  const cleanData = stripAnsi(rawData);
16774
16886
  if (this.isWaitingForResponse && cleanData) {
16775
16887
  this.responseBuffer = (this.responseBuffer + cleanData).slice(-8e3);
@@ -16914,6 +17026,7 @@ var init_provider_cli_adapter = __esm({
16914
17026
  finishResponse() {
16915
17027
  if (this.submitPendingUntil > Date.now()) return;
16916
17028
  if (this.responseSettleIgnoreUntil > Date.now()) return;
17029
+ this.commitCurrentTranscript();
16917
17030
  if (this.responseTimeout) {
16918
17031
  clearTimeout(this.responseTimeout);
16919
17032
  this.responseTimeout = null;
@@ -16935,10 +17048,58 @@ var init_provider_cli_adapter = __esm({
16935
17048
  this.responseSettleIgnoreUntil = 0;
16936
17049
  this.submitRetryUsed = false;
16937
17050
  this.submitRetryPromptSnippet = "";
17051
+ this.currentTurnScope = null;
16938
17052
  this.activeModal = null;
16939
17053
  this.setStatus("idle", "response_finished");
16940
17054
  this.onStatusChange?.();
16941
17055
  }
17056
+ commitCurrentTranscript() {
17057
+ const baseMessages = [...this.committedMessages];
17058
+ const parsed = this.parseCurrentTranscript(baseMessages, "", this.currentTurnScope);
17059
+ if (parsed && Array.isArray(parsed.messages) && parsed.messages.length > 0) {
17060
+ const parsedMessages = parsed.messages.filter((m) => m && (m.role === "user" || m.role === "assistant")).map((m) => ({
17061
+ role: m.role,
17062
+ content: typeof m.content === "string" ? m.content : String(m.content || ""),
17063
+ timestamp: m.timestamp
17064
+ }));
17065
+ const latestAssistant = [...parsedMessages].reverse().find((m) => m.role === "assistant" && m.content.trim());
17066
+ if (latestAssistant) {
17067
+ LOG.info("CLI", `[${this.cliType}] commitCurrentTranscript parsed assistant len=${latestAssistant.content.length} scopePrompt=${JSON.stringify(this.currentTurnScope?.prompt || "").slice(0, 120)}`);
17068
+ const nextMessages = [...baseMessages];
17069
+ const last2 = nextMessages[nextMessages.length - 1];
17070
+ if (last2?.role === "assistant") {
17071
+ last2.content = latestAssistant.content;
17072
+ last2.timestamp = latestAssistant.timestamp || last2.timestamp;
17073
+ } else if (last2?.role === "user") {
17074
+ nextMessages.push({
17075
+ role: "assistant",
17076
+ content: latestAssistant.content,
17077
+ timestamp: latestAssistant.timestamp || Date.now()
17078
+ });
17079
+ } else {
17080
+ nextMessages.push({
17081
+ role: "assistant",
17082
+ content: latestAssistant.content,
17083
+ timestamp: latestAssistant.timestamp || Date.now()
17084
+ });
17085
+ }
17086
+ this.committedMessages = nextMessages;
17087
+ this.syncMessageViews();
17088
+ return;
17089
+ }
17090
+ }
17091
+ const fallback = String(this.responseBuffer || "").trim();
17092
+ LOG.info("CLI", `[${this.cliType}] commitCurrentTranscript fallback len=${fallback.length} scopePrompt=${JSON.stringify(this.currentTurnScope?.prompt || "").slice(0, 120)}`);
17093
+ if (!fallback) return;
17094
+ const last = baseMessages[baseMessages.length - 1];
17095
+ if (last?.role === "assistant") {
17096
+ last.content = fallback;
17097
+ } else {
17098
+ baseMessages.push({ role: "assistant", content: fallback, timestamp: Date.now() });
17099
+ }
17100
+ this.committedMessages = baseMessages;
17101
+ this.syncMessageViews();
17102
+ }
16942
17103
  // ─── Script Execution ──────────────────────────
16943
17104
  runDetectStatus(text) {
16944
17105
  if (!this.cliScripts?.detectStatus) return null;
@@ -16968,24 +17129,12 @@ var init_provider_cli_adapter = __esm({
16968
17129
  }
16969
17130
  // ─── Public API (CliAdapter) ───────────────────
16970
17131
  getStatus() {
16971
- const scriptResult = this.getScriptParsedStatus();
16972
- if (scriptResult) {
16973
- return {
16974
- status: this.currentStatus,
16975
- messages: (scriptResult.messages || []).map((m) => ({
16976
- role: m.role,
16977
- content: m.content,
16978
- timestamp: m.timestamp
16979
- })),
16980
- workingDir: this.workingDir,
16981
- activeModal: this.activeModal
16982
- };
16983
- }
16984
17132
  return {
16985
17133
  status: this.currentStatus,
16986
- messages: [...this.messages],
17134
+ messages: [...this.committedMessages],
16987
17135
  workingDir: this.workingDir,
16988
- activeModal: this.activeModal
17136
+ activeModal: this.activeModal,
17137
+ terminalHistory: this.terminalHistory
16989
17138
  };
16990
17139
  }
16991
17140
  /**
@@ -16993,31 +17142,32 @@ var init_provider_cli_adapter = __esm({
16993
17142
  * Called by command handler / dashboard for rich content rendering.
16994
17143
  */
16995
17144
  getScriptParsedStatus() {
17145
+ const messages = [...this.committedMessages];
17146
+ return {
17147
+ id: "cli_session",
17148
+ status: this.currentStatus,
17149
+ title: this.cliName,
17150
+ terminalHistory: this.terminalHistory,
17151
+ messages: messages.slice(-50).map((message, index) => ({
17152
+ id: `msg_${index}`,
17153
+ role: message.role,
17154
+ content: message.content,
17155
+ timestamp: message.timestamp,
17156
+ index,
17157
+ kind: "standard"
17158
+ })),
17159
+ activeModal: this.activeModal
17160
+ };
17161
+ }
17162
+ parseCurrentTranscript(baseMessages, partialResponse, scope) {
16996
17163
  if (!this.cliScripts?.parseOutput) return null;
16997
17164
  try {
16998
- const input = {
16999
- buffer: this.accumulatedBuffer,
17000
- rawBuffer: this.accumulatedRawBuffer,
17001
- recentBuffer: this.recentOutputBuffer,
17002
- screenText: this.terminalScreen.getText(),
17003
- messages: [...this.structuredMessages.length > 0 ? this.structuredMessages : this.messages],
17004
- partialResponse: this.responseBuffer
17005
- };
17006
- const result = this.cliScripts.parseOutput(input);
17007
- if (result && typeof result === "object") {
17008
- if (Array.isArray(result.messages)) {
17009
- this.structuredMessages = result.messages.map((m) => ({
17010
- role: m.role,
17011
- content: m.content,
17012
- timestamp: m.timestamp
17013
- }));
17014
- }
17015
- return result;
17016
- }
17165
+ const input = this.buildParseInput(baseMessages, partialResponse, scope);
17166
+ return this.cliScripts.parseOutput(input);
17017
17167
  } catch (e) {
17018
17168
  LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
17169
+ return null;
17019
17170
  }
17020
- return null;
17021
17171
  }
17022
17172
  /** Whether this adapter has CLI scripts loaded */
17023
17173
  hasCliScripts() {
@@ -17057,10 +17207,18 @@ ${data.message || ""}`.trim();
17057
17207
  }
17058
17208
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
17059
17209
  if (this.isWaitingForResponse) return;
17060
- this.messages.push({ role: "user", content: text, timestamp: Date.now() });
17061
- this.structuredMessages.push({ role: "user", content: text, timestamp: Date.now() });
17210
+ this.committedMessages.push({ role: "user", content: text, timestamp: Date.now() });
17211
+ this.syncMessageViews();
17062
17212
  this.isWaitingForResponse = true;
17063
17213
  this.responseBuffer = "";
17214
+ this.currentTurnScope = {
17215
+ prompt: text,
17216
+ startedAt: Date.now(),
17217
+ bufferStart: this.accumulatedBuffer.length,
17218
+ rawBufferStart: this.accumulatedRawBuffer.length,
17219
+ terminalHistoryStart: this.terminalHistory.length
17220
+ };
17221
+ LOG.info("CLI", `[${this.cliType}] sendMessage turn scope buffer=${this.currentTurnScope.bufferStart} raw=${this.currentTurnScope.rawBufferStart} terminal=${this.currentTurnScope.terminalHistoryStart} prompt=${JSON.stringify(text).slice(0, 120)}`);
17064
17222
  this.submitRetryUsed = false;
17065
17223
  this.submitRetryPromptSnippet = extractPromptRetrySnippet(text);
17066
17224
  const normalizedPromptSnippet = normalizePromptText(this.submitRetryPromptSnippet);
@@ -17080,10 +17238,12 @@ ${data.message || ""}`.trim();
17080
17238
  this.responseSettleIgnoreUntil = Date.now() + submitDelayMs + this.timeouts.outputSettle + 250;
17081
17239
  this.setStatus("generating", "sendMessage");
17082
17240
  this.onStatusChange?.();
17083
- if (submitDelayMs > 0) {
17084
- this.submitPendingUntil = Date.now() + submitDelayMs;
17085
- }
17086
- this.ptyProcess.write(text);
17241
+ const startResponseTimeout = () => {
17242
+ if (this.responseTimeout) clearTimeout(this.responseTimeout);
17243
+ this.responseTimeout = setTimeout(() => {
17244
+ if (this.isWaitingForResponse) this.finishResponse();
17245
+ }, this.timeouts.maxResponse);
17246
+ };
17087
17247
  const submit = () => {
17088
17248
  if (!this.ptyProcess) return;
17089
17249
  this.submitPendingUntil = 0;
@@ -17106,10 +17266,30 @@ ${data.message || ""}`.trim();
17106
17266
  this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
17107
17267
  };
17108
17268
  this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
17109
- this.responseTimeout = setTimeout(() => {
17110
- if (this.isWaitingForResponse) this.finishResponse();
17111
- }, this.timeouts.maxResponse);
17269
+ startResponseTimeout();
17112
17270
  };
17271
+ if (this.submitStrategy === "immediate") {
17272
+ this.submitPendingUntil = 0;
17273
+ this.ptyProcess.write(text + this.sendKey);
17274
+ this.submitRetryTimer = setTimeout(() => {
17275
+ this.submitRetryTimer = null;
17276
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
17277
+ if (this.currentStatus !== "generating") return;
17278
+ if ((this.responseBuffer || "").trim()) return;
17279
+ const screenText = this.terminalScreen.getText();
17280
+ if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
17281
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
17282
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
17283
+ this.ptyProcess.write(this.sendKey);
17284
+ this.submitRetryUsed = true;
17285
+ }, retryDelayMs);
17286
+ startResponseTimeout();
17287
+ return;
17288
+ }
17289
+ if (submitDelayMs > 0) {
17290
+ this.submitPendingUntil = Date.now() + submitDelayMs;
17291
+ }
17292
+ this.ptyProcess.write(text);
17113
17293
  const submitStartedAt = Date.now();
17114
17294
  let lastNormalizedScreen = "";
17115
17295
  let lastScreenChangeAt = submitStartedAt;
@@ -17176,10 +17356,12 @@ ${data.message || ""}`.trim();
17176
17356
  }
17177
17357
  }
17178
17358
  clearHistory() {
17179
- this.messages = [];
17180
- this.structuredMessages = [];
17359
+ this.committedMessages = [];
17360
+ this.syncMessageViews();
17181
17361
  this.accumulatedBuffer = "";
17182
17362
  this.accumulatedRawBuffer = "";
17363
+ this.terminalHistory = "";
17364
+ this.currentTurnScope = null;
17183
17365
  this.submitRetryUsed = false;
17184
17366
  this.submitRetryPromptSnippet = "";
17185
17367
  this.terminalScreen.reset();
@@ -17233,9 +17415,12 @@ ${data.message || ""}`.trim();
17233
17415
  spawnAt: this.spawnAt,
17234
17416
  workingDir: this.workingDir,
17235
17417
  messages: this.messages.slice(-20),
17418
+ committedMessages: this.committedMessages.slice(-20),
17236
17419
  structuredMessages: this.structuredMessages.slice(-20),
17237
- messageCount: this.messages.length,
17420
+ messageCount: this.committedMessages.length,
17238
17421
  screenText: this.terminalScreen.getText().slice(-4e3),
17422
+ terminalHistory: this.terminalHistory.slice(-8e3),
17423
+ currentTurnScope: this.currentTurnScope,
17239
17424
  startupBuffer: this.startupBuffer.slice(-4e3),
17240
17425
  recentOutputBuffer: this.recentOutputBuffer.slice(-500),
17241
17426
  settledBuffer: this.settledBuffer.slice(-500),
@@ -17248,6 +17433,7 @@ ${data.message || ""}`.trim();
17248
17433
  lastApprovalResolvedAt: this.lastApprovalResolvedAt,
17249
17434
  sendDelayMs: this.sendDelayMs,
17250
17435
  sendKey: this.sendKey,
17436
+ submitStrategy: this.submitStrategy,
17251
17437
  submitPendingUntil: this.submitPendingUntil,
17252
17438
  responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
17253
17439
  resizeSuppressUntil: this.resizeSuppressUntil,
@@ -17320,31 +17506,12 @@ var init_cli_provider_instance = __esm({
17320
17506
  async onTick() {
17321
17507
  }
17322
17508
  getState() {
17323
- const rawStatus = this.adapter.getStatus();
17324
- const parsedStatus = this.adapter.getScriptParsedStatus();
17325
- const adapterStatus = parsedStatus ? {
17326
- ...rawStatus,
17327
- messages: parsedStatus.messages || rawStatus.messages,
17328
- activeModal: parsedStatus.activeModal || rawStatus.activeModal
17329
- } : rawStatus;
17509
+ const adapterStatus = this.adapter.getStatus();
17330
17510
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
17331
17511
  const recentMessages = adapterStatus.messages.slice(-50).map((m) => {
17332
17512
  const content = typeof m.content === "string" && m.content.length > 8e3 ? m.content.slice(0, 8e3) + "\n... (truncated)" : m.content;
17333
17513
  return { ...m, content };
17334
17514
  });
17335
- const partial2 = this.adapter.getPartialResponse();
17336
- const shouldAppendRawPartial = !parsedStatus;
17337
- if (shouldAppendRawPartial && adapterStatus.status === "generating" && partial2) {
17338
- const cleaned = partial2.trim();
17339
- if (cleaned && cleaned !== "(generating...)") {
17340
- recentMessages.push({
17341
- role: "assistant",
17342
- content: (cleaned.length > 8e3 ? cleaned.slice(0, 8e3) + "..." : cleaned) + "...",
17343
- timestamp: Date.now(),
17344
- meta: { streaming: true }
17345
- });
17346
- }
17347
- }
17348
17515
  if (recentMessages.length > 0) {
17349
17516
  const dirName2 = this.workingDir.split("/").filter(Boolean).pop() || "session";
17350
17517
  this.historyWriter.appendNewMessages(
@@ -17354,6 +17521,14 @@ var init_cli_provider_instance = __esm({
17354
17521
  this.instanceId
17355
17522
  );
17356
17523
  }
17524
+ if (adapterStatus.terminalHistory?.trim()) {
17525
+ this.historyWriter.appendTerminalHistory(
17526
+ this.type,
17527
+ adapterStatus.terminalHistory,
17528
+ `${this.provider.name} \xB7 ${dirName}`,
17529
+ this.instanceId
17530
+ );
17531
+ }
17357
17532
  return {
17358
17533
  type: this.type,
17359
17534
  name: this.provider.name,
@@ -17366,6 +17541,7 @@ var init_cli_provider_instance = __esm({
17366
17541
  status: adapterStatus.status,
17367
17542
  messages: recentMessages,
17368
17543
  activeModal: adapterStatus.activeModal,
17544
+ terminalHistory: adapterStatus.terminalHistory,
17369
17545
  inputContent: ""
17370
17546
  },
17371
17547
  workspace: this.workingDir,
@@ -35849,7 +36025,8 @@ async function detectAllVersions(loader, archive) {
35849
36025
  binary: null,
35850
36026
  detectedAt: (/* @__PURE__ */ new Date()).toISOString()
35851
36027
  };
35852
- const versionCommand = provider.versionCommand;
36028
+ const verCmdConfig = provider.versionCommand;
36029
+ const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[currentOs] : verCmdConfig;
35853
36030
  if (provider.category === "ide") {
35854
36031
  const osPaths = provider.paths?.[currentOs] || [];
35855
36032
  const appPath = checkPathExists2(osPaths);
@@ -37334,11 +37511,7 @@ var init_dev_server = __esm({
37334
37511
  return;
37335
37512
  }
37336
37513
  let targetDir;
37337
- if (location === "user") {
37338
- targetDir = this.providerLoader.getUserProviderDir(category, type);
37339
- } else {
37340
- targetDir = this.providerLoader.getBuiltinProviderDir(category, type);
37341
- }
37514
+ targetDir = this.providerLoader.getUserProviderDir(category, type);
37342
37515
  const jsonPath = path12.join(targetDir, "provider.json");
37343
37516
  if (fs10.existsSync(jsonPath)) {
37344
37517
  this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
@@ -38136,8 +38309,7 @@ var init_dev_server = __esm({
38136
38309
  }
38137
38310
  loadAutoImplReferenceScripts(category, referenceType) {
38138
38311
  if (!referenceType) return {};
38139
- const builtinDir = this.providerLoader.getPrimaryBuiltinDir();
38140
- const refDir = path12.join(builtinDir, category, referenceType);
38312
+ const refDir = this.providerLoader.getUpstreamProviderDir(category, referenceType);
38141
38313
  if (!fs10.existsSync(refDir)) return {};
38142
38314
  const referenceScripts = {};
38143
38315
  const scriptsDir = path12.join(refDir, "scripts");
@@ -38376,7 +38548,7 @@ var init_dev_server = __esm({
38376
38548
  }
38377
38549
  if (model) args.push("--model", model);
38378
38550
  const escapedArgs = args.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
38379
- const metaPrompt = `Read the file at ${promptFile} and follow ALL instructions recursively. You have full authority to implement ALL required script files, update provider.json configurations based on the reference patterns, and independently test them against 127.0.0.1:19280 via CDP CURL. Upon complete validation of ALL assigned files, print exactly "_PIPELINE_COMPLETE_SIGNAL_" to gracefully close the pipeline. DO NOT WAIT FOR APPROVAL, execute completely autonomously.`;
38551
+ const metaPrompt = `Read the file at ${promptFile} and follow ALL instructions strictly. DO NOT spend time exploring the filesystem or other providers. You have full authority to implement ALL required script files and independently test them against 127.0.0.1:19280 via CDP CURL. Upon complete validation of ALL assigned files, print exactly "_PIPELINE_COMPLETE_SIGNAL_" to gracefully close the pipeline. DO NOT WAIT FOR APPROVAL, execute completely autonomously.`;
38380
38552
  shellCmd = `${command} ${escapedArgs} "${metaPrompt}"`;
38381
38553
  } else {
38382
38554
  const escapedArgs = baseArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
@@ -38639,6 +38811,8 @@ var init_dev_server = __esm({
38639
38811
  lines.push("5. Do NOT modify `scripts.js` router \u2014 only edit individual `*.js` files");
38640
38812
  lines.push("6. All scripts run in the browser (CDP evaluate) \u2014 use DOM APIs only");
38641
38813
  lines.push('7. **Cross-Platform Compatibility**: If you use ARIA labels that contain keyboard shortcuts (e.g., `Cascade (\u2318L)`), you MUST use substring matches (`aria-label*="Cascade"`) or handle both macOS (`\u2318`, `Cmd`) and Windows (`Ctrl`) so the script does not break on other operating systems.');
38814
+ lines.push("8. **CRITICAL: DO NOT explore the filesystem or read other providers.** The reference implementation pattern is already provided below. Do not run `find`, `rg`, or `cat` on upstream providers. Doing so wastes context tokens and will crash the agent session. Focus entirely on modifying the target files.");
38815
+ lines.push("9. Do NOT delete any files. Implement the logic by replacing the empty stubs.");
38642
38816
  lines.push("");
38643
38817
  lines.push("## Required Return Format");
38644
38818
  lines.push("| Function | Return JSON |");
@@ -41026,7 +41200,7 @@ var init_adhdev_daemon = __esm({
41026
41200
  fs12 = __toESM(require("fs"));
41027
41201
  path14 = __toESM(require("path"));
41028
41202
  import_chalk2 = __toESM(require("chalk"));
41029
- pkgVersion = "0.6.57";
41203
+ pkgVersion = "0.6.58";
41030
41204
  if (pkgVersion === "unknown") {
41031
41205
  try {
41032
41206
  const possiblePaths = [