From jdeploy
Configure jDeploy app settings including splash screens, icons, commands, services, MCP servers, file associations, URL protocols, singleton mode, permissions, and Java runtime options.
How this skill is triggered — by the user, by Claude, or both
Slash command
/jdeploy:configureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Configure jDeploy application settings.
Configure jDeploy application settings.
This skill helps configure various jDeploy settings for your application. It detects your current configuration and presents relevant options based on your app type.
First, read the existing package.json to understand current state:
cat package.json 2>/dev/null || echo "No package.json found"
If no package.json exists, suggest running /jdeploy:setup first.
Parse the jdeploy section to determine:
Based on context, present relevant options to the user. Use AskUserQuestion to let them choose what to configure:
Always show:
Show if app has or could have commands: 5. Commands & services 6. Helper (system tray) actions (only if service controller exists)
Show if app is CLI/service type: 7. MCP server integration
Show for desktop apps: 8. File associations (documentTypes) 9. URL protocols (urlSchemes) 10. Singleton mode
Allow the user to select multiple options to configure in one session.
jDeploy supports two types of startup images:
splash.png) - Shown immediately when app launches, before JVM startsloading.png) - Shown while JVM initializes (optional, falls back to splash)Requirements:
package.json)Steps:
Check for existing splash/loading images:
ls -la splash.png loading.png 2>/dev/null
If user wants to set a splash screen, help them:
splash.png in project rootloading.pngNo package.json changes needed - jDeploy auto-detects these files.
Example search:
find . -name "*.png" -size +10k | head -20
The application icon is used for desktop shortcuts, taskbar, installers, etc.
Requirements:
icon.png in project rootSteps:
Check for existing icon:
ls -la icon.png 2>/dev/null && file icon.png
Search for candidate icons:
find . -name "*icon*.png" -o -name "*logo*.png" | head -10
Verify the icon is square:
file candidate.png
Copy to project root:
cp path/to/icon.png ./icon.png
Configure which Java runtime jDeploy bundles with your app.
Properties in package.json → jdeploy:
| Property | Type | Default | Description |
|---|---|---|---|
javaVersion | string | "17" | Java major version (8, 11, 17, 21, etc.) |
jdk | boolean | false | Bundle full JDK instead of JRE |
javafx | boolean | false | Include JavaFX modules |
javafxVersion | string | (auto) | Specific JavaFX version (optional) |
jdkProvider | string | "zulu" | JDK provider: "zulu" or "jbr" (JetBrains Runtime) |
jbrVariant | string | "standard" | JBR variant: "standard", "jcef", "sdk", "sdk_jcef" |
Steps:
Ask user what they need:
javac, jlink, etc.)?Update package.json:
{
"jdeploy": {
"javaVersion": "21",
"jdk": false,
"javafx": true
}
}
For JetBrains Runtime with JCEF:
{
"jdeploy": {
"javaVersion": "21",
"jdkProvider": "jbr",
"jbrVariant": "jcef"
}
}
Detection helpers:
Check for JavaFX usage:
grep -r "import javafx\." src/ --include="*.java" 2>/dev/null | head -3
Check for JDK tool usage:
grep -r "ToolProvider\|JavaCompiler\|ProcessBuilder.*javac" src/ --include="*.java" 2>/dev/null | head -3
Commands create CLI executables that get added to the user's PATH when installed.
Properties in package.json → jdeploy.commands:
Each command is a key-value pair where the key is the command name:
{
"jdeploy": {
"commands": {
"myapp-cli": {
"description": "Run MyApp from command line",
"args": ["-Dmode=cli"],
"implements": []
}
}
}
}
Command properties:
| Property | Type | Required | Description |
|---|---|---|---|
description | string | No | Human-readable description |
args | array | No | Arguments passed to Java app when command is invoked |
implements | array | No | Roles: "service_controller", "updater", "launcher" |
Service Controller:
To make a command act as a system service controller, add "service_controller" to implements:
{
"jdeploy": {
"commands": {
"myservice": {
"description": "My background service",
"implements": ["service_controller"]
}
}
}
}
This enables subcommands:
myservice service install - Install as system servicemyservice service start - Start the servicemyservice service stop - Stop the servicemyservice service status - Check service statusmyservice service uninstall - Remove system serviceSteps:
Ask user:
Update package.json with the commands configuration.
Important: Also update the bin field to include new commands:
{
"bin": {
"myapp": "jdeploy-bundle/jdeploy.js",
"myapp-cli": "jdeploy-bundle/jdeploy.js"
}
}
The Background Helper provides system tray integration with custom menu actions. Actions typically use custom URL schemes to communicate with your app.
Prerequisite: Works best with apps that have urlSchemes configured and singleton mode enabled.
Properties in package.json → jdeploy.helper:
{
"jdeploy": {
"urlSchemes": ["myapp"],
"singleton": true,
"helper": {
"actions": [
{
"label": "Open Dashboard",
"description": "Open the main application window",
"url": "myapp://open/dashboard"
},
{
"label": "View Logs",
"url": "myapp://open/logs"
}
]
}
}
}
Action properties:
| Property | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Text displayed in the menu item |
description | string | No | Tooltip text shown on hover |
url | string | Yes | URL to open when clicked (typically custom scheme) |
Steps:
Check if urlSchemes and singleton are configured (recommended for helper actions)
Ask user what tray actions they need:
Update package.json with helper configuration.
Configure the app as an MCP (Model Context Protocol) server for AI tool integration.
Properties in package.json → jdeploy.ai.mcp:
{
"jdeploy": {
"commands": {
"my-mcp-server": {
"description": "MCP server for AI tools"
}
},
"ai": {
"mcp": {
"command": "my-mcp-server",
"args": ["--stdio"],
"defaultEnabled": false
}
}
}
}
MCP properties:
| Property | Type | Required | Description |
|---|---|---|---|
command | string | Yes | Must match a key in jdeploy.commands |
args | array | No | Additional args when invoked as MCP server |
defaultEnabled | boolean | No | Auto-enable during installation (default: false) |
Steps:
Check if a command exists that could serve as MCP entry point:
node -p "Object.keys(require('./package.json').jdeploy?.commands || {})"
If no commands exist, create one first (see Commands section).
Ask user:
Update package.json with the ai.mcp configuration.
Reminder: MCP servers communicate via stdin/stdout, so ensure the app:
Register file extensions to open with your application.
Properties in package.json → jdeploy.documentTypes:
{
"jdeploy": {
"documentTypes": [
{
"extension": "myformat",
"mimetype": "application/x-myformat",
"editor": true,
"custom": true
}
]
}
}
Document type properties:
| Property | Type | Required | Description |
|---|---|---|---|
extension | string | Yes | File extension without dot (e.g., "txt") |
mimetype | string | Yes | MIME type for the file |
editor | boolean | No | true if app can edit (not just view) files |
custom | boolean | No | true for custom mimetypes (Linux registration) |
Directory associations (for IDE-style apps):
{
"jdeploy": {
"documentTypes": [
{
"type": "directory",
"role": "Editor",
"description": "Open folder as project"
}
]
}
}
Steps:
Ask user what file types the app should handle:
Update package.json with documentTypes array.
Tip: Enable singleton mode ("singleton": true) so double-clicking files activates the existing window rather than launching a new instance.
Example - handling opened files in Java:
public static void main(String[] args) {
if (args.length > 0) {
String filePath = args[0];
// Open the file
}
}
Register custom URL protocols (e.g., myapp://action) that open your application.
Properties in package.json → jdeploy.urlSchemes:
{
"jdeploy": {
"urlSchemes": ["myapp", "myapp-alt"]
}
}
The urlSchemes property is a simple array of scheme strings (without ://).
Steps:
Ask user what URL scheme(s) they want:
myapp for myapp://... URLs)?Update package.json with urlSchemes array.
Tip: Enable singleton mode ("singleton": true) so clicking URLs activates the existing window rather than launching a new instance.
Example - handling URL in Java:
public static void main(String[] args) {
if (args.length > 0 && args[0].startsWith("myapp://")) {
String url = args[0];
// Parse and handle the URL
}
}
Ensure only one instance of the application runs at a time. When a second instance is launched, it forwards files/URIs to the running instance via IPC.
Requirements:
"singleton": true in package.jsonjdeploy-desktop-lib dependency to receive forwarded eventsStep 1: Enable in package.json
{
"jdeploy": {
"singleton": true,
"urlSchemes": ["myapp"]
}
}
Step 2: Add dependency
For Swing apps (Maven):
<dependency>
<groupId>ca.weblite</groupId>
<artifactId>jdeploy-desktop-lib-swing</artifactId>
<version>1.0.4</version>
</dependency>
For Swing apps (Gradle):
implementation 'ca.weblite:jdeploy-desktop-lib-swing:1.0.4'
For JavaFX apps (Maven):
<dependency>
<groupId>ca.weblite</groupId>
<artifactId>jdeploy-desktop-lib-javafx</artifactId>
<version>1.0.4</version>
</dependency>
For JavaFX apps (Gradle):
implementation 'ca.weblite:jdeploy-desktop-lib-javafx:1.0.4'
Step 3: Register handler in code
Swing:
import ca.weblite.jdeploy.app.swing.JDeploySwingApp;
import ca.weblite.jdeploy.app.JDeployOpenHandler;
public class MyApp {
public static void main(String[] args) {
JDeploySwingApp.setOpenHandler(new JDeployOpenHandler() {
public void openFiles(List<File> files) {
for (File file : files) {
openDocument(file);
}
}
public void openURIs(List<URI> uris) {
for (URI uri : uris) {
handleDeepLink(uri);
}
}
public void appActivated() {
// Bring window to front
}
});
// ... rest of app
}
}
JavaFX:
import ca.weblite.jdeploy.app.javafx.JDeployFXApp;
import ca.weblite.jdeploy.app.JDeployOpenHandler;
public class MyApp extends Application {
public static void main(String[] args) {
JDeployFXApp.initialize(); // REQUIRED before launch() on macOS
launch(args);
}
@Override
public void start(Stage primaryStage) {
JDeployFXApp.setOpenHandler(new JDeployOpenHandler() {
public void openFiles(List<File> files) { /* handle files */ }
public void openURIs(List<URI> uris) { /* handle URIs */ }
public void appActivated() { /* bring window to front */ }
});
// ... rest of app
}
}
Steps:
Check if jdeploy-desktop-lib is already a dependency:
grep -r "jdeploy-desktop-lib" pom.xml build.gradle build.gradle.kts 2>/dev/null
Ask if it's a Swing or JavaFX app to choose the right artifact.
Add the dependency to the build file.
Guide user to add handler code to their main class.
Update package.json to enable singleton mode.
Configure what permissions the app requests on different platforms (currently macOS only).
Properties in package.json → jdeploy.permissions:
{
"jdeploy": {
"permissions": [
{
"name": "camera",
"description": "Camera access is required for video calls"
},
{
"name": "microphone",
"description": "Microphone access is required for voice recording"
}
]
}
}
Permission properties:
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Permission name (see table below) |
description | string | Yes | Why the app needs this permission (shown to user) |
Available permission names:
| Permission | Description |
|---|---|
camera | Access to the camera |
microphone | Access to the microphone |
location | Access to user's location |
location_when_in_use | Location access when app is in use |
location_always | Location access at all times |
contacts | Access to contacts |
calendars | Access to calendars |
reminders | Access to reminders |
photos | Access to photo library |
photos_add | Add photos to library |
bluetooth | Bluetooth access |
bluetooth_always | Bluetooth access at all times |
speech_recognition | Speech recognition |
desktop_folder | Access to Desktop folder |
documents_folder | Access to Documents folder |
downloads_folder | Access to Downloads folder |
network_volumes | Access to network volumes |
removable_volumes | Access to removable volumes |
local_network | Access to local network |
Steps:
Ask user what permissions the app needs.
For each permission, ask for a description explaining why it's needed.
Update package.json with permissions array.
Configure the application to run with elevated privileges.
Property in package.json → jdeploy.runAsAdministrator:
| Value | Description |
|---|---|
"disabled" | (Default) Normal user privileges |
"allowed" | Generates both standard and admin launchers |
"required" | All launchers use elevation |
{
"jdeploy": {
"runAsAdministrator": "allowed"
}
}
Steps:
Ask if the app needs elevated privileges:
"disabled""allowed""required"Update package.json with the setting.
Configure a custom installation directory on Windows to avoid Windows Defender warnings.
Property in package.json → jdeploy.winAppDir:
{
"jdeploy": {
"winAppDir": "AppData\\Local\\Programs"
}
}
This path is relative to %USERPROFILE%. Default is "jdeploy" (installs to %USERPROFILE%\jdeploy\apps).
When the user selects multiple options to configure:
Process them in a logical order:
After each section, show a summary of changes made.
At the end, show the complete updated jdeploy configuration.
After making changes, validate the configuration:
# Verify package.json is valid JSON
node -e "require('./package.json')"
# Show the jdeploy config
node -p "JSON.stringify(require('./package.json').jdeploy, null, 2)"
| Configuration | package.json location | Files/Dependencies needed |
|---|---|---|
| Splash screen | (auto-detected) | splash.png |
| Loading image | (auto-detected) | loading.png |
| Icon | (auto-detected) | icon.png |
| Java version | jdeploy.javaVersion | - |
| Full JDK | jdeploy.jdk | - |
| JavaFX | jdeploy.javafx | - |
| JDK provider | jdeploy.jdkProvider | - |
| Commands | jdeploy.commands | Update bin field too |
| Service controller | jdeploy.commands[name].implements | - |
| Helper actions | jdeploy.helper.actions | - |
| MCP server | jdeploy.ai.mcp | Requires command |
| File associations | jdeploy.documentTypes | - |
| URL protocols | jdeploy.urlSchemes | - |
| Singleton mode | jdeploy.singleton | jdeploy-desktop-lib-* |
| Permissions | jdeploy.permissions | - |
| Run as admin | jdeploy.runAsAdministrator | - |
| Windows install dir | jdeploy.winAppDir | - |
npx claudepluginhub shannah/jdeploy-claude --plugin jdeployPackages a local web project as a Windows desktop app with a Start Menu shortcut, .exe launcher, and Taskbar identity. Mirrors macOS app-it contract (soft-close vs quit, warm dev-server reuse). Beta — requires Windows maintainer to verify hardware-dependent steps.
Creates macOS .app bundles to launch any project from the Dock. Handles packaging, icons, Swift WKWebView shell, menu bar shortcuts, and warm reattach.
Adds production features like CI/CD, auto-updates, logging, SwiftLint, localization, Launch at Login to existing macOS Swift apps after analyzing project status.