codeam-cli 2.4.9 → 2.4.11

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,18 @@ 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.9] — 2026-05-03
8
+
9
+ ### Added
10
+
11
+ - **cli:** Ask before bridging local Claude credentials (v2.4.9)
12
+
13
+ ## [2.4.8] — 2026-05-03
14
+
15
+ ### Fixed
16
+
17
+ - **cli:** Never let Claude show first-launch login on a codeam deploy (v2.4.8)
18
+
7
19
  ## [2.4.7] — 2026-05-03
8
20
 
9
21
  ### 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.9",
182
+ version: "2.4.11",
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: {
@@ -5838,6 +5838,22 @@ async function deploy() {
5838
5838
  void err;
5839
5839
  }
5840
5840
  }
5841
+ if (bridged !== "none") {
5842
+ const localClaudeJson = path9.join(os6.homedir(), ".claude.json");
5843
+ if (fs8.existsSync(localClaudeJson)) {
5844
+ try {
5845
+ const contents = fs8.readFileSync(localClaudeJson);
5846
+ await provider.uploadFile(
5847
+ workspace.id,
5848
+ "/home/codespace/.claude.json",
5849
+ contents,
5850
+ { mode: 384 }
5851
+ );
5852
+ } catch (err) {
5853
+ void err;
5854
+ }
5855
+ }
5856
+ }
5841
5857
  const verifyStep = fe();
5842
5858
  verifyStep.start("Verifying Claude auth on workspace\u2026");
5843
5859
  const verified = await verifyClaudeAuth(provider, workspace.id);
@@ -5869,17 +5885,60 @@ async function deploy() {
5869
5885
  workspace.webUrl ? `Web: ${import_picocolors8.default.cyan(workspace.webUrl)}` : "",
5870
5886
  "",
5871
5887
  "Starting `codeam pair` on the workspace.",
5872
- "Scan the QR code below with the CodeAgent Mobile app to finish pairing."
5888
+ "Scan the QR code below with the CodeAgent Mobile app to finish pairing.",
5889
+ import_picocolors8.default.dim("(Once paired, this terminal disconnects automatically; the session stays alive on the codespace.)")
5873
5890
  ].filter(Boolean).join("\n"),
5874
5891
  "Almost there"
5875
5892
  );
5876
- const code = (await provider.streamCommand(workspace.id, "codeam pair")).code;
5893
+ const wrapperLines = [
5894
+ "mkdir -p ~/.codeam-deploy",
5895
+ "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
+ ': > "$LOG"',
5900
+ // Detach codeam pair from this shell so SSH hangup and Ctrl+C
5901
+ // can never reach it.
5902
+ 'nohup codeam pair > "$LOG" 2>&1 < /dev/null &',
5903
+ "PID=$!",
5904
+ "disown",
5905
+ 'echo "$PID" > "$PIDFILE"',
5906
+ // Stream the log to the local terminal.
5907
+ 'tail -n +1 -F "$LOG" 2>/dev/null &',
5908
+ "TAIL=$!",
5909
+ // Local Ctrl+C: kill ONLY the tail and exit — relay stays alive.
5910
+ "trap 'kill $TAIL 2>/dev/null; exit 130' INT TERM",
5911
+ // Wait for the paired-marker, or codeam dying / timing out.
5912
+ "SUCCESS=0",
5913
+ "while true; do",
5914
+ ' if grep -q "Paired with" "$LOG" 2>/dev/null; then sleep 1; SUCCESS=1; break; fi',
5915
+ ' if ! kill -0 "$PID" 2>/dev/null; then SUCCESS=0; break; fi',
5916
+ " sleep 1",
5917
+ "done",
5918
+ "trap - INT TERM",
5919
+ "kill $TAIL 2>/dev/null",
5920
+ "echo",
5921
+ 'if [ "$SUCCESS" = "1" ]; then',
5922
+ ' echo "\u2713 Session running on codespace (PID $PID). Closing local connection \u2014 your phone stays paired."',
5923
+ " exit 0",
5924
+ "else",
5925
+ ' echo "\u2717 Pairing did not complete (codeam pair exited)."',
5926
+ " exit 1",
5927
+ "fi"
5928
+ ];
5929
+ const wrapper = wrapperLines.join("\n");
5930
+ const code = (await provider.streamCommand(workspace.id, `bash -lc ${shellQuoteSingle(wrapper)}`)).code;
5877
5931
  if (code === 0) {
5878
- gt(import_picocolors8.default.green(`\u2713 Workspace deployed and paired. Drive from your phone, anywhere.`));
5932
+ gt(import_picocolors8.default.green("\u2713 Workspace deployed and paired. Drive from your phone, anywhere."));
5933
+ } else if (code === 130) {
5934
+ gt(import_picocolors8.default.yellow("Disconnected from local terminal. Mobile session keeps running on the codespace."));
5879
5935
  } else {
5880
- gt(import_picocolors8.default.yellow(`Pairing exited with code ${code}. Run "codeam pair" inside the codespace if needed.`));
5936
+ gt(import_picocolors8.default.yellow(`Pairing did not complete. Run "codeam pair" inside the codespace if needed.`));
5881
5937
  }
5882
5938
  }
5939
+ function shellQuoteSingle(s) {
5940
+ return `'${s.replace(/'/g, `'\\''`)}'`;
5941
+ }
5883
5942
  async function runRemoteClaudeLogin(provider, workspaceId) {
5884
5943
  wt(
5885
5944
  [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeam-cli",
3
- "version": "2.4.9",
3
+ "version": "2.4.11",
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": {