codeam-cli 2.4.13 → 2.4.14

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `codeam-cli` are documented here.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [2.4.13] — 2026-05-03
8
+
9
+ ### Fixed
10
+
11
+ - **cli:** Codeam pair survives SSH disconnect for codeam deploy (v2.4.13)
12
+
7
13
  ## [2.4.12] — 2026-05-03
8
14
 
9
15
  ### Fixed
package/dist/index.js CHANGED
@@ -179,7 +179,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
179
179
  // package.json
180
180
  var package_default = {
181
181
  name: "codeam-cli",
182
- version: "2.4.13",
182
+ version: "2.4.14",
183
183
  description: "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands \u2014 from anywhere.",
184
184
  main: "dist/index.js",
185
185
  bin: {
@@ -5894,24 +5894,33 @@ async function deploy() {
5894
5894
  const wrapper = [
5895
5895
  "mkdir -p ~/.codeam-deploy",
5896
5896
  "LOG=~/.codeam-deploy/session.log",
5897
- "PIDFILE=~/.codeam-deploy/session.pid",
5898
- 'if [ -f "$PIDFILE" ]; then OLD=$(cat "$PIDFILE" 2>/dev/null); if [ -n "$OLD" ] && kill -0 "$OLD" 2>/dev/null; then kill "$OLD" 2>/dev/null; sleep 1; fi; fi',
5899
5897
  ': > "$LOG"',
5900
- // Detach codeam pair from this shell so SSH hangup never reaches
5901
- // it. The combination is: setsid (new session, no controlling
5902
- // terminal) + nohup (ignore SIGHUP) + < /dev/null (no stdin
5903
- // attached) + redirect stdio to log file.
5904
- 'setsid nohup codeam pair > "$LOG" 2>&1 < /dev/null &',
5905
- "sleep 1",
5906
- 'PID=$(pgrep -fn "codeam pair" | head -1)',
5907
- 'echo "$PID" > "$PIDFILE"',
5908
- 'tail -n +1 -F "$LOG" 2>/dev/null &',
5898
+ // The default `gh codespace ssh` cwd is the repo root
5899
+ // (/workspaces/<repo>), which is exactly where Claude needs to
5900
+ // run so it can read/edit project files. Pass that to PM2 via
5901
+ // --cwd so the relay's child Claude inherits the right
5902
+ // working directory.
5903
+ 'PROJECT_DIR="$(pwd)"',
5904
+ // Install PM2 if it isn't already on PATH. Idempotent.
5905
+ "if ! command -v pm2 >/dev/null 2>&1; then",
5906
+ ' echo "Installing pm2 (one-time setup)\u2026"',
5907
+ ' npm install -g pm2 >/dev/null 2>&1 || { echo "\u2717 Failed to install pm2"; exit 1; }',
5908
+ "fi",
5909
+ // Stop any prior codeam-pair instance — fresh start each deploy.
5910
+ "pm2 delete codeam-pair >/dev/null 2>&1",
5911
+ // Start codeam pair under PM2. `--merge-logs` writes stdout
5912
+ // and stderr to the same file so we only need one tail.
5913
+ 'pm2 start codeam --name codeam-pair --cwd "$PROJECT_DIR" -o "$LOG" -e "$LOG" --merge-logs --time -- pair >/dev/null 2>&1',
5914
+ 'tail -n 0 -F "$LOG" 2>/dev/null &',
5909
5915
  "TAIL=$!",
5910
5916
  "trap 'kill $TAIL 2>/dev/null; exit 130' INT TERM",
5917
+ // Phase 1 — wait for "Paired with".
5911
5918
  "SUCCESS=0",
5912
5919
  "while true; do",
5913
5920
  ' if grep -q "Paired with" "$LOG" 2>/dev/null; then SUCCESS=1; break; fi',
5914
- ' if [ -z "$PID" ] || ! kill -0 "$PID" 2>/dev/null; then SUCCESS=0; break; fi',
5921
+ ` STATUS=$(pm2 jlist 2>/dev/null | grep -o '"name":"codeam-pair","[^}]*"status":"[^"]*"' | grep -o '"status":"[^"]*"' | head -1)`,
5922
+ ' if [ -z "$STATUS" ]; then SUCCESS=0; break; fi',
5923
+ ' if echo "$STATUS" | grep -q "stopped\\|errored"; then SUCCESS=0; break; fi',
5915
5924
  " sleep 1",
5916
5925
  "done",
5917
5926
  'if [ "$SUCCESS" = "1" ]; then',
@@ -5920,10 +5929,10 @@ async function deploy() {
5920
5929
  ' echo " Answer any first-time prompts ("trust this folder", etc.) on your phone."',
5921
5930
  ' echo " Local terminal will close once Claude is ready."',
5922
5931
  " echo",
5932
+ // Phase 2 — wait for the Claude "ready" marker.
5923
5933
  " WAIT_START=$(date +%s)",
5924
5934
  " while true; do",
5925
5935
  ' if grep -q "for shortcuts" "$LOG" 2>/dev/null; then break; fi',
5926
- ' if [ -z "$PID" ] || ! kill -0 "$PID" 2>/dev/null; then break; fi',
5927
5936
  " if [ $(($(date +%s) - WAIT_START)) -gt 180 ]; then break; fi",
5928
5937
  " sleep 1",
5929
5938
  " done",
@@ -5932,10 +5941,12 @@ async function deploy() {
5932
5941
  "kill $TAIL 2>/dev/null",
5933
5942
  "echo",
5934
5943
  'if [ "$SUCCESS" = "1" ]; then',
5935
- ' echo "\u2713 Session running on codespace (PID $PID). Closing local connection \u2014 your phone stays paired."',
5944
+ ' echo "\u2713 Session running via PM2 on the codespace. Closing local connection \u2014 your phone stays paired."',
5945
+ ' echo " To stop later: gh codespace ssh -- pm2 delete codeam-pair"',
5936
5946
  " exit 0",
5937
5947
  "else",
5938
- ' echo "\u2717 Pairing did not complete (codeam pair exited)."',
5948
+ ' echo "\u2717 Pairing did not complete (codeam pair did not start)."',
5949
+ " pm2 delete codeam-pair >/dev/null 2>&1",
5939
5950
  " exit 1",
5940
5951
  "fi"
5941
5952
  ].join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.4.13",
3
+ "version": "2.4.14",
4
4
  "description": "Remote control Claude Code (and other AI coding agents) from your mobile phone. Pair your device, send prompts, stream responses in real-time, and approve commands — from anywhere.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {