@sma1lboy/kobe 0.7.23 → 0.7.24
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/cli/index.js +1 -1
- package/dist/web-ui/pty-scrollback.mjs +51 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -90,7 +90,7 @@ var init_package = __esm(() => {
|
|
|
90
90
|
package_default = {
|
|
91
91
|
$schema: "https://json.schemastore.org/package.json",
|
|
92
92
|
name: "@sma1lboy/kobe",
|
|
93
|
-
version: "0.7.
|
|
93
|
+
version: "0.7.24",
|
|
94
94
|
description: "TUI orchestrator for Claude Code (codename)",
|
|
95
95
|
type: "module",
|
|
96
96
|
packageManager: "bun@1.3.13",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded scrollback ring for the PTY server.
|
|
3
|
+
*
|
|
4
|
+
* The web terminal replays recent output on every (re)attach, so each PTY keeps
|
|
5
|
+
* a cap of recent bytes. The naive shape — `buffer = (buffer + data).slice(-CAP)`
|
|
6
|
+
* on every chunk — re-flattens the whole ~256KB buffer per chunk once full, so a
|
|
7
|
+
* burst of N small chunks costs O(N·CAP) (quadratic) on the same thread that
|
|
8
|
+
* relays bytes to the browser.
|
|
9
|
+
*
|
|
10
|
+
* This ring keeps the chunks as-is and a running length total: `push` is
|
|
11
|
+
* O(chunk) (append + shift whole chunks off the head until back under the cap),
|
|
12
|
+
* and the string is materialized only on `replay` — once per attach, O(cap).
|
|
13
|
+
*
|
|
14
|
+
* "Length" is measured in JS string length (UTF-16 code units), matching the
|
|
15
|
+
* prior `.slice(-CAP)` semantics: the cap is an approximate recent-output
|
|
16
|
+
* window, not an exact byte count.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {number} cap Max retained length (string code units).
|
|
21
|
+
* @returns {{ push: (data: string) => void, replay: () => string, length: () => number, chunkCount: () => number }}
|
|
22
|
+
*/
|
|
23
|
+
export function createScrollback(cap) {
|
|
24
|
+
/** @type {string[]} */
|
|
25
|
+
let chunks = []
|
|
26
|
+
let total = 0
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
push(data) {
|
|
30
|
+
if (!data) return
|
|
31
|
+
chunks.push(data)
|
|
32
|
+
total += data.length
|
|
33
|
+
// Drop whole chunks off the head while over cap, but always keep the
|
|
34
|
+
// most recent chunk so a single oversized chunk still replays.
|
|
35
|
+
while (total > cap && chunks.length > 1) {
|
|
36
|
+
const dropped = chunks.shift()
|
|
37
|
+
total -= dropped.length
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
replay() {
|
|
41
|
+
if (chunks.length === 0) return ""
|
|
42
|
+
return chunks.length === 1 ? chunks[0] : chunks.join("")
|
|
43
|
+
},
|
|
44
|
+
length() {
|
|
45
|
+
return total
|
|
46
|
+
},
|
|
47
|
+
chunkCount() {
|
|
48
|
+
return chunks.length
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
}
|
package/package.json
CHANGED