@dmsdc-ai/aigentry-telepty 0.1.18 → 0.1.20

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.
Files changed (2) hide show
  1. package/cli.js +47 -2
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -694,6 +694,28 @@ async function main() {
694
694
  env: { ...process.env, TELEPTY_SESSION_ID: sessionId }
695
695
  });
696
696
 
697
+ // Prompt-ready detection for safe inject delivery
698
+ const PROMPT_PATTERNS = {
699
+ claude: /[❯>]\s*$/,
700
+ gemini: /[❯>]\s*$/,
701
+ codex: /[❯>]\s*$/,
702
+ };
703
+ const cmdBase = path.basename(command).replace(/\..*$/, '');
704
+ const promptPattern = PROMPT_PATTERNS[cmdBase] || /[❯>$#%]\s*$/;
705
+ let promptReady = true; // assume ready initially for first inject
706
+ const injectQueue = [];
707
+
708
+ function flushInjectQueue() {
709
+ if (injectQueue.length === 0) return;
710
+ const batch = injectQueue.splice(0);
711
+ let delay = 0;
712
+ for (const item of batch) {
713
+ setTimeout(() => child.write(item), delay);
714
+ delay += item === '\r' ? 0 : 100;
715
+ }
716
+ promptReady = false;
717
+ }
718
+
697
719
  // Connect to daemon WebSocket for inject reception and output relay
698
720
  const wsUrl = `ws://${REMOTE_HOST}:${PORT}/api/sessions/${encodeURIComponent(sessionId)}?token=${encodeURIComponent(TOKEN)}`;
699
721
  const daemonWs = new WebSocket(wsUrl);
@@ -708,7 +730,15 @@ async function main() {
708
730
  try {
709
731
  const msg = JSON.parse(message);
710
732
  if (msg.type === 'inject') {
711
- child.write(msg.data);
733
+ if (promptReady) {
734
+ child.write(msg.data);
735
+ // After writing prompt text (not \r), mark as not ready until next prompt
736
+ if (msg.data !== '\r' && msg.data.length > 1) {
737
+ promptReady = false;
738
+ }
739
+ } else {
740
+ injectQueue.push(msg.data);
741
+ }
712
742
  } else if (msg.type === 'resize') {
713
743
  child.resize(msg.cols, msg.rows);
714
744
  }
@@ -740,12 +770,27 @@ async function main() {
740
770
  }
741
771
  });
742
772
 
773
+ // Intercept terminal title escape sequences and prefix with session ID
774
+ const titlePrefix = `\u26A1 ${sessionId}`;
775
+ function rewriteTitleSequences(output) {
776
+ // Match OSC title sequences: \x1b]0;TITLE\x07 or \x1b]2;TITLE\x07
777
+ return output.replace(/\x1b\]([02]);([^\x07]*)\x07/g, (match, code, title) => {
778
+ return `\x1b]${code};${titlePrefix} | ${title}\x07`;
779
+ });
780
+ }
781
+
743
782
  // Relay PTY output to current terminal + send to daemon for attach clients
744
783
  child.onData((data) => {
745
- process.stdout.write(data);
784
+ const rewritten = rewriteTitleSequences(data);
785
+ process.stdout.write(rewritten);
746
786
  if (wsReady && daemonWs.readyState === 1) {
747
787
  daemonWs.send(JSON.stringify({ type: 'output', data }));
748
788
  }
789
+ // Detect prompt in output to enable inject delivery
790
+ if (promptPattern.test(data)) {
791
+ promptReady = true;
792
+ flushInjectQueue();
793
+ }
749
794
  });
750
795
 
751
796
  // Handle child exit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-telepty",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "main": "daemon.js",
5
5
  "bin": {
6
6
  "aigentry-telepty": "install.js",