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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6098f883dec29f87b5dcece9c69f8e115608cfd89b9cf045fd442355fbf48c9
4
- data.tar.gz: d9ffeb971f19158a6262401bdcadb7791bdbd70523c843dd6b7ac26cc3a4c536
3
+ metadata.gz: fd72fe083faded7ee6c7c7461125625f70a02a062da88eb9b28ed459cf767e40
4
+ data.tar.gz: 2096e3e9972ac19255f8b3f2ecdff467a979ac6cd9efe378f1bc226f625ce6aa
5
5
  SHA512:
6
- metadata.gz: b7d6f2d65abfc635d0dceec2122a788d7d2cc03159969c9e06a1b03a45e73eb9c03bf430d5f1a6170a7aaa8c717961bc5c51311336cdf80ab4a3b28feb1dc8b4
7
- data.tar.gz: b10535955c154eee0eaade46edb4ee5b1b9049e8e224cea1d49da58553d1bbd1ae263045977f9a1ac6d87dbb5bf0c7da62e26e73eb5ec0c4b3bf8152ba699f58
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`. Users pay, download, double-click, and run. No Docker. No cloud subscription. No infrastructure to maintain. The JVM handles cross-platform distribution the way it has for 30 years.
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
- if success
129
- puts ''
130
- jar = Dir['*.jar'].first || 'app.jar'
131
- puts "Done! Created: #{jar}"
132
- puts ''
133
- puts 'Run it with:'
134
- puts " java -XstartOnFirstThread -jar #{jar} # macOS"
135
- puts " java -jar #{jar} # Linux / Windows"
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
- abort 'warble jar failed. Check output above for details.'
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, :llamafile_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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zuzu
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.3"
5
5
  end
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.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 package as a single cross-platform .jar users download, double-click,
89
- run. No cloud. No subscriptions. No infrastructure to operate. Scaffolded projects
90
- include CLAUDE.md and Claude Code skills pre-tuned to Zuzu's patterns, so coding
91
- agents generate correct framework code from the start.
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 distribution,
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: []