thinkpool-pair 0.7.342 → 0.7.343
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 +33 -1
- package/package.json +1 -1
package/bridge.mjs
CHANGED
|
@@ -1283,6 +1283,15 @@ const replayPump = createLatestReplayPump({
|
|
|
1283
1283
|
// every announce carries them so a late-joining or second device sees them too.
|
|
1284
1284
|
const termNames = loadNames(room)
|
|
1285
1285
|
const manualNameTouched = new Set()
|
|
1286
|
+
const acknowledgeTermOpen = (id, kind, entry = null) => {
|
|
1287
|
+
bcast('term-opened', {
|
|
1288
|
+
id,
|
|
1289
|
+
kind,
|
|
1290
|
+
sideParent: entry?.sideParent || undefined,
|
|
1291
|
+
sideTask: entry?.sideTask || undefined,
|
|
1292
|
+
name: termNames[id] || undefined,
|
|
1293
|
+
})
|
|
1294
|
+
}
|
|
1286
1295
|
const autoNameAttempts = new Set()
|
|
1287
1296
|
const autoNames = new Map()
|
|
1288
1297
|
// The SDK's supported-model LIST (value/displayName/description), captured from
|
|
@@ -1726,7 +1735,6 @@ function pumpDesign(term) {
|
|
|
1726
1735
|
}
|
|
1727
1736
|
const active = { ...next, resultOk: false, proof: null, timer: null }
|
|
1728
1737
|
designActive.set(term, active)
|
|
1729
|
-
designStatus({ previewId: next.record.previewId, requestId: next.request.cid, state: 'applying' })
|
|
1730
1738
|
// Complete room-visible instructions, without host paths or locator packets.
|
|
1731
1739
|
const visible = {
|
|
1732
1740
|
kind: 'you',
|
|
@@ -1747,6 +1755,10 @@ function pumpDesign(term) {
|
|
|
1747
1755
|
} catch { accepted = false }
|
|
1748
1756
|
if (accepted) beginStructuredTurn(lane)
|
|
1749
1757
|
stampEvent(visible); pushLog(lane, visible); bcast('code-event', { term, evt: visible })
|
|
1758
|
+
// Browser clients use this as the positive dispatch acknowledgment. Keep it
|
|
1759
|
+
// after the accepted turn and its visible prompt so "applying" never navigates
|
|
1760
|
+
// a submitter away from an actionable Design failure.
|
|
1761
|
+
if (accepted) designStatus({ previewId: next.record.previewId, requestId: next.request.cid, state: 'applying' })
|
|
1750
1762
|
if (!accepted) {
|
|
1751
1763
|
syncStructuredTurn(lane)
|
|
1752
1764
|
const failed = { kind: 'error', message: 'The producing lane could not start the edit.', recoverable: true }
|
|
@@ -4111,6 +4123,13 @@ channel
|
|
|
4111
4123
|
// Multi-bridge rooms: a targeted open is for ONE machine. Untargeted
|
|
4112
4124
|
// opens (older web) are taken by whoever hears them — the solo case.
|
|
4113
4125
|
if (payload.host && payload.host !== name) return
|
|
4126
|
+
// A client retries an open when the first broadcast or this acknowledgement is
|
|
4127
|
+
// lost. PTY creation was already idempotent, but acknowledge the existing lane
|
|
4128
|
+
// explicitly so the watchdog can settle without waiting for a full roster.
|
|
4129
|
+
if (terms.has(payload.id)) {
|
|
4130
|
+
acknowledgeTermOpen(payload.id, 'pty', terms.get(payload.id))
|
|
4131
|
+
return
|
|
4132
|
+
}
|
|
4114
4133
|
// resume is a FLAG, never argv: the channel must not pass arbitrary
|
|
4115
4134
|
// args even though the room is shell-trust by design. The args come
|
|
4116
4135
|
// from our own KNOWN_AGENTS table, probe-gated so `--continue` with
|
|
@@ -4121,6 +4140,15 @@ channel
|
|
|
4121
4140
|
if (agent?.resume) { try { if (agent.resume.probe()) args = [...agent.resume.args] } catch { /* fresh */ } }
|
|
4122
4141
|
}
|
|
4123
4142
|
if (wantStructured(payload.cmd)) {
|
|
4143
|
+
// The open id is the idempotency key for the ENTIRE operation, including a
|
|
4144
|
+
// side lane's initial task. openStructured() already no-ops for an existing
|
|
4145
|
+
// runtime, but the old handler continued below and published side-started +
|
|
4146
|
+
// dispatched the task again. A retry must only replay the acceptance ack.
|
|
4147
|
+
const existing = sessions.get(payload.id)
|
|
4148
|
+
if (existing) {
|
|
4149
|
+
acknowledgeTermOpen(payload.id, 'structured', existing)
|
|
4150
|
+
return
|
|
4151
|
+
}
|
|
4124
4152
|
// model: the web passes the model to open on — a NEW terminal inherits the
|
|
4125
4153
|
// previous terminal's model (and the first uses the provider default). Falls
|
|
4126
4154
|
// through to the SDK default when absent. Stamped on the entry so the announce
|
|
@@ -4179,13 +4207,17 @@ channel
|
|
|
4179
4207
|
return
|
|
4180
4208
|
}
|
|
4181
4209
|
child.flush?.(); parent.flush?.(); announce()
|
|
4210
|
+
acknowledgeTermOpen(payload.id, 'structured', child)
|
|
4182
4211
|
process.stderr.write(`\n ◆ ${by} opened side lane ${String(payload.id).slice(0, 8)} under ${String(sideParent).slice(0, 8)}.\n`)
|
|
4183
4212
|
return
|
|
4184
4213
|
}
|
|
4214
|
+
const opened = sessions.get(payload.id)
|
|
4215
|
+
if (opened) acknowledgeTermOpen(payload.id, 'structured', opened)
|
|
4185
4216
|
process.stderr.write(`\n ◆ web opened a structured "${payload.cmd}" session (${payload.mode || 'default'}${payload.model ? `, model ${payload.model}` : ''}).\n`)
|
|
4186
4217
|
return
|
|
4187
4218
|
}
|
|
4188
4219
|
openTerm({ id: payload.id, cmd: payload.cmd, args })
|
|
4220
|
+
if (terms.has(payload.id)) acknowledgeTermOpen(payload.id, 'pty', terms.get(payload.id))
|
|
4189
4221
|
process.stderr.write(`\n ◆ web opened a "${payload.cmd}"${args.length ? ' (continue)' : ''} terminal (headless).\n`)
|
|
4190
4222
|
})
|
|
4191
4223
|
.on('broadcast', { event: 'term-close' }, ({ payload }) => {
|