fix(keyword-detector): use mainSessionID for session check instead of unreliable API

The keyword-detector was using ctx.client.session.get() to check parentID for
determining subagent sessions, but this API didn't reliably return parentID.

This caused non-ultrawork keywords (search, analyze) to be injected in subagent
sessions when they should only work in main sessions.

Changed to use getMainSessionID() comparison, consistent with other hooks like
session-notification and todo-continuation-enforcer.

- Replace unreliable parentID API check with mainSessionID comparison
- Add comprehensive test coverage for session filtering behavior
- Remove unnecessary session.get API call
This commit is contained in:
YeonGyu-Kim
2026-01-07 02:16:49 +09:00
parent cd97572d0a
commit b5c1cfb57f
2 changed files with 137 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
import type { PluginInput } from "@opencode-ai/plugin"
import { detectKeywordsWithType, extractPromptText, removeCodeBlocks } from "./detector"
import { log } from "../../shared"
import { getMainSessionID } from "../../features/claude-code-session-state"
export * from "./detector"
export * from "./constants"
@@ -27,29 +28,20 @@ export function createKeywordDetectorHook(ctx: PluginInput) {
return
}
// Check if this is a subagent session (has parent)
// Only ultrawork keywords work in subagent sessions
// Only ultrawork keywords work in non-main sessions
// Other keywords (search, analyze, etc.) only work in main sessions
try {
const sessionInfo = await ctx.client.session.get({ path: { id: input.sessionID } })
const isSubagentSession = !!sessionInfo.data?.parentID
const mainSessionID = getMainSessionID()
const isNonMainSession = mainSessionID && input.sessionID !== mainSessionID
if (isSubagentSession) {
// Filter to only ultrawork keywords in subagent sessions
detectedKeywords = detectedKeywords.filter((k) => k.type === "ultrawork")
if (detectedKeywords.length === 0) {
log(`[keyword-detector] Skipping non-ultrawork keywords in subagent session`, {
sessionID: input.sessionID,
parentID: sessionInfo.data?.parentID,
})
return
}
if (isNonMainSession) {
detectedKeywords = detectedKeywords.filter((k) => k.type === "ultrawork")
if (detectedKeywords.length === 0) {
log(`[keyword-detector] Skipping non-ultrawork keywords in non-main session`, {
sessionID: input.sessionID,
mainSessionID,
})
return
}
} catch (err) {
log(`[keyword-detector] Failed to get session info, proceeding with all keywords`, {
error: err,
sessionID: input.sessionID,
})
}
const hasUltrawork = detectedKeywords.some((k) => k.type === "ultrawork")