{"id":48640810,"url":"https://github.com/tsukhani/jclaw","last_synced_at":"2026-06-28T07:01:15.604Z","repository":{"id":349543030,"uuid":"1202789158","full_name":"tsukhani/jclaw","owner":"tsukhani","description":"Java-based Enterprise AI Harness — AI-powered automation platform built in pure Java on Abundent's fork of the Play Framework 1.x with a Nuxt frontend. Combines agent orchestration and job scheduling with no Spring, no Node.js, and no Python runtime.","archived":false,"fork":false,"pushed_at":"2026-06-25T08:59:41.000Z","size":44173,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-25T10:23:24.893Z","etag":null,"topics":["agent-orchestration","ai-agents","ai-assistant","automation","enterprise-ai-assistant","java","job-scheduling","nuxt","play-framework"],"latest_commit_sha":null,"homepage":"https://github.com/tsukhani/jclaw","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tsukhani.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-06T12:00:32.000Z","updated_at":"2026-06-25T08:59:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"8b0141a2-f260-45ca-adb1-d76e11874c0e","html_url":"https://github.com/tsukhani/jclaw","commit_stats":null,"previous_names":["tsukhani/jclaw"],"tags_count":321,"template":false,"template_full_name":null,"purl":"pkg:github/tsukhani/jclaw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsukhani%2Fjclaw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsukhani%2Fjclaw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsukhani%2Fjclaw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsukhani%2Fjclaw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsukhani","download_url":"https://codeload.github.com/tsukhani/jclaw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsukhani%2Fjclaw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34880189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-orchestration","ai-agents","ai-assistant","automation","enterprise-ai-assistant","java","job-scheduling","nuxt","play-framework"],"created_at":"2026-04-09T19:21:06.296Z","updated_at":"2026-06-28T07:01:15.594Z","avatar_url":"https://github.com/tsukhani.png","language":"Java","funding_links":[],"categories":["Skills \u0026 Plugins"],"sub_categories":["Third-Party Platforms"],"readme":"\u003ch1 align=\"center\"\u003eJClaw - Java-based Enterprise AI Assistant\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"combined-logo.png\" width=\"650\" alt=\"JClaw Logo\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eJAVA FIRST. NO BLOAT. PURE POWER.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://jenkins.abundent.com/job/JClaw/\"\u003e\u003cimg src=\"https://jenkins.abundent.com/buildStatus/icon?job=JClaw\u0026style=flat-square\" alt=\"Build Status\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/github/v/release/tsukhani/jclaw?style=flat-square\u0026label=release\u0026color=blue\" alt=\"Release\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/repo-size/tsukhani/jclaw?style=flat-square\u0026label=repo%20size\u0026color=blue\" alt=\"Repo Size\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-MIT-green?style=flat-square\" alt=\"License: MIT\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/JDK-25%2B-orange?style=flat-square\" alt=\"JDK: 25+\"\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Quick Install (one-line)\n\nGet JClaw running in one command. The installer downloads the self-contained\n`jclaw-bundle.zip` from the latest GitHub Release, verifies Java 25+ (the bundle's\n**only** runtime dependency), extracts it to `~/.jclaw`, and starts JClaw on\n\u003chttp://localhost:9000\u003e.\n\n**macOS \u0026 Linux**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/tsukhani/jclaw/main/install.sh | sh\n```\n\n**Windows (PowerShell)**\n\n```powershell\nirm https://raw.githubusercontent.com/tsukhani/jclaw/main/install.ps1 | iex\n```\n\n\u003e On Windows the bundle runs through **Git Bash** or **WSL** (the launcher is a\n\u003e POSIX shell script). The installer prefers Git Bash; if only WSL is present it\n\u003e launches there; if neither is found it installs and prints how to run it.\n\nOnce running, manage it with `jclaw status`, `jclaw stop`, `jclaw restart` from\nany new shell — the installer puts the `jclaw` command on your `PATH` (via\n`~/.local/bin`) and wires up `\u003cTAB\u003e` completion for bash and zsh. To remove JClaw\nentirely, run `jclaw uninstall`: it stops the app, undoes the PATH and completion\nwiring, and deletes `~/.jclaw`.\n\n**Requirements:** a Java 25+ runtime ([Zulu](https://www.azul.com/downloads/?version=java-25)\nor Temurin). Nothing else — the bundle bakes in the framework, app dependencies,\nprecompiled classes, and the prebuilt SPA.\n\n**Configuration** (optional environment variables):\n\n| Variable | Default | Purpose |\n| --- | --- | --- |\n| `JCLAW_HOME` | `~/.jclaw` | Install directory |\n| `JCLAW_VERSION` | `latest` | Pin a release tag, e.g. `v0.14.7` |\n| `JCLAW_PORT` | `9000` | Port reported on launch |\n| `JCLAW_NO_START` | — | Set to `1` to install without starting |\n| `JCLAW_BUNDLE_URL` | — | Install from a specific bundle URL (including `file://`) instead of GitHub Releases |\n\n```bash\n# Pin a version and install without auto-starting:\ncurl -fsSL https://raw.githubusercontent.com/tsukhani/jclaw/main/install.sh \\\n  | JCLAW_VERSION=v0.14.7 JCLAW_NO_START=1 sh\n```\n\n---\n\n## Overview\n\nJClaw is Abundent's AI-powered automation platform — built from scratch in **pure Java** on a customized [Play Framework 1.x](https://github.com/tsukhani/play1) foundation. It draws ideas and feature designs from three predecessor projects:\n\n- **[OpenClaw](https://github.com/tsukhani/openclaw)** (Node.js/TypeScript) — agent orchestration, memory system, conversational AI patterns\n- **[JavaClaw](https://github.com/jobrunr/javaclaw)** (Spring Boot) — job scheduling, background task processing, browser automation\n- **[Hermes](https://github.com/NousResearch/hermes-agent)** (Python) — cron/task scheduling parity, subagent delegation patterns\n\nThe implementation is entirely original — no code is shared with either project. JClaw is built on lean library primitives (OkHttp 5, db-scheduler, ProcessBuilder, virtual threads, JPA) with no Spring, no heavy framework bloat, no Python, and no Node.js runtime on the server. The result is a leaner, faster, more maintainable platform for building AI agents and automation workflows.\n\n---\n\n## Screenshot\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"jclaw-screenshot.png\" width=\"900\" alt=\"JClaw Chat Interface\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eWeb chat with memory-aware agents, tool execution, and markdown rendering.\u003c/em\u003e\u003c/p\u003e\n\n---\n\n## Features\n\n- 🤖 **Agent System** — Conversational AI agents with memory and context\n- ⚡ **Job Scheduling** — Persistent cron \u0026 scheduled tasks via db-scheduler, with automatic retries and crash recovery\n- 🔧 **Pure Java** — No Python/JavaScript runtimes required\n- 📦 **Built-in Frontend** — Nuxt 4 SPA (Vue 3 + TypeScript)\n- 🔌 **Plugin Architecture** — Modular, extensible design\n- 🧠 **Memory \u0026 Context** — Persistent conversations across sessions\n- 🚀 **Lightweight** — Minimal resource footprint, fast startup\n\n---\n\n## Directory Structure\n\n```\njclaw/\n├── app/                          # Application code\n│   ├── controllers/              # HTTP controllers (Play 1.x pattern)\n│   ├── models/                   # JPA domain entities\n│   ├── services/                 # Business logic (incl. db-scheduler bridge)\n│   ├── agents/                   # AI agent implementations\n│   ├── channels/                 # Messaging channels (web, Telegram, Slack)\n│   ├── llm/                      # LLM provider drivers (OkHttp 5)\n│   ├── tools/                    # Agent tool implementations\n│   ├── memory/                   # Agent memory stores (JPA-backed)\n│   ├── mcp/                      # Model Context Protocol client\n│   ├── slash/                    # Slash-command handlers\n│   ├── jobs/                     # Play @Every jobs + db-scheduler handlers\n│   ├── views/                    # Groovy server templates\n│   └── utils/                    # Utility classes\n├── conf/                         # Play configuration\n│   ├── application.conf          # Main app config\n│   ├── routes                    # URL routing\n│   ├── play.plugins              # Play plugin registration\n│   └── log4j2.xml                # Logging configuration\n├── frontend/                     # Nuxt 4 SPA (SPA-only; ssr: false)\n│   ├── app.vue                   # Root component\n│   ├── layouts/                  # Page layouts\n│   ├── pages/                    # Nuxt file-based routes\n│   ├── components/               # Reusable Vue components\n│   ├── composables/              # Shared reactive state (useAuth, useEventBus, ...)\n│   ├── middleware/               # Global route middleware (auth guard)\n│   ├── public/                   # Static assets\n│   └── nuxt.config.ts            # Nuxt configuration\n├── lib/                          # Custom JARs (if needed)\n├── modules/                      # Play modules (auto-managed)\n├── public/                       # Static web assets\n├── test/                         # Unit and integration tests\n├── tmp/                          # Play temp/runtime files\n├── logs/                         # Application logs\n└── README.md                     # This file\n```\n\n---\n\n## Getting Started\n\n### Runtime Prerequisites\n\n- **JDK 25+** (Zulu recommended)\n\nThat's the whole list. The [Abundent Play 1.x fork](https://github.com/tsukhani/play1),\napp dependencies, precompiled classes, and the prebuilt SPA all ship **inside**\n`jclaw-bundle.zip`, so a Java 25 runtime is the only thing the host needs to run\nJClaw — see [Quick Install](#quick-install-one-line). (Building from source instead\nadds a dev toolchain — Node.js, pnpm, and the `play` CLI — which the\n[Dev Container](#dev-container-recommended) installs for you.)\n\n#### Optional system dependencies\n\n**Tesseract OCR** — required for text extraction from images, scanned PDFs,\nand image-only PDFs via the `documents` tool. Apache Tika invokes the\n`tesseract` binary as a subprocess; without it, image inputs return empty\ntext. A startup probe logs a WARN line at boot if tesseract is missing so\nthe missing capability is visible without trial and error.\n\n```bash\n# Debian / Ubuntu\nsudo apt-get install tesseract-ocr\n\n# macOS\nbrew install tesseract\n\n# Windows\nchoco install tesseract\n# or: winget install --id UB-Mannheim.TesseractOCR\n```\n\nAdditional language packs install separately. The default is English\n(`eng`); install `tesseract-ocr-fra`, `tesseract-ocr-jpn`, etc. for other\nlanguages, then update `ocr.tesseract.languages` in `conf/application.conf`\n(e.g. `eng+fra+jpn`).\n\n**Local Ollama** — required only if you want to bind agents to the\n`ollama-local` LLM provider for self-hosted inference. JClaw seeds\n`provider.ollama-local.baseUrl=http://localhost:11434/v1` at first boot,\nso the provider is already listed in Settings without further wiring —\ninstall Ollama on the host and pull a model to make it usable. A startup\nprobe logs INFO with the model count when the local server is reachable,\nand WARN with an install hint when the server is reachable but broken;\na fresh install with no Ollama running stays silent (no spurious WARN\non every JVM start).\n\n```bash\n# Linux\ncurl https://ollama.com/install.sh | sh\n\n# macOS\nbrew install ollama\n\n# Windows — download the installer from https://ollama.com/download\n```\n\nAfter installing, pull a model:\n\n```bash\nollama pull qwen2.5\n```\n\nThen open the Settings page, expand the `ollama-local` card, and either\nrun Discover Models against `http://localhost:11434/v1` or paste the\nJSON for the model you pulled into the `models` field. Bind an agent\nto `ollama-local` from the Agent Edit page to start chatting against\nyour local model.\n\n**LM Studio** — required only if you want to bind agents to the\n`lm-studio` LLM provider. JClaw seeds\n`provider.lm-studio.baseUrl=http://localhost:1234/v1` at first boot\nso the provider is already listed under \"Local\" in Settings. Same\nboot-time probe as ollama-local: INFO when reachable, WARN with a\nlaunch hint when reachable-but-broken, silent (DEBUG) when LM Studio\nisn't running.\n\nLM Studio is a desktop application — install it from\n[https://lmstudio.ai](https://lmstudio.ai) (macOS DMG, Windows\ninstaller, or Linux AppImage). After launching, load a model in the\n**My Models** tab, then switch to the **Server** tab and click\n**Start Server**. The default port is 1234.\n\nIn JClaw Settings, expand the `lm-studio` card and either run\nDiscover Models against `http://localhost:1234/v1` or paste the JSON\nfor the model you loaded into the `models` field. Bind an agent to\n`lm-studio` from the Agent Edit page to use it.\n\n### Clone\n\n```bash\ngit clone https://bitbucket.abundent.com/scm/jclaw/jclaw.git\ncd jclaw\n```\n\nDependencies are automatically installed when you start with `jclaw.sh`.\n\n### Dev Container (Recommended)\n\nThe fastest way to start coding without installing any of the [Prerequisites](#prerequisites) on your host machine is to use the included dev container. The `.devcontainer/Dockerfile` ships a pinned toolchain (Java 25, Python 3.14, Node 24, corepack, the Play fork at the version recorded in `.play-version`, tesseract-ocr) on top of Ubuntu 26.04 LTS — all the prerequisites listed above, already installed.\n\n#### Host prerequisites\n\nJust two things on your machine:\n\n1. **Docker Desktop** (macOS/Windows) or **Docker Engine** (Linux) — the dev container runs in a Docker container, so the Docker daemon needs to be running.\n2. **An IDE that supports the [Dev Containers spec](https://containers.dev/)** — any of:\n   - [Cursor](https://cursor.com/) (built-in support)\n   - [VS Code](https://code.visualstudio.com/) with the **Dev Containers** extension\n   - [JetBrains Gateway](https://www.jetbrains.com/remote-development/gateway/) with the Dev Containers plugin\n   - [GitHub Codespaces](https://github.com/features/codespaces) (cloud, no local Docker needed)\n\n#### First-time launch\n\nAfter cloning, open the project in your IDE and trigger the \"Reopen in Container\" command:\n\n| IDE | How to launch |\n|---|---|\n| **Cursor** | \u003ckbd\u003eCmd\u003c/kbd\u003e/\u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eP\u003c/kbd\u003e → `Dev Containers: Reopen in Container` |\n| **VS Code** | Click the blue corner icon (bottom-left) → `Reopen in Container`, or \u003ckbd\u003eCmd\u003c/kbd\u003e/\u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eP\u003c/kbd\u003e → same command |\n| **GitHub Codespaces** | Push your branch to GitHub → click `Code` → `Codespaces` tab → `Create codespace on main` |\n| **JetBrains Gateway** | New Connection → Dev Containers → point at the local `jclaw` folder |\n\nWhat happens automatically once you click:\n\n1. Docker builds the image from `.devcontainer/Dockerfile` (~5–10 min the first time, cached on subsequent rebuilds).\n2. Your local jclaw directory is bind-mounted into the container at `/workspaces/jclaw`. **Edits you make inside the container persist on your host** — the container is an environment, not a copy.\n3. The IDE runs `postCreateCommand: ./jclaw.sh setup` automatically, which:\n   - Validates all prerequisites (every check passes — they're baked into the image)\n   - Wires git hooks (`.githooks/pre-commit`, `.githooks/pre-push`)\n   - Validates the pinned pnpm version via corepack with integrity-hash verification\n   - Runs `pnpm install` for the frontend\n   - Adds the canonical `github` remote (`https://github.com/tsukhani/jclaw.git`)\n4. Recommended VS Code/Cursor extensions install (Volar, Java Pack, ESLint, Stylelint, YAML).\n5. The IDE attaches to the container — your terminal, file explorer, and editor are now running inside it.\n\n#### Day-to-day inside the container\n\nEverything works the same as it would on a native host. The container *is* a Linux dev box with the pre-installed toolchain:\n\n```bash\n./jclaw.sh --dev start    # dev mode (Play autoreload + Nuxt HMR)\n./jclaw.sh test           # backend + frontend test suites\n./jclaw.sh status         # check what's running\n./jclaw.sh stop\n```\n\nPorts `9000` (backend) and `3000` (Nuxt) are forwarded to your host automatically. Open `http://localhost:9000` and `http://localhost:3000` in your **host's browser** while the dev server runs inside the container. The Nuxt port is configured to auto-open the browser when it boots; the backend port emits a notification.\n\n#### Commits and `/deploy`\n\nThe pre-commit hook (frontend lint-staged) and pre-push hook (full test suite) work inside the container without any extra setup. Two nuances:\n\n- **Signed commits** — `/deploy` produces signed commits and signed tags (`commit -S`, `tag -s`). Your host's GPG/SSH keys aren't visible inside the container by default. Two recovery options:\n  1. **Easiest**: do `/deploy` from your host shell (open a host terminal, `cd` into the project, run the slash command). Code inside the container, deploy from outside.\n  2. **More setup**: add a `mounts` block to `.devcontainer/devcontainer.json` to bind-mount `~/.ssh` and `~/.gnupg` into the container. Same end result, more configuration.\n- **File ownership** — files written inside the container land on your host with UID 1000 (`ubuntu` user). On macOS this maps to your user automatically; on Linux you may see \"owned by 1000\" in `ls -l` if your host UID differs. Usually harmless.\n\n#### Rebuilding\n\nWhen the toolchain changes (e.g., a new Play version, a JDK bump, a base-image bump), you'll want a fresh build:\n\n| IDE | How to rebuild |\n|---|---|\n| **Cursor / VS Code** | \u003ckbd\u003eCmd\u003c/kbd\u003e/\u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eP\u003c/kbd\u003e → `Dev Containers: Rebuild Container` |\n| **JetBrains Gateway** | Container settings → `Rebuild` |\n| **CLI fallback** | `docker build -t jclaw-devcontainer:latest .devcontainer/` (manual, you'd then need to update the IDE config to use the rebuilt image) |\n\nMost rebuilds reuse cached apt + JDK + Node layers and only re-download what changed (e.g., the Play release zip if `PLAY_VERSION` was bumped). Full cold rebuilds run ~5–10 min.\n\n#### Troubleshooting\n\n- **\"Docker not running\"** — start Docker Desktop / `sudo systemctl start docker`.\n- **First build hangs on apt-get** — your network is slow or the Ubuntu mirror is rate-limiting. Retry; layers are cached so progress isn't lost.\n- **Postcreate fails on `./jclaw.sh setup`** — read the error; it'll point at the failing prereq. Open `.devcontainer/Dockerfile` to see what's installed; if a tool is missing, file an issue or patch the Dockerfile and rebuild.\n- **Edits in the IDE don't appear on host** — verify you opened the folder via \"Reopen in Container,\" not by mounting a Docker volume. The bind-mount is what makes the edits round-trip.\n- **`docker rmi` to clean up** — `docker rmi jclaw-devcontainer:latest` (or the container image name your IDE assigns) removes the cached image. The next \"Reopen in Container\" rebuilds from scratch.\n\n### Development\n\n```bash\n# Start both backend and frontend in dev mode\n./jclaw.sh --dev start\n\n# Stop\n./jclaw.sh --dev stop\n\n# Check status\n./jclaw.sh --dev status\n\n# View logs (tails both backend and frontend logs)\n./jclaw.sh --dev logs\n```\nDefault ports: backend on **:9000**, frontend on **:3000**.\n\n### Production Deployment\n\n```bash\n# Deploy to /tmp (creates /tmp/jclaw), build everything, and start\n./jclaw.sh --deploy /tmp start\n\n# Stop\n./jclaw.sh --deploy /tmp stop\n\n# View logs\n./jclaw.sh --deploy /tmp logs\n```\n\nThis packages the app with `play dist`, unzips to `\u003cdir\u003e/jclaw/`, installs dependencies, builds the frontend, and starts both services in production mode.\n\nTo start an existing deployment (without re-packaging):\n\n```bash\n# Start\n./jclaw.sh start\n\n# Stop\n./jclaw.sh stop\n\n# View logs\n./jclaw.sh logs\n```\n\n### Docker (Production)\n\nThe simplest way to run JClaw in production is with Docker Compose. The shipped `docker-compose.yml` pulls the prebuilt image from GHCR, publishes the app on **:9000**, and persists `data/`, `logs/`, `workspace/`, and `skills/` to the host so config and conversations survive restarts.\n\n```bash\n# Start in the background\ndocker compose up -d\n\n# Follow logs\ndocker compose logs -f\n\n# Stop and remove the container\ndocker compose down\n\n# Run on a custom port (default: 9000)\nJCLAW_PORT=8080 docker compose up -d\n```\n\nThat's it — no `.env` setup needed. On first boot the container's entrypoint generates a 64-character `PLAY_SECRET` (used to sign session cookies) and persists it to `./data/.play-secret`. Subsequent restarts read the same file, so existing user sessions survive across `docker compose down` / `up` cycles. To rotate the secret, delete `./data/.play-secret` and restart the container — all existing `PLAY_SESSION` cookies become invalid, which is the point.\n\nIf you'd rather pin the secret yourself (e.g. for multi-host deployments that need a shared cookie key, or rotation managed by your secret-store), drop a `.env` file alongside `docker-compose.yml` with `PLAY_SECRET=\u003cvalue\u003e` — Compose will forward it into the container and the entrypoint will defer to it instead of generating one.\n\nYou can also set `JCLAW_PORT` in `.env` alongside `docker-compose.yml` instead of passing it inline — Compose reads the same file for variable interpolation in the YAML and for the runtime environment of the `jclaw` service.\n\nThe container runs in production mode — the Nuxt SPA is already built into the image, so no local Node.js, pnpm, or Play toolchain is required on the host. Open `http://localhost:9000` (or your custom port) once the container is healthy.\n\n#### Browser-trusted HTTPS\n\nThe container also exposes HTTPS on **:9443** (with HTTP/3 over the same UDP port) using a self-signed TLS cert generated at `certs/host.cert` on first boot. HTTPS works as-is but browsers show a cert-warning interstitial, and Chrome refuses HTTP/3 entirely — QUIC requires the cert to be in the system trust store. To get browser-trusted HTTPS plus working HTTP/3, sign the cert with [mkcert](https://github.com/FiloSottile/mkcert)'s local CA from your host. Install mkcert via your platform's package manager:\n\n```bash\n# macOS\nbrew install mkcert\n\n# Debian / Ubuntu (22.04+)\nsudo apt install mkcert libnss3-tools\n\n# Fedora / RHEL\nsudo dnf install mkcert nss-tools\n\n# Arch\nsudo pacman -S mkcert nss\n\n# Windows\nchoco install mkcert\n# or: scoop bucket add extras \u0026\u0026 scoop install mkcert\n```\n\nFor older distros that don't package mkcert, grab the prebuilt binary from [the mkcert releases page](https://github.com/FiloSottile/mkcert/releases) and install `libnss3-tools` (Debian/Ubuntu) or `nss-tools` (Fedora) separately so mkcert can register with Firefox.\n\nThen trust the local CA, regenerate the cert, and restart the container:\n\n```bash\nsudo mkcert -install             # adds mkcert's CA to the system trust store (and Firefox NSS if installed)\n./jclaw.sh https                 # regenerates certs/host.cert + host.key, signed by the CA\ndocker compose restart jclaw     # JVM reloads the new cert at boot\n```\n\nSubsequent `docker compose up -d` calls reuse the existing cert — you only need to re-run `./jclaw.sh https` after rotating mkcert's CA or deleting the `certs/` directory. Run `./jclaw.sh no-https` to delete the cert+key (the next start boots HTTP/1.1 only). `conf/application.conf` is never modified by either command.\n\n### Custom Ports\n\nUse `--backend-port` and `--frontend-port` with any `jclaw.sh` mode. The frontend reads the backend port via the `JCLAW_BACKEND_PORT` environment variable at startup — no files are modified.\n\n```bash\n# Dev mode with custom ports\n./jclaw.sh --dev --backend-port 8080 --frontend-port 4000 start\n\n# Production deploy with custom ports (creates /tmp/jclaw)\n./jclaw.sh --deploy /tmp --backend-port 8080 --frontend-port 4000 start\n\n# Bare start with custom backend port\n./jclaw.sh --backend-port 8080 start\n```\n\n### Testing\n\nRun the backend and frontend test suites together and print a consolidated pass/fail summary:\n\n```bash\n./jclaw.sh test\n```\n\nThis runs `play autotest` (backend JUnit + functional tests) followed by `pnpm test` (frontend Vitest), streams each side's output live, and finishes with a two-line verdict like:\n\n```\n backend  : PASSED  (47 classes, 26s)\n frontend : PASSED  Tests  199 passed (199) (5s)\n```\n\nFull logs land in `logs/test-backend.log` and `logs/test-frontend.log` for post-mortem on failure. The command exits non-zero if either suite failed, so it's safe to wire into git hooks or CI.\n\n#### Pre-push hook (optional)\n\nAn in-repo `.githooks/pre-push` hook runs `./jclaw.sh test` before a push reaches the remote and caches the tested SHA in `$GIT_DIR/jclaw-last-tested-sha`, so the second push in a two-remote deploy flow (origin + github) reuses the result instead of re-running the suite. Enable once per clone:\n\n```bash\ngit config core.hooksPath .githooks\n```\n\nTo bypass for a one-off push (e.g. urgent hotfix, docs-only change): `JCLAW_SKIP_TESTS=1 git push origin HEAD`.\n\n---\n\n## Architecture\n\n### Backend (Play 1.x + Java)\n\n- **Models**: JPA entities with Play's model pattern\n- **Controllers**: RESTful API endpoints\n- **Services**: Business logic with dependency injection\n- **Agents**: Conversational AI with memory/context persistence\n- **Jobs**: Internal maintenance (cleanup, probes, boot checks) on Play's built-in `@Every` / `@OnApplicationStart` job system\n- **Scheduling**: User-facing Tasks — cron, scheduled, and immediate — run on [db-scheduler](https://github.com/kagkarlsson/db-scheduler), persisted in a `scheduled_tasks` table with atomic row-claim, pluggable retries, and heartbeat-based dead-execution recovery\n\n### Frontend (Nuxt 4)\n\n- **Framework**: Vue 3 + TypeScript + Nuxt 4 (SPA mode, `ssr: false`)\n- **UI components**: [shadcn-nuxt](https://www.shadcn-vue.com/) on [Reka UI](https://reka-ui.com/) primitives, with `class-variance-authority` + `tailwind-merge` for variants\n- **Styling**: Tailwind CSS v4 (via `@tailwindcss/vite`), Lucide + Heroicons icons, Inter variable font\n- **State**: Composables backed by `useState` (no Pinia); `@vueuse/core` utilities\n- **Data \u0026 rendering**: `@tanstack/vue-table` for tables, `marked` + `dompurify` for safe Markdown, `zod` for validation\n- **API**: Cookie-session authenticated `$fetch` to the Play backend, proxied via Nitro in dev\n- **Tooling**: Vitest + `@nuxt/test-utils` + happy-dom, Playwright e2e, ESLint + Stylelint, `vue-tsc` typecheck, a11y via `vue-axe`/`axe-core`\n\n---\n\n## Key Principles\n\n1. **Java-First** — Everything in Java. No Python, no Node for server-side logic.\n2. **Minimal Dependencies** — Only bring in what we absolutely need.\n3. **Memory \u0026 Context** — Agents remember. Context persists. Conversations flow.\n4. **Async by Default** — Jobs run in background. APIs are non-blocking.\n5. **Modular Skills** — Agents can automatically create, share, and chain skills. Skill primitives are reusable across agents and shareable with other JClaw users.\n\n---\n\n## Documentation\n\n- [Play Framework 1.x](https://github.com/tsukhani/play1)\n- [OpenClaw Reference](https://docs.openclaw.ai)\n- [Nuxt 4 Docs](https://nuxt.com/docs)\n- [JavaClaw Concepts](https://github.com/jobrunr/javaclaw)\n\n---\n\n## Contributing\n\nThis is an internal Abundent project. For questions or contributions, [reach out to the team](mailto:support@abundent.com).\n\n---\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n---\n\n*Built with ☕ Java and ❤️ by the Abundent crew.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsukhani%2Fjclaw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsukhani%2Fjclaw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsukhani%2Fjclaw/lists"}