Skip to content

Commit f57aa39

Browse files
committed
feat(hooks): add ultrawork-mode hook for automatic agent orchestration guidance
When "ultrawork" or "ulw" keyword is detected in user prompt: - Injects ULTRAWORK_CONTEXT with agent-agnostic guidance - Executes AFTER CC hooks (UserPromptSubmit etc.) - Follows existing hook pattern (think-mode style) Key features: - Agent orchestration principles (by capability, not name) - Parallel execution rules - TODO tracking enforcement - Delegation guidance Closes #31 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
1 parent 41a318d commit f57aa39

File tree

7 files changed

+193
-0
lines changed

7 files changed

+193
-0
lines changed

src/config/schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const HookNameSchema = z.enum([
3939
"rules-injector",
4040
"background-notification",
4141
"auto-update-checker",
42+
"ultrawork-mode",
4243
])
4344

4445
export const AgentOverrideConfigSchema = z.object({

src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ export { createClaudeCodeHooksHook } from "./claude-code-hooks";
1313
export { createRulesInjectorHook } from "./rules-injector";
1414
export { createBackgroundNotificationHook } from "./background-notification"
1515
export { createAutoUpdateCheckerHook } from "./auto-update-checker";
16+
export { createUltraworkModeHook } from "./ultrawork-mode";
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/** Keyword patterns - "ultrawork", "ulw" (case-insensitive, word boundary) */
2+
export const ULTRAWORK_PATTERNS = [/\bultrawork\b/i, /\bulw\b/i]
3+
4+
/** Code block pattern to exclude from keyword detection */
5+
export const CODE_BLOCK_PATTERN = /```[\s\S]*?```/g
6+
7+
/** Inline code pattern to exclude */
8+
export const INLINE_CODE_PATTERN = /`[^`]+`/g
9+
10+
/**
11+
* ULTRAWORK_CONTEXT - Agent-Agnostic Guidance
12+
*
13+
* Key principles:
14+
* - NO specific agent names (oracle, librarian, etc.)
15+
* - Only provide guidance based on agent role/capability
16+
* - Emphasize parallel execution, TODO tracking, delegation
17+
*/
18+
export const ULTRAWORK_CONTEXT = `<ultrawork-mode>
19+
[CODE RED] Maximum precision required. Ultrathink before acting.
20+
21+
YOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.
22+
TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
23+
24+
## AGENT UTILIZATION PRINCIPLES (by capability, not by name)
25+
- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS for file patterns, internal implementations, project structure
26+
- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS for API references, examples, external library docs
27+
- **Planning & Strategy**: NEVER plan yourself - ALWAYS spawn a dedicated planning agent for work breakdown
28+
- **High-IQ Reasoning**: Leverage specialized agents for architecture decisions, code review, strategic planning
29+
- **Frontend/UI Tasks**: Delegate to UI-specialized agents for design and implementation
30+
31+
## EXECUTION RULES
32+
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each.
33+
- **PARALLEL**: Fire independent agent calls simultaneously via background_task - NEVER wait sequentially.
34+
- **BACKGROUND FIRST**: Use background_task for exploration/research agents (10+ concurrent if needed).
35+
- **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done.
36+
- **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths.
37+
38+
## WORKFLOW
39+
1. Analyze the request and identify required capabilities
40+
2. Spawn exploration/librarian agents via background_task in PARALLEL (10+ if needed)
41+
3. Use planning agents to create detailed work breakdown
42+
4. Execute with continuous verification against original requirements
43+
44+
</ultrawork-mode>
45+
46+
---
47+
48+
`
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {
2+
ULTRAWORK_PATTERNS,
3+
CODE_BLOCK_PATTERN,
4+
INLINE_CODE_PATTERN,
5+
} from "./constants"
6+
7+
/**
8+
* Remove code blocks and inline code from text.
9+
* Prevents false positives when keywords appear in code.
10+
*/
11+
export function removeCodeBlocks(text: string): string {
12+
return text.replace(CODE_BLOCK_PATTERN, "").replace(INLINE_CODE_PATTERN, "")
13+
}
14+
15+
/**
16+
* Detect ultrawork keywords in text (excluding code blocks).
17+
*/
18+
export function detectUltraworkKeyword(text: string): boolean {
19+
const textWithoutCode = removeCodeBlocks(text)
20+
return ULTRAWORK_PATTERNS.some((pattern) => pattern.test(textWithoutCode))
21+
}
22+
23+
/**
24+
* Extract text content from message parts.
25+
*/
26+
export function extractPromptText(
27+
parts: Array<{ type: string; text?: string }>
28+
): string {
29+
return parts
30+
.filter((p) => p.type === "text")
31+
.map((p) => p.text || "")
32+
.join("")
33+
}

src/hooks/ultrawork-mode/index.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { detectUltraworkKeyword, extractPromptText } from "./detector"
2+
import { ULTRAWORK_CONTEXT } from "./constants"
3+
import type { UltraworkModeState } from "./types"
4+
import { log } from "../../shared"
5+
6+
export * from "./detector"
7+
export * from "./constants"
8+
export * from "./types"
9+
10+
const ultraworkModeState = new Map<string, UltraworkModeState>()
11+
12+
export function clearUltraworkModeState(sessionID: string): void {
13+
ultraworkModeState.delete(sessionID)
14+
}
15+
16+
export function createUltraworkModeHook() {
17+
return {
18+
/**
19+
* chat.message hook - detect ultrawork/ulw keywords, inject context
20+
*
21+
* Execution timing: AFTER claudeCodeHooks["chat.message"]
22+
* Behavior:
23+
* 1. Extract text from user prompt
24+
* 2. Detect ultrawork/ulw keywords (excluding code blocks)
25+
* 3. If detected, prepend ULTRAWORK_CONTEXT to first text part
26+
*/
27+
"chat.message": async (
28+
input: {
29+
sessionID: string
30+
agent?: string
31+
model?: { providerID: string; modelID: string }
32+
messageID?: string
33+
},
34+
output: {
35+
message: Record<string, unknown>
36+
parts: Array<{ type: string; text?: string; [key: string]: unknown }>
37+
}
38+
): Promise<void> => {
39+
const state: UltraworkModeState = {
40+
detected: false,
41+
injected: false,
42+
}
43+
44+
const promptText = extractPromptText(output.parts)
45+
46+
if (!detectUltraworkKeyword(promptText)) {
47+
ultraworkModeState.set(input.sessionID, state)
48+
return
49+
}
50+
51+
state.detected = true
52+
log("Ultrawork keyword detected", { sessionID: input.sessionID })
53+
54+
const parts = output.parts as Array<{ type: string; text?: string }>
55+
const idx = parts.findIndex((p) => p.type === "text" && p.text)
56+
57+
if (idx >= 0) {
58+
parts[idx].text = `${ULTRAWORK_CONTEXT}${parts[idx].text ?? ""}`
59+
state.injected = true
60+
log("Ultrawork context injected", { sessionID: input.sessionID })
61+
}
62+
63+
ultraworkModeState.set(input.sessionID, state)
64+
},
65+
66+
/**
67+
* event hook - cleanup session state on deletion
68+
*/
69+
event: async ({
70+
event,
71+
}: {
72+
event: { type: string; properties?: unknown }
73+
}) => {
74+
if (event.type === "session.deleted") {
75+
const props = event.properties as
76+
| { info?: { id?: string } }
77+
| undefined
78+
if (props?.info?.id) {
79+
ultraworkModeState.delete(props.info.id)
80+
}
81+
}
82+
},
83+
}
84+
}

src/hooks/ultrawork-mode/types.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export interface UltraworkModeState {
2+
/** Whether ultrawork keyword was detected */
3+
detected: boolean
4+
/** Whether context was injected */
5+
injected: boolean
6+
}
7+
8+
export interface ModelRef {
9+
providerID: string
10+
modelID: string
11+
}
12+
13+
export interface MessageWithModel {
14+
model?: ModelRef
15+
}
16+
17+
export interface UltraworkModeInput {
18+
parts: Array<{ type: string; text?: string }>
19+
message: MessageWithModel
20+
}

src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
createRulesInjectorHook,
1717
createBackgroundNotificationHook,
1818
createAutoUpdateCheckerHook,
19+
createUltraworkModeHook,
1920
} from "./hooks";
2021
import { createGoogleAntigravityAuthPlugin } from "./auth/antigravity";
2122
import {
@@ -203,6 +204,9 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
203204
const autoUpdateChecker = isHookEnabled("auto-update-checker")
204205
? createAutoUpdateCheckerHook(ctx)
205206
: null;
207+
const ultraworkMode = isHookEnabled("ultrawork-mode")
208+
? createUltraworkModeHook()
209+
: null;
206210

207211
updateTerminalTitle({ sessionId: "main" });
208212

@@ -230,6 +234,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
230234

231235
"chat.message": async (input, output) => {
232236
await claudeCodeHooks["chat.message"]?.(input, output);
237+
await ultraworkMode?.["chat.message"]?.(input, output);
233238
},
234239

235240
config: async (config) => {
@@ -304,6 +309,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
304309
await rulesInjector?.event(input);
305310
await thinkMode?.event(input);
306311
await anthropicAutoCompact?.event(input);
312+
await ultraworkMode?.event(input);
307313

308314
const { event } = input;
309315
const props = event.properties as Record<string, unknown> | undefined;

0 commit comments

Comments
 (0)