@dmsdc-ai/aigentry-telepty 0.5.4 → 0.5.5

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/daemon.js CHANGED
@@ -1180,32 +1180,37 @@ async function writeDataToSession(id, session, data) {
1180
1180
  }
1181
1181
 
1182
1182
  /**
1183
- * Submit Enter to a session using terminal-level methods.
1183
+ * Submit Enter to a session via the PTY/context layer.
1184
1184
  * Used by POST /submit endpoint for explicit terminal-level submit.
1185
- * Priority: kitty send-text → cmux send-key → PTY \r fallback.
1186
- * Returns the strategy name or null on failure.
1185
+ *
1186
+ * Submit is a CONTEXT operation (telepty-owned), not a SURFACE operation
1187
+ * (cmux/kitty adaptor-owned). Deliver the submit Enter via the PTY only — a bare
1188
+ * 0x0D into the CLI's innermost node-pty. The former kitty `send-text` (P1) and
1189
+ * `cmux send-key` (P2) branches were SURFACE ops on a flaky side channel (75×
1190
+ * "Failed to write to socket" vs 0× for pty_cr in a 222k-line run; live
1191
+ * 2026-06-07 confirmed pty-only works 3/3). `submitViaCmux`/`sendViaKitty` defs
1192
+ * are kept (non-submit callers); codebase removal is gated on the warp/tmux
1193
+ * matrix. See docs/adr/2026-06-07-submit-via-pty-context-layer.md.
1194
+ *
1195
+ * Returns the strategy name ('pty_cr') or null on failure.
1187
1196
  */
1188
1197
  function terminalLevelSubmit(id, session) {
1189
- // Priority 1: kitty send-text (terminal-level, bypasses PTY raw mode quirks)
1190
- if (session.type === 'wrapped' && sendViaKitty(id, '\r')) return 'kitty';
1191
- // Priority 2: cmux send-key
1192
- if (session.backend === 'cmux' && session.cmuxWorkspaceId && submitViaCmux(id)) return 'cmux';
1193
- // Priority 3: PTY \r
1194
1198
  if (submitViaPty(session)) return 'pty_cr';
1195
1199
  return null;
1196
1200
  }
1197
1201
 
1198
- // #537 / Bug B: a forced submit is only HONESTLY confirmed when its strategy actually
1199
- // reached the rendered surface. On a cmux-backed session the surface is cmux; a `pty_cr`
1200
- // fallback means `cmux send-key` failed ("Failed to write to socket") and the live CLI
1201
- // never received Enter. Terminal-level strategies (kitty/cmux) are real delivery; a pty_cr
1202
- // fallback on a cmux surface is NOT. Pure + exported so the decision is unit-testable.
1202
+ // #544 / #537 / Bug B: with PTY-native submit (terminalLevelSubmit pty_cr only),
1203
+ // a successful pty_cr IS real delivery on every backend — the bare 0x0D reaches the
1204
+ // CLI's innermost node-pty directly (live 2026-06-07: pty-only delivered 3/3 even
1205
+ // when cmux send-key failed). The honest "was it accepted?" signal is the
1206
+ // PTY-derived confirm (confirmSubmitAccepted: state∈{working,thinking} since≥
1207
+ // submittedAt, or body consumed from outputRing) — NOT the strategy name. We no
1208
+ // longer special-case pty_cr-on-cmux as undelivered; that false-negative was the
1209
+ // direct cause of the BUG B bogus UNCONFIRMED reports + worker re-send loops.
1210
+ // Pure + exported so the decision is unit-testable.
1211
+ // See docs/adr/2026-06-07-submit-via-pty-context-layer.md.
1203
1212
  function forceSubmitDeliveredToSurface(session, strategy) {
1204
- if (!strategy) return false;
1205
- if (session && session.backend === 'cmux' && session.cmuxWorkspaceId && strategy === 'pty_cr') {
1206
- return false;
1207
- }
1208
- return true;
1213
+ return !!strategy;
1209
1214
  }
1210
1215
 
