tmux-ide 2.9.3 → 2.9.5

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.
Files changed (85) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +120 -139
  3. package/bin/cli.js +4847 -3585
  4. package/package.json +16 -9
  5. package/packages/contracts/src/session-runtime.ts +2 -0
  6. package/packages/contracts/src/terminal-delivery.ts +4 -0
  7. package/packages/core/src/terminal-compact-capability.ts +31 -1
  8. package/packages/core/src/terminal-delivery.ts +234 -32
  9. package/packages/core/src/terminal-replica-hash-cache.ts +162 -21
  10. package/packages/core/src/terminal-replica-owned-row.ts +165 -10
  11. package/packages/core/src/terminal-replica.ts +43 -21
  12. package/packages/daemon/dist/lib/daemon-embed.js +19 -34
  13. package/packages/daemon/dist/lib/runtime-trace-writer.js +133 -0
  14. package/packages/daemon/dist/lib/tmux-client-execution.js +37 -2
  15. package/packages/daemon/dist/lib/tmux-server-owner.js +20 -4
  16. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Info.plist +2 -2
  17. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/MacOS/tmux-ide-notifier +0 -0
  18. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/Assets.car +0 -0
  19. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources +2 -2
  20. package/packages/daemon/dist/native/tmux/darwin-arm64/manifest.json +5 -1
  21. package/packages/daemon/dist/native/tmux/darwin-arm64/tmux +0 -0
  22. package/packages/daemon/dist/native/tmux/darwin-x64/manifest.json +5 -1
  23. package/packages/daemon/dist/native/tmux/darwin-x64/tmux +0 -0
  24. package/packages/daemon/dist/native/tmux/linux-arm64/manifest.json +5 -1
  25. package/packages/daemon/dist/native/tmux/linux-arm64/tmux +0 -0
  26. package/packages/daemon/dist/native/tmux/linux-x64/licenses/libevent_core-2.1.so.7.txt +0 -0
  27. package/packages/daemon/dist/native/tmux/linux-x64/manifest.json +5 -1
  28. package/packages/daemon/dist/native/tmux/linux-x64/tmux +0 -0
  29. package/packages/daemon/dist/terminal/attachments/native-runtime.js +6 -6
  30. package/packages/daemon/dist/terminal/mirror/control-channel.js +379 -75
  31. package/packages/daemon/dist/terminal/mirror/mirror-service.js +43 -3
  32. package/packages/daemon/dist/terminal/mirror/native-grid-projection.js +20 -11
  33. package/packages/daemon/dist/terminal/mirror/session-channel.js +639 -811
  34. package/packages/daemon/dist/terminal/mirror/stock-pane-snapshot.js +177 -0
  35. package/packages/daemon/dist/terminal/session-runtime/causal-cell-ledger.js +1 -1
  36. package/packages/daemon/dist/terminal/session-runtime/registry.js +145 -15
  37. package/packages/daemon/dist/terminal/session-runtime/stock-capture-fidelity.js +12 -0
  38. package/packages/daemon/dist/terminal/session-runtime/terminal-delivery-hub.js +128 -10
  39. package/packages/daemon/dist/terminal/session-runtime/terminal-replica-interpreter.js +21 -4
  40. package/packages/daemon/dist/terminal/session-runtime/terminal-replica-owner.js +19 -2
  41. package/packages/daemon/dist/terminal/session-runtime/xterm-terminal-interpreter-backend.js +17 -19
  42. package/packages/daemon/dist/tui/integrations/claude-agent-teams.js +264 -0
  43. package/packages/daemon/dist/tui/mirror/open-tui-workspace-runtime-port.js +64 -4
  44. package/packages/daemon/dist/tui/mirror/pane-surface.jsx +10 -1
  45. package/packages/daemon/dist/tui/mirror/reference-performance-trace.js +117 -71
  46. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-input-ingress.js +27 -3
  47. package/packages/daemon/dist/tui/mirror/runtime/pane-scoped-terminal-surface.jsx +17 -4
  48. package/packages/daemon/dist/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.js +19 -0
  49. package/packages/daemon/dist/tui/mirror/runtime/terminal-input-adapter.js +10 -2
  50. package/packages/daemon/dist/tui/mirror/testing/styled-frame-oracle.js +156 -0
  51. package/packages/daemon/src/lib/daemon-embed.ts +22 -34
  52. package/packages/daemon/src/lib/runtime-trace-writer.ts +132 -0
  53. package/packages/daemon/src/lib/tmux-client-execution.ts +47 -2
  54. package/packages/daemon/src/lib/tmux-server-owner.ts +19 -3
  55. package/packages/daemon/src/terminal/attachments/native-runtime.ts +6 -0
  56. package/packages/daemon/src/terminal/mirror/control-channel.ts +428 -84
  57. package/packages/daemon/src/terminal/mirror/events.ts +7 -7
  58. package/packages/daemon/src/terminal/mirror/mirror-service.ts +49 -3
  59. package/packages/daemon/src/terminal/mirror/native-grid-projection.ts +21 -11
  60. package/packages/daemon/src/terminal/mirror/pane-feed.ts +9 -4
  61. package/packages/daemon/src/terminal/mirror/session-channel.ts +705 -859
  62. package/packages/daemon/src/terminal/mirror/stock-pane-snapshot.ts +228 -0
  63. package/packages/daemon/src/terminal/session-runtime/causal-cell-ledger.ts +1 -1
  64. package/packages/daemon/src/terminal/session-runtime/registry.ts +203 -32
  65. package/packages/daemon/src/terminal/session-runtime/runtime-observability.ts +7 -0
  66. package/packages/daemon/src/terminal/session-runtime/stock-capture-fidelity.ts +13 -0
  67. package/packages/daemon/src/terminal/session-runtime/terminal-delivery-hub.ts +142 -8
  68. package/packages/daemon/src/terminal/session-runtime/terminal-replica-interpreter.ts +26 -3
  69. package/packages/daemon/src/terminal/session-runtime/terminal-replica-owner.ts +25 -1
  70. package/packages/daemon/src/terminal/session-runtime/xterm-terminal-interpreter-backend.ts +26 -20
  71. package/packages/daemon/src/tui/integrations/claude-agent-teams.ts +334 -0
  72. package/packages/daemon/src/tui/mirror/open-tui-workspace-runtime-port.ts +63 -4
  73. package/packages/daemon/src/tui/mirror/pane-surface.tsx +9 -1
  74. package/packages/daemon/src/tui/mirror/reference-performance-trace.ts +141 -90
  75. package/packages/daemon/src/tui/mirror/runtime/application-terminal-input-ingress.ts +27 -4
  76. package/packages/daemon/src/tui/mirror/runtime/pane-scoped-terminal-surface.tsx +61 -31
  77. package/packages/daemon/src/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.ts +31 -3
  78. package/packages/daemon/src/tui/mirror/runtime/terminal-input-adapter.ts +9 -6
  79. package/packages/daemon/src/tui/mirror/testing/styled-frame-oracle.ts +209 -0
  80. package/packages/daemon-client/src/terminal-fast-lane.ts +53 -4
  81. package/packages/daemon-client/src/workspace-client-types.ts +1 -0
  82. package/packages/daemon-client/src/workspace-client.ts +78 -5
  83. package/packages/tmux-bridge/src/index.ts +1 -0
  84. package/packages/tmux-bridge/src/runner.ts +25 -1
  85. package/skill/SKILL.md +30 -30
