thinkpool-pair 0.7.120 → 0.7.121

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
@@ -1671,12 +1671,20 @@ function openStructured({ id, model, resume, log, commands, mode, spawnedBy, rol
1671
1671
  // 'suggestion' is Claude Code's predicted-next-prompt ghost text — ephemeral
1672
1672
  // composer UI, broadcast to both clients but never logged/persisted/replayed.
1673
1673
  const chrome = evt.kind === 'mode' || evt.kind === 'usage' || evt.kind === 'clear' || evt.kind === 'compact' || evt.kind === 'stalled' || evt.kind === 'suggestion'
1674
- // compact turn finished (or errored) → clear the pulsing indicator.
1675
- // No "done" ctl line — the SDK's own output in the transcript is the
1676
- // signal (compact summary on success, AbortError text on abort/too-small).
1674
+ // compact turn finished (or errored) → clear the pulsing indicator AND resolve the
1675
+ // "◈ compacting context…" line so it doesn't sit there forever looking stuck (Max asked
1676
+ // "is it compacted?" — 2026-07-02). On success post an explicit "◈ context compacted"
1677
+ // control line, paired with the start line; on error the SDK's AbortError/too-small
1678
+ // text is the signal, so no line. Same control-event shape as ctlLine (kind:'control').
1677
1679
  if ((evt.kind === 'result' || evt.kind === 'error') && entry.compacting) {
1678
1680
  entry.compacting = false
1679
1681
  bcast('code-event', { term: id, evt: { kind: 'compact', status: 'done', ts: Date.now() } })
1682
+ if (evt.kind === 'result') {
1683
+ const doneEvt = { kind: 'control', text: '◈ context compacted', by: entry.compactBy || null }
1684
+ pushLog(entry, doneEvt)
1685
+ bcast('code-event', { term: id, evt: doneEvt })
1686
+ }
1687
+ entry.compactBy = null
1680
1688
  }
1681
1689
  // Single tail: stamp into the log (transcript kinds only), broadcast live,
1682
1690
  // print locally, persist. Shared so a deferred image event re-enters it once
@@ -656,6 +656,16 @@ export function startClaudeSession({ cwd, model, resume, env, mode: initialMode
656
656
  // count before compaction. Emit a real recap card the room can pin.
657
657
  if (m.subtype === 'compact_boundary') {
658
658
  emit({ kind: 'compaction', trigger: m.compact_metadata?.trigger || 'auto', preTokens: m.compact_metadata?.pre_tokens ?? null })
659
+ // Refresh the ctx% meter RIGHT AFTER compaction — it otherwise only updates at
660
+ // turn-end, so the mode row kept showing the stale PRE-compaction window
661
+ // ("ctx 90% even though we just compacted", Max 2026-07-02). Re-query the live
662
+ // context usage so the meter drops to the compacted size immediately.
663
+ ;(async () => {
664
+ try {
665
+ const c = await q?.getContextUsage?.()
666
+ if (c) { emit({ kind: 'usage', ctx: { used: c.totalTokens, max: c.maxTokens, pct: Math.round(c.percentage), model: c.model } }); if (c.model) curModel = c.model }
667
+ } catch { /* control req may be unavailable */ }
668
+ })()
659
669
  break
660
670
  }
661
671
  if (m.session_id) sessionId = m.session_id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinkpool-pair",
3
- "version": "0.7.120",
3
+ "version": "0.7.121",
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": {