diff --git a/README.md b/README.md index 3cb73baf..e19387ff 100644 --- a/README.md +++ b/README.md @@ -140,16 +140,16 @@ The server also implements `resources/list` (7 `boj://` resources) and `prompts/ The bridge exposes **45 `boj_*` tools** and **23 `coord_*` tools**. A subset of cartridges have explicit `boj__` tools for high-frequency operations; everything catalogued is reachable through `boj_cartridge_invoke`. -| Group | Tools | Examples | -|----|----|----| -| **Core discovery / dispatch** | 5 | `boj_health`, `boj_menu`, `boj_cartridges`, `boj_cartridge_info`, `boj_cartridge_invoke` | -| **GitHub** | 14 | `boj_github_list_repos`, `boj_github_create_issue`, `boj_github_create_pr`, `boj_github_merge_pr`, `boj_github_search_code`, `boj_github_graphql` | -| **GitLab** | 8 | `boj_gitlab_list_projects`, `boj_gitlab_create_mr`, `boj_gitlab_list_pipelines`, `boj_gitlab_setup_mirror` | -| **Browser (Firefox)** | 7 | `boj_browser_navigate`, `boj_browser_click`, `boj_browser_type`, `boj_browser_read_page`, `boj_browser_screenshot`, `boj_browser_tabs`, `boj_browser_execute_js` | -| **Cloud** | 3 | `boj_cloud_cloudflare`, `boj_cloud_vercel`, `boj_cloud_verpex` | -| **Communications** | 2 | `boj_comms_gmail`, `boj_comms_calendar` | -| **Research / code intel / ML / search** | 4 | `boj_research`, `boj_codeseeker`, `boj_ml_huggingface`, `boj_search` | -| **Coordination (`local-coord-mcp`)** | 23 | `coord_register`, `coord_claim_task`, `coord_send`, `coord_review`, `coord_approve`, `coord_health` | +| Group | Tools | Examples | +|-----------------------------------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Core discovery / dispatch** | 5 | `boj_health`, `boj_menu`, `boj_cartridges`, `boj_cartridge_info`, `boj_cartridge_invoke` | +| **GitHub** | 14 | `boj_github_list_repos`, `boj_github_create_issue`, `boj_github_create_pr`, `boj_github_merge_pr`, `boj_github_search_code`, `boj_github_graphql` | +| **GitLab** | 8 | `boj_gitlab_list_projects`, `boj_gitlab_create_mr`, `boj_gitlab_list_pipelines`, `boj_gitlab_setup_mirror` | +| **Browser (Firefox)** | 7 | `boj_browser_navigate`, `boj_browser_click`, `boj_browser_type`, `boj_browser_read_page`, `boj_browser_screenshot`, `boj_browser_tabs`, `boj_browser_execute_js` | +| **Cloud** | 3 | `boj_cloud_cloudflare`, `boj_cloud_vercel`, `boj_cloud_verpex` | +| **Communications** | 2 | `boj_comms_gmail`, `boj_comms_calendar` | +| **Research / code intel / ML / search** | 4 | `boj_research`, `boj_codeseeker`, `boj_ml_huggingface`, `boj_search` | +| **Coordination (`local-coord-mcp`)** | 23 | `coord_register`, `coord_claim_task`, `coord_send`, `coord_review`, `coord_approve`, `coord_health` | > Set `BOJ_TOOL_SCOPE=core` to advertise only the discovery surface; explicit `boj__*` tools remain reachable via `boj_cartridge_invoke` regardless. A CSV of prefixes (e.g. `core,github,browser`) advertises core plus named groups. @@ -181,7 +181,7 @@ BoJ catalogues **125 cartridges** across trust tiers (Teranga / Shield / Ayo). B - **Without backend or credentials**, side-effectful tools return a structured `{error, hint}` telling you what’s missing — they never silently fail. -> **Number transparency:** **125** is the single source of truth — it is the number of `cartridge.json` manifests under `cartridges/` and what the live `boj_menu` reports. Every packaging file (`package.json`, `jsr.json`, `smithery.yaml`, `ai-plugin.json`, `openapi.yaml`, `CITATION.cff`) is reconciled to it. Of those 125, most are a catalogue entry rather than a live service — see the bullets above. +> **Number transparency:** **125** is the single source of truth — it is the number of `cartridge.json` manifests in the canonical [boj-server-cartridges](https://github.com/hyperpolymath/boj-server-cartridges) registry (the bundled `cartridges/` tree was retired from this repo; populate a local cache with `scripts/fetch-cartridges.sh` + `BOJ_CARTRIDGES_PATH`) and what the live `boj_menu` reports. Every packaging file (`package.json`, `jsr.json`, `smithery.yaml`, `ai-plugin.json`, `openapi.yaml`, `CITATION.cff`) is reconciled to it. Of those 125, most are a catalogue entry rather than a live service — see the bullets above. Catalogued domains include: git forges & code hosting, cloud platforms (Cloudflare, Vercel, AWS, GCP, DigitalOcean, Hetzner, Fly, Linode, Railway, Render), databases (PostgreSQL, MongoDB, Redis, Neo4j, ClickHouse, DuckDB, Turso, Supabase, Neon, …), containers & Kubernetes, CI/CD & observability (Buildkite, CircleCI, Hypatia, Grafana, Prometheus, Sentry), messaging (Slack, Discord, Telegram, Matrix), productivity (Notion, Linear, Jira, Obsidian, Zotero), ML/AI & coordination, browser & web automation, code intelligence & research, developer tooling (LSP/DAP/BSP, language & package registries), security & secrets, IaC & proof systems, and hyperpolymath-native admin cartridges. @@ -201,11 +201,11 @@ The coordination bus (`local-coord-mcp`) is a separate localhost service, defaul Selected with `BOJ_TRANSPORT` (ADR-0013): -| Value | Behaviour | -|----|----| -| `stdio` *(default)* | Reads JSON-RPC from stdin, writes to stdout — how Claude Code / Desktop launch the bridge as a subprocess. | -| `http` | Starts an HTTP+SSE listener on `BOJ_HTTP_PORT` (default `7780`) for remote / Workers / browser deployments. Binds `127.0.0.1` by default; `BOJ_HTTP_AUTH=none` is **refused** on a non-loopback bind. | -| `both` | Runs stdio and HTTP simultaneously. | +| Value | Behaviour | +|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `stdio` *(default)* | Reads JSON-RPC from stdin, writes to stdout — how Claude Code / Desktop launch the bridge as a subprocess. | +| `http` | Starts an HTTP+SSE listener on `BOJ_HTTP_PORT` (default `7780`) for remote / Workers / browser deployments. Binds `127.0.0.1` by default; `BOJ_HTTP_AUTH=none` is **refused** on a non-loopback bind. | +| `both` | Runs stdio and HTTP simultaneously. | HTTP auth: `none` (loopback only), or `bearer` against `BOJ_HTTP_AUTH_TOKENS`. `mtls`/`oidc` are planned, not yet implemented. @@ -213,20 +213,20 @@ HTTP auth: `none` (loopback only), or `bearer` against `BOJ_HTTP_AUTH_TOKENS`. ` Key environment variables (full schema in [`glama.json`](glama.json)): -| Variable | Default | Purpose | -|----|----|----| -| `BOJ_URL` | `http://localhost:7700` | Base URL for the BoJ REST backend. | -| `GITHUB_TOKEN` | — | PAT for `boj_github_*` tools. | -| `GITLAB_TOKEN` / `GITLAB_URL` | — / `https://gitlab.com` | Token + base URL for `boj_gitlab_*` tools. | -| `BOJ_TOOL_SCOPE` | `full` | `full`, `core`, or a CSV of domain prefixes (e.g. `core,github,browser`). | -| `BOJ_RATE_LIMIT` | `60` | Max tool calls per minute. | -| `BOJ_LOG_LEVEL` | `info` | `debug` / `info` / `warn` / `error` / `silent`. | -| `BOJ_TRANSPORT` | `stdio` | `stdio` / `http` / `both`. | -| `BOJ_HTTP_PORT` / `BOJ_HTTP_BIND` | `7780` / `127.0.0.1` | HTTP transport port and bind address. | -| `BOJ_HTTP_AUTH` / `BOJ_HTTP_AUTH_TOKENS` | `none` / — | HTTP auth mode and accepted bearer tokens. | -| `COORD_BACKEND_URL` | `http://127.0.0.1:7745` | Coordination bus backend. | -| `COORD_REQUIRE_NICKEL` | `0` | `1` enables strict Nickel-contract validation on gated envelopes. | -| `OTEL_EXPORTER_OTLP_ENDPOINT` | — | When set, every `tools/call` emits an OTLP/JSON span to `/v1/traces`. | +| Variable | Default | Purpose | +|------------------------------------------|--------------------------|---------------------------------------------------------------------------------| +| `BOJ_URL` | `http://localhost:7700` | Base URL for the BoJ REST backend. | +| `GITHUB_TOKEN` | — | PAT for `boj_github_*` tools. | +| `GITLAB_TOKEN` / `GITLAB_URL` | — / `https://gitlab.com` | Token + base URL for `boj_gitlab_*` tools. | +| `BOJ_TOOL_SCOPE` | `full` | `full`, `core`, or a CSV of domain prefixes (e.g. `core,github,browser`). | +| `BOJ_RATE_LIMIT` | `60` | Max tool calls per minute. | +| `BOJ_LOG_LEVEL` | `info` | `debug` / `info` / `warn` / `error` / `silent`. | +| `BOJ_TRANSPORT` | `stdio` | `stdio` / `http` / `both`. | +| `BOJ_HTTP_PORT` / `BOJ_HTTP_BIND` | `7780` / `127.0.0.1` | HTTP transport port and bind address. | +| `BOJ_HTTP_AUTH` / `BOJ_HTTP_AUTH_TOKENS` | `none` / — | HTTP auth mode and accepted bearer tokens. | +| `COORD_BACKEND_URL` | `http://127.0.0.1:7745` | Coordination bus backend. | +| `COORD_REQUIRE_NICKEL` | `0` | `1` enables strict Nickel-contract validation on gated envelopes. | +| `OTEL_EXPORTER_OTLP_ENDPOINT` | — | When set, every `tools/call` emits an OTLP/JSON span to `/v1/traces`. | # Security @@ -256,8 +256,6 @@ Report vulnerabilities per [`SECURITY.md`](SECURITY.md). - **Documentation** — MPL-2.0 today (the repository’s REUSE config tags every file MPL-2.0); a **CC-BY-SA-4.0** split for prose is the intended model, with the docs-licence rollout tracked as a follow-up. -This project **does not** use AGPL; any AGPL string remaining in a build manifest is a packaging regression, not the project’s license. - # Contributing & links - **Repository** — [github.com/hyperpolymath/boj-server](https://github.com/hyperpolymath/boj-server) diff --git a/elixir/lib/boj_rest/catalog.ex b/elixir/lib/boj_rest/catalog.ex index 010f4332..2a6b3671 100644 --- a/elixir/lib/boj_rest/catalog.ex +++ b/elixir/lib/boj_rest/catalog.ex @@ -63,10 +63,22 @@ defmodule BojRest.Catalog do end defp default_schema_path(root) do - root - |> Path.expand() - |> Path.dirname() - |> Path.join("schemas/cartridge-v1.json") + # Historical convention: the schema mirror sits one level above the + # cartridges root (true for the retired bundled tree and for caches + # that ship their own mirror). Roots without a sibling mirror (e.g. + # the E2E fixture catalog, ad-hoc BOJ_CARTRIDGES_PATH caches) fall + # back to this repo's own pinned mirror in schemas/. + sibling = + root + |> Path.expand() + |> Path.dirname() + |> Path.join("schemas/cartridge-v1.json") + + if File.exists?(sibling) do + sibling + else + Path.expand("../../../schemas/cartridge-v1.json", __DIR__) + end end defp load_schema(path) do diff --git a/tests/aspect_tests.sh b/tests/aspect_tests.sh index cb049d4c..370991a8 100755 --- a/tests/aspect_tests.sh +++ b/tests/aspect_tests.sh @@ -308,6 +308,11 @@ complete=0 stubs=0 ffi_only=0 +# The bundled cartridges/ tree was retired (canonical source: +# hyperpolymath/boj-server-cartridges, which carries its own completeness +# gates). Nothing to audit here unless a checkout-local tree exists. +shopt -s nullglob + for cart_dir in "$PROJECT_DIR"/cartridges/*/; do cart_name=$(basename "$cart_dir") has_abi=false; has_ffi=false @@ -351,6 +356,7 @@ for cart_dir in "$PROJECT_DIR"/cartridges/*/; do ;; esac done +shopt -u nullglob if [[ $incomplete -eq 0 ]]; then pass "All cartridges accounted for ($complete complete, $stubs stub, $ffi_only ffi_only)"