opentmux 1.5.1 → 1.5.4

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.
@@ -575,18 +575,14 @@ function spawnPluginUpdater() {
575
575
  const updaterPath = join3(__dirname2, "../scripts/update-plugins.js");
576
576
  if (!existsSync2(updaterPath)) return;
577
577
  try {
578
- const child = spawn(
579
- process.execPath,
580
- [updaterPath],
581
- {
582
- stdio: "ignore",
583
- detached: true,
584
- env: {
585
- ...process.env,
586
- OPENCODE_TMUX_UPDATE: "1"
587
- }
578
+ const child = spawn(process.execPath, [updaterPath], {
579
+ stdio: "ignore",
580
+ detached: true,
581
+ env: {
582
+ ...process.env,
583
+ OPENCODE_TMUX_UPDATE: "1"
588
584
  }
589
- );
585
+ });
590
586
  child.unref();
591
587
  } catch (error) {
592
588
  }
@@ -598,13 +594,19 @@ function findOpencodeBin() {
598
594
  const currentScript = argv[1];
599
595
  for (const bin of output) {
600
596
  const normalizedBin = bin.trim();
601
- if (normalizedBin.includes("opentmux") || normalizedBin === currentScript) continue;
597
+ if (normalizedBin.includes("opentmux") || normalizedBin === currentScript)
598
+ continue;
602
599
  if (normalizedBin) return normalizedBin;
603
600
  }
604
601
  } catch (e) {
605
602
  }
606
603
  const commonPaths = [
607
- join3(homedir(), ".opencode", "bin", platform2 === "win32" ? "opencode.exe" : "opencode"),
604
+ join3(
605
+ homedir(),
606
+ ".opencode",
607
+ "bin",
608
+ platform2 === "win32" ? "opencode.exe" : "opencode"
609
+ ),
608
610
  join3(homedir(), "AppData", "Local", "opencode", "bin", "opencode.exe"),
609
611
  "/usr/local/bin/opencode",
610
612
  "/usr/bin/opencode"
@@ -639,9 +641,9 @@ async function isOpencodeHealthy(port) {
639
641
  const timeout = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS);
640
642
  const healthUrl = `http://127.0.0.1:${port}/health`;
641
643
  try {
642
- const response = await fetch(healthUrl, { signal: controller.signal }).catch(
643
- () => null
644
- );
644
+ const response = await fetch(healthUrl, {
645
+ signal: controller.signal
646
+ }).catch(() => null);
645
647
  return response?.ok ?? false;
646
648
  } catch {
647
649
  return false;
@@ -731,19 +733,35 @@ async function tryReclaimPort(port, tmuxPanePids) {
731
733
  );
732
734
  if (command && command.includes("opencode")) {
733
735
  if (inTmux) {
734
- log2("Port owned by tmux process, skipping:", port.toString(), pid.toString());
736
+ log2(
737
+ "Port owned by tmux process, skipping:",
738
+ port.toString(),
739
+ pid.toString()
740
+ );
735
741
  continue;
736
742
  }
737
743
  if (hasTtyPeers) {
738
- log2("Port owned by active tty process, skipping:", port.toString(), pid.toString());
744
+ log2(
745
+ "Port owned by active tty process, skipping:",
746
+ port.toString(),
747
+ pid.toString()
748
+ );
739
749
  continue;
740
750
  }
741
751
  if (isForegroundProcess(pid)) {
742
- log2("Port owned by potentially busy foreground process, skipping:", port.toString(), pid.toString());
752
+ log2(
753
+ "Port owned by potentially busy foreground process, skipping:",
754
+ port.toString(),
755
+ pid.toString()
756
+ );
743
757
  continue;
744
758
  }
745
759
  }
746
- log2("Attempting to stop stale or non-opencode process:", port.toString(), pid.toString());
760
+ log2(
761
+ "Attempting to stop stale or non-opencode process:",
762
+ port.toString(),
763
+ pid.toString()
764
+ );
747
765
  attemptedKill = true;
748
766
  try {
749
767
  process.kill(pid, "SIGTERM");
@@ -754,7 +772,11 @@ async function tryReclaimPort(port, tmuxPanePids) {
754
772
  await new Promise((resolve) => setTimeout(resolve, 700));
755
773
  for (const pid of pids) {
756
774
  if (isProcessAlive(pid)) {
757
- log2("Process still alive, sending SIGKILL:", port.toString(), pid.toString());
775
+ log2(
776
+ "Process still alive, sending SIGKILL:",
777
+ port.toString(),
778
+ pid.toString()
779
+ );
758
780
  try {
759
781
  process.kill(pid, "SIGKILL");
760
782
  } catch {
@@ -786,8 +808,7 @@ function hasTmux() {
786
808
  }
787
809
  async function main() {
788
810
  const isRuntime = /\/?(node|bun)(\.exe)?$/i.test(argv[0]);
789
- const isScriptFile = argv[1] ? /\.(js|ts)$/.test(argv[1]) : false;
790
- const args = isRuntime && isScriptFile ? argv.slice(2) : argv.slice(1);
811
+ const args = isRuntime ? argv.slice(2) : argv.slice(1);
791
812
  if (args.includes("--reap") || args.includes("-reap")) {
792
813
  await ZombieReaper.reapAll();
793
814
  exit(0);
@@ -827,7 +848,8 @@ async function main() {
827
848
  "-h"
828
849
  ];
829
850
  const isCliCommand = args.length > 0 && NON_TUI_COMMANDS.includes(args[0]);
830
- if (isCliCommand) {
851
+ const isInteractiveMode = args.length === 0;
852
+ if (isCliCommand || isInteractiveMode) {
831
853
  const opencodeBin2 = findOpencodeBin();
832
854
  if (!opencodeBin2) {
833
855
  console.error(
@@ -862,7 +884,9 @@ async function main() {
862
884
  const opencodeBin = findOpencodeBin();
863
885
  log2("Found opencode binary:", opencodeBin);
864
886
  if (!opencodeBin) {
865
- console.error('Error: Could not find "opencode" binary in PATH or common locations.');
887
+ console.error(
888
+ 'Error: Could not find "opencode" binary in PATH or common locations.'
889
+ );
866
890
  log2("ERROR: opencode binary not found");
867
891
  exit(1);
868
892
  }
@@ -891,7 +915,9 @@ async function main() {
891
915
  }
892
916
  if (oldestPid && targetPort !== -1) {
893
917
  log2("Rotating port:", targetPort, "Killing oldest PID:", oldestPid);
894
- console.log(`\u267B\uFE0F Port rotation: Killing oldest session (PID ${oldestPid}) on port ${targetPort} to make room...`);
918
+ console.log(
919
+ `\u267B\uFE0F Port rotation: Killing oldest session (PID ${oldestPid}) on port ${targetPort} to make room...`
920
+ );
895
921
  safeKill(oldestPid, "SIGTERM");
896
922
  await waitForProcessExit(oldestPid, 2e3);
897
923
  if (isProcessAlive(oldestPid)) {
@@ -902,17 +928,25 @@ async function main() {
902
928
  port = targetPort;
903
929
  log2("Port reclaimed successfully:", port);
904
930
  } else {
905
- console.error(`\u26A0\uFE0F Failed to reclaim port ${targetPort} even after killing PID ${oldestPid}.`);
931
+ console.error(
932
+ `\u26A0\uFE0F Failed to reclaim port ${targetPort} even after killing PID ${oldestPid}.`
933
+ );
906
934
  exit(1);
907
935
  }
908
936
  } else {
909
- console.error("Error: Could not find any valid OpenCode sessions to rotate.");
937
+ console.error(
938
+ "Error: Could not find any valid OpenCode sessions to rotate."
939
+ );
910
940
  exit(1);
911
941
  }
912
942
  } else {
913
- console.error(`Error: No available ports found in range ${OPENCODE_PORT_START2}-${OPENCODE_PORT_MAX}.`);
943
+ console.error(
944
+ `Error: No available ports found in range ${OPENCODE_PORT_START2}-${OPENCODE_PORT_MAX}.`
945
+ );
914
946
  console.error('Tip: Run "opentmux -reap" to clean up stuck sessions.');
915
- console.error(' Or enable "rotate_port": true in config to automatically recycle oldest sessions.');
947
+ console.error(
948
+ ' Or enable "rotate_port": true in config to automatically recycle oldest sessions.'
949
+ );
916
950
  log2("ERROR: No available ports");
917
951
  exit(1);
918
952
  }
@@ -928,7 +962,10 @@ async function main() {
928
962
  log2("Tmux available?", tmuxAvailable);
929
963
  if (inTmux || !tmuxAvailable) {
930
964
  log2("Running directly (in tmux or no tmux available)");
931
- const child = spawn(opencodeBin, childArgs, { stdio: "inherit", env: env2 });
965
+ const child = spawn(opencodeBin, childArgs, {
966
+ stdio: "inherit",
967
+ env: env2
968
+ });
932
969
  child.on("error", (err) => {
933
970
  log2("ERROR spawning child:", err.message);
934
971
  });
@@ -950,10 +987,7 @@ async function main() {
950
987
  });
951
988
  const shellCommand = `${escapedBin} ${escapedArgs.join(" ")} || { echo "Exit code: $?"; echo "Press Enter to close..."; read; }`;
952
989
  log2("Shell command for tmux:", shellCommand);
953
- const tmuxArgs = [
954
- "new-session",
955
- shellCommand
956
- ];
990
+ const tmuxArgs = ["new-session", shellCommand];
957
991
  log2("Tmux args:", JSON.stringify(tmuxArgs));
958
992
  const child = spawn("tmux", tmuxArgs, { stdio: "inherit", env: env2 });
959
993
  child.on("error", (err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opentmux",
3
- "version": "1.5.1",
3
+ "version": "1.5.4",
4
4
  "description": "OpenCode tmux integration: automatically opens subagent panes and renders real-time agent execution with smart layouts",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",