peertable 0.8.5 → 0.8.7
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.
|
|
3
|
+
"version": "0.8.7",
|
|
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.
|
|
16
|
+
const MCP_VERSION = '0.8.7'
|
|
17
17
|
const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
|
|
18
18
|
|
|
19
19
|
const USAGE = `usage:
|
|
@@ -7,4 +7,8 @@ if (mission) body.mission = mission
|
|
|
7
7
|
return body
|
|
8
8
|
}
|
|
9
9
|
const [name, model, effort, harness, mission] = process.argv.slice(2)
|
|
10
|
-
process.
|
|
10
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
|
11
|
+
process.stdout.write(`${JSON.stringify(parentMember(name, model, effort, harness, mission))}\n`)
|
|
12
|
+
}
|
|
13
|
+
import { resolve } from 'node:path'
|
|
14
|
+
import { fileURLToPath } from 'node:url'
|
|
@@ -4,6 +4,7 @@ import { execFileSync } from 'node:child_process'
|
|
|
4
4
|
import { homedir, tmpdir } from 'node:os'
|
|
5
5
|
import path, { join } from 'node:path'
|
|
6
6
|
import { resolveWindowsLatticeCommand } from './platform/windows/resolve-lattice-command.mjs'
|
|
7
|
+
import { classifyGrokPaneTail, isGrokPrivacyBanner } from './vendors/grok/pane-status.mjs'
|
|
7
8
|
|
|
8
9
|
const TOKEN_HINT = /[↓↑]\s*([0-9]+(?:\.[0-9]+)?)\s*([kKmM]?)\s*tokens\b/gu
|
|
9
10
|
|
|
@@ -191,13 +192,7 @@ export const BLOCKED_MARKERS = [
|
|
|
191
192
|
'Press enter to confirm or esc to cancel',
|
|
192
193
|
]
|
|
193
194
|
|
|
194
|
-
|
|
195
|
-
export function isGrokPrivacyBanner(tail) {
|
|
196
|
-
return typeof tail === 'string'
|
|
197
|
-
&& tail.includes('Help improve Grok')
|
|
198
|
-
&& tail.includes('[Opt out]')
|
|
199
|
-
&& tail.includes('[Opt in]')
|
|
200
|
-
}
|
|
195
|
+
export { isGrokPrivacyBanner }
|
|
201
196
|
|
|
202
197
|
/**
|
|
203
198
|
* pane 末尾の生文字列から画面状態を判定する。判定順は busy → blocked → idle
|
|
@@ -213,14 +208,9 @@ export function classifyPaneTail(tail) {
|
|
|
213
208
|
if (tail.includes("without interrupting Claude's current work")) return 'busy'
|
|
214
209
|
if (tail.includes('Calling tools')) return 'busy'
|
|
215
210
|
if (/…\s*\(\d+(?:m \d+)?s\b/u.test(tail)) return 'busy'
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// 完了後の `Worked for 38s` は idle。未完了 hook だけ `[hooks: 1/3]`。
|
|
219
|
-
if (tail.includes('Waiting for response') || tail.includes('Responding…') || tail.includes('Responding...')) return 'busy'
|
|
220
|
-
if (tail.includes('[stop]')) return 'busy'
|
|
221
|
-
if (/\[hooks:\s*\d+\/\d+\]/u.test(tail)) return 'busy'
|
|
211
|
+
const grokStatus = classifyGrokPaneTail(tail)
|
|
212
|
+
if (grokStatus !== null) return grokStatus
|
|
222
213
|
if (BLOCKED_MARKERS.some(marker => tail.includes(marker))) return 'blocked'
|
|
223
|
-
if (isGrokPrivacyBanner(tail)) return 'blocked'
|
|
224
214
|
return 'idle'
|
|
225
215
|
}
|
|
226
216
|
|
|
@@ -280,10 +270,27 @@ export function parsePaneTokenHint(pane) {
|
|
|
280
270
|
export const STOP_DECLARATION = /\[待機\]|\[監査提出\]|待機します|散会/u
|
|
281
271
|
|
|
282
272
|
export function patrolTargets({ activeTasks, messages, statusOf, lastBusyStartAt, now, lastNag, nagIntervalMs }) {
|
|
283
|
-
|
|
273
|
+
// task_id -> claim発言者の履歴。[claim]で積み、[claim撤回]で本人の最新claimを取り消す
|
|
274
|
+
// (実被弾 2026-08-25 #160: 撤回を読めず、撤回済みの後発claim者へ番犬が誤って吠えた。
|
|
275
|
+
// roomのclaimは割当の正本(決定25)なので、撤回も同じ語彙で読む——正本の外の推定はしない)。
|
|
276
|
+
const claimHistory = new Map()
|
|
284
277
|
for (const m of messages) {
|
|
285
|
-
const
|
|
286
|
-
if (
|
|
278
|
+
const claim = /^\[claim\]\s+([0-9A-Za-z._-]+)/u.exec(m.body ?? '')
|
|
279
|
+
if (claim) {
|
|
280
|
+
if (!claimHistory.has(claim[1])) claimHistory.set(claim[1], [])
|
|
281
|
+
claimHistory.get(claim[1]).push(m.from)
|
|
282
|
+
continue
|
|
283
|
+
}
|
|
284
|
+
const retract = /^\[claim撤回\]\s+([0-9A-Za-z._-]+)/u.exec(m.body ?? '')
|
|
285
|
+
if (retract) {
|
|
286
|
+
const history = claimHistory.get(retract[1]) ?? []
|
|
287
|
+
const index = history.lastIndexOf(m.from)
|
|
288
|
+
if (index !== -1) history.splice(index, 1)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const owner = new Map()
|
|
292
|
+
for (const [task, history] of claimHistory) {
|
|
293
|
+
if (history.length > 0) owner.set(task, history.at(-1))
|
|
287
294
|
}
|
|
288
295
|
const targets = []
|
|
289
296
|
for (const task of activeTasks) {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Grok Build TUI固有のpane状態を返す。判定不能ならnull。 */
|
|
2
|
+
export function classifyGrokPaneTail(tail) {
|
|
3
|
+
if (typeof tail !== 'string') return null
|
|
4
|
+
|
|
5
|
+
if (isGrokPrivacyBanner(tail)) return 'blocked'
|
|
6
|
+
|
|
7
|
+
// 完了後も `stop [hooks: 1/3]` はステータス行へ残る。入力欄が戻った
|
|
8
|
+
// `Worked for ...` 行を先にidle扱いし、配達を永久保留しない。
|
|
9
|
+
if (/Worked for\s+\d+(?:m\d+)?s[\s\S]*?stop\s+\[hooks:\s*\d+\/\d+\]/u.test(tail)) return 'idle'
|
|
10
|
+
|
|
11
|
+
if (tail.includes('Waiting for response') || tail.includes('Responding…') || tail.includes('Responding...')) return 'busy'
|
|
12
|
+
if (tail.includes('[stop]')) return 'busy'
|
|
13
|
+
if (/\[hooks:\s*\d+\/\d+\]/u.test(tail)) return 'busy'
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Grok TUI の SpaceXAI coding-data バナー。 */
|
|
18
|
+
export function isGrokPrivacyBanner(tail) {
|
|
19
|
+
return typeof tail === 'string'
|
|
20
|
+
&& tail.includes('Help improve Grok')
|
|
21
|
+
&& tail.includes('[Opt out]')
|
|
22
|
+
&& tail.includes('[Opt in]')
|
|
23
|
+
}
|