@@ -328,6 +328,46 @@ export class MirrorService {
328
328
  flowSnapshot(session) {
329
329
  return this.channels.get(session)?.channel.flowSnapshot() ?? null;
330
330
  }
331
+ // Cumulative scalar totals sampled after each retired channel finishes disposal.
332
+ // Keep evidence of residual listeners without retaining retired channel objects.
333
+ retiredListenerCounts = {
334
+ channels: 0,
335
+ failures: 0,
336
+ pane: 0,
337
+ layout: 0,
338
+ layoutAuthority: 0,
339
+ };
340
+ qualificationListeners() {
341
+ const active = { pane: 0, layout: 0, layoutAuthority: 0 };
342
+ for (const entry of this.channels.values()) {
343
+ const counts = entry.channel.qualificationListeners();
344
+ active.pane += counts.pane;
345
+ active.layout += counts.layout;
346
+ active.layoutAuthority += counts.layoutAuthority;
347
+ }
348
+ return Object.freeze({
349
+ active: Object.freeze(active),
350
+ retired: Object.freeze({ ...this.retiredListenerCounts }),
351
+ pendingDisposals: this.pendingDisposals.size,
352
+ sessionExit: this.sessionExitListeners.size,
353
+ });
354
+ }
355
+ async disposeObservedChannel(channel) {
356
+ try {
357
+ await channel.dispose();
358
+ }
359
+ catch (error) {
360
+ this.retiredListenerCounts.failures += 1;
361
+ throw error;
362
+ }
363
+ finally {
364
+ const counts = channel.qualificationListeners();
365
+ this.retiredListenerCounts.channels += 1;
366
+ this.retiredListenerCounts.pane += counts.pane;
367
+ this.retiredListenerCounts.layout += counts.layout;
368
+ this.retiredListenerCounts.layoutAuthority += counts.layoutAuthority;
369
+ }
370
+ }
331
371
  activeChannelCount() {
332
372
  return this.channels.size;
333
373
  }
@@ -342,7 +382,7 @@ export class MirrorService {
342
382
  this.updateWindowMembership(entry.channel, []);
343
383
  this.channelSessions.delete(entry.channel);
344
384
  try {
345
- await entry.channel.dispose();
385
+ await this.disposeObservedChannel(entry.channel);
346
386
  }
347
387
  finally {
348
388
  entry.releaseAuthority();
@@ -446,6 +486,7 @@ export class MirrorService {
446
486
  }
447
487
  },
448
488
  onNativeClientActivity: () => this.opts.onNativeClientActivity?.(session),
489
+ captureInputWrite: (action, semanticPaneId) => this.opts.captureInputWrite?.(session, action, semanticPaneId),
449
490
  onInputWrite: (action, startedAtMicros, endedAtMicros, pendingBeforeSend) => this.opts.onInputWrite?.(session, action, startedAtMicros, endedAtMicros, pendingBeforeSend),
450
491
  onInputAccepted: (action, acceptedAtMicros, ok) => this.opts.onInputAccepted?.(session, action, acceptedAtMicros, ok),
451
492
  onOutputObserved: (semanticPaneId, ageMs, timing) => this.opts.onOutputObserved?.(session, semanticPaneId, ageMs, timing),
@@ -500,8 +541,7 @@ export class MirrorService {
500
541
  this.channelSessions.delete(entry.channel);
501
542
  if (this.channels.get(session) === entry)
502
543
  this.channels.delete(session);
503
- const disposal = entry.channel
504
- .dispose()
544
+ const disposal = this.disposeObservedChannel(entry.channel)
505
545
  .catch(() => { })
506
546
  .finally(() => entry.releaseAuthority());
507
547
  this.drainingChannels.set(session, disposal);
@@ -1,16 +1,11 @@
1
+ import { TERMINAL_REPLICA_EMPTY_CELL, TERMINAL_REPLICA_SPACE_CELL } from "@tmux-ide/core";
1
2
  const rowSources = new WeakMap();
2
3
  const paintCache = new WeakMap();
3
4
  export function nativeProjectedRowSource(row) {
4
5
  return rowSources.get(row);
5
6
  }
6
7
  const defaultColor = Object.freeze({ kind: "default" });
7
- const empty = Object.freeze({
8
- grapheme: "",
9
- width: 1,
10
- foreground: defaultColor,
11
- background: defaultColor,
12
- attributes: 0,
13
- });
8
+ const empty = TERMINAL_REPLICA_EMPTY_CELL;
14
9
  const acsKeys = [..."+,-.0`abcdefghijklmnopqrstuvwxyz{|}~"];
15
10
  const acsValues = [..."→←↑↓▮◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·"];
16
11
  const acs = new Map(acsKeys.map((key, index) => [key, acsValues[index]]));
@@ -29,7 +24,7 @@ function color(value) {
29
24
  }
30
25
  function paint(cell) {
31
26
  const bits = cell.attributes;
32
- return Object.freeze({
27
+ return {
33
28
  grapheme: bits & 0x80 ? (acs.get(cell.text) ?? cell.text) : cell.text,
34
29
  width: cell.width === 2 ? 2 : 1,
35
30
  foreground: color(cell.foreground),
@@ -41,7 +36,21 @@ function paint(cell) {
41
36
  (bits & 0x10 ? 32 : 0) |
42
37
  (bits & 0x20 ? 64 : 0) |
43
38
  (bits & 0x100 ? 128 : 0),
44
- });
39
+ };
40
+ }
41
+ // Only normalized, internally constructed paint can reuse trusted core values.
42
+ // Foreign native fields have already been read in the original paint order.
43
+ function freezePaint(cell) {
44
+ if (cell.width === 1 &&
45
+ cell.attributes === 0 &&
46
+ cell.foreground === defaultColor &&
47
+ cell.background === defaultColor) {
48
+ if (cell.grapheme === "")
49
+ return TERMINAL_REPLICA_EMPTY_CELL;
50
+ if (cell.grapheme === " ")
51
+ return TERMINAL_REPLICA_SPACE_CELL;
52
+ }
53
+ return Object.freeze(cell);
45
54
  }
46
55
  /**
47
56
  * Clean, column-preserving paint for a retained native row. This is a viewport
@@ -76,13 +85,13 @@ export function projectNativeGridRow(source, columns, startColumn = 0, wrapped =
76
85
  native.width > 2 ||
77
86
  x + native.width > columns) {
78
87
  const span = native.flags & 0x80 ? Math.max(1, Math.min(native.width, columns - x)) : 1;
79
- const blank = Object.freeze({ ...styled, grapheme: "", width: 1 });
88
+ const blank = freezePaint({ ...styled, grapheme: "", width: 1 });
80
89
  for (let offset = 0; offset < span; offset++)
81
90
  cells[x + offset] = blank;
82
91
  x += span - 1;
83
92
  continue;
84
93
  }
85
- cells[x] = styled;
94
+ cells[x] = freezePaint(styled);
86
95
  if (native.width === 2) {
87
96
  cells[++x] = Object.freeze({ ...styled, grapheme: "", width: 0 });
88
97
  }