refactor(hooks): improve interactive bash session tracking and command parsing

- Replace regex-based session extraction with quote-aware tokenizer
- Add proper tmux global options handling (-L, -S, -f, -c, -T)
- Add normalizeSessionName to strip :window and .pane suffixes
- Add findSubcommand for proper subcommand detection
- Add early error output return to avoid false state tracking
- Fix tool-output-truncator to exclude grep/Grep from generic truncation
- Fix todo-continuation-enforcer to clear reminded state on assistant response
- Add proper parallel stdout/stderr reading in interactive_bash tool
- Improve error handling with proper exit code checking

🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
YeonGyu-Kim
2025-12-15 19:02:31 +09:00
parent c2e96f1ffe
commit 03a450131d
4 changed files with 207 additions and 26 deletions

View File

@@ -208,11 +208,9 @@ export function createTodoContinuationEnforcer(ctx: PluginInput): TodoContinuati
const info = props?.info as Record<string, unknown> | undefined
const sessionID = info?.sessionID as string | undefined
log(`[${HOOK_NAME}] message.updated received`, { sessionID, role: info?.role })
if (sessionID && info?.role === "user") {
remindedSessions.delete(sessionID)
log(`[${HOOK_NAME}] Cleared remindedSessions on user message`, { sessionID })
// Cancel pending continuation on user interaction
// Cancel pending continuation on user interaction (real user input)
const timer = pendingTimers.get(sessionID)
if (timer) {
clearTimeout(timer)
@@ -220,6 +218,12 @@ export function createTodoContinuationEnforcer(ctx: PluginInput): TodoContinuati
log(`[${HOOK_NAME}] Cancelled pending timer on user message`, { sessionID })
}
}
// Clear reminded state when assistant responds (allows re-remind on next idle)
if (sessionID && info?.role === "assistant" && remindedSessions.has(sessionID)) {
remindedSessions.delete(sessionID)
log(`[${HOOK_NAME}] Cleared remindedSessions on assistant response`, { sessionID })
}
}
if (event.type === "session.deleted") {