@adhdev/daemon-standalone 0.9.82-rc.2 → 0.9.82-rc.200

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.
@@ -74,7 +74,8 @@ function formatXtermViewportPlain(terminal, rows) {
74
74
  const lines = [];
75
75
  for (let i = start; i < end; i++) {
76
76
  const line = buffer.getLine(i);
77
- lines.push(line ? line.translateToString(true) : "");
77
+ const raw = line ? line.translateToString(false) : "";
78
+ lines.push(raw.replace(/\s+$/, ""));
78
79
  }
79
80
  let first = 0;
80
81
  let last = lines.length;
@@ -137,6 +138,9 @@ function createXtermMirror(options) {
137
138
  if (serializer) return serializeXtermViewport(terminal, serializer, currentRows);
138
139
  return formatXtermViewportPlain(terminal, currentRows);
139
140
  },
141
+ formatPlainText() {
142
+ return formatXtermViewportPlain(terminal, currentRows).replace(/\r\n/g, "\n");
143
+ },
140
144
  getCursorPosition() {
141
145
  const buffer = terminal.buffer.active;
142
146
  return {
@@ -169,6 +173,9 @@ function normalizeGhosttyBinding(mod) {
169
173
  formatVT() {
170
174
  return viewportSnapshot.formatVT();
171
175
  },
176
+ formatPlainText() {
177
+ return viewportSnapshot.formatPlainText();
178
+ },
172
179
  getCursorPosition() {
173
180
  if (typeof handle.getCursorPosition === "function") return handle.getCursorPosition();
174
181
  return viewportSnapshot.getCursorPosition();
@@ -217,6 +224,10 @@ var PtySessionRuntime = class {
217
224
  ptyProcess = null;
218
225
  screenMirror = null;
219
226
  pendingQueryScanTail = "";
227
+ terminalModeScanTail = "";
228
+ altScreen = false;
229
+ pasteMode = false;
230
+ scrollRegion;
220
231
  onDataCallback;
221
232
  onExitCallback;
222
233
  constructor(options) {
@@ -224,6 +235,7 @@ var PtySessionRuntime = class {
224
235
  this.payload = options.payload;
225
236
  this.cols = resolveSessionHostCols(options.payload.cols);
226
237
  this.rows = resolveSessionHostRows(options.payload.rows);
238
+ this.scrollRegion = { top: 0, bot: this.rows - 1 };
227
239
  this.onDataCallback = options.onData;
228
240
  this.onExitCallback = options.onExit;
229
241
  }
@@ -255,6 +267,7 @@ var PtySessionRuntime = class {
255
267
  });
256
268
  this.ptyProcess.onData((data) => {
257
269
  this.screenMirror?.write(data);
270
+ this.trackTerminalModes(data);
258
271
  this.respondToTerminalQueries(data);
259
272
  this.onDataCallback(data);
260
273
  });
@@ -263,6 +276,7 @@ var PtySessionRuntime = class {
263
276
  this.screenMirror?.dispose();
264
277
  this.screenMirror = null;
265
278
  this.pendingQueryScanTail = "";
279
+ this.terminalModeScanTail = "";
266
280
  this.onExitCallback(exitCode ?? null);
267
281
  });
268
282
  return this.ptyProcess.pid;
@@ -274,6 +288,12 @@ var PtySessionRuntime = class {
274
288
  resize(cols, rows) {
275
289
  if (!this.ptyProcess) throw new Error(`Session not running: ${this.sessionId}`);
276
290
  this.ptyProcess.resize(cols, rows);
291
+ this.cols = Math.max(1, cols | 0);
292
+ this.rows = Math.max(1, rows | 0);
293
+ this.scrollRegion = {
294
+ top: Math.min(this.scrollRegion.top, this.rows - 1),
295
+ bot: Math.min(Math.max(this.scrollRegion.top, this.scrollRegion.bot), this.rows - 1)
296
+ };
277
297
  this.screenMirror?.resize(cols, rows);
278
298
  }
279
299
  stop() {
@@ -297,6 +317,55 @@ var PtySessionRuntime = class {
297
317
  getSnapshotText() {
298
318
  return this.screenMirror?.formatVT() || "";
299
319
  }
320
+ getTerminalSnapshot() {
321
+ if (!this.ptyProcess || !this.screenMirror) {
322
+ throw new Error(`Session not running: ${this.sessionId}`);
323
+ }
324
+ const cursor = this.screenMirror.getCursorPosition();
325
+ return {
326
+ text: this.screenMirror.formatPlainText(),
327
+ state: {
328
+ cursor: {
329
+ row: Math.max(0, cursor.row | 0),
330
+ col: Math.max(0, cursor.col | 0)
331
+ },
332
+ altScreen: this.altScreen,
333
+ pasteMode: this.pasteMode,
334
+ rawMode: true,
335
+ scrollRegion: { ...this.scrollRegion },
336
+ cols: this.cols,
337
+ rows: this.rows
338
+ }
339
+ };
340
+ }
341
+ trackTerminalModes(data) {
342
+ if (!data) return;
343
+ const combined = this.terminalModeScanTail + data;
344
+ const privateMode = /\x1b\[\?([0-9;]*)([hl])/g;
345
+ let privateMatch;
346
+ while ((privateMatch = privateMode.exec(combined)) !== null) {
347
+ const enabled = privateMatch[2] === "h";
348
+ for (const mode of privateMatch[1].split(";")) {
349
+ if (mode === "47" || mode === "1047" || mode === "1049") this.altScreen = enabled;
350
+ if (mode === "2004") this.pasteMode = enabled;
351
+ }
352
+ }
353
+ const scrollRegion = /\x1b\[(\d*)(?:;(\d*))?r/g;
354
+ let scrollMatch;
355
+ while ((scrollMatch = scrollRegion.exec(combined)) !== null) {
356
+ const top = scrollMatch[1] ? Number.parseInt(scrollMatch[1], 10) - 1 : 0;
357
+ const bot = scrollMatch[2] ? Number.parseInt(scrollMatch[2], 10) - 1 : this.rows - 1;
358
+ this.scrollRegion = {
359
+ top: Math.max(0, Math.min(this.rows - 1, top)),
360
+ bot: Math.max(0, Math.min(this.rows - 1, bot))
361
+ };
362
+ if (this.scrollRegion.bot < this.scrollRegion.top) {
363
+ this.scrollRegion = { top: 0, bot: this.rows - 1 };
364
+ }
365
+ }
366
+ const lastEscape = combined.lastIndexOf("\x1B");
367
+ this.terminalModeScanTail = lastEscape >= 0 && combined.length - lastEscape < 64 ? combined.slice(lastEscape) : "";
368
+ }
300
369
  respondToTerminalQueries(data) {
301
370
  if (!this.ptyProcess || !this.screenMirror || !data) return;
302
371
  const combined = this.pendingQueryScanTail + data;
@@ -510,6 +579,8 @@ var SessionHostServer = class _SessionHostServer extends EventEmitter {
510
579
  }
511
580
  case "get_snapshot":
512
581
  return { success: true, result: this.getSnapshot(request.payload.sessionId, request.payload.sinceSeq) };
582
+ case "get_terminal_snapshot":
583
+ return { success: true, result: this.requireRuntime(request.payload.sessionId).getTerminalSnapshot() };
513
584
  case "get_host_diagnostics":
514
585
  return { success: true, result: this.getHostDiagnostics(request.payload) };
515
586
  case "clear_session_buffer": {
@@ -750,7 +821,12 @@ var SessionHostServer = class _SessionHostServer extends EventEmitter {
750
821
  const record = this.registry.getSession(sessionId);
751
822
  if (!record) return;
752
823
  const snapshot = this.getSnapshot(sessionId);
753
- this.storage.save(record, snapshot);
824
+ try {
825
+ this.storage.save(record, snapshot);
826
+ } catch (error) {
827
+ const code = typeof error?.code === "string" ? error.code : "persist_failed";
828
+ console.error(`[session-host] Persist failed for ${sessionId}: ${code}: ${error?.message || error}`);
829
+ }
754
830
  }
755
831
  getSessionHostRecoveryLabel(record) {
756
832
  const recoveryState = typeof record.meta?.runtimeRecoveryState === "string" ? String(record.meta.runtimeRecoveryState).trim() : "";