Metadata-Version: 2.4
Name: jarn-cli
Version: 3.2.0
Summary: J.A.R.N. — Just a Reliable Nerd: Production-grade multi-agent orchestration framework
Author: J.A.R.N. Team
License: J.A.R.N. — Proprietary License
        Copyright (c) 2026 J.A.R.N. Team. All rights reserved.
        
        This software and associated documentation files (the "Software") are
        proprietary and confidential. The Software is licensed, not sold.
        
        Subject to the terms herein, you are granted a non-exclusive, non-transferable
        license to install and run the Software for internal evaluation and use.
        
        You MAY NOT, without prior written permission of the copyright holder:
          1. redistribute, sublicense, sell, or publish the Software or derivative works;
          2. remove or alter any proprietary notices;
          3. reverse engineer except to the extent permitted by applicable law.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
        OR OTHER DEALINGS IN THE SOFTWARE.
        
        For licensing inquiries, contact the J.A.R.N. Team.
        
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: langchain<2,>=1.3
Requires-Dist: langchain-core<2,>=1.4
Requires-Dist: langchain-openai<2,>=1.2
Requires-Dist: langgraph<2,>=1.2
Requires-Dist: langgraph-checkpoint<5,>=4.1
Requires-Dist: langgraph-prebuilt<2,>=1.1
Requires-Dist: langgraph-sdk<1,>=0.3
Requires-Dist: pydantic<3,>=2.13
Requires-Dist: python-dotenv<2,>=1.2
Requires-Dist: fastapi<1,>=0.136
Requires-Dist: starlette<2,>=1.2
Requires-Dist: uvicorn<1,>=0.48
Requires-Dist: websockets<17,>=16
Requires-Dist: pyjwt<3,>=2.13
Requires-Dist: python-jose[cryptography]<4,>=3.5
Requires-Dist: cryptography<49,>=48
Requires-Dist: structlog<26,>=25.5
Requires-Dist: prometheus-client<1,>=0.25
Requires-Dist: httpx<1,>=0.28
Requires-Dist: pyyaml<7,>=6
Provides-Extra: anthropic
Requires-Dist: langchain-anthropic<2,>=1; extra == "anthropic"
Provides-Extra: google
Requires-Dist: langchain-google-genai<4,>=3; extra == "google"
Provides-Extra: groq
Requires-Dist: langchain-groq<2,>=1; extra == "groq"
Provides-Extra: ollama
Requires-Dist: langchain-ollama<2,>=1; extra == "ollama"
Provides-Extra: community
Requires-Dist: langchain-community<1,>=0.4; extra == "community"
Provides-Extra: providers
Requires-Dist: jarn[anthropic,community,google,groq,ollama]; extra == "providers"
Provides-Extra: postgres
Requires-Dist: langgraph-checkpoint-postgres<4,>=3; extra == "postgres"
Requires-Dist: sqlalchemy[asyncio]<3,>=2; extra == "postgres"
Requires-Dist: alembic<2,>=1.13; extra == "postgres"
Requires-Dist: psycopg[binary,pool]<4,>=3.2; extra == "postgres"
Requires-Dist: psycopg2-binary<3,>=2.9; extra == "postgres"
Provides-Extra: redis
Requires-Dist: redis<6,>=5; extra == "redis"
Provides-Extra: secrets
Requires-Dist: boto3<2,>=1.30; extra == "secrets"
Requires-Dist: google-cloud-secret-manager<3,>=2.16; extra == "secrets"
Requires-Dist: hvac<3,>=2; extra == "secrets"
Requires-Dist: keyring>=24; extra == "secrets"
Provides-Extra: observability
Requires-Dist: opentelemetry-api>=1.20; extra == "observability"
Requires-Dist: opentelemetry-sdk>=1.20; extra == "observability"
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == "observability"
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.45b0; extra == "observability"
Requires-Dist: opentelemetry-instrumentation-httpx>=0.45b0; extra == "observability"
Requires-Dist: opentelemetry-instrumentation-logging>=0.45b0; extra == "observability"
Requires-Dist: sentry-sdk>=2; extra == "observability"
Provides-Extra: documents
Requires-Dist: python-docx>=1; extra == "documents"
Requires-Dist: openpyxl>=3.1; extra == "documents"
Requires-Dist: python-pptx>=1; extra == "documents"
Requires-Dist: pymupdf>=1.23; extra == "documents"
Requires-Dist: weasyprint>=60; extra == "documents"
Requires-Dist: reportlab>=4; extra == "documents"
Provides-Extra: search
Requires-Dist: langchain-tavily<1,>=0.1; extra == "search"
Provides-Extra: bridges
Requires-Dist: aiohttp<4,>=3.14; extra == "bridges"
Provides-Extra: server
Requires-Dist: uvicorn[standard]<1,>=0.48; extra == "server"
Requires-Dist: sse-starlette<4,>=3.4; extra == "server"
Provides-Extra: dev
Requires-Dist: pytest<10,>=8.2; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: pytest-cov>=5; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: pip-tools>=7.4; extra == "dev"
Provides-Extra: all
Requires-Dist: jarn[bridges,dev,documents,observability,postgres,providers,redis,search,secrets,server]; extra == "all"
Dynamic: license-file

