codeam-cli 2.4.12 → 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 +18 -0
- package/dist/index.js +33 -30
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ 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
|
+
|
|
13
|
+
## [2.4.12] — 2026-05-03
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Wait for Claude to be ready before closing local terminal (v2.4.12)
|
|
18
|
+
|
|
19
|
+
## [2.4.11] — 2026-05-03
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **cli:** Codeam deploy detaches local terminal after pairing (v2.4.11)
|
|
24
|
+
|
|
7
25
|
## [2.4.10] — 2026-05-03
|
|
8
26
|
|
|
9
27
|
### 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.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: {
|
|
@@ -706,6 +706,7 @@ def onwinch(n,f):
|
|
|
706
706
|
except Exception:pass
|
|
707
707
|
signal.signal(signal.SIGCHLD,onchld)
|
|
708
708
|
signal.signal(signal.SIGWINCH,onwinch)
|
|
709
|
+
signal.signal(signal.SIGHUP,signal.SIG_IGN)
|
|
709
710
|
i=sys.stdin.fileno()
|
|
710
711
|
o=sys.stdout.fileno()
|
|
711
712
|
while not done[0]:
|
|
@@ -5890,47 +5891,48 @@ async function deploy() {
|
|
|
5890
5891
|
].filter(Boolean).join("\n"),
|
|
5891
5892
|
"Almost there"
|
|
5892
5893
|
);
|
|
5893
|
-
const
|
|
5894
|
+
const wrapper = [
|
|
5894
5895
|
"mkdir -p ~/.codeam-deploy",
|
|
5895
5896
|
"LOG=~/.codeam-deploy/session.log",
|
|
5896
|
-
"PIDFILE=~/.codeam-deploy/session.pid",
|
|
5897
|
-
// Stop any prior detached session for this codespace.
|
|
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
|
-
|
|
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 &',
|
|
5908
5915
|
"TAIL=$!",
|
|
5909
|
-
// Local Ctrl+C: kill ONLY the tail and exit — relay stays alive.
|
|
5910
5916
|
"trap 'kill $TAIL 2>/dev/null; exit 130' INT TERM",
|
|
5911
|
-
// Phase 1 — wait for
|
|
5917
|
+
// Phase 1 — wait for "Paired with".
|
|
5912
5918
|
"SUCCESS=0",
|
|
5913
5919
|
"while true; do",
|
|
5914
5920
|
' if grep -q "Paired with" "$LOG" 2>/dev/null; then SUCCESS=1; break; fi',
|
|
5915
|
-
|
|
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',
|
|
5916
5924
|
" sleep 1",
|
|
5917
5925
|
"done",
|
|
5918
5926
|
'if [ "$SUCCESS" = "1" ]; then',
|
|
5919
5927
|
" echo",
|
|
5920
5928
|
' echo "\u2713 Phone paired."',
|
|
5921
|
-
' echo "
|
|
5922
|
-
' echo "
|
|
5929
|
+
' echo " Answer any first-time prompts ("trust this folder", etc.) on your phone."',
|
|
5930
|
+
' echo " Local terminal will close once Claude is ready."',
|
|
5923
5931
|
" echo",
|
|
5924
|
-
// Phase 2 — wait
|
|
5925
|
-
// "? for shortcuts" line (from Claude\'s status bar) is the most
|
|
5926
|
-
// reliable "ready" marker — it only renders AFTER any trust /
|
|
5927
|
-
// onboarding prompts have been resolved. Cap at 3 minutes so we
|
|
5928
|
-
// never hang the local terminal forever if the user doesn\'t
|
|
5929
|
-
// resolve a prompt on their phone.
|
|
5932
|
+
// Phase 2 — wait for the Claude "ready" marker.
|
|
5930
5933
|
" WAIT_START=$(date +%s)",
|
|
5931
5934
|
" while true; do",
|
|
5932
5935
|
' if grep -q "for shortcuts" "$LOG" 2>/dev/null; then break; fi',
|
|
5933
|
-
' if ! kill -0 "$PID" 2>/dev/null; then break; fi',
|
|
5934
5936
|
" if [ $(($(date +%s) - WAIT_START)) -gt 180 ]; then break; fi",
|
|
5935
5937
|
" sleep 1",
|
|
5936
5938
|
" done",
|
|
@@ -5939,21 +5941,22 @@ async function deploy() {
|
|
|
5939
5941
|
"kill $TAIL 2>/dev/null",
|
|
5940
5942
|
"echo",
|
|
5941
5943
|
'if [ "$SUCCESS" = "1" ]; then',
|
|
5942
|
-
' echo "\u2713 Session running on codespace
|
|
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"',
|
|
5943
5946
|
" exit 0",
|
|
5944
5947
|
"else",
|
|
5945
|
-
' echo "\u2717 Pairing did not complete (codeam pair
|
|
5948
|
+
' echo "\u2717 Pairing did not complete (codeam pair did not start)."',
|
|
5949
|
+
" pm2 delete codeam-pair >/dev/null 2>&1",
|
|
5946
5950
|
" exit 1",
|
|
5947
5951
|
"fi"
|
|
5948
|
-
];
|
|
5949
|
-
const wrapper = wrapperLines.join("\n");
|
|
5952
|
+
].join("\n");
|
|
5950
5953
|
const code = (await provider.streamCommand(workspace.id, `bash -lc ${shellQuoteSingle(wrapper)}`)).code;
|
|
5951
5954
|
if (code === 0) {
|
|
5952
5955
|
gt(import_picocolors8.default.green("\u2713 Workspace deployed and paired. Drive from your phone, anywhere."));
|
|
5953
5956
|
} else if (code === 130) {
|
|
5954
5957
|
gt(import_picocolors8.default.yellow("Disconnected from local terminal. Mobile session keeps running on the codespace."));
|
|
5955
5958
|
} else {
|
|
5956
|
-
gt(import_picocolors8.default.yellow(
|
|
5959
|
+
gt(import_picocolors8.default.yellow('Pairing did not complete. Run "codeam pair" inside the codespace if needed.'));
|
|
5957
5960
|
}
|
|
5958
5961
|
}
|
|
5959
5962
|
function shellQuoteSingle(s) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.4.
|
|
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": {
|