thinkpool-pair 0.7.8 → 0.7.9

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 (2) hide show
  1. package/bridge.mjs +16 -4
  2. package/package.json +1 -1
package/bridge.mjs CHANGED
@@ -499,8 +499,11 @@ function openStructured({ id, model, resume, log, commands, mode }) {
499
499
  if (!chrome) persist()
500
500
  },
501
501
  requestPermission: (req) => new Promise((resolve) => {
502
- entry.pending.set(req.id, resolve)
503
- bcast('code-perm-req', { term: id, id: req.id, toolName: req.toolName, input: req.input, risk: req.risk, plan: req.plan, questions: req.questions })
502
+ // Keep the broadcast payload with the resolver so a reconnect can re-send it
503
+ // (replay-request handler) pending cards never enter the replayed event log.
504
+ const payload = { term: id, id: req.id, toolName: req.toolName, input: req.input, risk: req.risk, plan: req.plan, questions: req.questions }
505
+ entry.pending.set(req.id, { resolve, payload })
506
+ bcast('code-perm-req', payload)
504
507
  process.stderr.write(req.risk === 'plan'
505
508
  ? `\n ${A.mag}◆ plan ready — approve in the room.${A.rst}\n`
506
509
  : req.risk === 'ask'
@@ -609,6 +612,15 @@ channel
609
612
  if (!s.log.length) continue
610
613
  bcast('code-replay', { to: payload?.to ?? null, term: id, events: s.log })
611
614
  }
615
+ // Re-send any still-pending permission/question cards. They ride a one-shot
616
+ // code-perm-req broadcast (NOT the replayed event log), so a reconnect/refresh
617
+ // would otherwise lose the answerable card while the transcript still shows the
618
+ // (unanswered) tool row — the AskUserQuestion "vanished on reconnect" bug. Only
619
+ // truly-unresolved cards remain in `pending` (resolved ones are deleted), and
620
+ // the client dedupes code-perm-req by id, so this can't resurrect an answered one.
621
+ for (const [, s] of sessions) {
622
+ for (const [, p] of s.pending) bcast('code-perm-req', p.payload)
623
+ }
612
624
  announce()
613
625
  })
614
626
  .on('broadcast', { event: 'file-put' }, ({ payload }) => {
@@ -677,10 +689,10 @@ channel
677
689
  })
678
690
  .on('broadcast', { event: 'code-perm' }, ({ payload }) => {
679
691
  const s = payload?.term && sessions.get(payload.term)
680
- const resolve = s && payload.id && s.pending.get(payload.id)
692
+ const p = s && payload.id && s.pending.get(payload.id)
681
693
  // Pass the raw decision through — normal tools use allow/deny, plan cards
682
694
  // use run/accept/keep (claude-session interprets). Default deny on missing.
683
- if (resolve) { s.pending.delete(payload.id); resolve(payload.decision || 'deny') }
695
+ if (p) { s.pending.delete(payload.id); p.resolve(payload.decision || 'deny') }
684
696
  })
685
697
  .on('broadcast', { event: 'code-abort' }, ({ payload }) => {
686
698
  const s = payload?.term && sessions.get(payload.term)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinkpool-pair",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
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": {