codeam-cli 2.4.13 → 2.4.15
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 +6 -0
- package/dist/index.js +65 -16
- package/package.json +1 -1
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.
|
|
182
|
+
version: "2.4.15",
|
|
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,67 @@ 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
|
-
//
|
|
5901
|
-
//
|
|
5902
|
-
//
|
|
5903
|
-
//
|
|
5904
|
-
|
|
5905
|
-
"
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
'
|
|
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
|
+
// --max-restarts 3 keeps PM2 from looping forever if codeam pair
|
|
5914
|
+
// can't start (e.g. backend unreachable) — three attempts is
|
|
5915
|
+
// enough for transient flakes, anything more wastes time.
|
|
5916
|
+
'pm2 start codeam --name codeam-pair --cwd "$PROJECT_DIR" --max-restarts 3 -o "$LOG" -e "$LOG" --merge-logs --time -- pair >/dev/null 2>&1',
|
|
5917
|
+
// Give PM2 a moment to spawn the process before we start polling
|
|
5918
|
+
// status — otherwise the very first jlist can race the spawn.
|
|
5919
|
+
"sleep 2",
|
|
5920
|
+
'tail -n 0 -F "$LOG" 2>/dev/null &',
|
|
5909
5921
|
"TAIL=$!",
|
|
5910
5922
|
"trap 'kill $TAIL 2>/dev/null; exit 130' INT TERM",
|
|
5923
|
+
// Phase 1 — wait for "Paired with", or for codeam to print a
|
|
5924
|
+
// recognisable failure, or for PM2 to report the process gone.
|
|
5911
5925
|
"SUCCESS=0",
|
|
5926
|
+
'FAIL_REASON=""',
|
|
5912
5927
|
"while true; do",
|
|
5913
5928
|
' if grep -q "Paired with" "$LOG" 2>/dev/null; then SUCCESS=1; break; fi',
|
|
5914
|
-
|
|
5929
|
+
// Detect specific codeam error messages early so the user gets
|
|
5930
|
+
// an actionable message instead of a generic "did not start".
|
|
5931
|
+
' if grep -q "Could not reach the server" "$LOG" 2>/dev/null; then',
|
|
5932
|
+
' FAIL_REASON="codeam could not reach the CodeAgent backend (network/firewall? Vercel bot-challenge on the API?)"',
|
|
5933
|
+
" SUCCESS=0; break",
|
|
5934
|
+
" fi",
|
|
5935
|
+
' if grep -qE "Pairing timed out|Failed to" "$LOG" 2>/dev/null; then',
|
|
5936
|
+
' FAIL_REASON="$(grep -E "Pairing timed out|Failed to" "$LOG" | head -1)"',
|
|
5937
|
+
" SUCCESS=0; break",
|
|
5938
|
+
" fi",
|
|
5939
|
+
// Status check: parse PM2 jlist via Python (every codespace has
|
|
5940
|
+
// python3) for resilient JSON handling, instead of fragile grep.
|
|
5941
|
+
' ALIVE=$(pm2 jlist 2>/dev/null | python3 -c "import json,sys',
|
|
5942
|
+
"try:",
|
|
5943
|
+
" d=json.load(sys.stdin)",
|
|
5944
|
+
" it=[x for x in d if x.get('name')=='codeam-pair']",
|
|
5945
|
+
" print(it[0]['pm2_env']['status'] if it else 'missing')",
|
|
5946
|
+
"except Exception:",
|
|
5947
|
+
` print('parse-error')" 2>/dev/null)`,
|
|
5948
|
+
' case "$ALIVE" in',
|
|
5949
|
+
" online|launching) ;;",
|
|
5950
|
+
// still good
|
|
5951
|
+
' "")',
|
|
5952
|
+
' FAIL_REASON="PM2 not responding"',
|
|
5953
|
+
" SUCCESS=0; break ;;",
|
|
5954
|
+
" missing|stopped|errored|stopping)",
|
|
5955
|
+
' FAIL_REASON="PM2 reports codeam-pair is $ALIVE"',
|
|
5956
|
+
" SUCCESS=0; break ;;",
|
|
5957
|
+
" esac",
|
|
5915
5958
|
" sleep 1",
|
|
5916
5959
|
"done",
|
|
5917
5960
|
'if [ "$SUCCESS" = "1" ]; then',
|
|
@@ -5920,10 +5963,10 @@ async function deploy() {
|
|
|
5920
5963
|
' echo " Answer any first-time prompts ("trust this folder", etc.) on your phone."',
|
|
5921
5964
|
' echo " Local terminal will close once Claude is ready."',
|
|
5922
5965
|
" echo",
|
|
5966
|
+
// Phase 2 — wait for the Claude "ready" marker.
|
|
5923
5967
|
" WAIT_START=$(date +%s)",
|
|
5924
5968
|
" while true; do",
|
|
5925
5969
|
' 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
5970
|
" if [ $(($(date +%s) - WAIT_START)) -gt 180 ]; then break; fi",
|
|
5928
5971
|
" sleep 1",
|
|
5929
5972
|
" done",
|
|
@@ -5932,10 +5975,16 @@ async function deploy() {
|
|
|
5932
5975
|
"kill $TAIL 2>/dev/null",
|
|
5933
5976
|
"echo",
|
|
5934
5977
|
'if [ "$SUCCESS" = "1" ]; then',
|
|
5935
|
-
' echo "\u2713 Session running on codespace
|
|
5978
|
+
' echo "\u2713 Session running via PM2 on the codespace. Closing local connection \u2014 your phone stays paired."',
|
|
5979
|
+
' echo " To stop later: gh codespace ssh -- pm2 delete codeam-pair"',
|
|
5936
5980
|
" exit 0",
|
|
5937
5981
|
"else",
|
|
5938
|
-
' echo "\u2717 Pairing did not complete
|
|
5982
|
+
' echo "\u2717 Pairing did not complete."',
|
|
5983
|
+
' if [ -n "$FAIL_REASON" ]; then echo " Reason: $FAIL_REASON"; fi',
|
|
5984
|
+
" echo",
|
|
5985
|
+
' echo " Last log lines from codeam pair:"',
|
|
5986
|
+
' tail -n 8 "$LOG" 2>/dev/null | sed "s/^/ /"',
|
|
5987
|
+
" pm2 delete codeam-pair >/dev/null 2>&1",
|
|
5939
5988
|
" exit 1",
|
|
5940
5989
|
"fi"
|
|
5941
5990
|
].join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.15",
|
|
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": {
|