zenox 1.1.2 → 1.2.0

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 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 search, file discovery, pattern matching | `claude-haiku-4-5` |
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.3"` in your plugins array.
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;
package/dist/cli/index.js CHANGED
@@ -3760,19 +3760,19 @@ async function runConfig() {
3760
3760
  finalModels[agent] = model;
3761
3761
  }
3762
3762
  }
3763
- if (Object.keys(finalModels).length > 0) {
3764
- const spinner = Y2();
3765
- spinner.start("Saving model configuration");
3766
- try {
3767
- await updateAgentModels(finalModels);
3763
+ const spinner = Y2();
3764
+ spinner.start("Saving model configuration");
3765
+ try {
3766
+ await updateAgentModels(finalModels);
3767
+ if (Object.keys(finalModels).length > 0) {
3768
3768
  spinner.stop(`Updated ${getZenoxConfigPath()}`);
3769
- } catch (err) {
3770
- spinner.stop("Failed to save config");
3771
- M2.error(err instanceof Error ? err.message : "Unknown error");
3772
- process.exit(1);
3769
+ } else {
3770
+ spinner.stop("All agents using default models");
3773
3771
  }
3774
- } else {
3775
- M2.info("All agents using default models - zenox.json not needed");
3772
+ } catch (err) {
3773
+ spinner.stop("Failed to save config");
3774
+ M2.error(err instanceof Error ? err.message : "Unknown error");
3775
+ process.exit(1);
3776
3776
  }
3777
3777
  Se(import_picocolors6.default.green("Configuration updated!"));
3778
3778
  }
@@ -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 {};
@@ -1 +1,3 @@
1
1
  export { createAutoUpdateHook } from "./auto-update";
2
+ export { createKeywordDetectorHook } from "./keyword-detector";
3
+ export type { KeywordType, KeywordConfig } from "./keyword-detector";
@@ -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,26 @@
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
7
+ * 3. Shows toast notification for user feedback
8
+ */
9
+ import type { PluginInput } from "@opencode-ai/plugin";
10
+ interface MessagePart {
11
+ type: string;
12
+ text?: string;
13
+ }
14
+ interface HookOutput {
15
+ parts: MessagePart[];
16
+ message: {
17
+ variant?: string;
18
+ };
19
+ }
20
+ export declare function createKeywordDetectorHook(ctx: PluginInput): {
21
+ "chat.message": (input: {
22
+ sessionID: string;
23
+ agent: string;
24
+ }, output: HookOutput) => Promise<void>;
25
+ };
26
+ 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 search, "Where is X?", file discovery, pattern matching | \`explorer\` |
552
- | **Librarian** | External docs, library research, OSS examples, GitHub permalinks | \`librarian\` |
553
- | **Oracle** | Architecture decisions, debugging strategy, trade-offs, code review | \`oracle\` |
554
- | **UI Planner** | Visual design, CSS, animations, UI/UX, beautiful interfaces | \`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,7 @@ var ZenoxPlugin = async (ctx) => {
17497
17835
  };
17498
17836
  return {
17499
17837
  tool: backgroundTools,
17838
+ hook: keywordDetectorHook,
17500
17839
  event: async (input) => {
17501
17840
  const { event } = input;
17502
17841
  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 search, \"Where is X?\", file discovery, pattern matching | `explorer` |\n| **Librarian** | External docs, library research, OSS examples, GitHub permalinks | `librarian` |\n| **Oracle** | Architecture decisions, debugging strategy, trade-offs, code review | `oracle` |\n| **UI Planner** | Visual design, CSS, animations, UI/UX, beautiful interfaces | `ui-planner` |\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";
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.2",
3
+ "version": "1.2.0",
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"