# slhaf-hub Kotlin-based dynamic script host with HTTP APIs, root/sub token auth, script metadata, timeout control, and companion CLI/TUI tools. Language: - English: [README.md](README.md) - 中文: [README.zh-CN.md](README.zh-CN.md) ## Features - Dynamic script loading from `scripts/*.hub.kts` without restarting host - Root/Sub token authorization model - Metadata in script comments (`@desc`, `@timeout`, `@param`) - Script CRUD + run + metadata APIs - Subtoken management APIs - Run concurrency limit (`--max-run-concurrency`) - Script timeout (default 10s, script-level override) ## Requirements - JDK 17+ - Gradle (or Gradle wrapper) ## Quick Start Clone project: ```bash git clone https://github.com/slhafzjw/slhaf-hub.git cd slhaf-hub ``` ### Server #### 1) Run from terminal (Gradle) ```bash ./gradlew runWeb --args='--host=0.0.0.0 --port=8080 --scripts-dir=./scripts' ``` #### 2) Run with Docker ```bash docker build -t slhaf-hub:latest . docker run --rm -p 8080:8080 \ -v "$(pwd)/scripts:/app/scripts" \ -e SLHAF_HUB_TOKEN=your-token \ -e MAX_RUN_CONCURRENCY=8 \ slhaf-hub:latest ``` #### 3) Run with Docker Compose ```bash # optional: export SLHAF_HUB_TOKEN=your-token # optional: export SLHAF_HUB_PORT=8080 # optional: export MAX_RUN_CONCURRENCY=8 docker compose up -d --build ``` Health check: ```bash curl http://127.0.0.1:8080/health ``` ### Clients #### CLI ```bash kotlin tools/slhaf-hub-cli.kts --base-url=http://127.0.0.1:8080 --token-file=./scripts/.host-api-token list kotlin tools/slhaf-hub-cli.kts --token-file=./scripts/.host-api-token type kotlin tools/slhaf-hub-cli.kts --token-file=./scripts/.host-api-token run hello --arg=name=Alice --arg=upper=true ``` #### TUI ```bash kotlin tools/slhaf-hub-tui.kts --base-url=http://127.0.0.1:8080 --token-file=./scripts/.host-api-token ``` CLI/TUI env vars: - `SLHAF_HUB_BASE_URL` - `SLHAF_HUB_TOKEN` - `SLHAF_HUB_TOKEN_FILE` ## Auth Model Auth headers: - `Authorization: Bearer ` (recommended) - `X-Host-Token: ` Token source priority: 1. `SLHAF_HUB_TOKEN` env var 2. `scripts/.host-api-token` 3. Auto-generated token saved to `scripts/.host-api-token` Token types: - `root`: full access - `sub`: access to `/health`, `/type`, filtered `/scripts`, and allowed-script `/meta/{script}` + `/run/{script}` ## Script Metadata (`*.hub.kts`) Example: ```kotlin // @desc: Demo greeting API // @timeout: 10s // @param: name | required=false | default=world | desc=Name to greet val args: Array = emptyArray() val kv = args.mapNotNull { val i = it.indexOf('=') if (i <= 0) null else it.substring(0, i) to it.substring(i + 1) }.toMap() println("hello " + (kv["name"] ?: "world")) ``` Fields: - `@desc: ` - `@timeout: ` - `@param: | required=true|false | default= | desc=` Timeout formats: - `500ms`, `10s`, `1m`, or plain integer seconds (`10`) Default timeout: - `10s` ### Metadata Validation `POST /scripts/{script}` and `PUT /scripts/{script}` validate metadata before saving. On validation failure, server returns `400 Bad Request` with: - line-based reason details - valid metadata examples ## API Summary Public: - `GET /health` Authenticated: - `GET /type` - `GET /scripts` - `GET /meta/{script}` - `GET /run/{script}?k=v` - `POST /run/{script}?k=v` Root only: - `GET /scripts/{script}` - `POST /scripts/{script}` - `PUT /scripts/{script}` - `DELETE /scripts/{script}` - `GET /subtokens` - `GET /subtokens/{name}` - `POST /subtokens/{name}` - `PUT /subtokens/{name}` - `DELETE /subtokens/{name}` Common statuses: - `200`, `201`, `400`, `401`, `403`, `404`, `408` (timeout) ## Runtime Controls Run concurrency: - arg: `--max-run-concurrency=` - env (compose): `MAX_RUN_CONCURRENCY` - default: number of available processors The limit only applies to `/run/*` endpoints. ## Testing Run: ```bash ./gradlew test ``` Current automated coverage focuses on WebHost APIs: - auth behavior - script CRUD/meta/run - metadata validation responses - subtoken permission filtering - run timeout behavior ## Project Layout - `src/main/kotlin/work/slhaf/hub`: host implementation - `src/test/kotlin/work/slhaf/hub`: automated tests - `scripts`: runtime scripts and token/subtoken storage - `tools`: standalone CLI/TUI scripts - `Dockerfile`, `docker-compose.yml`: container deployment