zuzu 0.2.2-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.
- checksums.yaml +4 -4
- data/README.md +27 -1
- data/bin/zuzu +99 -9
- data/lib/zuzu/config.rb +23 -1
- data/lib/zuzu/version.rb +1 -1
- data/templates/AGENTS.md +33 -1
- data/templates/CLAUDE.md +13 -1
- metadata +9 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd72fe083faded7ee6c7c7461125625f70a02a062da88eb9b28ed459cf767e40
|
|
4
|
+
data.tar.gz: 2096e3e9972ac19255f8b3f2ecdff467a979ac6cd9efe378f1bc226f625ce6aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 779b1e6821bcbe4199fa08868a8e0f4be6d197fae68e42ed6f46605f02c8e402a1e05e34c79b2abae71d7e4c06b4eaacd2a1b20c206eecf3ef64fc134d6762f4
|
|
7
|
+
data.tar.gz: 3453ba743830abb356d912a7f770fd27a7b22869a376830697b9419df11eea2c2cd9ce41fc01cbc827a5ea3370e913f05f8341a5c74a560111d30c40c899dedc
|
data/README.md
CHANGED
|
@@ -10,7 +10,7 @@ LLMs are simply a more expressive interface for exactly that orchestration. Zuzu
|
|
|
10
10
|
|
|
11
11
|
- **Privacy by architecture.** The agent operates inside AgentFS — a sandboxed virtual filesystem backed by a single SQLite file. It cannot touch the host OS unless you explicitly open that door. There is no network call to make, no token to rotate, no terms of service that changes next quarter.
|
|
12
12
|
|
|
13
|
-
- **Deployable like software, not like a service.** Package your app as a single `.jar`.
|
|
13
|
+
- **Deployable like software, not like a service.** Package your app as a single `.jar` — or go further with `zuzu package` and produce a native installer (`.dmg`/`.app` on macOS, `.deb` on Linux, `.exe` on Windows) that bundles a minimal JRE via jlink. Users download, double-click, and run. No Java pre-installed. No Docker. No cloud subscription. No infrastructure to maintain.
|
|
14
14
|
|
|
15
15
|
- **Built for regulated environments.** A therapist keeping session notes, an auditor running confidential analysis, a corporate team in a restricted environment — these are exactly the users who benefit most from powerful AI but are currently blocked by cloud dependency. A bundled LLM in a self-contained Java application needs no external approval to run.
|
|
16
16
|
|
|
@@ -312,6 +312,32 @@ java -jar my_app.jar # Linux / Windows
|
|
|
312
312
|
> **Note:** Place your llamafile model in a `models/` directory alongside the
|
|
313
313
|
> `.jar` — models are not bundled into the archive.
|
|
314
314
|
|
|
315
|
+
### Packaging as a native installer (no Java required for users)
|
|
316
|
+
|
|
317
|
+
After building the JAR, `zuzu package` asks if you want to go further:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
Bundle into a self-contained native executable? (no Java required for users) [y/N]:
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Type `y` and Zuzu uses **jpackage** (bundled with JDK 21+) to produce a native
|
|
324
|
+
installer that includes a minimal JRE — users never need to install Java:
|
|
325
|
+
|
|
326
|
+
| Platform | Output |
|
|
327
|
+
|----------|--------|
|
|
328
|
+
| macOS | `.dmg` with a drag-to-Applications `.app` |
|
|
329
|
+
| Linux | `.deb` package |
|
|
330
|
+
| Windows | `.exe` installer |
|
|
331
|
+
|
|
332
|
+
The model file is not bundled (it can be gigabytes). After installing, users
|
|
333
|
+
place it in the platform user-data directory that Zuzu prints at build time:
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
macOS: ~/Library/Application Support/<AppName>/models/<model>.llamafile
|
|
337
|
+
Linux: ~/.local/share/<AppName>/models/<model>.llamafile
|
|
338
|
+
Windows: %APPDATA%\<AppName>\models\<model>.llamafile
|
|
339
|
+
```
|
|
340
|
+
|
|
315
341
|
---
|
|
316
342
|
|
|
317
343
|
## Configuration Reference
|
data/bin/zuzu
CHANGED
|
@@ -125,16 +125,106 @@ when 'package'
|
|
|
125
125
|
puts 'Packaging app as zuzu-app.jar ...'
|
|
126
126
|
puts ' (this may take a minute)'
|
|
127
127
|
success = Bundler.with_unbundled_env { system(warble_bin, 'jar') }
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
abort 'warble jar failed. Check output above for details.' unless success
|
|
129
|
+
|
|
130
|
+
jar = Dir['*.jar'].first || 'app.jar'
|
|
131
|
+
puts ''
|
|
132
|
+
puts "Done! Created: #{jar}"
|
|
133
|
+
puts ''
|
|
134
|
+
puts 'Run it with:'
|
|
135
|
+
puts " java -XstartOnFirstThread -jar #{jar} # macOS"
|
|
136
|
+
puts " java -jar #{jar} # Linux / Windows"
|
|
137
|
+
puts ''
|
|
138
|
+
|
|
139
|
+
# ── jpackage: optional self-contained native executable ─────────────────
|
|
140
|
+
# jpackage (JDK 14+) bundles a minimal JRE via jlink so users don't need
|
|
141
|
+
# Java pre-installed. Model files can't be bundled — they're resolved from
|
|
142
|
+
# the platform user-data directory at runtime via the zuzu.model JVM property.
|
|
143
|
+
|
|
144
|
+
jpackage_bin = `which jpackage 2>/dev/null`.strip
|
|
145
|
+
if jpackage_bin.empty?
|
|
146
|
+
puts 'Tip: Install JDK 21+ to create a self-contained executable (no Java required for users).'
|
|
136
147
|
else
|
|
137
|
-
|
|
148
|
+
print 'Bundle into a self-contained native executable? (no Java required for users) [y/N]: '
|
|
149
|
+
$stdout.flush
|
|
150
|
+
answer = $stdin.gets.to_s.strip.downcase
|
|
151
|
+
|
|
152
|
+
if answer == 'y' || answer == 'yes'
|
|
153
|
+
# ── detect / ask for model filename ───────────────────────────────────
|
|
154
|
+
model_files = Dir['models/*.llamafile']
|
|
155
|
+
model_name = if model_files.length == 1
|
|
156
|
+
puts "Using model: #{File.basename(model_files.first)}"
|
|
157
|
+
File.basename(model_files.first)
|
|
158
|
+
elsif model_files.length > 1
|
|
159
|
+
puts 'Model files found in models/:'
|
|
160
|
+
model_files.each { |f| puts " #{File.basename(f)}" }
|
|
161
|
+
print 'Enter model filename: '
|
|
162
|
+
$stdout.flush
|
|
163
|
+
$stdin.gets.to_s.strip
|
|
164
|
+
else
|
|
165
|
+
print 'Enter model filename (e.g. llava-v1.5-7b-q4.llamafile): '
|
|
166
|
+
$stdout.flush
|
|
167
|
+
$stdin.gets.to_s.strip
|
|
168
|
+
end
|
|
169
|
+
abort 'No model filename provided.' if model_name.to_s.empty?
|
|
170
|
+
|
|
171
|
+
print 'App version [1.0.0]: '
|
|
172
|
+
$stdout.flush
|
|
173
|
+
version_input = $stdin.gets.to_s.strip
|
|
174
|
+
app_version = version_input.empty? ? '1.0.0' : version_input
|
|
175
|
+
|
|
176
|
+
app_name = File.basename(Dir.pwd).gsub(/[^a-zA-Z0-9._-]/, '-')
|
|
177
|
+
|
|
178
|
+
platform = RbConfig::CONFIG['host_os']
|
|
179
|
+
pkg_type = case platform
|
|
180
|
+
when /darwin/ then 'dmg'
|
|
181
|
+
when /linux/ then 'deb'
|
|
182
|
+
else 'exe'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
FileUtils.mkdir_p('dist')
|
|
186
|
+
|
|
187
|
+
java_opts = [
|
|
188
|
+
'--enable-native-access=ALL-UNNAMED',
|
|
189
|
+
"-Dzuzu.model=#{model_name}"
|
|
190
|
+
]
|
|
191
|
+
java_opts << '-XstartOnFirstThread' if platform =~ /darwin/
|
|
192
|
+
|
|
193
|
+
jpackage_args = [
|
|
194
|
+
jpackage_bin,
|
|
195
|
+
'--type', pkg_type,
|
|
196
|
+
'--name', app_name,
|
|
197
|
+
'--app-version', app_version,
|
|
198
|
+
'--input', '.',
|
|
199
|
+
'--main-jar', jar,
|
|
200
|
+
'--main-class', 'org.jruby.JarBootstrapMain',
|
|
201
|
+
'--dest', 'dist'
|
|
202
|
+
]
|
|
203
|
+
java_opts.each { |opt| jpackage_args.push('--java-options', opt) }
|
|
204
|
+
|
|
205
|
+
puts ''
|
|
206
|
+
puts "Building native #{pkg_type.upcase} installer with jpackage..."
|
|
207
|
+
puts ' (this may take a minute)'
|
|
208
|
+
native_ok = system(*jpackage_args)
|
|
209
|
+
|
|
210
|
+
if native_ok
|
|
211
|
+
puts ''
|
|
212
|
+
puts 'Done! Native installer created in dist/'
|
|
213
|
+
pkg_file = Dir["dist/*.#{pkg_type}"].first
|
|
214
|
+
puts " #{pkg_file}" if pkg_file
|
|
215
|
+
puts ''
|
|
216
|
+
puts 'Important — place your model file at:'
|
|
217
|
+
model_dest = case platform
|
|
218
|
+
when /darwin/ then " ~/Library/Application\\ Support/#{app_name}/models/#{model_name}"
|
|
219
|
+
when /linux/ then " ~/.local/share/#{app_name}/models/#{model_name}"
|
|
220
|
+
else " %APPDATA%\\#{app_name}\\models\\#{model_name}"
|
|
221
|
+
end
|
|
222
|
+
puts model_dest
|
|
223
|
+
puts ' (create the directory if it does not exist)'
|
|
224
|
+
else
|
|
225
|
+
warn 'jpackage failed. Check output above for details.'
|
|
226
|
+
end
|
|
227
|
+
end
|
|
138
228
|
end
|
|
139
229
|
|
|
140
230
|
when 'console'
|
data/lib/zuzu/config.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Zuzu
|
|
|
13
13
|
attr_accessor :port, :model, :channels, :log_level, :app_name,
|
|
14
14
|
:window_width, :window_height, :system_prompt_extras
|
|
15
15
|
|
|
16
|
-
attr_reader :db_path
|
|
16
|
+
attr_reader :db_path
|
|
17
17
|
|
|
18
18
|
def initialize
|
|
19
19
|
@port = 8080
|
|
@@ -37,6 +37,28 @@ module Zuzu
|
|
|
37
37
|
def llamafile_path=(path)
|
|
38
38
|
@llamafile_path = path ? File.expand_path(path) : path
|
|
39
39
|
end
|
|
40
|
+
|
|
41
|
+
# When running as a jpackage native executable, the model is NOT bundled
|
|
42
|
+
# in the app. Instead it lives in the platform user-data directory and its
|
|
43
|
+
# filename is injected via the `-Dzuzu.model=<filename>` JVM property set
|
|
44
|
+
# by jpackage at build time.
|
|
45
|
+
def llamafile_path
|
|
46
|
+
if defined?(Java) &&
|
|
47
|
+
(model_name = Java::JavaLang::System.getProperty('zuzu.model')) &&
|
|
48
|
+
!model_name.empty?
|
|
49
|
+
data_dir = case RbConfig::CONFIG['host_os']
|
|
50
|
+
when /darwin/
|
|
51
|
+
File.join(Dir.home, 'Library', 'Application Support', @app_name || 'Zuzu')
|
|
52
|
+
when /mswin|mingw/
|
|
53
|
+
File.join(ENV.fetch('APPDATA', Dir.home), @app_name || 'Zuzu')
|
|
54
|
+
else
|
|
55
|
+
File.join(Dir.home, '.local', 'share', @app_name || 'Zuzu')
|
|
56
|
+
end
|
|
57
|
+
File.join(data_dir, 'models', model_name)
|
|
58
|
+
else
|
|
59
|
+
@llamafile_path
|
|
60
|
+
end
|
|
61
|
+
end
|
|
40
62
|
end
|
|
41
63
|
|
|
42
64
|
@config = Config.new
|
data/lib/zuzu/version.rb
CHANGED
data/templates/AGENTS.md
CHANGED
|
@@ -451,6 +451,8 @@ Log line: `[zuzu] loop detected for <tool_name>, breaking`
|
|
|
451
451
|
|
|
452
452
|
## Packaging
|
|
453
453
|
|
|
454
|
+
### Step 1 — Build the JAR
|
|
455
|
+
|
|
454
456
|
```bash
|
|
455
457
|
bundle exec zuzu package
|
|
456
458
|
```
|
|
@@ -461,12 +463,42 @@ bundle exec zuzu package
|
|
|
461
463
|
- Path resolution: `__dir__` inside a jar returns `uri:classloader:/` —
|
|
462
464
|
app.rb already handles this with the `base` variable pattern
|
|
463
465
|
|
|
464
|
-
Run the jar:
|
|
466
|
+
Run the jar (requires Java 21+ installed):
|
|
465
467
|
```bash
|
|
466
468
|
java -XstartOnFirstThread -jar my_app.jar # macOS (SWT requires first thread)
|
|
467
469
|
java -jar my_app.jar # Linux / Windows
|
|
468
470
|
```
|
|
469
471
|
|
|
472
|
+
### Step 2 — Build a native installer (optional, no Java required for users)
|
|
473
|
+
|
|
474
|
+
After the JAR is built, `zuzu package` prompts:
|
|
475
|
+
|
|
476
|
+
```
|
|
477
|
+
Bundle into a self-contained native executable? (no Java required for users) [y/N]:
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Type `y`. Zuzu uses **jpackage** (included with JDK 21+) to bundle a minimal JRE
|
|
481
|
+
via jlink and produce a platform-native installer:
|
|
482
|
+
|
|
483
|
+
| Platform | Output in `dist/` |
|
|
484
|
+
|----------|-------------------|
|
|
485
|
+
| macOS | `.dmg` — drag-to-Applications `.app` bundle |
|
|
486
|
+
| Linux | `.deb` package |
|
|
487
|
+
| Windows | `.exe` installer |
|
|
488
|
+
|
|
489
|
+
The model file cannot be bundled (too large). Zuzu injects the model filename as
|
|
490
|
+
the `-Dzuzu.model` JVM property. At runtime, `Zuzu::Config#llamafile_path` resolves
|
|
491
|
+
it from the platform user-data directory automatically:
|
|
492
|
+
|
|
493
|
+
```
|
|
494
|
+
macOS: ~/Library/Application Support/<AppName>/models/<model>.llamafile
|
|
495
|
+
Linux: ~/.local/share/<AppName>/models/<model>.llamafile
|
|
496
|
+
Windows: %APPDATA%\<AppName>\models\<model>.llamafile
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
`zuzu package` prints the exact path — tell your users to place the model there
|
|
500
|
+
before launching the installed app.
|
|
501
|
+
|
|
470
502
|
---
|
|
471
503
|
|
|
472
504
|
## Debugging
|
data/templates/CLAUDE.md
CHANGED
|
@@ -53,10 +53,22 @@ What would you like to build today?
|
|
|
53
53
|
```bash
|
|
54
54
|
bundle exec zuzu start # launch the app
|
|
55
55
|
bundle exec zuzu console # IRB with Zuzu loaded — test tools interactively
|
|
56
|
-
bundle exec zuzu package # build standalone .jar
|
|
56
|
+
bundle exec zuzu package # build standalone .jar, then optionally a native installer
|
|
57
57
|
bundle install # sync gems after Gemfile changes
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
### Distribution tiers
|
|
61
|
+
|
|
62
|
+
| Command | Output | User requirement |
|
|
63
|
+
|---------|--------|-----------------|
|
|
64
|
+
| `zuzu package` → JAR only | `<app>.jar` | Java 21+ installed |
|
|
65
|
+
| `zuzu package` → native (type `y` at prompt) | `.dmg` / `.deb` / `.exe` in `dist/` | Nothing — JRE bundled |
|
|
66
|
+
|
|
67
|
+
For the native installer, the model file is NOT bundled. After install, users place it at:
|
|
68
|
+
- **macOS:** `~/Library/Application Support/<AppName>/models/<model>.llamafile`
|
|
69
|
+
- **Linux:** `~/.local/share/<AppName>/models/<model>.llamafile`
|
|
70
|
+
- **Windows:** `%APPDATA%\<AppName>\models\<model>.llamafile`
|
|
71
|
+
|
|
60
72
|
## Core rules — always enforce these
|
|
61
73
|
|
|
62
74
|
- Tools registered **before** `Zuzu::App.launch!` in `app.rb`
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zuzu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- Abhishek Parolkar
|
|
@@ -85,10 +85,11 @@ description: Every installed application is an orchestrator of OS capabilities.
|
|
|
85
85
|
the user's hardware — not in a data center. It uses JRuby and Glimmer DSL for SWT
|
|
86
86
|
for the GUI, Mozilla's llamafile for local LLM inference, and SQLite (via AgentFS)
|
|
87
87
|
as a sandboxed virtual filesystem the agent can read and write without touching
|
|
88
|
-
the host OS. Apps
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
the host OS. Apps ship as a cross-platform .jar, or as a native installer (.dmg/.deb/.exe)
|
|
89
|
+
with a JRE bundled via jpackage — users download, double-click, and run with no
|
|
90
|
+
Java installation required. No cloud. No subscriptions. No infrastructure to operate.
|
|
91
|
+
Scaffolded projects include CLAUDE.md and Claude Code skills pre-tuned to Zuzu's
|
|
92
|
+
patterns, so coding agents generate correct framework code from the start.
|
|
92
93
|
email:
|
|
93
94
|
- abhishek@parolkar.com
|
|
94
95
|
executables:
|
|
@@ -148,6 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
148
149
|
requirements: []
|
|
149
150
|
rubygems_version: 3.7.2
|
|
150
151
|
specification_version: 4
|
|
151
|
-
summary: JRuby framework for AI-native desktop apps — local LLM, single .jar
|
|
152
|
-
Claude Code-ready scaffolding.
|
|
152
|
+
summary: JRuby framework for AI-native desktop apps — local LLM, single .jar/.dmg/.exe/.deb
|
|
153
|
+
distribution, Claude Code-ready scaffolding. SQLite-backed AgentFS as a sandboxed
|
|
154
|
+
virtual filesystem for the agent. No cloud required.
|
|
153
155
|
test_files: []
|