zuzu 0.2.1-java → 0.2.3-java

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.
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: customize
3
+ description: Customize the Zuzu app — change the app name, window size, system prompt persona, or extend the UI. Use when the developer wants to rebrand the app, add personality to the assistant, or make visual/behavioral changes.
4
+ ---
5
+
6
+ # Customize Zuzu App
7
+
8
+ Ask what the developer wants to change, then make the changes directly.
9
+
10
+ ## Step 1 — Understand the request
11
+
12
+ AskUserQuestion: "What would you like to customize? Choose one or more:
13
+ 1. App name / window title
14
+ 2. Window size
15
+ 3. Assistant persona / system prompt instructions
16
+ 4. Add a new button or panel to the UI
17
+ 5. Something else — describe it"
18
+
19
+ Route to the relevant section below based on the answer.
20
+
21
+ ---
22
+
23
+ ## Route A — App name and window title
24
+
25
+ Read the current value from `app.rb`:
26
+
27
+ ```ruby
28
+ Zuzu.configure do |c|
29
+ c.app_name = 'Current Name'
30
+ ```
31
+
32
+ AskUserQuestion: "What should the app be called?"
33
+
34
+ Edit `app.rb` — update `c.app_name`. Done. Tell the user to restart the app.
35
+
36
+ ---
37
+
38
+ ## Route B — Window size
39
+
40
+ Read current values (`c.window_width`, `c.window_height`).
41
+
42
+ AskUserQuestion: "What size should the window be? (e.g. 1024 × 768, 1280 × 800)"
43
+
44
+ Edit `app.rb`:
45
+ ```ruby
46
+ c.window_width = 1024
47
+ c.window_height = 768
48
+ ```
49
+
50
+ Done. Tell the user to restart.
51
+
52
+ ---
53
+
54
+ ## Route C — Assistant persona and system prompt
55
+
56
+ Read the current `c.system_prompt_extras` from `app.rb` (may be nil/absent).
57
+
58
+ AskUserQuestion: "Describe the assistant's persona or any extra rules you want it to follow. Examples:
59
+ - 'You are a Ruby developer assistant. Always use Ruby in code examples.'
60
+ - 'You are a cooking assistant. Only discuss food, recipes, and nutrition.'
61
+ - 'Always respond concisely in bullet points.'"
62
+
63
+ AskUserQuestion: "Should this replace the current instructions or be added to them?"
64
+
65
+ Edit `app.rb` — set or update `c.system_prompt_extras`:
66
+
67
+ ```ruby
68
+ Zuzu.configure do |c|
69
+ # ...
70
+ c.system_prompt_extras = <<~EXTRA
71
+ <the persona instructions here>
72
+ EXTRA
73
+ end
74
+ ```
75
+
76
+ **Important rules to preserve** — always keep these in `system_prompt_extras` if the developer's text doesn't already cover them:
77
+ - Do not override the tool-calling rules (those come from the base prompt automatically)
78
+ - Keep instructions concise — the model sees this verbatim on every request
79
+
80
+ Verify it loads:
81
+ ```bash
82
+ bundle exec ruby -e "require 'zuzu'; load 'app.rb' rescue nil; puts Zuzu.config.system_prompt_extras" 2>&1
83
+ ```
84
+
85
+ Done. Tell the user to restart.
86
+
87
+ ---
88
+
89
+ ## Route D — UI: add a button to the Admin Panel
90
+
91
+ The Admin Panel is the popup window opened by the "Admin Panel" button.
92
+ The easiest UI extension is adding a button there.
93
+
94
+ AskUserQuestion: "What should the button do when clicked?"
95
+ AskUserQuestion: "What label should the button have?"
96
+
97
+ This requires subclassing `Zuzu::App`. Check if `app.rb` already subclasses it.
98
+
99
+ **If not subclassing yet**, add this pattern to `app.rb` before `Zuzu::App.launch!`:
100
+
101
+ ```ruby
102
+ class MyApp < Zuzu::App
103
+ private
104
+
105
+ def open_admin_panel
106
+ file_list_widget = nil
107
+
108
+ admin = shell {
109
+ text 'Admin Panel'
110
+ minimum_size 380, 500
111
+ grid_layout 1, false
112
+
113
+ label {
114
+ layout_data(:fill, :fill, true, false)
115
+ text 'AgentFS — Virtual File Browser'
116
+ font height: 12, style: :bold
117
+ }
118
+
119
+ file_list_widget = list(:single, :v_scroll, :border) {
120
+ layout_data(:fill, :fill, true, true)
121
+ font name: 'Monospace', height: 11
122
+ }
123
+
124
+ # ── Default buttons (keep these) ─────────────────────────
125
+ button {
126
+ layout_data(:fill, :fill, true, false)
127
+ text 'Create Test File'
128
+ on_widget_selected {
129
+ @fs.write_file('/test.txt', "Hello!\nCreated at: #{Time.now}")
130
+ populate_file_list(file_list_widget)
131
+ }
132
+ }
133
+
134
+ button {
135
+ layout_data(:fill, :fill, true, false)
136
+ text 'Clear Chat History'
137
+ on_widget_selected {
138
+ @memory.clear
139
+ message_box { text 'Done'; message 'History cleared.' }.open
140
+ }
141
+ }
142
+
143
+ button {
144
+ layout_data(:fill, :fill, true, false)
145
+ text 'Refresh'
146
+ on_widget_selected { populate_file_list(file_list_widget) }
147
+ }
148
+
149
+ # ── New custom button ─────────────────────────────────────
150
+ button {
151
+ layout_data(:fill, :fill, true, false)
152
+ text '<Button Label>'
153
+ on_widget_selected {
154
+ # your action here
155
+ message_box { text 'Done'; message 'Action completed.' }.open
156
+ }
157
+ }
158
+ }
159
+
160
+ populate_file_list(file_list_widget)
161
+ admin.open
162
+ end
163
+ end
164
+ ```
165
+
166
+ Then change the launch line to:
167
+ ```ruby
168
+ MyApp.launch!(use_llamafile: true)
169
+ ```
170
+
171
+ **Glimmer DSL rules to enforce:**
172
+ - `layout_data(:fill, :fill, true, false)` — always use argument form, never block form
173
+ - Never call widget methods from a background thread — wrap in `async_exec { }`
174
+ - Never use `sash_form` — invisible on macOS
175
+
176
+ Verify syntax:
177
+ ```bash
178
+ bundle exec ruby -e "require 'zuzu'; load 'app.rb' rescue puts $!.message" 2>&1
179
+ ```
180
+
181
+ Done. Tell the user to restart.
182
+
183
+ ---
184
+
185
+ ## Route E — Something else
186
+
187
+ Read `AGENTS.md` for the relevant section and implement accordingly.
188
+ Always verify with a syntax check after making changes:
189
+
190
+ ```bash
191
+ bundle exec ruby -e "require 'zuzu'; load 'app.rb' rescue puts $!.message" 2>&1
192
+ ```
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: debug
3
+ description: Diagnose and fix Zuzu app issues. Use when the app won't start, the agent isn't responding, tools aren't being called, the LLM seems stuck, or the UI is broken. Runs a systematic health check and fixes what it finds.
4
+ ---
5
+
6
+ # Debug Zuzu App
7
+
8
+ Run each check in order. Fix problems as they're found — don't present a list and ask the user to fix them.
9
+
10
+ ## Check 1 — Ruby code syntax
11
+
12
+ ```bash
13
+ bundle exec ruby -e "require 'zuzu'; load 'app.rb'" 2>&1
14
+ ```
15
+
16
+ - If syntax error or LoadError: fix the error in `app.rb`, re-run, continue.
17
+ - If clean: continue.
18
+
19
+ ## Check 2 — Registered tools
20
+
21
+ ```bash
22
+ bundle exec ruby -e "
23
+ require 'zuzu'
24
+ load 'app.rb' rescue nil
25
+ tools = Zuzu::ToolRegistry.tools
26
+ if tools.empty?
27
+ puts 'WARNING: No tools registered'
28
+ else
29
+ tools.each { |t| puts ' - ' + t.name + ': ' + t.description }
30
+ end
31
+ " 2>&1
32
+ ```
33
+
34
+ - No tools: check `app.rb` — registrations must be before `Zuzu::App.launch!`. Fix and retry.
35
+ - Tools listed: continue.
36
+
37
+ ## Check 3 — Model file
38
+
39
+ Read `app.rb` to find `c.llamafile_path`. Then:
40
+
41
+ ```bash
42
+ ls -lh <model_path> 2>&1
43
+ ```
44
+
45
+ - File not found: tell the user they need to download the model to the `models/` directory.
46
+ - File exists but not executable: `chmod +x <model_path>` — do this automatically.
47
+ - File ok: continue.
48
+
49
+ ## Check 4 — Is llamafile running?
50
+
51
+ ```bash
52
+ curl -s --max-time 3 http://127.0.0.1:8080/v1/models 2>&1
53
+ ```
54
+
55
+ - Connection refused / timeout: llamafile isn't running. The app starts it — check the log:
56
+
57
+ ```bash
58
+ ls models/*.log 2>/dev/null && tail -30 models/*.log 2>/dev/null || echo "No log file found"
59
+ ```
60
+
61
+ Common causes:
62
+ - Model file not found (covered above)
63
+ - Port 8080 already in use: `lsof -i :8080` — if another process, kill it or change port in `app.rb`
64
+ - Model too large for available RAM — check `tail -5 models/llama.log` for OOM errors
65
+
66
+ - Returns JSON with models: llamafile is running. Continue.
67
+
68
+ ## Check 5 — LLM responds to a basic chat
69
+
70
+ ```bash
71
+ curl -s --max-time 30 http://127.0.0.1:8080/v1/chat/completions \
72
+ -H 'Content-Type: application/json' \
73
+ -d '{"model":"LLaMA_CPP","messages":[{"role":"user","content":"reply with the single word: OK"}],"temperature":0.1}' \
74
+ 2>&1 | head -5
75
+ ```
76
+
77
+ - Returns JSON with `OK` in choices: LLM is healthy. Continue.
78
+ - Times out: model is still loading. Wait 30s, retry.
79
+ - Error: check `models/llama.log` for details.
80
+
81
+ ## Check 6 — Tool call parsing (agent loop)
82
+
83
+ ```bash
84
+ bundle exec zuzu console 2>/dev/null <<'EOF'
85
+ store = Zuzu::Store.new
86
+ fs = Zuzu::AgentFS.new(store)
87
+ memory = Zuzu::Memory.new(store)
88
+ llm = Zuzu::LlmClient.new
89
+ agent = Zuzu::Agent.new(agent_fs: fs, memory: memory, llm: llm)
90
+ result = agent.process('What time is it? Use the current_time tool if available, otherwise just say hello.')
91
+ puts "Agent response: #{result}"
92
+ EOF
93
+ ```
94
+
95
+ - Response contains sensible text: agent loop works.
96
+ - `Max iterations reached`: model isn't calling tools. See "Agent not calling tools" below.
97
+ - Error: read the traceback, fix the root cause.
98
+
99
+ ## Check 7 — Recent tool call history
100
+
101
+ ```bash
102
+ bundle exec ruby -e "
103
+ require 'zuzu'
104
+ store = Zuzu::Store.new
105
+ rows = store.query_all('SELECT tool_name, input, output, started_at FROM tool_calls ORDER BY started_at DESC LIMIT 10')
106
+ if rows.empty?
107
+ puts 'No tool calls recorded yet'
108
+ else
109
+ rows.each { |r| puts r['tool_name'] + ' → ' + r['output'].to_s[0,80] }
110
+ end
111
+ " 2>&1
112
+ ```
113
+
114
+ - Shows recent calls: tools are firing.
115
+ - Empty: either app hasn't been used yet, or tools aren't being called.
116
+
117
+ ## Check 8 — AgentFS health
118
+
119
+ ```bash
120
+ bundle exec ruby -e "
121
+ require 'zuzu'
122
+ store = Zuzu::Store.new
123
+ fs = Zuzu::AgentFS.new(store)
124
+ fs.write_file('/debug_test.txt', 'hello')
125
+ result = fs.read_file('/debug_test.txt')
126
+ puts result == 'hello' ? 'AgentFS OK' : 'AgentFS BROKEN: got ' + result.inspect
127
+ fs.delete('/debug_test.txt')
128
+ " 2>&1
129
+ ```
130
+
131
+ - "AgentFS OK": filesystem healthy.
132
+ - Error: check that `.zuzu/` directory is writable: `ls -la .zuzu/`
133
+
134
+ ---
135
+
136
+ ## Known issues and fixes
137
+
138
+ ### Agent not calling tools
139
+
140
+ The most common cause is the model not following the system prompt reliably.
141
+
142
+ 1. **Check the system prompt is being built**: open `bundle exec zuzu console` and run:
143
+ ```ruby
144
+ require 'zuzu'; load 'app.rb' rescue nil
145
+ store = Zuzu::Store.new; fs = Zuzu::AgentFS.new(store); memory = Zuzu::Memory.new(store); llm = Zuzu::LlmClient.new
146
+ agent = Zuzu::Agent.new(agent_fs: fs, memory: memory, llm: llm)
147
+ puts agent.send(:build_system_prompt)
148
+ ```
149
+ Verify your tools appear in the "Available tools:" section.
150
+
151
+ 2. **Check `system_prompt_extras`** — if it contains conflicting instructions (e.g. "never use tools") it can override the base prompt.
152
+
153
+ 3. **Model quality** — llava-v1.5-7b-q4 is a vision model and follows tool-calling instructions inconsistently. Try a more capable model or rephrase your request to more explicitly ask for tool use.
154
+
155
+ ### Blank or invisible UI widgets
156
+
157
+ Caused by wrong `layout_data`. Check `app.rb` for any subclassed body or UI code:
158
+
159
+ - `layout_data(:fill, :fill, true, true)` on an input composite → change last arg to `false`
160
+ - `layout_data { height_hint N }` → replace with `layout_data(:fill, :center, false, false)`
161
+ - `sash_form` → remove and replace with plain `composite`
162
+
163
+ ### SWT thread error / crash on UI update
164
+
165
+ Wrap all widget updates that happen inside `Thread.new` with `async_exec`:
166
+
167
+ ```ruby
168
+ Thread.new do
169
+ result = do_something_slow
170
+ async_exec { @chat_display.swt_widget.set_text(result) } # ← required
171
+ end
172
+ ```
173
+
174
+ ### Port 8080 already in use
175
+
176
+ ```bash
177
+ lsof -i :8080
178
+ ```
179
+
180
+ Kill the occupying process, or change `c.port = 8081` in `app.rb` — the LLM client and manager both read from config.
181
+
182
+ ### Database locked
183
+
184
+ Only one process can write to `.zuzu/zuzu.db` at a time. Ensure only one instance of the app is running.
185
+
186
+ ---
187
+
188
+ ## Summary output
189
+
190
+ After all checks, tell the user:
191
+ - ✅/❌ Ruby syntax
192
+ - ✅/❌ Tools registered (list names)
193
+ - ✅/❌ Model file
194
+ - ✅/❌ LLM running
195
+ - ✅/❌ LLM responding
196
+ - ✅/❌ AgentFS healthy
197
+ - Any fixes applied + next steps
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: setup
3
+ description: First-time setup for a Zuzu app. Verifies JRuby and Java versions, runs bundle install, checks the model file exists, and does a smoke-test launch. Use when the developer first clones or scaffolds the app, or when the runtime environment seems broken.
4
+ ---
5
+
6
+ # Zuzu App Setup
7
+
8
+ Run each step automatically. Only pause when the user must take an action (e.g. downloading a model file). Fix problems directly — don't tell the user to fix them unless it genuinely requires their input.
9
+
10
+ ## Step 1 — Verify Java 21+
11
+
12
+ ```bash
13
+ java -version 2>&1
14
+ ```
15
+
16
+ - If missing or < 21: `brew install --cask temurin@21` (macOS) or `sudo apt-get install openjdk-21-jdk` (Linux). Re-check after.
17
+ - If correct: continue.
18
+
19
+ ## Step 2 — Verify JRuby 10.0.3.0
20
+
21
+ ```bash
22
+ ruby -v
23
+ ```
24
+
25
+ - Must show `jruby 10.0.3.0`. If not:
26
+ - Check rbenv: `rbenv versions`
27
+ - If jruby-10.0.3.0 is listed but not active: `rbenv local jruby-10.0.3.0`
28
+ - If not installed: `rbenv install jruby-10.0.3.0 && rbenv local jruby-10.0.3.0`
29
+ - Re-check after.
30
+
31
+ ## Step 3 — Bundle install
32
+
33
+ ```bash
34
+ bundle install 2>&1
35
+ ```
36
+
37
+ - If fails: read the error. Common fixes:
38
+ - Native extension failure → ensure Java 21 is on PATH, retry
39
+ - Network error → `bundle config mirror.https://rubygems.org https://rubygems.org`, retry
40
+ - Wrong ruby → `rbenv local jruby-10.0.3.0`, retry
41
+
42
+ ## Step 4 — Verify Zuzu loads
43
+
44
+ ```bash
45
+ bundle exec ruby -e "require 'zuzu'; puts 'Zuzu ' + Zuzu::VERSION + ' loaded OK'"
46
+ ```
47
+
48
+ - If LoadError: re-run `bundle install`, then retry.
49
+
50
+ ## Step 5 — Check model file
51
+
52
+ Read `app.rb` and find the `c.llamafile_path` value.
53
+
54
+ Check if the model file exists at that path:
55
+
56
+ ```bash
57
+ ls -lh <extracted_model_path>
58
+ ```
59
+
60
+ - If missing:
61
+ - AskUserQuestion: "No model file found. Would you like instructions for downloading llava-v1.5-7b-q4.llamafile (~4 GB)?"
62
+ - If yes, tell the user:
63
+ ```bash
64
+ mkdir -p models
65
+ curl -L -o models/llava-v1.5-7b-q4.llamafile \
66
+ https://huggingface.co/Mozilla/llava-v1.5-7b-llamafile/resolve/main/llava-v1.5-7b-q4.llamafile
67
+ chmod +x models/llava-v1.5-7b-q4.llamafile
68
+ ```
69
+ - This requires the user to run it (large download). Tell them to re-run `/setup` after.
70
+ - If exists but not executable: `chmod +x <path>` — do this automatically.
71
+ - If exists and executable: continue.
72
+
73
+ ## Step 6 — Smoke test (without model)
74
+
75
+ Test that the Ruby code parses and tools load without launching the GUI:
76
+
77
+ ```bash
78
+ bundle exec ruby -e "
79
+ require 'zuzu'
80
+ load 'app.rb' rescue nil
81
+ puts 'Tools registered: ' + Zuzu::ToolRegistry.tools.map(&:name).join(', ')
82
+ " 2>&1 | head -20
83
+ ```
84
+
85
+ - If it shows tool names: good.
86
+ - If Ruby syntax error or LoadError: read the error, fix it in `app.rb`, retry.
87
+
88
+ ## Step 7 — Summary
89
+
90
+ Tell the user:
91
+ - ✅ Java version found
92
+ - ✅ JRuby version confirmed
93
+ - ✅ Gems installed
94
+ - ✅ Zuzu loads
95
+ - ✅/⚠️ Model file status
96
+ - ✅ Tools registered: (list them)
97
+
98
+ If model is ready:
99
+ > Everything is set. Run `bundle exec zuzu start` to launch the app.
100
+
101
+ If model is missing:
102
+ > Download the model file (see step 5), then run `bundle exec zuzu start`.