
Ready-made plugins for HAL client: API-key, bearer-token, base-url rewriter, chain combinator, CURIE and logger; supports service-discovery or declarative JSON/YAML config loading.
Ready-made example plugins for the HALDiSh Kotlin Multiplatform HAL client. Each is an independent module, published to Maven Central.
| Module | Pattern | Artifact |
|---|---|---|
api-key |
KMP (commonMain) | com.helpchoice.nahal-plugins:haldish-plugin-api-key |
bearer-token |
Per-platform | com.helpchoice.nahal-plugins:haldish-plugin-bearer-token |
base-url-rewriter |
Per-platform | com.helpchoice.nahal-plugins:haldish-plugin-base-url-rewriter |
chain |
KMP (combinator) | com.helpchoice.nahal-plugins:haldish-plugin-chain |
curie |
KMP (preLink) |
com.helpchoice.nahal-plugins:haldish-plugin-curie |
logger |
KMP + expect/actual file I/O | com.helpchoice.nahal-plugins:haldish-plugin-logger |
Each module's own README.md documents its configuration and hooks. Their dependency snippets leave
the version as a placeholder: Gradle writes <current-version>, Maven writes
${haldish.plugins.version}. Substitute the latest release — shown on the
releases page — or, for Maven, define the
property once and let every plugin dependency read it:
<properties>
<haldish.plugins.version>REPLACE-ME</haldish.plugins.version>
</properties>All six modules are published from one build and always share a version, so one property covers however many of them you use.
JVM, JS (IR), WasmJS, Linux (x64/arm64), macOS (x64/arm64), iOS (x64/arm64/simulator-arm64), Windows (mingwX64) — the same target set as the library.
Two independent mechanisms, and every module here ships for both:
ServiceLoader
(META-INF/services/com.helpchoice.nahal.haldish.plugin.HaldishPlugin) or
HALDISH_PLUGIN_PATH pointing at a jar; on native, dlopen of libhaldish_plugin.*
resolving the haldish_plugin_* C symbols.HALDISH_CONFIG (JSON/YAML) or window.__nahalConfig, keyed by
the plugin's fully-qualified class name. This bypasses mechanism 1 entirely.See ../nahal/PLUGIN_CONTRACT.md for the authoritative contract.
Grab haldish-plugins-chain-<version>.zip from the
releases page. It holds the curie,
base-url-rewriter and logger jars plus a config that activates all three in the right order —
curie first (its expansion runs before base-URL resolution), logger last (it sees the final
request). Unzip it and start an installed NaHAL with both
variables set:
cd haldish-plugins-chain-<version>
NAHAL_PLUGINS_DIR="$PWD/plugins" \
HALDISH_CONFIG="$PWD/haldish-config.json" \
/Applications/NaHAL.app/Contents/MacOS/NaHAL # macOS; use the installed launcher elsewhereBoth variables are required. NAHAL_PLUGINS_DIR only makes the jars loadable; HALDISH_CONFIG is
what turns them on. Double-clicking the app won't work — the variables must be in its environment.
CURIE-prefixed and relative hrefs then resolve as you navigate, and every exchange is written to
./haldish-log.
:web-demo is this repository's own demo page — the real NaHAL UI (consumed as the published
nahal-ui artifact, never built here) running with curie → base-url-rewriter → logger
active, against same-origin HAL fixtures:
./gradlew stageWebDemo # → build/web-demo/
python3 -m http.server -d build/web-demo 8080The staged site has a chooser at / — it picks between the JavaScript build (js/, runs
anywhere) and the WebAssembly build (wasm/, smaller and faster, needs a WasmGC browser), and
prints the sample resource URLs to paste into either one. Follow the links from the root document
and watch CURIE-prefixed and relative hrefs resolve. Open devtools too — a browser has no writable
filesystem, so logger prints each exchange to the console instead of ./haldish-log. See
web-demo/README.md.
The staged directory is a plain static site, and
.github/workflows/pages.yml publishes it to GitHub Pages on every
push to master, on v* tags, and on manual dispatch.
./gradlew build # all modules, all host-buildable targets
./gradlew :curie:jvmTest # one module's JVM tests
./gradlew stagePluginArtifacts # JVM jars, native shared libs, chain bundle → build/release
./gradlew stageChainBundle # just the ready-to-run chain bundle
./gradlew stageWebDemo # browser demo page → build/web-demo
./gradlew stageChainMacosApp # signed + notarized NaHAL_Chain.app, both arches → build/releasestageChainMacosApp codesigns, notarizes and staples :chain's standalone NaHAL_Chain.app
before staging it, so it needs MACOS_SIGN_IDENTITY plus one notarytool credential set
(MACOS_NOTARY_PROFILE, an App Store Connect API key, or an Apple ID and app-specific password) —
as a Gradle property or an environment variable. stagePluginArtifacts leaves it out unless you
pass -PincludeMacosApp. See the credential list at the top of that task in
build.gradle.kts.
Releases run from .github/workflows/release.yml on a v* tag or
manual dispatch: it checks the tag against the project version, stages the plugin assets and both
signed, notarized NaHAL_Chain.app bundles, and collects them into one draft GitHub release with a
SHA-256 table. Without the macOS signing secrets the app jobs are skipped and the plugin assets are
released on their own.
Publishing: ./gradlew publishToMavenCentral (signing required).
haldish comes from HALDiSh_KMP; nahal-ui comes from
NaHAL and is used only by the demo runners (jvmRun, chain's
macOS app binary, and :web-demo) — never by the published plugin klibs. Both are versioned
independently of this repository; the versions consumed are pinned in gradle/libs.versions.toml
and both are on Maven Central, so a clean clone builds with no local publishing.
settings.gradle.kts keeps mavenLocal() only for iterating against unreleased builds of them; see
CLAUDE.md for the cold-start order.
Apache-2.0 — see LICENSE.
Ready-made example plugins for the HALDiSh Kotlin Multiplatform HAL client. Each is an independent module, published to Maven Central.
| Module | Pattern | Artifact |
|---|---|---|
api-key |
KMP (commonMain) | com.helpchoice.nahal-plugins:haldish-plugin-api-key |
bearer-token |
Per-platform | com.helpchoice.nahal-plugins:haldish-plugin-bearer-token |
base-url-rewriter |
Per-platform | com.helpchoice.nahal-plugins:haldish-plugin-base-url-rewriter |
chain |
KMP (combinator) | com.helpchoice.nahal-plugins:haldish-plugin-chain |
curie |
KMP (preLink) |
com.helpchoice.nahal-plugins:haldish-plugin-curie |
logger |
KMP + expect/actual file I/O | com.helpchoice.nahal-plugins:haldish-plugin-logger |
Each module's own README.md documents its configuration and hooks. Their dependency snippets leave
the version as a placeholder: Gradle writes <current-version>, Maven writes
${haldish.plugins.version}. Substitute the latest release — shown on the
releases page — or, for Maven, define the
property once and let every plugin dependency read it:
<properties>
<haldish.plugins.version>REPLACE-ME</haldish.plugins.version>
</properties>All six modules are published from one build and always share a version, so one property covers however many of them you use.
JVM, JS (IR), WasmJS, Linux (x64/arm64), macOS (x64/arm64), iOS (x64/arm64/simulator-arm64), Windows (mingwX64) — the same target set as the library.
Two independent mechanisms, and every module here ships for both:
ServiceLoader
(META-INF/services/com.helpchoice.nahal.haldish.plugin.HaldishPlugin) or
HALDISH_PLUGIN_PATH pointing at a jar; on native, dlopen of libhaldish_plugin.*
resolving the haldish_plugin_* C symbols.HALDISH_CONFIG (JSON/YAML) or window.__nahalConfig, keyed by
the plugin's fully-qualified class name. This bypasses mechanism 1 entirely.See ../nahal/PLUGIN_CONTRACT.md for the authoritative contract.
Grab haldish-plugins-chain-<version>.zip from the
releases page. It holds the curie,
base-url-rewriter and logger jars plus a config that activates all three in the right order —
curie first (its expansion runs before base-URL resolution), logger last (it sees the final
request). Unzip it and start an installed NaHAL with both
variables set:
cd haldish-plugins-chain-<version>
NAHAL_PLUGINS_DIR="$PWD/plugins" \
HALDISH_CONFIG="$PWD/haldish-config.json" \
/Applications/NaHAL.app/Contents/MacOS/NaHAL # macOS; use the installed launcher elsewhereBoth variables are required. NAHAL_PLUGINS_DIR only makes the jars loadable; HALDISH_CONFIG is
what turns them on. Double-clicking the app won't work — the variables must be in its environment.
CURIE-prefixed and relative hrefs then resolve as you navigate, and every exchange is written to
./haldish-log.
:web-demo is this repository's own demo page — the real NaHAL UI (consumed as the published
nahal-ui artifact, never built here) running with curie → base-url-rewriter → logger
active, against same-origin HAL fixtures:
./gradlew stageWebDemo # → build/web-demo/
python3 -m http.server -d build/web-demo 8080The staged site has a chooser at / — it picks between the JavaScript build (js/, runs
anywhere) and the WebAssembly build (wasm/, smaller and faster, needs a WasmGC browser), and
prints the sample resource URLs to paste into either one. Follow the links from the root document
and watch CURIE-prefixed and relative hrefs resolve. Open devtools too — a browser has no writable
filesystem, so logger prints each exchange to the console instead of ./haldish-log. See
web-demo/README.md.
The staged directory is a plain static site, and
.github/workflows/pages.yml publishes it to GitHub Pages on every
push to master, on v* tags, and on manual dispatch.
./gradlew build # all modules, all host-buildable targets
./gradlew :curie:jvmTest # one module's JVM tests
./gradlew stagePluginArtifacts # JVM jars, native shared libs, chain bundle → build/release
./gradlew stageChainBundle # just the ready-to-run chain bundle
./gradlew stageWebDemo # browser demo page → build/web-demo
./gradlew stageChainMacosApp # signed + notarized NaHAL_Chain.app, both arches → build/releasestageChainMacosApp codesigns, notarizes and staples :chain's standalone NaHAL_Chain.app
before staging it, so it needs MACOS_SIGN_IDENTITY plus one notarytool credential set
(MACOS_NOTARY_PROFILE, an App Store Connect API key, or an Apple ID and app-specific password) —
as a Gradle property or an environment variable. stagePluginArtifacts leaves it out unless you
pass -PincludeMacosApp. See the credential list at the top of that task in
build.gradle.kts.
Releases run from .github/workflows/release.yml on a v* tag or
manual dispatch: it checks the tag against the project version, stages the plugin assets and both
signed, notarized NaHAL_Chain.app bundles, and collects them into one draft GitHub release with a
SHA-256 table. Without the macOS signing secrets the app jobs are skipped and the plugin assets are
released on their own.
Publishing: ./gradlew publishToMavenCentral (signing required).
haldish comes from HALDiSh_KMP; nahal-ui comes from
NaHAL and is used only by the demo runners (jvmRun, chain's
macOS app binary, and :web-demo) — never by the published plugin klibs. Both are versioned
independently of this repository; the versions consumed are pinned in gradle/libs.versions.toml
and both are on Maven Central, so a clean clone builds with no local publishing.
settings.gradle.kts keeps mavenLocal() only for iterating against unreleased builds of them; see
CLAUDE.md for the cold-start order.
Apache-2.0 — see LICENSE.