# J.A.R.N. — Just a Reliable Nerd

**Multi-Agent Orchestration Harness · v3.2.0**

> Runs on **LangGraph 1.x + LangChain 1.x**, Python `>=3.12`. Boots on both a local
> venv and Docker (`python:3.12-slim`): `docker build` passes, `/health` → 200,
> **639 tests pass**. `docker compose up` brings up the full stack (JARN + Postgres
> checkpointer + Redis cache) in one command; the agent loop, HITL, parallel `Send`
> fan-out, and the GUI↔server WebSocket bridge are verified live.
>
> 📐 Architecture → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) ·
> 🩺 Status & deferred work → [docs/audit-remediation-status.md](docs/audit-remediation-status.md)

J.A.R.N. is a hub-and-spoke multi-agent framework inspired by Claude Code internals
and [thClaws](https://github.com/thClaws/thClaws). A central **Supervisor** routes
work to specialist agents (Coder, Researcher, Analyst, Explorer), which return to the
hub after each step — so the supervisor keeps full context for every decision.

```
__inject__ ─┬─(workflow_spec set)─► workflow_runner ─────────────┐
            │                                                     │
            └─► summarizer → supervisor ──► planner ──► parallel_executor
                              ▲   │                        │ Send(per-step)
                              │   ├──► explorer            ▼
              hitl_gate ◄─────┤   ├──► coder / researcher / analyst
              (approve        │   │            │
               destructive)   │   └────────────┴──► observer → reflector ─► router
                              │                              (continue / replan)│
                              └──────────────────────────────────────┘         │
                                       (finish) ─► __session_end__ ─► END ◄──────┘
```

`__inject__` loads the lifecycle **hook manager** (SESSION_START fires here; tool
hooks fire around specialists; SESSION_END fires at `__session_end__`). When
`state['workflow_spec']` is set, the run short-circuits the agent loop and executes
the dynamic **workflow engine** (real side-channel sub-agent dispatch) instead.

## Install

Pick whichever fits your setup — all of these install the `jarn` command:

```bash
npx jarn-cli            # zero Python setup — fetches jarn-cli into a managed venv and opens the GUI
pipx install jarn-cli   # isolated global install (recommended for a persistent CLI)
uvx jarn-cli            # run via uv without a permanent install
pip install jarn-cli    # plain pip into the current environment
```

> The package is published as **`jarn-cli`** on both PyPI and npm; the installed command is **`jarn`** (with a `jarn-cli` alias).

`npx jarn-cli` is the fastest path: no manual Python steps, it provisions an isolated
venv and launches the GUI in your browser.

> **LLM key:** chat needs an LLM provider key. Copy `cp .env.example .env` and set
> `OPENAI_API_KEY` (or another supported provider). Without a key the GUI still boots
> but chat will warn and stay idle.

## Launch

```bash
jarn                            # open the GUI + auto-open the browser (default)
jarn --serve --no-browser       # headless server (e.g. on a remote box) → http://127.0.0.1:8000
jarn "สร้าง Fibonacci function พร้อม tests"   # one-shot CLI task through the agent graph
jarn "/schedule list"           # built-in slash commands
jarn "/research <topic>"        # needs an LLM key (+ TAVILY_API_KEY for live search)
jarn --doctor                   # environment / health diagnostics
```

The GUI **Terminal** tab runs real shell commands and is therefore **off by default**.
Enable it only on a trusted local desktop by setting `JARN_GUI_EXEC=1` before launch;
otherwise the exec endpoint returns `403`.

## Update

```bash
jarn update                     # auto-detects how jarn was installed and upgrades in place
# equivalents, if you prefer to do it yourself:
pipx upgrade jarn               # pipx installs
pip install -U jarn             # pip installs
npm update -g jarn-cli          # npm wrapper
```

`jarn` prints a one-line notice when a newer release is available.

## Develop from source

```bash
git clone <repo> && cd harness
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env            # set OPENAI_API_KEY

jarn "สร้าง Fibonacci function พร้อม tests"   # CLI
jarn --serve                                   # GUI + server

# Tests
pytest jarn/tests -q            # 639 passed, 1 skipped

# Docker (lean-core single image)
docker build -t jarn .
# Full stack — one command (JARN + Postgres checkpointer + Redis cache + Prometheus + Grafana).
# The image bakes in the postgres/redis extras, so the checkpointer + cache are live
# (not the in-memory fallback). Needs an LLM key in .env.
docker compose up -d
```

> **Legacy / compat:** the old entry points `python run_jarn.py "<task>"` and
> `python run_server.py` still work as thin shims, but the `jarn` command is the
> supported way to launch the CLI and GUI.

## Install profiles

The default install is a **lean core** (no heavy native deps). Optional features are
extras, imported lazily so the core boots without them:

```bash
pip install -e '.[providers]'      # anthropic, google, groq, ollama, community
pip install -e '.[postgres]'       # Postgres checkpointer + sqlalchemy/alembic/psycopg
pip install -e '.[redis]'          # Redis cache
pip install -e '.[documents]'      # pdf/docx/pptx/xlsx tools
pip install -e '.[search]'         # Tavily web search
pip install -e '.[bridges]'        # chat bridges (aiohttp)
pip install -e '.[observability]'  # OpenTelemetry + Sentry
pip install -e '.[all]'            # everything
```

## Capabilities

| Area | What it does |
|------|--------------|
| **Agent graph** | Supervisor + planner + parallel executor + specialists (coder/researcher/analyst) + explorer + observer + reflector + HITL gate |
| **Tools** | read/write/edit files, glob/grep, sandboxed shell + Python, web search (Tavily), document tools, MCP-adapted tools |
| **LLM providers** | 13 — OpenAI (core) + Anthropic, Google, Groq, DeepSeek, Ollama, OpenThaiGPT, Typhoon, OpenRouter, DashScope, NVIDIA NIM, Azure, generic OpenAI-compatible (lazy) |
| **3-tier models** | cheap (routing) · standard (implementation) · expensive (reserved) |
| **Self-correction** | retry → adjust → replan; transient-error auto-retry in the observer |
| **Memory & KMS** | thread-safe file-backed memory store; markdown knowledge base |
| **Skills & plugins** | SKILL.md discovery (bundled/user/project/plugin), dynamic activation; plugin system |
| **MCP** | client + stdio/HTTP JSON-RPC transports, tool adapter, health |
| **Teams** | multi-process teammates via filesystem mailboxes + task queue |
| **Scheduling** | cron jobs + persistence + daemon + `/loop` |
| **Bridges** | Telegram (two-way); Slack/Discord/WhatsApp/LINE/Messenger — send + receive servers, all launchable via `--<platform>` CLI flags (live needs platform creds) |
| **Background** | `/dream` consolidation, `/research` deep research, side-channel sub-agents, dynamic workflows (auto-run from `workflow_spec`); deep sub-agent dispatch via side-channel worker / queue drainer |
| **Lifecycle hooks** | SESSION_START/END + PRE/POST_TOOL_USE auto-fire from the graph (subprocess hooks via `.jarn/hooks.json`; no-op when unconfigured) |
| **Eventing** | webhook producers (`plan_created`/`step_completed`/`step_failed`/`plan_finished`/`error`) + background task queue producer (`POST /chat/{id}/async`) |
| **Server** | FastAPI: SSE + WebSocket streaming, deep `/health`, JWT + API-key auth, React/Vite GUI |
| **GUI IPC** | WebSocket bridge (`/ws/gui/{id}`) streaming token/tool/agent(enter+exit)/`plan_update`/`approval_required`/`done`; `approve` resumes the interrupted graph (`Command(resume)`); JWT/API-key enforced when auth is configured |
| **Security** | input sanitization, path/command-injection guards, capability-scoped tools, OIDC SSO (mounted `/api/v1/auth/oidc/*`), audit log |
| **Resilience & obs** | circuit breaker + provider fallback; structlog, Prometheus, OpenTelemetry, Sentry, LangSmith |

## API

FastAPI app exposes ~34 routes — `/health`, `/metrics`, `/ws/{thread_id}`,
`/ws/gui/{id}` (+ `/api/v1/gui/files`, static GUI), `/api/v1/auth/token`,
`/api/v1/auth/oidc/*` (login/callback/refresh/providers), `/api/v1/threads`,
`/api/v1/chat/{id}` (SSE), `/sync`, and `/async` (enqueue to the background task
queue → poll `/api/v1/tasks/{id}`), `/api/v1/state/{id}`, `/api/v1/costs/*`,
`/api/v1/audit/entries`, `/api/v1/webhooks`, … Full interactive docs at `/docs`
(Swagger) and `/redoc`.

WS auth: `?token=<jwt>` or `?x_api_key=<key>`; reconnection: `?resume=true`. The GUI
WS (`/ws/gui/{id}`) + `/api/v1/gui/files` enforce the same auth when configured.

## Documentation

- **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** — current architecture (graph, subsystems, entry points)
- **[docs/audit-remediation-status.md](docs/audit-remediation-status.md)** — remediation history + P1/P2 + GUI-gaps closeout
- **[docs/TODO.md](docs/TODO.md)** — remaining work (mostly external: chat-bridge live creds, Python-3.12 lock/Tavily, browser-level GUI test)
- **[docs/adr/](docs/adr/)** — 12 Architecture Decision Records (design rationale; 011 = P1 wiring & full-stack image, 012 = GUI IPC contract, auth, OIDC & bridge CLI)
- **[docs/security/bridge-review.md](docs/security/bridge-review.md)** — chat-bridge hardening summary

## License

Internal / Proprietary
