Skip to content

Comments

Feature/local install command#419

Open
shannah wants to merge 36 commits intomasterfrom
feature/local-install-command
Open

Feature/local install command#419
shannah wants to merge 36 commits intomasterfrom
feature/local-install-command

Conversation

@shannah
Copy link
Owner

@shannah shannah commented Feb 16, 2026

No description provided.

shannah and others added 30 commits February 16, 2026 21:11
Add support for installing apps locally with full native launchers, CLI
commands, and services to enable local development testing without
publishing to npm or GitHub.

- Add --full flag to 'jdeploy install' command
- Create LocalInstallService to orchestrate local installation
- Create LocalJDeployFilesGenerator to generate .jdeploy-files directory
- Add local-package-json and local-bundle attributes to app.xml
- Add runHeadlessInstallProgrammatic() to installer for CLI invocation
- Add NPMPackageVersion.fromLocalPackageJson() for local package.json
- Update AppInfo/AppDescription with local mode support
- Update MacBundler and LauncherWriterHelper for local attributes
…nstall

Add support for configuring AI tools (MCP servers) during local installation
with the --full flag. This enables developers to test MCP server integrations
locally without publishing.

Changes:
- Add --ai-tools CLI option to specify AI tools (e.g., claude-desktop, cursor)
- Update LocalInstallService to pass AI tools to headless installer
- Add runHeadlessInstallProgrammatic overload accepting AI tools set
- Call applyContext() in headless install to load AI integration config
- Fix findInstallFilesDir() to check client4j.appxml.path at top level
- Fix findInstallFilesDir() to recognize when already in .jdeploy-files dir
- Fix duplicate CLI command path in uninstall manifest on macOS

Usage: jdeploy install --full --ai-tools=claude-desktop,cursor
The cli module now depends on jdeploy-installer, so the build order needed
to be updated to install the parent pom first, then build and install the
installer module before building the cli.
Changed jdeploy install to use the headless installer by default instead
of npm link. Added --npm flag to opt into the legacy npm link behavior.
Add support for running locally-installed jDeploy applications:
- jdeploy run: launches the GUI application
- jdeploy run <command> [args...]: runs a CLI command with arguments

New services:
- InstalledAppLocator: locates installed apps per platform
- LocalRunService: handles app/command launching
- NotInstalledException/CommandNotFoundException for error handling
Add debug command that launches installed applications with Java remote
debugging enabled via JDEPLOY_DEBUG_PORT and JDEPLOY_DEBUG_SUSPEND
environment variables.

- jdeploy debug: Debug GUI app (port 5005, suspend=true by default)
- jdeploy debug --port=N: Use custom debug port
- jdeploy debug --no-suspend: Don't wait for debugger to attach
- jdeploy debug <command> [args...]: Debug CLI command

On macOS, uses 'open --env' to pass environment variables to the
launched application bundle.
- Add --install (-I) flag to run install before run/debug commands
- Require -- delimiter before command arguments to avoid ambiguity
- Pre-process args to extract post-delimiter portion before option parsing

Usage:
  jdeploy run --install              # install first, then run GUI
  jdeploy run mycommand -- foo bar   # run command with args
  jdeploy debug --install --port=5006 mycommand -- arg1 arg2
Add support for writing debug-port and debug-suspend attributes to
app.xml when creating bundles. These properties enable Java remote
debugging via JDWP when the application is launched.

- Add debugPort and debugSuspend fields to AppDescription
- Add addDebugAttributesTo() helper method for centralized logic
- Update MacBundler to include debug attributes in app.xml
- Update LauncherWriterHelper for Windows/Linux bundlers

By default, debug attributes are not written. They must be explicitly
set via AppDescription.setDebugPort() and setDebugSuspend().
Add standalone commands to verify jDeploy app installations and uninstallations
for smoke testing. Supports three input methods:
- Local/remote package.json path or URL
- Project code (jDeploy registry lookup)
- Package name with optional GitHub source

Features:
- Platform-specific verification (macOS, Windows, Linux)
- Checks GUI executable, CLI launcher, command wrappers, PATH updates
- Windows registry verification via reg query
- Graceful degradation for legacy installations
- Summary output with verbose mode option
PackageInfoResolver now correctly parses commands when defined as an
object ({"cmd-name": {...}}) in addition to the array format. This
ensures command wrapper verification works for all jDeploy projects.
The --source parameter now works with --package-json to override the
source URL from package.json. This is needed when an app is published
to both GitHub and NPM, as the source affects the FQPN and installation
paths:
- NPM: bin-arm64/{packageName}/
- GitHub: bin-arm64/{MD5(source)}.{packageName}/
The CLI settings configuration (which determines whether to install
CLI commands based on the commands defined in package.json) was only
being called in buildUI() for GUI mode, but not in headless mode.

This fix extracts the CLI settings configuration into a new method
configureCliSettings() and calls it from both:
- buildUI() for GUI installations
- runHeadlessInstall() for headless installations (jdeploy install)

This ensures that CLI commands are properly installed when using
`jdeploy install` (headless local installation mode).
The computeFullyQualifiedPackageName() method was only checking for
null source, but AppInfo.npmSource defaults to empty string "".
This caused local installations (with no source) to incorrectly
use MD5("") as a prefix, resulting in CLI commands being installed
at ~/.jdeploy/bin-arm64/d41d8cd98f00b204e9800998ecf8427e.{package}/
instead of ~/.jdeploy/bin-arm64/{package}/.

Now empty strings are treated the same as null, so packages without
a source use the simple package name as the fully qualified name.
Shell config files typically use $HOME instead of the absolute home
directory path (e.g., $HOME/.jdeploy/bin-arm64/... vs /Users/user/...).
The PATH verifier was only checking for the absolute path, causing
false negatives.

