adhdev 0.9.11 → 0.9.13

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
@@ -9487,14 +9487,14 @@ async function handleOpenPanel(h, args) {
9487
9487
  success: revealState.visible || focusState.focused
9488
9488
  };
9489
9489
  }
9490
- function handlePtyInput(h, args) {
9490
+ async function handlePtyInput(h, args) {
9491
9491
  const { cliType, data, targetSessionId } = args || {};
9492
9492
  if (!data) return { success: false, error: "data required" };
9493
9493
  const adapter = h.getCliAdapter(targetSessionId || cliType);
9494
9494
  if (!adapter || typeof adapter.writeRaw !== "function") {
9495
9495
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
9496
9496
  }
9497
- adapter.writeRaw(data);
9497
+ await adapter.writeRaw(data);
9498
9498
  return { success: true };
9499
9499
  }
9500
9500
  function handlePtyResize(_h, args) {
@@ -9671,7 +9671,7 @@ async function executeProviderScript(h, args, scriptName) {
9671
9671
  if (cliCommand?.type === "send_message" && cliCommand.text) {
9672
9672
  await adapter.sendMessage(cliCommand.text);
9673
9673
  } else if (cliCommand?.type === "pty_write" && cliCommand.text && adapter.writeRaw) {
9674
- adapter.writeRaw(cliCommand.text + "\r");
9674
+ await adapter.writeRaw(cliCommand.text + "\r");
9675
9675
  }
9676
9676
  applyProviderPatch(h, args, parsed.payload);
9677
9677
  return {
@@ -13971,6 +13971,29 @@ var init_provider_cli_adapter = __esm({
13971
13971
  }
13972
13972
  await this.sendMessage(promptText);
13973
13973
  }
13974
+ async writeToPty(data) {
13975
+ if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
13976
+ await this.ptyProcess.write(data);
13977
+ }
13978
+ resetPendingSendState(reason) {
13979
+ this.isWaitingForResponse = false;
13980
+ this.responseBuffer = "";
13981
+ this.currentTurnScope = null;
13982
+ this.submitPendingUntil = 0;
13983
+ this.clearIdleFinishCandidate(reason);
13984
+ if (this.responseTimeout) {
13985
+ clearTimeout(this.responseTimeout);
13986
+ this.responseTimeout = null;
13987
+ }
13988
+ if (this.submitRetryTimer) {
13989
+ clearTimeout(this.submitRetryTimer);
13990
+ this.submitRetryTimer = null;
13991
+ }
13992
+ if (this.finishRetryTimer) {
13993
+ clearTimeout(this.finishRetryTimer);
13994
+ this.finishRetryTimer = null;
13995
+ }
13996
+ }
13974
13997
  async sendMessage(text) {
13975
13998
  if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
13976
13999
  const allowInputDuringGeneration = this.provider.allowInputDuringGeneration === true;
@@ -14065,19 +14088,29 @@ var init_provider_cli_adapter = __esm({
14065
14088
  if (this.isWaitingForResponse) this.finishResponse();
14066
14089
  }, this.timeouts.maxResponse);
14067
14090
  };
14068
- await new Promise((resolve18) => {
14091
+ await new Promise((resolve18, reject) => {
14069
14092
  let resolved = false;
14070
14093
  const resolveOnce = () => {
14071
14094
  if (resolved) return;
14072
14095
  resolved = true;
14073
14096
  resolve18();
14074
14097
  };
14098
+ const rejectOnce = (error48) => {
14099
+ if (resolved) return;
14100
+ this.resetPendingSendState("send_write_failed");
14101
+ resolved = true;
14102
+ reject(error48);
14103
+ };
14104
+ const writeRetryKey = (mode) => {
14105
+ void this.writeToPty(this.sendKey).catch((error48) => {
14106
+ LOG.warn("CLI", `[${this.cliType}] ${mode} write failed: ${error48?.message || error48}`);
14107
+ });
14108
+ };
14075
14109
  const submit = () => {
14076
14110
  if (!this.ptyProcess) {
14077
14111
  resolveOnce();
14078
14112
  return;
14079
14113
  }
14080
- commitUserTurn();
14081
14114
  this.submitPendingUntil = 0;
14082
14115
  const screenText = this.terminalScreen.getText();
14083
14116
  this.recordTrace("submit_write", {
@@ -14085,7 +14118,6 @@ var init_provider_cli_adapter = __esm({
14085
14118
  sendKey: this.sendKey,
14086
14119
  screenText: summarizeCliTraceText(screenText, 500)
14087
14120
  });
14088
- this.ptyProcess.write(this.sendKey);
14089
14121
  const retrySubmitIfStuck = (attempt) => {
14090
14122
  this.submitRetryTimer = null;
14091
14123
  if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
@@ -14105,19 +14137,21 @@ var init_provider_cli_adapter = __esm({
14105
14137
  sendKey: this.sendKey,
14106
14138
  screenText: summarizeCliTraceText(screenText2, 500)
14107
14139
  });
14108
- this.ptyProcess.write(this.sendKey);
14140
+ writeRetryKey("submit_retry");
14109
14141
  if (attempt >= 3) {
14110
14142
  this.submitRetryUsed = true;
14111
14143
  return;
14112
14144
  }
14113
14145
  this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
14114
14146
  };
14115
- this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
14116
- startResponseTimeout();
14117
- resolveOnce();
14147
+ void this.writeToPty(this.sendKey).then(() => {
14148
+ commitUserTurn();
14149
+ this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
14150
+ startResponseTimeout();
14151
+ resolveOnce();
14152
+ }, rejectOnce);
14118
14153
  };
14119
14154
  if (this.submitStrategy === "immediate") {
14120
- commitUserTurn();
14121
14155
  this.submitPendingUntil = 0;
14122
14156
  this.recordTrace("submit_write", {
14123
14157
  mode: "immediate",
@@ -14125,37 +14159,38 @@ var init_provider_cli_adapter = __esm({
14125
14159
  sendKey: this.sendKey,
14126
14160
  screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
14127
14161
  });
14128
- this.ptyProcess.write(text + this.sendKey);
14129
- this.submitRetryTimer = setTimeout(() => {
14130
- this.submitRetryTimer = null;
14131
- if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
14132
- if (this.currentStatus === "waiting_approval") return;
14133
- if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
14134
- const screenText = this.terminalScreen.getText();
14135
- if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
14136
- const liveApproval = this.runParseApproval(screenText) || this.runParseApproval(this.recentOutputBuffer);
14137
- if (liveApproval) return;
14138
- const liveStatus = this.runDetectStatus(screenText) || this.runDetectStatus(this.recentOutputBuffer);
14139
- if (liveStatus === "generating" || liveStatus === "waiting_approval") return;
14140
- LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
14141
- this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
14142
- this.recordTrace("submit_write", {
14143
- mode: "immediate_retry",
14144
- attempt: 1,
14145
- sendKey: this.sendKey,
14146
- screenText: summarizeCliTraceText(screenText, 500)
14147
- });
14148
- this.ptyProcess.write(this.sendKey);
14149
- this.submitRetryUsed = true;
14150
- }, retryDelayMs);
14151
- startResponseTimeout();
14152
- resolveOnce();
14162
+ void this.writeToPty(text + this.sendKey).then(() => {
14163
+ commitUserTurn();
14164
+ this.submitRetryTimer = setTimeout(() => {
14165
+ this.submitRetryTimer = null;
14166
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
14167
+ if (this.currentStatus === "waiting_approval") return;
14168
+ if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
14169
+ const screenText = this.terminalScreen.getText();
14170
+ if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
14171
+ const liveApproval = this.runParseApproval(screenText) || this.runParseApproval(this.recentOutputBuffer);
14172
+ if (liveApproval) return;
14173
+ const liveStatus = this.runDetectStatus(screenText) || this.runDetectStatus(this.recentOutputBuffer);
14174
+ if (liveStatus === "generating" || liveStatus === "waiting_approval") return;
14175
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
14176
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
14177
+ this.recordTrace("submit_write", {
14178
+ mode: "immediate_retry",
14179
+ attempt: 1,
14180
+ sendKey: this.sendKey,
14181
+ screenText: summarizeCliTraceText(screenText, 500)
14182
+ });
14183
+ writeRetryKey("immediate_retry");
14184
+ this.submitRetryUsed = true;
14185
+ }, retryDelayMs);
14186
+ startResponseTimeout();
14187
+ resolveOnce();
14188
+ }, rejectOnce);
14153
14189
  return;
14154
14190
  }
14155
14191
  if (submitDelayMs > 0) {
14156
14192
  this.submitPendingUntil = Date.now() + submitDelayMs;
14157
14193
  }
14158
- this.ptyProcess.write(text);
14159
14194
  this.recordTrace("submit_write", {
14160
14195
  mode: "type_then_submit",
14161
14196
  text: summarizeCliTraceText(text, 500),
@@ -14192,7 +14227,7 @@ var init_provider_cli_adapter = __esm({
14192
14227
  }
14193
14228
  setTimeout(waitForEchoAndSubmit, 50);
14194
14229
  };
14195
- waitForEchoAndSubmit();
14230
+ void this.writeToPty(text).then(() => waitForEchoAndSubmit(), rejectOnce);
14196
14231
  });
14197
14232
  }
14198
14233
  getPartialResponse() {
@@ -14347,12 +14382,12 @@ var init_provider_cli_adapter = __esm({
14347
14382
  isReady() {
14348
14383
  return this.ready;
14349
14384
  }
14350
- writeRaw(data) {
14385
+ async writeRaw(data) {
14351
14386
  this.recordTrace("write_raw", {
14352
14387
  keys: JSON.stringify(data),
14353
14388
  length: data.length
14354
14389
  });
14355
- this.ptyProcess?.write(data);
14390
+ await this.writeToPty(data);
14356
14391
  }
14357
14392
  resolveModal(buttonIndex) {
14358
14393
  let modal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
@@ -14898,7 +14933,7 @@ var init_cli_provider_instance = __esm({
14898
14933
  if (cliCommand?.type === "send_message" && cliCommand.text) {
14899
14934
  await this.adapter.sendMessage(cliCommand.text);
14900
14935
  } else if (cliCommand?.type === "pty_write" && cliCommand.text) {
14901
- this.adapter.writeRaw(cliCommand.text + "\r");
14936
+ await this.adapter.writeRaw(cliCommand.text + "\r");
14902
14937
  }
14903
14938
  this.applyProviderResponse(parsed.payload, { phase: "immediate" });
14904
14939
  }
@@ -42873,7 +42908,7 @@ async function handleCliRaw(ctx, req, res) {
42873
42908
  }
42874
42909
  try {
42875
42910
  if (typeof adapter.writeRaw === "function") {
42876
- adapter.writeRaw(keys);
42911
+ await adapter.writeRaw(keys);
42877
42912
  ctx.json(res, 200, { sent: true, type: target.type, instanceId: target.instanceId, keysLength: keys.length });
42878
42913
  } else {
42879
42914
  ctx.json(res, 400, { error: "writeRaw not available on this adapter" });
@@ -45836,7 +45871,7 @@ var init_session_host_transport = __esm({
45836
45871
  this.exitCallbacks.add(callback);
45837
45872
  }
45838
45873
  write(data) {
45839
- this.enqueue(async () => {
45874
+ return this.enqueue(async () => {
45840
45875
  let response = await this.client.request({
45841
45876
  type: "send_input",
45842
45877
  payload: {
@@ -46138,9 +46173,11 @@ var init_session_host_transport = __esm({
46138
46173
  };
46139
46174
  }
46140
46175
  enqueue(action) {
46141
- this.operationChain = this.operationChain.then(() => this.ready).then(action).catch((error48) => {
46176
+ const operation = this.operationChain.then(() => this.ready).then(action);
46177
+ this.operationChain = operation.catch((error48) => {
46142
46178
  LOG.warn("CLI", `[session-host:${this.options.runtimeId}] ${error48?.message || error48}`);
46143
46179
  });
46180
+ return operation;
46144
46181
  }
46145
46182
  async closeClient(destroy = false) {
46146
46183
  if (this.closed) return;
@@ -78731,14 +78768,41 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
78731
78768
  return;
78732
78769
  }
78733
78770
  if (parsed.type === "pty_input") {
78734
- const permission = peers.get(peerId)?.sharePermission;
78771
+ const peer = peers.get(peerId);
78772
+ const permission = peer?.sharePermission;
78773
+ const sendPtyInputError = (sessionId2, reason, error48) => {
78774
+ const message = error48 instanceof Error ? error48.message : typeof error48 === "string" ? error48 : void 0;
78775
+ sendToPeer(peer, {
78776
+ type: "session_io_error",
78777
+ sessionId: sessionId2,
78778
+ reason,
78779
+ ...message ? { error: message } : {}
78780
+ });
78781
+ };
78735
78782
  if (permission) {
78736
78783
  log(`pty_input: REJECTED \u2014 permission=${permission} peer=${peerId}`);
78784
+ const sessionId2 = typeof (parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType) === "string" ? parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType : "";
78785
+ sendPtyInputError(sessionId2, "permission_denied");
78786
+ return;
78787
+ }
78788
+ const sessionIdCandidate = parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType || "";
78789
+ const sessionId = typeof sessionIdCandidate === "string" ? sessionIdCandidate : "";
78790
+ if (!sessionId || typeof parsed.data !== "string" || parsed.data.length === 0) {
78791
+ sendPtyInputError(sessionId, "invalid_payload");
78792
+ return;
78793
+ }
78794
+ if (!handlers.ptyInputHandler) {
78795
+ sendPtyInputError(sessionId, "handler_unavailable");
78737
78796
  return;
78738
78797
  }
78739
- const sessionId = parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType || "";
78740
- if (handlers.ptyInputHandler && parsed.data && sessionId) {
78741
- handlers.ptyInputHandler(sessionId, parsed.data);
78798
+ try {
78799
+ Promise.resolve(handlers.ptyInputHandler(sessionId, parsed.data)).catch((error48) => {
78800
+ log(`pty_input write failed: peer=${peerId} sessionId=${sessionId} error=${error48?.message || error48}`);
78801
+ sendPtyInputError(sessionId, "write_failed", error48);
78802
+ });
78803
+ } catch (error48) {
78804
+ log(`pty_input write failed: peer=${peerId} sessionId=${sessionId} error=${error48?.message || error48}`);
78805
+ sendPtyInputError(sessionId, "write_failed", error48);
78742
78806
  }
78743
78807
  return;
78744
78808
  }
@@ -87116,7 +87180,7 @@ var init_adhdev_daemon = __esm({
87116
87180
  init_version();
87117
87181
  init_src();
87118
87182
  init_runtime_defaults();
87119
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.11" });
87183
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.13" });
87120
87184
  AdhdevDaemon = class _AdhdevDaemon {
87121
87185
  localHttpServer = null;
87122
87186
  localWss = null;
@@ -87312,11 +87376,7 @@ var init_adhdev_daemon = __esm({
87312
87376
  });
87313
87377
  }
87314
87378
  getHotChatSessionIdsForP2PFlush() {
87315
- const sessions = buildSessionEntries(
87316
- this.components.instanceManager.collectAllStates(),
87317
- this.components.cdpManagers,
87318
- { profile: "live" }
87319
- );
87379
+ const sessions = this.buildLiveStatusSnapshot().sessions || [];
87320
87380
  const hotSessions = classifyHotChatSessionsForSubscriptionFlush(
87321
87381
  sessions,
87322
87382
  this.hotP2PChatSessionIds
@@ -87642,24 +87702,25 @@ ${err?.stack || ""}`);
87642
87702
  return { id: req.id, success: result.success, entries: result.files, error: result.error };
87643
87703
  }
87644
87704
  });
87645
- this.p2p.onPtyInput((sessionId, data) => {
87705
+ this.p2p.onPtyInput(async (sessionId, data) => {
87646
87706
  if (!this.isCliSession(sessionId)) {
87647
87707
  this.logPtyInputDrop(sessionId, "not_cli_session");
87648
- return;
87708
+ throw new Error("not_cli_session");
87649
87709
  }
87650
87710
  const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
87651
87711
  if (!found) {
87652
87712
  this.logPtyInputDrop(sessionId, "adapter_not_found");
87653
- return;
87713
+ throw new Error("adapter_not_found");
87654
87714
  }
87655
87715
  if (typeof found.adapter.writeRaw !== "function") {
87656
87716
  this.logPtyInputDrop(sessionId, "writeRaw_missing");
87657
- return;
87717
+ throw new Error("writeRaw_missing");
87658
87718
  }
87659
87719
  try {
87660
- found.adapter.writeRaw(data);
87661
- } catch {
87720
+ await found.adapter.writeRaw(data);
87721
+ } catch (error48) {
87662
87722
  this.logPtyInputDrop(sessionId, "write_failed");
87723
+ throw error48;
87663
87724
  }
87664
87725
  });
87665
87726
  this.p2p.onPtyResize((sessionId, cols, rows) => {