Skip to content

feat: add abdm-cli IPC companion CLI#1313

Open
ID-VerNe wants to merge 3 commits into
amir1376:masterfrom
ID-VerNe:cli-ipc
Open

feat: add abdm-cli IPC companion CLI#1313
ID-VerNe wants to merge 3 commits into
amir1376:masterfrom
ID-VerNe:cli-ipc

Conversation

@ID-VerNe

@ID-VerNe ID-VerNe commented Jul 2, 2026

Copy link
Copy Markdown

Summary

Add an optional abdm-cli desktop companion CLI for AB Download Manager.

This is not a standalone download manager. The CLI acts as an IPC client for the single-instance desktop app: it reads the configured integration port from appSettings.json, starts the desktop app in the background when needed, and sends commands to the embedded HTTP server.

The CLI is always bundled with the Windows installer. Adding it to PATH is available as an optional installer checkbox and is disabled by default.

Addresses #1294.

Design alignment with #1294

This PR follows the direction discussed in #1294:

  • abdm-cli is an IPC client, not a standalone download manager.
  • The desktop app remains the single source of state.
  • The CLI auto-starts the desktop app when it is not running and waits until it is ready.
  • The initial command surface is intentionally small: add, list, info, pause, resume, and remove.
  • The CLI reads the integration port from ~/.abdm/config/appSettings.json.
  • The CLI uses http4k with OkHttp, matching the existing SingleInstance communication stack.
  • The CLI is always bundled with the Windows installer, while PATH integration is optional and disabled by default.

Architecture

NSIS install directory ($INSTDIR)
├── ABDownloadManager.exe          ← Desktop GUI
├── runtime\bin\java.exe           ← Bundled JRE used by the CLI
├── cli\abdm-cli.jar               ← CLI fat JAR
└── abdm-cli.bat                   ← CLI entry point

When the user runs abdm-cli <command>:

  1. abdm-cli.bat invokes the bundled JRE:
    runtime\bin\java.exe -jar cli\abdm-cli.jar <command>
  2. The CLI reads the integration port from ~/.abdm/config/appSettings.json.
  3. If the desktop app is not running, the CLI starts ABDownloadManager.exe --background.
  4. The CLI waits until the embedded HTTP server responds.
  5. The CLI sends the requested command to http://127.0.0.1:{port}/<endpoint>.
  6. Results are printed to stdout as table output or JSON.

CLI commands

Command HTTP endpoint Description
add <url> POST /start-headless-download Add a new download and return the download ID
list GET /list List downloads; supports --all and --json
info <id> POST /info Show detailed information for one download
pause <id>... POST /pause Pause one or more downloads
resume <id>... POST /resume Resume one or more downloads
remove <id>... POST /remove Remove downloads; keeps completed files by default

Implementation notes

CLI packaging

  • Adds a CLI module under cli/app.
  • Builds abdm-cli.jar as a fat JAR using the Shadow plugin.
  • Reuses the desktop app's bundled JRE instead of requiring a system Java installation.
  • Adds java.management to the runtime image because Mordant terminal detection requires it.

Windows installer integration

  • The NSIS installer now always includes:
    • cli\abdm-cli.jar
    • abdm-cli.bat
  • Adds an optional "Add AB Download Manager to PATH" installer section.
  • The PATH option is disabled by default.
  • Uninstall removes the PATH entry.
  • Installer cleanup removes the CLI directory and batch entry point.

Desktop app discovery

  • DesktopLauncher can discover the installed desktop app on Windows.
  • Registry-based discovery is preferred when available.
  • Standard install locations are used as fallback candidates.

Scope and follow-ups

This PR only wires the CLI into the Windows NSIS installer.

The CLI implementation is kept platform-neutral where possible, and DesktopLauncher includes platform-specific discovery hooks for Windows, Linux, and macOS. However, only the Windows installer path is included in this PR because the current installer plugin does not provide equivalent Linux/macOS file injection support.

Linux/macOS packaging and website documentation can be handled in follow-up PRs.

Testing

Tested manually on Windows.

./gradlew :cli:app:shadowJar -Pjvm.toolchain=21
./gradlew :desktop:app:createInstallerNsis -Pjvm.toolchain=21

After installing ABDM with "Add AB Download Manager to PATH" enabled:

abdm-cli --help
abdm-cli list
abdm-cli list --json
abdm-cli add https://example.com/file.dat
abdm-cli info <id>
abdm-cli pause <id>
abdm-cli resume <id>
abdm-cli remove <id>

Also verified:

  • The CLI starts the desktop app in the background when it is not already running.
  • Commands work when the desktop app is already running.
  • The CLI reads the port from ~/.abdm/config/appSettings.json.
  • The bundled runtime\bin\java.exe is used.
  • PATH integration is disabled by default in the installer.
  • PATH integration works when enabled.
  • Uninstall removes the PATH entry.

ID-VerNe and others added 3 commits June 29, 2026 09:02
ADD:
- ApiDownloadModel, IdRequest, IdsRequest, RemoveRequest serializable DTOs
- IntegrationHandler with 5 new methods: listDownloads, getDownloadInfo, pauseDownloads, resumeDownloads, removeDownloads
- GET /list, POST /info, POST /pause, POST /resume, POST /remove routes
- /start-headless-download returns JSON {"id": <downloadId>}
- Full IntegrationHandlerImp implementation with toApiModel() mapping and auto-categorization

FIX:
- addDownloadTask returns actual download ID via downloadManager.addDownload
- Auto-categorization via categoryManager.autoAddItemsToCategoriesBasedOnFileNames
ADD:
- DesktopClient, DesktopResult for HTTP IPC to desktop app
- DesktopLauncher for auto-starting the desktop app with 30s polling
- PortResolver reading browserIntegrationPort from appSettings.json
- CliFormatting utilities using shared SizeConverter
- CliMain entry point with Clikt command tree and versionOption
- 6 commands: add, list, info, pause, resume, remove
- build.gradle.kts with buildConfig plugin for version sync

FIX:
- Ping response parsing: compare against "pong" (not "\"pong\"")
- --help exits with code 0, not 64
- Null exception message shows class name instead of "null"
- ANSI alignment: padEnd on plain text before applying color
- JSON error messages go to stderr, not stdout
- CliktError no longer prints duplicate messages
- Orphan desktop process destroyed on startup timeout
- DesktopLauncher scans Program Files on Windows for binary
- URL scheme check tightened to http/https only
- DesktopLauncher uses DISCARD redirect, not inheritIO
… keep-file fix

ADD:
- Shadow plugin config for abdm-cli fat JAR build
- abdm-cli.bat launcher invoking bundled JRE
- AddToPath.nsh and RemoveFromPath.nsh for PATH management
- copyJavaExeToRuntime Gradle task (Compose jlink omits java.exe)
- Registry-based binary discovery in DesktopLauncher
- cli/CLI.md with usage documentation for all 6 commands

CHANGE:
- NSIS template: CLI file copy, optional PATH, uninstall cleanup
- desktop/app/build.gradle.kts: installer deps, java.management module
- gradle/libs.versions.toml: add shadow plugin version

FIX:
- --keep-file defaults to true, keeping completed files by default
@ID-VerNe ID-VerNe marked this pull request as ready for review July 2, 2026 02:54
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