@adhdev/daemon-standalone 0.8.34 → 0.8.35

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
@@ -30284,8 +30284,6 @@ ${data.message || ""}`.trim();
30284
30284
  if (blockingModal || this.currentStatus === "waiting_approval") {
30285
30285
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
30286
30286
  }
30287
- this.committedMessages.push({ role: "user", content: text, timestamp: Date.now() });
30288
- this.syncMessageViews();
30289
30287
  this.isWaitingForResponse = true;
30290
30288
  this.responseBuffer = "";
30291
30289
  this.finishRetryCount = 0;
@@ -30317,6 +30315,13 @@ ${data.message || ""}`.trim();
30317
30315
  const submitDelayMs = this.sendDelayMs + Math.min(2e3, Math.max(0, estimatedLines - 1) * 350);
30318
30316
  const maxEchoWaitMs = submitDelayMs + Math.max(1500, Math.min(5e3, estimatedLines * 500));
30319
30317
  const retryDelayMs = Math.max(350, Math.min(1500, Math.max(this.sendDelayMs, submitDelayMs)));
30318
+ let didCommitUserTurn = false;
30319
+ const commitUserTurn = () => {
30320
+ if (didCommitUserTurn) return;
30321
+ didCommitUserTurn = true;
30322
+ this.committedMessages.push({ role: "user", content: text, timestamp: Date.now() });
30323
+ this.syncMessageViews();
30324
+ };
30320
30325
  if (this.settleTimer) {
30321
30326
  clearTimeout(this.settleTimer);
30322
30327
  this.settleTimer = null;
@@ -30329,109 +30334,128 @@ ${data.message || ""}`.trim();
30329
30334
  if (this.isWaitingForResponse) this.finishResponse();
30330
30335
  }, this.timeouts.maxResponse);
30331
30336
  };
30332
- const submit = () => {
30333
- if (!this.ptyProcess) return;
30334
- this.submitPendingUntil = 0;
30335
- this.recordTrace("submit_write", {
30336
- mode: "submit_key",
30337
- sendKey: this.sendKey,
30338
- screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
30339
- });
30340
- this.ptyProcess.write(this.sendKey);
30341
- const retrySubmitIfStuck = (attempt) => {
30342
- this.submitRetryTimer = null;
30343
- if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
30344
- if (this.currentStatus === "waiting_approval") return;
30345
- if ((this.responseBuffer || "").trim()) return;
30337
+ await new Promise((resolve12) => {
30338
+ let resolved = false;
30339
+ const resolveOnce = () => {
30340
+ if (resolved) return;
30341
+ resolved = true;
30342
+ resolve12();
30343
+ };
30344
+ const submit = () => {
30345
+ if (!this.ptyProcess) {
30346
+ resolveOnce();
30347
+ return;
30348
+ }
30349
+ commitUserTurn();
30350
+ this.submitPendingUntil = 0;
30346
30351
  const screenText = this.terminalScreen.getText();
30347
- if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
30348
- if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText)) return;
30349
- this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
30350
- LOG2.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
30351
30352
  this.recordTrace("submit_write", {
30352
- mode: "submit_retry",
30353
- attempt,
30353
+ mode: "submit_key",
30354
30354
  sendKey: this.sendKey,
30355
30355
  screenText: summarizeCliTraceText(screenText, 500)
30356
30356
  });
30357
30357
  this.ptyProcess.write(this.sendKey);
30358
- if (attempt >= 3) {
30359
- this.submitRetryUsed = true;
30360
- return;
30361
- }
30362
- this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
30358
+ const retrySubmitIfStuck = (attempt) => {
30359
+ this.submitRetryTimer = null;
30360
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
30361
+ if (this.currentStatus === "waiting_approval") return;
30362
+ if ((this.responseBuffer || "").trim()) return;
30363
+ const screenText2 = this.terminalScreen.getText();
30364
+ if (!promptLikelyVisible(screenText2, normalizedPromptSnippet)) return;
30365
+ if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText2)) return;
30366
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
30367
+ LOG2.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
30368
+ this.recordTrace("submit_write", {
30369
+ mode: "submit_retry",
30370
+ attempt,
30371
+ sendKey: this.sendKey,
30372
+ screenText: summarizeCliTraceText(screenText2, 500)
30373
+ });
30374
+ this.ptyProcess.write(this.sendKey);
30375
+ if (attempt >= 3) {
30376
+ this.submitRetryUsed = true;
30377
+ return;
30378
+ }
30379
+ this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
30380
+ };
30381
+ this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
30382
+ startResponseTimeout();
30383
+ resolveOnce();
30363
30384
  };
30364
- this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
30365
- startResponseTimeout();
30366
- };
30367
- if (this.submitStrategy === "immediate") {
30368
- this.submitPendingUntil = 0;
30385
+ if (this.submitStrategy === "immediate") {
30386
+ commitUserTurn();
30387
+ this.submitPendingUntil = 0;
30388
+ this.recordTrace("submit_write", {
30389
+ mode: "immediate",
30390
+ text: summarizeCliTraceText(text, 500),
30391
+ sendKey: this.sendKey,
30392
+ screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
30393
+ });
30394
+ this.ptyProcess.write(text + this.sendKey);
30395
+ this.submitRetryTimer = setTimeout(() => {
30396
+ this.submitRetryTimer = null;
30397
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
30398
+ if (this.currentStatus === "waiting_approval") return;
30399
+ if ((this.responseBuffer || "").trim()) return;
30400
+ const screenText = this.terminalScreen.getText();
30401
+ if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
30402
+ LOG2.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
30403
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
30404
+ this.recordTrace("submit_write", {
30405
+ mode: "immediate_retry",
30406
+ attempt: 1,
30407
+ sendKey: this.sendKey,
30408
+ screenText: summarizeCliTraceText(screenText, 500)
30409
+ });
30410
+ this.ptyProcess.write(this.sendKey);
30411
+ this.submitRetryUsed = true;
30412
+ }, retryDelayMs);
30413
+ startResponseTimeout();
30414
+ resolveOnce();
30415
+ return;
30416
+ }
30417
+ if (submitDelayMs > 0) {
30418
+ this.submitPendingUntil = Date.now() + submitDelayMs;
30419
+ }
30420
+ this.ptyProcess.write(text);
30369
30421
  this.recordTrace("submit_write", {
30370
- mode: "immediate",
30422
+ mode: "type_then_submit",
30371
30423
  text: summarizeCliTraceText(text, 500),
30372
30424
  sendKey: this.sendKey,
30373
30425
  screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
30374
30426
  });
30375
- this.ptyProcess.write(text + this.sendKey);
30376
- this.submitRetryTimer = setTimeout(() => {
30377
- this.submitRetryTimer = null;
30378
- if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
30379
- if (this.currentStatus === "waiting_approval") return;
30380
- if ((this.responseBuffer || "").trim()) return;
30427
+ const submitStartedAt = Date.now();
30428
+ let lastNormalizedScreen = "";
30429
+ let lastScreenChangeAt = submitStartedAt;
30430
+ const waitForEchoAndSubmit = () => {
30431
+ if (!this.ptyProcess) {
30432
+ resolveOnce();
30433
+ return;
30434
+ }
30435
+ const now = Date.now();
30436
+ const elapsed = now - submitStartedAt;
30381
30437
  const screenText = this.terminalScreen.getText();
30382
- if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
30383
- LOG2.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
30384
- this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
30385
- this.recordTrace("submit_write", {
30386
- mode: "immediate_retry",
30387
- attempt: 1,
30388
- sendKey: this.sendKey,
30389
- screenText: summarizeCliTraceText(screenText, 500)
30390
- });
30391
- this.ptyProcess.write(this.sendKey);
30392
- this.submitRetryUsed = true;
30393
- }, retryDelayMs);
30394
- startResponseTimeout();
30395
- return;
30396
- }
30397
- if (submitDelayMs > 0) {
30398
- this.submitPendingUntil = Date.now() + submitDelayMs;
30399
- }
30400
- this.ptyProcess.write(text);
30401
- this.recordTrace("submit_write", {
30402
- mode: "type_then_submit",
30403
- text: summarizeCliTraceText(text, 500),
30404
- sendKey: this.sendKey,
30405
- screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
30406
- });
30407
- const submitStartedAt = Date.now();
30408
- let lastNormalizedScreen = "";
30409
- let lastScreenChangeAt = submitStartedAt;
30410
- const waitForEchoAndSubmit = () => {
30411
- if (!this.ptyProcess) return;
30412
- const now = Date.now();
30413
- const elapsed = now - submitStartedAt;
30414
- const screenText = this.terminalScreen.getText();
30415
- const normalizedScreen = normalizePromptText(screenText);
30416
- if (normalizedScreen !== lastNormalizedScreen) {
30417
- lastNormalizedScreen = normalizedScreen;
30418
- lastScreenChangeAt = now;
30419
- }
30420
- const echoVisible = !normalizedPromptSnippet || promptLikelyVisible(screenText, normalizedPromptSnippet);
30421
- if (echoVisible) {
30422
- const screenSettled = now - lastScreenChangeAt >= 500;
30423
- if (elapsed >= submitDelayMs && screenSettled) {
30438
+ const normalizedScreen = normalizePromptText(screenText);
30439
+ if (normalizedScreen !== lastNormalizedScreen) {
30440
+ lastNormalizedScreen = normalizedScreen;
30441
+ lastScreenChangeAt = now;
30442
+ }
30443
+ const echoVisible = !normalizedPromptSnippet || promptLikelyVisible(screenText, normalizedPromptSnippet);
30444
+ if (echoVisible) {
30445
+ const screenSettled = now - lastScreenChangeAt >= 500;
30446
+ if (elapsed >= submitDelayMs && screenSettled) {
30447
+ submit();
30448
+ return;
30449
+ }
30450
+ }
30451
+ if (elapsed >= maxEchoWaitMs) {
30424
30452
  submit();
30425
30453
  return;
30426
30454
  }
30427
- }
30428
- if (elapsed >= maxEchoWaitMs) {
30429
- submit();
30430
- return;
30431
- }
30432
- setTimeout(waitForEchoAndSubmit, 50);
30433
- };
30434
- waitForEchoAndSubmit();
30455
+ setTimeout(waitForEchoAndSubmit, 50);
30456
+ };
30457
+ waitForEchoAndSubmit();
30458
+ });
30435
30459
  }
30436
30460
  getPartialResponse() {
30437
30461
  if (!this.isWaitingForResponse) return "";
@@ -42121,6 +42145,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
42121
42145
  lastStatusSentAt = 0;
42122
42146
  statusPendingThrottle = false;
42123
42147
  lastP2PStatusHash = "";
42148
+ lastServerStatusHash = "";
42124
42149
  lastStatusSummary = "";
42125
42150
  statusTimer = null;
42126
42151
  p2pTimer = null;
@@ -42131,11 +42156,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
42131
42156
  // ─── Lifecycle ───────────────────────────────────
42132
42157
  startReporting() {
42133
42158
  setTimeout(() => {
42134
- this.sendUnifiedStatusReport().catch((e) => LOG2.warn("Status", `Initial report failed: ${e?.message}`));
42159
+ this.sendUnifiedStatusReport({ forceServer: true, reason: "initial" }).catch((e) => LOG2.warn("Status", `Initial report failed: ${e?.message}`));
42135
42160
  }, 2e3);
42136
42161
  const scheduleServerReport = () => {
42137
42162
  this.statusTimer = setTimeout(() => {
42138
- this.sendUnifiedStatusReport().catch((e) => LOG2.warn("Status", `Periodic report failed: ${e?.message}`));
42163
+ this.sendUnifiedStatusReport({ forceServer: true, reason: "periodic" }).catch((e) => LOG2.warn("Status", `Periodic report failed: ${e?.message}`));
42139
42164
  scheduleServerReport();
42140
42165
  }, 3e4);
42141
42166
  };
@@ -42282,24 +42307,24 @@ Run 'adhdev doctor' for detailed diagnostics.`
42282
42307
  cdpConnected: session.cdpConnected,
42283
42308
  currentModel: session.currentModel,
42284
42309
  currentPlan: session.currentPlan,
42285
- currentAutoApprove: session.currentAutoApprove,
42286
- lastUpdated: session.lastUpdated,
42287
- unread: session.unread,
42288
- lastSeenAt: session.lastSeenAt,
42289
- inboxBucket: session.inboxBucket,
42290
- surfaceHidden: session.surfaceHidden,
42291
- controlValues: session.controlValues,
42292
- providerControls: session.providerControls,
42293
- acpConfigOptions: session.acpConfigOptions,
42294
- acpModes: session.acpModes
42310
+ currentAutoApprove: session.currentAutoApprove
42295
42311
  })),
42296
42312
  p2p: payload.p2p,
42297
42313
  timestamp: now,
42298
42314
  detectedIdes: payload.detectedIdes,
42299
42315
  availableProviders: payload.availableProviders
42300
42316
  };
42317
+ const wsHash = this.simpleHash(JSON.stringify({
42318
+ ...wsPayload,
42319
+ timestamp: void 0
42320
+ }));
42321
+ if (!opts?.forceServer && wsHash === this.lastServerStatusHash) {
42322
+ LOG2.debug("Server", `skip duplicate status_report${opts?.reason ? ` (${opts.reason})` : ""}`);
42323
+ return;
42324
+ }
42325
+ this.lastServerStatusHash = wsHash;
42301
42326
  serverConn.sendMessage("status_report", wsPayload);
42302
- LOG2.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
42327
+ LOG2.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)${opts?.reason ? ` [${opts.reason}]` : ""}`);
42303
42328
  }
42304
42329
  // ─── P2P ─────────────────────────────────────────
42305
42330
  sendP2PPayload(payload) {