thinkpool-pair 0.7.133 → 0.7.135

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/bridge.mjs CHANGED
@@ -1762,6 +1762,17 @@ function openStructured({ id, model, resume, log, commands, mode, spawnedBy, rol
1762
1762
  // A background-warmed terminal is now live — free its warmer slot so the next queued
1763
1763
  // idle terminal starts booting.
1764
1764
  if (evt.kind === 'system' && entry.warming) warmComplete(entry)
1765
+ // Compaction milestone → the persistent recap card (CompactionCard). Attribute a
1766
+ // MANUAL compaction to whoever ran /compact; for an AUTO compaction (SDK-initiated
1767
+ // mid-turn) flash a brief "Compacting…" beat so it isn't silent — we only learn of it
1768
+ // post-hoc, so there's no real duration to animate (Max, 2026-07-02).
1769
+ if (evt.kind === 'compaction') {
1770
+ if (entry.compacting) evt.by = entry.compactBy || null
1771
+ else if (evt.trigger === 'auto') {
1772
+ bcast('code-event', { term: id, evt: { kind: 'compact', status: 'start', ts: Date.now() } })
1773
+ setTimeout(() => { bcast('code-event', { term: id, evt: { kind: 'compact', status: 'done', ts: Date.now() } }) }, 2500)
1774
+ }
1775
+ }
1765
1776
  // Chrome events (mode / usage / clear / compact) are transient state, not
1766
1777
  // transcript — broadcast + print them but keep out of the persisted/replayed log.
1767
1778
  // 'stalled' is transient turn-liveness state (would replay as a stale frozen
@@ -1777,12 +1788,10 @@ function openStructured({ id, model, resume, log, commands, mode, spawnedBy, rol
1777
1788
  // text is the signal, so no line. Same control-event shape as ctlLine (kind:'control').
1778
1789
  if ((evt.kind === 'result' || evt.kind === 'error') && entry.compacting) {
1779
1790
  entry.compacting = false
1791
+ // Clear the ephemeral "Compacting…" indicator. The persistent record is the
1792
+ // CompactionCard (kind:'compaction', now attributed) — no redundant control line
1793
+ // that lingers in scrollback reading as "compacted recently" (Max, 2026-07-02).
1780
1794
  bcast('code-event', { term: id, evt: { kind: 'compact', status: 'done', ts: Date.now() } })
1781
- if (evt.kind === 'result') {
1782
- const doneEvt = { kind: 'control', text: '◈ context compacted', by: entry.compactBy || null }
1783
- pushLog(entry, doneEvt)
1784
- bcast('code-event', { term: id, evt: doneEvt })
1785
- }
1786
1795
  entry.compactBy = null
1787
1796
  }
1788
1797
  // Single tail: stamp into the log (transcript kinds only), broadcast live,
@@ -2183,10 +2192,10 @@ channel
2183
2192
  ctlLine('context cleared. You can continue with these answers in mind.')
2184
2193
  return
2185
2194
  }
2186
- // /compact → announce immediately, track so onEvent can emit a done signal when
2187
- // the SDK turn finishes. No echoYou — the ctl line IS the announcement.
2195
+ // /compact → show the ephemeral "Compacting…" indicator (the compact-start event),
2196
+ // track so onEvent clears it + attributes the recap card when the SDK turn finishes.
2197
+ // No persisted ctl line — the live indicator + the CompactionCard are the record.
2188
2198
  if (/^\/compact\b/.test(text)) {
2189
- ctlLine('◈ compacting context…')
2190
2199
  s.compacting = true
2191
2200
  s.compactBy = payload.by
2192
2201
  bcast('code-event', { term: payload.term, evt: { kind: 'compact', status: 'start', ts: Date.now() } })
package/event-id.mjs CHANGED
@@ -53,10 +53,14 @@ export function makeSeqCounter(startAfter = 0) {
53
53
  // transcript events, so a seq on one of these would leave a hole in the applied
54
54
  // sequence → the client sees a false gap → spurious resync storms. So the counter
55
55
  // skips them and they ride the log seq-less (the client cid-handles/ignores them).
56
- // MUST stay a subset of REPLAY_CHROME ∩ {kinds the bridge logs} — guarded by
57
- // bridge/test-seq.mjs S6. (mode/usage/clear/compact/stalled are bridge-chrome and
58
- // never logged at all, so they never reach the counter.)
59
- export const NO_SEQ_KINDS = new Set(['system', 'thinking_tokens', 'effort'])
56
+ // MUST equal REPLAY_CHROME ∩ {kinds the bridge logs} — guarded by bridge/test-seq.mjs
57
+ // S6. (mode/usage/clear/compact/stalled are bridge-chrome and never logged at all, so
58
+ // they never reach the counter.) 2026-07-02: models/queue-add/queue-cancel/propose-done/
59
+ // update-available were MISSING here — they're bridge-logged but web-filtered, so they
60
+ // consumed a seq + set the durable archive floor while the client dropped them, leaving
61
+ // the client's oldest RENDERED seq above the floor → a phantom "load earlier history"
62
+ // pill on a fresh lane (models fires on every session init) that fetched nothing.
63
+ export const NO_SEQ_KINDS = new Set(['system', 'thinking_tokens', 'effort', 'models', 'queue-add', 'queue-cancel', 'propose-done', 'update-available'])
60
64
  export const seqable = (evt) => !!evt && typeof evt === 'object' && !NO_SEQ_KINDS.has(evt.kind)
61
65
 
62
66
  // Highest numeric `seq` across a log of events (0 when none) — the floor a restored
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinkpool-pair",
3
- "version": "0.7.133",
3
+ "version": "0.7.135",
4
4
  "description": "Share a local coding-agent CLI (Claude Code, Codex, Gemini, Aider, …) into a ThinkPool Code room, live.",
5
5
  "type": "module",
6
6
  "bin": {