peertable 0.4.26 → 0.4.27
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peertable",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.27",
|
|
4
4
|
"description": "A round table of peer agents. No orchestrator at the head. Turn Claude Code, Codex, and Grok sessions into a team of equal, long-lived peers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/room/client.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { findModelsDoc, resolveSeatIdentity } from '../skill/scripts/resolve-sea
|
|
|
13
13
|
|
|
14
14
|
// client.mjs 側のハードコード版数。package.json の version と一致していることを
|
|
15
15
|
// diagnostics の version_consistency が見る(2 つの版数源の drift 検出。決定45)
|
|
16
|
-
const MCP_VERSION = '0.4.
|
|
16
|
+
const MCP_VERSION = '0.4.27'
|
|
17
17
|
const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
|
|
18
18
|
|
|
19
19
|
const USAGE = `usage:
|
|
@@ -91,6 +91,16 @@ if (rest[0] === '--stop') process.exit(0)
|
|
|
91
91
|
const requestedSeats = rest
|
|
92
92
|
const state = JSON.parse(readFileSync(join(proj, '.team', 'setup-state.json'), 'utf8'))
|
|
93
93
|
const { room, server_url: url } = state
|
|
94
|
+
const parentName = (() => {
|
|
95
|
+
if (process.env.PEERTABLE_PARENT_NAME) return process.env.PEERTABLE_PARENT_NAME
|
|
96
|
+
try {
|
|
97
|
+
const watch = JSON.parse(readFileSync(join(proj, '.team', 'parent-watch.json'), 'utf8'))
|
|
98
|
+
return typeof watch.parent === 'string' ? watch.parent : null
|
|
99
|
+
} catch {
|
|
100
|
+
return null
|
|
101
|
+
}
|
|
102
|
+
})()
|
|
103
|
+
const targetOpts = { parentName }
|
|
94
104
|
writeFileSync(record, JSON.stringify({
|
|
95
105
|
pid: process.pid, room, server_url: url, requested_seats: requestedSeats, started_at: new Date().toISOString(),
|
|
96
106
|
}) + '\n')
|
|
@@ -124,7 +134,7 @@ function reconcileSeats() {
|
|
|
124
134
|
const next = new Set()
|
|
125
135
|
if (membersObserved) {
|
|
126
136
|
for (const member of members.values()) {
|
|
127
|
-
if (!isWakeupBridgeTarget(member)) continue
|
|
137
|
+
if (!isWakeupBridgeTarget(member, targetOpts)) continue
|
|
128
138
|
next.add(member.name)
|
|
129
139
|
if (!pending.has(member.name)) pending.set(member.name, new Map())
|
|
130
140
|
}
|
|
@@ -227,7 +237,7 @@ async function wake(seat, msgs) {
|
|
|
227
237
|
// 配送直前に member ledger を取り直し、current name -> descriptor の一経路だけを使う。
|
|
228
238
|
await refreshMembers()
|
|
229
239
|
const member = members.get(seat)
|
|
230
|
-
if (!isWakeupBridgeTarget(member)) return 'skipped'
|
|
240
|
+
if (!isWakeupBridgeTarget(member, targetOpts)) return 'skipped'
|
|
231
241
|
const observation = resolveSeatObservation(member, null)
|
|
232
242
|
if (observation === null) {
|
|
233
243
|
const code = members.has(seat) ? 'DESCRIPTOR_MISSING' : 'MEMBER_MISSING'
|
|
@@ -265,7 +275,7 @@ function dispatch(msg) {
|
|
|
265
275
|
advanceLastSeq()
|
|
266
276
|
return
|
|
267
277
|
}
|
|
268
|
-
const targets = recipientNames(msg).filter(seat => isWakeupBridgeTarget(members.get(seat)))
|
|
278
|
+
const targets = recipientNames(msg).filter(seat => isWakeupBridgeTarget(members.get(seat), targetOpts))
|
|
269
279
|
const state = { message: msg, targets: new Set(targets), delivered: new Set() }
|
|
270
280
|
for (const seat of targets) {
|
|
271
281
|
if (delivered.has(deliveryKey(msg.seq, seat))) state.delivered.add(seat)
|
|
@@ -20,13 +20,24 @@ export function formatWakeNotice(msg) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
* observe 欠落は対象外ではない——配達できない故障であり、黙って飛ばさない。
|
|
23
|
+
* 親は parent-watch が配達する。通常席の TUI 配達から外す。
|
|
24
|
+
* Codex / Grok の observe 欠落は対象外ではない——配達できない故障であり、黙って飛ばさない。
|
|
25
25
|
*/
|
|
26
|
-
export function isWakeupBridgeTarget(member) {
|
|
26
|
+
export function isWakeupBridgeTarget(member, options = {}) {
|
|
27
27
|
if (!member || typeof member.name !== 'string' || member.name.length === 0) return false
|
|
28
28
|
if (member.delivery?.kind === 'parent_watch') return false
|
|
29
|
-
|
|
29
|
+
const parentName = options.parentName
|
|
30
|
+
if (typeof parentName === 'string' && parentName.length > 0 && member.name === parentName) return false
|
|
31
|
+
const observe = member.observe
|
|
32
|
+
const hasPane = Boolean(
|
|
33
|
+
observe
|
|
34
|
+
&& typeof observe === 'object'
|
|
35
|
+
&& typeof observe.tmux_target === 'string'
|
|
36
|
+
&& observe.tmux_target,
|
|
37
|
+
)
|
|
38
|
+
if (hasPane) return true
|
|
39
|
+
const vendor = member.vendor || member.settings?.vendor
|
|
40
|
+
return vendor === 'codex' || vendor === 'grok'
|
|
30
41
|
}
|
|
31
42
|
|
|
32
43
|
/**
|