cli-setu 0.2.7 → 0.2.9
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/README.md +3 -3
- package/bin/setu.js +1 -1
- package/package.json +1 -1
- package/src/pair.js +15 -1
- package/src/supervisor.js +20 -9
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# cli-setu
|
|
2
2
|
|
|
3
|
-
Bridge your terminal to your phone. Run Claude Code, Codex, or any plain shell on your laptop, and approve prompts, type, and watch the live output from the [
|
|
3
|
+
Bridge your terminal to your phone. Run Claude Code, Codex, or any plain shell on your laptop, and approve prompts, type, and watch the live output from the [cli-setu](https://clisetu.com) app on your phone.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ cli-setu --cli claude # same, but runs Claude Code inside the bridged session
|
|
|
16
16
|
cli-setu --cli codex # or Codex
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
The first time you run it, `cli-setu` prints a QR code (and an 8-digit fallback code) - scan it with the
|
|
19
|
+
The first time you run it, `cli-setu` prints a QR code (and an 8-digit fallback code) - scan it with the cli-setu app to pair this computer and start watching the session live.
|
|
20
20
|
|
|
21
21
|
Once paired, running `cli-setu` in any folder just works - no QR code needed again, unless this is a device you haven't paired before.
|
|
22
22
|
|
|
@@ -33,7 +33,7 @@ cli-setu --help # show all commands
|
|
|
33
33
|
|
|
34
34
|
## How it works
|
|
35
35
|
|
|
36
|
-
`cli-setu` spawns your real terminal (or Claude Code/Codex) inside a PTY, same as any terminal emulator. Every byte it produces streams live to the
|
|
36
|
+
`cli-setu` spawns your real terminal (or Claude Code/Codex) inside a PTY, same as any terminal emulator. Every byte it produces streams live to the cli-setu app over a secure relay; anything you type on the phone writes back into that same PTY, exactly like a local keystroke. Permission prompts (file edits, shell commands, etc.) are detected and relayed as structured approve/reject cards instead of raw text, when the adapter for your CLI supports it.
|
|
37
37
|
|
|
38
38
|
## License
|
|
39
39
|
|
package/bin/setu.js
CHANGED
|
@@ -91,7 +91,7 @@ async function main() {
|
|
|
91
91
|
const config = readConfig();
|
|
92
92
|
if (!config || !config.deviceToken) {
|
|
93
93
|
const { pair } = require('../src/pair');
|
|
94
|
-
await pair(AUTH_SERVER, AUTH_SERVER_PUBLIC);
|
|
94
|
+
await pair(AUTH_SERVER, AUTH_SERVER_PUBLIC, { standalone: false });
|
|
95
95
|
}
|
|
96
96
|
require('../src/supervisor');
|
|
97
97
|
}
|
package/package.json
CHANGED
package/src/pair.js
CHANGED
|
@@ -8,7 +8,7 @@ const qrcode = require('qrcode-terminal');
|
|
|
8
8
|
const { loadOrCreateConfig, writeConfig, hasKeypair } = require('./config');
|
|
9
9
|
const { generateKeypair, publicKeyToBase64, privateKeyToBase64 } = require('./crypto');
|
|
10
10
|
|
|
11
|
-
async function pair(authServer, authServerPublic) {
|
|
11
|
+
async function pair(authServer, authServerPublic, { standalone = true } = {}) {
|
|
12
12
|
const config = loadOrCreateConfig();
|
|
13
13
|
|
|
14
14
|
// Section 1 E2E: generate this device's own keypair up front, before
|
|
@@ -125,6 +125,20 @@ async function pair(authServer, authServerPublic) {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
// Real gap found by testing (PM report): a first-time user had no clear
|
|
129
|
+
// next step after pairing succeeded - pairing a device and starting a
|
|
130
|
+
// real terminal session are deliberately separate commands (one laptop
|
|
131
|
+
// can run several sessions, switch CLIs across restarts, etc.), but
|
|
132
|
+
// nothing here ever told a first-time user that distinction, or what
|
|
133
|
+
// to actually type next. Only shown for an explicit, standalone
|
|
134
|
+
// `cli-setu pair` - bin/setu.js's own bare-`cli-setu` flow calls this
|
|
135
|
+
// function too (auto-pairing an unpaired machine before immediately
|
|
136
|
+
// starting a session right after), where this message would be
|
|
137
|
+
// immediately followed by the session actually starting anyway.
|
|
138
|
+
if (standalone) {
|
|
139
|
+
console.log('[cli-setu] Run `cli-setu` in a project folder to start your first session.');
|
|
140
|
+
}
|
|
141
|
+
|
|
128
142
|
return config;
|
|
129
143
|
}
|
|
130
144
|
|
package/src/supervisor.js
CHANGED
|
@@ -275,6 +275,12 @@ async function connectToAzure() {
|
|
|
275
275
|
}
|
|
276
276
|
const conn = await res.json();
|
|
277
277
|
deviceId = conn.deviceId;
|
|
278
|
+
// See this function's own call site (main()'s former focusTimer
|
|
279
|
+
// comment) for why this starts HERE and not unconditionally at
|
|
280
|
+
// startup - deviceId must be real before pollFocus's heartbeat is
|
|
281
|
+
// worth sending at all. Guarded so a reconnect (connectToAzure called
|
|
282
|
+
// again after a dropped WebSocket) never stacks a second timer.
|
|
283
|
+
if (!focusTimer) focusTimer = setInterval(pollFocus, 2000);
|
|
278
284
|
log(`[supervisor] Connecting to Azure as device:${deviceId} (owner: ${conn.userId})...`);
|
|
279
285
|
// Diagnostic found by testing: a session not appearing in the phone's
|
|
280
286
|
// Terminal tab had no visible cause from the laptop's own side - this
|
|
@@ -1296,15 +1302,20 @@ async function main() {
|
|
|
1296
1302
|
// ptyProcess.onExit's cleanup still has a valid, harmless no-op target.
|
|
1297
1303
|
|
|
1298
1304
|
pollTimer = setInterval(pollForRequests, POLL_INTERVAL_MS);
|
|
1299
|
-
// Real
|
|
1300
|
-
//
|
|
1301
|
-
// (
|
|
1302
|
-
//
|
|
1303
|
-
//
|
|
1304
|
-
//
|
|
1305
|
-
//
|
|
1306
|
-
//
|
|
1307
|
-
|
|
1305
|
+
// Real bug found by testing (PM report: "device shows offline after
|
|
1306
|
+
// connecting"): focusTimer used to start HERE, unconditionally, before
|
|
1307
|
+
// connectToAzure() (called at the bottom of this function, unawaited)
|
|
1308
|
+
// had any chance to resolve its /device/connect call and set the real
|
|
1309
|
+
// deviceId below. pollFocus's own deviceId-aware URL building silently
|
|
1310
|
+
// omits the heartbeat whenever deviceId is still null - harmless for a
|
|
1311
|
+
// couple of ticks on a normal fast connect, but genuinely persistent
|
|
1312
|
+
// (heartbeat omitted for the ENTIRE outage) whenever /device/connect is
|
|
1313
|
+
// stuck in its own 3s retry loop (network hiccup, backend restart) -
|
|
1314
|
+
// every tick silently did nothing, with no visible error, for as long
|
|
1315
|
+
// as that retry loop ran. Moved to start right where deviceId itself
|
|
1316
|
+
// gets set, inside connectToAzure() (see its own comment there) -
|
|
1317
|
+
// "Offline" on the phone now correctly means "genuinely not
|
|
1318
|
+
// connected," never "connected, but the heartbeat hasn't started yet."
|
|
1308
1319
|
// CLI-agnostic - runs for every adapter (Claude Code, Codex, generic),
|
|
1309
1320
|
// since battery is a property of the LAPTOP, not of whatever CLI it
|
|
1310
1321
|
// happens to be running.
|