codeam-cli 1.0.9 → 1.1.0
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 +64 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -110,7 +110,7 @@ var import_picocolors = __toESM(require("picocolors"));
|
|
|
110
110
|
// package.json
|
|
111
111
|
var package_default = {
|
|
112
112
|
name: "codeam-cli",
|
|
113
|
-
version: "1.0
|
|
113
|
+
version: "1.1.0",
|
|
114
114
|
description: "Remote control Claude Code from your mobile device",
|
|
115
115
|
main: "dist/index.js",
|
|
116
116
|
bin: {
|
|
@@ -745,68 +745,87 @@ var OutputService = class _OutputService {
|
|
|
745
745
|
}
|
|
746
746
|
sessionId;
|
|
747
747
|
pluginId;
|
|
748
|
+
// Buffer that accumulates PTY text (ANSI stripped, growing during response)
|
|
748
749
|
buffer = "";
|
|
749
|
-
|
|
750
|
-
|
|
750
|
+
lastSentBuffer = "";
|
|
751
|
+
stableCount = 0;
|
|
752
|
+
pollTimer = null;
|
|
753
|
+
startTime = 0;
|
|
751
754
|
active = false;
|
|
752
|
-
|
|
753
|
-
static
|
|
755
|
+
// After this many stable polls (POLL_MS each) with content, mark done
|
|
756
|
+
static POLL_MS = 1e3;
|
|
757
|
+
static STABLE_THRESHOLD = 3;
|
|
758
|
+
// Give up after 2 minutes (absolute) or 30 seconds with no content at all
|
|
759
|
+
static MAX_MS = 12e4;
|
|
760
|
+
static EMPTY_TIMEOUT_MS = 3e4;
|
|
754
761
|
/**
|
|
755
762
|
* Call before sending a command from mobile.
|
|
756
|
-
* Clears previous output
|
|
757
|
-
* shows the typing indicator.
|
|
763
|
+
* Clears previous output, sends new_turn event, starts polling.
|
|
758
764
|
*/
|
|
759
|
-
|
|
760
|
-
this.
|
|
765
|
+
newTurn() {
|
|
766
|
+
this.stopPoll();
|
|
761
767
|
this.buffer = "";
|
|
768
|
+
this.lastSentBuffer = "";
|
|
769
|
+
this.stableCount = 0;
|
|
762
770
|
this.active = true;
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
771
|
+
this.startTime = Date.now();
|
|
772
|
+
this.postChunk({ clear: true }).then(() => this.postChunk({ type: "new_turn", content: "", done: false })).catch(() => {
|
|
773
|
+
});
|
|
774
|
+
this.pollTimer = setInterval(() => this.checkStability(), _OutputService.POLL_MS);
|
|
766
775
|
}
|
|
767
776
|
/** Feed raw terminal output from Claude (called on every stdout chunk). */
|
|
768
777
|
push(raw) {
|
|
769
778
|
if (!this.active) return;
|
|
770
779
|
const text = stripAnsi(raw).replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n");
|
|
771
|
-
if (
|
|
772
|
-
this.buffer += text;
|
|
773
|
-
this.resetDoneDebounce();
|
|
780
|
+
if (text) this.buffer += text;
|
|
774
781
|
}
|
|
775
782
|
dispose() {
|
|
776
|
-
this.
|
|
783
|
+
this.stopPoll();
|
|
777
784
|
this.active = false;
|
|
778
785
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
786
|
+
/**
|
|
787
|
+
* Stability check — runs every POLL_MS while active.
|
|
788
|
+
*
|
|
789
|
+
* Only finalises when we have content that has stopped changing.
|
|
790
|
+
* This avoids premature done signals while Claude is still thinking
|
|
791
|
+
* (which would set active=false and silently drop the real response).
|
|
792
|
+
*/
|
|
793
|
+
checkStability() {
|
|
794
|
+
if (!this.active) return;
|
|
795
|
+
if (Date.now() - this.startTime > _OutputService.MAX_MS) {
|
|
796
|
+
this.finalize();
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
const current = this.buffer;
|
|
800
|
+
if (!current.trim()) {
|
|
801
|
+
if (Date.now() - this.startTime > _OutputService.EMPTY_TIMEOUT_MS) {
|
|
802
|
+
this.finalize();
|
|
785
803
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
this.stopTimers();
|
|
793
|
-
const text = this.buffer;
|
|
794
|
-
this.buffer = "";
|
|
795
|
-
this.active = false;
|
|
796
|
-
if (text.trim()) {
|
|
797
|
-
this.postChunk({ type: "text", content: text, done: true }).catch(() => {
|
|
798
|
-
});
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
if (current === this.lastSentBuffer) {
|
|
807
|
+
this.stableCount++;
|
|
808
|
+
if (this.stableCount >= _OutputService.STABLE_THRESHOLD) {
|
|
809
|
+
this.finalize();
|
|
799
810
|
}
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
this.flushTimer = null;
|
|
811
|
+
} else {
|
|
812
|
+
this.stableCount = 0;
|
|
813
|
+
this.lastSentBuffer = current;
|
|
814
|
+
this.postChunk({ type: "text", content: current, done: false }).catch(() => {
|
|
815
|
+
});
|
|
806
816
|
}
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
817
|
+
}
|
|
818
|
+
finalize() {
|
|
819
|
+
const text = this.buffer;
|
|
820
|
+
this.stopPoll();
|
|
821
|
+
this.active = false;
|
|
822
|
+
this.postChunk({ type: "text", content: text, done: true }).catch(() => {
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
stopPoll() {
|
|
826
|
+
if (this.pollTimer) {
|
|
827
|
+
clearInterval(this.pollTimer);
|
|
828
|
+
this.pollTimer = null;
|
|
810
829
|
}
|
|
811
830
|
}
|
|
812
831
|
postChunk(body) {
|
|
@@ -862,8 +881,7 @@ async function start() {
|
|
|
862
881
|
const ws = new WebSocketService(session.id, pluginId);
|
|
863
882
|
const outputSvc = new OutputService(session.id, pluginId);
|
|
864
883
|
function sendPrompt(prompt) {
|
|
865
|
-
outputSvc.newTurn()
|
|
866
|
-
});
|
|
884
|
+
outputSvc.newTurn();
|
|
867
885
|
claude.sendCommand(prompt);
|
|
868
886
|
}
|
|
869
887
|
const relay = new CommandRelayService(pluginId, (cmd) => {
|