adhdev 0.9.12 → 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/index.js CHANGED
@@ -8967,14 +8967,14 @@ async function handleOpenPanel(h, args) {
8967
8967
  success: revealState.visible || focusState.focused
8968
8968
  };
8969
8969
  }
8970
- function handlePtyInput(h, args) {
8970
+ async function handlePtyInput(h, args) {
8971
8971
  const { cliType, data, targetSessionId } = args || {};
8972
8972
  if (!data) return { success: false, error: "data required" };
8973
8973
  const adapter = h.getCliAdapter(targetSessionId || cliType);
8974
8974
  if (!adapter || typeof adapter.writeRaw !== "function") {
8975
8975
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
8976
8976
  }
8977
- adapter.writeRaw(data);
8977
+ await adapter.writeRaw(data);
8978
8978
  return { success: true };
8979
8979
  }
8980
8980
  function handlePtyResize(_h, args) {
@@ -9151,7 +9151,7 @@ async function executeProviderScript(h, args, scriptName) {
9151
9151
  if (cliCommand?.type === "send_message" && cliCommand.text) {
9152
9152
  await adapter.sendMessage(cliCommand.text);
9153
9153
  } else if (cliCommand?.type === "pty_write" && cliCommand.text && adapter.writeRaw) {
9154
- adapter.writeRaw(cliCommand.text + "\r");
9154
+ await adapter.writeRaw(cliCommand.text + "\r");
9155
9155
  }
9156
9156
  applyProviderPatch(h, args, parsed.payload);
9157
9157
  return {
@@ -13015,6 +13015,29 @@ var init_provider_cli_adapter = __esm({
13015
13015
  }
13016
13016
  await this.sendMessage(promptText);
13017
13017
  }
13018
+ async writeToPty(data) {
13019
+ if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
13020
+ await this.ptyProcess.write(data);
13021
+ }
13022
+ resetPendingSendState(reason) {
13023
+ this.isWaitingForResponse = false;
13024
+ this.responseBuffer = "";
13025
+ this.currentTurnScope = null;
13026
+ this.submitPendingUntil = 0;
13027
+ this.clearIdleFinishCandidate(reason);
13028
+ if (this.responseTimeout) {
13029
+ clearTimeout(this.responseTimeout);
13030
+ this.responseTimeout = null;
13031
+ }
13032
+ if (this.submitRetryTimer) {
13033
+ clearTimeout(this.submitRetryTimer);
13034
+ this.submitRetryTimer = null;
13035
+ }
13036
+ if (this.finishRetryTimer) {
13037
+ clearTimeout(this.finishRetryTimer);
13038
+ this.finishRetryTimer = null;
13039
+ }
13040
+ }
13018
13041
  async sendMessage(text) {
13019
13042
  if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
13020
13043
  const allowInputDuringGeneration = this.provider.allowInputDuringGeneration === true;
@@ -13109,19 +13132,29 @@ var init_provider_cli_adapter = __esm({
13109
13132
  if (this.isWaitingForResponse) this.finishResponse();
13110
13133
  }, this.timeouts.maxResponse);
13111
13134
  };
13112
- await new Promise((resolve16) => {
13135
+ await new Promise((resolve16, reject) => {
13113
13136
  let resolved = false;
13114
13137
  const resolveOnce = () => {
13115
13138
  if (resolved) return;
13116
13139
  resolved = true;
13117
13140
  resolve16();
13118
13141
  };
13142
+ const rejectOnce = (error48) => {
13143
+ if (resolved) return;
13144
+ this.resetPendingSendState("send_write_failed");
13145
+ resolved = true;
13146
+ reject(error48);
13147
+ };
13148
+ const writeRetryKey = (mode) => {
13149
+ void this.writeToPty(this.sendKey).catch((error48) => {
13150
+ LOG.warn("CLI", `[${this.cliType}] ${mode} write failed: ${error48?.message || error48}`);
13151
+ });
13152
+ };
13119
13153
  const submit = () => {
13120
13154
  if (!this.ptyProcess) {
13121
13155
  resolveOnce();
13122
13156
  return;
13123
13157
  }
13124
- commitUserTurn();
13125
13158
  this.submitPendingUntil = 0;
13126
13159
  const screenText = this.terminalScreen.getText();
13127
13160
  this.recordTrace("submit_write", {
@@ -13129,7 +13162,6 @@ var init_provider_cli_adapter = __esm({
13129
13162
  sendKey: this.sendKey,
13130
13163
  screenText: summarizeCliTraceText(screenText, 500)
13131
13164
  });
13132
- this.ptyProcess.write(this.sendKey);
13133
13165
  const retrySubmitIfStuck = (attempt) => {
13134
13166
  this.submitRetryTimer = null;
13135
13167
  if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
@@ -13149,19 +13181,21 @@ var init_provider_cli_adapter = __esm({
13149
13181
  sendKey: this.sendKey,
13150
13182
  screenText: summarizeCliTraceText(screenText2, 500)
13151
13183
  });
13152
- this.ptyProcess.write(this.sendKey);
13184
+ writeRetryKey("submit_retry");
13153
13185
  if (attempt >= 3) {
13154
13186
  this.submitRetryUsed = true;
13155
13187
  return;
13156
13188
  }
13157
13189
  this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
13158
13190
  };
13159
- this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
13160
- startResponseTimeout();
13161
- resolveOnce();
13191
+ void this.writeToPty(this.sendKey).then(() => {
13192
+ commitUserTurn();
13193
+ this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
13194
+ startResponseTimeout();
13195
+ resolveOnce();
13196
+ }, rejectOnce);
13162
13197
  };
13163
13198
  if (this.submitStrategy === "immediate") {
13164
- commitUserTurn();
13165
13199
  this.submitPendingUntil = 0;
13166
13200
  this.recordTrace("submit_write", {
13167
13201
  mode: "immediate",
@@ -13169,37 +13203,38 @@ var init_provider_cli_adapter = __esm({
13169
13203
  sendKey: this.sendKey,
13170
13204
  screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
13171
13205
  });
13172
- this.ptyProcess.write(text + this.sendKey);
13173
- this.submitRetryTimer = setTimeout(() => {
13174
- this.submitRetryTimer = null;
13175
- if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
13176
- if (this.currentStatus === "waiting_approval") return;
13177
- if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
13178
- const screenText = this.terminalScreen.getText();
13179
- if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
13180
- const liveApproval = this.runParseApproval(screenText) || this.runParseApproval(this.recentOutputBuffer);
13181
- if (liveApproval) return;
13182
- const liveStatus = this.runDetectStatus(screenText) || this.runDetectStatus(this.recentOutputBuffer);
13183
- if (liveStatus === "generating" || liveStatus === "waiting_approval") return;
13184
- LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
13185
- this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
13186
- this.recordTrace("submit_write", {
13187
- mode: "immediate_retry",
13188
- attempt: 1,
13189
- sendKey: this.sendKey,
13190
- screenText: summarizeCliTraceText(screenText, 500)
13191
- });
13192
- this.ptyProcess.write(this.sendKey);
13193
- this.submitRetryUsed = true;
13194
- }, retryDelayMs);
13195
- startResponseTimeout();
13196
- resolveOnce();
13206
+ void this.writeToPty(text + this.sendKey).then(() => {
13207
+ commitUserTurn();
13208
+ this.submitRetryTimer = setTimeout(() => {
13209
+ this.submitRetryTimer = null;
13210
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
13211
+ if (this.currentStatus === "waiting_approval") return;
13212
+ if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
13213
+ const screenText = this.terminalScreen.getText();
13214
+ if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
13215
+ const liveApproval = this.runParseApproval(screenText) || this.runParseApproval(this.recentOutputBuffer);
13216
+ if (liveApproval) return;
13217
+ const liveStatus = this.runDetectStatus(screenText) || this.runDetectStatus(this.recentOutputBuffer);
13218
+ if (liveStatus === "generating" || liveStatus === "waiting_approval") return;
13219
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
13220
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
13221
+ this.recordTrace("submit_write", {
13222
+ mode: "immediate_retry",
13223
+ attempt: 1,
13224
+ sendKey: this.sendKey,
13225
+ screenText: summarizeCliTraceText(screenText, 500)
13226
+ });
13227
+ writeRetryKey("immediate_retry");
13228
+ this.submitRetryUsed = true;
13229
+ }, retryDelayMs);
13230
+ startResponseTimeout();
13231
+ resolveOnce();
13232
+ }, rejectOnce);
13197
13233
  return;
13198
13234
  }
13199
13235
  if (submitDelayMs > 0) {
13200
13236
  this.submitPendingUntil = Date.now() + submitDelayMs;
13201
13237
  }
13202
- this.ptyProcess.write(text);
13203
13238
  this.recordTrace("submit_write", {
13204
13239
  mode: "type_then_submit",
13205
13240
  text: summarizeCliTraceText(text, 500),
@@ -13236,7 +13271,7 @@ var init_provider_cli_adapter = __esm({
13236
13271
  }
13237
13272
  setTimeout(waitForEchoAndSubmit, 50);
13238
13273
  };
13239
- waitForEchoAndSubmit();
13274
+ void this.writeToPty(text).then(() => waitForEchoAndSubmit(), rejectOnce);
13240
13275
  });
13241
13276
  }
13242
13277
  getPartialResponse() {
@@ -13391,12 +13426,12 @@ var init_provider_cli_adapter = __esm({
13391
13426
  isReady() {
13392
13427
  return this.ready;
13393
13428
  }
13394
- writeRaw(data) {
13429
+ async writeRaw(data) {
13395
13430
  this.recordTrace("write_raw", {
13396
13431
  keys: JSON.stringify(data),
13397
13432
  length: data.length
13398
13433
  });
13399
- this.ptyProcess?.write(data);
13434
+ await this.writeToPty(data);
13400
13435
  }
13401
13436
  resolveModal(buttonIndex) {
13402
13437
  let modal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
@@ -13942,7 +13977,7 @@ var init_cli_provider_instance = __esm({
13942
13977
  if (cliCommand?.type === "send_message" && cliCommand.text) {
13943
13978
  await this.adapter.sendMessage(cliCommand.text);
13944
13979
  } else if (cliCommand?.type === "pty_write" && cliCommand.text) {
13945
- this.adapter.writeRaw(cliCommand.text + "\r");
13980
+ await this.adapter.writeRaw(cliCommand.text + "\r");
13946
13981
  }
13947
13982
  this.applyProviderResponse(parsed.payload, { phase: "immediate" });
13948
13983
  }
@@ -41917,7 +41952,7 @@ async function handleCliRaw(ctx, req, res) {
41917
41952
  }
41918
41953
  try {
41919
41954
  if (typeof adapter.writeRaw === "function") {
41920
- adapter.writeRaw(keys);
41955
+ await adapter.writeRaw(keys);
41921
41956
  ctx.json(res, 200, { sent: true, type: target.type, instanceId: target.instanceId, keysLength: keys.length });
41922
41957
  } else {
41923
41958
  ctx.json(res, 400, { error: "writeRaw not available on this adapter" });
@@ -44880,7 +44915,7 @@ var init_session_host_transport = __esm({
44880
44915
  this.exitCallbacks.add(callback);
44881
44916
  }
44882
44917
  write(data) {
44883
- this.enqueue(async () => {
44918
+ return this.enqueue(async () => {
44884
44919
  let response = await this.client.request({
44885
44920
  type: "send_input",
44886
44921
  payload: {
@@ -45182,9 +45217,11 @@ var init_session_host_transport = __esm({
45182
45217
  };
45183
45218
  }
45184
45219
  enqueue(action) {
45185
- this.operationChain = this.operationChain.then(() => this.ready).then(action).catch((error48) => {
45220
+ const operation = this.operationChain.then(() => this.ready).then(action);
45221
+ this.operationChain = operation.catch((error48) => {
45186
45222
  LOG.warn("CLI", `[session-host:${this.options.runtimeId}] ${error48?.message || error48}`);
45187
45223
  });
45224
+ return operation;
45188
45225
  }
45189
45226
  async closeClient(destroy = false) {
45190
45227
  if (this.closed) return;
@@ -46517,14 +46554,41 @@ function routeDataChannelMessage(peerId, msg, peers, handlers) {
46517
46554
  return;
46518
46555
  }
46519
46556
  if (parsed.type === "pty_input") {
46520
- const permission = peers.get(peerId)?.sharePermission;
46557
+ const peer = peers.get(peerId);
46558
+ const permission = peer?.sharePermission;
46559
+ const sendPtyInputError = (sessionId2, reason, error48) => {
46560
+ const message = error48 instanceof Error ? error48.message : typeof error48 === "string" ? error48 : void 0;
46561
+ sendToPeer(peer, {
46562
+ type: "session_io_error",
46563
+ sessionId: sessionId2,
46564
+ reason,
46565
+ ...message ? { error: message } : {}
46566
+ });
46567
+ };
46521
46568
  if (permission) {
46522
46569
  log(`pty_input: REJECTED \u2014 permission=${permission} peer=${peerId}`);
46570
+ const sessionId2 = typeof (parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType) === "string" ? parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType : "";
46571
+ sendPtyInputError(sessionId2, "permission_denied");
46572
+ return;
46573
+ }
46574
+ const sessionIdCandidate = parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType || "";
46575
+ const sessionId = typeof sessionIdCandidate === "string" ? sessionIdCandidate : "";
46576
+ if (!sessionId || typeof parsed.data !== "string" || parsed.data.length === 0) {
46577
+ sendPtyInputError(sessionId, "invalid_payload");
46523
46578
  return;
46524
46579
  }
46525
- const sessionId = parsed.sessionId || parsed.targetSessionId || parsed.cliId || parsed.cliType || "";
46526
- if (handlers.ptyInputHandler && parsed.data && sessionId) {
46527
- handlers.ptyInputHandler(sessionId, parsed.data);
46580
+ if (!handlers.ptyInputHandler) {
46581
+ sendPtyInputError(sessionId, "handler_unavailable");
46582
+ return;
46583
+ }
46584
+ try {
46585
+ Promise.resolve(handlers.ptyInputHandler(sessionId, parsed.data)).catch((error48) => {
46586
+ log(`pty_input write failed: peer=${peerId} sessionId=${sessionId} error=${error48?.message || error48}`);
46587
+ sendPtyInputError(sessionId, "write_failed", error48);
46588
+ });
46589
+ } catch (error48) {
46590
+ log(`pty_input write failed: peer=${peerId} sessionId=${sessionId} error=${error48?.message || error48}`);
46591
+ sendPtyInputError(sessionId, "write_failed", error48);
46528
46592
  }
46529
46593
  return;
46530
46594
  }
@@ -55396,7 +55460,7 @@ var init_adhdev_daemon = __esm({
55396
55460
  init_version();
55397
55461
  init_src();
55398
55462
  init_runtime_defaults();
55399
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.12" });
55463
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.13" });
55400
55464
  AdhdevDaemon = class _AdhdevDaemon {
55401
55465
  localHttpServer = null;
55402
55466
  localWss = null;
@@ -55918,24 +55982,25 @@ ${err?.stack || ""}`);
55918
55982
  return { id: req.id, success: result.success, entries: result.files, error: result.error };
55919
55983
  }
55920
55984
  });
55921
- this.p2p.onPtyInput((sessionId, data) => {
55985
+ this.p2p.onPtyInput(async (sessionId, data) => {
55922
55986
  if (!this.isCliSession(sessionId)) {
55923
55987
  this.logPtyInputDrop(sessionId, "not_cli_session");
55924
- return;
55988
+ throw new Error("not_cli_session");
55925
55989
  }
55926
55990
  const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
55927
55991
  if (!found) {
55928
55992
  this.logPtyInputDrop(sessionId, "adapter_not_found");
55929
- return;
55993
+ throw new Error("adapter_not_found");
55930
55994
  }
55931
55995
  if (typeof found.adapter.writeRaw !== "function") {
55932
55996
  this.logPtyInputDrop(sessionId, "writeRaw_missing");
55933
- return;
55997
+ throw new Error("writeRaw_missing");
55934
55998
  }
55935
55999
  try {
55936
- found.adapter.writeRaw(data);
55937
- } catch {
56000
+ await found.adapter.writeRaw(data);
56001
+ } catch (error48) {
55938
56002
  this.logPtyInputDrop(sessionId, "write_failed");
56003
+ throw error48;
55939
56004
  }
55940
56005
  });
55941
56006
  this.p2p.onPtyResize((sessionId, cols, rows) => {