peertable 0.8.10 → 0.8.11

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.8.10",
3
+ "version": "0.8.11",
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.8.10'
16
+ const MCP_VERSION = '0.8.11'
17
17
  const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
18
18
 
19
19
  const USAGE = `usage:
@@ -173,10 +173,20 @@ for (const [name, judge] of [['wakeup', judgeWakeup], ['seat-status', judgeSeatS
173
173
  try {
174
174
  const probe = spawnSync('tmux', ['list-sessions', '-F', '#{session_name}'], { encoding: 'utf8' })
175
175
  if (probe.error) throw probe.error
176
- line('OK', `job観測: tmux list-sessions 実行可(ランプ合成は有効。jobは peer-<name>-job* セッションで走らせること)`)
176
+ line('OK', `job観測: tmux list-sessions 実行可(ランプ合成は有効。ジョブは席のシェルからtmuxセッションで走らせる——名前は自由)`)
177
177
  } catch (error) {
178
178
  line('NG', `job観測: tmux list-sessions が失敗——預け仕事のランプ合成はこの端末で無効(${String(error.message ?? error).split('\n')[0]})`)
179
179
  }
180
+ // env帰属(2026-08-26 オーナー裁定: 帰属は規約名でなくOSの環境変数継承): この端末のtmux/psmuxが
181
+ // update-environment と show-environment を持つか。持たない実装(psmuxの互換欠け等)では
182
+ // 名前fallback(peer-<name>- 前置)だけで動くので、その事実を機械判定で出す。
183
+ try {
184
+ const opts = execFileSync('tmux', tmuxArgv(['show-options', '-g', 'update-environment'], { socket: resolveTmuxSocket(process.env).socket }), { encoding: 'utf8' })
185
+ if (/PEERTABLE_MEMBER/.test(opts)) line('OK', 'env帰属: update-environment に PEERTABLE_MEMBER が載っている(新規セッションへ持ち主が自動継承される)')
186
+ else line('NG', 'env帰属: update-environment に PEERTABLE_MEMBER が無い——launch-seat をこの版で一度通すと設定される。それまで帰属は peer-<name>- 前置の名前fallbackのみ')
187
+ } catch (error) {
188
+ line('NG', `env帰属: show-options が失敗——この端末のtmux/psmuxはenv帰属を判定できず、名前fallbackのみで動作(${String(error.message ?? error).split('\n')[0]})`)
189
+ }
180
190
  // 読了ack: server members に read_seq 欄が観測できるか(席が一度もackしていない間は判定できない)
181
191
  try {
182
192
  const res = JSON.parse(execFileSync('curl', ['-s', `${url}/api/${encodeURIComponent(room)}/members`], { encoding: 'utf8' }))
@@ -131,6 +131,7 @@ function readSeat(member, previous, observedAt) {
131
131
  const jobPaneHash = new Map() // `${name}:${session}` -> { hash, changedAt }
132
132
  const jobCpuSeconds = new Map() // `${name}:${session}` -> 前周期の累積CPU秒(root=job本体を含む)
133
133
  let jobObserveFailureLogged = false
134
+ let envAttributionFailureLogged = false
134
135
  function observeJob(socket, name, memberNames, envCache) {
135
136
  const listed = tmux(socket, 'list-sessions', '-F', '#{session_name}')
136
137
  if (listed === null) {
@@ -148,8 +149,19 @@ function observeJob(socket, name, memberNames, envCache) {
148
149
  const names = memberNames?.length ? memberNames : [name]
149
150
  const envOf = (session) => {
150
151
  if (envCache?.has(session)) return envCache.get(session)
151
- const out = tmux(socket, 'show-environment', '-t', session, 'PEERTABLE_MEMBER')
152
- const m = out === null ? null : /^PEERTABLE_MEMBER=(.+)$/m.exec(out)
152
+ // 変数名指定でなく全量listを読む: 「変数が無い」と「show-environment自体が使えない」
153
+ // (psmux等のtmux互換の欠け)を区別するため。使えない端末は名前fallbackで動き続けるが、
154
+ // その事実は黙らず一度だけ吠える(silent absence禁止)
155
+ const out = tmux(socket, 'show-environment', '-t', session)
156
+ if (out === null) {
157
+ if (!envAttributionFailureLogged) {
158
+ envAttributionFailureLogged = true
159
+ console.error('ENV_ATTRIBUTION_UNAVAILABLE: show-environment がこの端末のtmux/psmuxで失敗するため、預け仕事の帰属はsession envで判定できない(peer-<name>- 前置の名前fallbackのみで動作)')
160
+ }
161
+ envCache?.set(session, null)
162
+ return null
163
+ }
164
+ const m = /^PEERTABLE_MEMBER=(.+)$/m.exec(out)
153
165
  const value = m ? m[1].trim() : null
154
166
  envCache?.set(session, value)
155
167
  return value