Now containsPathEntry() checks for both formats.
The CLI metadata file (.jdeploy-cli.json) is stored in Contents/MacOS/
alongside the CLI launcher, not in Contents/. Updated getAppDirectory()
to return the correct path.
Add inverse of jdeploy install command to uninstall locally-installed
apps during development. The command supports:
- jdeploy uninstall (reads package.json in current directory)
- jdeploy uninstall --package=<name> [--source=<url>]

Uses the existing UninstallService from installer module which handles:
- File and directory cleanup based on uninstall manifest
- Registry cleanup on Windows
- PATH entry removal from shell configs
- Package and app directory cleanup
Add support for testing jDeploy applications on Windows using Docker
containers (dockur/windows image). This enables macOS/Linux developers
to test Windows installations without a physical Windows machine.

Two modes supported:
- Headless mode (--windows or --windows=headless): Automated install
  and verification with JSON results
- Interactive mode (--windows=rdp): Boot container with RDP access
  for manual testing

New files:
- WindowsDockerConfig: Configuration model with mode, timeout, port
- WindowsDockerTestService: Orchestrates Docker container lifecycle
- WindowsTestResult: Result model with check status parsing
- PowerShell scripts for installation and verification
- Fix Docker image name: dockur/windows -> dockurr/windows
- Add --privileged flag for proper container access
- Add KVM=N on macOS for software emulation (no /dev/kvm)
- Add inheritIO() to show Docker output in real-time
- Add automatic RDP client opening when Windows boots
- Support RDP auto-open on macOS, Windows, and Linux
Add support for testing jDeploy applications on Linux using Docker
containers (dorowu/ubuntu-desktop-lxde-vnc image). This provides
a Linux desktop environment accessible via browser or VNC client.

Two modes supported:
- Headless mode (--linux or --linux=headless): Automated install
  and verification
- Interactive mode (--linux=vnc): Boot container with VNC access
  via browser (http://localhost:6080) or VNC client (port 5900)

New files:
- LinuxDockerConfig: Configuration model with mode, ports, resolution
- LinuxDockerTestService: Orchestrates Docker container lifecycle
- LinuxTestResult: Result model with check status parsing
- Shell scripts for Linux installation and verification
Dev mode (when running from jdeploy source project):
- Detects jdeploy dev environment automatically
- Copies jdeploy project to container local filesystem for faster builds
- Builds jdeploy from source with mvn package -DskipTests
- Runs jdeploy install && jdeploy run

Non-dev mode (when running from npm-installed jdeploy):
- Installs jdeploy via npm install -g jdeploy
- Runs jdeploy install && jdeploy run

Both modes:
- Mount app project to /app in container
- Auto-open browser when web interface is ready
- Autostart script runs on desktop login
- Terminal stays open for debugging
… installs

Separates local installation settings from headless server settings:
- LocalInstallationSettings enables all GUI integrations (dock, desktop,
  start menu, programs menu) for developer testing
- HeadlessInstallationSettings remains unchanged for headless server environments
- LocalInstallService now uses runLocalInstallProgrammatic() which uses
  the new LocalInstallationSettings
- dev-install-and-launch.sh now builds installer module before CLI

This fixes the issue where apps installed via `jdeploy install` wouldn't
appear in the Linux Applications menu because addToPrograms was disabled.
Windows Docker testing:
- Add golden snapshot approach for fast clean starts
- First run installs Windows to golden volume (~20 min)
- Default: reuses working volume (fast, keeps state)
- --windows=rdp,clean: copies golden to working (clean state)
- Use web interface on port 8006 instead of RDP
- Proper Ctrl+C handling with docker stop

Linux Docker testing:
- Add persistent config volume for state preservation
- Default: reuses existing container (fast, keeps installed apps)
- --linux=vnc,clean: removes container/volume (fresh state)
- Named container (jdeploy-linux-test) for easy management
- Proper Ctrl+C handling with docker stop
The installer creates .desktop files using the app title as filename
(e.g., 'Note Manager.desktop'), but the verifier was looking for
the FQPN (e.g., 'com.example.notemanager.desktop').
- Add autostart-install.bat for Windows startup automation
- Mount OEM folder to /oem in container (copied to C:\OEM in Windows)
- Update instructions to show how to enable autostart
- User can copy batch file to Startup folder for automatic runs
Add comprehensive E2E test framework that runs inside a Docker container
to verify headless installation, verification, uninstallation, and
uninstall verification for jDeploy applications.

Key features:
- Builds jdeploy from source inside the container using Maven
- Tests apps from jdeploy.com registry via headless installers
- Uses jdeploy verify-installation and verify-uninstallation commands
- Uses jdeploy uninstall --package for proper cleanup
- Generates JSON summary and per-app logs

Also fixes verification-checks.sh to use correct app directory paths
(~/.jdeploy/apps/ instead of incorrect ~/.local/share/jdeploy-apps/).

Usage: ./tests/e2e/linux/run-docker-tests.sh [--app=NAME] [--verbose]
Remove duplicate verification-checks.sh shell script and use the
jdeploy CLI verify-installation command instead. This ensures both
the E2E tests and jdeploy run --linux use the same verification logic.

Changes:
- LinuxDockerTestService: Copy jdeploy CLI JAR and libs to container
- install-and-verify.sh: Use jdeploy verify-installation command
- Remove verification-checks.sh (functionality now in Java)
Update LinuxVerifier to check ~/.profile first since the Linux
installer now writes PATH entries to ~/.profile instead of ~/.bashrc.
This ensures verify-installation and verify-uninstallation find the
PATH entry in the primary target file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant