zames_pro 2.82.69 → 2.82.70

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/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.82.70] - 2026-10-24
11
+
12
+ ### Fixed
13
+
14
+ - **transcript:** keep a capped line valid JSON so the event is not lost
15
+
10
16
  ## [2.82.69] - 2026-10-24
11
17
 
12
18
  ### Fixed
@@ -46,6 +46,60 @@ export function rotateTranscripts(dir, keep = MAX_TRANSCRIPT_FILES) {
46
46
  }
47
47
  return removed;
48
48
  }
49
+ /**
50
+ * Re-serialize an oversized event with its LONG STRING FIELDS cut, so the line
51
+ * stays VALID JSON. A raw slice + ellipsis produced an unparsable line and
52
+ * parseTranscript() silently dropped the whole event — /cost and /export lost
53
+ * the turn that produced a big tool result.
54
+ */
55
+ function capTranscriptLine(entry) {
56
+ const budget = TRANSCRIPT_LINE_CAP - 2;
57
+ // A binary search over the per-string allowance keeps the result close to
58
+ // the cap without serializing a 200 KB payload over and over.
59
+ let lo = 0;
60
+ let hi = budget;
61
+ let best = '';
62
+ for (let i = 0; i < 24; i++) {
63
+ const allow = Math.floor((lo + hi) / 2);
64
+ const line = JSON.stringify(trimStrings(entry, allow)) + String.fromCharCode(10);
65
+ if (line.length <= TRANSCRIPT_LINE_CAP) {
66
+ best = line;
67
+ lo = allow;
68
+ }
69
+ else {
70
+ hi = allow;
71
+ }
72
+ if (lo >= hi)
73
+ break;
74
+ }
75
+ if (best)
76
+ return best;
77
+ // Degenerate (the keys alone exceed the cap): keep a VALID minimal event.
78
+ return (JSON.stringify({ type: entry.type, truncated: true }) +
79
+ String.fromCharCode(10));
80
+ }
81
+ /** Deep-copy `entry`, cutting every string longer than `allow` (surrogate-safe). */
82
+ function trimStrings(v, allow) {
83
+ if (typeof v === 'string') {
84
+ if (v.length <= allow)
85
+ return v;
86
+ let cut = Math.max(0, allow);
87
+ const last = v.charCodeAt(cut - 1);
88
+ if (last >= 0xd800 && last <= 0xdbff)
89
+ cut--;
90
+ return v.slice(0, cut) + '…';
91
+ }
92
+ if (Array.isArray(v))
93
+ return v.map((x) => trimStrings(x, allow));
94
+ if (v && typeof v === 'object') {
95
+ const out = {};
96
+ for (const [k, x] of Object.entries(v)) {
97
+ out[k] = trimStrings(x, allow);
98
+ }
99
+ return out;
100
+ }
101
+ return v;
102
+ }
49
103
  function transcriptErrorLine(e) {
50
104
  return `transcript: failed to create file: ${e.message}`;
51
105
  }
@@ -108,11 +162,7 @@ export class Transcript {
108
162
  // transcript a LOG: cap each line with a marker (never splitting a
109
163
  // surrogate pair).
110
164
  if (line.length > TRANSCRIPT_LINE_CAP) {
111
- let cut = TRANSCRIPT_LINE_CAP - 2;
112
- const last = line.charCodeAt(cut - 1);
113
- if (last >= 0xd800 && last <= 0xdbff)
114
- cut--;
115
- line = line.slice(0, cut) + '…' + String.fromCharCode(10);
165
+ line = capTranscriptLine(entry);
116
166
  }
117
167
  // The mirror runs even when the file is disabled (jsonl mode).
118
168
  if (this.onLine) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.82.69",
3
+ "version": "2.82.70",
4
4
  "description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen and other web LLMs — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
5
5
  "type": "module",
6
6
  "bin": {