diff --git a/src/hooks/keyword-detector/constants.ts b/src/hooks/keyword-detector/constants.ts
new file mode 100644
index 0000000..194a8df
--- /dev/null
+++ b/src/hooks/keyword-detector/constants.ts
@@ -0,0 +1,69 @@
+export const CODE_BLOCK_PATTERN = /```[\s\S]*?```/g
+export const INLINE_CODE_PATTERN = /`[^`]+`/g
+
+export const KEYWORD_DETECTORS: Array<{ pattern: RegExp; message: string }> = [
+ // ULTRAWORK: ulw, ultrawork
+ {
+ pattern: /\b(ultrawork|ulw)\b/i,
+ message: `
+[CODE RED] Maximum precision required. Ultrathink before acting.
+
+YOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.
+TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
+
+## AGENT UTILIZATION PRINCIPLES (by capability, not by name)
+- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS for file patterns, internal implementations, project structure
+- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS for API references, examples, external library docs
+- **Planning & Strategy**: NEVER plan yourself - ALWAYS spawn a dedicated planning agent for work breakdown
+- **High-IQ Reasoning**: Leverage specialized agents for architecture decisions, code review, strategic planning
+- **Frontend/UI Tasks**: Delegate to UI-specialized agents for design and implementation
+
+## EXECUTION RULES
+- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each.
+- **PARALLEL**: Fire independent agent calls simultaneously via background_task - NEVER wait sequentially.
+- **BACKGROUND FIRST**: Use background_task for exploration/research agents (10+ concurrent if needed).
+- **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done.
+- **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths.
+
+## WORKFLOW
+1. Analyze the request and identify required capabilities
+2. Spawn exploration/librarian agents via background_task in PARALLEL (10+ if needed)
+3. Use planning agents to create detailed work breakdown
+4. Execute with continuous verification against original requirements
+
+
+
+---
+
+`,
+ },
+ // SEARCH: EN/KO/JP/CN/VN
+ {
+ pattern:
+ /\b(search|find|locate|lookup|look\s*up|explore|discover|scan|grep|query|browse|detect|trace|seek|track|pinpoint|hunt)\b|where\s+is|show\s+me|list\s+all|검색|찾아|탐색|조회|스캔|서치|뒤져|찾기|어디|추적|탐지|찾아봐|찾아내|보여줘|목록|検索|探して|見つけて|サーチ|探索|スキャン|どこ|発見|捜索|見つけ出す|一覧|搜索|查找|寻找|查询|检索|定位|扫描|发现|在哪里|找出来|列出|tìm kiếm|tra cứu|định vị|quét|phát hiện|truy tìm|tìm ra|ở đâu|liệt kê/i,
+ message: `[search-mode]
+MAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL:
+- explore agents (codebase patterns, file structures, ast-grep)
+- librarian agents (remote repos, official docs, GitHub examples)
+Plus direct tools: Grep, ripgrep (rg), ast-grep (sg)
+NEVER stop at first result - be exhaustive.`,
+ },
+ // ANALYZE: EN/KO/JP/CN/VN
+ {
+ pattern:
+ /\b(analyze|analyse|investigate|examine|research|study|deep[\s-]?dive|inspect|audit|evaluate|assess|review|diagnose|scrutinize|dissect|debug|comprehend|interpret|breakdown|understand)\b|why\s+is|how\s+does|how\s+to|분석|조사|파악|연구|검토|진단|이해|설명|원인|이유|뜯어봐|따져봐|평가|해석|디버깅|디버그|어떻게|왜|살펴|分析|調査|解析|検討|研究|診断|理解|説明|検証|精査|究明|デバッグ|なぜ|どう|仕組み|调查|检查|剖析|深入|诊断|解释|调试|为什么|原理|搞清楚|弄明白|phân tích|điều tra|nghiên cứu|kiểm tra|xem xét|chẩn đoán|giải thích|tìm hiểu|gỡ lỗi|tại sao/i,
+ message: `[analyze-mode]
+DEEP ANALYSIS MODE. Execute in phases:
+
+PHASE 1 - GATHER CONTEXT (10+ agents parallel):
+- 3+ explore agents (codebase structure, patterns, implementations)
+- 3+ librarian agents (official docs, best practices, examples)
+- 2+ general agents (different analytical perspectives)
+
+PHASE 2 - EXPERT CONSULTATION (after Phase 1):
+- 3+ oracle agents in parallel with gathered context
+- Each oracle: different angle (architecture, performance, edge cases)
+
+SYNTHESIZE: Cross-reference findings, identify consensus & contradictions.`,
+ },
+]
diff --git a/src/hooks/ultrawork-mode/detector.ts b/src/hooks/keyword-detector/detector.ts
similarity index 51%
rename from src/hooks/ultrawork-mode/detector.ts
rename to src/hooks/keyword-detector/detector.ts
index 898c480..2f57db2 100644
--- a/src/hooks/ultrawork-mode/detector.ts
+++ b/src/hooks/keyword-detector/detector.ts
@@ -1,33 +1,25 @@
import {
- ULTRAWORK_PATTERNS,
+ KEYWORD_DETECTORS,
CODE_BLOCK_PATTERN,
INLINE_CODE_PATTERN,
} from "./constants"
-/**
- * Remove code blocks and inline code from text.
- * Prevents false positives when keywords appear in code.
- */
export function removeCodeBlocks(text: string): string {
return text.replace(CODE_BLOCK_PATTERN, "").replace(INLINE_CODE_PATTERN, "")
}
-/**
- * Detect ultrawork keywords in text (excluding code blocks).
- */
-export function detectUltraworkKeyword(text: string): boolean {
+export function detectKeywords(text: string): string[] {
const textWithoutCode = removeCodeBlocks(text)
- return ULTRAWORK_PATTERNS.some((pattern) => pattern.test(textWithoutCode))
+ return KEYWORD_DETECTORS.filter(({ pattern }) =>
+ pattern.test(textWithoutCode)
+ ).map(({ message }) => message)
}
-/**
- * Extract text content from message parts.
- */
export function extractPromptText(
parts: Array<{ type: string; text?: string }>
): string {
return parts
.filter((p) => p.type === "text")
.map((p) => p.text || "")
- .join("")
+ .join(" ")
}
diff --git a/src/hooks/keyword-detector/index.ts b/src/hooks/keyword-detector/index.ts
new file mode 100644
index 0000000..9cf1db0
--- /dev/null
+++ b/src/hooks/keyword-detector/index.ts
@@ -0,0 +1,72 @@
+import { detectKeywords, extractPromptText } from "./detector"
+import { log } from "../../shared"
+import { injectHookMessage } from "../../features/hook-message-injector"
+
+export * from "./detector"
+export * from "./constants"
+export * from "./types"
+
+const injectedSessions = new Set()
+
+export function createKeywordDetectorHook() {
+ return {
+ "chat.message": async (
+ input: {
+ sessionID: string
+ agent?: string
+ model?: { providerID: string; modelID: string }
+ messageID?: string
+ },
+ output: {
+ message: Record
+ parts: Array<{ type: string; text?: string; [key: string]: unknown }>
+ }
+ ): Promise => {
+ if (injectedSessions.has(input.sessionID)) {
+ return
+ }
+
+ const promptText = extractPromptText(output.parts)
+ const messages = detectKeywords(promptText)
+
+ if (messages.length === 0) {
+ return
+ }
+
+ log(`Keywords detected: ${messages.length}`, { sessionID: input.sessionID })
+
+ const message = output.message as {
+ agent?: string
+ model?: { modelID?: string; providerID?: string }
+ path?: { cwd?: string; root?: string }
+ tools?: Record
+ }
+
+ const context = messages.join("\n")
+ const success = injectHookMessage(input.sessionID, context, {
+ agent: message.agent,
+ model: message.model,
+ path: message.path,
+ tools: message.tools,
+ })
+
+ if (success) {
+ injectedSessions.add(input.sessionID)
+ log("Keyword context injected", { sessionID: input.sessionID })
+ }
+ },
+
+ event: async ({
+ event,
+ }: {
+ event: { type: string; properties?: unknown }
+ }) => {
+ if (event.type === "session.deleted") {
+ const props = event.properties as { info?: { id?: string } } | undefined
+ if (props?.info?.id) {
+ injectedSessions.delete(props.info.id)
+ }
+ }
+ },
+ }
+}
diff --git a/src/hooks/keyword-detector/types.ts b/src/hooks/keyword-detector/types.ts
new file mode 100644
index 0000000..3a9aa84
--- /dev/null
+++ b/src/hooks/keyword-detector/types.ts
@@ -0,0 +1,4 @@
+export interface KeywordDetectorState {
+ detected: boolean
+ injected: boolean
+}
diff --git a/src/hooks/ultrawork-mode/constants.ts b/src/hooks/ultrawork-mode/constants.ts
deleted file mode 100644
index 4341346..0000000
--- a/src/hooks/ultrawork-mode/constants.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/** Keyword patterns - "ultrawork", "ulw" (case-insensitive, word boundary) */
-export const ULTRAWORK_PATTERNS = [/\bultrawork\b/i, /\bulw\b/i]
-
-/** Code block pattern to exclude from keyword detection */
-export const CODE_BLOCK_PATTERN = /```[\s\S]*?```/g
-
-/** Inline code pattern to exclude */
-export const INLINE_CODE_PATTERN = /`[^`]+`/g
-
-/**
- * ULTRAWORK_CONTEXT - Agent-Agnostic Guidance
- *
- * Key principles:
- * - NO specific agent names (oracle, librarian, etc.)
- * - Only provide guidance based on agent role/capability
- * - Emphasize parallel execution, TODO tracking, delegation
- */
-export const ULTRAWORK_CONTEXT = `
-[CODE RED] Maximum precision required. Ultrathink before acting.
-
-YOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.
-TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
-
-## AGENT UTILIZATION PRINCIPLES (by capability, not by name)
-- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS for file patterns, internal implementations, project structure
-- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS for API references, examples, external library docs
-- **Planning & Strategy**: NEVER plan yourself - ALWAYS spawn a dedicated planning agent for work breakdown
-- **High-IQ Reasoning**: Leverage specialized agents for architecture decisions, code review, strategic planning
-- **Frontend/UI Tasks**: Delegate to UI-specialized agents for design and implementation
-
-## EXECUTION RULES
-- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each.
-- **PARALLEL**: Fire independent agent calls simultaneously via background_task - NEVER wait sequentially.
-- **BACKGROUND FIRST**: Use background_task for exploration/research agents (10+ concurrent if needed).
-- **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done.
-- **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths.
-
-## WORKFLOW
-1. Analyze the request and identify required capabilities
-2. Spawn exploration/librarian agents via background_task in PARALLEL (10+ if needed)
-3. Use planning agents to create detailed work breakdown
-4. Execute with continuous verification against original requirements
-
-
-
----
-
-`
diff --git a/src/hooks/ultrawork-mode/index.ts b/src/hooks/ultrawork-mode/index.ts
deleted file mode 100644
index 58c378c..0000000
--- a/src/hooks/ultrawork-mode/index.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import { detectUltraworkKeyword, extractPromptText } from "./detector"
-import { ULTRAWORK_CONTEXT } from "./constants"
-import type { UltraworkModeState } from "./types"
-import { log } from "../../shared"
-import { injectHookMessage } from "../../features/hook-message-injector"
-
-export * from "./detector"
-export * from "./constants"
-export * from "./types"
-
-const ultraworkModeState = new Map()
-
-export function clearUltraworkModeState(sessionID: string): void {
- ultraworkModeState.delete(sessionID)
-}
-
-export function createUltraworkModeHook() {
- return {
- /**
- * chat.message hook - detect ultrawork/ulw keywords, inject context via history
- *
- * Execution timing: AFTER claudeCodeHooks["chat.message"]
- * Behavior:
- * 1. Extract text from user prompt
- * 2. Detect ultrawork/ulw keywords (excluding code blocks)
- * 3. If detected, inject ULTRAWORK_CONTEXT via injectHookMessage (history injection)
- */
- "chat.message": async (
- input: {
- sessionID: string
- agent?: string
- model?: { providerID: string; modelID: string }
- messageID?: string
- },
- output: {
- message: Record
- parts: Array<{ type: string; text?: string; [key: string]: unknown }>
- }
- ): Promise => {
- const state: UltraworkModeState = {
- detected: false,
- injected: false,
- }
-
- const promptText = extractPromptText(output.parts)
-
- if (!detectUltraworkKeyword(promptText)) {
- ultraworkModeState.set(input.sessionID, state)
- return
- }
-
- state.detected = true
- log("Ultrawork keyword detected", { sessionID: input.sessionID })
-
- const message = output.message as {
- agent?: string
- model?: { modelID?: string; providerID?: string }
- path?: { cwd?: string; root?: string }
- tools?: Record
- }
-
- const success = injectHookMessage(input.sessionID, ULTRAWORK_CONTEXT, {
- agent: message.agent,
- model: message.model,
- path: message.path,
- tools: message.tools,
- })
-
- if (success) {
- state.injected = true
- log("Ultrawork context injected via history", { sessionID: input.sessionID })
- } else {
- log("Ultrawork context injection failed", { sessionID: input.sessionID })
- }
-
- ultraworkModeState.set(input.sessionID, state)
- },
-
- /**
- * event hook - cleanup session state on deletion
- */
- event: async ({
- event,
- }: {
- event: { type: string; properties?: unknown }
- }) => {
- if (event.type === "session.deleted") {
- const props = event.properties as
- | { info?: { id?: string } }
- | undefined
- if (props?.info?.id) {
- ultraworkModeState.delete(props.info.id)
- }
- }
- },
- }
-}
diff --git a/src/hooks/ultrawork-mode/types.ts b/src/hooks/ultrawork-mode/types.ts
deleted file mode 100644
index 6c92ace..0000000
--- a/src/hooks/ultrawork-mode/types.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export interface UltraworkModeState {
- /** Whether ultrawork keyword was detected */
- detected: boolean
- /** Whether context was injected */
- injected: boolean
-}
-
-export interface ModelRef {
- providerID: string
- modelID: string
-}
-
-export interface MessageWithModel {
- model?: ModelRef
-}
-
-export interface UltraworkModeInput {
- parts: Array<{ type: string; text?: string }>
- message: MessageWithModel
-}