claude-code-remote-pilot 0.2.9 → 0.2.10
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/bin/claude-pilot.js +11 -4
- package/lib/Watcher.js +20 -3
- package/package.json +1 -1
package/bin/claude-pilot.js
CHANGED
|
@@ -111,14 +111,21 @@ function trunc(str, len) {
|
|
|
111
111
|
return str.length <= len ? str.padEnd(len) : str.slice(0, len - 1) + '…';
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
function uptime(startedAt) {
|
|
115
|
+
const s = Math.floor((Date.now() - new Date(startedAt)) / 1000);
|
|
116
|
+
if (s < 60) return `${s}s`;
|
|
117
|
+
if (s < 3600) return `${Math.floor(s / 60)}m`;
|
|
118
|
+
return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`;
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
function renderTable(sessions) {
|
|
115
|
-
const NW =
|
|
116
|
-
const bar = ' ' + '─'.repeat(NW + SW +
|
|
117
|
-
const header = ` ${'SESSION'.padEnd(NW)} ${'STATUS'.padEnd(SW)} DIRECTORY`;
|
|
122
|
+
const NW = 18, SW = 14, UW = 8;
|
|
123
|
+
const bar = ' ' + '─'.repeat(NW + SW + UW + 34);
|
|
124
|
+
const header = ` ${'SESSION'.padEnd(NW)} ${'STATUS'.padEnd(SW)} ${'UP'.padEnd(UW)} DIRECTORY`;
|
|
118
125
|
const rows = sessions.map(s => {
|
|
119
126
|
const { plain, colored } = formatStatus(s);
|
|
120
127
|
const pad = ' '.repeat(Math.max(0, SW - plain.length));
|
|
121
|
-
return ` ${trunc(s.name, NW)} ${colored}${pad} ${trunc(s.path,
|
|
128
|
+
return ` ${trunc(s.name, NW)} ${colored}${pad} ${uptime(s.startedAt).padEnd(UW)} ${trunc(s.path, 32)}`;
|
|
122
129
|
});
|
|
123
130
|
const footer = ` ${sessions.length} session${sessions.length !== 1 ? 's' : ''} ${new Date().toLocaleTimeString()} q to exit`;
|
|
124
131
|
return ['\n', ' Claude Code Remote Pilot', bar, header, bar, ...rows, bar, footer, ''].join('\n');
|
package/lib/Watcher.js
CHANGED
|
@@ -25,6 +25,12 @@ class Watcher {
|
|
|
25
25
|
this.lastResumeAt = 0;
|
|
26
26
|
this._timer = null;
|
|
27
27
|
this._busy = false;
|
|
28
|
+
this._prevOutputHash = '';
|
|
29
|
+
this._outputUnchangedCount = 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_stripAnsi(text) {
|
|
33
|
+
return text.replace(/\x1b\[[0-9;]*[mGKHFABCDJsuhl]/g, '').replace(/\x1b[()][AB012]/g, '');
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
start() {
|
|
@@ -73,12 +79,22 @@ class Watcher {
|
|
|
73
79
|
return;
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
const
|
|
82
|
+
const raw = this._capture();
|
|
83
|
+
const text = this._stripAnsi(raw);
|
|
77
84
|
const nonEmptyLines = text.split('\n').filter(l => l.trim());
|
|
78
85
|
const lastLine = nonEmptyLines[nonEmptyLines.length - 1] || '';
|
|
79
|
-
// Only check recent lines for transient UI elements
|
|
80
86
|
const recentLines = nonEmptyLines.slice(-5).join('\n');
|
|
81
87
|
|
|
88
|
+
// Track whether output is changing between checks
|
|
89
|
+
const outputHash = this._hash(recentLines);
|
|
90
|
+
if (outputHash === this._prevOutputHash) {
|
|
91
|
+
this._outputUnchangedCount++;
|
|
92
|
+
} else {
|
|
93
|
+
this._prevOutputHash = outputHash;
|
|
94
|
+
this._outputUnchangedCount = 0;
|
|
95
|
+
}
|
|
96
|
+
const outputIsStable = this._outputUnchangedCount >= 2;
|
|
97
|
+
|
|
82
98
|
if (LIMIT_RE.test(text)) {
|
|
83
99
|
await this._handleLimit(text);
|
|
84
100
|
} else if (RESPONSE_RE.test(recentLines)) {
|
|
@@ -92,7 +108,7 @@ class Watcher {
|
|
|
92
108
|
this.session.status = 'running';
|
|
93
109
|
this.session.resumeAt = null;
|
|
94
110
|
}
|
|
95
|
-
} else if (IDLE_RE.test(lastLine)) {
|
|
111
|
+
} else if (IDLE_RE.test(lastLine) || outputIsStable) {
|
|
96
112
|
if (this.session.status !== 'idle') {
|
|
97
113
|
this.session.status = 'idle';
|
|
98
114
|
this.session.resumeAt = null;
|
|
@@ -112,6 +128,7 @@ class Watcher {
|
|
|
112
128
|
if ((Date.now() / 1000) - this.lastResumeAt < this.cooldown) return;
|
|
113
129
|
|
|
114
130
|
this.lastHash = hash;
|
|
131
|
+
this._outputUnchangedCount = 0; // reset — we're intentionally waiting
|
|
115
132
|
const wait = this._parseWait(text);
|
|
116
133
|
this.session.status = 'limit';
|
|
117
134
|
this.session.resumeAt = Date.now() + wait * 1000;
|
package/package.json
CHANGED