codeam-cli 1.4.42 → 1.4.44
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/dist/index.js +53 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -116,7 +116,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
116
116
|
// package.json
|
|
117
117
|
var package_default = {
|
|
118
118
|
name: "codeam-cli",
|
|
119
|
-
version: "1.4.
|
|
119
|
+
version: "1.4.44",
|
|
120
120
|
description: "Remote control Claude Code from your mobile device",
|
|
121
121
|
main: "dist/index.js",
|
|
122
122
|
bin: {
|
|
@@ -1143,12 +1143,13 @@ function filterChrome(lines) {
|
|
|
1143
1143
|
return result;
|
|
1144
1144
|
}
|
|
1145
1145
|
var OutputService = class _OutputService {
|
|
1146
|
-
constructor(sessionId, pluginId, onSessionIdDetected, onRateLimitDetected, onTurnComplete) {
|
|
1146
|
+
constructor(sessionId, pluginId, onSessionIdDetected, onRateLimitDetected, onTurnComplete, onTerminalTurnDetected) {
|
|
1147
1147
|
this.sessionId = sessionId;
|
|
1148
1148
|
this.pluginId = pluginId;
|
|
1149
1149
|
this.onSessionIdDetected = onSessionIdDetected;
|
|
1150
1150
|
this.onRateLimitDetected = onRateLimitDetected;
|
|
1151
1151
|
this.onTurnComplete = onTurnComplete;
|
|
1152
|
+
this.onTerminalTurnDetected = onTerminalTurnDetected;
|
|
1152
1153
|
}
|
|
1153
1154
|
sessionId;
|
|
1154
1155
|
pluginId;
|
|
@@ -1157,10 +1158,12 @@ var OutputService = class _OutputService {
|
|
|
1157
1158
|
pollTimer = null;
|
|
1158
1159
|
startTime = 0;
|
|
1159
1160
|
active = false;
|
|
1161
|
+
terminalTurnPending = false;
|
|
1160
1162
|
lastPushTime = 0;
|
|
1161
1163
|
onSessionIdDetected;
|
|
1162
1164
|
onRateLimitDetected;
|
|
1163
1165
|
onTurnComplete;
|
|
1166
|
+
onTerminalTurnDetected;
|
|
1164
1167
|
static POLL_MS = 1e3;
|
|
1165
1168
|
static IDLE_MS = 3e3;
|
|
1166
1169
|
/** Shorter idle threshold for selector detection (UI is ready immediately). */
|
|
@@ -1175,12 +1178,34 @@ var OutputService = class _OutputService {
|
|
|
1175
1178
|
/** Max idle with no visible content (spinner only) before finalizing. */
|
|
1176
1179
|
static EMPTY_TIMEOUT_MS = 6e4;
|
|
1177
1180
|
static MAX_MS = 12e4;
|
|
1181
|
+
/**
|
|
1182
|
+
* Called by the terminal-turn callback once the user message is known.
|
|
1183
|
+
* Sequences: clear → user_message (if any) → new_turn → start timer.
|
|
1184
|
+
* This guarantees the user message appears before the typing placeholder
|
|
1185
|
+
* in the apps, with no race against the clear event.
|
|
1186
|
+
*/
|
|
1187
|
+
async startTerminalTurn(userText) {
|
|
1188
|
+
this.terminalTurnPending = false;
|
|
1189
|
+
this.stopPoll();
|
|
1190
|
+
this.rawBuffer = "";
|
|
1191
|
+
this.lastSentContent = "";
|
|
1192
|
+
this.lastPushTime = 0;
|
|
1193
|
+
this.active = true;
|
|
1194
|
+
this.startTime = Date.now();
|
|
1195
|
+
await this.postChunk({ clear: true });
|
|
1196
|
+
if (userText) {
|
|
1197
|
+
await this.postChunk({ type: "user_message", content: userText, done: true });
|
|
1198
|
+
}
|
|
1199
|
+
await this.postChunk({ type: "new_turn", content: "", done: false });
|
|
1200
|
+
this.pollTimer = setInterval(() => this.tick(), _OutputService.POLL_MS);
|
|
1201
|
+
}
|
|
1178
1202
|
newTurn() {
|
|
1179
1203
|
this.stopPoll();
|
|
1180
1204
|
this.rawBuffer = "";
|
|
1181
1205
|
this.lastSentContent = "";
|
|
1182
1206
|
this.lastPushTime = 0;
|
|
1183
1207
|
this.active = true;
|
|
1208
|
+
this.terminalTurnPending = false;
|
|
1184
1209
|
this.startTime = Date.now();
|
|
1185
1210
|
this.postChunk({ clear: true }).then(() => this.postChunk({ type: "new_turn", content: "", done: false })).catch(() => {
|
|
1186
1211
|
});
|
|
@@ -1203,7 +1228,16 @@ var OutputService = class _OutputService {
|
|
|
1203
1228
|
this.pollTimer = setInterval(() => this.tick(), _OutputService.POLL_MS);
|
|
1204
1229
|
}
|
|
1205
1230
|
push(raw) {
|
|
1206
|
-
if (!this.active)
|
|
1231
|
+
if (!this.active) {
|
|
1232
|
+
if (!this.terminalTurnPending) {
|
|
1233
|
+
const printable2 = raw.replace(/\x1B\[[^@-~]*[@-~]/g, "").replace(/[\x00-\x1F\x7F]/g, "");
|
|
1234
|
+
if (printable2.trim()) {
|
|
1235
|
+
this.terminalTurnPending = true;
|
|
1236
|
+
this.onTerminalTurnDetected?.();
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1207
1241
|
this.rawBuffer += raw;
|
|
1208
1242
|
const printable = raw.replace(/\x1B\[[^@-~]*[@-~]/g, "").replace(/[\x00-\x1F\x7F]/g, "");
|
|
1209
1243
|
if (printable.trim()) {
|
|
@@ -1493,6 +1527,16 @@ var HistoryService = class {
|
|
|
1493
1527
|
getCurrentConversationId() {
|
|
1494
1528
|
return this.currentConversationId;
|
|
1495
1529
|
}
|
|
1530
|
+
/** Return the text of the last user message in the current conversation, or null. */
|
|
1531
|
+
getLastUserMessage() {
|
|
1532
|
+
if (!this.currentConversationId) return null;
|
|
1533
|
+
const filePath = path4.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
1534
|
+
const messages = parseJsonl(filePath);
|
|
1535
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1536
|
+
if (messages[i].role === "user") return messages[i].text;
|
|
1537
|
+
}
|
|
1538
|
+
return null;
|
|
1539
|
+
}
|
|
1496
1540
|
/** Detect the active conversation by finding the most recently modified JSONL file */
|
|
1497
1541
|
detectCurrentConversation() {
|
|
1498
1542
|
const dir = this.projectDir;
|
|
@@ -1853,6 +1897,12 @@ except Exception:sys.exit(0)
|
|
|
1853
1897
|
if (historySvc.isQuotaStale()) {
|
|
1854
1898
|
fetchQuotaUsage();
|
|
1855
1899
|
}
|
|
1900
|
+
}, () => {
|
|
1901
|
+
setTimeout(() => {
|
|
1902
|
+
const userText = historySvc.getLastUserMessage() ?? void 0;
|
|
1903
|
+
outputSvc.startTerminalTurn(userText).catch(() => {
|
|
1904
|
+
});
|
|
1905
|
+
}, 300);
|
|
1856
1906
|
});
|
|
1857
1907
|
function sendPrompt(prompt) {
|
|
1858
1908
|
outputSvc.newTurn();
|