thinkpool-pair 0.7.104 → 0.7.105
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 +5 -0
- package/claude-session.mjs +10 -1
- package/package.json +1 -1
package/bridge.mjs
CHANGED
|
@@ -1322,6 +1322,11 @@ function openStructured({ id, model, resume, log, commands, mode, spawnedBy, rol
|
|
|
1322
1322
|
})
|
|
1323
1323
|
entry.session = startClaudeSession({
|
|
1324
1324
|
cwd: cwd || process.cwd(), model, resume, mode, rolePrompt,
|
|
1325
|
+
// A Flow CONDUCTOR (flowSessionId set, no flowTaskKey) must DECOMPOSE, not explore via
|
|
1326
|
+
// a fan-out of Task/Explore subagents — those raise permission cards in plan mode (which
|
|
1327
|
+
// now land on the hidden conductor terminal) and the model ignores the prompt rule not
|
|
1328
|
+
// to. Hard-block the Task tool for conductors so it reads with Read/Grep/Glob + ExitPlanMode.
|
|
1329
|
+
blockSubagents: !!flowSessionId && !flowTaskKey,
|
|
1325
1330
|
mcpServers: { thinkpool: peekServer },
|
|
1326
1331
|
// Tier C precheck — the PreToolUse gate calls this BEFORE raising a card, so a
|
|
1327
1332
|
// disabled/looping/over-cap post never bothers a person. Closes over `entry`.
|
package/claude-session.mjs
CHANGED
|
@@ -120,7 +120,7 @@ const simplifyBlocks = (blocks = []) => blocks.map((b) => {
|
|
|
120
120
|
*/
|
|
121
121
|
const MODES = new Set(['default', 'acceptEdits', 'plan', 'bypassPermissions'])
|
|
122
122
|
|
|
123
|
-
export function startClaudeSession({ cwd, model, resume, env, mode: initialMode = 'default', onEvent, requestPermission, mcpServers, crossPostGate, crossRoomPostGate, rolePrompt }) {
|
|
123
|
+
export function startClaudeSession({ cwd, model, resume, env, mode: initialMode = 'default', onEvent, requestPermission, mcpServers, crossPostGate, crossRoomPostGate, rolePrompt, blockSubagents = false }) {
|
|
124
124
|
const ac = new AbortController()
|
|
125
125
|
let input = makeInputStream() // `let`: auto-restart swaps in a fresh stream
|
|
126
126
|
let sessionId = resume || null
|
|
@@ -248,6 +248,15 @@ export function startClaudeSession({ cwd, model, resume, env, mode: initialMode
|
|
|
248
248
|
// Surface it to the room when it changes; absent on models without effort.
|
|
249
249
|
const lvl = hookInput.effort?.level
|
|
250
250
|
if (lvl && lvl !== effort) { effort = lvl; emit({ kind: 'effort', level: effort }) }
|
|
251
|
+
// Flow CONDUCTOR hard-stop: a conductor must DECOMPOSE, never fan out Task/Explore
|
|
252
|
+
// subagents. The prompt asks it not to, but the model's parallelize instinct wins and
|
|
253
|
+
// it spawns Explore agents anyway — which (in plan mode) raise permission cards on the
|
|
254
|
+
// now-hidden conductor terminal and hang the whole flow. Deny the Task tool outright and
|
|
255
|
+
// tell it to read with Read/Grep/Glob + ExitPlanMode. (blockSubagents is set only for
|
|
256
|
+
// the conductor session — lanes are governed by their own one-hop prompt rule.)
|
|
257
|
+
if (blockSubagents && (toolName === 'Task' || toolName === 'Agent')) {
|
|
258
|
+
return { continue: true, hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: 'Flow conductors do NOT spawn subagents — it stalls the flow on a permission card. If you must inspect the codebase, read it yourself with Read/Grep/Glob (allowed here, no prompt). Then DECOMPOSE and call ExitPlanMode once. Do not call Task/Agent again.' } }
|
|
259
|
+
}
|
|
251
260
|
// ThinkPool cross-terminal READ (B2) is read-only + within-room — never
|
|
252
261
|
// prompt, in any mode. It still surfaces as a tool card so the room sees the peek.
|
|
253
262
|
if (toolName === 'mcp__thinkpool__read_terminal') {
|