@adhdev/daemon-core 0.9.82-rc.341 → 0.9.82-rc.342

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.341",
3
+ "version": "0.9.82-rc.342",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,7 +46,7 @@
46
46
  "author": "vilmire",
47
47
  "license": "AGPL-3.0-or-later",
48
48
  "dependencies": {
49
- "@adhdev/mesh-shared": "0.9.82-rc.341",
49
+ "@adhdev/mesh-shared": "0.9.82-rc.342",
50
50
  "@adhdev/session-host-core": "*",
51
51
  "@agentclientprotocol/sdk": "^0.16.1",
52
52
  "ajv": "^8.20.0",
@@ -145,6 +145,14 @@ function countNewlines(s: string): number {
145
145
 
146
146
  const SUBMIT_DELAY_FLOOR_MS = 200;
147
147
 
148
+ // win32 ConPTY submit reliability: after the text settles we write the submit
149
+ // key (CR) as its OWN keystroke, then repeat it once after a short gap. The
150
+ // repeat is the safety net for the case where ConPTY drops/coalesces the first
151
+ // lone CR; on an already-submitted prompt the second CR lands on an empty input
152
+ // and is a harmless no-op. The gap must be long enough that the TUI has redrawn
153
+ // after the first CR before the second arrives.
154
+ const WIN32_SUBMIT_REPEAT_GAP_MS = 300;
155
+
148
156
  export function resolveSubmitDelayMs(specBeforeSubmit: number | undefined, text: string): number {
149
157
  const lines = countNewlines(text);
150
158
  const linesBonus = Math.min(800, lines * 80);
@@ -832,24 +840,26 @@ export class FsmDriver implements ISpecDriver {
832
840
  const perChar = sm.delay_ms_per_char ?? 0;
833
841
  const beforeSubmit = resolveSubmitDelayMs(sm.delay_ms_before_submit, text);
834
842
 
835
- // win32 ConPTY swallows a lone submit key (CR) that arrives in its own
836
- // PTY chunk after a delay: ConPTY does not treat a delayed, standalone
837
- // CR as a submit, so the prompt sits typed-but-unsent until the user
838
- // hits Enter manually. mac/linux PTYs do recognise the split write, so
839
- // this asymmetry is win32-only. The fix mirrors the legacy
840
- // ProviderCliAdapter.forceSendMessage fix: honour the settle delay so
841
- // the TUI input handler is ready, then write `text + submit_key` as ONE
842
- // PTY write keeping the submit key in the same write unit as the text
843
- // is the invariant ConPTY needs to recognise the submit. perChar typing
844
- // simulation is skipped on win32 (a per-char loop necessarily ends with a
845
- // separate trailing CR); correctness of submission wins over the typing
846
- // visual there.
843
+ // win32 ConPTY submit: the text and the submit key (CR) must NOT be
844
+ // combined into one PTY write. Ink-based TUIs (claude-cli) treat a single
845
+ // write that carries text + a trailing CR as a bracketed/multi-line paste
846
+ // and absorb the CR as a literal newline in the input box instead of a
847
+ // submit keystroke the prompt sits typed-but-unsent until the user hits
848
+ // Enter manually. (A previous "atomic write" attempt regressed exactly
849
+ // this way.) Instead, write the text, let it settle so the TUI leaves any
850
+ // paste-accumulation state, then deliver the CR as its OWN keystroke. We
851
+ // send the CR twice with a short gap: ConPTY can drop/coalesce the first
852
+ // lone CR, and a second CR on an already-submitted (now empty) prompt is a
853
+ // harmless no-op. perChar typing simulation is skipped on win32;
854
+ // correctness of submission wins over the typing visual there.
847
855
  if (process.platform === 'win32') {
848
- if (beforeSubmit > 0) {
849
- setTimeout(() => this.adapter.send_keys(text + sm.submit_key), beforeSubmit);
850
- } else {
851
- this.adapter.send_keys(text + sm.submit_key);
852
- }
856
+ const submitTwice = (): void => {
857
+ this.adapter.send_keys(sm.submit_key);
858
+ setTimeout(() => this.adapter.send_keys(sm.submit_key), WIN32_SUBMIT_REPEAT_GAP_MS);
859
+ };
860
+ this.adapter.send_keys(text);
861
+ if (beforeSubmit > 0) setTimeout(submitTwice, beforeSubmit);
862
+ else submitTwice();
853
863
  return;
854
864
  }
855
865