zenox 1.2.3 → 1.4.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 +79 -0
- package/dist/agents/types.d.ts +1 -0
- package/dist/background/manager.d.ts +1 -1
- package/dist/config/schema.d.ts +52 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/todo-enforcer/index.d.ts +26 -0
- package/dist/index.js +492 -25
- package/dist/orchestration/prompt.d.ts +1 -1
- package/dist/shared/agent-variant.d.ts +19 -0
- package/dist/shared/first-message-variant.d.ts +34 -0
- package/dist/shared/index.d.ts +5 -0
- package/dist/tools/code-intelligence/index.d.ts +1 -0
- package/dist/tools/code-intelligence/tools.d.ts +13 -0
- package/dist/tools/session/index.d.ts +1 -0
- package/dist/tools/session/tools.d.ts +13 -0
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
|
|
18
18
|
Zenox supercharges [OpenCode](https://opencode.ai) with specialized AI agents that handle different aspects of development. Instead of one agent doing everything, you get a team of experts — each optimized for their domain.
|
|
19
19
|
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **4 Specialized Agents** — Explorer, Librarian, Oracle, UI Planner
|
|
23
|
+
- **Background Tasks** — Fire multiple agents in parallel
|
|
24
|
+
- **Thinking Mode Variants** — Configure thinking levels (high, xhigh, max) per agent
|
|
25
|
+
- **Keyword Triggers** — `ultrawork`, `deep research`, `explore codebase`
|
|
26
|
+
- **Session History** — Query past sessions to learn from previous work
|
|
27
|
+
- **Code Intelligence** — Search symbols via LSP
|
|
28
|
+
- **Todo Continuation** — Auto-reminds when tasks are incomplete
|
|
29
|
+
- **Auto-Updates** — Toast notification when new version available
|
|
30
|
+
|
|
20
31
|
## Why Zenox?
|
|
21
32
|
|
|
22
33
|
Most AI coding assistants use a single model for everything. Zenox takes a different approach:
|
|
@@ -114,6 +125,46 @@ Zenox shows toast notifications for background task events:
|
|
|
114
125
|
- 🎉 **All Complete** — Shows summary of all finished tasks
|
|
115
126
|
- ❌ **Task Failed** — Shows error message
|
|
116
127
|
|
|
128
|
+
## Session History
|
|
129
|
+
|
|
130
|
+
Query past sessions to learn from previous work:
|
|
131
|
+
|
|
132
|
+
| Tool | What it does |
|
|
133
|
+
|------|--------------|
|
|
134
|
+
| `session_list` | List recent sessions to find relevant past work |
|
|
135
|
+
| `session_search` | Search messages across sessions for how something was done |
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
You: "How did we implement auth last time?"
|
|
139
|
+
→ session_search({ query: "authentication" })
|
|
140
|
+
→ Finds excerpts from past sessions where auth was discussed
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Code Intelligence
|
|
144
|
+
|
|
145
|
+
Search for symbols via LSP (Language Server Protocol):
|
|
146
|
+
|
|
147
|
+
| Tool | What it does |
|
|
148
|
+
|------|--------------|
|
|
149
|
+
| `find_symbols` | Search for functions, classes, variables by name |
|
|
150
|
+
| `lsp_status` | Check which language servers are running |
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
You: "Find where handleLogin is defined"
|
|
154
|
+
→ find_symbols({ query: "handleLogin" })
|
|
155
|
+
→ Returns: Function in src/auth/handlers.ts, line 42
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Todo Continuation
|
|
159
|
+
|
|
160
|
+
Zenox automatically reminds you to continue working when:
|
|
161
|
+
|
|
162
|
+
- You have incomplete tasks in your todo list
|
|
163
|
+
- The session goes idle
|
|
164
|
+
- There's been enough time since the last reminder (10 second cooldown)
|
|
165
|
+
|
|
166
|
+
This keeps you on track without manual intervention. The agent will be prompted to continue until all todos are complete or blocked.
|
|
167
|
+
|
|
117
168
|
## Configuration
|
|
118
169
|
|
|
119
170
|
### Custom Models
|
|
@@ -135,6 +186,34 @@ Config saves to `~/.config/opencode/zenox.json`:
|
|
|
135
186
|
}
|
|
136
187
|
```
|
|
137
188
|
|
|
189
|
+
### Thinking Mode Variants
|
|
190
|
+
|
|
191
|
+
Configure thinking/reasoning levels for models that support extended thinking (like Claude, GPT with reasoning, etc.):
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"agents": {
|
|
196
|
+
"oracle": {
|
|
197
|
+
"model": "anthropic/claude-opus-4-5",
|
|
198
|
+
"variant": "high"
|
|
199
|
+
},
|
|
200
|
+
"ui-planner": {
|
|
201
|
+
"model": "openai/gpt-5.2-codex",
|
|
202
|
+
"variant": "xhigh"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Available variants (model-dependent):
|
|
209
|
+
- `low` — Minimal thinking
|
|
210
|
+
- `medium` — Balanced thinking
|
|
211
|
+
- `high` — Extended thinking
|
|
212
|
+
- `xhigh` — Extra high thinking
|
|
213
|
+
- `max` — Maximum reasoning depth
|
|
214
|
+
|
|
215
|
+
Variants are applied safely — if an agent doesn't exist or the model doesn't support the variant, it gracefully falls back.
|
|
216
|
+
|
|
138
217
|
### Disable Agents or MCPs
|
|
139
218
|
|
|
140
219
|
```json
|
package/dist/agents/types.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export type AgentFactory = (model?: string) => AgentConfig;
|
|
|
3
3
|
export type BuiltinAgentName = "explorer" | "librarian" | "oracle" | "ui-planner";
|
|
4
4
|
export type AgentOverrideConfig = Partial<AgentConfig> & {
|
|
5
5
|
prompt_append?: string;
|
|
6
|
+
variant?: string;
|
|
6
7
|
};
|
|
7
8
|
export type AgentOverrides = Partial<Record<BuiltinAgentName, AgentOverrideConfig>>;
|
|
@@ -15,7 +15,7 @@ export declare class BackgroundManager {
|
|
|
15
15
|
private mainSessionID;
|
|
16
16
|
private toastManager;
|
|
17
17
|
setToastManager(manager: TaskToastManager): void;
|
|
18
|
-
setMainSession(sessionID: string): void;
|
|
18
|
+
setMainSession(sessionID: string | undefined): void;
|
|
19
19
|
getMainSession(): string | undefined;
|
|
20
20
|
private generateTaskId;
|
|
21
21
|
launch(client: OpencodeClient, input: LaunchInput): Promise<BackgroundTask>;
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -6,14 +6,17 @@ export declare const AgentNameSchema: z.ZodEnum<["explorer", "librarian", "oracl
|
|
|
6
6
|
export type AgentName = z.infer<typeof AgentNameSchema>;
|
|
7
7
|
/**
|
|
8
8
|
* Configuration for overriding an agent's settings
|
|
9
|
-
*
|
|
9
|
+
* Supports model and variant overrides for thinking modes
|
|
10
10
|
*/
|
|
11
11
|
export declare const AgentOverrideConfigSchema: z.ZodObject<{
|
|
12
12
|
model: z.ZodOptional<z.ZodString>;
|
|
13
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
13
14
|
}, "strip", z.ZodTypeAny, {
|
|
14
15
|
model?: string | undefined;
|
|
16
|
+
variant?: string | undefined;
|
|
15
17
|
}, {
|
|
16
18
|
model?: string | undefined;
|
|
19
|
+
variant?: string | undefined;
|
|
17
20
|
}>;
|
|
18
21
|
export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>;
|
|
19
22
|
/**
|
|
@@ -22,57 +25,77 @@ export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>;
|
|
|
22
25
|
export declare const AgentOverridesSchema: z.ZodObject<{
|
|
23
26
|
explorer: z.ZodOptional<z.ZodObject<{
|
|
24
27
|
model: z.ZodOptional<z.ZodString>;
|
|
28
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
25
29
|
}, "strip", z.ZodTypeAny, {
|
|
26
30
|
model?: string | undefined;
|
|
31
|
+
variant?: string | undefined;
|
|
27
32
|
}, {
|
|
28
33
|
model?: string | undefined;
|
|
34
|
+
variant?: string | undefined;
|
|
29
35
|
}>>;
|
|
30
36
|
librarian: z.ZodOptional<z.ZodObject<{
|
|
31
37
|
model: z.ZodOptional<z.ZodString>;
|
|
38
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
32
39
|
}, "strip", z.ZodTypeAny, {
|
|
33
40
|
model?: string | undefined;
|
|
41
|
+
variant?: string | undefined;
|
|
34
42
|
}, {
|
|
35
43
|
model?: string | undefined;
|
|
44
|
+
variant?: string | undefined;
|
|
36
45
|
}>>;
|
|
37
46
|
oracle: z.ZodOptional<z.ZodObject<{
|
|
38
47
|
model: z.ZodOptional<z.ZodString>;
|
|
48
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
39
49
|
}, "strip", z.ZodTypeAny, {
|
|
40
50
|
model?: string | undefined;
|
|
51
|
+
variant?: string | undefined;
|
|
41
52
|
}, {
|
|
42
53
|
model?: string | undefined;
|
|
54
|
+
variant?: string | undefined;
|
|
43
55
|
}>>;
|
|
44
56
|
"ui-planner": z.ZodOptional<z.ZodObject<{
|
|
45
57
|
model: z.ZodOptional<z.ZodString>;
|
|
58
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
46
59
|
}, "strip", z.ZodTypeAny, {
|
|
47
60
|
model?: string | undefined;
|
|
61
|
+
variant?: string | undefined;
|
|
48
62
|
}, {
|
|
49
63
|
model?: string | undefined;
|
|
64
|
+
variant?: string | undefined;
|
|
50
65
|
}>>;
|
|
51
66
|
}, "strip", z.ZodTypeAny, {
|
|
52
67
|
explorer?: {
|
|
53
68
|
model?: string | undefined;
|
|
69
|
+
variant?: string | undefined;
|
|
54
70
|
} | undefined;
|
|
55
71
|
librarian?: {
|
|
56
72
|
model?: string | undefined;
|
|
73
|
+
variant?: string | undefined;
|
|
57
74
|
} | undefined;
|
|
58
75
|
oracle?: {
|
|
59
76
|
model?: string | undefined;
|
|
77
|
+
variant?: string | undefined;
|
|
60
78
|
} | undefined;
|
|
61
79
|
"ui-planner"?: {
|
|
62
80
|
model?: string | undefined;
|
|
81
|
+
variant?: string | undefined;
|
|
63
82
|
} | undefined;
|
|
64
83
|
}, {
|
|
65
84
|
explorer?: {
|
|
66
85
|
model?: string | undefined;
|
|
86
|
+
variant?: string | undefined;
|
|
67
87
|
} | undefined;
|
|
68
88
|
librarian?: {
|
|
69
89
|
model?: string | undefined;
|
|
90
|
+
variant?: string | undefined;
|
|
70
91
|
} | undefined;
|
|
71
92
|
oracle?: {
|
|
72
93
|
model?: string | undefined;
|
|
94
|
+
variant?: string | undefined;
|
|
73
95
|
} | undefined;
|
|
74
96
|
"ui-planner"?: {
|
|
75
97
|
model?: string | undefined;
|
|
98
|
+
variant?: string | undefined;
|
|
76
99
|
} | undefined;
|
|
77
100
|
}>;
|
|
78
101
|
export type AgentOverrides = z.infer<typeof AgentOverridesSchema>;
|
|
@@ -84,57 +107,77 @@ export declare const ZenoxConfigSchema: z.ZodObject<{
|
|
|
84
107
|
agents: z.ZodOptional<z.ZodObject<{
|
|
85
108
|
explorer: z.ZodOptional<z.ZodObject<{
|
|
86
109
|
model: z.ZodOptional<z.ZodString>;
|
|
110
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
87
111
|
}, "strip", z.ZodTypeAny, {
|
|
88
112
|
model?: string | undefined;
|
|
113
|
+
variant?: string | undefined;
|
|
89
114
|
}, {
|
|
90
115
|
model?: string | undefined;
|
|
116
|
+
variant?: string | undefined;
|
|
91
117
|
}>>;
|
|
92
118
|
librarian: z.ZodOptional<z.ZodObject<{
|
|
93
119
|
model: z.ZodOptional<z.ZodString>;
|
|
120
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
94
121
|
}, "strip", z.ZodTypeAny, {
|
|
95
122
|
model?: string | undefined;
|
|
123
|
+
variant?: string | undefined;
|
|
96
124
|
}, {
|
|
97
125
|
model?: string | undefined;
|
|
126
|
+
variant?: string | undefined;
|
|
98
127
|
}>>;
|
|
99
128
|
oracle: z.ZodOptional<z.ZodObject<{
|
|
100
129
|
model: z.ZodOptional<z.ZodString>;
|
|
130
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
101
131
|
}, "strip", z.ZodTypeAny, {
|
|
102
132
|
model?: string | undefined;
|
|
133
|
+
variant?: string | undefined;
|
|
103
134
|
}, {
|
|
104
135
|
model?: string | undefined;
|
|
136
|
+
variant?: string | undefined;
|
|
105
137
|
}>>;
|
|
106
138
|
"ui-planner": z.ZodOptional<z.ZodObject<{
|
|
107
139
|
model: z.ZodOptional<z.ZodString>;
|
|
140
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
108
141
|
}, "strip", z.ZodTypeAny, {
|
|
109
142
|
model?: string | undefined;
|
|
143
|
+
variant?: string | undefined;
|
|
110
144
|
}, {
|
|
111
145
|
model?: string | undefined;
|
|
146
|
+
variant?: string | undefined;
|
|
112
147
|
}>>;
|
|
113
148
|
}, "strip", z.ZodTypeAny, {
|
|
114
149
|
explorer?: {
|
|
115
150
|
model?: string | undefined;
|
|
151
|
+
variant?: string | undefined;
|
|
116
152
|
} | undefined;
|
|
117
153
|
librarian?: {
|
|
118
154
|
model?: string | undefined;
|
|
155
|
+
variant?: string | undefined;
|
|
119
156
|
} | undefined;
|
|
120
157
|
oracle?: {
|
|
121
158
|
model?: string | undefined;
|
|
159
|
+
variant?: string | undefined;
|
|
122
160
|
} | undefined;
|
|
123
161
|
"ui-planner"?: {
|
|
124
162
|
model?: string | undefined;
|
|
163
|
+
variant?: string | undefined;
|
|
125
164
|
} | undefined;
|
|
126
165
|
}, {
|
|
127
166
|
explorer?: {
|
|
128
167
|
model?: string | undefined;
|
|
168
|
+
variant?: string | undefined;
|
|
129
169
|
} | undefined;
|
|
130
170
|
librarian?: {
|
|
131
171
|
model?: string | undefined;
|
|
172
|
+
variant?: string | undefined;
|
|
132
173
|
} | undefined;
|
|
133
174
|
oracle?: {
|
|
134
175
|
model?: string | undefined;
|
|
176
|
+
variant?: string | undefined;
|
|
135
177
|
} | undefined;
|
|
136
178
|
"ui-planner"?: {
|
|
137
179
|
model?: string | undefined;
|
|
180
|
+
variant?: string | undefined;
|
|
138
181
|
} | undefined;
|
|
139
182
|
}>>;
|
|
140
183
|
disabled_agents: z.ZodOptional<z.ZodArray<z.ZodEnum<["explorer", "librarian", "oracle", "ui-planner"]>, "many">>;
|
|
@@ -144,15 +187,19 @@ export declare const ZenoxConfigSchema: z.ZodObject<{
|
|
|
144
187
|
agents?: {
|
|
145
188
|
explorer?: {
|
|
146
189
|
model?: string | undefined;
|
|
190
|
+
variant?: string | undefined;
|
|
147
191
|
} | undefined;
|
|
148
192
|
librarian?: {
|
|
149
193
|
model?: string | undefined;
|
|
194
|
+
variant?: string | undefined;
|
|
150
195
|
} | undefined;
|
|
151
196
|
oracle?: {
|
|
152
197
|
model?: string | undefined;
|
|
198
|
+
variant?: string | undefined;
|
|
153
199
|
} | undefined;
|
|
154
200
|
"ui-planner"?: {
|
|
155
201
|
model?: string | undefined;
|
|
202
|
+
variant?: string | undefined;
|
|
156
203
|
} | undefined;
|
|
157
204
|
} | undefined;
|
|
158
205
|
disabled_agents?: ("explorer" | "librarian" | "oracle" | "ui-planner")[] | undefined;
|
|
@@ -162,15 +209,19 @@ export declare const ZenoxConfigSchema: z.ZodObject<{
|
|
|
162
209
|
agents?: {
|
|
163
210
|
explorer?: {
|
|
164
211
|
model?: string | undefined;
|
|
212
|
+
variant?: string | undefined;
|
|
165
213
|
} | undefined;
|
|
166
214
|
librarian?: {
|
|
167
215
|
model?: string | undefined;
|
|
216
|
+
variant?: string | undefined;
|
|
168
217
|
} | undefined;
|
|
169
218
|
oracle?: {
|
|
170
219
|
model?: string | undefined;
|
|
220
|
+
variant?: string | undefined;
|
|
171
221
|
} | undefined;
|
|
172
222
|
"ui-planner"?: {
|
|
173
223
|
model?: string | undefined;
|
|
224
|
+
variant?: string | undefined;
|
|
174
225
|
} | undefined;
|
|
175
226
|
} | undefined;
|
|
176
227
|
disabled_agents?: ("explorer" | "librarian" | "oracle" | "ui-planner")[] | undefined;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Todo Continuation Enforcer Hook
|
|
3
|
+
*
|
|
4
|
+
* Automatically reminds the agent to continue working when:
|
|
5
|
+
* - Session goes idle (session.idle event)
|
|
6
|
+
* - There are incomplete todos (pending or in_progress)
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Skips child sessions (background tasks)
|
|
10
|
+
* - Cooldown to prevent spam (10 seconds between reminders)
|
|
11
|
+
* - Shows toast notification when enforcing
|
|
12
|
+
*
|
|
13
|
+
* Inspired by oh-my-opencode's todo-continuation-enforcer
|
|
14
|
+
*/
|
|
15
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
16
|
+
import type { Event } from "@opencode-ai/sdk";
|
|
17
|
+
interface SessionState {
|
|
18
|
+
lastEnforcedAt: number;
|
|
19
|
+
enforceCount: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function createTodoEnforcerHook(ctx: PluginInput): {
|
|
22
|
+
event: ({ event }: {
|
|
23
|
+
event: Event;
|
|
24
|
+
}) => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
export type { SessionState };
|
package/dist/index.js
CHANGED
|
@@ -743,6 +743,85 @@ Include these keywords in your prompt to unlock special modes:
|
|
|
743
743
|
| \`ultrawork\` or \`ulw\` | Maximum multi-agent coordination - aggressive parallel research |
|
|
744
744
|
| \`deep research\` | Comprehensive exploration - fires 3-4 background agents |
|
|
745
745
|
| \`explore codebase\` | Codebase mapping - multiple explorers in parallel |
|
|
746
|
+
|
|
747
|
+
---
|
|
748
|
+
|
|
749
|
+
## Session History Tools
|
|
750
|
+
|
|
751
|
+
You have tools to learn from past work sessions:
|
|
752
|
+
|
|
753
|
+
| Tool | Use For |
|
|
754
|
+
|------|---------|
|
|
755
|
+
| \`session_list\` | List recent sessions to find relevant past work |
|
|
756
|
+
| \`session_search\` | Search messages across sessions for how something was done |
|
|
757
|
+
|
|
758
|
+
### When to Use Session Tools
|
|
759
|
+
|
|
760
|
+
- **Before implementing unfamiliar features** \u2014 search if done before
|
|
761
|
+
- **When user says "like before" or "last time"** \u2014 find that session
|
|
762
|
+
- **When debugging** \u2014 check if similar issues were solved previously
|
|
763
|
+
- **For context on ongoing projects** \u2014 understand recent work history
|
|
764
|
+
|
|
765
|
+
### Example Usage
|
|
766
|
+
|
|
767
|
+
\`\`\`
|
|
768
|
+
// Find how authentication was implemented before
|
|
769
|
+
session_search({ query: "JWT authentication" })
|
|
770
|
+
|
|
771
|
+
// List recent sessions to understand project context
|
|
772
|
+
session_list({ limit: 5 })
|
|
773
|
+
|
|
774
|
+
// Find past implementations of a feature
|
|
775
|
+
session_search({ query: "rate limiting" })
|
|
776
|
+
\`\`\`
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
## Code Intelligence Tools
|
|
781
|
+
|
|
782
|
+
You have tools to understand code structure via LSP:
|
|
783
|
+
|
|
784
|
+
| Tool | Use For |
|
|
785
|
+
|------|---------|
|
|
786
|
+
| \`find_symbols\` | Search for functions, classes, variables by name |
|
|
787
|
+
| \`lsp_status\` | Check which language servers are running |
|
|
788
|
+
|
|
789
|
+
### When to Use Code Intelligence
|
|
790
|
+
|
|
791
|
+
- **Before editing code** \u2014 find the symbol's definition location
|
|
792
|
+
- **When refactoring** \u2014 search for related symbols
|
|
793
|
+
- **To understand project structure** \u2014 search for key symbols like "auth", "user", "api"
|
|
794
|
+
- **To verify LSP availability** \u2014 check if code intelligence is working
|
|
795
|
+
|
|
796
|
+
### Example Usage
|
|
797
|
+
|
|
798
|
+
\`\`\`
|
|
799
|
+
// Find all auth-related functions/classes
|
|
800
|
+
find_symbols({ query: "auth" })
|
|
801
|
+
|
|
802
|
+
// Find a specific function
|
|
803
|
+
find_symbols({ query: "handleLogin" })
|
|
804
|
+
|
|
805
|
+
// Check LSP server status
|
|
806
|
+
lsp_status()
|
|
807
|
+
\`\`\`
|
|
808
|
+
|
|
809
|
+
---
|
|
810
|
+
|
|
811
|
+
## Todo Continuation
|
|
812
|
+
|
|
813
|
+
The system automatically reminds you if you go idle with incomplete tasks.
|
|
814
|
+
|
|
815
|
+
**Best Practices:**
|
|
816
|
+
- Keep your todo list updated with \`TodoWrite\`
|
|
817
|
+
- Mark tasks complete immediately when finished
|
|
818
|
+
- Use clear, actionable task descriptions
|
|
819
|
+
- The system will prompt you to continue if tasks remain incomplete
|
|
820
|
+
|
|
821
|
+
**Note:** You don't need to invoke the todo enforcer \u2014 it runs automatically when:
|
|
822
|
+
- You have pending or in-progress todos
|
|
823
|
+
- The session goes idle
|
|
824
|
+
- There's been sufficient time since the last reminder
|
|
746
825
|
`;
|
|
747
826
|
|
|
748
827
|
// node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
@@ -4733,7 +4812,8 @@ var AgentNameSchema = exports_external.enum([
|
|
|
4733
4812
|
"ui-planner"
|
|
4734
4813
|
]);
|
|
4735
4814
|
var AgentOverrideConfigSchema = exports_external.object({
|
|
4736
|
-
model: exports_external.string().optional()
|
|
4815
|
+
model: exports_external.string().optional(),
|
|
4816
|
+
variant: exports_external.string().optional()
|
|
4737
4817
|
});
|
|
4738
4818
|
var AgentOverridesSchema = exports_external.object({
|
|
4739
4819
|
explorer: AgentOverrideConfigSchema.optional(),
|
|
@@ -4890,24 +4970,34 @@ class BackgroundManager {
|
|
|
4890
4970
|
agent: task.agent
|
|
4891
4971
|
}).catch(() => {});
|
|
4892
4972
|
}
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4973
|
+
const sendPrompt = async (retryWithoutAgent = false) => {
|
|
4974
|
+
try {
|
|
4975
|
+
await client.session.prompt({
|
|
4976
|
+
path: { id: sessionID },
|
|
4977
|
+
body: {
|
|
4978
|
+
...retryWithoutAgent ? {} : { agent: input.agent },
|
|
4979
|
+
tools: { task: false },
|
|
4980
|
+
parts: [{ type: "text", text: input.prompt }]
|
|
4981
|
+
}
|
|
4982
|
+
});
|
|
4983
|
+
} catch (err) {
|
|
4984
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
4985
|
+
if (!retryWithoutAgent && (errorMsg.includes("agent.name") || errorMsg.includes("undefined is not an object"))) {
|
|
4986
|
+
console.warn(`[zenox] Agent "${input.agent}" not found. Retrying with default agent.`);
|
|
4987
|
+
return sendPrompt(true);
|
|
4988
|
+
}
|
|
4989
|
+
const existingTask = this.tasks.get(task.id);
|
|
4990
|
+
if (existingTask) {
|
|
4991
|
+
existingTask.status = "failed";
|
|
4992
|
+
existingTask.error = errorMsg;
|
|
4993
|
+
existingTask.completedAt = new Date;
|
|
4994
|
+
if (this.toastManager) {
|
|
4995
|
+
this.toastManager.showFailureToast(task.id, existingTask.error).catch(() => {});
|
|
4996
|
+
}
|
|
4908
4997
|
}
|
|
4909
4998
|
}
|
|
4910
|
-
}
|
|
4999
|
+
};
|
|
5000
|
+
sendPrompt().catch(() => {});
|
|
4911
5001
|
return task;
|
|
4912
5002
|
}
|
|
4913
5003
|
getTask(taskId) {
|
|
@@ -17706,6 +17796,111 @@ ${primaryKeyword.context}`;
|
|
|
17706
17796
|
}
|
|
17707
17797
|
};
|
|
17708
17798
|
}
|
|
17799
|
+
// src/hooks/todo-enforcer/index.ts
|
|
17800
|
+
var COOLDOWN_MS = 1e4;
|
|
17801
|
+
var TOAST_DURATION3 = 3000;
|
|
17802
|
+
var CONTINUATION_PROMPT = `[TODO CONTINUATION REMINDER]
|
|
17803
|
+
|
|
17804
|
+
You have incomplete tasks in your todo list. Continue working on them.
|
|
17805
|
+
|
|
17806
|
+
Rules:
|
|
17807
|
+
- Proceed without asking for permission
|
|
17808
|
+
- Mark each task complete when finished
|
|
17809
|
+
- Update todo status as you work
|
|
17810
|
+
- Do not stop until all tasks are done or blocked`;
|
|
17811
|
+
function createTodoEnforcerHook(ctx) {
|
|
17812
|
+
const sessionStates = new Map;
|
|
17813
|
+
const cleanupOldStates = () => {
|
|
17814
|
+
const now = Date.now();
|
|
17815
|
+
const maxAge = 30 * 60 * 1000;
|
|
17816
|
+
for (const [sessionID, state] of sessionStates) {
|
|
17817
|
+
if (now - state.lastEnforcedAt > maxAge) {
|
|
17818
|
+
sessionStates.delete(sessionID);
|
|
17819
|
+
}
|
|
17820
|
+
}
|
|
17821
|
+
};
|
|
17822
|
+
return {
|
|
17823
|
+
event: async ({ event }) => {
|
|
17824
|
+
if (event.type !== "session.idle")
|
|
17825
|
+
return;
|
|
17826
|
+
const props = event.properties;
|
|
17827
|
+
const sessionID = props?.sessionID;
|
|
17828
|
+
if (!sessionID)
|
|
17829
|
+
return;
|
|
17830
|
+
let state = sessionStates.get(sessionID);
|
|
17831
|
+
if (!state) {
|
|
17832
|
+
state = { lastEnforcedAt: 0, enforceCount: 0 };
|
|
17833
|
+
sessionStates.set(sessionID, state);
|
|
17834
|
+
}
|
|
17835
|
+
const now = Date.now();
|
|
17836
|
+
if (now - state.lastEnforcedAt < COOLDOWN_MS) {
|
|
17837
|
+
return;
|
|
17838
|
+
}
|
|
17839
|
+
try {
|
|
17840
|
+
const sessionResult = await ctx.client.session.get({
|
|
17841
|
+
path: { id: sessionID }
|
|
17842
|
+
});
|
|
17843
|
+
const session = sessionResult.data;
|
|
17844
|
+
if (session?.parentID) {
|
|
17845
|
+
return;
|
|
17846
|
+
}
|
|
17847
|
+
} catch {
|
|
17848
|
+
return;
|
|
17849
|
+
}
|
|
17850
|
+
let todos = [];
|
|
17851
|
+
try {
|
|
17852
|
+
const todosResult = await ctx.client.session.todo({
|
|
17853
|
+
path: { id: sessionID }
|
|
17854
|
+
});
|
|
17855
|
+
todos = todosResult.data ?? [];
|
|
17856
|
+
} catch {
|
|
17857
|
+
return;
|
|
17858
|
+
}
|
|
17859
|
+
if (todos.length === 0) {
|
|
17860
|
+
return;
|
|
17861
|
+
}
|
|
17862
|
+
const incomplete = todos.filter((t) => t.status === "pending" || t.status === "in_progress");
|
|
17863
|
+
if (incomplete.length === 0) {
|
|
17864
|
+
return;
|
|
17865
|
+
}
|
|
17866
|
+
state.lastEnforcedAt = now;
|
|
17867
|
+
state.enforceCount++;
|
|
17868
|
+
const todoList = incomplete.map((t) => {
|
|
17869
|
+
const priority = t.priority === "high" ? "!" : "";
|
|
17870
|
+
return `- [${t.status}]${priority} ${t.content}`;
|
|
17871
|
+
}).join(`
|
|
17872
|
+
`);
|
|
17873
|
+
const completedCount = todos.length - incomplete.length;
|
|
17874
|
+
const statusLine = `[Status: ${completedCount}/${todos.length} completed, ${incomplete.length} remaining]`;
|
|
17875
|
+
const prompt = `${CONTINUATION_PROMPT}
|
|
17876
|
+
|
|
17877
|
+
Current incomplete tasks:
|
|
17878
|
+
${todoList}
|
|
17879
|
+
|
|
17880
|
+
${statusLine}`;
|
|
17881
|
+
try {
|
|
17882
|
+
await ctx.client.session.prompt({
|
|
17883
|
+
path: { id: sessionID },
|
|
17884
|
+
body: {
|
|
17885
|
+
noReply: false,
|
|
17886
|
+
parts: [{ type: "text", text: prompt }]
|
|
17887
|
+
}
|
|
17888
|
+
});
|
|
17889
|
+
await ctx.client.tui.showToast({
|
|
17890
|
+
body: {
|
|
17891
|
+
title: "\uD83D\uDCCB Todo Reminder",
|
|
17892
|
+
message: `${incomplete.length} task(s) remaining`,
|
|
17893
|
+
variant: "info",
|
|
17894
|
+
duration: TOAST_DURATION3
|
|
17895
|
+
}
|
|
17896
|
+
}).catch(() => {});
|
|
17897
|
+
} catch {}
|
|
17898
|
+
if (sessionStates.size > 50) {
|
|
17899
|
+
cleanupOldStates();
|
|
17900
|
+
}
|
|
17901
|
+
}
|
|
17902
|
+
};
|
|
17903
|
+
}
|
|
17709
17904
|
// src/features/task-toast/manager.ts
|
|
17710
17905
|
var LAUNCH_TOAST_DURATION = 3000;
|
|
17711
17906
|
var COMPLETE_TOAST_DURATION = 4000;
|
|
@@ -17825,6 +18020,239 @@ Use background_output to retrieve.`,
|
|
|
17825
18020
|
return this.tasks.get(taskId);
|
|
17826
18021
|
}
|
|
17827
18022
|
}
|
|
18023
|
+
// src/tools/session/tools.ts
|
|
18024
|
+
var MAX_SESSIONS_TO_SEARCH = 10;
|
|
18025
|
+
var DEFAULT_SEARCH_LIMIT = 20;
|
|
18026
|
+
var DEFAULT_LIST_LIMIT = 10;
|
|
18027
|
+
function createSessionTools(client) {
|
|
18028
|
+
const sessionList = tool({
|
|
18029
|
+
description: `List recent sessions to find relevant past work.
|
|
18030
|
+
Use when you need to see what was done before or find a specific session.
|
|
18031
|
+
Returns session IDs, titles, and creation dates.`,
|
|
18032
|
+
args: {
|
|
18033
|
+
limit: tool.schema.number().optional().describe("Max sessions to return (default: 10)")
|
|
18034
|
+
},
|
|
18035
|
+
async execute(args) {
|
|
18036
|
+
try {
|
|
18037
|
+
const result = await client.session.list();
|
|
18038
|
+
const sessions = result.data ?? [];
|
|
18039
|
+
const mainSessions = sessions.filter((s) => !s.parentID).slice(0, args.limit ?? DEFAULT_LIST_LIMIT);
|
|
18040
|
+
if (mainSessions.length === 0) {
|
|
18041
|
+
return "No sessions found.";
|
|
18042
|
+
}
|
|
18043
|
+
const formatted = mainSessions.map((s) => ({
|
|
18044
|
+
id: s.id,
|
|
18045
|
+
title: s.title ?? "(untitled)",
|
|
18046
|
+
created: s.time?.created ? new Date(s.time.created).toISOString() : "unknown"
|
|
18047
|
+
}));
|
|
18048
|
+
return JSON.stringify(formatted, null, 2);
|
|
18049
|
+
} catch (err) {
|
|
18050
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown error";
|
|
18051
|
+
return `Failed to list sessions: ${errorMsg}`;
|
|
18052
|
+
}
|
|
18053
|
+
}
|
|
18054
|
+
});
|
|
18055
|
+
const sessionSearch = tool({
|
|
18056
|
+
description: `Search messages across sessions to find how something was done before.
|
|
18057
|
+
Use when looking for past implementations, solutions, or context.
|
|
18058
|
+
Searches the last 10 sessions for matching content.`,
|
|
18059
|
+
args: {
|
|
18060
|
+
query: tool.schema.string().describe("Search query (case-insensitive)"),
|
|
18061
|
+
limit: tool.schema.number().optional().describe("Max results to return (default: 20)")
|
|
18062
|
+
},
|
|
18063
|
+
async execute(args) {
|
|
18064
|
+
try {
|
|
18065
|
+
const sessionsResult = await client.session.list();
|
|
18066
|
+
const sessions = sessionsResult.data ?? [];
|
|
18067
|
+
const searchSessions = sessions.filter((s) => !s.parentID).slice(0, MAX_SESSIONS_TO_SEARCH);
|
|
18068
|
+
if (searchSessions.length === 0) {
|
|
18069
|
+
return "No sessions to search.";
|
|
18070
|
+
}
|
|
18071
|
+
const query = args.query.toLowerCase();
|
|
18072
|
+
const maxResults = args.limit ?? DEFAULT_SEARCH_LIMIT;
|
|
18073
|
+
const results = [];
|
|
18074
|
+
for (const session of searchSessions) {
|
|
18075
|
+
if (results.length >= maxResults)
|
|
18076
|
+
break;
|
|
18077
|
+
try {
|
|
18078
|
+
const messagesResult = await client.session.messages({
|
|
18079
|
+
path: { id: session.id },
|
|
18080
|
+
query: { limit: 50 }
|
|
18081
|
+
});
|
|
18082
|
+
const messages = messagesResult.data ?? [];
|
|
18083
|
+
for (const msg of messages) {
|
|
18084
|
+
if (results.length >= maxResults)
|
|
18085
|
+
break;
|
|
18086
|
+
const textParts = msg.parts?.filter((p) => p.type === "text" && p.text) ?? [];
|
|
18087
|
+
for (const part of textParts) {
|
|
18088
|
+
if (results.length >= maxResults)
|
|
18089
|
+
break;
|
|
18090
|
+
const text = part.text ?? "";
|
|
18091
|
+
if (text.toLowerCase().includes(query)) {
|
|
18092
|
+
const lowerText = text.toLowerCase();
|
|
18093
|
+
const matchIndex = lowerText.indexOf(query);
|
|
18094
|
+
const start = Math.max(0, matchIndex - 50);
|
|
18095
|
+
const end = Math.min(text.length, matchIndex + query.length + 150);
|
|
18096
|
+
const excerpt = (start > 0 ? "..." : "") + text.substring(start, end).trim() + (end < text.length ? "..." : "");
|
|
18097
|
+
results.push({
|
|
18098
|
+
sessionId: session.id,
|
|
18099
|
+
sessionTitle: session.title ?? "(untitled)",
|
|
18100
|
+
role: msg.info?.role ?? "unknown",
|
|
18101
|
+
excerpt
|
|
18102
|
+
});
|
|
18103
|
+
}
|
|
18104
|
+
}
|
|
18105
|
+
}
|
|
18106
|
+
} catch {
|
|
18107
|
+
continue;
|
|
18108
|
+
}
|
|
18109
|
+
}
|
|
18110
|
+
if (results.length === 0) {
|
|
18111
|
+
return `No matches found for "${args.query}" in the last ${MAX_SESSIONS_TO_SEARCH} sessions.`;
|
|
18112
|
+
}
|
|
18113
|
+
return JSON.stringify(results, null, 2);
|
|
18114
|
+
} catch (err) {
|
|
18115
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown error";
|
|
18116
|
+
return `Failed to search sessions: ${errorMsg}`;
|
|
18117
|
+
}
|
|
18118
|
+
}
|
|
18119
|
+
});
|
|
18120
|
+
return {
|
|
18121
|
+
session_list: sessionList,
|
|
18122
|
+
session_search: sessionSearch
|
|
18123
|
+
};
|
|
18124
|
+
}
|
|
18125
|
+
// src/tools/code-intelligence/tools.ts
|
|
18126
|
+
var SYMBOL_KINDS = {
|
|
18127
|
+
1: "File",
|
|
18128
|
+
2: "Module",
|
|
18129
|
+
3: "Namespace",
|
|
18130
|
+
4: "Package",
|
|
18131
|
+
5: "Class",
|
|
18132
|
+
6: "Method",
|
|
18133
|
+
7: "Property",
|
|
18134
|
+
8: "Field",
|
|
18135
|
+
9: "Constructor",
|
|
18136
|
+
10: "Enum",
|
|
18137
|
+
11: "Interface",
|
|
18138
|
+
12: "Function",
|
|
18139
|
+
13: "Variable",
|
|
18140
|
+
14: "Constant",
|
|
18141
|
+
15: "String",
|
|
18142
|
+
16: "Number",
|
|
18143
|
+
17: "Boolean",
|
|
18144
|
+
18: "Array",
|
|
18145
|
+
19: "Object",
|
|
18146
|
+
20: "Key",
|
|
18147
|
+
21: "Null",
|
|
18148
|
+
22: "EnumMember",
|
|
18149
|
+
23: "Struct",
|
|
18150
|
+
24: "Event",
|
|
18151
|
+
25: "Operator",
|
|
18152
|
+
26: "TypeParameter"
|
|
18153
|
+
};
|
|
18154
|
+
function createCodeIntelligenceTools(client) {
|
|
18155
|
+
const findSymbols = tool({
|
|
18156
|
+
description: `Search for functions, classes, variables, and other symbols by name.
|
|
18157
|
+
Use to find where something is defined or to understand code structure.
|
|
18158
|
+
Returns symbol name, type (function/class/etc), file path, and location.`,
|
|
18159
|
+
args: {
|
|
18160
|
+
query: tool.schema.string().describe("Symbol name or pattern to search (e.g., 'handleAuth', 'User')")
|
|
18161
|
+
},
|
|
18162
|
+
async execute(args) {
|
|
18163
|
+
try {
|
|
18164
|
+
const result = await client.find.symbols({
|
|
18165
|
+
query: { query: args.query }
|
|
18166
|
+
});
|
|
18167
|
+
const symbols = result.data ?? [];
|
|
18168
|
+
if (symbols.length === 0) {
|
|
18169
|
+
return `No symbols found matching "${args.query}"`;
|
|
18170
|
+
}
|
|
18171
|
+
const formatted = symbols.map((s) => {
|
|
18172
|
+
const uri = s.location?.uri ?? "";
|
|
18173
|
+
const path2 = uri.startsWith("file://") ? uri.slice(7) : uri;
|
|
18174
|
+
return {
|
|
18175
|
+
name: s.name,
|
|
18176
|
+
kind: SYMBOL_KINDS[s.kind] ?? `Unknown(${s.kind})`,
|
|
18177
|
+
path: path2,
|
|
18178
|
+
location: s.location?.range ? `line ${s.location.range.start.line + 1}` : "unknown"
|
|
18179
|
+
};
|
|
18180
|
+
});
|
|
18181
|
+
return JSON.stringify(formatted, null, 2);
|
|
18182
|
+
} catch (err) {
|
|
18183
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown error";
|
|
18184
|
+
return `Failed to search symbols: ${errorMsg}`;
|
|
18185
|
+
}
|
|
18186
|
+
}
|
|
18187
|
+
});
|
|
18188
|
+
const lspStatus = tool({
|
|
18189
|
+
description: `Get the status of language servers (LSP).
|
|
18190
|
+
Use to check if code intelligence is available for the current project's languages.
|
|
18191
|
+
Shows which LSP servers are running and their status.`,
|
|
18192
|
+
args: {},
|
|
18193
|
+
async execute() {
|
|
18194
|
+
try {
|
|
18195
|
+
const result = await client.lsp.status();
|
|
18196
|
+
const servers = result.data ?? [];
|
|
18197
|
+
if (servers.length === 0) {
|
|
18198
|
+
return "No LSP servers currently running.";
|
|
18199
|
+
}
|
|
18200
|
+
const formatted = servers.map((s) => ({
|
|
18201
|
+
name: s.name ?? s.id,
|
|
18202
|
+
status: s.status,
|
|
18203
|
+
root: s.root
|
|
18204
|
+
}));
|
|
18205
|
+
return JSON.stringify(formatted, null, 2);
|
|
18206
|
+
} catch (err) {
|
|
18207
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown error";
|
|
18208
|
+
return `Failed to get LSP status: ${errorMsg}`;
|
|
18209
|
+
}
|
|
18210
|
+
}
|
|
18211
|
+
});
|
|
18212
|
+
return {
|
|
18213
|
+
find_symbols: findSymbols,
|
|
18214
|
+
lsp_status: lspStatus
|
|
18215
|
+
};
|
|
18216
|
+
}
|
|
18217
|
+
// src/shared/agent-variant.ts
|
|
18218
|
+
function resolveAgentVariant(config2, agentName) {
|
|
18219
|
+
if (!agentName)
|
|
18220
|
+
return;
|
|
18221
|
+
const agentOverrides = config2.agents;
|
|
18222
|
+
return agentOverrides?.[agentName]?.variant;
|
|
18223
|
+
}
|
|
18224
|
+
function applyAgentVariant(config2, agentName, message) {
|
|
18225
|
+
const variant = resolveAgentVariant(config2, agentName);
|
|
18226
|
+
if (variant !== undefined && message.variant === undefined) {
|
|
18227
|
+
message.variant = variant;
|
|
18228
|
+
}
|
|
18229
|
+
}
|
|
18230
|
+
// src/shared/first-message-variant.ts
|
|
18231
|
+
function createFirstMessageVariantGate() {
|
|
18232
|
+
const pending = new Set;
|
|
18233
|
+
return {
|
|
18234
|
+
markSessionCreated(info) {
|
|
18235
|
+
if (info?.id && !info.parentID) {
|
|
18236
|
+
pending.add(info.id);
|
|
18237
|
+
}
|
|
18238
|
+
},
|
|
18239
|
+
shouldOverride(sessionID) {
|
|
18240
|
+
if (!sessionID)
|
|
18241
|
+
return false;
|
|
18242
|
+
return pending.has(sessionID);
|
|
18243
|
+
},
|
|
18244
|
+
markApplied(sessionID) {
|
|
18245
|
+
if (!sessionID)
|
|
18246
|
+
return;
|
|
18247
|
+
pending.delete(sessionID);
|
|
18248
|
+
},
|
|
18249
|
+
clear(sessionID) {
|
|
18250
|
+
if (!sessionID)
|
|
18251
|
+
return;
|
|
18252
|
+
pending.delete(sessionID);
|
|
18253
|
+
}
|
|
18254
|
+
};
|
|
18255
|
+
}
|
|
17828
18256
|
// src/index.ts
|
|
17829
18257
|
var ZenoxPlugin = async (ctx) => {
|
|
17830
18258
|
const pluginConfig = loadPluginConfig(ctx.directory);
|
|
@@ -17836,6 +18264,10 @@ var ZenoxPlugin = async (ctx) => {
|
|
|
17836
18264
|
const backgroundTools = createBackgroundTools(backgroundManager, ctx.client);
|
|
17837
18265
|
const autoUpdateHook = createAutoUpdateHook(ctx);
|
|
17838
18266
|
const keywordDetectorHook = createKeywordDetectorHook(ctx);
|
|
18267
|
+
const todoEnforcerHook = createTodoEnforcerHook(ctx);
|
|
18268
|
+
const sessionTools = createSessionTools(ctx.client);
|
|
18269
|
+
const codeIntelligenceTools = createCodeIntelligenceTools(ctx.client);
|
|
18270
|
+
const firstMessageVariantGate = createFirstMessageVariantGate();
|
|
17839
18271
|
const applyModelOverride = (agentName, baseAgent) => {
|
|
17840
18272
|
const override = pluginConfig.agents?.[agentName];
|
|
17841
18273
|
if (override?.model) {
|
|
@@ -17844,8 +18276,22 @@ var ZenoxPlugin = async (ctx) => {
|
|
|
17844
18276
|
return baseAgent;
|
|
17845
18277
|
};
|
|
17846
18278
|
return {
|
|
17847
|
-
tool:
|
|
18279
|
+
tool: {
|
|
18280
|
+
...backgroundTools,
|
|
18281
|
+
...sessionTools,
|
|
18282
|
+
...codeIntelligenceTools
|
|
18283
|
+
},
|
|
17848
18284
|
"chat.message": async (input, output) => {
|
|
18285
|
+
const message = output.message;
|
|
18286
|
+
if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
|
|
18287
|
+
const variant = resolveAgentVariant(pluginConfig, input.agent);
|
|
18288
|
+
if (variant !== undefined) {
|
|
18289
|
+
message.variant = variant;
|
|
18290
|
+
}
|
|
18291
|
+
firstMessageVariantGate.markApplied(input.sessionID);
|
|
18292
|
+
} else {
|
|
18293
|
+
applyAgentVariant(pluginConfig, input.agent, message);
|
|
18294
|
+
}
|
|
17849
18295
|
await keywordDetectorHook["chat.message"]?.(input, output);
|
|
17850
18296
|
},
|
|
17851
18297
|
event: async (input) => {
|
|
@@ -17854,10 +18300,19 @@ var ZenoxPlugin = async (ctx) => {
|
|
|
17854
18300
|
if (event.type === "session.created") {
|
|
17855
18301
|
const props = event.properties;
|
|
17856
18302
|
const sessionInfo = props?.info;
|
|
18303
|
+
firstMessageVariantGate.markSessionCreated(sessionInfo);
|
|
17857
18304
|
if (sessionInfo?.id && !sessionInfo?.parentID) {
|
|
17858
18305
|
backgroundManager.setMainSession(sessionInfo.id);
|
|
17859
18306
|
}
|
|
17860
18307
|
}
|
|
18308
|
+
if (event.type === "session.deleted") {
|
|
18309
|
+
const props = event.properties;
|
|
18310
|
+
const sessionID = props?.info?.id;
|
|
18311
|
+
firstMessageVariantGate.clear(sessionID);
|
|
18312
|
+
if (sessionID && sessionID === backgroundManager.getMainSession()) {
|
|
18313
|
+
backgroundManager.setMainSession(undefined);
|
|
18314
|
+
}
|
|
18315
|
+
}
|
|
17861
18316
|
if (event.type === "session.idle") {
|
|
17862
18317
|
const props = event.properties;
|
|
17863
18318
|
const sessionID = props?.sessionID;
|
|
@@ -17867,16 +18322,28 @@ var ZenoxPlugin = async (ctx) => {
|
|
|
17867
18322
|
if (notification) {
|
|
17868
18323
|
const mainSessionID = backgroundManager.getMainSession();
|
|
17869
18324
|
if (mainSessionID) {
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
18325
|
+
const sendNotification = async (omitAgent = false) => {
|
|
18326
|
+
try {
|
|
18327
|
+
await ctx.client.session.prompt({
|
|
18328
|
+
path: { id: mainSessionID },
|
|
18329
|
+
body: {
|
|
18330
|
+
noReply: !notification.allComplete,
|
|
18331
|
+
...omitAgent ? {} : { agent: notification.parentAgent },
|
|
18332
|
+
parts: [{ type: "text", text: notification.message }]
|
|
18333
|
+
}
|
|
18334
|
+
});
|
|
18335
|
+
} catch (err) {
|
|
18336
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
18337
|
+
if (!omitAgent && (errorMsg.includes("agent.name") || errorMsg.includes("undefined"))) {
|
|
18338
|
+
return sendNotification(true);
|
|
18339
|
+
}
|
|
17876
18340
|
}
|
|
17877
|
-
}
|
|
18341
|
+
};
|
|
18342
|
+
await sendNotification();
|
|
17878
18343
|
}
|
|
18344
|
+
return;
|
|
17879
18345
|
}
|
|
18346
|
+
await todoEnforcerHook.event(input);
|
|
17880
18347
|
}
|
|
17881
18348
|
},
|
|
17882
18349
|
config: async (config2) => {
|
|
@@ -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 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";
|
|
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\n---\n\n## Session History Tools\n\nYou have tools to learn from past work sessions:\n\n| Tool | Use For |\n|------|---------|\n| `session_list` | List recent sessions to find relevant past work |\n| `session_search` | Search messages across sessions for how something was done |\n\n### When to Use Session Tools\n\n- **Before implementing unfamiliar features** \u2014 search if done before\n- **When user says \"like before\" or \"last time\"** \u2014 find that session\n- **When debugging** \u2014 check if similar issues were solved previously\n- **For context on ongoing projects** \u2014 understand recent work history\n\n### Example Usage\n\n```\n// Find how authentication was implemented before\nsession_search({ query: \"JWT authentication\" })\n\n// List recent sessions to understand project context\nsession_list({ limit: 5 })\n\n// Find past implementations of a feature\nsession_search({ query: \"rate limiting\" })\n```\n\n---\n\n## Code Intelligence Tools\n\nYou have tools to understand code structure via LSP:\n\n| Tool | Use For |\n|------|---------|\n| `find_symbols` | Search for functions, classes, variables by name |\n| `lsp_status` | Check which language servers are running |\n\n### When to Use Code Intelligence\n\n- **Before editing code** \u2014 find the symbol's definition location\n- **When refactoring** \u2014 search for related symbols\n- **To understand project structure** \u2014 search for key symbols like \"auth\", \"user\", \"api\"\n- **To verify LSP availability** \u2014 check if code intelligence is working\n\n### Example Usage\n\n```\n// Find all auth-related functions/classes\nfind_symbols({ query: \"auth\" })\n\n// Find a specific function\nfind_symbols({ query: \"handleLogin\" })\n\n// Check LSP server status\nlsp_status()\n```\n\n---\n\n## Todo Continuation\n\nThe system automatically reminds you if you go idle with incomplete tasks.\n\n**Best Practices:**\n- Keep your todo list updated with `TodoWrite`\n- Mark tasks complete immediately when finished\n- Use clear, actionable task descriptions\n- The system will prompt you to continue if tasks remain incomplete\n\n**Note:** You don't need to invoke the todo enforcer \u2014 it runs automatically when:\n- You have pending or in-progress todos\n- The session goes idle\n- There's been sufficient time since the last reminder\n";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Variant Handling
|
|
3
|
+
*
|
|
4
|
+
* Safely resolves and applies agent variants for thinking modes.
|
|
5
|
+
* Defensive implementation to prevent "undefined is not an object" errors.
|
|
6
|
+
*/
|
|
7
|
+
import type { ZenoxConfig } from "../config";
|
|
8
|
+
/**
|
|
9
|
+
* Safely resolve agent variant from config
|
|
10
|
+
* Returns undefined if agent doesn't exist or has no variant configured
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveAgentVariant(config: ZenoxConfig, agentName?: string): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Apply agent variant to message if configured
|
|
15
|
+
* Safe for undefined agents - simply does nothing
|
|
16
|
+
*/
|
|
17
|
+
export declare function applyAgentVariant(config: ZenoxConfig, agentName: string | undefined, message: {
|
|
18
|
+
variant?: string;
|
|
19
|
+
}): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First Message Variant Gate
|
|
3
|
+
*
|
|
4
|
+
* Tracks new sessions to apply variants only on the first message.
|
|
5
|
+
* Prevents variants from being applied to forked/child sessions.
|
|
6
|
+
*/
|
|
7
|
+
type SessionInfo = {
|
|
8
|
+
id?: string;
|
|
9
|
+
parentID?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Creates a gate that tracks which sessions need variant applied on first message
|
|
13
|
+
*/
|
|
14
|
+
export declare function createFirstMessageVariantGate(): {
|
|
15
|
+
/**
|
|
16
|
+
* Mark a newly created session as pending variant application
|
|
17
|
+
* Only marks non-child sessions (no parentID)
|
|
18
|
+
*/
|
|
19
|
+
markSessionCreated(info?: SessionInfo): void;
|
|
20
|
+
/**
|
|
21
|
+
* Check if this session should have variant overridden
|
|
22
|
+
*/
|
|
23
|
+
shouldOverride(sessionID?: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Mark variant as applied for this session
|
|
26
|
+
*/
|
|
27
|
+
markApplied(sessionID?: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Clear session from tracking (on session delete)
|
|
30
|
+
*/
|
|
31
|
+
clear(sessionID?: string): void;
|
|
32
|
+
};
|
|
33
|
+
export type FirstMessageVariantGate = ReturnType<typeof createFirstMessageVariantGate>;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createCodeIntelligenceTools, type CodeIntelligenceTools } from "./tools";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Intelligence Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for understanding code structure via LSP:
|
|
5
|
+
* - find_symbols: Search workspace symbols by name
|
|
6
|
+
* - lsp_status: Check LSP server health
|
|
7
|
+
*/
|
|
8
|
+
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
9
|
+
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
10
|
+
export type CodeIntelligenceTools = {
|
|
11
|
+
[key: string]: ToolDefinition;
|
|
12
|
+
};
|
|
13
|
+
export declare function createCodeIntelligenceTools(client: OpencodeClient): CodeIntelligenceTools;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createSessionTools, type SessionTools } from "./tools";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for querying past sessions and learning from previous work:
|
|
5
|
+
* - session_list: List recent sessions
|
|
6
|
+
* - session_search: Search messages across sessions
|
|
7
|
+
*/
|
|
8
|
+
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
9
|
+
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
10
|
+
export type SessionTools = {
|
|
11
|
+
[key: string]: ToolDefinition;
|
|
12
|
+
};
|
|
13
|
+
export declare function createSessionTools(client: OpencodeClient): SessionTools;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zenox",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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",
|
|
@@ -40,6 +40,12 @@
|
|
|
40
40
|
"ultrawork",
|
|
41
41
|
"keyword-triggers",
|
|
42
42
|
"toast-notifications",
|
|
43
|
+
"session-history",
|
|
44
|
+
"code-intelligence",
|
|
45
|
+
"lsp",
|
|
46
|
+
"todo-enforcer",
|
|
47
|
+
"thinking-modes",
|
|
48
|
+
"variants",
|
|
43
49
|
"ai",
|
|
44
50
|
"llm",
|
|
45
51
|
"cli"
|