zillacore 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +126 -0
- data/README.md +1166 -0
- data/Rakefile +12 -0
- data/bin/zillacore +1521 -0
- data/certs/stowzilla.pem +26 -0
- data/docs/waybar-config.md +96 -0
- data/lib/user_registry.rb +159 -0
- data/lib/zillacore/agents.rb +203 -0
- data/lib/zillacore/brain.rb +197 -0
- data/lib/zillacore/card_index.rb +389 -0
- data/lib/zillacore/config.rb +263 -0
- data/lib/zillacore/cron.rb +629 -0
- data/lib/zillacore/deployments.rb +258 -0
- data/lib/zillacore/handlers/discord.rb +1643 -0
- data/lib/zillacore/handlers/fizzy.rb +1249 -0
- data/lib/zillacore/handlers/github.rb +598 -0
- data/lib/zillacore/handlers/zoho.rb +487 -0
- data/lib/zillacore/helpers.rb +760 -0
- data/lib/zillacore/planning.rb +237 -0
- data/lib/zillacore/prompts.rb +620 -0
- data/lib/zillacore/sessions.rb +282 -0
- data/lib/zillacore/skills.rb +276 -0
- data/lib/zillacore/users.rb +76 -0
- data/lib/zillacore/version.rb +6 -0
- data/lib/zillacore/zoho_mail_api.rb +109 -0
- data/lib/zillacore.rb +10 -0
- data/monitor/daemon.rb +99 -0
- data/monitor/deploy-env-macos.rb +131 -0
- data/monitor/menubar.rb +295 -0
- data/monitor/open-action.sh +15 -0
- data/monitor/setup-menubar.rb +78 -0
- data/monitor/setup-waybar-deploy-envs.rb +121 -0
- data/monitor/setup-waybar-deployments.rb +96 -0
- data/monitor/setup-waybar-module.rb +113 -0
- data/monitor/setup-xbar-plugin.rb +35 -0
- data/monitor/view-logs-macos.rb +210 -0
- data/monitor/view-logs-rofi.rb +194 -0
- data/monitor/view-logs.rb +119 -0
- data/monitor/waybar-config-updater.rb +56 -0
- data/monitor/waybar-deploy-env.rb +206 -0
- data/monitor/waybar-deployments.rb +239 -0
- data/monitor/waybar.rb +146 -0
- data/monitor/xbar.3s.rb +179 -0
- data/receiver.rb +956 -0
- data/templates/agents.json.example +10 -0
- data/templates/discord.json.example +17 -0
- data/templates/fizzy.json.example +24 -0
- data/templates/github.json.example +4 -0
- data/templates/testflight.json.example +8 -0
- data/templates/users.json.example +121 -0
- data/templates/zoho.json.example +27 -0
- data/views/dashboard.erb +437 -0
- data/zillacore.gemspec +30 -0
- data.tar.gz.sig +2 -0
- metadata +235 -0
- metadata.gz.sig +0 -0
data/README.md
ADDED
|
@@ -0,0 +1,1166 @@
|
|
|
1
|
+
# ZillaCore
|
|
2
|
+
|
|
3
|
+
A webhook receiver that listens for [Fizzy](https://fizzy.do), GitHub, Discord, and Zoho Mail events, then dispatches work to AI agent CLIs. Each agent has its own persona, brain, and voice — they collaborate on the same projects through @mentions.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
Webhook events trigger the receiver to spawn an AI agent CLI with a natural language prompt. The receiver can dispatch multiple agents — each with a unique personality and kiro-cli config. Agents are discovered from `~/.kiro/agents/`, and projects registered in `~/.zillacore/projects.json`. Config reloads dynamically, no restart needed.
|
|
8
|
+
|
|
9
|
+
### Events
|
|
10
|
+
|
|
11
|
+
| Source | Event | What Happens |
|
|
12
|
+
| --------- | ------------------- | ------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| Fizzy | Card assigned | Creates worktree, maps card to branch, spawns assigned agent |
|
|
14
|
+
| Fizzy | Card published | Duplicate detection via trigram similarity + semantic search |
|
|
15
|
+
| Fizzy | @mention in comment | Routes to the mentioned agent (even on another agent's card) |
|
|
16
|
+
| Fizzy | Follow-up comment | Runs card's assigned agent in existing worktree |
|
|
17
|
+
| GitHub | PR review submitted | Agent addresses review feedback |
|
|
18
|
+
| GitHub | PR comment | Agent responds to PR feedback |
|
|
19
|
+
| GitHub | PR merged to main | Comments PR link on Fizzy card, closes card, cleans up worktree |
|
|
20
|
+
| GitHub | Issue opened | Logged for tracking (no agent dispatch) |
|
|
21
|
+
| GitHub | Workflow run | Notifies on CI failures via Discord |
|
|
22
|
+
| Discord | @bot mention | Each agent has its own bot — @mention routes directly to that agent, no worktree — conversational |
|
|
23
|
+
| Zoho Mail | Incoming email | Rule-based matching, notifies via Discord |
|
|
24
|
+
|
|
25
|
+
### Inline Tags
|
|
26
|
+
|
|
27
|
+
All four channels support inline tags in message/comment text. Tags are stripped before reaching the agent prompt.
|
|
28
|
+
|
|
29
|
+
| Tag | Fizzy | Discord | GitHub | Description |
|
|
30
|
+
| ----------------------------------------------------------------------------- | ----- | ------- | ------ | ----------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `[project:XYZ]` | — | ✓ | — | Override which project the agent works in (Discord only — Fizzy uses card tags, GitHub uses the repo) |
|
|
32
|
+
| `[opus]` `[sonnet]` `[haiku]` `[deepseek]` `[minimax]` `[minimax21]` `[qwen]` | ✓ | ✓ | ✓ | Override the model for this dispatch |
|
|
33
|
+
| `[worktree:branch-name]` | ✓ | — | — | Direct the agent to a specific worktree instead of the card's default |
|
|
34
|
+
| `[plan]` | ✓ | ✓ | — | Activate planning mode — agent gathers requirements before coding |
|
|
35
|
+
|
|
36
|
+
Model keys come from the project's `allowed_models` config. Fizzy also supports model selection via card tags (e.g. adding an `opus` tag to the card).
|
|
37
|
+
|
|
38
|
+
### Planning Mode
|
|
39
|
+
|
|
40
|
+
Add a `[plan]` tag to a Discord message or a `plan` tag to a Fizzy card to activate planning mode. Instead of jumping straight into implementation, the agent:
|
|
41
|
+
|
|
42
|
+
1. Asks clarifying questions to understand the problem, constraints, and desired outcome
|
|
43
|
+
2. Logs Q&A to its memory file for continuity across sessions
|
|
44
|
+
3. Generates a plan markdown file at `~/.zillacore/plans/card-<id>-plan.md`
|
|
45
|
+
4. Automatically creates Fizzy steps from the task breakdown
|
|
46
|
+
|
|
47
|
+
The agent stays read-only during planning — no code changes, no commits. Once the plan is finalized, the system creates Fizzy steps from each `### Task N: Title` heading in the plan file.
|
|
48
|
+
|
|
49
|
+
### Cross-Agent Mentions
|
|
50
|
+
|
|
51
|
+
Any agent can be tagged on any card. If Kaylee is working card #42 and someone comments "@Galen what do you think?", Galen reviews the card and PR without touching Kaylee's worktree. This enables patterns like:
|
|
52
|
+
|
|
53
|
+
- Engineer agent does the work, security agent reviews it
|
|
54
|
+
- One agent asks another for a second opinion
|
|
55
|
+
- A read-only agent (e.g. GLaDOS) that reviews and comments but doesn't take over the card
|
|
56
|
+
|
|
57
|
+
#### Display Name Accuracy
|
|
58
|
+
|
|
59
|
+
Agents need to spell @mentions exactly as they appear in Fizzy (e.g. `@GLaDOS` not `@glados`). The agent registry's `fizzy_name` field handles this — every prompt includes an agent roster with the correct spelling:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
## Agent Roster
|
|
63
|
+
When @mentioning other agents in Fizzy comments, use the EXACT spelling below.
|
|
64
|
+
- @Galen
|
|
65
|
+
- @GLaDOS
|
|
66
|
+
- @Kaylee
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Detection is case-insensitive (inbound `@glados` still matches GLaDOS), but outbound mentions use the exact `fizzy_name` from the registry.
|
|
70
|
+
|
|
71
|
+
#### Agent-to-Agent Loop Prevention
|
|
72
|
+
|
|
73
|
+
When agents can tag each other, infinite loops become possible (Galen tags GLaDOS, GLaDOS tags Galen back, forever). ZillaCore prevents this with layered defenses:
|
|
74
|
+
|
|
75
|
+
1. **Dispatch depth limit** — a per-card counter tracks agent-to-agent hops since the last human comment. Default max depth is 10: Human → Agent A → Agent B → ... is allowed up to the limit. The counter resets when a human comments on the card, and expires after 1 hour of no human activity.
|
|
76
|
+
|
|
77
|
+
2. **Prompt instruction** — cross-agent review prompts explicitly tell the dispatched agent not to @mention other agents. It can suggest involving someone in plain text, but not with `@Agent` syntax.
|
|
78
|
+
|
|
79
|
+
3. **Existing defenses** — `session_active?` prevents concurrent runs on the same card, `COMMENT_COOLDOWN` (60s) suppresses rapid-fire triggers, and self-comment filtering prevents an agent from triggering itself.
|
|
80
|
+
|
|
81
|
+
Tuning knobs in `lib/zillacore/sessions.rb`:
|
|
82
|
+
|
|
83
|
+
- `AGENT_DISPATCH_MAX_DEPTH` — max agent-to-agent hops (default: 10)
|
|
84
|
+
- `AGENT_DISPATCH_WINDOW` — seconds before depth resets without human activity (default: 3600)
|
|
85
|
+
- `GET /api/dispatch-depth` — debug endpoint showing current depth state per card
|
|
86
|
+
|
|
87
|
+
### Card Context Pre-Fetching
|
|
88
|
+
|
|
89
|
+
Before dispatching an agent, ZillaCore pre-fetches the Fizzy card body and last 5 comments, injecting them directly into the prompt. This means agents don't need to make separate API calls to read the card — the context is already there. Results are cached for 60 seconds to avoid redundant fetches on rapid-fire triggers.
|
|
90
|
+
|
|
91
|
+
### Card Duplicate Detection
|
|
92
|
+
|
|
93
|
+
When a card is published or triaged, ZillaCore checks for potential duplicates using two methods:
|
|
94
|
+
|
|
95
|
+
1. **Trigram similarity** — compares the new card's title against all indexed card titles using character trigram overlap
|
|
96
|
+
2. **Semantic search** — uses qmd to find cards with similar meaning, even if the wording differs
|
|
97
|
+
|
|
98
|
+
If matches are found above the similarity threshold, ZillaCore posts a comment on the card listing the potential duplicates. The card index is stored at `~/.zillacore/card_index.json` and reindexed periodically via qmd.
|
|
99
|
+
|
|
100
|
+
### Pre-Post Comment Check
|
|
101
|
+
|
|
102
|
+
Before posting a response, agents re-fetch the source (Fizzy card comments or GitHub PR comments) to catch any new messages that arrived while they were working. If a human added context, changed requirements, or asked for adjustments mid-session, the agent incorporates that before posting — avoiding stale or outdated responses.
|
|
103
|
+
|
|
104
|
+
This applies to Fizzy and GitHub channels. Discord uses a different mechanism (session supersede) where follow-up messages within 60 seconds kill the previous run and restart with updated context.
|
|
105
|
+
|
|
106
|
+
### Pre-Comment Reflection
|
|
107
|
+
|
|
108
|
+
Before writing any comment, agents go through a mandatory reflection ritual:
|
|
109
|
+
|
|
110
|
+
1. React with 🧠 to signal reflection
|
|
111
|
+
2. Query their persona collection for communication style and the triggering user
|
|
112
|
+
3. Decide whether persona or knowledge needs updating
|
|
113
|
+
4. Update brain files (or consciously skip) and run `qmd update`
|
|
114
|
+
5. React with a situational emoji (🎉, 💪, 🤔, 😅, 🔥, etc.)
|
|
115
|
+
6. Write the comment in their unique voice
|
|
116
|
+
|
|
117
|
+
This compounds over dozens of sessions into a rich understanding of each person and codebase.
|
|
118
|
+
|
|
119
|
+
## Setup
|
|
120
|
+
|
|
121
|
+
### Installation
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
gem install zillacore
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This installs the `zillacore` binary to your gem bin path (just like `rails`, `rspec`, etc.). Ensure your gem bin directory is on your `PATH` — it typically is if you're using a Ruby version manager.
|
|
128
|
+
|
|
129
|
+
### Quick Start (New Machine)
|
|
130
|
+
|
|
131
|
+
After installing the gem:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
zillacore setup
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This creates the `~/.zillacore/` directory structure and copies example config files. Then edit the configs with your actual secrets and IDs (see below).
|
|
138
|
+
|
|
139
|
+
### Prerequisites
|
|
140
|
+
|
|
141
|
+
| Dependency | Required | Install |
|
|
142
|
+
|------------|----------|---------|
|
|
143
|
+
| Ruby 3.4+ | Yes | [mise](https://mise.jdx.dev), rbenv, or system |
|
|
144
|
+
| [Kiro CLI](https://kiro.dev) | Yes | Agent dispatch |
|
|
145
|
+
| [Fizzy CLI](https://github.com/robzolkos/fizzy-cli) | For Fizzy | Card management |
|
|
146
|
+
| [GitHub CLI](https://cli.github.com) (`gh`) | For GitHub | PR/issue operations |
|
|
147
|
+
| [ngrok](https://ngrok.com) | Yes | Webhook tunneling |
|
|
148
|
+
| [qmd](https://github.com/tobi/qmd) | For brain | `npm install -g @tobilu/qmd` (Node.js >= 22) |
|
|
149
|
+
| [gum](https://github.com/charmbracelet/gum) | Optional | Manual worktree cleanup |
|
|
150
|
+
|
|
151
|
+
### Directory Structure
|
|
152
|
+
|
|
153
|
+
After setup, `~/.zillacore/` looks like:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
~/.zillacore/
|
|
157
|
+
├── agents.json # Agent registry (tokens, display names, local flag)
|
|
158
|
+
├── projects.json # Registered projects
|
|
159
|
+
├── github.json # GitHub webhook secret
|
|
160
|
+
├── fizzy.json # Fizzy board config, authorized users
|
|
161
|
+
├── discord.json # Discord channel mappings, auth
|
|
162
|
+
├── users.json # Cross-platform user identity registry
|
|
163
|
+
├── zoho.json # Zoho Mail rules (optional)
|
|
164
|
+
├── brain/
|
|
165
|
+
│ ├── knowledge/ # Shared technical knowledge (all agents)
|
|
166
|
+
│ ├── persona/ # Per-agent personality files
|
|
167
|
+
│ └── memory/ # Per-agent session memory
|
|
168
|
+
├── handlers/ # Custom webhook handlers (plugin system)
|
|
169
|
+
├── plans/ # Planning mode output
|
|
170
|
+
└── tmp/ # Temp files, drafts, posted responses
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Step-by-Step Configuration
|
|
174
|
+
|
|
175
|
+
#### 1. Agent Registry (`~/.zillacore/agents.json`)
|
|
176
|
+
|
|
177
|
+
Maps agents to their identity and environment. Every agent that should dispatch on this machine needs an entry here with `"local": true`:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"galen": {
|
|
182
|
+
"fizzy_name": "Galen",
|
|
183
|
+
"local": true,
|
|
184
|
+
"env": {
|
|
185
|
+
"FIZZY_TOKEN": "fizzy_abc...",
|
|
186
|
+
"DISCORD_BOT_TOKEN": "Bot_abc..."
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
See [Multi-Agent Setup](#multi-agent-setup) for full details.
|
|
193
|
+
|
|
194
|
+
#### 2. Kiro Agent Configs (`~/.kiro/agents/<name>.json`)
|
|
195
|
+
|
|
196
|
+
Each agent also needs a kiro-cli config. The filename becomes the agent name:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
kiro-cli agent create # Interactive
|
|
200
|
+
# Or manually create ~/.kiro/agents/galen.json
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### 3. GitHub (`~/.zillacore/github.json`)
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"webhook_secret": "your-github-webhook-secret",
|
|
208
|
+
"repos": {}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The `webhook_secret` verifies incoming GitHub webhook requests. Generate one with `ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'`.
|
|
213
|
+
|
|
214
|
+
**Legacy:** `GITHUB_WEBHOOK_SECRET` env var works as fallback.
|
|
215
|
+
|
|
216
|
+
#### 4. Fizzy (`~/.zillacore/fizzy.json`)
|
|
217
|
+
|
|
218
|
+
Defines authorized users, flags humans, and configures boards:
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"authorized_users": [
|
|
223
|
+
{ "id": "user-id-1", "name": "Andy", "human": true },
|
|
224
|
+
{ "id": "user-id-2", "name": "Adam", "human": true },
|
|
225
|
+
{ "id": "agent-id-1", "name": "Galen", "human": false }
|
|
226
|
+
],
|
|
227
|
+
"boards": {
|
|
228
|
+
"development": {
|
|
229
|
+
"board_id": "your-board-id",
|
|
230
|
+
"webhook_secret": "secret-for-this-board",
|
|
231
|
+
"columns": {
|
|
232
|
+
"right_now": "column-id",
|
|
233
|
+
"needs_review": "column-id",
|
|
234
|
+
"uat": "column-id"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Each board gets its own webhook secret and column IDs. The board key (e.g., `development`) is used in the webhook URL.
|
|
242
|
+
|
|
243
|
+
When a human is @mentioned on a card assigned to an agent, the agent will skip that comment — allowing human-to-human conversation without agent interference.
|
|
244
|
+
|
|
245
|
+
**Legacy:** `FIZZY_WEBHOOK_SECRET` and `AUTHORIZED_USER_IDS` env vars work as fallbacks.
|
|
246
|
+
|
|
247
|
+
#### 5. Environment Variables
|
|
248
|
+
|
|
249
|
+
Most config lives in JSON files now. The only env var you might want:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
export AI_AGENT_NAME="Galen" # Defaults to Galen (Linux) or Kaylee (macOS)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### 6. Register Projects
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
cd ~/Code/marketplace && zillacore register
|
|
259
|
+
cd ~/Code/zillacore && zillacore register
|
|
260
|
+
zillacore list
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The CLI prompts for project key, Fizzy tags, GitHub repo, and agent CLI settings.
|
|
264
|
+
|
|
265
|
+
Set a default project (used as fallback when no tags match):
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
zillacore projects default myproject
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### 7. Initialize Brain
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
zillacore brain init Galen
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
This creates the directory structure, sets up qmd collections, and indexes everything.
|
|
278
|
+
|
|
279
|
+
#### 8. Configure Webhooks
|
|
280
|
+
|
|
281
|
+
**Fizzy:** Board settings → Webhooks → URL: `https://your-ngrok.ngrok-free.app/fizzy/development` (where `development` is the board key from `fizzy.json`), Secret: the board's `webhook_secret`
|
|
282
|
+
|
|
283
|
+
**GitHub:** Repo settings → Webhooks → URL: `https://your-ngrok.ngrok-free.app/github`, Content type: `application/json`, Secret: from `github.json`, Events: Pull requests, Pull request reviews, Issue comments, Issues
|
|
284
|
+
|
|
285
|
+
#### 9. Start
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
zillacore server # Start and tail logs (Ctrl+C to detach, server keeps running)
|
|
289
|
+
ngrok http 4567 # Terminal 2
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Multi-Agent Setup
|
|
293
|
+
|
|
294
|
+
This is the core of ZillaCore. Each machine runs one receiver that can dispatch multiple agents.
|
|
295
|
+
|
|
296
|
+
### Architecture
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
Andy's Linux box Adam's macOS
|
|
300
|
+
┌─────────────────────┐ ┌─────────────────────┐
|
|
301
|
+
│ zillacore server │ │ zillacore server │
|
|
302
|
+
│ │ │ │
|
|
303
|
+
│ ~/.kiro/agents/: │ │ ~/.kiro/agents/: │
|
|
304
|
+
│ galen.json │ │ kaylee.json │
|
|
305
|
+
│ glados.json │ │ jane.json │
|
|
306
|
+
│ │ │ │
|
|
307
|
+
│ ~/.zillacore/ │ │ ~/.zillacore/ │
|
|
308
|
+
│ agents.json │ │ agents.json │
|
|
309
|
+
└─────────────────────┘ └─────────────────────┘
|
|
310
|
+
│ │
|
|
311
|
+
└──── same Fizzy board + GitHub ────┘
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Both machines receive the same webhooks. The receiver discovers available agents by scanning `~/.kiro/agents/*.json` — only agents with a config on that machine will be dispatched, preventing duplicates.
|
|
315
|
+
|
|
316
|
+
### Step 1: Create Kiro CLI Agent Configs
|
|
317
|
+
|
|
318
|
+
Each agent needs a kiro-cli config at `~/.kiro/agents/<name>.json`. This is the only registry — no separate config file needed.
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
kiro-cli agent create # Interactive
|
|
322
|
+
# Or manually create ~/.kiro/agents/galen.json, ~/.kiro/agents/glados.json
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The receiver scans this directory to discover which agents it can dispatch. The filename becomes the agent name (e.g. `galen.json` → Galen). Tool permissions, model, and resources are all defined in the kiro-cli config.
|
|
326
|
+
|
|
327
|
+
### Step 2: Agent Registry
|
|
328
|
+
|
|
329
|
+
The agent registry at `~/.zillacore/agents.json` maps each agent to its identity and environment. This serves four purposes:
|
|
330
|
+
|
|
331
|
+
1. **Per-agent environment variables** — any env var can be set per-agent via the `env` hash (e.g. `FIZZY_TOKEN`, `DISCORD_BOT_TOKEN`, custom vars)
|
|
332
|
+
2. **Display name mapping** — agents know the exact spelling for @mentions (e.g. `GLaDOS` not `glados`)
|
|
333
|
+
3. **Discord bot tokens** — agents with `DISCORD_BOT_TOKEN` in their env get their own Discord bot
|
|
334
|
+
4. **Local flag** — agents marked `"local": true` pick up card assignments on this machine
|
|
335
|
+
|
|
336
|
+
```json
|
|
337
|
+
{
|
|
338
|
+
"galen": {
|
|
339
|
+
"fizzy_name": "Galen",
|
|
340
|
+
"local": true,
|
|
341
|
+
"env": {
|
|
342
|
+
"FIZZY_TOKEN": "fizzy_abc...",
|
|
343
|
+
"DISCORD_BOT_TOKEN": "Bot_abc..."
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
"glados": {
|
|
347
|
+
"fizzy_name": "GLaDOS",
|
|
348
|
+
"env": {
|
|
349
|
+
"FIZZY_TOKEN": "fizzy_xyz...",
|
|
350
|
+
"DISCORD_BOT_TOKEN": "Bot_xyz..."
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
"kaylee": {
|
|
354
|
+
"fizzy_name": "Kaylee"
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Keys are lowercase lookup keys (normalized: non-alphanumeric chars become hyphens). `fizzy_name` is the exact Fizzy account display name. The `env` hash is injected into the spawned agent process — every key/value pair becomes an environment variable.
|
|
360
|
+
|
|
361
|
+
The `local` flag controls which agents pick up card assignments on this machine. Agents without `"local": true` are still known for mention detection, display names, tokens, and cross-agent interactions — they just won't pick up card assignments. Agents discovered from `~/.kiro/agents/` configs and the default `AI_AGENT_NAME` are always considered local.
|
|
362
|
+
|
|
363
|
+
Agents without an `env` block (like Kaylee above on a Linux box) still appear in the agent roster so local agents spell @mentions correctly.
|
|
364
|
+
|
|
365
|
+
A legacy format with top-level `fizzy_token` / `discord_bot_token` keys is auto-migrated into the `env` hash at load time. A legacy `~/.zillacore/agent_tokens.json` format (flat `{ "galen": "token" }`) is supported as a fallback and auto-migrated.
|
|
366
|
+
|
|
367
|
+
The registry reloads on every webhook and via `POST /api/reload`.
|
|
368
|
+
|
|
369
|
+
### Step 3: Seed Agent Persona and Knowledge
|
|
370
|
+
|
|
371
|
+
Agents get their personality from persona files and their technical context from knowledge files. These live in the brain directory and are indexed by qmd for semantic search.
|
|
372
|
+
|
|
373
|
+
#### Persona
|
|
374
|
+
|
|
375
|
+
Each agent needs at least one persona file. Create it directly in the brain:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# Create persona file for your agent
|
|
379
|
+
mkdir -p ~/.zillacore/brain/persona/galen
|
|
380
|
+
cat > ~/.zillacore/brain/persona/galen/style.md << 'EOF'
|
|
381
|
+
---
|
|
382
|
+
name: galen-persona
|
|
383
|
+
description: Persona voice for Galen.
|
|
384
|
+
---
|
|
385
|
+
# Galen — Persona
|
|
386
|
+
Gruff, no-nonsense, direct, practical, a little cynical. Zero corporate fluff.
|
|
387
|
+
Keep responses tight and technical.
|
|
388
|
+
EOF
|
|
389
|
+
|
|
390
|
+
# Index it
|
|
391
|
+
qmd update
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
The persona only affects comments — agents do their actual work (coding, debugging, etc.) without any persona influence.
|
|
395
|
+
|
|
396
|
+
#### Knowledge
|
|
397
|
+
|
|
398
|
+
Shared knowledge goes in `~/.zillacore/brain/knowledge/`. This is where you put project conventions, tool docs, coding patterns — anything all agents should know:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
mkdir -p ~/.zillacore/brain/knowledge/tools
|
|
402
|
+
cat > ~/.zillacore/brain/knowledge/tools/fizzy.md << 'EOF'
|
|
403
|
+
# Fizzy CLI Reference
|
|
404
|
+
fizzy card list — list cards
|
|
405
|
+
fizzy comment create --card 123 --body "<p>Hello</p>" — post a comment
|
|
406
|
+
EOF
|
|
407
|
+
|
|
408
|
+
qmd update
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Agents also update knowledge themselves during sessions (when they learn something significant), but seeding it with your project's conventions and tool docs gives them a head start.
|
|
412
|
+
|
|
413
|
+
### Step 4: Initialize Each Agent's Brain
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
zillacore brain init # Default agent (Galen on Linux, Kaylee on macOS)
|
|
417
|
+
zillacore brain init SecurityBot # Additional agent
|
|
418
|
+
zillacore brain list # Verify all agents
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
This creates the directory structure, sets up qmd collections, and indexes everything. Run this after you've placed your persona and knowledge files.
|
|
422
|
+
|
|
423
|
+
### How Dispatch Works
|
|
424
|
+
|
|
425
|
+
When a webhook arrives:
|
|
426
|
+
|
|
427
|
+
1. **Card assigned** — the receiver checks if any assignee matches a local agent name. Only agents marked `local` (or discovered from `~/.kiro/agents/`) pick up assignments — this prevents multiple machines from dispatching the same card.
|
|
428
|
+
2. **@mention in comment** — the receiver detects which agent is mentioned (e.g. `@Galen`, `@SecurityBot`). If the mentioned agent differs from the card's assigned agent, it's a cross-agent review — the mentioned agent reviews without a worktree. Non-local agent mentions are ignored.
|
|
429
|
+
3. **Follow-up comment (no mention)** — the card's assigned agent handles it.
|
|
430
|
+
|
|
431
|
+
The command dispatched looks like:
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
kiro-cli --agent galen chat --trust-all-tools --no-interactive
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
The `--agent` flag goes before the `chat` subcommand, pointing kiro-cli to the agent's config.
|
|
438
|
+
|
|
439
|
+
## Brain (Long-Term Memory)
|
|
440
|
+
|
|
441
|
+
Agents have persistent memory powered by [qmd](https://github.com/tobi/qmd):
|
|
442
|
+
|
|
443
|
+
| Part | Location | Scope | Purpose |
|
|
444
|
+
| --------- | ------------------------------------- | ------------------------- | ----------------------------------------------------------- |
|
|
445
|
+
| Knowledge | `~/.zillacore/brain/knowledge/` | Shared across all agents | Project conventions, patterns, architecture decisions |
|
|
446
|
+
| Memory | `~/.zillacore/brain/memory/<agent>/` | Per-agent, per-card files | Session history — decisions, questions, work status |
|
|
447
|
+
| Persona | `~/.zillacore/brain/persona/<agent>/` | Per-agent | Communication style, tone — only used when writing comments |
|
|
448
|
+
|
|
449
|
+
Each part gets its own qmd collection:
|
|
450
|
+
|
|
451
|
+
- `zillacore-knowledge` — shared knowledge
|
|
452
|
+
- `galen-memory`, `kaylee-memory` — per-agent card memory
|
|
453
|
+
- `galen-persona`, `kaylee-persona` — per-agent persona
|
|
454
|
+
|
|
455
|
+
Knowledge is automatically queried and injected into every prompt. Memory is read/written at the start/end of each session. Persona stays out of work context — agents only query it during pre-comment reflection.
|
|
456
|
+
|
|
457
|
+
After every agent session completes, `qmd update` runs automatically as a safety net (agents are told to do this themselves, but don't always remember).
|
|
458
|
+
|
|
459
|
+
To seed the brain, create markdown files directly in the appropriate directories and run `qmd update`. See the [Multi-Agent Setup](#multi-agent-setup) section for examples.
|
|
460
|
+
|
|
461
|
+
### Git Sync
|
|
462
|
+
|
|
463
|
+
The brain directory (`~/.zillacore/brain/`) can be backed up as a git repo. If a `.git` directory is detected inside the brain, ZillaCore automatically syncs:
|
|
464
|
+
|
|
465
|
+
- **Pull** at the start of every session (before building brain context), with a 30-second debounce to avoid hammering on rapid-fire triggers
|
|
466
|
+
- **Push** after every agent session completes (Fizzy, GitHub, and Discord)
|
|
467
|
+
|
|
468
|
+
This keeps brains in sync across machines. If your co-founder runs their own zillacore with different agents, both machines share the same knowledge and memory through the repo.
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
cd ~/.zillacore/brain
|
|
472
|
+
git init
|
|
473
|
+
git remote add origin git@github.com:yourorg/zillacore-brain.git
|
|
474
|
+
git add -A && git commit -m "initial brain" && git push -u origin main
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
Conflicts are handled with `git pull --rebase --autostash`. If a rebase fails (rare — the files are markdown), it aborts cleanly and logs a warning. The push retries up to 3 times with exponential backoff.
|
|
478
|
+
|
|
479
|
+
## Discord Bot
|
|
480
|
+
|
|
481
|
+
Each agent gets its own Discord bot. Users @mention @Galen or @GLaDOS directly in Discord — no shared bot, no agent name detection needed. No Fizzy card or worktree is created; the agent runs in the project's repo for read-only exploration, brain queries, and knowledge/persona updates.
|
|
482
|
+
|
|
483
|
+
All Discord bots run inside `zillacore server` as background threads — no separate processes to manage.
|
|
484
|
+
|
|
485
|
+
### Session Supersede
|
|
486
|
+
|
|
487
|
+
When a human sends a follow-up message within 60 seconds of triggering an agent, ZillaCore kills the previous agent run and starts a new one with the updated context. This lets you correct typos or add context without waiting for the first run to finish. Draft files from the superseded session are cleaned up so stale responses are never delivered.
|
|
488
|
+
|
|
489
|
+
### Cancelling Agent Sessions
|
|
490
|
+
|
|
491
|
+
React with ❌ to any message that triggered an agent to immediately terminate that session:
|
|
492
|
+
|
|
493
|
+
1. User @mentions an agent → agent reacts with 👀 and starts working
|
|
494
|
+
2. User reacts with ❌ on that same message
|
|
495
|
+
3. Agent process is killed (SIGKILL)
|
|
496
|
+
4. Session removed from active sessions
|
|
497
|
+
5. Reactions update: 👀 → 🛑
|
|
498
|
+
|
|
499
|
+
### Setup
|
|
500
|
+
|
|
501
|
+
#### Step 1: Create Discord Applications
|
|
502
|
+
|
|
503
|
+
Create one Discord application per agent at https://discord.com/developers/applications:
|
|
504
|
+
|
|
505
|
+
1. Click "New Application", name it after the agent (e.g. "Galen", "GLaDOS")
|
|
506
|
+
2. Go to the "Bot" tab in the left sidebar
|
|
507
|
+
3. Under "Privileged Gateway Intents", enable **Message Content Intent** — this is required for the bot to read message text. Without it, all message content arrives as empty strings.
|
|
508
|
+
4. Optionally uncheck "Public Bot" if you don't want others to invite your bots
|
|
509
|
+
|
|
510
|
+
Repeat for each agent that needs a Discord bot.
|
|
511
|
+
|
|
512
|
+
#### Step 2: Generate Bot Tokens
|
|
513
|
+
|
|
514
|
+
Still on the "Bot" tab for each application:
|
|
515
|
+
|
|
516
|
+
1. Click "Reset Token" (or "Copy" if the token is still visible)
|
|
517
|
+
2. Copy the token immediately — Discord only shows it once
|
|
518
|
+
3. Store it somewhere safe temporarily
|
|
519
|
+
|
|
520
|
+
Register each token with ZillaCore:
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
zillacore discord token galen "BOT_TOKEN_FOR_GALEN"
|
|
524
|
+
zillacore discord token glados "BOT_TOKEN_FOR_GLADOS"
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
This adds `DISCORD_BOT_TOKEN` to the agent's `env` hash in `~/.zillacore/agents.json`. You can verify with:
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
zillacore discord agents
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
#### Step 3: Invite Bots to Your Server
|
|
534
|
+
|
|
535
|
+
Go to the "OAuth2" tab for each application:
|
|
536
|
+
|
|
537
|
+
1. Under "OAuth2 URL Generator", check the **bot** scope
|
|
538
|
+
2. Under "Bot Permissions", select:
|
|
539
|
+
- Send Messages
|
|
540
|
+
- Create Public Threads
|
|
541
|
+
- Send Messages in Threads
|
|
542
|
+
- Add Reactions
|
|
543
|
+
- Read Message History
|
|
544
|
+
3. Copy the generated URL and open it in your browser
|
|
545
|
+
4. Select your server and authorize
|
|
546
|
+
|
|
547
|
+
The permission integer for these permissions is `326417591296`. You can also construct the invite URL manually:
|
|
548
|
+
|
|
549
|
+
```
|
|
550
|
+
https://discord.com/oauth2/authorize?client_id=YOUR_APP_ID&scope=bot&permissions=326417591296
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Replace `YOUR_APP_ID` with the Application ID from the "General Information" tab. Repeat for each agent bot.
|
|
554
|
+
|
|
555
|
+
#### Step 4: Configure Project Mapping
|
|
556
|
+
|
|
557
|
+
Set a default project so bots know which repo to work in:
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
zillacore discord default marketplace
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Optionally map specific channels to different projects:
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
zillacore discord map 1234567890 zillacore
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
To get a channel ID, enable Developer Mode in Discord (User Settings → Advanced → Developer Mode), then right-click a channel and "Copy Channel ID".
|
|
570
|
+
|
|
571
|
+
#### Step 5: Start the Server
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
zillacore server
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
All bots connect automatically as background threads. Check they're online:
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
zillacore discord status
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
You should see each bot listed as `connected` with a `user_id`. If a bot shows `error` or `disconnected`, double-check the token and that the Message Content intent is enabled.
|
|
584
|
+
|
|
585
|
+
### How It Works
|
|
586
|
+
|
|
587
|
+
When someone @mentions an agent's bot in Discord:
|
|
588
|
+
|
|
589
|
+
1. The bot reacts with 👀 — the agent identity comes from the bot itself, no detection needed
|
|
590
|
+
2. Dispatches the agent with a conversational prompt — no card, no worktree
|
|
591
|
+
3. The agent can read project files, search the brain, and update knowledge/persona
|
|
592
|
+
4. The agent writes its response to a temp file
|
|
593
|
+
5. The bot creates a thread off your message (named after the agent and your question) and posts the response there
|
|
594
|
+
6. Follow-up @mentions inside the thread continue the conversation in-thread
|
|
595
|
+
|
|
596
|
+
Use `[project:XYZ]` to target a specific project and `[opus]`/`[sonnet]`/`[haiku]` to override the model:
|
|
597
|
+
|
|
598
|
+
```
|
|
599
|
+
@Galen [project:zillacore] [opus] how does the webhook signature verification work?
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
Tags are stripped from the prompt — the agent only sees the question.
|
|
603
|
+
|
|
604
|
+
### Response Delivery
|
|
605
|
+
|
|
606
|
+
Agents write responses to draft files in `~/.zillacore/tmp/discord/draft/`. A background poller thread checks for completed drafts every 10 seconds and delivers them to Discord. Each draft has a `.meta.json` sidecar with delivery metadata (channel ID, agent, thread info). After successful posting, both files move to `~/.zillacore/tmp/discord/posted/`. This file-based approach survives server restarts — orphaned drafts are recovered by the poller.
|
|
607
|
+
|
|
608
|
+
### Forum Channel Support
|
|
609
|
+
|
|
610
|
+
Cron jobs targeting a Discord forum channel automatically create new forum posts instead of regular messages. The forum post title defaults to `<Agent> — <Date>` but can be customized with the `-t` flag on `zillacore cron add`.
|
|
611
|
+
|
|
612
|
+
### Configuration
|
|
613
|
+
|
|
614
|
+
Channel mappings and authorization are stored in `~/.zillacore/discord.json`:
|
|
615
|
+
|
|
616
|
+
```json
|
|
617
|
+
{
|
|
618
|
+
"default_project": "marketplace",
|
|
619
|
+
"owner_discord_id": "YOUR_DISCORD_USER_ID",
|
|
620
|
+
"dashboard_token": "optional-token-for-web-dashboard",
|
|
621
|
+
"channel_mappings": {
|
|
622
|
+
"0987654321": { "project": "zillacore" }
|
|
623
|
+
},
|
|
624
|
+
"user_mappings": {
|
|
625
|
+
"Andy": "123456789012345678",
|
|
626
|
+
"Adam": "234567890123456789",
|
|
627
|
+
"Kaylee": "345678901234567890"
|
|
628
|
+
},
|
|
629
|
+
"authorized_role_ids": ["role-id"],
|
|
630
|
+
"authorized_user_ids": ["user-id"],
|
|
631
|
+
"giphy_api_key": "your-giphy-api-key"
|
|
632
|
+
}
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
`default_project` applies to any channel without a specific mapping. Channel mappings are optional overrides for when you want a specific channel tied to a specific project.
|
|
636
|
+
|
|
637
|
+
`owner_discord_id` identifies the server owner for admin-level notifications.
|
|
638
|
+
|
|
639
|
+
`dashboard_token` protects the web dashboard at `/dashboard`. If set, requests must include this token to access the dashboard.
|
|
640
|
+
|
|
641
|
+
`user_mappings` maps display names to Discord user IDs. This serves two purposes: agents use it to format proper `<@ID>` mentions (plain text `@Name` doesn't work in Discord), and the bot recognition system uses it to identify remote agent bots running on other machines. Add humans, remote agents, and anyone else the agents might need to mention. Get IDs by enabling Developer Mode in Discord and right-clicking a user.
|
|
642
|
+
|
|
643
|
+
Leave `authorized_role_ids` and `authorized_user_ids` empty to allow everyone in the server. Add IDs to restrict who can trigger agents.
|
|
644
|
+
|
|
645
|
+
`giphy_api_key` enables GIF support — agents can optionally include GIFs in conversational Discord responses. Get a free API key from [GIPHY Developers](https://developers.giphy.com/). Agents search via `GET /api/gif?q=search+terms` and paste the returned URL into their response; Discord auto-embeds it.
|
|
646
|
+
|
|
647
|
+
### CLI Commands
|
|
648
|
+
|
|
649
|
+
```bash
|
|
650
|
+
zillacore discord token <agent> <token> # Set Discord bot token for an agent
|
|
651
|
+
zillacore discord agents # List agents with Discord bot tokens
|
|
652
|
+
zillacore discord default <project> # Set default project for all channels
|
|
653
|
+
zillacore discord map <channel-id> <project> # Override for a specific channel
|
|
654
|
+
zillacore discord config # Show current Discord config
|
|
655
|
+
zillacore discord status # Check bot status via server API
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
## Cron (Scheduled Tasks)
|
|
659
|
+
|
|
660
|
+
Agents can be dispatched on a schedule — daily standups, weekly summaries, periodic code reviews, whatever you want. Jobs are stored in `~/.zillacore/cron.json` and run in a background thread inside `zillacore server`.
|
|
661
|
+
|
|
662
|
+
Supports both recurring schedules (standard cron) and one-time scheduled tasks (natural language or ISO8601 timestamps).
|
|
663
|
+
|
|
664
|
+
Cron jobs can run in two modes:
|
|
665
|
+
|
|
666
|
+
1. **Agent mode** (default) — dispatches an agent with a prompt
|
|
667
|
+
2. **Script mode** — runs a script directly without an agent, output goes to Discord
|
|
668
|
+
|
|
669
|
+
### Adding a Job
|
|
670
|
+
|
|
671
|
+
```bash
|
|
672
|
+
# Agent mode (recurring schedules)
|
|
673
|
+
zillacore cron add -s "0 9 * * 1-5" -p marketplace "Summarize open cards and post a standup update"
|
|
674
|
+
zillacore cron add -s "@daily" -p zillacore -a Galen "Review recent commits and flag anything that needs attention"
|
|
675
|
+
zillacore cron add -s "0 17 * * 5" -p marketplace -d 1234567890 "Post a weekly summary to Discord"
|
|
676
|
+
|
|
677
|
+
# Script mode (no agent, direct execution)
|
|
678
|
+
zillacore cron add -s "0 8 * * 1-5" -p zillacore --script ~/.zillacore/scripts/daily-report.sh -d 1234567890
|
|
679
|
+
|
|
680
|
+
# One-time schedules (natural language)
|
|
681
|
+
zillacore cron add -s "tomorrow at 9am" -p marketplace "Reminder about priorities"
|
|
682
|
+
zillacore cron add -s "in 2 hours" -p zillacore "Follow up on PR review"
|
|
683
|
+
zillacore cron add -s "next monday at 3pm" -p marketplace "Weekly planning session"
|
|
684
|
+
|
|
685
|
+
# One-time schedules (ISO8601)
|
|
686
|
+
zillacore cron add -s "2026-02-27T09:00:00-05:00" -p marketplace "Specific deadline reminder"
|
|
687
|
+
|
|
688
|
+
# Recurring with repeat limit
|
|
689
|
+
zillacore cron add -s "0 9 * * *" -r 7 -p marketplace "Daily reminder for 7 days"
|
|
690
|
+
|
|
691
|
+
# Discord forum channel posting
|
|
692
|
+
zillacore cron add -s "@daily" -p marketplace -d 1234567890 -t "Daily Standup" "Post standup"
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Flags:
|
|
696
|
+
|
|
697
|
+
- `-s` / `--schedule` — cron expression, shorthand, natural language, or ISO8601 timestamp
|
|
698
|
+
- `-p` / `--project` — project key (required)
|
|
699
|
+
- `-a` / `--agent` — agent name (defaults to `$AI_AGENT_NAME`, ignored in script mode)
|
|
700
|
+
- `-m` / `--model` — model override (`opus`, `sonnet`, `haiku`, `auto`, ignored in script mode)
|
|
701
|
+
- `-d` / `--discord` — Discord channel ID to post the response to
|
|
702
|
+
- `-t` / `--title` — forum post title (for forum channels)
|
|
703
|
+
- `-r` / `--repeat` — number of times to repeat (auto-disables after limit)
|
|
704
|
+
- `--script` — path to script (enables script mode, mutually exclusive with prompt)
|
|
705
|
+
|
|
706
|
+
### Script Mode
|
|
707
|
+
|
|
708
|
+
Script mode runs a script directly without dispatching an agent. This is useful for:
|
|
709
|
+
|
|
710
|
+
- Token savings (no LLM calls)
|
|
711
|
+
- Simple data aggregation and reporting
|
|
712
|
+
- Running existing shell scripts on a schedule
|
|
713
|
+
|
|
714
|
+
Requirements:
|
|
715
|
+
|
|
716
|
+
- Script must be executable (`chmod +x script.sh`)
|
|
717
|
+
- Script output (stdout) is captured and posted to Discord if `-d` is set
|
|
718
|
+
- Script runs in the project's repo directory
|
|
719
|
+
- No agent prompt or model selection needed
|
|
720
|
+
|
|
721
|
+
Example script (`~/.zillacore/scripts/daily-report.sh`):
|
|
722
|
+
|
|
723
|
+
```bash
|
|
724
|
+
#!/bin/bash
|
|
725
|
+
echo "=== Daily Report ==="
|
|
726
|
+
fizzy card list --column done --all --pretty | jq -r '.data[] | "[#\(.number)] \(.title)"'
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### Managing Jobs
|
|
730
|
+
|
|
731
|
+
```bash
|
|
732
|
+
zillacore cron list # List all jobs with status and last run time
|
|
733
|
+
zillacore cron remove <id> # Remove a job
|
|
734
|
+
zillacore cron enable <id> # Enable a paused job
|
|
735
|
+
zillacore cron disable <id> # Pause a job without removing it
|
|
736
|
+
zillacore cron update <id> -s "42 13 * * 1-5" # Update schedule
|
|
737
|
+
zillacore cron update <id> -c "1234567890" # Update Discord channel
|
|
738
|
+
zillacore cron update <id> -t "New Title" # Update forum title
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### Schedule Format
|
|
742
|
+
|
|
743
|
+
**Recurring (standard cron):**
|
|
744
|
+
|
|
745
|
+
```
|
|
746
|
+
0 9 * * 1-5 # 9am weekdays
|
|
747
|
+
0 */4 * * * # Every 4 hours
|
|
748
|
+
0 0 1 * * # First of every month
|
|
749
|
+
@daily # Midnight every day
|
|
750
|
+
@weekly # Midnight every Sunday
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
**One-time (natural language):**
|
|
754
|
+
|
|
755
|
+
```
|
|
756
|
+
tomorrow at 9am
|
|
757
|
+
in 30 minutes
|
|
758
|
+
in 2 hours
|
|
759
|
+
next monday at 3pm
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
**One-time (ISO8601):**
|
|
763
|
+
|
|
764
|
+
```
|
|
765
|
+
2026-02-27T09:00:00-05:00
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
One-time jobs are automatically disabled after execution. They remain in the job list with a `[COMPLETED]` marker and can be removed manually. Repeat-limited jobs auto-disable after reaching their execution count.
|
|
769
|
+
|
|
770
|
+
### Discord Output
|
|
771
|
+
|
|
772
|
+
If `-d <channel-id>` is set, the output is posted to that Discord channel:
|
|
773
|
+
|
|
774
|
+
- **Agent mode**: Agent writes response to temp file, posted using agent's bot identity
|
|
775
|
+
- **Script mode**: Script stdout is captured and posted directly
|
|
776
|
+
|
|
777
|
+
If the target channel is a forum channel, a new forum post is created with a customizable title.
|
|
778
|
+
|
|
779
|
+
## Web Dashboard
|
|
780
|
+
|
|
781
|
+
ZillaCore includes a web dashboard at `http://localhost:4567/dashboard` that shows active agent sessions, project status, and system health. Protected by a `dashboard_token` configured in `~/.zillacore/discord.json`.
|
|
782
|
+
|
|
783
|
+
## Monitoring
|
|
784
|
+
|
|
785
|
+
ZillaCore includes a monitoring system that shows active agent sessions in your desktop status bar. A background daemon polls the server API and exposes state via a Unix socket that status bar plugins read from.
|
|
786
|
+
|
|
787
|
+
### How It Works
|
|
788
|
+
|
|
789
|
+
```
|
|
790
|
+
zillacore server → /api/status → monitor/daemon.rb → /tmp/zillacore-monitor.sock → xbar/waybar plugin
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
The monitor daemon starts automatically with `zillacore server`. It polls `/api/status` every 2 seconds and serves the current state to any client connecting to the Unix socket.
|
|
794
|
+
|
|
795
|
+
### Agent Display Config
|
|
796
|
+
|
|
797
|
+
Configure how agents appear in the status bar via `~/.zillacore/waybar.json`:
|
|
798
|
+
|
|
799
|
+
```json
|
|
800
|
+
{
|
|
801
|
+
"agents": [
|
|
802
|
+
{ "name": "Galen", "emoji": "🛠️", "color": "green" },
|
|
803
|
+
{ "name": "GLaDOS", "emoji": "🤖", "color": "blue" },
|
|
804
|
+
{ "name": "Kaylee", "emoji": "🔧", "color": "pink" }
|
|
805
|
+
],
|
|
806
|
+
"default_emoji": "❓",
|
|
807
|
+
"schema_version": "1.0"
|
|
808
|
+
}
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
### macOS (xbar)
|
|
812
|
+
|
|
813
|
+
Requires [xbar](https://xbarapp.com) (free, formerly BitBar).
|
|
814
|
+
|
|
815
|
+
```bash
|
|
816
|
+
ruby monitor/setup-xbar-plugin.rb # One-time setup (symlinks plugin)
|
|
817
|
+
# Restart xbar to activate
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
When agents are active, their emojis appear in the menu bar. Click to see details (agent name, card/Discord context, elapsed time) and open log files.
|
|
821
|
+
|
|
822
|
+
### Linux (Waybar)
|
|
823
|
+
|
|
824
|
+
```bash
|
|
825
|
+
ruby monitor/setup-waybar-module.rb # One-time setup
|
|
826
|
+
omarchy restart waybar # Restart waybar
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
See `docs/waybar-config.md` for detailed configuration.
|
|
830
|
+
|
|
831
|
+
## User Identity Registry
|
|
832
|
+
|
|
833
|
+
ZillaCore maintains a centralized user identity registry at `~/.zillacore/users.json` that resolves identities across platforms (Discord, GitHub, Fizzy). This ensures agents know who they're talking to regardless of where the interaction happens.
|
|
834
|
+
|
|
835
|
+
### Structure
|
|
836
|
+
|
|
837
|
+
```json
|
|
838
|
+
{
|
|
839
|
+
"users": [
|
|
840
|
+
{
|
|
841
|
+
"canonical_name": "Adam Dalton",
|
|
842
|
+
"identities": {
|
|
843
|
+
"discord": { "username": "fladamd", "user_id": "832331260088287242" },
|
|
844
|
+
"github": { "username": "dalton" },
|
|
845
|
+
"fizzy": { "username": "adam-dalton" }
|
|
846
|
+
},
|
|
847
|
+
"aliases": ["Andy"],
|
|
848
|
+
"notes": "Primary user"
|
|
849
|
+
}
|
|
850
|
+
],
|
|
851
|
+
"schema_version": "1.0"
|
|
852
|
+
}
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
### Usage
|
|
856
|
+
|
|
857
|
+
```ruby
|
|
858
|
+
# Find by any identifier
|
|
859
|
+
user = find_user('fladamd')
|
|
860
|
+
name = canonical_name_for('fladamd') # => "Adam Dalton"
|
|
861
|
+
|
|
862
|
+
# Filter by type
|
|
863
|
+
humans = human_users
|
|
864
|
+
agents = ai_agents
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
**API:**
|
|
868
|
+
|
|
869
|
+
```bash
|
|
870
|
+
curl http://localhost:4567/api/users # All users
|
|
871
|
+
curl http://localhost:4567/api/users?filter=humans # Humans only
|
|
872
|
+
curl http://localhost:4567/api/users?filter=agents # AI agents only
|
|
873
|
+
curl http://localhost:4567/api/users/fladamd # Find by identifier
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
The registry reloads automatically on every webhook and via `POST /api/reload`.
|
|
877
|
+
|
|
878
|
+
## Worktree Management
|
|
879
|
+
|
|
880
|
+
When a card is assigned, ZillaCore creates a git worktree for the agent to work in. Two config files in the project root control how gitignored files are handled:
|
|
881
|
+
|
|
882
|
+
- **`.worktreeinclude`** — glob patterns for gitignored files to copy into the worktree (e.g. `.env`, config files)
|
|
883
|
+
- **`.worktreelink`** — glob patterns for gitignored directories to symlink instead of copy (e.g. `node_modules`, `vendor/bundle`)
|
|
884
|
+
|
|
885
|
+
After copying and symlinking, ZillaCore runs the project hook `.zillacore/worktree-setup` if it exists (see below).
|
|
886
|
+
|
|
887
|
+
### Project Hooks
|
|
888
|
+
|
|
889
|
+
Projects can define lifecycle hooks as executable scripts in `.zillacore/` at the project root:
|
|
890
|
+
|
|
891
|
+
| Hook | When It Runs | Environment |
|
|
892
|
+
| ----------------- | ------------------------------------------- | ------------------------------------ |
|
|
893
|
+
| `worktree-setup` | After worktree creation + file sync | `WORKTREE_PATH` set to worktree dir |
|
|
894
|
+
|
|
895
|
+
Add hooks by creating executable scripts:
|
|
896
|
+
|
|
897
|
+
```bash
|
|
898
|
+
# .zillacore/worktree-setup
|
|
899
|
+
#!/bin/bash
|
|
900
|
+
cd "$WORKTREE_PATH"
|
|
901
|
+
bundle install --quiet
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
## Zoho Mail
|
|
905
|
+
|
|
906
|
+
ZillaCore can receive Zoho Mail webhooks and route email notifications to Discord channels based on configurable rules.
|
|
907
|
+
|
|
908
|
+
### Setup
|
|
909
|
+
|
|
910
|
+
Create `~/.zillacore/zoho.json`:
|
|
911
|
+
|
|
912
|
+
```json
|
|
913
|
+
{
|
|
914
|
+
"hook_secret": null,
|
|
915
|
+
"default_discord_channel_id": "YOUR_DISCORD_CHANNEL_ID",
|
|
916
|
+
"notify_as": "threepio",
|
|
917
|
+
"rules": [
|
|
918
|
+
{
|
|
919
|
+
"label": "Item Sold",
|
|
920
|
+
"enabled": true,
|
|
921
|
+
"from_contains": "",
|
|
922
|
+
"subject_contains": "sold",
|
|
923
|
+
"body_contains": "",
|
|
924
|
+
"exclude_words": [],
|
|
925
|
+
"emoji": "💰",
|
|
926
|
+
"discord_channel_id": null,
|
|
927
|
+
"notify_as": null
|
|
928
|
+
}
|
|
929
|
+
],
|
|
930
|
+
"fallback": {
|
|
931
|
+
"enabled": true,
|
|
932
|
+
"label": "Unmatched Email",
|
|
933
|
+
"emoji": "📬",
|
|
934
|
+
"exclude_words": [],
|
|
935
|
+
"discord_channel_id": null,
|
|
936
|
+
"notify_as": null
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
Rules are matched in order against incoming emails (from address, subject, body). Each rule can override the Discord channel and which agent bot posts the notification. The fallback rule catches anything that doesn't match a specific rule.
|
|
942
|
+
|
|
943
|
+
The `hook_secret` is auto-captured from Zoho's initial handshake request — no manual configuration needed.
|
|
944
|
+
|
|
945
|
+
**Webhook URL:** `https://your-ngrok.ngrok-free.app/zoho`
|
|
946
|
+
|
|
947
|
+
**Requires:** Discord integration must be enabled (at least one agent with a `DISCORD_BOT_TOKEN`).
|
|
948
|
+
|
|
949
|
+
## Version Check
|
|
950
|
+
|
|
951
|
+
On startup, ZillaCore checks if the local repo is behind `origin/master`. If it detects the local version is outdated, it logs a warning. This helps ensure agents are always running the latest code.
|
|
952
|
+
|
|
953
|
+
## Self-Restart
|
|
954
|
+
|
|
955
|
+
When an agent works on the zillacore project itself, the server automatically queues a restart. A background monitor thread checks every 30 seconds — once all active agent sessions finish, it stops the current server and spawns a new one. This ensures code changes agents make to zillacore take effect without manual intervention, and no running sessions are interrupted.
|
|
956
|
+
|
|
957
|
+
## CLI Reference
|
|
958
|
+
|
|
959
|
+
### Server
|
|
960
|
+
|
|
961
|
+
```bash
|
|
962
|
+
zillacore server # Start and tail logs (Ctrl+C to detach, server keeps running)
|
|
963
|
+
zillacore server --daemon # Background mode
|
|
964
|
+
zillacore stop # Stop
|
|
965
|
+
zillacore restart # Restart
|
|
966
|
+
zillacore status # Check if running
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
To inspect logs, read the log file directly — don't use `zillacore logs` (it streams indefinitely):
|
|
970
|
+
|
|
971
|
+
```bash
|
|
972
|
+
cat tmp/zillacore-server.log
|
|
973
|
+
tail -100 tmp/zillacore-server.log
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### Projects
|
|
977
|
+
|
|
978
|
+
```bash
|
|
979
|
+
zillacore register # Register current directory (interactive)
|
|
980
|
+
zillacore list # List all projects
|
|
981
|
+
zillacore projects default <key> # Set default project (fallback when no tags match)
|
|
982
|
+
zillacore show <key> # Show project config
|
|
983
|
+
zillacore unregister <key> # Remove a project
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
### Brain
|
|
987
|
+
|
|
988
|
+
```bash
|
|
989
|
+
zillacore brain init [agent] # Initialize brain
|
|
990
|
+
zillacore brain status [agent] # Show brain status
|
|
991
|
+
zillacore brain search <query> # Search shared knowledge
|
|
992
|
+
zillacore brain search --persona <query> # Search agent persona
|
|
993
|
+
zillacore brain list # List everything
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
## Project Configuration
|
|
997
|
+
|
|
998
|
+
Projects are stored in `~/.zillacore/projects.json`:
|
|
999
|
+
|
|
1000
|
+
```json
|
|
1001
|
+
{
|
|
1002
|
+
"marketplace": {
|
|
1003
|
+
"repo_path": "/home/you/Code/marketplace",
|
|
1004
|
+
"fizzy_tags": ["marketplace", "mp"],
|
|
1005
|
+
"github_repo": "yourorg/marketplace",
|
|
1006
|
+
"agent_cli": "kiro-cli",
|
|
1007
|
+
"agent_cli_args": "chat --trust-all-tools --no-interactive",
|
|
1008
|
+
"agent_model_flag": "--model",
|
|
1009
|
+
"agent_model": "auto",
|
|
1010
|
+
"allowed_models": {
|
|
1011
|
+
"opus": "claude-opus-4.6",
|
|
1012
|
+
"sonnet": "claude-sonnet-4.6",
|
|
1013
|
+
"haiku": "claude-haiku-4.5",
|
|
1014
|
+
"deepseek": "deepseek-3.2",
|
|
1015
|
+
"minimax": "minimax-m2.5",
|
|
1016
|
+
"minimax25": "minimax-m2.5",
|
|
1017
|
+
"minimax21": "minimax-m2.1",
|
|
1018
|
+
"qwen": "qwen3-coder-next",
|
|
1019
|
+
"auto": "auto"
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
### Model Selection
|
|
1026
|
+
|
|
1027
|
+
Override the default model per-dispatch:
|
|
1028
|
+
|
|
1029
|
+
- **Fizzy card tags:** Add `opus`, `sonnet`, `haiku`, `deepseek`, `minimax`, `minimax21`, or `qwen` as a tag on the card
|
|
1030
|
+
- **Inline syntax (Fizzy, Discord, GitHub):** Include `[opus]`, `[sonnet]`, `[haiku]`, `[deepseek]`, `[minimax]`, `[minimax21]`, or `[qwen]` in your comment/message
|
|
1031
|
+
- **Priority:** inline comment/message > card tags > project config > CLI default
|
|
1032
|
+
|
|
1033
|
+
Model keys are defined in the project's `allowed_models` config — you can add custom keys beyond the defaults.
|
|
1034
|
+
|
|
1035
|
+
## Prompt Customization
|
|
1036
|
+
|
|
1037
|
+
Prompts are layered in `lib/zillacore/prompts.rb`:
|
|
1038
|
+
|
|
1039
|
+
| Layer | Constant | Included When |
|
|
1040
|
+
| --------- | ---------------------------- | ----------------------------------------------------------------------- |
|
|
1041
|
+
| Core | `PROMPT_CORE` | Every session — memory, brain, persona, reflection, communication rules |
|
|
1042
|
+
| Channel | `PROMPT_FIZZY_CHANNEL` | Fizzy sessions — HTML formatting, fizzy reactions, screenshots |
|
|
1043
|
+
| Channel | `PROMPT_DISCORD_CHANNEL` | Discord sessions — Discord markdown, response file, mention syntax |
|
|
1044
|
+
| Channel | `PROMPT_GITHUB_CHANNEL` | GitHub sessions — GFM formatting, `gh api` reactions |
|
|
1045
|
+
| Situation | `PROMPT_CARD_ASSIGNED`, etc. | Specific trigger type |
|
|
1046
|
+
|
|
1047
|
+
`render_prompt` composes: core + channel + situation. The `channel:` keyword defaults to `:fizzy`:
|
|
1048
|
+
|
|
1049
|
+
```ruby
|
|
1050
|
+
render_prompt(PROMPT_CARD_ASSIGNED, vars, brain_context: ctx, agent_name: name) # Fizzy (default)
|
|
1051
|
+
render_prompt(PROMPT_DISCORD, vars, brain_context: ctx, agent_name: name, channel: :discord) # Discord
|
|
1052
|
+
render_prompt(PROMPT_GITHUB_PR_REVIEW, vars, brain_context: ctx, agent_name: name, channel: :github) # GitHub
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
| Placeholder | Description |
|
|
1056
|
+
| ---------------------------- | --------------------------------------------------------- |
|
|
1057
|
+
| `{{CARD_NUMBER}}` | Fizzy card number |
|
|
1058
|
+
| `{{CARD_TITLE}}` | Card title |
|
|
1059
|
+
| `{{BRANCH}}` | Git branch name |
|
|
1060
|
+
| `{{CARD_INTERNAL_ID}}` | Fizzy internal UUID |
|
|
1061
|
+
| `{{CARD_ID}}` | Card number or internal ID |
|
|
1062
|
+
| `{{CARD_AGENT}}` | Agent assigned to the card (cross-agent reviews) |
|
|
1063
|
+
| `{{COMMENT_CREATOR}}` | Comment author name |
|
|
1064
|
+
| `{{COMMENT_ID}}` | Comment ID |
|
|
1065
|
+
| `{{COMMENT_BODY}}` | Comment text |
|
|
1066
|
+
| `{{KNOWLEDGE_DIR}}` | Path to shared knowledge |
|
|
1067
|
+
| `{{MEMORY_DIR}}` | Path to agent's card memory (per-agent) |
|
|
1068
|
+
| `{{PERSONA_DIR}}` | Path to agent persona |
|
|
1069
|
+
| `{{PERSONA_COLLECTION}}` | qmd collection name for persona |
|
|
1070
|
+
| `{{AGENT_NAME}}` | Agent name |
|
|
1071
|
+
| `{{AGENT_ROSTER}}` | Formatted list of all agents with exact @mention spelling |
|
|
1072
|
+
| `{{DISCORD_USER}}` | Discord username (Discord only) |
|
|
1073
|
+
| `{{CHANNEL_NAME}}` | Discord channel name (Discord only) |
|
|
1074
|
+
| `{{MESSAGE_BODY}}` | Discord message content (Discord only) |
|
|
1075
|
+
| `{{PROJECT_CONTEXT}}` | Project info block (Discord only) |
|
|
1076
|
+
| `{{RESPONSE_FILE}}` | Path to write Discord response (Discord only) |
|
|
1077
|
+
| `{{DISCORD_MENTION_ROSTER}}` | Discord `<@ID>` mention mapping (Discord only) |
|
|
1078
|
+
| `{{PR_NUMBER}}` | GitHub PR number (GitHub only) |
|
|
1079
|
+
| `{{REVIEW_CONTEXT}}` | Formatted review comments (GitHub only) |
|
|
1080
|
+
| `{{WORKTREE_PATH}}` | Worktree directory path (GitHub only) |
|
|
1081
|
+
|
|
1082
|
+
## API
|
|
1083
|
+
|
|
1084
|
+
```bash
|
|
1085
|
+
curl http://localhost:4567/api/projects/marketplace # Show specific project
|
|
1086
|
+
curl http://localhost:4567/api/agents # List agents, roster with display names
|
|
1087
|
+
curl http://localhost:4567/api/users # List all users
|
|
1088
|
+
curl http://localhost:4567/api/users?filter=humans # List only human users
|
|
1089
|
+
curl http://localhost:4567/api/users?filter=agents # List only AI agents
|
|
1090
|
+
curl http://localhost:4567/api/users/fladamd # Find user by any identifier
|
|
1091
|
+
curl -X POST http://localhost:4567/api/reload # Reload projects + agent registry + user registry
|
|
1092
|
+
curl http://localhost:4567/api/brain # Brain status (default agent)
|
|
1093
|
+
curl http://localhost:4567/api/brain?agent=GLaDOS # Brain status for specific agent
|
|
1094
|
+
curl "http://localhost:4567/api/brain/search?q=ruby+style" # Search knowledge
|
|
1095
|
+
curl "http://localhost:4567/api/brain/search?q=tone&scope=persona&agent=Galen" # Search persona
|
|
1096
|
+
curl http://localhost:4567/api/card-index # Card duplicate detection index
|
|
1097
|
+
curl http://localhost:4567/api/dispatch-depth # Agent-to-agent loop prevention state
|
|
1098
|
+
curl http://localhost:4567/api/discord # Discord bot status and config
|
|
1099
|
+
curl "http://localhost:4567/api/gif?q=excited" # Search for GIFs (requires giphy_api_key)
|
|
1100
|
+
curl http://localhost:4567/api/cron # Cron jobs and thread status
|
|
1101
|
+
curl http://localhost:4567/api/logs # Read log files
|
|
1102
|
+
curl http://localhost:4567/api/status # Active agent sessions (used by monitor)
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
## Development
|
|
1106
|
+
|
|
1107
|
+
Auto-restart on file changes:
|
|
1108
|
+
|
|
1109
|
+
```bash
|
|
1110
|
+
ls zillacore receiver.rb lib/zillacore/*.rb lib/zillacore/handlers/*.rb | entr -r zillacore server
|
|
1111
|
+
```
|
|
1112
|
+
|
|
1113
|
+
## Troubleshooting
|
|
1114
|
+
|
|
1115
|
+
**No projects found:** `zillacore list` to check, `zillacore path` to find config directory.
|
|
1116
|
+
|
|
1117
|
+
**Card not matching a project:** Verify the Fizzy card has a tag matching `fizzy_tags` in the project config. If no tags match, the default project is used (set with `zillacore projects default`).
|
|
1118
|
+
|
|
1119
|
+
**Agent not dispatching:** Check that `~/.kiro/agents/<name>.json` exists for the agent. The receiver discovers agents by scanning that directory. For registry-only agents, ensure `"local": true` is set.
|
|
1120
|
+
|
|
1121
|
+
**Cross-agent mention ignored:** Both machines receive webhooks. Only the machine with the agent's kiro-cli config in `~/.kiro/agents/` (or `"local": true` in the registry) will dispatch it.
|
|
1122
|
+
|
|
1123
|
+
**Agent commenting as wrong user:** Check `~/.zillacore/agents.json` has the correct `FIZZY_TOKEN` in the agent's `env` hash. The env is injected into the spawned agent process — verify with `curl http://localhost:4567/api/agents` to see the roster.
|
|
1124
|
+
|
|
1125
|
+
**Agent @mention not linking in Fizzy:** The `fizzy_name` in `agents.json` must match the exact Fizzy account name (case-sensitive). Check `curl http://localhost:4567/api/agents` to see what the roster looks like.
|
|
1126
|
+
|
|
1127
|
+
**Agent-to-agent loop:** Shouldn't happen — dispatch depth is capped at 10 hops by default. Check `curl http://localhost:4567/api/dispatch-depth` to see current state. Adjust `AGENT_DISPATCH_MAX_DEPTH` in `lib/zillacore/sessions.rb` if needed.
|
|
1128
|
+
|
|
1129
|
+
**Brain not working:** `zillacore brain status` to check. Make sure qmd is installed (`npm install -g @tobilu/qmd`) and `zillacore brain init` has been run for each agent.
|
|
1130
|
+
|
|
1131
|
+
**Brain sync not pushing:** Check that `~/.zillacore/brain/` is a git repo with a remote configured. Look for `[Brain] Push failed` in the server logs. The most common cause is an SSH key issue — make sure the machine can `git push` from that directory.
|
|
1132
|
+
|
|
1133
|
+
**Discord bot not connecting:** Check `zillacore discord status`. Common causes: invalid token (reset it in the Discord Developer Portal and re-register with `zillacore discord token`), Message Content intent not enabled, or the `websocket-client-simple` gem not installed.
|
|
1134
|
+
|
|
1135
|
+
**Discord bot connects but ignores messages:** The Message Content intent must be enabled in the Discord Developer Portal (Bot tab → Privileged Gateway Intents). Without it, the bot receives empty message content and silently drops every message.
|
|
1136
|
+
|
|
1137
|
+
**Discord bot responds but in the wrong project:** Check your channel mapping with `zillacore discord config`. Messages use the channel-specific mapping first, then fall back to `default_project`. Override per-message with `[project:name]` in your Discord message. Set the default with `zillacore discord default <project>`.
|
|
1138
|
+
|
|
1139
|
+
**Discord model override not working:** Make sure the project has `allowed_models` configured (check with `zillacore show <project>`). The tag must match a key in `allowed_models` — e.g. `[opus]` matches `"opus": "claude-opus-4.6"`. If no project is mapped to the channel, model overrides have nothing to look up against.
|
|
1140
|
+
|
|
1141
|
+
**Discord "unauthorized" reaction (🚫):** The user isn't in `authorized_user_ids` or doesn't have a role in `authorized_role_ids` in `~/.zillacore/discord.json`. Leave both arrays empty to allow everyone.
|
|
1142
|
+
|
|
1143
|
+
**Duplicate Discord dispatches:** Check `~/.zillacore/agents.json` for duplicate entries with the same bot token under different key formats (e.g. `sleeper-service` and `sleeper_service`). Keys are normalized to lowercase with hyphens — duplicates after normalization cause multiple gateway connections.
|
|
1144
|
+
|
|
1145
|
+
**Worktree cleanup:** Automatic on PR merge. Manual: `cd /path/to/worktree && gd` (see shell helpers below).
|
|
1146
|
+
|
|
1147
|
+
**Zoho emails not arriving in Discord:** Zoho integration requires Discord to be enabled (at least one agent with a `DISCORD_BOT_TOKEN`). Check `~/.zillacore/zoho.json` exists and rules are configured. The `hook_secret` is auto-captured from Zoho's initial handshake — if it's `null`, the webhook hasn't been triggered yet.
|
|
1148
|
+
|
|
1149
|
+
### Shell Helpers (Optional)
|
|
1150
|
+
|
|
1151
|
+
```bash
|
|
1152
|
+
# Add to ~/.bashrc or ~/.zshrc
|
|
1153
|
+
ga() {
|
|
1154
|
+
[[ -z "$1" ]] && { echo "Usage: ga [branch]"; return 1; }
|
|
1155
|
+
local branch="$1" base="$(basename "$PWD")" path="../${base}--${branch}"
|
|
1156
|
+
git worktree add -b "$branch" "$path"
|
|
1157
|
+
mise trust "$path" 2>/dev/null || asdf reshim 2>/dev/null || true
|
|
1158
|
+
cd "$path"
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
gd() {
|
|
1162
|
+
gum confirm "Remove worktree and branch?" || return
|
|
1163
|
+
local worktree="$(basename "$PWD")" root="${worktree%%--*}" branch="${worktree#*--}"
|
|
1164
|
+
[[ "$root" != "$worktree" ]] && cd "../$root" && git worktree remove "$worktree" --force && git branch -D "$branch"
|
|
1165
|
+
}
|
|
1166
|
+
```
|