zenox 1.1.3 → 1.2.1
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/README.md +41 -3
- package/dist/background/manager.d.ts +3 -0
- package/dist/features/task-toast/index.d.ts +1 -0
- package/dist/features/task-toast/manager.d.ts +38 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/keyword-detector/contexts.d.ts +18 -0
- package/dist/hooks/keyword-detector/index.d.ts +28 -0
- package/dist/index.js +345 -4
- package/dist/orchestration/prompt.d.ts +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://www.npmjs.com/package/zenox"><img src="https://img.shields.io/npm/v/zenox.svg?style=flat-square" alt="npm version" /></a>
|
|
13
|
-
<!-- <a href="https://www.npmjs.com/package/zenox"><img src="https://img.shields.io/npm/dm/zenox.svg?style=flat-square" alt="npm downloads" /></a> -->
|
|
14
13
|
<a href="https://github.com/CYBERBOYAYUSH/zenox/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="license" /></a>
|
|
15
14
|
</p>
|
|
16
15
|
|
|
@@ -41,7 +40,7 @@ That's it. Restart OpenCode and the agents are ready.
|
|
|
41
40
|
|
|
42
41
|
| Agent | What it does | Default Model |
|
|
43
42
|
|-------|-------------|---------------|
|
|
44
|
-
| **Explorer** | Codebase
|
|
43
|
+
| **Explorer** | Codebase grep, file discovery, pattern matching | `claude-haiku-4-5` |
|
|
45
44
|
| **Librarian** | Library research, docs lookup, GitHub examples | `claude-sonnet-4-5` |
|
|
46
45
|
| **Oracle** | Architecture decisions, debugging strategy, code review | `gpt-5.2` |
|
|
47
46
|
| **UI Planner** | Frontend design, CSS, animations, visual polish | `gemini-3-pro-high` |
|
|
@@ -64,6 +63,36 @@ You: "Make this dashboard look better"
|
|
|
64
63
|
→ UI Planner redesigns with proper aesthetics
|
|
65
64
|
```
|
|
66
65
|
|
|
66
|
+
## Keyword Triggers
|
|
67
|
+
|
|
68
|
+
Include these magic words in your prompt to unlock special modes:
|
|
69
|
+
|
|
70
|
+
| Keyword | What it does |
|
|
71
|
+
|---------|--------------|
|
|
72
|
+
| `ultrawork` or `ulw` | Maximum multi-agent coordination — fires parallel background agents, sets max precision |
|
|
73
|
+
| `deep research` | Comprehensive exploration — fires 3-4 background agents (explorer + librarian) |
|
|
74
|
+
| `explore codebase` | Codebase mapping — multiple explorers search in parallel |
|
|
75
|
+
|
|
76
|
+
### Examples
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
You: "ultrawork - add authentication to this app"
|
|
80
|
+
→ ⚡ Ultrawork Mode activated
|
|
81
|
+
→ Fires explorer + librarian in parallel
|
|
82
|
+
→ Maximum precision engaged
|
|
83
|
+
|
|
84
|
+
You: "deep research how this project handles errors"
|
|
85
|
+
→ 🔬 Deep Research Mode activated
|
|
86
|
+
→ Fires multiple explorers + librarians
|
|
87
|
+
→ Waits for comprehensive results before proceeding
|
|
88
|
+
|
|
89
|
+
You: "explore codebase for payment logic"
|
|
90
|
+
→ 🔍 Explore Mode activated
|
|
91
|
+
→ Multiple explorers search patterns, implementations, tests
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
You'll see a toast notification when these modes activate.
|
|
95
|
+
|
|
67
96
|
## Background Tasks
|
|
68
97
|
|
|
69
98
|
Need comprehensive research? Fire multiple agents in parallel:
|
|
@@ -76,6 +105,15 @@ background_task(agent="librarian", description="JWT best practices", prompt="...
|
|
|
76
105
|
// You're notified when all tasks complete
|
|
77
106
|
```
|
|
78
107
|
|
|
108
|
+
### Toast Notifications
|
|
109
|
+
|
|
110
|
+
Zenox shows toast notifications for background task events:
|
|
111
|
+
|
|
112
|
+
- ⚡ **Task Launched** — Shows task description and agent
|
|
113
|
+
- ✅ **Task Completed** — Shows duration and remaining count
|
|
114
|
+
- 🎉 **All Complete** — Shows summary of all finished tasks
|
|
115
|
+
- ❌ **Task Failed** — Shows error message
|
|
116
|
+
|
|
79
117
|
## Configuration
|
|
80
118
|
|
|
81
119
|
### Custom Models
|
|
@@ -133,7 +171,7 @@ Zenox checks for updates on startup. When a new version drops:
|
|
|
133
171
|
2. Bun cache is invalidated
|
|
134
172
|
3. Restart to get the update
|
|
135
173
|
|
|
136
|
-
Pin a version to disable: `"zenox@1.0
|
|
174
|
+
Pin a version to disable: `"zenox@1.2.0"` in your plugins array.
|
|
137
175
|
|
|
138
176
|
## Credits
|
|
139
177
|
|
|
@@ -9,9 +9,12 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
11
11
|
import type { BackgroundTask, LaunchInput, CompletionNotification } from "./types";
|
|
12
|
+
import type { TaskToastManager } from "../features/task-toast";
|
|
12
13
|
export declare class BackgroundManager {
|
|
13
14
|
private tasks;
|
|
14
15
|
private mainSessionID;
|
|
16
|
+
private toastManager;
|
|
17
|
+
setToastManager(manager: TaskToastManager): void;
|
|
15
18
|
setMainSession(sessionID: string): void;
|
|
16
19
|
getMainSession(): string | undefined;
|
|
17
20
|
private generateTaskId;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TaskToastManager } from "./manager";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Toast Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages toast notifications for background tasks:
|
|
5
|
+
* - Shows toast when task is launched
|
|
6
|
+
* - Shows toast when task completes
|
|
7
|
+
* - Shows summary toast when all tasks complete
|
|
8
|
+
*/
|
|
9
|
+
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
10
|
+
interface TrackedTask {
|
|
11
|
+
id: string;
|
|
12
|
+
description: string;
|
|
13
|
+
agent: string;
|
|
14
|
+
startedAt: Date;
|
|
15
|
+
status: "running" | "completed" | "failed";
|
|
16
|
+
}
|
|
17
|
+
export declare class TaskToastManager {
|
|
18
|
+
private tasks;
|
|
19
|
+
private client;
|
|
20
|
+
constructor(client: OpencodeClient);
|
|
21
|
+
showLaunchToast(task: {
|
|
22
|
+
id: string;
|
|
23
|
+
description: string;
|
|
24
|
+
agent: string;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
showCompletionToast(taskId: string): Promise<void>;
|
|
27
|
+
showFailureToast(taskId: string, error?: string): Promise<void>;
|
|
28
|
+
private showAllCompleteToast;
|
|
29
|
+
private getRunningCount;
|
|
30
|
+
private clearCompleted;
|
|
31
|
+
trackTask(task: {
|
|
32
|
+
id: string;
|
|
33
|
+
description: string;
|
|
34
|
+
agent: string;
|
|
35
|
+
}): void;
|
|
36
|
+
getTask(taskId: string): TrackedTask | undefined;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context strings injected when keywords are detected.
|
|
3
|
+
* These provide mode-specific guidance to the agent.
|
|
4
|
+
*/
|
|
5
|
+
export declare const ULTRAWORK_CONTEXT = "<ultrawork-mode>\nULTRAWORK MODE ACTIVE - Maximum multi-agent coordination engaged.\n\n**Mandatory behaviors**:\n1. Fire explore + librarian in PARALLEL BACKGROUND for ANY research task\n2. Use pre-delegation reasoning before EVERY delegation\n3. Continue productive work while background agents run (never idle)\n4. Consult oracle for architectural decisions before implementing\n5. Verify ALL delegated work before marking tasks complete\n\n**Pre-delegation reasoning** (do this before every Task/background_task):\n- What type of work? (search \u2192 background, decision \u2192 sync, visual \u2192 sync)\n- Can I continue working while this runs? If yes \u2192 background_task\n- Do I need this answer RIGHT NOW to proceed? If no \u2192 background_task\n\n**Parallel research pattern**:\n```\n// Fire research immediately\nbackground_task(agent=\"explorer\", description=\"Find patterns\", prompt=\"...\")\nbackground_task(agent=\"librarian\", description=\"Find best practices\", prompt=\"...\")\n\n// Continue working while they run:\n// - Plan implementation approach\n// - Read files you know about\n// - Identify edge cases\n\n// When notified \u2192 retrieve and synthesize\nbackground_output(task_id=\"bg_xxx\")\n```\n</ultrawork-mode>";
|
|
6
|
+
export declare const DEEP_RESEARCH_CONTEXT = "<deep-research-mode>\nDEEP RESEARCH MODE - Comprehensive exploration requested.\n\n**Required actions**:\n1. Fire at least 2-3 parallel background agents before proceeding\n2. Search BOTH internal (explorer) AND external (librarian) sources\n3. Explore multiple angles: implementations, tests, patterns, docs\n4. DO NOT proceed until you have comprehensive context\n5. Synthesize all findings before making decisions\n\n**Research pattern**:\n```\n// Fire comprehensive research\nbackground_task(agent=\"explorer\", description=\"Find implementations\", prompt=\"...\")\nbackground_task(agent=\"explorer\", description=\"Find related tests\", prompt=\"...\")\nbackground_task(agent=\"librarian\", description=\"Find official docs\", prompt=\"...\")\nbackground_task(agent=\"librarian\", description=\"Find OSS examples\", prompt=\"...\")\n\n// Wait for ALL results before proceeding\n// When notified \u2192 retrieve, synthesize, then act\n```\n</deep-research-mode>";
|
|
7
|
+
export declare const EXPLORE_CONTEXT = "<explore-mode>\nEXPLORE MODE - Codebase exploration active.\n\n**Required actions**:\n1. Fire multiple explorer agents in background for parallel search\n2. Search for: patterns, implementations, tests, related code\n3. Map out the relevant code landscape before modifying\n4. Look for existing conventions and follow them\n\n**Exploration pattern**:\n```\n// Fire multiple explorers in parallel\nbackground_task(agent=\"explorer\", description=\"Find main implementation\", prompt=\"...\")\nbackground_task(agent=\"explorer\", description=\"Find related tests\", prompt=\"...\")\nbackground_task(agent=\"explorer\", description=\"Find usage examples\", prompt=\"...\")\n\n// Continue analyzing what you know while they search\n```\n</explore-mode>";
|
|
8
|
+
export type KeywordType = "ultrawork" | "deep-research" | "explore";
|
|
9
|
+
export interface KeywordConfig {
|
|
10
|
+
type: KeywordType;
|
|
11
|
+
pattern: RegExp;
|
|
12
|
+
context: string;
|
|
13
|
+
toast: {
|
|
14
|
+
title: string;
|
|
15
|
+
message: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export declare const KEYWORD_CONFIGS: KeywordConfig[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyword Detector Hook
|
|
3
|
+
*
|
|
4
|
+
* Detects special keywords in user messages and:
|
|
5
|
+
* 1. Injects mode-specific context into the message
|
|
6
|
+
* 2. Sets message variant to "max" for higher precision (ultrawork only)
|
|
7
|
+
* 3. Shows toast notification for user feedback
|
|
8
|
+
*
|
|
9
|
+
* Uses the "chat.message" hook which fires when user submits a message.
|
|
10
|
+
*/
|
|
11
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
12
|
+
interface MessagePart {
|
|
13
|
+
type: string;
|
|
14
|
+
text?: string;
|
|
15
|
+
}
|
|
16
|
+
interface ChatMessageOutput {
|
|
17
|
+
parts: MessagePart[];
|
|
18
|
+
message: {
|
|
19
|
+
variant?: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare function createKeywordDetectorHook(ctx: PluginInput): {
|
|
23
|
+
"chat.message": (input: {
|
|
24
|
+
sessionID: string;
|
|
25
|
+
agent?: string;
|
|
26
|
+
}, output: ChatMessageOutput) => Promise<void>;
|
|
27
|
+
};
|
|
28
|
+
export { KEYWORD_CONFIGS, type KeywordType, type KeywordConfig } from "./contexts";
|
package/dist/index.js
CHANGED
|
@@ -548,10 +548,21 @@ You have specialized subagents. Use the **Task tool** to delegate work proactive
|
|
|
548
548
|
|
|
549
549
|
| Agent | Use For | subagent_type |
|
|
550
550
|
|-------|---------|---------------|
|
|
551
|
-
| **Explorer** | Codebase
|
|
552
|
-
| **Librarian** | External docs,
|
|
553
|
-
| **Oracle** |
|
|
554
|
-
| **UI Planner** |
|
|
551
|
+
| **Explorer** | Codebase grep - fast pattern matching, "Where is X?" | \`explorer\` |
|
|
552
|
+
| **Librarian** | External grep - docs, GitHub, OSS examples | \`librarian\` |
|
|
553
|
+
| **Oracle** | Strategic advisor - architecture, debugging, decisions | \`oracle\` |
|
|
554
|
+
| **UI Planner** | Designer-developer - visual design, CSS, animations | \`ui-planner\` |
|
|
555
|
+
|
|
556
|
+
### Quick Rule: Background vs Synchronous
|
|
557
|
+
|
|
558
|
+
| Agent | Default Execution | Why |
|
|
559
|
+
|-------|-------------------|-----|
|
|
560
|
+
| Explorer | \`background_task\` | It's codebase grep - fire and continue |
|
|
561
|
+
| Librarian | \`background_task\` | It's external grep - fire and continue |
|
|
562
|
+
| Oracle | \`Task\` (sync) | Need strategic answer before proceeding |
|
|
563
|
+
| UI Planner | \`Task\` (sync) | Implements changes, needs write access |
|
|
564
|
+
|
|
565
|
+
**Mental Model**: Explorer & Librarian = **grep commands**. You don't wait for grep, you fire it and continue thinking.
|
|
555
566
|
|
|
556
567
|
### When to Delegate (Fire Immediately)
|
|
557
568
|
|
|
@@ -699,6 +710,39 @@ background_output(task_id="bg_ghi789")
|
|
|
699
710
|
- **Background** = Use when researching multiple angles independently
|
|
700
711
|
|
|
701
712
|
**Both tools coexist - choose based on whether tasks are dependent or independent.**
|
|
713
|
+
|
|
714
|
+
### The Parallel Research Pattern
|
|
715
|
+
|
|
716
|
+
For complex tasks, fire research first, then continue working:
|
|
717
|
+
|
|
718
|
+
\`\`\`
|
|
719
|
+
// 1. FIRE parallel research (don't wait!)
|
|
720
|
+
background_task(agent="explorer", description="Find existing patterns", prompt="...")
|
|
721
|
+
background_task(agent="librarian", description="Find best practices", prompt="...")
|
|
722
|
+
|
|
723
|
+
// 2. CONTINUE productive work while they run:
|
|
724
|
+
// - Plan your implementation approach
|
|
725
|
+
// - Read files you already know about
|
|
726
|
+
// - Identify edge cases and questions
|
|
727
|
+
|
|
728
|
+
// 3. When notified \u2192 RETRIEVE and synthesize
|
|
729
|
+
background_output(task_id="bg_xxx")
|
|
730
|
+
background_output(task_id="bg_yyy")
|
|
731
|
+
\`\`\`
|
|
732
|
+
|
|
733
|
+
**Anti-pattern**: Firing background tasks then doing nothing. Always continue productive work!
|
|
734
|
+
|
|
735
|
+
---
|
|
736
|
+
|
|
737
|
+
## Keyword Triggers (Power User)
|
|
738
|
+
|
|
739
|
+
Include these keywords in your prompt to unlock special modes:
|
|
740
|
+
|
|
741
|
+
| Keyword | Effect |
|
|
742
|
+
|---------|--------|
|
|
743
|
+
| \`ultrawork\` or \`ulw\` | Maximum multi-agent coordination - aggressive parallel research |
|
|
744
|
+
| \`deep research\` | Comprehensive exploration - fires 3-4 background agents |
|
|
745
|
+
| \`explore codebase\` | Codebase mapping - multiple explorers in parallel |
|
|
702
746
|
`;
|
|
703
747
|
|
|
704
748
|
// node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
@@ -4801,6 +4845,10 @@ function createBuiltinMcps(disabledMcps = []) {
|
|
|
4801
4845
|
class BackgroundManager {
|
|
4802
4846
|
tasks = new Map;
|
|
4803
4847
|
mainSessionID;
|
|
4848
|
+
toastManager;
|
|
4849
|
+
setToastManager(manager) {
|
|
4850
|
+
this.toastManager = manager;
|
|
4851
|
+
}
|
|
4804
4852
|
setMainSession(sessionID) {
|
|
4805
4853
|
this.mainSessionID = sessionID;
|
|
4806
4854
|
}
|
|
@@ -4834,6 +4882,13 @@ class BackgroundManager {
|
|
|
4834
4882
|
startedAt: new Date
|
|
4835
4883
|
};
|
|
4836
4884
|
this.tasks.set(task.id, task);
|
|
4885
|
+
if (this.toastManager) {
|
|
4886
|
+
this.toastManager.showLaunchToast({
|
|
4887
|
+
id: task.id,
|
|
4888
|
+
description: task.description,
|
|
4889
|
+
agent: task.agent
|
|
4890
|
+
}).catch(() => {});
|
|
4891
|
+
}
|
|
4837
4892
|
client.session.prompt({
|
|
4838
4893
|
path: { id: sessionID },
|
|
4839
4894
|
body: {
|
|
@@ -4847,6 +4902,9 @@ class BackgroundManager {
|
|
|
4847
4902
|
existingTask.status = "failed";
|
|
4848
4903
|
existingTask.error = err.message ?? "Unknown error";
|
|
4849
4904
|
existingTask.completedAt = new Date;
|
|
4905
|
+
if (this.toastManager) {
|
|
4906
|
+
this.toastManager.showFailureToast(task.id, existingTask.error).catch(() => {});
|
|
4907
|
+
}
|
|
4850
4908
|
}
|
|
4851
4909
|
});
|
|
4852
4910
|
return task;
|
|
@@ -4919,6 +4977,9 @@ class BackgroundManager {
|
|
|
4919
4977
|
}
|
|
4920
4978
|
task.status = "completed";
|
|
4921
4979
|
task.completedAt = new Date;
|
|
4980
|
+
if (this.toastManager) {
|
|
4981
|
+
this.toastManager.showCompletionToast(task.id).catch(() => {});
|
|
4982
|
+
}
|
|
4922
4983
|
return this.getCompletionStatus();
|
|
4923
4984
|
}
|
|
4924
4985
|
getCompletionStatus() {
|
|
@@ -17480,14 +17541,291 @@ async function showVersionToast(ctx, version2) {
|
|
|
17480
17541
|
}
|
|
17481
17542
|
}).catch(() => {});
|
|
17482
17543
|
}
|
|
17544
|
+
// src/hooks/keyword-detector/contexts.ts
|
|
17545
|
+
var ULTRAWORK_CONTEXT = `<ultrawork-mode>
|
|
17546
|
+
ULTRAWORK MODE ACTIVE - Maximum multi-agent coordination engaged.
|
|
17547
|
+
|
|
17548
|
+
**Mandatory behaviors**:
|
|
17549
|
+
1. Fire explore + librarian in PARALLEL BACKGROUND for ANY research task
|
|
17550
|
+
2. Use pre-delegation reasoning before EVERY delegation
|
|
17551
|
+
3. Continue productive work while background agents run (never idle)
|
|
17552
|
+
4. Consult oracle for architectural decisions before implementing
|
|
17553
|
+
5. Verify ALL delegated work before marking tasks complete
|
|
17554
|
+
|
|
17555
|
+
**Pre-delegation reasoning** (do this before every Task/background_task):
|
|
17556
|
+
- What type of work? (search \u2192 background, decision \u2192 sync, visual \u2192 sync)
|
|
17557
|
+
- Can I continue working while this runs? If yes \u2192 background_task
|
|
17558
|
+
- Do I need this answer RIGHT NOW to proceed? If no \u2192 background_task
|
|
17559
|
+
|
|
17560
|
+
**Parallel research pattern**:
|
|
17561
|
+
\`\`\`
|
|
17562
|
+
// Fire research immediately
|
|
17563
|
+
background_task(agent="explorer", description="Find patterns", prompt="...")
|
|
17564
|
+
background_task(agent="librarian", description="Find best practices", prompt="...")
|
|
17565
|
+
|
|
17566
|
+
// Continue working while they run:
|
|
17567
|
+
// - Plan implementation approach
|
|
17568
|
+
// - Read files you know about
|
|
17569
|
+
// - Identify edge cases
|
|
17570
|
+
|
|
17571
|
+
// When notified \u2192 retrieve and synthesize
|
|
17572
|
+
background_output(task_id="bg_xxx")
|
|
17573
|
+
\`\`\`
|
|
17574
|
+
</ultrawork-mode>`;
|
|
17575
|
+
var DEEP_RESEARCH_CONTEXT = `<deep-research-mode>
|
|
17576
|
+
DEEP RESEARCH MODE - Comprehensive exploration requested.
|
|
17577
|
+
|
|
17578
|
+
**Required actions**:
|
|
17579
|
+
1. Fire at least 2-3 parallel background agents before proceeding
|
|
17580
|
+
2. Search BOTH internal (explorer) AND external (librarian) sources
|
|
17581
|
+
3. Explore multiple angles: implementations, tests, patterns, docs
|
|
17582
|
+
4. DO NOT proceed until you have comprehensive context
|
|
17583
|
+
5. Synthesize all findings before making decisions
|
|
17584
|
+
|
|
17585
|
+
**Research pattern**:
|
|
17586
|
+
\`\`\`
|
|
17587
|
+
// Fire comprehensive research
|
|
17588
|
+
background_task(agent="explorer", description="Find implementations", prompt="...")
|
|
17589
|
+
background_task(agent="explorer", description="Find related tests", prompt="...")
|
|
17590
|
+
background_task(agent="librarian", description="Find official docs", prompt="...")
|
|
17591
|
+
background_task(agent="librarian", description="Find OSS examples", prompt="...")
|
|
17592
|
+
|
|
17593
|
+
// Wait for ALL results before proceeding
|
|
17594
|
+
// When notified \u2192 retrieve, synthesize, then act
|
|
17595
|
+
\`\`\`
|
|
17596
|
+
</deep-research-mode>`;
|
|
17597
|
+
var EXPLORE_CONTEXT = `<explore-mode>
|
|
17598
|
+
EXPLORE MODE - Codebase exploration active.
|
|
17599
|
+
|
|
17600
|
+
**Required actions**:
|
|
17601
|
+
1. Fire multiple explorer agents in background for parallel search
|
|
17602
|
+
2. Search for: patterns, implementations, tests, related code
|
|
17603
|
+
3. Map out the relevant code landscape before modifying
|
|
17604
|
+
4. Look for existing conventions and follow them
|
|
17605
|
+
|
|
17606
|
+
**Exploration pattern**:
|
|
17607
|
+
\`\`\`
|
|
17608
|
+
// Fire multiple explorers in parallel
|
|
17609
|
+
background_task(agent="explorer", description="Find main implementation", prompt="...")
|
|
17610
|
+
background_task(agent="explorer", description="Find related tests", prompt="...")
|
|
17611
|
+
background_task(agent="explorer", description="Find usage examples", prompt="...")
|
|
17612
|
+
|
|
17613
|
+
// Continue analyzing what you know while they search
|
|
17614
|
+
\`\`\`
|
|
17615
|
+
</explore-mode>`;
|
|
17616
|
+
var KEYWORD_CONFIGS = [
|
|
17617
|
+
{
|
|
17618
|
+
type: "ultrawork",
|
|
17619
|
+
pattern: /\b(ultrawork|ulw)\b/i,
|
|
17620
|
+
context: ULTRAWORK_CONTEXT,
|
|
17621
|
+
toast: {
|
|
17622
|
+
title: "\u26A1 Ultrawork Mode",
|
|
17623
|
+
message: "Maximum precision engaged. Multi-agent coordination active."
|
|
17624
|
+
}
|
|
17625
|
+
},
|
|
17626
|
+
{
|
|
17627
|
+
type: "deep-research",
|
|
17628
|
+
pattern: /\b(deep\s*research|research\s*deep(ly)?)\b/i,
|
|
17629
|
+
context: DEEP_RESEARCH_CONTEXT,
|
|
17630
|
+
toast: {
|
|
17631
|
+
title: "\uD83D\uDD2C Deep Research Mode",
|
|
17632
|
+
message: "Comprehensive exploration enabled. Background agents will fire."
|
|
17633
|
+
}
|
|
17634
|
+
},
|
|
17635
|
+
{
|
|
17636
|
+
type: "explore",
|
|
17637
|
+
pattern: /\b(explore\s*(the\s*)?(codebase|code|project))\b/i,
|
|
17638
|
+
context: EXPLORE_CONTEXT,
|
|
17639
|
+
toast: {
|
|
17640
|
+
title: "\uD83D\uDD0D Explore Mode",
|
|
17641
|
+
message: "Codebase exploration active. Multiple explorers will run."
|
|
17642
|
+
}
|
|
17643
|
+
}
|
|
17644
|
+
];
|
|
17645
|
+
|
|
17646
|
+
// src/hooks/keyword-detector/index.ts
|
|
17647
|
+
var TOAST_DURATION2 = 4000;
|
|
17648
|
+
function extractTextFromParts(parts) {
|
|
17649
|
+
return parts.filter((p) => p.type === "text" && p.text).map((p) => p.text ?? "").join(" ");
|
|
17650
|
+
}
|
|
17651
|
+
function removeCodeBlocks(text) {
|
|
17652
|
+
return text.replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "");
|
|
17653
|
+
}
|
|
17654
|
+
function detectKeywords(text) {
|
|
17655
|
+
const cleanText = removeCodeBlocks(text);
|
|
17656
|
+
const detected = [];
|
|
17657
|
+
for (const config2 of KEYWORD_CONFIGS) {
|
|
17658
|
+
if (config2.pattern.test(cleanText)) {
|
|
17659
|
+
detected.push(config2);
|
|
17660
|
+
}
|
|
17661
|
+
}
|
|
17662
|
+
return detected;
|
|
17663
|
+
}
|
|
17664
|
+
function createKeywordDetectorHook(ctx) {
|
|
17665
|
+
const detectedSessions = new Set;
|
|
17666
|
+
return {
|
|
17667
|
+
"chat.message": async (input, output) => {
|
|
17668
|
+
const promptText = extractTextFromParts(output.parts);
|
|
17669
|
+
const detectedKeywords = detectKeywords(promptText);
|
|
17670
|
+
if (detectedKeywords.length === 0)
|
|
17671
|
+
return;
|
|
17672
|
+
const sessionKey = `${input.sessionID}-${detectedKeywords.map((k) => k.type).join("-")}`;
|
|
17673
|
+
if (detectedSessions.has(sessionKey))
|
|
17674
|
+
return;
|
|
17675
|
+
detectedSessions.add(sessionKey);
|
|
17676
|
+
const primaryKeyword = detectedKeywords[0];
|
|
17677
|
+
if (primaryKeyword.type === "ultrawork") {
|
|
17678
|
+
output.message.variant = "max";
|
|
17679
|
+
}
|
|
17680
|
+
output.parts.push({
|
|
17681
|
+
type: "text",
|
|
17682
|
+
text: primaryKeyword.context
|
|
17683
|
+
});
|
|
17684
|
+
await ctx.client.tui.showToast({
|
|
17685
|
+
body: {
|
|
17686
|
+
title: primaryKeyword.toast.title,
|
|
17687
|
+
message: primaryKeyword.toast.message,
|
|
17688
|
+
variant: "success",
|
|
17689
|
+
duration: TOAST_DURATION2
|
|
17690
|
+
}
|
|
17691
|
+
}).catch(() => {});
|
|
17692
|
+
if (detectedSessions.size > 100) {
|
|
17693
|
+
const entries = [...detectedSessions];
|
|
17694
|
+
entries.slice(0, 50).forEach((key) => detectedSessions.delete(key));
|
|
17695
|
+
}
|
|
17696
|
+
}
|
|
17697
|
+
};
|
|
17698
|
+
}
|
|
17699
|
+
// src/features/task-toast/manager.ts
|
|
17700
|
+
var LAUNCH_TOAST_DURATION = 3000;
|
|
17701
|
+
var COMPLETE_TOAST_DURATION = 4000;
|
|
17702
|
+
var ALL_COMPLETE_TOAST_DURATION = 5000;
|
|
17703
|
+
function formatDuration(startedAt) {
|
|
17704
|
+
const seconds = Math.floor((Date.now() - startedAt.getTime()) / 1000);
|
|
17705
|
+
if (seconds < 60)
|
|
17706
|
+
return `${seconds}s`;
|
|
17707
|
+
const minutes = Math.floor(seconds / 60);
|
|
17708
|
+
const remainingSeconds = seconds % 60;
|
|
17709
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
17710
|
+
}
|
|
17711
|
+
|
|
17712
|
+
class TaskToastManager {
|
|
17713
|
+
tasks = new Map;
|
|
17714
|
+
client;
|
|
17715
|
+
constructor(client) {
|
|
17716
|
+
this.client = client;
|
|
17717
|
+
}
|
|
17718
|
+
async showLaunchToast(task) {
|
|
17719
|
+
this.tasks.set(task.id, {
|
|
17720
|
+
...task,
|
|
17721
|
+
startedAt: new Date,
|
|
17722
|
+
status: "running"
|
|
17723
|
+
});
|
|
17724
|
+
const runningCount = this.getRunningCount();
|
|
17725
|
+
const message = runningCount > 1 ? `"${task.description}"
|
|
17726
|
+
Agent: ${task.agent}
|
|
17727
|
+
Running: ${runningCount}` : `"${task.description}"
|
|
17728
|
+
Agent: ${task.agent}`;
|
|
17729
|
+
await this.client.tui.showToast({
|
|
17730
|
+
body: {
|
|
17731
|
+
title: "\u26A1 Background Task Launched",
|
|
17732
|
+
message,
|
|
17733
|
+
variant: "info",
|
|
17734
|
+
duration: LAUNCH_TOAST_DURATION
|
|
17735
|
+
}
|
|
17736
|
+
}).catch(() => {});
|
|
17737
|
+
}
|
|
17738
|
+
async showCompletionToast(taskId) {
|
|
17739
|
+
const task = this.tasks.get(taskId);
|
|
17740
|
+
if (!task)
|
|
17741
|
+
return;
|
|
17742
|
+
task.status = "completed";
|
|
17743
|
+
const duration3 = formatDuration(task.startedAt);
|
|
17744
|
+
const runningCount = this.getRunningCount();
|
|
17745
|
+
if (runningCount === 0) {
|
|
17746
|
+
await this.showAllCompleteToast();
|
|
17747
|
+
return;
|
|
17748
|
+
}
|
|
17749
|
+
const message = `"${task.description}" (${duration3})
|
|
17750
|
+
Still running: ${runningCount}`;
|
|
17751
|
+
await this.client.tui.showToast({
|
|
17752
|
+
body: {
|
|
17753
|
+
title: "\u2705 Task Completed",
|
|
17754
|
+
message,
|
|
17755
|
+
variant: "success",
|
|
17756
|
+
duration: COMPLETE_TOAST_DURATION
|
|
17757
|
+
}
|
|
17758
|
+
}).catch(() => {});
|
|
17759
|
+
}
|
|
17760
|
+
async showFailureToast(taskId, error45) {
|
|
17761
|
+
const task = this.tasks.get(taskId);
|
|
17762
|
+
if (!task)
|
|
17763
|
+
return;
|
|
17764
|
+
task.status = "failed";
|
|
17765
|
+
const duration3 = formatDuration(task.startedAt);
|
|
17766
|
+
const message = error45 ? `"${task.description}" (${duration3})
|
|
17767
|
+
Error: ${error45}` : `"${task.description}" (${duration3})`;
|
|
17768
|
+
await this.client.tui.showToast({
|
|
17769
|
+
body: {
|
|
17770
|
+
title: "\u274C Task Failed",
|
|
17771
|
+
message,
|
|
17772
|
+
variant: "error",
|
|
17773
|
+
duration: COMPLETE_TOAST_DURATION
|
|
17774
|
+
}
|
|
17775
|
+
}).catch(() => {});
|
|
17776
|
+
}
|
|
17777
|
+
async showAllCompleteToast() {
|
|
17778
|
+
const completedTasks = [...this.tasks.values()].filter((t) => t.status === "completed" || t.status === "failed");
|
|
17779
|
+
const taskList = completedTasks.map((t) => {
|
|
17780
|
+
const icon = t.status === "completed" ? "\u2713" : "\u2717";
|
|
17781
|
+
const duration3 = formatDuration(t.startedAt);
|
|
17782
|
+
return `${icon} ${t.description} (${duration3})`;
|
|
17783
|
+
}).join(`
|
|
17784
|
+
`);
|
|
17785
|
+
await this.client.tui.showToast({
|
|
17786
|
+
body: {
|
|
17787
|
+
title: "\uD83C\uDF89 All Background Tasks Complete",
|
|
17788
|
+
message: `${taskList}
|
|
17789
|
+
|
|
17790
|
+
Use background_output to retrieve.`,
|
|
17791
|
+
variant: "success",
|
|
17792
|
+
duration: ALL_COMPLETE_TOAST_DURATION
|
|
17793
|
+
}
|
|
17794
|
+
}).catch(() => {});
|
|
17795
|
+
this.clearCompleted();
|
|
17796
|
+
}
|
|
17797
|
+
getRunningCount() {
|
|
17798
|
+
return [...this.tasks.values()].filter((t) => t.status === "running").length;
|
|
17799
|
+
}
|
|
17800
|
+
clearCompleted() {
|
|
17801
|
+
for (const [id, task] of this.tasks) {
|
|
17802
|
+
if (task.status !== "running") {
|
|
17803
|
+
this.tasks.delete(id);
|
|
17804
|
+
}
|
|
17805
|
+
}
|
|
17806
|
+
}
|
|
17807
|
+
trackTask(task) {
|
|
17808
|
+
this.tasks.set(task.id, {
|
|
17809
|
+
...task,
|
|
17810
|
+
startedAt: new Date,
|
|
17811
|
+
status: "running"
|
|
17812
|
+
});
|
|
17813
|
+
}
|
|
17814
|
+
getTask(taskId) {
|
|
17815
|
+
return this.tasks.get(taskId);
|
|
17816
|
+
}
|
|
17817
|
+
}
|
|
17483
17818
|
// src/index.ts
|
|
17484
17819
|
var ZenoxPlugin = async (ctx) => {
|
|
17485
17820
|
const pluginConfig = loadPluginConfig(ctx.directory);
|
|
17486
17821
|
const disabledAgents = new Set(pluginConfig.disabled_agents ?? []);
|
|
17487
17822
|
const disabledMcps = pluginConfig.disabled_mcps ?? [];
|
|
17823
|
+
const taskToastManager = new TaskToastManager(ctx.client);
|
|
17488
17824
|
const backgroundManager = new BackgroundManager;
|
|
17825
|
+
backgroundManager.setToastManager(taskToastManager);
|
|
17489
17826
|
const backgroundTools = createBackgroundTools(backgroundManager, ctx.client);
|
|
17490
17827
|
const autoUpdateHook = createAutoUpdateHook(ctx);
|
|
17828
|
+
const keywordDetectorHook = createKeywordDetectorHook(ctx);
|
|
17491
17829
|
const applyModelOverride = (agentName, baseAgent) => {
|
|
17492
17830
|
const override = pluginConfig.agents?.[agentName];
|
|
17493
17831
|
if (override?.model) {
|
|
@@ -17497,6 +17835,9 @@ var ZenoxPlugin = async (ctx) => {
|
|
|
17497
17835
|
};
|
|
17498
17836
|
return {
|
|
17499
17837
|
tool: backgroundTools,
|
|
17838
|
+
"chat.message": async (input, output) => {
|
|
17839
|
+
await keywordDetectorHook["chat.message"]?.(input, output);
|
|
17840
|
+
},
|
|
17500
17841
|
event: async (input) => {
|
|
17501
17842
|
const { event } = input;
|
|
17502
17843
|
await autoUpdateHook.event(input);
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Orchestration prompt to inject into Build and Plan agents.
|
|
3
3
|
* This teaches the primary agents how to delegate to specialized subagents using the Task tool.
|
|
4
4
|
*/
|
|
5
|
-
export declare const ORCHESTRATION_PROMPT = "\n\n---\n\n## Sub-Agent Delegation\n\nYou have specialized subagents. Use the **Task tool** to delegate work proactively.\n\n### Available Agents\n\n| Agent | Use For | subagent_type |\n|-------|---------|---------------|\n| **Explorer** | Codebase
|
|
5
|
+
export declare const ORCHESTRATION_PROMPT = "\n\n---\n\n## Sub-Agent Delegation\n\nYou have specialized subagents. Use the **Task tool** to delegate work proactively.\n\n### Available Agents\n\n| Agent | Use For | subagent_type |\n|-------|---------|---------------|\n| **Explorer** | Codebase grep - fast pattern matching, \"Where is X?\" | `explorer` |\n| **Librarian** | External grep - docs, GitHub, OSS examples | `librarian` |\n| **Oracle** | Strategic advisor - architecture, debugging, decisions | `oracle` |\n| **UI Planner** | Designer-developer - visual design, CSS, animations | `ui-planner` |\n\n### Quick Rule: Background vs Synchronous\n\n| Agent | Default Execution | Why |\n|-------|-------------------|-----|\n| Explorer | `background_task` | It's codebase grep - fire and continue |\n| Librarian | `background_task` | It's external grep - fire and continue |\n| Oracle | `Task` (sync) | Need strategic answer before proceeding |\n| UI Planner | `Task` (sync) | Implements changes, needs write access |\n\n**Mental Model**: Explorer & Librarian = **grep commands**. You don't wait for grep, you fire it and continue thinking.\n\n### When to Delegate (Fire Immediately)\n\n| Trigger | subagent_type | Why |\n|---------|---------------|-----|\n| \"Where is X?\", \"Find Y\", locate code | `explorer` | Fast codebase search |\n| External library, \"how does X library work?\" | `librarian` | Searches docs, GitHub, OSS |\n| 2+ modules involved, cross-cutting concerns | `explorer` | Multi-file pattern discovery |\n| Architecture decision, \"should I use X or Y?\" | `oracle` | Deep reasoning advisor |\n| Visual/styling, CSS, animations, UI/UX | `ui-planner` | Designer-developer hybrid |\n| After 2+ failed fix attempts | `oracle` | Debugging escalation |\n\n### How to Delegate\n\nUse the Task tool with these parameters:\n\n```\nTask(\n subagent_type: \"explorer\" | \"librarian\" | \"oracle\" | \"ui-planner\",\n description: \"Short 3-5 word task description\",\n prompt: \"Detailed instructions for the agent\"\n)\n```\n\n**Example delegations:**\n\n```\n// Find code in codebase\nTask(\n subagent_type: \"explorer\",\n description: \"Find auth middleware\",\n prompt: \"Find all authentication middleware implementations in this codebase. Return file paths and explain the auth flow.\"\n)\n\n// Research external library\nTask(\n subagent_type: \"librarian\",\n description: \"React Query caching docs\",\n prompt: \"How does React Query handle caching? Find official documentation and real-world examples with GitHub permalinks.\"\n)\n\n// Architecture decision\nTask(\n subagent_type: \"oracle\",\n description: \"Redux vs Zustand analysis\",\n prompt: \"Analyze trade-offs between Redux and Zustand for this project. Consider bundle size, learning curve, and our existing patterns.\"\n)\n\n// UI/Visual work\nTask(\n subagent_type: \"ui-planner\",\n description: \"Redesign dashboard cards\",\n prompt: \"Redesign the dashboard stat cards to be more visually appealing. Use modern aesthetics, subtle animations, and ensure responsive design.\"\n)\n```\n\n### Parallel Execution\n\nTo run multiple agents in parallel, call multiple Task tools in the **same response message**:\n\n```\n// CORRECT: Multiple Task calls in ONE message = parallel execution\nTask(subagent_type: \"explorer\", description: \"Find auth code\", prompt: \"...\")\nTask(subagent_type: \"librarian\", description: \"JWT best practices\", prompt: \"...\")\n// Both run simultaneously\n\n// WRONG: One Task per message = sequential (slow)\nMessage 1: Task(...) \u2192 wait for result\nMessage 2: Task(...) \u2192 wait for result\n```\n\n### Delegation Priority\n\n1. **Explorer FIRST** \u2014 Always locate code before modifying unfamiliar areas\n2. **Librarian** \u2014 When dealing with external libraries/APIs you don't fully understand\n3. **Oracle** \u2014 For complex decisions or after 2+ failed fix attempts\n4. **UI Planner** \u2014 For ANY visual/styling work (never edit CSS/UI yourself)\n\n### Critical Rules\n\n1. **Never touch frontend visual/styling code yourself** \u2014 Always delegate to `ui-planner`\n2. **Fire librarian proactively** when unfamiliar libraries are involved\n3. **Consult oracle BEFORE major architectural decisions**, not after\n4. **Verify delegated work** before marking task complete\n\n### When to Handle Directly (Don't Delegate)\n\n- Single file edits with known location\n- Questions answerable from code already in context\n- Trivial changes requiring no specialist knowledge\n- Tasks you can complete faster than explaining to an agent\n\n---\n\n## Background Tasks (Parallel Research)\n\nFor **independent research tasks** that benefit from parallelism, use background tasks instead of sequential Task calls.\n\n### When to Use Background Tasks\n\n| Scenario | Use Background Tasks |\n|----------|---------------------|\n| User wants \"comprehensive\" / \"thorough\" / \"deep\" exploration | YES - fire 3-4 agents in parallel |\n| Need BOTH codebase search AND external docs | YES - explore + librarian in parallel |\n| Exploring multiple modules/features simultaneously | YES - separate explore for each |\n| Result of Task A needed before Task B | NO - use sequential Task |\n| Single focused lookup | NO - just use Task directly |\n\n### How Background Tasks Work\n\n1. **Fire**: Launch multiple agents with `background_task` - they run in parallel\n2. **Continue**: Keep working while background agents search\n3. **Notify**: You'll be notified when ALL background tasks complete\n4. **Retrieve**: Use `background_output` to get each result\n\n### Usage\n\n```\n// Launch parallel research (all run simultaneously)\nbackground_task(agent=\"explorer\", description=\"Find auth code\", prompt=\"Search for authentication...\")\nbackground_task(agent=\"explorer\", description=\"Find db layer\", prompt=\"Search for database/ORM...\")\nbackground_task(agent=\"librarian\", description=\"Best practices\", prompt=\"Find framework best practices...\")\n\n// Continue working on other things while they run...\n\n// [NOTIFICATION: All background tasks complete!]\n\n// Retrieve results\nbackground_output(task_id=\"bg_abc123\")\nbackground_output(task_id=\"bg_def456\")\nbackground_output(task_id=\"bg_ghi789\")\n```\n\n### Background Tasks vs Task Tool\n\n| Aspect | Task Tool | Background Tasks |\n|--------|-----------|------------------|\n| Execution | Sequential (waits for result) | Parallel (fire-and-forget) |\n| Best for | Dependent tasks, immediate needs | Independent research, breadth |\n| Result | Inline, immediate | Retrieved later via background_output |\n\n### Key Insight\n\n- **Task** = Use when you need the result immediately before proceeding\n- **Background** = Use when researching multiple angles independently\n\n**Both tools coexist - choose based on whether tasks are dependent or independent.**\n\n### The Parallel Research Pattern\n\nFor complex tasks, fire research first, then continue working:\n\n```\n// 1. FIRE parallel research (don't wait!)\nbackground_task(agent=\"explorer\", description=\"Find existing patterns\", prompt=\"...\")\nbackground_task(agent=\"librarian\", description=\"Find best practices\", prompt=\"...\")\n\n// 2. CONTINUE productive work while they run:\n// - Plan your implementation approach\n// - Read files you already know about\n// - Identify edge cases and questions\n\n// 3. When notified \u2192 RETRIEVE and synthesize\nbackground_output(task_id=\"bg_xxx\")\nbackground_output(task_id=\"bg_yyy\")\n```\n\n**Anti-pattern**: Firing background tasks then doing nothing. Always continue productive work!\n\n---\n\n## Keyword Triggers (Power User)\n\nInclude these keywords in your prompt to unlock special modes:\n\n| Keyword | Effect |\n|---------|--------|\n| `ultrawork` or `ulw` | Maximum multi-agent coordination - aggressive parallel research |\n| `deep research` | Comprehensive exploration - fires 3-4 background agents |\n| `explore codebase` | Codebase mapping - multiple explorers in parallel |\n";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zenox",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "OpenCode plugin with specialized agents (explorer, librarian, oracle, ui-planner), background tasks for parallel execution, and smart orchestration",
|
|
5
5
|
"author": "Ayush",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"background-tasks",
|
|
38
38
|
"parallel",
|
|
39
39
|
"orchestration",
|
|
40
|
+
"ultrawork",
|
|
41
|
+
"keyword-triggers",
|
|
42
|
+
"toast-notifications",
|
|
40
43
|
"ai",
|
|
41
44
|
"llm",
|
|
42
45
|
"cli"
|