All notable changes to this project will be documented in this file.
- Fix: envFile Now Overrides Inherited Shell Environment:
applyLoadedEnvToProcessEnvironmentnow usesputinstead ofputIfAbsent, so values fromenvFileand layeredenvironments.<env>.envFilereplace existing process environment entries (including empty strings from deploy shells). Precedence is nowinherited shell < envFile < LuCLI runtime env < lucee.json envVars. Dry-run--include envpreviews and Docker runtime env assembly seed fromSystem.getenv()so they match Tomcat/Jetty startup. Added regression coverage inLuceeServerConfigTestfor shell override, empty-shell override, andenvVarsfinal precedence. - Snapshot Workflow Rename + Pipeline Alignment: The dedicated snapshot pipeline is now
.github/workflows/publish-snapshot.yml(publish-snapshotjob), uses a rolling GitHub prerelease tagsnapshot(instead ofbeta-snapshot), and now owns both snapshot binary + snapshot Docker image publishing;release.ymlkeeps stable publish/manual-release responsibilities only. - Fix: Snapshot Release Notes Newline Rendering:
.github/workflows/publish-snapshot.ymlnow builds release notes via heredoc multiline text so GitHub release content renders with real line breaks instead of escaped\\nsequences. - Fix:
publish-snapshotWorkflow Launch4j Resolution on Fresh Runners:.github/workflows/publish-snapshot.ymlno longer uses Maven offline mode for the snapshot binary build step, solaunch4j-maven-plugincan resolve on runners where that plugin is not already cached. - Dedicated
publish-snapshotWorkflow for Snapshot Binaries: Snapshot binary prerelease publishing (snapshot) is now handled in a separate.github/workflows/publish-snapshot.ymlflow that runs onmainpushes (and manual dispatch), whilerelease.ymlkeeps stable release publishing manual-only. - Stable Release Publishing Now Manual-Only (
workflow_dispatch):release.ymlnon-snapshot publish steps (tag check, JReleaser publishing, and stable Docker image push) now require manual workflow dispatch, ensuring automatic push/merge runs tomainstay on the snapshot pipeline. - Rolling Snapshot Binary Publishing on
main(snapshot): The snapshot pipeline builds snapshot binaries (Linux/macOS launcher, Windowslucli.exe, and JAR) onmainpushes whenproject.versionis-SNAPSHOT, then publishes them to the rolling GitHub prerelease tagsnapshotwith both commit-specific (...-<shortsha>...) and stable (lucli-snapshot-*) asset names. - Release Script: Changelog-Based Bump Suggestion (
suggest-bump): Added./scripts/release.sh suggest-bumpto scanCHANGELOG.md## Unreleasedentries and recommend a SemVer bump (major,minor, orpatch) with a matchingbumpcommand hint. - Fix: Environment
configurationFileOverrides Now Layer over Base CFConfig (#64):environments.<env>.configurationFilenow preserves base CFConfig and deep-merges environment file values on top (with environment values winning on conflicts), instead of replacing the base configuration entirely. Added regression coverage inLuceeServerConfigTest#resolveConfigurationNode_environmentConfigurationFileMergesOverBaseConfigurationFile. - Fix: Windows Single-Binary Distribution via Launch4j (
#92): Release packaging now builds and publishes a Launch4jlucli.exeartifact (includinglucli-windows.zip), replacing concatenated batch+JAR assembly in release automation. The Windows installer now prefers.exeassets with legacy.batfallback for older tags, docs/download metadata now point to.exe, and CI now includes a Windows smoke check that builds with-Pwindows-exeand runslucli.exe --version. - Fix: Environment Dependency
enabledOverrides Ignored for Runtime Extension Activation:environments.<env>.dependencies.<dep>.enabled = falseoverrides were correctly applied duringlucli deps install --env, but were silently ignored when computingLUCEE_EXTENSIONSand the extension deploy list duringlucli server start --env <env>.buildLuceeExtensionsandresolveExtensionDependenciesForRuntimenow accept and apply the active environment before filtering disabled extensions, bringing runtime activation into parity with the install flow. The same fix is applied todeployExtensionsForServer. Closes #88. - MCP Per-Tool Input Schemas (
mcpToolSpecs()convention):tools/listnow consults an optional publicmcpToolSpecs()module function returning{toolName: inputSchema-struct}; a declared schema wins over the signature-derived one. Modules whose command functions take no formal parameters (e.g. the wheels module's structured-argCollection commands) previously advertised{properties:{}, additionalProperties:false}— telling MCP clients the tools accept no arguments at all. Same optional-convention mechanism asmcpHiddenTools(); the registry function itself is excluded from tool discovery. Declared schemas are deep-converted (Struct/Array → JSON object/array) with property-name case preserved. - Fix: Strip
hint:Key Prefix from MCP Tool Descriptions:tools/listno longer leaks the literalhint:key prefix into tool and parameter descriptions. The/** hint: ... */doc-comment convention (used by the Wheels module and others) is surfaced by Lucee with thehint:token included in the metadata value, so descriptions previously read"hint: Run the test suite"instead of"Run the test suite". Descriptions are now normalised at discovery time, matching how modules already strip the prefix for their own CLI help output. - Fix: Changing Lucee Version No Longer Requires Manual Prune: When restarting a stopped server directory for the same project, LuCLI now compares requested Lucee version/variant against stored (or inferred) runtime metadata and auto-recreates the server directory when they differ, instead of requiring manual
server prune. Startup now persists.lucee-versionand.lucee-variantmarkers for future comparisons, with regression coverage inLuceeServerManagerVersionChangeTest. - Regression Coverage: UrlRewrite RewriteValve Activation + Routed Paths (
#33): Added explicit regression checks thaturlRewrite.enabled=trueinjects Tomcat'sorg.apache.catalina.valves.rewrite.RewriteValve, writes host-levelconf/Catalina/<host>/rewrite.config, routes/hellothroughindex.cfmwithPATH_INFO, and preserves direct.cfmpassthrough. - Contract Clarification: Direct
.cfcExecution Is Unsupported (#14): Clarified docs and command help to consistently direct users to module entrypoints (lucli modules run <module>/ module shortcuts) instead oflucli run <file>.cfc. Added regression coverage for both blocked paths (lucli run file.cfcandlucli file.cfc) in BATS. - Fix: Windows Lucee Express Startup Script Selection (
#16): Tomcat/Lucee Express launch now resolves startup script selection through explicit helper methods (startup.sh/startup.batfor background,catalina.sh/catalina.batfor foreground), preserves Lucee Express root-script fallback, and launches.batscripts viacmd /con Windows so startup works reliably. Added focused unit coverage inLuceeServerManagerStartupScriptSelectionTest. - Fix: Windows Java 24+ Unsafe Warning Noise (
#38):src/bin/lucli.batnow conditionally adds--sun-misc-unsafe-memory-access=allowfor Java 24+ launches to suppress terminally deprecatedsun.misc.Unsafewarning spam seen during REPL startup, while preserving explicit user overrides fromLUCLI_JAVA_ARGS,JDK_JAVA_OPTIONS, orJAVA_TOOL_OPTIONS. - Regression Coverage:
configurationFile+ inlineconfiguration.extensionsmerge: AddedLuceeServerConfigTest#resolveConfigurationNode_mergesExtensionsFromConfigurationFileAndInlineConfigurationto lock expected CFConfig merge behavior where baseconfigurationFileextensions are preserved and inline duplicates override in place (expected unionA,B,Cfor baseA,B+ inlineB,C). - Fix: Stop/Prune Consistency with Stale
server.pid: Server lifecycle resolution now falls back to a livecatalina.pidwhenserver.pidpoints to a dead process.server status,server stop, project-scoped running-server lookup, and managed port-ownership checks now share a common PID recovery path; when a live Catalina PID is recovered,server.pidis refreshed (<pid>:<port>) so subsequent lifecycle commands stay consistent. Added regression coverage inLuceeServerManagerLifecycleTestfor both named lookup and project-scoped lookup recovery behavior. - Trailing
?Help Alias (One-Shot + Terminal): Added support for a trailing?token as a help alias solucli server ?showsserverhelp andlucli server start ?showsserver starthelp in both one-shot command mode and interactive terminal mode. Includes BATS coverage for both execution paths. - Fix:
admin.enabled=falseNow Enforces Tomcat Admin Endpoint Blocking inweb.xml:TomcatWebXmlPatchernow enforces admin disablement at servlet-mapping level and security-constraint level by removing explicit/lucee/admin.cfmand/lucee/admin/*servlet mappings (when present), skipping admin mapping generation for newly-added CFML servlet mappings, and adding a deny-all security constraint for admin URL patterns. Added unit coverage inCatalinaBaseConfigGeneratorTestand a new BATS regression test (tests/bats/12_admin_security.bats). - BATS Local Runtime Cache Reuse:
tests/bats/test_helper.bashnow reuses local Lucee Express downloads by symlinking~/.lucli/expressinto each per-test temporaryLUCLI_HOME, avoiding repeated runtime downloads and significantly improving local BATS execution speed. - Benchmark Workflow + README Badge: Added
.github/workflows/perf-benchmark.ymlto run startup/cfml now()benchmarks on schedule, manual dispatch, and relevantmainpushes, publish a run summary, and upload benchmark JSON artifacts. Added a benchmark status badge toREADME.mdlinking to the new workflow. - Performance Testing: BATS Perf Smoke + Benchmark Script: Added
tests/bats/12_perf_smoke.batswith conservative startup/simple-command latency smoke checks (--versionandcfml writeOutput(now())) and a newtests/perf/benchmark-startup.shscript for repeatable multi-run benchmarking with JSON output, optional baseline comparison, and optional regression-threshold enforcement. BATS runners now default toBATS_TEST_TIMEOUT=10, server dry-run fixtures now use Lucee7.0.4.34withvariant: "zero", andtests/test-bats.sh/tests/test.shprewarm a shared Lucee Express cache (LUCLI_BATS_EXPRESS_CACHE_DIR) so per-test temp homes avoid one-time runtime download delays. - Script Env Flag Propagation (
LUCLI_ENV): When running LuCLI command scripts with--env, the resolved environment is now exposed in script__envasLUCLI_ENV. Added regression test coverage to verify script-level access. - Release Workflow JReleaser Config Path: Updated
.github/workflows/release.ymlto runjreleaser:full-releasewith-Djreleaser.config.file=jreleaser.ymlso publishing uses the intended explicit JReleaser config. - Repository Default CODEOWNERS: Added a repository-level
CODEOWNERSfile that assigns@cybersonicas the default code owner. - Fix: Aliased-Binary Usage Strings in
completion,module init, andmodulesHints: User-facing usage text, next-step hints, and error messages inCompletionCommand,ModulesInitCommandImpl, andModuleCommandnow resolve the active binary name viaSystem.getProperty("lucli.binary.name", "lucli")instead of hardcodinglucli. When invoked under an alias (for examplewheelsvia-Dlucli.binary.name),wheels completionprintsUsage: wheels completion …, the generated bash/zsh script registers completion forwheelsand callswheels versions-list,wheels completion mddocumentswheels …, andwheels module init/wheels modules updateerrors point the user atwheels. Bareluclioutput is unchanged (the property defaults tolucli). Javadoc,org.lucee.lucli.*class references,~/.luclihome-path plumbing, and the install temp-dir prefix are intentionally left as-is. Complements the existing profile-aware home-directory work; themcpusage string is fixed separately. - Fix: Profile-Aware Module Commands:
lucli modules list,modules init,modules run, andmodules uninstallnow resolve the modules directory viaLucliPaths.resolve().modulesDir()instead of duplicating path resolution with a hardcoded~/.luclifallback. Under a non-default profile (e.g. thewheelsbinary) these commands now correctly target~/.wheels/modules/— previously they silently operated on~/.lucli/modules/even whensystem pathsreported the correct location. Themodules listheading also reflects the active profile's display name (e.g.Wheels Modules), andModuleRepositoryIndex'ssettings.jsonlookup is routed through the same resolver. Adds regression tests for the list command output and the repository-index path resolution. - Fix: Per-Subcommand
--helpfor Modules:lucli modules run <module> <subcommand> --help(e.g.wheels migrate --help) now forwards the subcommand to the module'sshowHelpso modules can render per-subcommand help. Previously the trailing subcommand was discarded and every<module> <subcommand> --helpprinted the module's global help. Modules whoseshowHelpignores the extra argument fall back to global help unchanged, so behavior is preserved for them. - Fix: Aliased-Binary Dispatch (
--verbose/--version/ barehelp/mcpbranding): When LuCLI runs under an aliased binary name (e.g.wheelsvia-Dlucli.binary.name), several root-level concerns were swallowed before the module ran.--verbose/-vwas consumed by the root option and never reached the module (so a module'sdoctor --verbose/stats --verboseproduced no verbose output); a value-bearing--version=<tag>(e.g.wheels deploy --version=v1.2.3) hit the root's booleanversionHelpflag and errored with "Invalid value for option '--version'"; the barehelpverb (wheels help) printed LuCLI's global builtin help instead of the module's; andmcp's usage message printed the literallucli. NowexecuteViaModulesCommandre-injects--verbose/--debuginto the module args; a newpreprocessModuleVersionrewrites<module> … --version=<value>tomodules run …(mirroringpreprocessModuleHelp);preprocessModuleHelproutes the barehelpverb to the module'sshowHelp; andMcpCommandusage text uses the active binary name. Bareluclibehavior is unchanged; full test suite green (651). - Fix: Port Availability Check Was IPv4-Blind:
isPortAvailable()probed with a wildcardServerSocket, which on a dual-stack JVM (no-Djava.net.preferIPv4Stack) binds the IPv6 wildcard and never conflicts with a listener bound to the IPv4 family. Any port already held by an IPv4-only process (python -m http.server, Djangorunserveron 8000, Postgres/Redis on127.0.0.1, ...) was reported "available", soserver start/wheels startbooted on top of it — a split-stack collision where IPv4-loopback clients reach the other process whilelocalhost→::1reaches Lucee, frequently masking the conflict.isPortAvailable()now connect-probes both loopback families (127.0.0.1and::1) before the wildcard bind; a successful connect means a listener is present in either family. A connect probe (rather than a second bind) is used because it detects listeners regardless of address family and is not fooled by sockets inTIME_WAIT, so a server's own quick restart is not bumped to a new port. Regression-tested inLuceeServerConfigTest(IPv4-only listener → unavailable; free port → available). - Install Validation Workflow Across macOS/Linux/Windows: Added
.github/workflows/install-validation.ymlwith a manualworkflow_dispatchsmoke test matrix that validates LuCLI installation on Linux via the bootstrap installer, macOS via Homebrew tap install, and Windows via Scoop bucket install. - Fix: Pages Workflow Markspresso Build Invocation: Updated
.github/workflows/static.ymlto runlucli markspresso buildinstead oflucli markspresso build clean, which was incorrectly treatingcleanas a source directory and preventingpublic/artifact generation. - Release Pipeline: CI-Gated JReleaser Publishing: Refactored
.github/workflows/release.ymlto gate publishing behind the reusable CI workflow and switched non-snapshot publishing tojreleaser:full-releasefor GitHub release and Homebrew tap automation, replacing standalone tap update workflows. - Default Version Semantics: App Version vs Lucee Version: Updated defaults so new configs use app
version: "1.0.0"while Lucee engine defaults tolucee.version: "7.0.4.34". Also tightened Lucee version resolution to treat top-levelversionas a legacy Lucee value only when it matches Lucee-style version format, preventing app-version values from being misinterpreted as runtime engine versions. - Fix: Release Binaries Missing Since v0.3.18 + Legacy Asset Names Restored: The
jreleaser-maven-pluginconfiguration inpom.xmlcarried an inline<jreleaser>DSL block (token only), which takes precedence over the rootjreleaser.yml— so JReleaser ran with zero distributions ("No files configured for checksum. Skipping") and v0.3.18 was published with no binaries. The plugin now points atjreleaser.ymlvia<configFile>, and the release additionally ships the legacy-named assets every pre-0.3.18 consumer downloads (lucli-<version>-linux,lucli-<version>-macos,lucli-<version>.bat,lucli-<version>.jar,lucli.jar) via afiles.artifactsblock plus copy step inrelease.yml.
-
CI + Release Stability for Environment Fallback/Snapshot Builds: Updated BATS dry-run coverage to match current missing
--envbehavior (warn and use base config instead of failing), and hardenedrelease.ymlpublish Docker build steps by restoring Maven cache inpublishand building JARs in offline mode to avoid snapshot-resolution 403 regressions. -
Docs: Dependency Examples Page: Added
content/docs/100_dependencies-and-extensions/020_dependency-examples.mdwith copy/pastelucee.jsonsnippets for supported dependency types (git,forgebox, andextensionvia ID/slug, URL, and local path), plus install command examples; linked it from the dependency section in docs index and dependency management page. -
Java 21 Runtime Gate in Wrapper Scripts: Added early runtime checks in
src/bin/lucli.shandsrc/bin/lucli.batso LuCLI fails fast with a clear error when Java is missing, unparseable, or older than Java 21. -
Dependency Shortcut Templates for
deps add:lucli deps add <shortcut>now supports non-interactive shortcut templates loaded fromsrc/main/resources/dependencies/dependency-shortcuts.json(including built-intestboxandfw1), and--devwrites the shortcut dependency todevDependencies. -
Fix: Numeric
#env:Placeholder Deserialization inlucee.json: Server config loading now preprocesses typed numeric port fields before strict Jackson binding, so values like"port": "#env:HTTP_PORT#"(including env overrides) resolve correctly from.env/system variables instead of failing withnot a valid int value. -
Fix: Environment Override
envFileReload: Applying--envoverrides now reloads the realized mergedenvFilebefore runtime env assembly, so dry-run env previews and server runtime env variables use the environment-specific file (for exampleprod.env) instead of the base file. -
Dry-Run
--includeSection Selector:lucli server start --dry-runandlucli server run --dry-runnow support explicit section selection via--include(for example--include env,lucee,tomcat-web,tomcat-server).--include-envno longer implicitly includes realizedlucee.json; once any include selector is provided, only requested sections are printed. Legacy start preview flags remain available as aliases. -
Dry-Run Realized Env Variable Preview:
lucli server start --dry-run --include-envnow prints a dedicated section showing environment variables realized duringlucee.jsonplaceholder substitution (#env:VAR#, deprecated${VAR}, and default fallbacks), in addition to the runtime env preview. -
Dependency-Level
enabledToggle for Extensions: Added support forenabled: falseondependencies/devDependenciesentries (including environment overrides) so disabled extensions are fully ignored bydeps install, auto-install on server start, and runtime extension activation (LUCEE_EXTENSIONS/ deploy handling). -
Fix: Default
rewrite.configNow Actually Serves Static Files: The bundledrewrite_template/rewrite.configwas using a stack ofRewriteCond %{REQUEST_URI} !patternentries before a single rewriteRewriteRuleto "skip" static-file paths. On Tomcat 11'sRewriteValvethat idiom does NOT short-circuit the way Apachemod_rewritedoes — the conditions effectively don't gate the rule, the rule fires for every request, andpublic/static files (.css,.js,.txt,.png, etc.) silently 404 even though their extensions are explicitly listed in the negation. The template now expresses the same intent as positive-matchRewriteRule … - [L]passthroughs (router-file passthrough, CFML-extension match, conventional static directories,/lucee,/rest/), which terminate rule processing for matching requests and let Tomcat's default servlet serve the file. Each passthrough preserves the exact semantic of the corresponding originalRewriteCond !entry — including^/${routerFile}.*$(so/${routerFile}/path-infostyle framework URLs aren't incorrectly rewritten to/${routerFile}/${routerFile}/path-infowhen URL rewriting is partially configured) and^/lucee.*$(matches/luceewith or without a trailing slash, equivalent to the original's!^/luceeno-trailing-slash semantic). Net effect:public/assets/foo.css,public/__sentinel.txt, etc. now return HTTP 200 withContent-Typeset correctly; framework routing through${routerFile}still works for/,/posts, etc.; and/${routerFile}/anythingpaths pass through cleanly. Discovered during a Wheels Tutorial fresh-VM bake (the bonus-basecoat chapter'scurl -o public/assets/basecoat.min.css ...instructions were dead on arrival because the file existed but the rewrite intercepted the request before the default servlet could serve it). Verified end-to-end on Tomcat 11.0.13 + Lucee Express 7.0.0.395 against a 10-case URL matrix covering both static and dynamic paths plus the new edge cases. -
Whitelabeling Support for LuCLI: Added a new build-time whitelabeling feature for branded distributions, including profile-aware naming/home isolation, configurable branding metadata and banner content, optional product-version override (
branding.productVersion) with${LUCLI_VERSION}banner token support, and bundled module packaging/deployment from/modules-installon first startup. -
Version Output Includes Java Runtime:
lucli --versionnow includes aJava Version:line alongside LuCLI and Lucee versions, sourced from the active Java runtime (java -version) with a runtime-property fallback for portability. -
Fix:
.lucliLeadinglucliPrefix Now Preserves Quoted Arguments: Script-line normalization no longer rebuilds commands from parsed tokens when stripping an initiallucliprefix. We now remove only the leading command token from the raw line, preserving quoted values likename=\"Mark Drew\"for module andruninvocations. Added regression test coverage for quoted argument preservation. -
Fix: OpenAI AI Config Timeout Compatibility:
lucli ai config addnow omitscustom.timeoutfor OpenAI-compatible providers (openai,copilot,deepseek,grok,ollama,perplexity,other) because newer OpenAI-compatible APIs reject it as an unsupported request argument. When--timeoutis provided for those providers, LuCLI now warns that the value is ignored. -
Admin Disabled Security Env Enforcement: When
admin.enabled=false, LuCLI now enforcesLUCEE_ADMIN_ENABLED=falsein runtime process environments and Tomcatsetenv.sh/setenv.batgeneration, and surfaces it in dry-run--include-envpreviews. -
Fix:
.lucliCommand Failures Now Exit Non-Zero:.lucliscripts now propagate subcommand exit codes (for example,runfailures) so command errors no longer end with an overall success exit status. Added BATS regression coverage. -
Fix:
cfmlCommand Exits Non-Zero on Failure:lucli cfml '<expr>'now exits with code 1 when the expression throws. Previously, the catch block logged the error and fell through toreturn resultwithresult == null, which picocli maps to exit 0. Callers checking exit codes (shell pipelines, CI jobs, pre-commit hooks, doctest harnesses) now correctly see failure. -
Fix:
JAVA_HOMEPreflight Before Server Start:lucli server start(andwheels start) now detects missing or brokenJAVA_HOMEbefore the child JVM is spawned, and prints an actionable error pointing at Adoptium. Previously the child exited silently and the parent reported a misleading "port conflicts detected" error, forcing users to hunt through~/.wheels/servers/<name>/server.errto find the real cause. The preflight now runs against the effective child-process environment (parent shell +.envfile +lucee.jsonenvVars), so project-levelJAVA_HOMEoverrides are honored and the check won't false-positive when the var is defined in project config but not the parent shell. -
Module Dispatch: Auto-Bind Positional Args to Typed Params: LuCLI's module dispatch now maps CLI positional args (
arg1,arg2, ...) to a target function's typed parameters by declaration order. Module authors can declare typed signatures likefunction greet(required string name, boolean verbose = false)and get rich MCP JSONSchema (via existing auto-discovery), MCP named-arg binding (standard CFMLargumentCollection), and CLI positional binding (this change) all from a single source of truth. Named args and already-populated typed params win over positional fallback; excess positional args stay in argCollection for variadic access. Closes the last remaining "write a per-function arg-parsing shim" pattern for LuCLI module authors. -
Lockfile-Independent Extension Activation: Server runtime extension activation no longer requires
dependencySettings.useLockFile=true.server start/server runnow derive extension deployment andLUCEE_EXTENSIONSfromlucee.jsondependencies when lockfiles are disabled (including dry-run--include-envpreviews), with lockfile entries still used when enabled/available. -
Deps Install Materializes Extension Files by Default:
lucli deps installnow copies/downloadstype: "extension"dependencies withpath/urlinto theirinstallPathduring install (instead of only recording metadata). AddeddependencySettings.materializeExtensionsOnInstall(defaulttrue) to opt out and keep metadata/cache-based behavior. -
BATS Coverage for Local Extension Deployment: Added an integration lifecycle test that creates a fake local
.lexdependency, runslucli deps install, starts the server, and verifies the extension is deployed under~/.lucli/servers/<server>/lucee-server/deploy/. -
CI Test Result Publishing Permissions: Updated GitHub Actions test jobs to grant
pull-requests: writeandissues: writesoEnricoMi/publish-unit-test-result-actioncan post PR comments without failing Linux unit/integration jobs with403 Resource not accessible by integration. -
Server Runtime Prewarm Flag (
--prewarm): Added--prewarmsupport to bothlucli server startandlucli server runto pre-download runtime artifacts and exit without starting a server. LuCLI now prewarms Lucee Express forlucee-expressruntime, prewarms Lucee JARs fortomcat/jettyruntimes, and reports a no-download message fordockerruntime. -
Server Header Shows Generated Lucee Config Path: When server startup writes
.CFConfig.json, LuCLI now printsGenerated lucee config in: <path>alongside existing startup header lines so the effective Lucee config file location is explicit. -
Fix: Profile-Aware Home Directory in Script Engine:
LuceeScriptEngine.getLucliHomeDirectory()now uses the active CLI profile's home directory instead of a hardcoded~/.luclipath. This ensures thatBaseModule.cfcand other shared resources are provisioned to the correct home directory (e.g.~/.wheels/modules/when running aswheels). -
Server Environment Fallback (
LUCLI_ENV) + Docker Default:lucli server startandlucli server runnow fall back toLUCLI_ENVwhen--env/--environmentis not provided, while still honoring explicit--envprecedence. The Docker image now setsLUCLI_ENV=""by default so deployments can override it at runtime (for exampledocker run -e LUCLI_ENV=prod ...). -
Server Warmup Flag (
--warmup): Added--warmupsupport tolucli server startandlucli server runto enable Lucee build-time warmup by injecting bothLUCEE_ENABLE_WARMUP=trueand-Dlucee.enable.warmup=truefor that invocation (without persisting changes tolucee.json). -
Fix: MCP Tool Output Capture:
lucli mcp <module>now correctly captures moduleout()/err()output into JSON-RPC response bodies. Previously, Lucee'ssystemOutput()bypassedSystem.setOut()redirection because it caches stream references at engine startup — so every MCP tool returned empty content to callers while output leaked to the terminal, contaminating the stdio protocol stream.BaseModulenow usescreateObject("java", "java.lang.System").out.println(...)for dynamic lookup that honors redirection. -
MCP Tool Hiding: Public functions inherited from
BaseModule(init,getEnv,getSecret,verbose,getAbsolutePath,executeCommand,version,showHelp) are now automatically excluded from MCPtools/listresponses. Modules can additionally declare specific commands to hide with a newmcpHiddenTools()convention:public array function mcpHiddenTools() { return ["start", "stop", "console"]; }Hidden tools remain reachable as CLI subcommands — this is purely an MCP-surface filter for commands that are stateful, interactive, or otherwise inappropriate for autonomous agent use.
-
Fix: BaseModule.cfc Dev Sync: The shared
BaseModule.cfcin the active profile's modules directory is now refreshed when its content differs from the JAR-bundled copy, instead of only when the LuCLI version number changes. Dev iterations that modifysrc/main/resources/modules/BaseModule.cfcnow reach the installed copy without needing a formal version bump. -
executeModuleAndReturn()onLuceeScriptEngine: Framework callers can now invoke a module function and capture its return value without triggering the legacy print-if-non-null CLI behavior. Used internally by MCP tool introspection. -
#project:path#Placeholder in Configuration: Added#project:path#placeholder support forlucee.jsonconfiguration values (e.g. datasource DSNs). Resolved at server start alongside#env:VAR#and#secret:NAME#, replacing the token with the absolute project directory path.
- Unit Test Coverage One-Shot Script: Added
tests/unit-tests-coverage.shto run Maven unit tests with JaCoCo coverage from project root and print/open generated report paths (target/site/jacoco/index.html). - Fix: Gemini AI Config Template Output:
lucli ai config add --type gemininow emits the GeminiEngine-oriented template shape with provider-specific keys (apikey,connectTimeout,socketTimeout,temperature,conversationSizeLimit, andbeta) and no default-mode field when left at the command default. - Fix: AI Provider Mapping for
ai config add:lucli ai config add --type claude/--type gemininow infer the correct Lucee engine classes when--classis omitted, emit provider-specific API key fields (apiKeyvssecretKey), preserve OpenAI-compatibletypehandling, and mask/list both key formats consistently. - PR Review Workflow Templates + Script: Added a new
pr-review/workflow with reusable reviewer/synthesis prompts, baseline review rules, example pending-code context payload, and a LuCLI command script (pr-review/review-pending-code.lucli) that runs multi-agent review passes and produces a synthesized final report. - Server Slug-First Lifecycle Resolution + BATS Coverage: Server lifecycle now treats server slug/name as the primary identity, with project path as a secondary one-to-many index. Project-scoped
status,stop, andprunecommands now fail with a clear ambiguity error when multiple server slugs are linked to the same project path (requiring--nameor--config),status/prunenow accept--configto resolve alternatelucee*.jsonnames, andprune --forcenow attempts a managed stop before pruning. Added new BATS lifecycle tests validating start/status/stop flow, config-targeted stopping, and multi-slug ambiguity behavior. - BATS Migration Coverage Expansion: Added BATS coverage for module install validation and module run execution, server dry-run preview flags (
--include-lucee,--include-tomcat-server,--include-tomcat-web, HTTPS preview flags, and--include-all), extended environment merge assertions, computed dependency mappings in dry-run CFConfig output, server command-surface smoke checks, and binary/JAR version parity. Also hardened BATS temp home setup to work in bothsetupandsetup_filescopes. - Fix: Whitespace Flag Semantics + Coverage: Made whitespace preservation opt-in by default (
--whitespacenow explicitly enables preserved writer mode), corrected CFML writer mode mapping for the flag, and added deterministic BATS coverage that verifiescfmlWritertoggles betweenregularandwhite-space. - Fix:
.lucliCommented Continuation Lines: Fixed line-continuation parsing so# ...comment lines inside backslash-continued commands are ignored instead of being concatenated into the executed command. - AI Prompt Rough Cost Estimation: Added
lucli ai prompt --estimateto show a pre-send rough estimate (estimate-only mode, no provider request is sent) that breaks down composed text tokens, JSON envelope overhead tokens, and image heuristic tokens. Added optional--assume-output-tokens,--input-price-per-1m, and--output-price-per-1mto approximate total tokens and estimated USD cost with explicit warning language that billed usage may differ. - Updated install location for
./build.sh install: Changed the default install location to~/.local/bin/luclifor better compatibility with the curl installer and common Linux conventions. The script now checks for an existinglucliin the PATH and uses that location if found, otherwise it falls back to~/.local/bin/lucli. - Docs: README Status Badges + Contributing Guide: Replaced placeholder README badges with live GitHub Actions workflow badges, refreshed key README links/version notes, and added a new
CONTRIBUTING.mdguide for contributor onboarding. - Testing Migration to BATS: We are moving tests from legacy shell suites to BATS (
tests/bats/andtests/test-bats.sh). - Block Direct
.cfcExecution viarun:lucli run <file>.cfc(and equivalent shortcut invocation) is now blocked with a clear error message to avoid component pathing instability. Use module entry points vialucli modules run <module>instead. - Runtime CWD Sync + Local Component Resolution: LuCLI now tracks effective runtime CWD across terminal and
.lucliexecution flows, refreshes Lucee/cwdmappings before eval, and fixescd+cfml new LocalComponent()/ relativerunbehavior in command scripts. - URL Rewrite Direct CFML Bypass: Tomcat
rewrite.confignow preserves direct.cfm/.cfc/.cfmlrequests while still routing framework-style paths through the configured router file, with integration tests and harness cleanup updates to validate this behavior. - Docs: LuCLI Command Scripts Terminology: Documentation now standardizes
.lucli/.lucautomation files as “LuCLI command scripts,” adds a dedicated guide, and updates cross-links from CFML execution and CLI basics pages. - One-Shot Server Overrides No Longer Persist to
lucee.json:lucli server start/lucli server runnow apply invocation overrides (including barekey=value,--port,--webroot, and--enable-lucee/--disable-lucee) in memory for that run only, instead of mutating your project config file. - CFConfig Path Normalization + Legacy Compatibility: Standardized server CFConfig handling to
~/.lucli/<server>/context/.CFConfig.json(removing the duplicatedlucee-serverpath segment), while still reading legacy locations when present and cleaning up old nested files/directories after migration. - Script Argument Variables (
ARGS,ARGV,__namedArguments): CFML scripts (.cfs,.cfm) now have access toARGS(a struct with both numeric positional keys and namedkey=valueentries),ARGV(an array with the script filename as element 0 followed by raw args), and__namedArguments(a map of only the named key=value arguments). The__env/ENVbinding also now includes variables set viasetin the parent.lucliscript. setVariable Propagation to External Commands: Variables defined viaset VAR=valuein.lucliscripts are now merged into the environment of external child processes (e.g. shell commands,env,curl). Previously they were only visible to the embedded CFML engine context.- Fix:
lucli module initWizard Error: Fixed an interactive prompt issue where module creation could fail with❌ Error: No line foundafter entering module details. - AI Config Quiet Mode: Added
--quiettolucli ai config addto suppress printing imported config payload output, making CI logs safer.
- Bootstrap Installers + Download UX: Added cross-platform bootstrap installers (
install.shandinstall.ps1) for one-line install flows (curl ... | shandirm ... | iex), published as release assets, and documented in README/install docs. Updated the download page with copyable install commands, pinned-version examples, and automatic pinned-version updates from the latest release (with release workflow stamping). - Adding JQ and Curl to docker image - this allows us to use common tools alongside with lucli in pipelines
- Fix: Module Install with
--revon Branch Names: Fixedmodules install --rev <branch>failing when git is not available. You can now install modules from both tags and branches in non-git environments. .lucliOutput Redirection: Added script-level output redirection support in.luclifiles using>(overwrite) and>>(append), so command/module output can be routed directly to files during automation runs.- Windows Bat File fixes
- MCP Server for Modules: Added
lucli mcp <module>to run a per-module MCP server over stdio, exposing a module’s public functions as MCP tools (with JSON schema-derived input). - AI Command (
lucli ai) Enhancements:- Added
lucli aicommand group with provider config, prompting, testing, and skill-path management workflows. - Registered
AiCommandat the root CLI command level solucli ai ...works consistently in one-shot command mode. - Added AI command coverage in terminal help output (
ai config,ai config defaults,ai config add,ai config list,ai prompt,ai list,ai skill). - Added guided provider setup via
lucli ai config add --guidedwith optional--test-after-save. - Added
lucli ai config defaultsfor default endpoint/model management, and madelucli ai configshow subcommand help. - Added provider listing from Lucee CFConfig (
lucli ai list/lucli ai config list) and compatibility handling for--refresh. - Added secret key masking by default in list/config output, with explicit
--showto reveal full values when needed. - Updated prompt UX to support repeatable
--image, rules via--rules-file/--rules-folder, and clearer instruction composition behavior. - Added
@filesupport for--textso prompt task content can be loaded directly from files. - Added
lucli ai prompt --dry-runto print the fully resolved prompt payload/composed question without sending a provider request. - Added
lucli ai prompt --output-file <path>support to persist rendered prompt responses (including--jsonand dry-run output), with overwrite protection via--force. - Fixed
--system @file/--text @filehandling by disabling picocli@argfileexpansion, so file paths are consumed literally and full file contents are loaded as intended.
- Added
- Module Runtime Permissions + Env/Secrets Resolution:
- Added module metadata keys
permissions.envandpermissions.secretsto declare runtime env/secret aliases. - Added shorthand compatibility arrays
envVarsandsecrets(treated as required aliases). - Added module runtime resolver with
.env.luclisupport and optional.envfallback (controlled by settings). - Added support for
#secret:NAME#resolution in module runtime values via LuCLI local secret store. - Added strict-mode controls for module env exposure (
moduleRuntime.strictEnv) and.envfallback (moduleRuntime.allowDotEnvFallback). - Added install/update permission approval prompts and persisted grants under
modulePermissionsin settings. - Extended BaseModule helpers to support injected context (
getEnvprecedence updates and newgetSecrethelper).
- Added module metadata keys
- System Backup Commands: Added
lucli system backupcommand group withcreate,list,verify,prune, andrestoresubcommands. - System Backup Create Progress:
lucli system backup createnow shows a shared progress bar with source size totals, supports--progressfor per-file archive output, and excludes legacy~/.lucli/backupscontent by default unless backups are explicitly included. - System Inspect Command: Added
lucli system inspect --luceeto pretty-print Lucee CFConfig JSON from~/.lucli/lucee-server/lucee-server/context/.CFConfig.json(or--path), and madelucli systemshow help when run without a subcommand. - Safer Backup Storage Location: Backup archives now default to
~/.lucli_backups(outside~/.lucli) to reduce risk of losing backups when cleaning or replacing the LuCLI home directory. Optional overrides are supported viaLUCLI_BACKUPS_DIRor-Dlucli.backups.dir. - Backup Retention Pruning: Added
lucli system backup prune --older-than <duration> --keep <count> [--force]with dry-run by default and checksum sidecar cleanup when pruning. - Module Install Name/Alias Override (
--name): Added-n/--nameoption tomodules installandmodules addcommands, allowing you to install a module under a different local name that overrides themodule.jsonname (e.g.,lucli modules install --url=https://github.com/cybersonic/lucli-bitbucket.git#dev --name=bitbucket-dev). Includes validation of the alias and improved error messages when module names mismatch. - Modules Help Improvements: The
modules --helpoutput now includes an explicit "Install/Add Options" section listing-u,-r,-n, and-fflags with descriptions.
- URL Rewriting: Migrated to Tomcat RewriteValve: Replaced the Tuckey UrlRewriteFilter (
urlrewrite.xml) with Tomcat's built-in RewriteValve (rewrite.config). This eliminates javax/jakarta servlet API compatibility issues across Tomcat versions and removes the need for an external JAR. Rewrite rules now use Apachemod_rewritesyntax and are placed at the Host level (conf/Catalina/<host>/rewrite.config) instead of insideWEB-INF/. When both HTTPS redirect and URL rewriting are enabled, rules are combined into a singlerewrite.configfile. ⚠️ Deprecation:urlrewrite.xml: Existing projects usingurlrewrite.xmlwill see a warning at server startup. Migrate your rewrite rules to the newrewrite.configformat (Apachemod_rewritesyntax). See the updated URL Rewriting documentation.- Jetty Runtime: URL Rewriting Not Supported: URL rewriting is not available when using the Jetty runtime. A warning is displayed if
urlRewrite.enabledis set with a Jetty-based runtime. - New
#env:VAR#Variable Syntax: Variable substitution inlucee.jsonnow uses#env:VAR_NAME#syntax (e.g.,#env:DB_HOST#,#env:PORT:-8080#for defaults). Theenv:prefix makes intent explicit, distinguishing environment lookups from#secret:NAME#and potential future CFML expression support. - Protected Zones: The
configuration,environments.<env>.configuration, andjvm.additionalArgsblocks are protected — only#env:VAR#substitution is applied, preserving${VAR}for Lucee runtime evaluation and JVM system properties. ⚠️ Deprecation:${VAR}and bare#VAR#Syntax: The old${VAR}syntax and the bare#VAR#syntax (without theenv:prefix) are both deprecated. They still work but trigger a one-time warning. Migrate to#env:VAR#— the old syntax will be removed in a future release.- CFML Expression Guard: A warning is shown if
#...#placeholders contain parentheses, which may indicate accidental CFML expressions rather than simple variable references. --configSupport forserver stopandserver restart: Added--config/-coption toserver stopandserver restartcommands. Allows stopping/restarting servers by specifying their configuration file (e.g.,lucli server stop --config lucee-docker.json) instead of requiring--name. The server name is resolved from the config file automatically.sourceDirective for.lucliScripts: Added asourcecommand for loading.env-style files inside.lucliscripts (e.g.,source .env). Paths are resolved relative to the script's directory. Loaded variables become available as${VAR}placeholders and inscriptEnvironment, just likeset.--envfileCLI Option: Added--envfile <path>flag to pre-load environment variables from a file before script execution (e.g.,lucli --envfile=.env myscript.lucli). Variables are available to all script lines from the start.⚠️ Deprecation: Top-levelversioninlucee.json: The Lucee engine version should now be specified under a new"lucee"block:"lucee": { "version": "6.2.2.91", "variant": "standard" }. This frees up the top-level"version"key for specifying the application/project version. Existing configs with a top-level"version"containing a Lucee version string (e.g."6.2.2.91") are automatically migrated at load time with a deprecation warning. A"variant"field (default"standard") replaces the previousruntime.variantfor selecting Lucee editions. The old format will be removed in a future release.- Fix: Shebang Line Handling: Fixed syntax error when executing CFML scripts (.cfs, .cfm) that contain shebang lines (e.g.,
#!/usr/bin/env lucli). Scripts can now include shebangs for direct execution while remaining compatible withlucli run. The shebang line is automatically stripped before the script is passed to the Lucee engine. - JSON Comments:
lucee.jsonnow supports//line comments and/* */block comments, making it easier to annotate your configuration. - Relative Path Resolution in envVars: Relative paths (starting with
./or../) inenvVarsare now automatically resolved to absolute paths against the project directory, so the server process receives correct paths regardless of its working directory. - Dry-Run for
server run:lucli server run --dry-runnow works the same asserver start --dry-run, showing the realized configuration without starting the server. - Environment Preview (
--include-env): Added--include-envflag for--dry-runon bothserver startandserver runto display the environment variables that would be passed to the runtime (CATALINA_OPTS, LUCEE_EXTENSIONS, envVars, etc.). Also included in--include-all. - Platform Updates: Updated to Lucee 7.0.2.101-SNAPSHOT.
- Module Help: Modules now support
--help(e.g.lucli markspresso --help) to display available subcommands with their arguments, types, and defaults. Module name, version, and description are pulled frommodule.json. Module authors can overrideshowHelp()for custom help output. - Runtime Providers: LuCLI now supports pluggable server runtimes via the new
runtimekey inlucee.json. Choose how your Lucee server runs:- Lucee Express (default) — same as before, no config change needed.
- Vendor Tomcat — point LuCLI at your own Tomcat installation with
"runtime": {"type": "tomcat", "catalinaHome": "/path/to/tomcat"}. LuCLI validates the installation, checks Lucee/Tomcat version compatibility, and creates an isolated per-server instance. Also supports theCATALINA_HOMEenvironment variable as a fallback. - Docker (experimental) — run Lucee in a Docker container with
"runtime": "docker". Automatically pulls thelucee/luceeimage, maps ports and volumes, and manages the container lifecycle.server stop,server status, andserver listall work with Docker containers.
- Runtime Configuration in lucee.json: Supports both string shorthand (
"runtime": "docker") and object form ("runtime": {"type": "tomcat", "catalinaHome": "..."}) with optional fields for Docker image, tag, and container name. Updatedlucee.schema.jsonwith the new schema. - Fix: Server Status with Tomcat: Fixed a bug where
server statuswould report a running server as "NOT RUNNING" because the PID file was being overwritten during Tomcat startup. - Documentation: Added runtime providers guide covering all three providers with configuration examples and a manual QA test guide.
- New Aliases Added plural aliases for better discoverability:
lucli server→lucli servers,lucli module→lucli modules,lucli secret→lucli secrets. - Reusable Table UI Component: Added
org.lucee.lucli.ui.Tableclass for consistent CLI table rendering across commands. Features include multiple title rows, auto-sizing columns, full-width separators, optional footer, and configurable border styles (BOX, ASCII, NONE). Uses builder pattern for fluent API. - ModuleConfig Loader: Added
org.lucee.lucli.modules.ModuleConfigclass that loadsmodule.jsononce with sensible defaults. Eliminates redundant JSON parsing (was reading file 3x per module) and provides status detection (DEV/INSTALLED/AVAILABLE). - Modules Refactoring: Moved module commands to
cli/commands/modules/subpackage. RefactoredModulesListCommandImplto use new Table and ModuleConfig classes for cleaner, more maintainable code. - Code Cleanup: Removed unused imports across codebase, fixed WindowsSupport statics, general import organization.
- Emoji Support Refactoring: Created new
EmojiSupportclass with centralized global emoji control. SingleshowEmojissetting in~/.lucli/settings.jsonnow affects all output. UseEmojiSupport.process()to replace emojis with text fallbacks when disabled. SimplifiedPromptConfigandTerminalto use this unified approach. - Fix: Prompt Display Bug: Fixed broken Unicode regex patterns that were stripping letters from paths in prompts (e.g., showing
//instead of~/Code/LuCLI). - Fix: Environment Configuration Merge: Fixed issue where environment-specific config in
lucee.json(e.g.,--env=prod) would revert to defaults instead of properly overriding base config values. Now reads raw JSON from file for correct deep merging. - Fix: Terminal Exception Handling: Added general exception handler to the REPL loop so uncaught exceptions display an error message and continue instead of crashing the terminal.
- Fix: Tab Completion for File Paths: Fixed tab completion for
ls,cat,cd,head,tail, etc. - completion now triggers correctly after typing a command with a trailing space. Also fixed~/path completion to preserve the tilde prefix instead of expanding to the full home path. - External Command File Completion: Added file path completion as fallback for external commands like
code,vim,open, etc. - Welcome Page: When starting a Lucee server with
enableLucee=true(the default), LuCLI now automatically creates a welcomeindex.cfmin the webroot if one doesn't exist. The page displays server info, helpful commands, and links to documentation. Existingindex.cfmfiles are never overwritten. - Fix: resolved an issue after refactoring where the values are not returned from the
executeLucliScriptCommandmethod, causing CFML command outputs to not be displayed in the terminal. The method now returns the command output as a string, which is printed to the terminal if not empty. - Fix: Fixed silent failures when executing picocli subcommands (e.g.
server stop) in.lucliscripts. Captured output was being discarded instead of returned, so commands would run but produce no visible output or error messages. - SpotBugs Integration: Added SpotBugs Maven plugin for static analysis. New documentation at
content/docs/150_testing-and-qa/020_spotbugs.mdcovers setup, usage, and configuration.
- REPL Command: Added
lucli replcommand for an interactive CFML read-eval-print loop. Provides a focused CFML-only environment for quick experimentation with history support, separate from the full terminal mode. - Script Preprocessor: New
LucliScriptPreprocessorfor.lucliscript files with support for:- Line continuation using backslash (
\) at end of line - Comment stripping (lines starting with
#) - Environment conditional blocks (
#@env:dev ... #@end,#@prod,#@env:!prod) - Secret resolution (
${secret:NAME}) - Placeholder substitution
- Line continuation using backslash (
- Environment Flag: Added
--env/-eoption to set the execution environment (dev, staging, prod) for.lucliscripts. Also reads fromLUCLI_ENVenvironment variable as fallback. - Code Refactoring: Major internal refactoring of LuCLI main entry point and command handling:
- Merged LuCLICommand into LuCLI to eliminate code duplication
- Cleaned up main() method and moved routing logic for better maintainability
- Added cleaner output methods with format string support
- Fixed deprecated method names after refactoring
- Documentation: Added blog layout templates and navigation components. Added TODO document for picocli enhancements and remaining refactoring tasks.
- Git Dependency Caching: Added persistent git dependency cache under
~/.lucli/deps/git-cache(configurable viausePersistentGitCache) and a newlucli deps prunecommand to clear cached git clones.
- Fixing build process: Corrected the release workflow to add the expected "static" lucee.json
- Server Sandbox Mode: Added a
--sandboxoption tolucli server runto start a transient foreground server without creating or modifyinglucee.jsonand without persisting the server instance after shutdown. - Run Commands from Modules: Added
executeCommandmethod toBaseModule.cfcto allow modules to programmatically execute LuCLI commands. - Env File Configuration & Tomcat Environment: Added
envFileandenvVarstop-level keys tolucee.jsonso projects can control which env file is loaded for${VAR}substitution and explicitly pass selected variables through to the Tomcat process environment. You can see usage examples in the updated Environment Variables documentation. - Dependency Install Reliability: Improved
deps installand local repository behavior when using env-driven configuration and custom repositories.
- Secrets Management: Added first-class secrets management support with safeguards to prevent accidental leakage in logs, dry-run output, and documentation examples. Includes automatic checks for hard-coded secrets and improved validation of sensitive configuration values.
- Server Configuration Editor: Introduced an interactive server configuration editor and new
server new/server editstyle commands for creating and modifying Lucee server configurations without manually editinglucee.json. Centralized configuration handling in a newServerConfigHelperfor more consistent behavior. - Configuration Locking: Added configuration lock behavior and tests to ensure locked server configurations cannot be modified unintentionally, improving safety for shared or production server configs.
- Lucee Enable/Disable Flags: Added
--enable-luceeand--disable-luceeoptions tolucli server startso you can explicitly turn Lucee on or off per run without changing the underlying configuration file. - Server Open Command & Webroot Override: Added a
lucli server opencommand to quickly open the active server in a browser, plus support for overriding the webroot at startup for temporary testing setups. - Terminal Completion Enhancements: Improved terminal autocompletion to include new server commands and options, as well as better coverage of existing commands in both CLI and interactive terminal modes.
- Local Repository Improvements: Added an initial local repository implementation to support more flexible module and project workflows (e.g., local repositories for tools like markspresso), laying groundwork for richer dependency and module sources.
- Documentation Updates: Expanded and corrected documentation, including new content docs and fixes to the generated command reference and completion markdown for more accurate and readable help output.
- Internal Refactoring: Refactored internal classes to keep public APIs and high-level logic at the top of key classes, improving readability and maintainability without changing user-facing behavior.
- Dependency Management: Added
depsandinstallCLI commands for managing project dependencies. New dependency infrastructure withdependencySettingsconfiguration. - Server Run Command: New
server runcommand for running Lucee server in foreground mode (non-daemon), useful for Docker containers and debugging. - Server Configuration Improvements: Added AJP connector configuration support with ability to disable via
ajp.enabled=false. Enhanced mapping computation for server startup. Additional server start command options now available. - Docker Support: Added Docker documentation and examples with improved default user configuration in Dockerfile.
- Server Prune Enhancement: Added confirmation prompt and
--forceflag toserver prunecommand for safer cleanup operations. - Version Display: Enhanced version message output with improved formatting.
- Architecture Refactoring: Major refactoring to simplify architecture - consolidated terminal implementations, migrated commands to direct Picocli implementation, improved code quality. Added naming conventions documentation.
- Command Timing: Added execution timing information to all Picocli commands for performance monitoring.
- Lucee Extension Support: Added comprehensive extension dependency management with name-based resolution via extension registry. Extensions can be defined in
lucee.jsondependencies using friendly names (e.g., "h2", "redis", "postgres") instead of UUIDs. Supports both automatic ID-based installation viaLUCEE_EXTENSIONSenvironment variable and direct .lex file deployment to server deploy folder. - Extension Registry: Created
ExtensionRegistrywith JSON-based mapping of 24+ common extensions (databases, cache, core utilities) from friendly names/slugs to UUIDs. Registry located atsrc/main/resources/extensions/lucee-extensions.jsonwith comprehensive documentation. - Dependency Installer: New
ExtensionDependencyInstallerhandles extension installation and deployment. Extensions with URL/path are deployed to{serverDir}/lucee-server/deploy/folder. Lock file tracks extension IDs and sources. - Alternate Configuration Files: Added
-c/--configoption toserver startandserver runcommands for using alternate configuration files (e.g.,lucli server start -c lucee-prod.json). - Stop All Servers: Added
--allflag toserver stopcommand to stop all running servers at once:lucli server stop --all. Displays progress and summary of stopped servers. - Bug Fixes: Renamed
LuceLockFiletoLuceeLockFile(corrected spelling). - Examples: New
examples/dependency-extensions/andexamples/server-environments/demonstrating extension usage and environment configurations. Addedexamples/dependency-git-subpath/for dependency documentation. Archived old examples. - Testing: Removed obsolete test scripts and updated .gitignore.
- Dry-Run Enhancements: Added
--include-luceeflag toserver start --dry-runfor previewing resolved.CFConfig.jsonbefore deployment. Shows merged configuration fromconfigurationFileand inlineconfigurationwith environment variable substitution applied. - Documentation: New comprehensive guides for Dry-Run Preview System and Environment Variables. Updated main documentation index with quick-start links.
- Testing: Enhanced test suite with dry-run validation tests for configuration preview functionality.
- Lucee Admin Password Added lucee admin configuration in
admin.enabledandadmin.passwordkeys of lucee.json - HTTPS Support: Added full HTTPS support with per-server keystores, automatic certificate generation, and HTTP→HTTPS redirect. Fixed Tomcat configuration to use modern
SSLHostConfignested element structure. Includes optionalhostfield for custom domains and--dry-runpreview flags (--include-https-keystore-plan,--include-https-redirect-rules,--include-all). - Configuration Management: New
server getandserver setcommands with dot notation support for reading/writing configuration values. Includes--dry-runflag for previewing changes. Added environment variable substitution with${VAR_NAME}and${VAR_NAME:-default}syntax, automatic.envfile loading, and virtual read-onlyserverDirkey. - Server Management Improvements: Smart shutdown port auto-assignment (HTTP port + 1000 with conflict detection), comprehensive port conflict checking (HTTP, HTTPS, JMX, shutdown),
server list --runningfilter, and enhanced startup output with server directory path. - Tomcat Configuration:
--dry-runmode now shows patchedserver.xmlandweb.xml(not just vendor templates) via--include-tomcat-weband--include-tomcat-serverflags. Support for passing arbitrary Lucee server options throughserver start. - Module System Enhancements: Module repository support with bundled local index and external repositories via
~/.lucli/settings.json. Git-aware module protection for development modules. Modules can now accept Picocli @Option annotations for parameters. Enhanced module initialization with--gitflag. - Lucee CFConfig Integration: Improved handling with deep JSON merging -
configurationFileloads as base, inlineconfigurationoverrides/extends. Enables shared base configs with per-project customization. - Shell & Terminal: Migrated to picocli's built-in
AutoCompletegenerator (bash + zsh). Enhanced terminal with name display, Timer utility for script execution, and improved argument parsing (--argument=value,argument=value,--no-argument). - Module System: Added output and background colors to BaseModule. Removed BaseModule functions from Module.cfc template. Improved module repository list view.
- Platform Updates: Updated to Lucee 7.0.1.93-SNAPSHOT and Java 21. Updated documentation and
lucee.schema.jsonwithenableLucee=truedefault. Newdocumentation/ENVIRONMENT_VARIABLES.md.
- Add first-class Java agent support for Lucee servers via
lucee.json:- New optional
agentssection inlucee.jsonto declare named Java agents withenabled,jvmArgs, anddescriptionfields. lucli server startnow accepts--agents,--enable-agent,--disable-agent, and--no-agentsflags to toggle agents per run without editinglucee.json.- JVM options are assembled in a stable order: memory settings, JMX flags, active agents'
jvmArgs, then existingjvm.additionalArgs.
- New optional
- Fix interactive terminal autocomplete behavior to provide more accurate and reliable command suggestions.
- Improve
lsoutput alignment when using emoji prefixes:- Column width calculation now accounts for the
emoji + space + namedisplay string, keeping columns consistent. - Script and executable files now use a more consistently rendered emoji to reduce visual drift between columns.
- Column width calculation now accounts for the
- Refactor the interactive terminal to use the Picocli + JLine3 integration (
InteractiveTerminalV2), unifying CLI and terminal command handling and improving error reporting. - Expand one-shot execution support so
luclican run CFML scripts, CFML components, LuCLI modules, and.luclibatch scripts with consistent argument handling and built-in variables. - Enhance module management:
- Add richer
lucli modulessupport for listing, initializing, installing, updating, and uninstalling modules under~/.lucli/modules. - Introduce
module.jsonmetadata and publicmodule.schema.jsonfor editor tooling and validation. - Add language and template example modules under
src/main/resources/modules/.
- Add richer
- Improve server configuration and security:
- Add XML-based patchers for
server.xmlandweb.xmlso LuCLI can adjust the HTTP connector port and ROOT context docBase to matchlucee.json. - Automatically add a
security-constraintto preventlucee.jsonfrom being served over HTTP. - Extend
lucee.jsonwithurlRewrite,admin,configuration, andconfigurationFileoptions, plus a publishedlucee.schema.jsonfor validation.
- Add XML-based patchers for
- Add new documentation:
documentation/EXECUTING_COMMANDS.mdcovering CFML scripts, components, modules, and.luclibatch scripts.documentation/SERVER_AGENTS.mdexplaining Java agent configuration and server start flags.documentation/SERVER_TEMPLATE_DEVELOPMENT.mddescribing Tomcat template generation and conditional blocks for URL rewriting and admin routes.- Additional documentation updates and examples for configuration and URL rewriting.