cli-setu 0.2.5 → 0.2.6

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/status.js +32 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cli-setu",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Bridge your terminal to your phone — run and approve Claude Code, Codex CLI and other AI coding agents from anywhere.",
5
5
  "type": "commonjs",
6
6
  "bin": {
package/src/status.js CHANGED
@@ -24,26 +24,49 @@ async function status(authServer) {
24
24
  console.log('[cli-setu] Not paired. Run `cli-setu pair` to get started.');
25
25
  return;
26
26
  }
27
- console.log(`[cli-setu] Paired as "${config.deviceName}".`);
28
27
 
29
- // Real gap found by testing with multiple real accounts across multiple
30
- // laptops: there was no way to confirm which Google account a laptop was
31
- // paired to without checking the phone app directly - the device token
32
- // itself carries no human-readable identity. Best-effort: a network
33
- // failure here shouldn't block the rest of `status` from reporting what
34
- // it already knows locally.
28
+ // Real bug found by testing: this used to print "Paired as X" straight
29
+ // from the local config file with no server check at all - unpairing
30
+ // from the PHONE deletes the device server-side, but the laptop's own
31
+ // config.json still has the old (now-dead) token, so `status` kept
32
+ // claiming the device was paired indefinitely, with nothing telling the
33
+ // user their session was actually dead until something else failed
34
+ // later. Same real distinction pair.js's own re-pair check already
35
+ // makes: a 401 means the server genuinely doesn't recognize this token
36
+ // anymore (deliberately re-pairable from here); a network error/
37
+ // unreachable server is a THIRD, distinct outcome, not treated as
38
+ // "unpaired" - it falls through to reporting local state as before,
39
+ // same as this check not existing, so a flaky-wifi run doesn't get
40
+ // told it's unpaired when it might just be offline.
41
+ let serverSaysUnpaired = false;
42
+ let userId = null;
35
43
  try {
36
44
  const whoamiRes = await fetch(`${authServer}/device/whoami`, {
37
45
  headers: { Authorization: `Bearer ${config.deviceToken}` },
38
46
  });
39
47
  if (whoamiRes.ok) {
40
- const { userId } = await whoamiRes.json();
41
- console.log(`[cli-setu] Paired to account: ${userId}`);
48
+ ({ userId } = await whoamiRes.json());
49
+ } else if (whoamiRes.status === 401) {
50
+ serverSaysUnpaired = true;
42
51
  }
43
52
  } catch {
44
53
  // Offline, or the server's unreachable - status still works from local state alone.
45
54
  }
46
55
 
56
+ if (serverSaysUnpaired) {
57
+ // Deliberately NOT returning here - a `cli-setu` process can still be
58
+ // genuinely running (pointlessly retrying against this now-dead
59
+ // token, see supervisor.js's own 401 handling), and the user should
60
+ // still be told that so they know to `cli-setu stop` it rather than
61
+ // it silently retrying in the background forever.
62
+ console.log(`[cli-setu] "${config.deviceName}" was unpaired from the app. Run \`cli-setu pair\` to reconnect.`);
63
+ } else {
64
+ console.log(`[cli-setu] Paired as "${config.deviceName}".`);
65
+ if (userId) {
66
+ console.log(`[cli-setu] Paired to account: ${userId}`);
67
+ }
68
+ }
69
+
47
70
  let files;
48
71
  try {
49
72
  files = fs.readdirSync(CONFIG_DIR).filter((f) => f.startsWith('session.') && f.endsWith('.pid'));