thinkpool-pair 0.7.189 → 0.7.190

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/cross-terminal.mjs +18 -5
  2. package/package.json +1 -1
@@ -91,16 +91,29 @@ export const isOrdinalRef = (q) => /^(terminal\s*)?\d+$/i.test(q) || /^t\d+$/i.t
91
91
 
92
92
  // Resolve an agent-supplied reference to one sibling, or null. Match priority:
93
93
  // exact id → exact name → exact short-ref → id-prefix (≥4 chars) → name substring
94
- // → command substring. Name matching is what makes "Pivot" / "Grug" resolvable;
95
- // positional ordinals are refused (see isOrdinalRef).
94
+ // → command substring. Name matching is what makes "Pivot" / "Grug" resolvable.
95
+ //
96
+ // The ordinal guard runs AFTER the exact matches, not before (2026-07-10). A ref is
97
+ // 8 hex characters, and ~2.3% of them contain no letters at all — "33729214" is a
98
+ // perfectly good ref that `isOrdinalRef` reads as the ordinal "33,729,214". Refusing
99
+ // it early made those lanes unresolvable by the very handle read_terminal prints:
100
+ // unreadable, un-postable, and — the reason this surfaced — UNCLOSABLE, holding a
101
+ // slot against the machine cap until the bridge restarted. Two of ~30 lanes in one
102
+ // day, which is exactly the rate the arithmetic predicts.
103
+ //
104
+ // Checking identity first is safe: an ordinal like "3" or "terminal 2" can never
105
+ // exactly equal an 8-char ref, a UUID, or a lane's name, so the guard still refuses
106
+ // every reference it was written to refuse. It only stops shadowing real handles.
96
107
  export const resolveSibling = (siblings, terminal) => {
97
108
  const q = String(terminal || '').toLowerCase().trim()
98
- if (!q || isOrdinalRef(q)) return null
109
+ if (!q) return null
99
110
  const list = Array.isArray(siblings) ? siblings : []
100
- return list.find(x => String(x.id).toLowerCase() === q)
111
+ const exact = list.find(x => String(x.id).toLowerCase() === q)
101
112
  || list.find(x => String(x.name || '').toLowerCase() === q)
102
113
  || list.find(x => String(x.ref).toLowerCase() === q)
103
- || list.find(x => q.length >= 4 && String(x.id).toLowerCase().startsWith(q))
114
+ if (exact) return exact
115
+ if (isOrdinalRef(q)) return null
116
+ return list.find(x => q.length >= 4 && String(x.id).toLowerCase().startsWith(q))
104
117
  || list.find(x => x.name && String(x.name).toLowerCase().includes(q))
105
118
  || list.find(x => String(x.cmd).toLowerCase().includes(q))
106
119
  || null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinkpool-pair",
3
- "version": "0.7.189",
3
+ "version": "0.7.190",
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": {