1211
1216
  async function deliverInjectionToSession(id, session, prompt, options = {}) {
@@ -3520,7 +3525,9 @@ if (require.main === module) {
3520
3525
  // production call sites is unchanged. NOT a public API — internal/test use only.
3521
3526
  module.exports = {
3522
3527
  fireAutoReport, // #32: provenance-tagged auto-report (deps DI: now/deliver/...)
3523
- forceSubmitDeliveredToSurface, // #537/Bug B: honest force-confirm (pty_cr on cmux = not delivered)
3528
+ forceSubmitDeliveredToSurface, // #544/#537/Bug B: PTY-native force-confirm (pty_cr = delivered)
3529
+ terminalLevelSubmit, // #544: PTY-only submit path (pty_cr | null)
3530
+ submitViaPty, // #544: bare-0x0D submit into the innermost node-pty
3524
3531
  failBootstrapQueueOnTimeout, // #31: actionable bootstrap-timeout queue flush
3525
3532
  shouldApplyOwnerAliveFloor, // #29: owner-alive optimistic-floor decision (deps DI: isProcessRunning/...)
3526
3533
  scheduleBootstrapPromptPoll, // #29: arms the floor timer (deps DI: setTimeout/...)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-telepty",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "main": "daemon.js",
5
5
  "bin": {
6
6
  "aigentry-telepty": "install.js",
@@ -35,9 +35,9 @@
35
35
  ],
36
36
  "scripts": {
37
37
  "postinstall": "node scripts/postinstall.js",
38
- "test": "node --test test/auth.test.js test/http-auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/integration/daemon-launch.test.js test/cli.test.js test/telepty-kill.test.js test/idle-ttl.test.js test/telepty-clean-older-than.test.js test/lifecycle-transport-agnostic.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js test/session-state.test.js test/session-store-persistence.test.js test/mailbox-lock.test.js test/report-enforcement.test.js test/enforce-report.test.js test/enforce-submit-gate.test.js test/submit-gate.test.js test/prompt-symbol-registry.test.js test/inject-submit-flags.test.js test/inject-submit-force-env.test.js test/host-spec.test.js test/cross-host-inject.test.js test/cross-machine-ssh-routing.test.js test/init.test.js test/win-resolve-executable.test.js test/version-handshake.test.js test/win-kill-process.test.js test/daemon-control-port-owner.test.js test/banner-stderr-jq-safety.test.js test/bridge-supervisor-ipc.test.js test/bridge-j3-shim.test.js test/bridge-e2e.test.js test/release-0.4.5-bugfixes.test.js && git diff --exit-code tests/snippet-protocol/v1/",
39
- "test:watch": "node --test --watch test/auth.test.js test/http-auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/integration/daemon-launch.test.js test/cli.test.js test/telepty-kill.test.js test/idle-ttl.test.js test/telepty-clean-older-than.test.js test/lifecycle-transport-agnostic.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js test/session-state.test.js test/session-store-persistence.test.js test/mailbox-lock.test.js test/report-enforcement.test.js test/enforce-report.test.js test/enforce-submit-gate.test.js test/submit-gate.test.js test/prompt-symbol-registry.test.js test/inject-submit-flags.test.js test/inject-submit-force-env.test.js test/host-spec.test.js test/cross-host-inject.test.js test/cross-machine-ssh-routing.test.js test/init.test.js test/win-resolve-executable.test.js test/version-handshake.test.js test/win-kill-process.test.js test/daemon-control-port-owner.test.js test/banner-stderr-jq-safety.test.js test/bridge-supervisor-ipc.test.js test/bridge-j3-shim.test.js test/bridge-e2e.test.js test/release-0.4.5-bugfixes.test.js",
40
- "test:ci": "node --test --test-reporter=spec test/auth.test.js test/http-auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/integration/daemon-launch.test.js test/cli.test.js test/telepty-kill.test.js test/idle-ttl.test.js test/telepty-clean-older-than.test.js test/lifecycle-transport-agnostic.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js test/session-state.test.js test/session-store-persistence.test.js test/mailbox-lock.test.js test/report-enforcement.test.js test/enforce-report.test.js test/enforce-submit-gate.test.js test/submit-gate.test.js test/prompt-symbol-registry.test.js test/inject-submit-flags.test.js test/inject-submit-force-env.test.js test/host-spec.test.js test/cross-host-inject.test.js test/cross-machine-ssh-routing.test.js test/init.test.js test/win-resolve-executable.test.js test/version-handshake.test.js test/win-kill-process.test.js test/daemon-control-port-owner.test.js test/banner-stderr-jq-safety.test.js test/bridge-supervisor-ipc.test.js test/bridge-j3-shim.test.js test/bridge-e2e.test.js test/release-0.4.5-bugfixes.test.js && git diff --exit-code tests/snippet-protocol/v1/",
38
+ "test": "node --test test/auth.test.js test/http-auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/integration/daemon-launch.test.js test/cli.test.js test/telepty-kill.test.js test/idle-ttl.test.js test/telepty-clean-older-than.test.js test/lifecycle-transport-agnostic.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js test/session-state.test.js test/session-store-persistence.test.js test/mailbox-lock.test.js test/report-enforcement.test.js test/enforce-report.test.js test/enforce-submit-gate.test.js test/submit-gate.test.js test/submit-via-pty.test.js test/prompt-symbol-registry.test.js test/inject-submit-flags.test.js test/inject-submit-force-env.test.js test/host-spec.test.js test/cross-host-inject.test.js test/cross-machine-ssh-routing.test.js test/init.test.js test/win-resolve-executable.test.js test/version-handshake.test.js test/win-kill-process.test.js test/daemon-control-port-owner.test.js test/banner-stderr-jq-safety.test.js test/bridge-supervisor-ipc.test.js test/bridge-j3-shim.test.js test/bridge-e2e.test.js test/release-0.4.5-bugfixes.test.js && git diff --exit-code tests/snippet-protocol/v1/",
39
+ "test:watch": "node --test --watch test/auth.test.js test/http-auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/integration/daemon-launch.test.js test/cli.test.js test/telepty-kill.test.js test/idle-ttl.test.js test/telepty-clean-older-than.test.js test/lifecycle-transport-agnostic.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js test/session-state.test.js test/session-store-persistence.test.js test/mailbox-lock.test.js test/report-enforcement.test.js test/enforce-report.test.js test/enforce-submit-gate.test.js test/submit-gate.test.js test/submit-via-pty.test.js test/prompt-symbol-registry.test.js test/inject-submit-flags.test.js test/inject-submit-force-env.test.js test/host-spec.test.js test/cross-host-inject.test.js test/cross-machine-ssh-routing.test.js test/init.test.js test/win-resolve-executable.test.js test/version-handshake.test.js test/win-kill-process.test.js test/daemon-control-port-owner.test.js test/banner-stderr-jq-safety.test.js test/bridge-supervisor-ipc.test.js test/bridge-j3-shim.test.js test/bridge-e2e.test.js test/release-0.4.5-bugfixes.test.js",
40
+ "test:ci": "node --test --test-reporter=spec test/auth.test.js test/http-auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/integration/daemon-launch.test.js test/cli.test.js test/telepty-kill.test.js test/idle-ttl.test.js test/telepty-clean-older-than.test.js test/lifecycle-transport-agnostic.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js test/session-state.test.js test/session-store-persistence.test.js test/mailbox-lock.test.js test/report-enforcement.test.js test/enforce-report.test.js test/enforce-submit-gate.test.js test/submit-gate.test.js test/submit-via-pty.test.js test/prompt-symbol-registry.test.js test/inject-submit-flags.test.js test/inject-submit-force-env.test.js test/host-spec.test.js test/cross-host-inject.test.js test/cross-machine-ssh-routing.test.js test/init.test.js test/win-resolve-executable.test.js test/version-handshake.test.js test/win-kill-process.test.js test/daemon-control-port-owner.test.js test/banner-stderr-jq-safety.test.js test/bridge-supervisor-ipc.test.js test/bridge-j3-shim.test.js test/bridge-e2e.test.js test/release-0.4.5-bugfixes.test.js && git diff --exit-code tests/snippet-protocol/v1/",
41
41
  "typecheck": "tsc --noEmit",
42
42
  "regen-fixtures": "node scripts/regen-snippet-fixtures.js"
43
43
  },
@@ -308,10 +308,16 @@ function observeBodyVisibility(session, bodyText, opts = {}) {
308
308
  };
309
309
  }
310
310
 
311
+ // PTY-native confirm (#544): do NOT shell to `cmux read-screen` for the submit
312
+ // confirm. The body-visibility source is the PTY-fed outputRing
313
+ // (observeBodyVisibility falls through to it when this returns null). An explicit
314
+ // opts.readScreen seam is still honored (tests / future surface adaptors); the
315
+ // cmux default is dropped so confirmation is screen-free and no longer depends on
316
+ // the flaky cmux surface. The pre-submit readiness probe (awaitPromptSymbol) keeps
317
+ // its own defaultReadScreen — that is a separate concern, out of scope here.
318
+ // See docs/adr/2026-06-07-submit-via-pty-context-layer.md.
311
319
  function readCurrentScreen(session, opts = {}) {
312
- const readScreen = typeof opts.readScreen === 'function'
313
- ? opts.readScreen
314
- : (session && session.backend === 'cmux' && session.cmuxWorkspaceId ? defaultReadScreen : null);
320
+ const readScreen = typeof opts.readScreen === 'function' ? opts.readScreen : null;
315
321
  if (!readScreen || !session || !session.cmuxWorkspaceId) return null;
316
322
  const tailLines = Number.isFinite(opts.tailLines) ? opts.tailLines : 30;
317
323
  try {