# Authentication Source: https://docs.coderhelm.com/api/authentication How requests to the CoderHelm API are authenticated, how teams are chosen, and the short-lived tokens for streaming and CI. ## Sessions [#sessions] The dashboard signs people in with email and password, Google or GitHub (all under `/auth`). A successful sign-in sets one cookie: ```http Set-Cookie: __Host-coderhelm_session=; HttpOnly; Secure; SameSite=Strict; Path=/ ``` Every route under `/api` requires it. The session lasts 7 days and slides: once it is more than halfway through, the next request gets a fresh cookie with your current role. Someone removed from the team gets no fresh cookie, so their access ends with the session. Because the cookie is `SameSite=Strict` and the API only accepts cross-origin requests from the dashboard, a page on another site can't use your session. A request without a valid session gets `401`. ## Teams [#teams] A person can belong to several teams. The session holds the current team, and every request acts on it; there is no team header. To switch: ```http POST /api/teams/switch Content-Type: application/json { "team_id": "" } ``` CoderHelm checks you are a member, then sets a new cookie for that team. `GET /api/teams` lists your teams. ## Roles [#roles] Each route checks a [capability](/concepts/roles#capabilities) against your role in the current team, on the server. A member calling an admin-only route gets `403`. ## Streaming tokens [#streaming-tokens] Plan chat streams its answer from `stream.coderhelm.com`, which can't read the session cookie. The dashboard first asks for a short-lived token: ```http POST /api/plans/chat/token ``` ```json { "token": "" } ``` The token is valid for 5 minutes and is sent as a bearer token: ```http POST /api/plans/chat/stream Authorization: Bearer ``` ## CI uploads [#ci-uploads] CoderHelm reads test reports from your GitHub workflow runs by itself. A CI job whose results never reach GitHub (a device farm, say) can upload its report instead, signed with GitHub Actions' own OIDC identity token, so you don't store a CoderHelm secret in CI. Request a token with the audience `coderhelm` and send the report file as the body: ```yaml title=".github/workflows/e2e.yml" permissions: id-token: write contents: read steps: - name: Upload test results to CoderHelm run: | TOKEN=$(curl -sS -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=coderhelm" | jq -r .value) curl -sS -X POST "https://api.coderhelm.com/webhooks/ci/tests/results?name=results.json" \ -H "Authorization: Bearer $TOKEN" \ --data-binary @test-results/results.json ``` - `name` is the report's file name and must end in `.json` (Playwright or Cucumber JSON) or `.xml` (JUnit XML). One report of at most 6 MB per request. - CoderHelm checks the token was issued by GitHub for one run of a repository connected to your team, with E2E results turned on under **Tests**. - The same token can ask which tests are quarantined: `GET /webhooks/ci/tests/quarantine`. ## Two-factor sign-in [#two-factor-sign-in] People can turn on two-factor authentication under **Security**. Sign-in then asks for a code (`POST /auth/mfa/verify`) before the session cookie is set. # API overview Source: https://docs.coderhelm.com/api What the CoderHelm API is, its hosts, how errors and pages of results look, and its limits. CoderHelm's API is the one its own dashboard uses. Everything the dashboard can do goes through it, and [All routes](/api/routes) lists every route, generated from the gateway's code. The API authenticates people with a browser session; there are no API keys or personal access tokens yet. Integrations reach CoderHelm through [webhooks](/api/webhooks), which are documented and stable. Routes under `/api` can change between releases. ## Hosts [#hosts] | Host | Serves | | --- | --- | | `https://api.coderhelm.com` | Every route: the dashboard API under `/api`, sign-in under `/auth`, webhooks under `/webhooks`, email links under `/email`. | | `https://stream.coderhelm.com` | Streamed answers (server-sent events) for plan chat. | | `https://auth.coderhelm.com` | The sign-in pages for Google and GitHub. | `GET https://api.coderhelm.com/` returns `{"service":"coderhelm","status":"ok"}` and needs no authentication. Every response carries `Cache-Control: no-store`. ## Requests and responses [#requests-and-responses] Bodies are JSON. Path parameters are written `:name` in the route list, for example `GET /api/runs/:run_id`. ### Errors [#errors] The status code is the error. Many errors have an empty body; others return a message: ```json { "error": "Plan not found" } ``` Some add a machine-readable `code`, for example `{"error": "...", "code": "already_fixing"}`. Treat any `4xx` or `5xx` as a failure and show `error` when it is there. | Status | Means | | --- | --- | | `400` | The request is malformed. | | `401` | Not signed in, or the session expired. | | `403` | Signed in, but your role can't do this (see [Roles](/concepts/roles)). | | `404` | Not found, or not in your team. | | `429` | Too many requests (sign-in and email links only). | ### Pages of results [#pages-of-results] Lists that can grow without end are paged with a cursor, newest first: ```http GET /api/reviewer/reviews?repo=your-org/web&limit=50 ``` ```json { "reviews": [ ... ], "next": "1729771200|REVIEW#..." } ``` Pass `next` back as `cursor` for the next page; it is `null` on the last page. `limit` defaults to 50 and is clamped to 1 to 200. ## Limits [#limits] - Sign-in routes: 20 requests per 5 minutes per IP address. Email links: 60 per 5 minutes. - The API as a whole is throttled at 500 requests per second with bursts to 1000. Over a limit, the API answers `429` with no body. # All routes Source: https://docs.coderhelm.com/api/routes Every route the CoderHelm gateway serves (304 in all), read from its router at build time. This list is generated from [`services/gateway/src/main.rs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs) at commit `637aaa459db2` each time the docs are built, so it always matches the code. All paths are on `https://api.coderhelm.com`. Path parameters are written `:name`. Unless a section says otherwise, a route needs a signed-in session: see [Authentication](/api/authentication). These are the routes the dashboard itself calls; they can change between releases, and there are no API keys for them yet. ## Service [#service] Public. | Method | Path | Handler | | --- | --- | --- | | `GET` | `/` | [`inline`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L760) | ## Sign-in [#sign-in] Public, limited to 20 requests per 5 minutes per IP address. | Method | Path | Handler | | --- | --- | --- | | `POST` | `/auth/signup` | [`auth::signup`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L730) | | `POST` | `/auth/waitlist` | [`auth::join_waitlist`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L731) | | `POST` | `/auth/login` | [`auth::login_email`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L732) | | `POST` | `/auth/verify-email` | [`auth::verify_email`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L733) | | `POST` | `/auth/forgot-password` | [`auth::forgot_password`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L734) | | `POST` | `/auth/confirm-reset` | [`auth::confirm_reset`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L735) | | `POST` | `/auth/mfa/verify` | [`auth::mfa_verify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L736) | | `GET` | `/auth/google` | [`auth::google_login`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L737) | | `GET` | `/auth/google/callback` | [`auth::google_callback`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L738) | | `GET` | `/auth/github` | [`auth::github_login`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L739) | | `GET` | `/auth/github/callback` | [`auth::github_callback`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L740) | | `POST` | `/auth/logout` | [`auth::logout`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L741) | ## Webhooks [#webhooks] Public, but every call is verified: see [Webhooks](/api/webhooks). | Method | Path | Handler | | --- | --- | --- | | `POST` | `/webhooks/github` | [`github_webhook::handle`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L720) | | `POST` | `/webhooks/jira/:token` | [`jira_webhook::handle`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L721) | | `POST` | `/webhooks/jira` | [`jira_webhook::handle_forge`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L722) | | `POST` | `/webhooks/alerts/sns` | [`alerts::handle_sns`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L723) | | `POST` | `/webhooks/ci/tests/results` | [`tests::ci_upload`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L725) | | `GET` | `/webhooks/ci/tests/quarantine` | [`tests::ci_quarantine`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L726) | ## Email links [#email-links] Public; the signed `t` token in the link is the credential. Limited to 60 requests per 5 minutes per IP address. | Method | Path | Handler | | --- | --- | --- | | `GET` | `/email/unsubscribe` | [`email::unsubscribe_link`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L749) | | `POST` | `/email/unsubscribe` | [`email::unsubscribe_one_click`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L749) | ## Account and teams [#account-and-teams] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/me` | [`api::me`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L109) | | `GET` | `/api/teams` | [`api::list_teams`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L115) | | `POST` | `/api/teams/switch` | [`api::switch_team`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L116) | | `PUT` | `/api/teams/rename` | [`api::rename_team`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L117) | | `GET` | `/api/allowlist` | [`api::list_allowlist`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L118) | | `POST` | `/api/allowlist` | [`api::add_to_allowlist`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L118) | | `DELETE` | `/api/allowlist` | [`api::remove_from_allowlist`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L118) | | `POST` | `/api/account/reset` | [`api::reset_account`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L383) | ## Users and roles [#users-and-roles] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/users` | [`users::list_users`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L385) | | `GET` | `/api/users/permissions` | [`users::get_permissions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L386) | | `POST` | `/api/users/invite` | [`users::invite_user`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L397) | | `PUT` | `/api/users/:user_id/role` | [`users::update_role`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L398) | | `POST` | `/api/users/:user_id/resend` | [`users::resend_invite`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L399) | | `POST` | `/api/users/:user_id/link-github` | [`users::link_github`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L400) | | `DELETE` | `/api/users/:user_id` | [`users::remove_user`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L404) | | `PUT` | `/api/users/password` | [`users::change_password`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L405) | | `POST` | `/api/users/mfa/setup` | [`users::mfa_setup`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L406) | | `POST` | `/api/users/mfa/verify` | [`users::mfa_verify_setup`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L407) | | `DELETE` | `/api/users/mfa` | [`users::mfa_disable`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L408) | ## Runs [#runs] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/runs` | [`api::list_runs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L196) | | `GET` | `/api/runs/:run_id` | [`api::get_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L197) | | `GET` | `/api/runs/:run_id/traces` | [`api::get_run_traces`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L198) | | `GET` | `/api/runs/:run_id/agent-log` | [`api::get_agent_log`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L199) | | `GET` | `/api/runs/:run_id/openspec` | [`api::get_run_openspec`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L200) | | `POST` | `/api/runs/:run_id/retry` | [`api::retry_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L201) | | `POST` | `/api/runs/:run_id/reset` | [`api::reset_and_rerun`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L202) | | `POST` | `/api/runs/:run_id/re-review` | [`api::re_review_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L203) | | `POST` | `/api/runs/:run_id/cancel` | [`api::cancel_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L204) | | `POST` | `/api/runs/:run_id/close` | [`run_close::close_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L205) | | `POST` | `/api/runs/:run_id/reopen` | [`run_close::reopen_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L206) | | `POST` | `/api/runs/close` | [`run_close::close_runs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L207) | ## Search [#search] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/search` | [`search::search`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L195) | ## Repos [#repos] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/repos` | [`api::list_repos`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L208) | | `POST` | `/api/repos/sync` | [`api::sync_repos`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L209) | | `POST` | `/api/repos/:owner/:name` | [`api::update_repo`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L210) | | `DELETE` | `/api/repos/:owner/:name` | [`api::delete_repo`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L210) | | `POST` | `/api/repos/:owner/:name/regenerate` | [`api::regenerate_repo`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L214) | | `POST` | `/api/repos/:owner/:name/role` | [`api::set_repo_role`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L218) | | `POST` | `/api/github/link-installation` | [`github::link_installation`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L309) | | `GET` | `/api/github/installation-status` | [`github::installation_status`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L313) | ## Plans [#plans] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/plans` | [`plans::list_plans`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L410) | | `POST` | `/api/plans` | [`plans::create_plan`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L410) | | `POST` | `/api/plans/chat` | [`plans::plan_chat`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L414) | | `POST` | `/api/plans/chat/token` | [`plans::stream_token`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L415) | | `GET` | `/api/plans/templates` | [`plans::list_templates`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L417) | | `POST` | `/api/plans/templates` | [`plans::create_template`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L417) | | `POST` | `/api/plans/templates/from-plan/:plan_id` | [`plans::create_template_from_plan`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L421) | | `GET` | `/api/plans/templates/:template_id` | [`plans::get_template`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L425) | | `DELETE` | `/api/plans/templates/:template_id` | [`plans::delete_template`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L425) | | `POST` | `/api/plans/templates/:template_id/use` | [`plans::use_template`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L429) | | `GET` | `/api/plans/:plan_id` | [`plans::get_plan`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L433) | | `PUT` | `/api/plans/:plan_id` | [`plans::update_plan`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L433) | | `DELETE` | `/api/plans/:plan_id` | [`plans::delete_plan`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L433) | | `POST` | `/api/plans/:plan_id/tasks` | [`plans::add_task`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L439) | | `PUT` | `/api/plans/:plan_id/tasks/:task_id` | [`plans::update_task`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L440) | | `DELETE` | `/api/plans/:plan_id/tasks/:task_id` | [`plans::delete_task`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L440) | | `POST` | `/api/plans/:plan_id/tasks/:task_id/approve` | [`plans::approve_task`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L444) | | `POST` | `/api/plans/:plan_id/tasks/:task_id/reject` | [`plans::reject_task`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L448) | | `POST` | `/api/plans/:plan_id/execute` | [`plans::execute_plan`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L452) | | `POST` | `/api/plans/:plan_id/tasks/:task_id/force-run` | [`plans::force_run_task`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L453) | | `POST` | `/api/plans/:plan_id/approve-and-execute` | [`plans::approve_all_and_execute`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L457) | | `GET` | `/api/plans/:plan_id/openspec` | [`plans::get_plan_openspec`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L461) | | `POST` | `/api/plans/:plan_id/openspec/generate` | [`plans::generate_plan_openspec`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L465) | | `POST` | `/api/plans/chat/stream` | [`plans::plan_chat_stream`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L767) | ## Reviewer and releases [#reviewer-and-releases] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/reviewer/org-config` | [`reviewer::get_org_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L249) | | `PUT` | `/api/reviewer/org-config` | [`reviewer::update_org_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L249) | | `GET` | `/api/reviewer/config/:owner/:name` | [`reviewer::get_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L253) | | `PUT` | `/api/reviewer/config/:owner/:name` | [`reviewer::update_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L253) | | `GET` | `/api/reviewer/reviews` | [`reviewer::list_reviews`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L279) | | `GET` | `/api/reviewer/review` | [`reviewer::get_review`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L280) | | `GET` | `/api/reviewer/live` | [`reviewer::live_prs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L281) | | `GET` | `/api/reviewer/gate` | [`reviewer::get_gate`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L282) | | `POST` | `/api/reviewer/gate` | [`reviewer::control_gate`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L282) | | `POST` | `/api/reviewer/review/rate` | [`reviewer::rate_review`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L286) | | `POST` | `/api/reviewer/re-review` | [`reviewer::re_review`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L287) | | `GET` | `/api/reviewer/lessons` | [`review_lessons::list_lessons`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L289) | | `DELETE` | `/api/reviewer/lessons` | [`review_lessons::delete_lesson`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L289) | | `GET` | `/api/releases` | [`reviewer::list_releases`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L293) | | `POST` | `/api/releases/send` | [`reviewer::send_release`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L294) | | `GET` | `/api/releases/pending` | [`reviewer::pending_releases`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L295) | | `POST` | `/api/releases/now` | [`reviewer::release_now`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L296) | ## Skills [#skills] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/skills` | [`skills::list`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L588) | | `POST` | `/api/skills/repos` | [`skills::connect`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L589) | | `DELETE` | `/api/skills/repos/:owner/:name` | [`skills::disconnect`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L590) | | `POST` | `/api/skills/repos/:owner/:name/sync` | [`skills::sync`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L594) | | `GET` | `/api/skills/item` | [`skills::item`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L598) | | `PUT` | `/api/skills/item` | [`skills::set_enabled`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L598) | | `GET` | `/api/skills/asks` | [`skills::asks`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L602) | | `POST` | `/api/skills/asks` | [`skills::try_agent`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L602) | | `GET` | `/api/skills/stats` | [`skills::stats`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L606) | | `POST` | `/api/skills/recheck` | [`skills::recheck`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L607) | | `PUT` | `/api/skills/always` | [`skills::set_always_apply`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L608) | | `PUT` | `/api/skills/reviews` | [`skills::set_reviews`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L609) | | `PUT` | `/api/skills/translated` | [`skills::set_use_translated`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L610) | | `GET` | `/api/skills/activity` | [`skills::activity`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L614) | | `GET` | `/api/skills/used` | [`skills::used`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L615) | ## Team tools [#team-tools] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/tools` | [`tools::list`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L572) | | `POST` | `/api/tools` | [`tools::create`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L572) | | `POST` | `/api/tools/validate` | [`tools::check`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L576) | | `GET` | `/api/tools/asks` | [`tools::asks`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L577) | | `POST` | `/api/tools/asks/:id` | [`tools::decide`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L578) | | `GET` | `/api/tools/:name` | [`tools::get`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L579) | | `PUT` | `/api/tools/:name` | [`tools::update`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L579) | | `DELETE` | `/api/tools/:name` | [`tools::remove`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L579) | | `POST` | `/api/tools/:name/approve` | [`tools::approve`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L585) | | `POST` | `/api/tools/:name/preview` | [`tools::preview`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L586) | ## Connections (MCP) [#connections-mcp] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/plugins/catalog` | [`plugins::list_catalog`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L561) | | `GET` | `/api/plugins` | [`plugins::list_enabled`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L562) | | `POST` | `/api/plugins/:id/enable` | [`plugins::enable_plugin`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L563) | | `DELETE` | `/api/plugins/:id` | [`plugins::disable_plugin`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L564) | | `PUT` | `/api/plugins/:id/credentials` | [`plugins::update_credentials`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L565) | | `PUT` | `/api/plugins/:id/prompt` | [`plugins::update_prompt`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L569) | | `POST` | `/api/plugins/:id/test` | [`plugins::test_connection`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L570) | ## Data sources [#data-sources] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/data-sources` | [`data_sources::list`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L617) | | `GET` | `/api/data-sources/activity` | [`data_sources::activity`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L625) | | `POST` | `/api/data-sources/api/probe` | [`data_sources::probe`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L629) | | `POST` | `/api/data-sources/api/check` | [`data_sources::check`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L630) | | `POST` | `/api/data-sources/api` | [`data_sources::create`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L631) | | `POST` | `/api/data-sources/rest` | [`data_sources::create_rest`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L632) | | `POST` | `/api/data-sources/search` | [`data_sources::create_search`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L636) | | `GET` | `/api/data-sources/aws/setup` | [`data_sources::aws_setup`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L640) | | `POST` | `/api/data-sources/aws/connect` | [`data_sources::aws_connect`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L644) | | `POST` | `/api/data-sources/logs` | [`data_sources::create_logs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L648) | | `POST` | `/api/data-sources/database` | [`data_sources::create_database`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L652) | | `PUT` | `/api/data-sources/:id` | [`data_sources::update`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L656) | | `DELETE` | `/api/data-sources/:id` | [`data_sources::remove`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L656) | | `POST` | `/api/data-sources/:id/key` | [`data_sources::replace_key`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L660) | | `POST` | `/api/data-sources/:id/test` | [`data_sources::test`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L664) | | `GET` | `/api/data-sources/:id/samples` | [`data_sources::samples`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L665) | | `POST` | `/api/data-sources/:id/try` | [`data_sources::try_lookup`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L669) | | `GET` | `/api/data-sources/:id/hidden-suggestions` | [`data_sources::hidden_suggestions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L673) | | `POST` | `/api/data-sources/:id/hidden-suggestions` | [`data_sources::decide_hidden_suggestions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L673) | ## Integrations [#integrations] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/integrations/jira/check` | [`api::get_jira_integration_check`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L219) | | `POST` | `/api/integrations/jira/check` | [`api::validate_jira_integration_payload`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L219) | | `DELETE` | `/api/integrations/jira/check` | [`api::delete_jira_integration`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L219) | | `POST` | `/api/integrations/jira/secret` | [`api::generate_jira_secret`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L225) | | `DELETE` | `/api/integrations/jira/secret` | [`api::delete_jira_secret`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L225) | | `GET` | `/api/integrations/jira/config` | [`api::get_jira_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L229) | | `PUT` | `/api/integrations/jira/config` | [`api::update_jira_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L229) | | `PUT` | `/api/integrations/jira/projects` | [`api::update_jira_projects`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L233) | | `GET` | `/api/integrations/jira/projects/fetch` | [`api::fetch_jira_projects`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L237) | | `GET` | `/api/integrations/jira/events` | [`api::get_jira_events`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L241) | | `GET` | `/api/aws-connections` | [`log_analyzer::list_connections`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L486) | | `POST` | `/api/aws-connections` | [`log_analyzer::create_connection`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L486) | | `GET` | `/api/aws-connections/cfn-url` | [`log_analyzer::get_cfn_url`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L491) | | `PUT` | `/api/aws-connections/:id` | [`log_analyzer::update_connection`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L495) | | `DELETE` | `/api/aws-connections/:id` | [`log_analyzer::delete_connection`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L495) | | `POST` | `/api/aws-connections/:id/test` | [`log_analyzer::test_connection`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L500) | | `GET` | `/api/aws-connections/:id/log-groups` | [`log_analyzer::discover_log_groups`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L504) | | `PUT` | `/api/aws-connections/:id/abilities` | [`integrations::set_aws_abilities`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L508) | | `POST` | `/api/aws-connections/:id/abilities/check` | [`integrations::check_aws`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L512) | | `GET` | `/api/integrations` | [`integrations::list`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L516) | | `GET` | `/api/connectors` | [`connectors::list`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L618) | | `GET` | `/api/connectors/aws-check` | [`connectors::aws_check`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L619) | | `PUT` | `/api/connectors/:kind` | [`connectors::save`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L620) | | `DELETE` | `/api/connectors/:kind` | [`connectors::remove`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L620) | | `POST` | `/api/connectors/:kind/test` | [`connectors::test`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L624) | | `POST` | `/integrations/jira/forge-register` | [`api::forge_register_urls`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L772) | ## Memories [#memories] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/memories` | [`memory::list_memories`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L702) | | `POST` | `/api/memories` | [`memory::create_memory`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L702) | | `GET` | `/api/memories/agents` | [`memory::agent_profiles`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L706) | | `POST` | `/api/memories/preview` | [`memory::preview_recall`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L707) | | `GET` | `/api/memories/stats` | [`memory::memory_stats`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L708) | | `DELETE` | `/api/memories/:memory_id` | [`memory::delete_memory`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L709) | | `PUT` | `/api/memories/:memory_id` | [`memory::update_memory`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L709) | ## Code graph [#code-graph] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/graph/repos` | [`graph::list_repos`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L299) | | `GET` | `/api/graph/status` | [`graph::status`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L300) | | `GET` | `/api/graph/symbol` | [`graph::symbol`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L301) | | `GET` | `/api/graph/neighborhood` | [`graph::neighborhood`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L302) | | `PUT` | `/api/graph/config/:owner/:name` | [`graph::update_config`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L303) | | `POST` | `/api/graph/rebuild/:owner/:name` | [`graph::rebuild`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L307) | ## Settings and instructions [#settings-and-instructions] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/notifications` | [`api::get_notification_prefs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L317) | | `PUT` | `/api/notifications` | [`api::update_notification_prefs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L317) | | `GET` | `/api/instructions/global` | [`api::get_global_instructions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L321) | | `PUT` | `/api/instructions/global` | [`api::update_global_instructions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L321) | | `GET` | `/api/instructions/repo/:owner/:name` | [`api::get_repo_instructions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L325) | | `PUT` | `/api/instructions/repo/:owner/:name` | [`api::update_repo_instructions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L325) | | `GET` | `/api/rules/global` | [`api::get_global_rules`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L330) | | `PUT` | `/api/rules/global` | [`api::update_global_rules`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L330) | | `GET` | `/api/rules/repo/:owner/:name` | [`api::get_repo_rules`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L334) | | `PUT` | `/api/rules/repo/:owner/:name` | [`api::update_repo_rules`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L334) | | `GET` | `/api/voice/global` | [`api::get_global_voice`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L339) | | `PUT` | `/api/voice/global` | [`api::update_global_voice`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L339) | | `GET` | `/api/voice/repo/:owner/:name` | [`api::get_repo_voice`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L343) | | `PUT` | `/api/voice/repo/:owner/:name` | [`api::update_repo_voice`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L343) | | `GET` | `/api/agents/global` | [`api::get_global_agents`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L348) | | `PUT` | `/api/agents/global` | [`api::update_global_agents`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L348) | | `GET` | `/api/agents/repo/:owner/:name` | [`api::get_repo_agents`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L352) | | `PUT` | `/api/agents/repo/:owner/:name` | [`api::update_repo_agents`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L352) | | `GET` | `/api/settings/budget` | [`api::get_budget`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L357) | | `PUT` | `/api/settings/budget` | [`api::update_budget`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L357) | | `GET` | `/api/settings/workflow` | [`api::get_workflow_settings`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L362) | | `PUT` | `/api/settings/workflow` | [`api::update_workflow_settings`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L362) | | `GET` | `/api/settings/git-conventions` | [`api::get_git_conventions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L367) | | `PUT` | `/api/settings/git-conventions` | [`api::update_git_conventions`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L367) | | `GET` | `/api/settings/model-provider` | [`api::get_model_provider`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L372) | | `PUT` | `/api/settings/model-provider` | [`api::update_model_provider`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L372) | | `DELETE` | `/api/settings/model-provider` | [`api::delete_model_provider`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L372) | | `GET` | `/api/banners` | [`banners::list_banners`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L381) | ## Usage and analytics [#usage-and-analytics] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/stats` | [`api::get_stats`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L245) | | `GET` | `/api/stats/history` | [`api::get_stats_history`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L246) | | `GET` | `/api/analytics` | [`analytics::get_analytics`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L247) | | `GET` | `/api/usage` | [`api::get_usage`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L379) | | `GET` | `/api/activity/summary` | [`activity::summary`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L616) | ## Alerts [#alerts] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/alert-routes` | [`alerts::list_routes`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L257) | | `PUT` | `/api/alert-routes` | [`alerts::put_route`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L257) | | `DELETE` | `/api/alert-routes` | [`alerts::delete_route`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L257) | | `GET` | `/api/alert-routes/alarms` | [`alerts::list_topic_alarms`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L263) | | `GET` | `/api/alert-budget` | [`alerts::get_budget`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L267) | | `PUT` | `/api/alert-budget` | [`alerts::put_budget`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L267) | | `GET` | `/api/alert-notify` | [`alerts::get_notify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L271) | | `PUT` | `/api/alert-notify` | [`alerts::put_notify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L271) | | `POST` | `/api/alert-notify/test` | [`alerts::test_notify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L275) | | `POST` | `/api/notify/test` | [`alerts::test_notify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L276) | | `GET` | `/api/alerts` | [`alerts::list_events`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L277) | | `GET` | `/api/alerts/event` | [`alerts::get_event`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L278) | ## Infrastructure and logs [#infrastructure-and-logs] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/infrastructure` | [`infrastructure::get_infrastructure`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L469) | | `POST` | `/api/infrastructure/refresh` | [`infrastructure::refresh_infrastructure`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L473) | | `GET` | `/api/infrastructure/repo/:owner/:name` | [`infrastructure::get_repo_infrastructure`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L477) | | `POST` | `/api/infrastructure/repo/:owner/:name/refresh` | [`infrastructure::refresh_repo_infrastructure`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L481) | | `GET` | `/api/recommendations` | [`log_analyzer::list_recommendations`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L518) | | `GET` | `/api/recommendations/notify` | [`log_analyzer::get_rec_notify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L522) | | `PUT` | `/api/recommendations/notify` | [`log_analyzer::put_rec_notify`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L522) | | `POST` | `/api/recommendations/:id/plan` | [`log_analyzer::create_plan_from_recommendation`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L526) | | `POST` | `/api/recommendations/:id/dismiss` | [`log_analyzer::dismiss_recommendation`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L530) | | `GET` | `/api/log-findings` | [`log_findings::list_findings`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L535) | | `GET` | `/api/log-findings/autofix` | [`log_findings::get_autofix`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L536) | | `PUT` | `/api/log-findings/autofix` | [`log_findings::put_autofix`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L536) | | `GET` | `/api/log-findings/:id/samples` | [`log_findings::get_samples`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L540) | | `POST` | `/api/log-findings/:id/fix` | [`log_findings::create_fix`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L544) | | `POST` | `/api/log-findings/:id/ignore` | [`log_findings::ignore_finding`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L548) | | `POST` | `/api/log-findings/:id/acknowledge` | [`log_findings::acknowledge_finding`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L552) | | `POST` | `/api/log-findings/:id/reopen` | [`log_findings::reopen_finding`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L556) | ## Tests [#tests] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/tests/settings` | [`tests::get_settings`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L679) | | `PUT` | `/api/tests/settings` | [`tests::put_settings`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L679) | | `GET` | `/api/tests/summary` | [`tests::summary`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L683) | | `GET` | `/api/tests/runs` | [`tests::list_runs`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L684) | | `GET` | `/api/tests/runs/:run_key` | [`tests::get_run`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L685) | | `GET` | `/api/tests/failure-groups` | [`tests::failure_groups`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L686) | | `GET` | `/api/tests/coverage` | [`tests::coverage`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L687) | | `POST` | `/api/tests/recommendations/:id/accept` | [`tests::accept_recommendation`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L688) | | `POST` | `/api/tests/recommendations/:id/dismiss` | [`tests::dismiss_recommendation`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L692) | | `GET` | `/api/tests` | [`tests::list_tests`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L696) | | `GET` | `/api/tests/:id` | [`tests::get_test`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L697) | | `POST` | `/api/tests/:id/quarantine` | [`tests::quarantine`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L698) | | `POST` | `/api/tests/:id/pin` | [`tests::pin`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L699) | | `POST` | `/api/tests/:id/fix` | [`tests::fix`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L700) | ## Health and failed messages [#health-and-failed-messages] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/health` | [`api::health`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L110) | | `GET` | `/api/dlq` | [`dlq::list_dlq_messages`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L111) | | `POST` | `/api/dlq/redrive` | [`dlq::redrive_dlq_message`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L112) | | `POST` | `/api/dlq/delete` | [`dlq::delete_dlq_message`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L113) | | `POST` | `/api/dlq/purge` | [`dlq::purge_dlq`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L114) | ## Support [#support] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/support/tickets` | [`support::list`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L136) | | `POST` | `/api/support/tickets` | [`support::create_handler`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L136) | | `GET` | `/api/support/tickets/:id` | [`support::get`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L140) | | `POST` | `/api/support/tickets/:id/reply` | [`support::reply`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L141) | | `POST` | `/api/support/tickets/:id/resolve` | [`support::resolve`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L142) | | `POST` | `/api/support/tickets/:id/participants` | [`support::add_people`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L146) | | `POST` | `/api/support/tickets/:id/participants/remove` | [`support::remove_people`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L150) | | `GET` | `/api/support/badge` | [`support::badge`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L154) | | `GET` | `/api/support/access` | [`support_access::get_access`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L181) | | `POST` | `/api/support/access` | [`support_access::grant_access`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L181) | | `DELETE` | `/api/support/access` | [`support_access::revoke_access`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L181) | | `GET` | `/api/support/view` | [`support_access::view_status`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L187) | | `DELETE` | `/api/support/view` | [`support_access::exit_view`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L187) | ## Platform admin [#platform-admin] Session cookie, and only for CoderHelm operators listed in the platform configuration. | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/admin/teams` | [`admin::admin_teams`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L124) | | `GET` | `/api/admin/dlq` | [`admin::admin_dlq`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L126) | | `GET` | `/api/admin/usage-check` | [`admin::admin_usage_check`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L128) | | `POST` | `/api/admin/dlq/delete` | [`admin::admin_dlq_delete`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L129) | | `GET` | `/api/admin/beta-signups` | [`admin::beta_signups`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L130) | | `POST` | `/api/admin/beta-signups/invite` | [`admin::invite_beta_signup`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L131) | | `GET` | `/api/admin/support/tickets` | [`support::admin_list_handler`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L155) | | `GET` | `/api/admin/support/tickets/:id` | [`support::admin_get`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L159) | | `POST` | `/api/admin/support/tickets/:id/reply` | [`support::admin_reply_handler`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L163) | | `POST` | `/api/admin/support/tickets/:id/status` | [`support::admin_status`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L167) | | `POST` | `/api/admin/support/tickets/:id/participants` | [`support::admin_add_people`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L171) | | `POST` | `/api/admin/support/tickets/:id/participants/remove` | [`support::admin_remove_people`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L175) | | `POST` | `/api/admin/support/view` | [`support_access::start_view`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L191) | ## Other [#other] | Method | Path | Handler | | --- | --- | --- | | `GET` | `/api/roles` | [`roles::list_roles`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L388) | | `POST` | `/api/roles` | [`roles::create_role`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L388) | | `GET` | `/api/roles/audit` | [`roles::list_audit`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L392) | | `PUT` | `/api/roles/:role_id` | [`roles::update_role`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L393) | | `DELETE` | `/api/roles/:role_id` | [`roles::delete_role`](https://github.com/CoderHelm/coderhelm-platform/blob/637aaa459db20c29f5292475688a2b5f77601d15/services/gateway/src/main.rs#L393) | # Webhooks Source: https://docs.coderhelm.com/api/webhooks The webhooks CoderHelm receives from GitHub, Jira and AWS, how each is verified, and what each event does. CoderHelm receives events on four kinds of webhook. Every one is verified before anything happens; an unverified request is refused and changes nothing. | Path | From | Verified by | | --- | --- | --- | | `POST /webhooks/github` | The CoderHelm GitHub App | `X-Hub-Signature-256` HMAC | | `POST /webhooks/jira` | The CoderHelm Jira app | The team's Jira app secret in the body | | `POST /webhooks/jira/:token` | A Jira webhook you create | The per-team token in the URL, and optionally `X-Hub-Signature` | | `POST /webhooks/alerts/sns` | An AWS SNS topic | The SNS message signature | | `POST /webhooks/ci/tests/results` | GitHub Actions | A GitHub OIDC token (see [Authentication](/api/authentication#ci-uploads)) | All paths are on `https://api.coderhelm.com`. ## GitHub [#github] GitHub sends every event of the CoderHelm App here. You don't set this up; installing the app does. Each request is signed with the app's webhook secret: `X-Hub-Signature-256: sha256=` is an HMAC-SHA256 of the raw body, compared in constant time. A missing or wrong signature gets `401`. The event type comes from `X-GitHub-Event`, and the body must name an installation. | Event | What CoderHelm does | | --- | --- | | `installation`, `installation_repositories` | Links the installation and its repositories to your team. | | `issues` (`assigned` to the bot, or `labeled` `coderhelm`) | Starts a run. | | `issue_comment`, `pull_request_review_comment` | `/coderhelm` or `@coderhelm` starts a run or sends feedback; `@coderhelm re-review` and questions go to the reviewer. | | `pull_request` | Reviewer triggers (the review label, new pushes), review requests, and merge tracking. | | `pull_request_review` | Feedback on CoderHelm's pull requests. | | `push` | A tag writes release notes. A push to the default branch syncs skills, proposes team tools from `.coderhelm/tools/` and updates the code graph. | | `check_run`, `check_suite`, `workflow_run` | Records CI results and resumes CI fixing. | | `repository` | Follows renames, archives and deletes. | Other events are accepted with `200` and ignored. An event from an installation that isn't linked to a team is also accepted and ignored. ## Jira app [#jira-app] The CoderHelm Jira app (an Atlassian Forge app) posts events here. The body carries your team id and the secret shown on the Jira page of the dashboard, under `coderhelm.team_id` and `coderhelm.forge_secret`. A wrong secret gets `403`. ## Jira webhook [#jira-webhook] If you can't install the Jira app, create a plain Jira webhook (see [Connect Jira](/getting-started/jira)). Its URL holds a token generated for your team: ```txt https://api.coderhelm.com/webhooks/jira/ ``` An unknown token gets `401`. If you also generated a secret, each request must carry `X-Hub-Signature: sha256=`, an HMAC-SHA256 of the body with that secret. What happens with each event: - An event whose name contains `comment` retries a failed run, or sends feedback to a run that already opened a pull request. - Any other issue event starts a run when the ticket has the label `coderhelm` (or one starting `coderhelm:`), or is assigned to a user whose name contains "CoderHelm", in a project you switched on. To pin a ticket to a repository from an automation, add `repo_owner` and `repo_name` to the payload, at the top level or under `coderhelm`: ```json { "webhookEvent": "jira:issue_updated", "issue": { "key": "WEB-42", "fields": { "labels": ["coderhelm"] } }, "coderhelm": { "repo_owner": "your-org", "repo_name": "web" } } ``` ## Alerts from AWS [#alerts-from-aws] CoderHelm can turn an alarm into a fix. Subscribe CoderHelm to an SNS topic with an HTTPS subscription to `https://api.coderhelm.com/webhooks/alerts/sns`, and add the topic under **Alert routes** in the dashboard. - Every message's SNS signature is checked (signature versions 1 and 2), and the signing certificate must come from SNS. Anything else gets `403`. - The subscription is confirmed automatically once the topic has an enabled route. Messages from topics without a route are accepted and ignored. - Accepted messages: CloudWatch alarm notifications, AWS Chatbot custom notifications, EventBridge events and plain text. A message that matches one of the route's rules becomes a run that opens a pull request. Other messages are posted to your team's Slack or Teams channel. Every alert is listed on the **Alerts** page with what CoderHelm did with it. There are no inbound webhooks for Slack or Teams; CoderHelm only sends messages to them. # Changelog Source: https://docs.coderhelm.com/changelog What changed in CoderHelm, month by month, from the merged pull requests of both repos. Generated at build time from the merged pull requests of [coderhelm-platform](https://github.com/CoderHelm/coderhelm-platform) (the agents and API, at `637aaa459db2`) and [coderhelm](https://github.com/CoderHelm/coderhelm) (the dashboard and these docs), covering the last 6 months. CoderHelm ships from `main` continuously, so there are no version numbers after the tags listed at the end. ## October 2026 [#october-2026] ### Agents and API [#agents-and-api] - Custom roles: team-made roles, enforced on every request ([#273](https://github.com/CoderHelm/coderhelm-platform/pull/273)) - Support tickets: name people when the ticket is opened ([#274](https://github.com/CoderHelm/coderhelm-platform/pull/274)) - Token limits: separate monthly limits for new tokens, cache reads and cache writes ([#272](https://github.com/CoderHelm/coderhelm-platform/pull/272)) - Meter every model call: streamed worker calls, broken replies, Titan, durable writes ([#271](https://github.com/CoderHelm/coderhelm-platform/pull/271)) - Log findings: create a fix PR from a finding, by hand or automatically ([#266](https://github.com/CoderHelm/coderhelm-platform/pull/266)) - Cache the skill check's inventory across a sync's items ([#270](https://github.com/CoderHelm/coderhelm-platform/pull/270)) - Health counts only a team's own failed messages; unreadable DLQ messages are archived ([#267](https://github.com/CoderHelm/coderhelm-platform/pull/267)) - Log analyzer test: Sonnet 5.5 cache reads at $0.20 ([#269](https://github.com/CoderHelm/coderhelm-platform/pull/269)) - Sonnet 5.5 cache reads are $0.20 per million tokens, not $0.10 ([#268](https://github.com/CoderHelm/coderhelm-platform/pull/268)) - Support tickets: add people, follow, email everyone on the ticket ([#264](https://github.com/CoderHelm/coderhelm-platform/pull/264)) - Code graph for every repo and every agent that reads code ([#263](https://github.com/CoderHelm/coderhelm-platform/pull/263)) - Close runs on purpose: a new closed status, one or many at once, and reopen ([#265](https://github.com/CoderHelm/coderhelm-platform/pull/265)) - Weekly summary goes to every active team; each person can still turn it off ([#262](https://github.com/CoderHelm/coderhelm-platform/pull/262)) - Retired model ids run as their replacement; they can no longer be saved ([#261](https://github.com/CoderHelm/coderhelm-platform/pull/261)) - History tool: a blame range over 500 lines is cut to the first 500, not refused ([#260](https://github.com/CoderHelm/coderhelm-platform/pull/260)) - Every failed run says why and where; CI red told honestly ([#259](https://github.com/CoderHelm/coderhelm-platform/pull/259)) - Notifications: post to Slack as well as Teams, with sealed, masked webhooks ([#258](https://github.com/CoderHelm/coderhelm-platform/pull/258)) - Plan new work as new work, read the ticket's earlier PRs, prove environments, follow near matches ([#256](https://github.com/CoderHelm/coderhelm-platform/pull/256)) - Real ticket keys in commits, sandbox results read from what ran, unconfirmed checks routed through CI ([#257](https://github.com/CoderHelm/coderhelm-platform/pull/257)) - Support tickets: attach items, and consented read-only support view ([#255](https://github.com/CoderHelm/coderhelm-platform/pull/255)) - Support queue: read every queued ticket without begins_with on an empty prefix ([#254](https://github.com/CoderHelm/coderhelm-platform/pull/254)) - PRs cover the whole job: copied blocks, steps outside the PR, every environment, Open items ([#253](https://github.com/CoderHelm/coderhelm-platform/pull/253)) - Proof check: read CI gates for any stack, check Terraform in the sandbox ([#252](https://github.com/CoderHelm/coderhelm-platform/pull/252)) - Reviewer: keep the PR's title and the findings on each review record ([#250](https://github.com/CoderHelm/coderhelm-platform/pull/250)) - Distrust the compromised eMudhra intermediates: webpki-roots 1.0.10, rustls-webpki 0.103.16 ([#251](https://github.com/CoderHelm/coderhelm-platform/pull/251)) - Admin: teams grouped by organisation, beta sign-ups, and invitees join the team that invited them ([#248](https://github.com/CoderHelm/coderhelm-platform/pull/248)) - Auto-merge: stop and re-arm from a PR comment or the dashboard ([#249](https://github.com/CoderHelm/coderhelm-platform/pull/249)) - Support tickets: team-scoped tickets, an admin queue and email both ways ([#247](https://github.com/CoderHelm/coderhelm-platform/pull/247)) - Analytics: compare with the period before, counted from records ([#246](https://github.com/CoderHelm/coderhelm-platform/pull/246)) - Reviews approve or request changes; unconfirmed facts are triaged, not a blanket hold ([#244](https://github.com/CoderHelm/coderhelm-platform/pull/244)) - Jira app: read:space:confluence, which the Confluence probe and space reads need ([#245](https://github.com/CoderHelm/coderhelm-platform/pull/245)) - Search across runs, reviewed PRs, releases and plans for ⌘K; runs list filters by repo ([#239](https://github.com/CoderHelm/coderhelm-platform/pull/239)) - Team agents run as review steps: plan, code and prose ([#243](https://github.com/CoderHelm/coderhelm-platform/pull/243)) - feat: read Confluence through the installed Jira app ([#242](https://github.com/CoderHelm/coderhelm-platform/pull/242)) - SQL name check: a date part (dateadd(day, ...)) is a keyword, not a column ([#241](https://github.com/CoderHelm/coderhelm-platform/pull/241)) - Admins can resend and revoke every pending invite; invites expire after 30 days ([#240](https://github.com/CoderHelm/coderhelm-platform/pull/240)) - Proof and review hold to the evidence the run recorded; pushes after an approval are reviewed incrementally ([#237](https://github.com/CoderHelm/coderhelm-platform/pull/237)) - Proof warning says only what is still unverified, and CI's green result clears it ([#238](https://github.com/CoderHelm/coderhelm-platform/pull/238)) - Repo pick follows the ticket's PR; continuations keep their plan; no duplicate run while a PR is open ([#236](https://github.com/CoderHelm/coderhelm-platform/pull/236)) - Large files read in full; empty writes over real files refused; no-op fix cycles stall ([#235](https://github.com/CoderHelm/coderhelm-platform/pull/235)) - Reviewer evals: review a case's diff with the real prompt, tools and critic ([#232](https://github.com/CoderHelm/coderhelm-platform/pull/232)) - Teams set their own branch, commit and PR title templates ([#233](https://github.com/CoderHelm/coderhelm-platform/pull/233)) - Data first, regex last: read real records before deciding a rule ([#234](https://github.com/CoderHelm/coderhelm-platform/pull/234)) - Reviewer learns from people's pushback on its findings ([#231](https://github.com/CoderHelm/coderhelm-platform/pull/231)) - Team instructions reach every agent that writes, proves, describes or reviews a change ([#230](https://github.com/CoderHelm/coderhelm-platform/pull/230)) - Reviewer: extending an existing pattern or carrying out a stated decision is not a finding ([#229](https://github.com/CoderHelm/coderhelm-platform/pull/229)) - Reviewer: show which PRs are queued, being reviewed, or waiting on CI or people ([#228](https://github.com/CoderHelm/coderhelm-platform/pull/228)) - REST lookups: record how much came back, and flag an empty list to the agent ([#227](https://github.com/CoderHelm/coderhelm-platform/pull/227)) - Prove what a change rests on before its PR opens ([#226](https://github.com/CoderHelm/coderhelm-platform/pull/226)) - REST APIs and OpenSearch are data sources; every source has a guide for agents ([#222](https://github.com/CoderHelm/coderhelm-platform/pull/222)) - Platform admin: teams overview, and only CoderHelm-verified identities count ([#225](https://github.com/CoderHelm/coderhelm-platform/pull/225)) - Record when members use the app, not only when they sign in ([#223](https://github.com/CoderHelm/coderhelm-platform/pull/223)) - Read unique indexes, not only constraints, before deciding a table's keys ([#221](https://github.com/CoderHelm/coderhelm-platform/pull/221)) - Named OpenSearch clusters, a guide per connection, PR descriptions kept true, field-meaning rules ([#220](https://github.com/CoderHelm/coderhelm-platform/pull/220)) - Who asks for work: one row per person, CoderHelm's own work labelled ([#219](https://github.com/CoderHelm/coderhelm-platform/pull/219)) - Runs list: search by ticket key or number, title, repo, PR number and status over all of a team's runs ([#218](https://github.com/CoderHelm/coderhelm-platform/pull/218)) - Many REST APIs per team; no second E2E fix while one is open; one-size merge status ([#217](https://github.com/CoderHelm/coderhelm-platform/pull/217)) - Releases: release now, automatic retries, blocked releases shown ([#216](https://github.com/CoderHelm/coderhelm-platform/pull/216)) - Coder diligence: no duplicate PRs, full-diff descriptions, migration registration, schema-change rules ([#215](https://github.com/CoderHelm/coderhelm-platform/pull/215)) - A multi-repo run waits on each pull request's own CI, and the CI wait loop stops after about a day of checks instead of looping forever ([#214](https://github.com/CoderHelm/coderhelm-platform/pull/214)) - A database lookup whose result has a type the Data API can't send (regclass, oid) runs again returning rows as JSON text, instead of failing as unreachable ([#213](https://github.com/CoderHelm/coderhelm-platform/pull/213)) - Any answer to CoderHelm's question on a waiting run carries the person's direction, whatever words it uses ([#212](https://github.com/CoderHelm/coderhelm-platform/pull/212)) - A plan says what it rests on (code, data or new work) and is checked for that; a person's direction on the ticket informs the checks instead of being blocked by them ([#211](https://github.com/CoderHelm/coderhelm-platform/pull/211)) - A traced code decision supersedes an earlier outside-the-code conclusion; a cause spanning repositories is planned in full, in merge order ([#210](https://github.com/CoderHelm/coderhelm-platform/pull/210)) - REST API connection: agents GET records from a system a team uses, under the paths it allows, with its key in the header it names ([#209](https://github.com/CoderHelm/coderhelm-platform/pull/209)) - Code that writes a wrong value makes it our bug, never a change outside the code; data problems need the source's own value; unreproducible values and display fallbacks get rules ([#208](https://github.com/CoderHelm/coderhelm-platform/pull/208)) - Data decisions must cite the code that writes the value (opened in the run) and the scope ([#207](https://github.com/CoderHelm/coderhelm-platform/pull/207)) - The planner reads the code that writes a wrong value, the keys that force records together, how widespread it is and who reads it, before deciding ([#206](https://github.com/CoderHelm/coderhelm-platform/pull/206)) - OpenSearch connection: agents list indexes, read mappings, search and count documents read only, limited to the indexes a team shares ([#205](https://github.com/CoderHelm/coderhelm-platform/pull/205)) - A run that ended as needing a change outside the code can be retried ([#204](https://github.com/CoderHelm/coderhelm-platform/pull/204)) - The planner reads the team's own instructions and traces a value step by step in production; test fixtures use neutral names ([#203](https://github.com/CoderHelm/coderhelm-platform/pull/203)) - Agents can see what a page rendered, the planner traces a shown value from the page back to its source, and a plan whose files exist here stays here ([#202](https://github.com/CoderHelm/coderhelm-platform/pull/202)) - A plan that describes data the planner never looked up goes back once to check it; still unchecked, it writes no code ([#201](https://github.com/CoderHelm/coderhelm-platform/pull/201)) - The planner reads each ticket comment whole, with line breaks; only a ticket past 60,000 characters of comments has its oldest shortened ([#200](https://github.com/CoderHelm/coderhelm-platform/pull/200)) - Jira comments reach the planner as plain text, dated and in full, so a person's diagnosis is read instead of 600 characters of document markup ([#199](https://github.com/CoderHelm/coderhelm-platform/pull/199)) - The planner debugs data before deciding where a fix belongs: follows the exact value by id, gets room to trace it, never blames a system it couldn't read ([#198](https://github.com/CoderHelm/coderhelm-platform/pull/198)) - CI failing on CoderHelm's own PR after its run finished goes back to the fix loop, and a flaky-test fix starts its proof when its run finishes ([#197](https://github.com/CoderHelm/coderhelm-platform/pull/197)) - The auto-merge status comment is one bold line and a short checklist, not a heading with commit hashes ([#196](https://github.com/CoderHelm/coderhelm-platform/pull/196)) - Skill stats range reads again, a PR a person closed is never reopened, the reviewer knows its page-check budget, quieter shared-install log ([#195](https://github.com/CoderHelm/coderhelm-platform/pull/195)) - A ticket CoderHelm already handled never gets the same PR again: plans keyed on history, read it and fail closed, comments read for intent, one review verdict ([#194](https://github.com/CoderHelm/coderhelm-platform/pull/194)) - One merge gate per PR with one status comment, woken by reviews and finished CI; replies to people on CoderHelm's PRs; a person's draft stays a draft; nightly evals call the model through a narrow AWS role ([#193](https://github.com/CoderHelm/coderhelm-platform/pull/193)) - One verdict function decides every formal review; model errors are typed and requeued by one policy in every pass; asks are read by a model; replayed reviewer evals guard the class ([#192](https://github.com/CoderHelm/coderhelm-platform/pull/192)) - A review that fails for a service error is retried and never posts a blocking verdict; replies keep the formal verdict in step; a sweep re-runs stuck reviews ([#191](https://github.com/CoderHelm/coderhelm-platform/pull/191)) - Plans decide where the fix belongs: a change outside the code is reported on the ticket with no PR, the reviewer flags hardcoded record overrides, and closed PRs teach the repo a lesson ([#190](https://github.com/CoderHelm/coderhelm-platform/pull/190)) - chore(gateway): stop scanning the MCP configs table on every cold start now that all credentials are sealed ([#189](https://github.com/CoderHelm/coderhelm-platform/pull/189)) - fix(live): check table, column, type and field names against the source's description before a lookup is sent, and hide columns per table with suggested hidden fields ([#188](https://github.com/CoderHelm/coderhelm-platform/pull/188)) - fix(reviewer): check the team's own public pages with check_url, and only verified defects request changes ([#187](https://github.com/CoderHelm/coderhelm-platform/pull/187)) - fix(security): seal MCP server credentials with KMS bound to team and server ([#186](https://github.com/CoderHelm/coderhelm-platform/pull/186)) - Team agents read with their own declared tools; the check holds each item to its runtime; plan chat uses skills, agents and data sources ([#185](https://github.com/CoderHelm/coderhelm-platform/pull/185)) - feat(integrations): AWS account abilities (logs, metrics, Airflow) found by a role check, one integrations endpoint, old metrics and Airflow connections folded in ([#184](https://github.com/CoderHelm/coderhelm-platform/pull/184)) - fix(worker): stop a Jira run whose named repo isn't turned on instead of silently re-picking another ([#183](https://github.com/CoderHelm/coderhelm-platform/pull/183)) - fix(skills): a re-check of the same item gives the same result: inventory-settled requirements, held steps, temperature 0 where taken ([#182](https://github.com/CoderHelm/coderhelm-platform/pull/182)) - feat(connectors): New Relic, Confluence, CloudWatch metrics, Airflow and AWS identity for agents ([#181](https://github.com/CoderHelm/coderhelm-platform/pull/181)) - fix(skills): a placeholder answer is unusable and asked again, and the check no longer asks the API to hold answers to the schema ([#180](https://github.com/CoderHelm/coderhelm-platform/pull/180)) - feat(skills): always apply a team skill or command in full to matching work, scoped by repository, pass and path ([#179](https://github.com/CoderHelm/coderhelm-platform/pull/179)) - feat(agents): github_history tool reads commits, blame, pull requests, releases, tags, deployments and Actions runs through the GitHub App ([#177](https://github.com/CoderHelm/coderhelm-platform/pull/177)) - fix(skills): one malformed step never fails a check, read commands map to GitHub backed tools, and nobody is sent to connect what is already connected ([#178](https://github.com/CoderHelm/coderhelm-platform/pull/178)) - fix(skills): the second try of a check isn't held to the schema by the API, since every stub came from a constrained answer ([#176](https://github.com/CoderHelm/coderhelm-platform/pull/176)) - fix(skills): retry a stub check at high effort, log how each answer ended, and never leave an outdated check showing after a failure ([#175](https://github.com/CoderHelm/coderhelm-platform/pull/175)) - chore: mentedb 0.41.0, an edited memory is recalled again ([#174](https://github.com/CoderHelm/coderhelm-platform/pull/174)) - fix(skills): a stub answer from the check is asked again once and never kept, and the item text is fenced off as data ([#173](https://github.com/CoderHelm/coderhelm-platform/pull/173)) - feat(skills): check each repository skill against the team's real Coderhelm tools and keep a translated version ([#171](https://github.com/CoderHelm/coderhelm-platform/pull/171)) - Treat quarantined-only CI failures as passing and make the ticket delay a team setting ([#172](https://github.com/CoderHelm/coderhelm-platform/pull/172)) - feat(alerts): a recovery records the ticket of the alert it resolves, so the dashboard can pair them ([#170](https://github.com/CoderHelm/coderhelm-platform/pull/170)) - chore: memory engine to mentedb 0.40.0 from crates.io, proven to open snapshots the old engine wrote ([#169](https://github.com/CoderHelm/coderhelm-platform/pull/169)) - fix(weekly-summary): every figure counts what its label says, over the week it names ([#168](https://github.com/CoderHelm/coderhelm-platform/pull/168)) - fix: count every model call once, with all four token parts and per-model prices ([#166](https://github.com/CoderHelm/coderhelm-platform/pull/166)) - feat(weekly-summary): turn on the Monday send, only for teams with a rollout list ([#167](https://github.com/CoderHelm/coderhelm-platform/pull/167)) - feat: make the weekly summary email and unsubscribe pages dark only, and add a per-team rollout list for the scheduled send ([#165](https://github.com/CoderHelm/coderhelm-platform/pull/165)) - feat: redesign the weekly summary email with no money, tokens split four ways, and an unsubscribe page that asks before it acts ([#164](https://github.com/CoderHelm/coderhelm-platform/pull/164)) - feat: admins set the token limit; weekly summary email with signed one-click unsubscribe, shipped switched off ([#163](https://github.com/CoderHelm/coderhelm-platform/pull/163)) - fix(gateway): platform admin only for the signup allowlist, member checks on plan writes, plans paging, health checks read the status index, no start over for runs in flight ([#161](https://github.com/CoderHelm/coderhelm-platform/pull/161)) - fix(gateway): store and return the token usage email preference the worker reads ([#160](https://github.com/CoderHelm/coderhelm-platform/pull/160)) - feat(activity): access log of every skill read and agent ask with run, work and reason; filtered lookup log; activity summary ([#158](https://github.com/CoderHelm/coderhelm-platform/pull/158)) - feat(team): permissions table from enforced role checks, link GitHub sign-ins, non-clobbering GitHub upsert ([#162](https://github.com/CoderHelm/coderhelm-platform/pull/162)) - fix(data-sources): agents look schemas up and get real names on a wrong one; no stray colons reach the Data API; broken tools can't be saved; failures keep their cause ([#159](https://github.com/CoderHelm/coderhelm-platform/pull/159)) - fix: team per installation, server-side write shas, sandbox runway, memlock/code-graph errors, review anchors and cost, plan cap, run outcomes ([#157](https://github.com/CoderHelm/coderhelm-platform/pull/157)) - fix: update open PRs on ticket edits, drop stale CI events, skip bot comments, resolve SHA refs, paginate PR run lookup ([#156](https://github.com/CoderHelm/coderhelm-platform/pull/156)) - feat(skills): flag tools a repo item asks for that Coderhelm's agents don't have ([#155](https://github.com/CoderHelm/coderhelm-platform/pull/155)) - feat(alerts): one recovery card per open alert, linking the alert it resolves ([#154](https://github.com/CoderHelm/coderhelm-platform/pull/154)) - feat(skills): usage stats for a team's skills and agents ([#153](https://github.com/CoderHelm/coderhelm-platform/pull/153)) - feat(skills): say which team agents were consulted on what Coderhelm writes ([#152](https://github.com/CoderHelm/coderhelm-platform/pull/152)) - feat(skills): tie each agent ask to its run and file version, count asks, record who switched an agent ([#151](https://github.com/CoderHelm/coderhelm-platform/pull/151)) - feat(skills): keep each question put to a team agent, and let admins try one ([#150](https://github.com/CoderHelm/coderhelm-platform/pull/150)) - feat(skills): agents can ask a team agent a question, with no tools ([#149](https://github.com/CoderHelm/coderhelm-platform/pull/149)) - feat(skills): read a team's skills from a connected repo and give them to the agents ([#148](https://github.com/CoderHelm/coderhelm-platform/pull/148)) - fix(data-sources): array slices run, and database errors say what went wrong ([#147](https://github.com/CoderHelm/coderhelm-platform/pull/147)) - fix(analytics): fill in merge times for PRs merged before they were recorded ([#146](https://github.com/CoderHelm/coderhelm-platform/pull/146)) - fix(tools): a path input can't carry a slash, backslash or escape ([#145](https://github.com/CoderHelm/coderhelm-platform/pull/145)) - fix(data-sources): close five read-path escapes found in a security review ([#144](https://github.com/CoderHelm/coderhelm-platform/pull/144)) - feat(e2e): the fix PRs setting starts fixes on its own, at most two per repo a week ([#143](https://github.com/CoderHelm/coderhelm-platform/pull/143)) - fix(triggers): editing a ticket whose PR merged no longer starts a second PR ([#142](https://github.com/CoderHelm/coderhelm-platform/pull/142)) - feat(tools): a team's own tools — named, typed, reviewed reads the agents can call ([#140](https://github.com/CoderHelm/coderhelm-platform/pull/140)) - feat(memory): provenance, usage, pins, edits, recall preview and agent profiles ([#138](https://github.com/CoderHelm/coderhelm-platform/pull/138)) - feat(analytics): token totals per run, per merged PR, per day and per repo ([#141](https://github.com/CoderHelm/coderhelm-platform/pull/141)) - fix(runs): answer from what was read when steps run out, record the chosen repo, name the repo a ticket's files live in ([#139](https://github.com/CoderHelm/coderhelm-platform/pull/139)) - feat(e2e): read Playwright HTML reports, so repos that only upload them need no change ([#137](https://github.com/CoderHelm/coderhelm-platform/pull/137)) - feat(e2e): E2E test intelligence — read every run, tell flaky from broken, act on it ([#133](https://github.com/CoderHelm/coderhelm-platform/pull/133)) - feat(analytics): answer whether Coderhelm is worth it, from records it already keeps ([#132](https://github.com/CoderHelm/coderhelm-platform/pull/132)) - fix(reviewer): steadier verdicts, shorter reviews, one review per commit ([#136](https://github.com/CoderHelm/coderhelm-platform/pull/136)) - feat(data-sources): exact hidden names with a leading = ([#135](https://github.com/CoderHelm/coderhelm-platform/pull/135)) - fix(data-sources): warehouse lookups run in a rolled-back read-only transaction ([#134](https://github.com/CoderHelm/coderhelm-platform/pull/134)) - feat(data-sources): read-only Redshift warehouses, every shared database in one source ([#131](https://github.com/CoderHelm/coderhelm-platform/pull/131)) - fix(data-sources): say 1 row and 1 line, not 1 rows ([#130](https://github.com/CoderHelm/coderhelm-platform/pull/130)) - feat(data-sources): full lookup text and paging for the activity feed ([#129](https://github.com/CoderHelm/coderhelm-platform/pull/129)) - feat(agents): read-only logs and database sources in a team's AWS account ([#128](https://github.com/CoderHelm/coderhelm-platform/pull/128)) - fix(reviewer): a before-merge heads-up is fine, a demand is not ([#127](https://github.com/CoderHelm/coderhelm-platform/pull/127)) - fix(reviewer): leave copy to its owners, answer with the repo, and keep a calm tone ([#126](https://github.com/CoderHelm/coderhelm-platform/pull/126)) - feat(agents): investigate bug reports with the team's data sources ([#125](https://github.com/CoderHelm/coderhelm-platform/pull/125)) - feat(agents): planner and coding agents use a team's data sources ([#124](https://github.com/CoderHelm/coderhelm-platform/pull/124)) - feat(reviewer): read-only lookups against a team's own API ([#123](https://github.com/CoderHelm/coderhelm-platform/pull/123)) - fix(reviewer): team label rules outrank the repo's docs ([#122](https://github.com/CoderHelm/coderhelm-platform/pull/122)) - fix(reviewer): read replies and resolved threads before re-raising a concern ([#121](https://github.com/CoderHelm/coderhelm-platform/pull/121)) - chore: use generic names in comments, prompts and test fixtures ([#120](https://github.com/CoderHelm/coderhelm-platform/pull/120)) - feat(alerts): alert budget in tokens; offer seen non-alarm alerts for text rules ([#119](https://github.com/CoderHelm/coderhelm-platform/pull/119)) - feat(alerts): daily alert spend budget, 5 runs per rule, no catch-all rules ([#118](https://github.com/CoderHelm/coderhelm-platform/pull/118)) - feat(alerts): per-alarm rules on alert routes and a topic's alarm list ([#117](https://github.com/CoderHelm/coderhelm-platform/pull/117)) - feat(alerts): recoveries post to Teams only when the route turns them on ([#116](https://github.com/CoderHelm/coderhelm-platform/pull/116)) - fix(alerts): message alerts keep their fields; link fields become buttons ([#115](https://github.com/CoderHelm/coderhelm-platform/pull/115)) - feat(alerts): compact Teams alert cards with details behind a toggle ([#114](https://github.com/CoderHelm/coderhelm-platform/pull/114)) - feat(alerts): notify-only routes post alerts to Teams without a run ([#113](https://github.com/CoderHelm/coderhelm-platform/pull/113)) - fix(log-analyzer): restore analysis, stop false resolutions, add Teams notifications ([#112](https://github.com/CoderHelm/coderhelm-platform/pull/112)) - feat(alerts): Teams notifications with a team channel and per-route override ([#111](https://github.com/CoderHelm/coderhelm-platform/pull/111)) - feat(api): cursor pagination for runs, reviews, releases and recommendations ([#110](https://github.com/CoderHelm/coderhelm-platform/pull/110)) - feat(alerts): record every alert so each has its own link ([#109](https://github.com/CoderHelm/coderhelm-platform/pull/109)) - feat(alerts): turn monitoring alerts into pull requests ([#108](https://github.com/CoderHelm/coderhelm-platform/pull/108)) - fix(reviewer): a person's push always gets a visible review ([#107](https://github.com/CoderHelm/coderhelm-platform/pull/107)) - fix(reviewer): let a burst of pushes settle before reviewing ([#106](https://github.com/CoderHelm/coderhelm-platform/pull/106)) - fix(reviewer): don't post a verdict once the PR has moved past the reviewed commit ([#105](https://github.com/CoderHelm/coderhelm-platform/pull/105)) - fix(reviewer): offer a suggestion only when it is a safe in-place edit ([#104](https://github.com/CoderHelm/coderhelm-platform/pull/104)) - feat(release-notes): send the email webhook's secret as X-Automation-Webhook-Token ([#103](https://github.com/CoderHelm/coderhelm-platform/pull/103)) - fix(reviewer): approve only when nothing is left to change ([#102](https://github.com/CoderHelm/coderhelm-platform/pull/102)) - fix(reviewer): with Require tests on, every missing-tests finding blocks the merge ([#101](https://github.com/CoderHelm/coderhelm-platform/pull/101)) - feat(release-notes): also write notes for release tags pushed outside CoderHelm ([#100](https://github.com/CoderHelm/coderhelm-platform/pull/100)) - fix(github): pin installation-token format via X-GitHub-Stateless-S2S-Token; scrub stateless tokens fully ([#99](https://github.com/CoderHelm/coderhelm-platform/pull/99)) - fix(reviewer): add family labels (E2E:\) even before they exist; never defer a label to the author ([#98](https://github.com/CoderHelm/coderhelm-platform/pull/98)) - feat(coder): write tests per the repo's conventions when Require tests is on ([#97](https://github.com/CoderHelm/coderhelm-platform/pull/97)) - fix(reviewer): log every CI-label decision with the reviewer's reason ([#96](https://github.com/CoderHelm/coderhelm-platform/pull/96)) ### Dashboard and docs [#dashboard-and-docs] - Learning page: what CoderHelm learned from outcomes, with pin and revert ([#189](https://github.com/CoderHelm/coderhelm/pull/189)) - Dashboard: long saved text reads like text ([#184](https://github.com/CoderHelm/coderhelm/pull/184)) - Docs site: send the CORS header through CloudFront's CORS settings ([#188](https://github.com/CoderHelm/coderhelm/pull/188)) - Integrations: add remote MCP servers by address, connect with OAuth, pick their tools ([#186](https://github.com/CoderHelm/coderhelm/pull/186)) - Developer docs at docs.coderhelm.com ([#187](https://github.com/CoderHelm/coderhelm/pull/187)) - Custom roles on the team page ([#181](https://github.com/CoderHelm/coderhelm/pull/181)) - Support: add people on the new-ticket form ([#182](https://github.com/CoderHelm/coderhelm/pull/182)) - Token limit page: set new token, cache read and cache write limits separately ([#180](https://github.com/CoderHelm/coderhelm/pull/180)) - Code graph explorer: calm motion and readable labels ([#179](https://github.com/CoderHelm/coderhelm/pull/179)) - Show estimated and late model calls on Analytics, and the usage check on Admin ([#178](https://github.com/CoderHelm/coderhelm/pull/178)) - Dashboard: no page scrolls sideways on a phone ([#177](https://github.com/CoderHelm/coderhelm/pull/177)) - Logs in the main menu: findings, fix PRs and automatic fix PRs ([#171](https://github.com/CoderHelm/coderhelm/pull/171)) - Dashboard: agent, memory, test runs, alert, new tool and health pages on the shared components ([#174](https://github.com/CoderHelm/coderhelm/pull/174)) - Name the shared queue page in the top bar; main's UI lint is green again ([#176](https://github.com/CoderHelm/coderhelm/pull/176)) - Deploys never delete the files open pages still need ([#175](https://github.com/CoderHelm/coderhelm/pull/175)) - Health shows only the team's failed messages; admins get the shared queue ([#172](https://github.com/CoderHelm/coderhelm/pull/172)) - Dashboard: one top bar on every page, and a permissions matrix on Settings \> Team ([#169](https://github.com/CoderHelm/coderhelm/pull/169)) - Support ticket page: a readable thread, a side panel, and people on a ticket ([#170](https://github.com/CoderHelm/coderhelm/pull/170)) - Settings pages on the shared settings pieces: one save bar, plain words ([#173](https://github.com/CoderHelm/coderhelm/pull/173)) - Code graph page: every repo with its graph's status, Turn off and Rebuild ([#167](https://github.com/CoderHelm/coderhelm/pull/167)) - Close runs on purpose: from the run page, several from the runs list, and reopen ([#168](https://github.com/CoderHelm/coderhelm/pull/168)) - Dashboard: one code block with syntax highlighting everywhere ([#166](https://github.com/CoderHelm/coderhelm/pull/166)) - One markdown editor for tickets, replies, instructions, notes and the plan chat ([#165](https://github.com/CoderHelm/coderhelm/pull/165)) - Dashboard UI foundations: shared settings pieces, UI lint in CI, a menu that shows it scrolls ([#164](https://github.com/CoderHelm/coderhelm/pull/164)) - Analytics: CI outcomes in Where it struggles ([#163](https://github.com/CoderHelm/coderhelm/pull/163)) - Dashboard: choose Teams, Slack or both wherever CoderHelm posts ([#162](https://github.com/CoderHelm/coderhelm/pull/162)) - Redesign Settings \> AI models as settings rows with a sticky save bar ([#161](https://github.com/CoderHelm/coderhelm/pull/161)) - New plan: one question first, and a chat that reads like a conversation ([#160](https://github.com/CoderHelm/coderhelm/pull/160)) - Plan page: a document with one summary line and one action ([#159](https://github.com/CoderHelm/coderhelm/pull/159)) - Support: attach items to tickets, support access setting, support view banner ([#158](https://github.com/CoderHelm/coderhelm/pull/158)) - Lists: a long chip never squeezes the title; skills show always-apply in a few words ([#157](https://github.com/CoderHelm/coderhelm/pull/157)) - Admin: one row per organisation, a Beta sign-ups tab, and the count in the menu ([#152](https://github.com/CoderHelm/coderhelm/pull/152)) - Run page: team agents asked, as a timeline ([#156](https://github.com/CoderHelm/coderhelm/pull/156)) - Review page: the PR's title and link, findings as cards, a quiet used section ([#154](https://github.com/CoderHelm/coderhelm/pull/154)) - Reviewer: stop and re-arm auto-merge on a PR ([#153](https://github.com/CoderHelm/coderhelm/pull/153)) - Support: Report an issue and Contact us open a ticket in the app, not GitHub or email ([#155](https://github.com/CoderHelm/coderhelm/pull/155)) - Support tickets: Get help in the menu and ⌘K, the team's tickets, and an admin queue ([#151](https://github.com/CoderHelm/coderhelm/pull/151)) - Analytics: compare with the period before, and this month so far ([#150](https://github.com/CoderHelm/coderhelm/pull/150)) - Reviewer settings: a summary, section nav and one row per setting ([#149](https://github.com/CoderHelm/coderhelm/pull/149)) - Analytics: ratings read as the share rated helpful, not emoji counts ([#148](https://github.com/CoderHelm/coderhelm/pull/148)) - Skills: review steps for team agents, and needs that assume a local machine ([#146](https://github.com/CoderHelm/coderhelm/pull/146)) - feat: show Confluence connected through the Jira app ([#145](https://github.com/CoderHelm/coderhelm/pull/145)) - One list system on every listing page, and a ⌘K command palette ([#147](https://github.com/CoderHelm/coderhelm/pull/147)) - Team page: admins can resend and revoke every pending invite, and expired invites say so ([#144](https://github.com/CoderHelm/coderhelm/pull/144)) - Releases: a dense list grouped by repo, with each destination's real state ([#143](https://github.com/CoderHelm/coderhelm/pull/143)) - Reviewer: a skipped review reads 'No review needed' with the reason ([#142](https://github.com/CoderHelm/coderhelm/pull/142)) - Workflow settings: git conventions for branch names, commits and PR titles ([#141](https://github.com/CoderHelm/coderhelm/pull/141)) - Reviewer page: in-review, waiting and done PRs with live status ([#140](https://github.com/CoderHelm/coderhelm/pull/140)) - Data sources: grouped by kind, one row per source, one Add button ([#139](https://github.com/CoderHelm/coderhelm/pull/139)) - Data sources: REST APIs and OpenSearch clusters, and a guide for agents on every source ([#136](https://github.com/CoderHelm/coderhelm/pull/136)) - Admin: teams overview, and the server decides who sees the page ([#138](https://github.com/CoderHelm/coderhelm/pull/138)) - Team page: show when each member was last active, not only signed in ([#137](https://github.com/CoderHelm/coderhelm/pull/137)) - Connections: saved key shown as saved, a guide for agents, any kind named when adding another ([#135](https://github.com/CoderHelm/coderhelm/pull/135)) - Who asks for work: people first, CoderHelm's own work and unrecorded runs after ([#134](https://github.com/CoderHelm/coderhelm/pull/134)) - Runs page: search by ticket, title, repo or PR number, and filter by status ([#133](https://github.com/CoderHelm/coderhelm/pull/133)) - Many REST APIs; release buttons say what they do ([#132](https://github.com/CoderHelm/coderhelm/pull/132)) - Releases: Release now, retry blocked releases, show failed runs ([#131](https://github.com/CoderHelm/coderhelm/pull/131)) - REST API in Settings → Integrations: address, key header, key, allowed paths and hidden fields ([#130](https://github.com/CoderHelm/coderhelm/pull/130)) - OpenSearch in Settings → Integrations: cluster address, read-only user, shared indexes and hidden fields; neutral examples in comments ([#129](https://github.com/CoderHelm/coderhelm/pull/129)) - The run page offers Retry on a run that ended as needing a change outside the code ([#128](https://github.com/CoderHelm/coderhelm/pull/128)) - Runs whose fix is a change outside the code say so in the list and show what to change on the run page ([#126](https://github.com/CoderHelm/coderhelm/pull/126)) - feat(integrations): one aligned list per section instead of cards; no AWS item or count in the menu ([#127](https://github.com/CoderHelm/coderhelm/pull/127)) - feat(integrations): cards open from anywhere and say what you can do inside; Connections in the menu with an attention count; your websites list ([#125](https://github.com/CoderHelm/coderhelm/pull/125)) - feat(data-sources): show lookups stopped for an unknown name, hide a column in one table, and accept or dismiss suggested hidden fields ([#124](https://github.com/CoderHelm/coderhelm/pull/124)) - feat(skills): plan chat shows the skills, agents and data sources each answer used; runs, reviews and plans say what they used; agent pages show the read-only tools each agent's own file gives it ([#123](https://github.com/CoderHelm/coderhelm/pull/123)) - feat(integrations): one Settings → Integrations page with status, abilities and credentials for every integration; old pages redirect ([#122](https://github.com/CoderHelm/coderhelm/pull/122)) - fix(skills): put the read and ask switches in their own settings row ([#121](https://github.com/CoderHelm/coderhelm/pull/121)) - fix(skills): label steps that talk to a person instead of showing the raw kind ([#120](https://github.com/CoderHelm/coderhelm/pull/120)) - feat(data-sources): connect New Relic, Confluence, CloudWatch metrics and Airflow, show the AWS role update link, and send skill-check gaps to the right connection ([#119](https://github.com/CoderHelm/coderhelm/pull/119)) - feat(skills): always apply toggle with repository, pass and path scope, list badge, suggestions, and applied standards on runs and reviews ([#118](https://github.com/CoderHelm/coderhelm/pull/118)) - fix(skills): no connect link for an integration that's already connected, a partly checked state instead of a failure, and the check's notes on the page ([#117](https://github.com/CoderHelm/coderhelm/pull/117)) - feat(site): restore Ship code, not tickets and tell the product as one story grouped by job ([#116](https://github.com/CoderHelm/coderhelm/pull/116)) - fix(site): markdown rewrite regex broke the viewer request function and took the site down ([#115](https://github.com/CoderHelm/coderhelm/pull/115)) - feat(dashboard): every page outside skills, data sources and the AWS, alerts and Jira settings sits in the shared centered column with the shared header ([#114](https://github.com/CoderHelm/coderhelm/pull/114)) - feat(site): story driven home, one page per job, Markdown twins and llms.txt ([#113](https://github.com/CoderHelm/coderhelm/pull/113)) - feat(skills): show how Coderhelm runs each skill, step by step, with what to connect and the translated version ([#111](https://github.com/CoderHelm/coderhelm/pull/111)) - feat(dashboard): redesigned AWS, Alert routes, Jira and Data sources pages with status cards, guided setup, a live rule preview and paired recoveries ([#112](https://github.com/CoderHelm/coderhelm/pull/112)) - Tests page: ticket delay setting and the CI step that skips quarantined tests ([#110](https://github.com/CoderHelm/coderhelm/pull/110)) - feat(dashboard): shared Page, PageHeader and Section layout at the analytics width; analytics and releases use it ([#109](https://github.com/CoderHelm/coderhelm/pull/109)) - feat(dashboard): every token meter shows the total of all four parts, with the parts, cache hit rate and split by feature ([#108](https://github.com/CoderHelm/coderhelm/pull/108)) - feat(dashboard): admins and the owner change the token limit; weekly summary switch says what it sends and when ([#107](https://github.com/CoderHelm/coderhelm/pull/107)) - fix(dashboard): audit every page outside settings: error states with retry, plain status words, phone layouts, keyboard and screen reader fixes, page titles, 404 page ([#106](https://github.com/CoderHelm/coderhelm/pull/106)) - feat(dashboard): settings hub redesign; token limit, GitHub and nav items open for the roles that see them ([#105](https://github.com/CoderHelm/coderhelm/pull/105)) - feat(dashboard): activity views for skill reads, agent asks and data lookups with who, why, run and result ([#104](https://github.com/CoderHelm/coderhelm/pull/104)) - feat(dashboard): redesigned team page with live permissions, one row per person, GitHub linking and invites ([#103](https://github.com/CoderHelm/coderhelm/pull/103)) - fix(dashboard): explain a blocked GitHub sign-in when the org already uses Coderhelm ([#102](https://github.com/CoderHelm/coderhelm/pull/102)) - chore: new Google tags for coderhelm.com and app.coderhelm.com ([#101](https://github.com/CoderHelm/coderhelm/pull/101)) - feat(dashboard): warn on the Skills page when an item asks for tools Coderhelm doesn't have ([#100](https://github.com/CoderHelm/coderhelm/pull/100)) - feat(dashboard): label recovery outcomes and explain one-recovery-per-alert ([#99](https://github.com/CoderHelm/coderhelm/pull/99)) - feat(dashboard): usage stats on the Skills page ([#98](https://github.com/CoderHelm/coderhelm/pull/98)) - feat(dashboard): a page for each team agent, and team agent asks on run pages ([#97](https://github.com/CoderHelm/coderhelm/pull/97)) - feat(dashboard): Skills page for a team's skills read from a repo ([#96](https://github.com/CoderHelm/coderhelm/pull/96)) - fix(dashboard): draw select arrows with room from the edge ([#95](https://github.com/CoderHelm/coderhelm/pull/95)) - fix(dashboard): distinct icons for Tests, Code Graph and Plans; landing covers memory profiles and your own tools ([#94](https://github.com/CoderHelm/coderhelm/pull/94)) - feat(dashboard): your own tools — write, check, approve, try and follow team tools ([#93](https://github.com/CoderHelm/coderhelm/pull/93)) - feat(dashboard): Memory redesign: agent profiles, provenance, pins, edits, recall preview, new icon ([#92](https://github.com/CoderHelm/coderhelm/pull/92)) - feat(analytics): measure in tokens, not dollars ([#91](https://github.com/CoderHelm/coderhelm/pull/91)) - feat(landing): E2E test intelligence, Redshift warehouses, analytics ([#90](https://github.com/CoderHelm/coderhelm/pull/90)) - feat(dashboard): Tests area for E2E runs, flaky and broken tests, quarantine, fixes and coverage ([#87](https://github.com/CoderHelm/coderhelm/pull/87)) - feat(dashboard): analytics that show whether Coderhelm is worth it and where it struggles ([#88](https://github.com/CoderHelm/coderhelm/pull/88)) - feat(data-sources): explain exact hidden names in the editor ([#89](https://github.com/CoderHelm/coderhelm/pull/89)) - feat(dashboard): connect and try a Redshift warehouse ([#86](https://github.com/CoderHelm/coderhelm/pull/86)) - feat(landing): maintenance, not a handoff ([#85](https://github.com/CoderHelm/coderhelm/pull/85)) - feat: live activity feed for data sources, and the landing page section ([#84](https://github.com/CoderHelm/coderhelm/pull/84)) - feat(dashboard): connect logs and databases from your AWS account ([#83](https://github.com/CoderHelm/coderhelm/pull/83)) - feat(dashboard): label planner and coding-agent lookups ([#82](https://github.com/CoderHelm/coderhelm/pull/82)) - feat(dashboard): data sources setup for the reviewer ([#81](https://github.com/CoderHelm/coderhelm/pull/81)) - chore(dashboard): generic placeholder text ([#80](https://github.com/CoderHelm/coderhelm/pull/80)) - fix(dashboard): show a rule's full match and repo on the route card ([#79](https://github.com/CoderHelm/coderhelm/pull/79)) - feat(dashboard): alert budget in tokens; pick seen alerts for text rules ([#78](https://github.com/CoderHelm/coderhelm/pull/78)) - feat(dashboard): alert budget card and match-by switch on rules ([#77](https://github.com/CoderHelm/coderhelm/pull/77)) - feat(dashboard): per-alarm rules and alarm list on alert routes ([#76](https://github.com/CoderHelm/coderhelm/pull/76)) - feat(dashboard): Post recoveries toggle on alert routes ([#75](https://github.com/CoderHelm/coderhelm/pull/75)) - feat(dashboard): notify-only option on alert routes ([#74](https://github.com/CoderHelm/coderhelm/pull/74)) - fix(dashboard): AWS page shows analysis errors, stable External ID, Teams for findings ([#73](https://github.com/CoderHelm/coderhelm/pull/73)) - feat(dashboard): Teams channel for alerts with per-route override ([#72](https://github.com/CoderHelm/coderhelm/pull/72)) - feat(dashboard): paginate runs, reviews and releases ([#71](https://github.com/CoderHelm/coderhelm/pull/71)) - feat(dashboard): alert history with a shareable page per alert ([#70](https://github.com/CoderHelm/coderhelm/pull/70)) - feat(dashboard): Alerts page for alert → pull request routes ([#69](https://github.com/CoderHelm/coderhelm/pull/69)) - feat(dashboard): write-only webhook secret for release-notes email ([#68](https://github.com/CoderHelm/coderhelm/pull/68)) - docs(dashboard): release notes run for any release tag, not only CoderHelm's ([#67](https://github.com/CoderHelm/coderhelm/pull/67)) - docs(dashboard): Require tests also makes CoderHelm write the tests ([#66](https://github.com/CoderHelm/coderhelm/pull/66)) ## September 2026 [#september-2026] ### Agents and API [#agents-and-api-1] - feat: release notes for every release tag — GitHub Release, Confluence changelog, IT email ([#95](https://github.com/CoderHelm/coderhelm-platform/pull/95)) - feat(reviewer): every review says which tests will run and where, or why none ([#94](https://github.com/CoderHelm/coderhelm-platform/pull/94)) - fix(reviewer): CI labels only for behavior changes, strictest for deploy labels ([#93](https://github.com/CoderHelm/coderhelm-platform/pull/93)) - fix(infra): pin the aws-cdk CLI so deploys never resolve "latest" from npm ([#92](https://github.com/CoderHelm/coderhelm-platform/pull/92)) - feat(reviewer): per-repo CI labels picked from the PR's changes; require tests option ([#91](https://github.com/CoderHelm/coderhelm-platform/pull/91)) - fix(reviewer): re-reviews resolve fixed threads and always report progress; @CoderHelm in any case, thread replies ([#90](https://github.com/CoderHelm/coderhelm-platform/pull/90)) - feat: dashboard re-review endpoint + Claude Opus 5.5 / Sonnet 5.5 / Fable 5.1 ([#89](https://github.com/CoderHelm/coderhelm-platform/pull/89)) - fix(reviewer): removing a Terraform lifecycle guard forces HIGH risk ([#87](https://github.com/CoderHelm/coderhelm-platform/pull/87)) - fix(reviewer): auto-release tags are ANNOTATED, never lightweight ([#86](https://github.com/CoderHelm/coderhelm-platform/pull/86)) ### Dashboard and docs [#dashboard-and-docs-1] - feat(dashboard): release notes settings + Releases page ([#65](https://github.com/CoderHelm/coderhelm/pull/65)) - feat(landing): Reviewer section — reviews, auto merge, CI labels, tests, code graph ([#64](https://github.com/CoderHelm/coderhelm/pull/64)) - fix(infra): pin the aws-cdk CLI so deploys never resolve "latest" from npm ([#63](https://github.com/CoderHelm/coderhelm/pull/63)) - feat(reviewer): PR labels + require tests settings ([#62](https://github.com/CoderHelm/coderhelm/pull/62)) - feat(reviewer): Review-now + Re-review buttons, Claude 5.5 / Fable 5.1 models ([#61](https://github.com/CoderHelm/coderhelm/pull/61)) ## August 2026 [#august-2026] ### Agents and API [#agents-and-api-2] - fix(reviewer): one dashboard record per review — armed APPROVE updated, not re-inserted ([#85](https://github.com/CoderHelm/coderhelm-platform/pull/85)) - fix(reviewer): sensitive classifier — path-precise hard override, score-only content ([#84](https://github.com/CoderHelm/coderhelm-platform/pull/84)) - fix(worker): never reset a PR's branch + 15-min health watch + approval semantics ([#83](https://github.com/CoderHelm/coderhelm-platform/pull/83)) - fix(reviewer): never assert external facts from memory — verify registry, cite CI ([#82](https://github.com/CoderHelm/coderhelm-platform/pull/82)) - feat(graph): code graph as its own API surface + precomputed browse summary ([#81](https://github.com/CoderHelm/coderhelm-platform/pull/81)) - feat(worker): code-graph lookups for the PR-maker agent (shared with reviewer) ([#80](https://github.com/CoderHelm/coderhelm-platform/pull/80)) - feat(reviewer): persistent per-repo code graph — structure the agent can query ([#79](https://github.com/CoderHelm/coderhelm-platform/pull/79)) - fix(reviewer): dedup duplicate review jobs (consume-once) — no more double reviews ([#78](https://github.com/CoderHelm/coderhelm-platform/pull/78)) - feat(reviewer): batch release tags per repo (tag_batch_minutes, default 15) ([#77](https://github.com/CoderHelm/coderhelm-platform/pull/77)) - feat(reviewer): handle native "Re-request review" button + explicit re-reviews always post ([#76](https://github.com/CoderHelm/coderhelm-platform/pull/76)) - fix(reviewer): bound the self-review-\>fix loop (convergence cap + approve hysteresis) ([#75](https://github.com/CoderHelm/coderhelm-platform/pull/75)) - fix(reviewer): auto-merge "declined" now waits + explains, not "merge manually" ([#74](https://github.com/CoderHelm/coderhelm-platform/pull/74)) - fix(reviewer): stop comment spam — comment only on verdict change + dedup gate notices ([#73](https://github.com/CoderHelm/coderhelm-platform/pull/73)) - feat(worker): PR maker adds deploy label(s) at PR creation, not the merge gate ([#72](https://github.com/CoderHelm/coderhelm-platform/pull/72)) - fix(worker): auto-merge CI verdict — cancelled ≠ failure, wait for CI to settle, post abort once ([#71](https://github.com/CoderHelm/coderhelm-platform/pull/71)) - fix(worker): read codegen result from the uploaded artifact, not the log marker ([#70](https://github.com/CoderHelm/coderhelm-platform/pull/70)) - fix(worker): a cancelled run must never be resurrected to awaiting_ci ([#69](https://github.com/CoderHelm/coderhelm-platform/pull/69)) - fix(worker): resolve PR base branch from the live PR, not the stale run record ([#68](https://github.com/CoderHelm/coderhelm-platform/pull/68)) - fix(reviewer): never review draft PRs + dedup same-head events ([#67](https://github.com/CoderHelm/coderhelm-platform/pull/67)) - fix(reviewer/implement): honest zero-change message + coalesce rapid re-reviews ([#66](https://github.com/CoderHelm/coderhelm-platform/pull/66)) - feat(reviewer): flag out-of-scope / scope-creep changes ([#65](https://github.com/CoderHelm/coderhelm-platform/pull/65)) - fix(worker): restore_file defaults to the PR base branch, not main ([#64](https://github.com/CoderHelm/coderhelm-platform/pull/64)) - feat(reviewer): support multiple deploy labels (comma-separated) ([#63](https://github.com/CoderHelm/coderhelm-platform/pull/63)) - feat(reviewer): org-aware review — org-wide instructions + cross-repo blast radius ([#62](https://github.com/CoderHelm/coderhelm-platform/pull/62)) - feat(reviewer): CoderHelm self-labels the PRs it opens ([#61](https://github.com/CoderHelm/coderhelm-platform/pull/61)) - fix(reviewer): require the trigger label for bot-authored PRs too ([#60](https://github.com/CoderHelm/coderhelm-platform/pull/60)) - fix(worker): give the implement pass the original ticket as data source-of-truth ([#59](https://github.com/CoderHelm/coderhelm-platform/pull/59)) - feat(reviewer): configurable deploy label added before merge ([#58](https://github.com/CoderHelm/coderhelm-platform/pull/58)) - fix(reviewer): enforce the bot-APPROVE key in the auto-merge gate ([#57](https://github.com/CoderHelm/coderhelm-platform/pull/57)) - feat(reviewer): armed auto-merge — waits for human approval + all-green CI (#56) ([#56](https://github.com/CoderHelm/coderhelm-platform/pull/56)) - fix(worker): stop Teams reminder spam — head-change floor, sweep card cap, visible dedup-save failures ([#55](https://github.com/CoderHelm/coderhelm-platform/pull/55)) - ci(deploy): batch prod deploys on a 10-min window instead of per-push ([#54](https://github.com/CoderHelm/coderhelm-platform/pull/54)) - feat(reviewer): agentic repo-context review + risk engine + verification + health-v2 ([#53](https://github.com/CoderHelm/coderhelm-platform/pull/53)) - fix(infra): move review-reminder schedule to API stack (dependency cycle) ([#52](https://github.com/CoderHelm/coderhelm-platform/pull/52)) - feat(reviewer): merge own PRs w/ human approval, self-review feedback, Teams reminders ([#51](https://github.com/CoderHelm/coderhelm-platform/pull/51)) - feat(reviewer): real semver release tags + auto-review CoderHelm's own PRs ([#50](https://github.com/CoderHelm/coderhelm-platform/pull/50)) - feat(reviewer): label-triggered PR reviewer agent (backend) ([#49](https://github.com/CoderHelm/coderhelm-platform/pull/49)) - fix(worker): give the feedback/review pass a surgical edit_file (shared with implement) ([#48](https://github.com/CoderHelm/coderhelm-platform/pull/48)) - feat(worker): teach the agent not to querySelector by Tailwind arbitrary-value classes ([#47](https://github.com/CoderHelm/coderhelm-platform/pull/47)) - fix(worker): run affected unit tests in the sandbox gate before opening a PR ([#46](https://github.com/CoderHelm/coderhelm-platform/pull/46)) - fix(worker): a passing workflow no longer masks a failing one (shipped red PRs) ([#45](https://github.com/CoderHelm/coderhelm-platform/pull/45)) ### Dashboard and docs [#dashboard-and-docs-2] - feat(dashboard): Code Graph section — stats, symbol search, visual explorer ([#60](https://github.com/CoderHelm/coderhelm/pull/60)) - feat(dashboard): code-graph toggle in reviewer config ([#59](https://github.com/CoderHelm/coderhelm/pull/59)) - feat(dashboard): batch-window (minutes) control for release tags ([#58](https://github.com/CoderHelm/coderhelm/pull/58)) - feat(dashboard): deploy-label help text reflects add-at-PR-creation ([#57](https://github.com/CoderHelm/coderhelm/pull/57)) - feat(dashboard): deploy label field supports multiple labels ([#56](https://github.com/CoderHelm/coderhelm/pull/56)) - feat(dashboard): org-wide review standards editor ([#55](https://github.com/CoderHelm/coderhelm/pull/55)) - feat(dashboard): persist selected repo in reviewer config URL ([#54](https://github.com/CoderHelm/coderhelm/pull/54)) - feat(dashboard): reviewer deploy-label config field ([#53](https://github.com/CoderHelm/coderhelm/pull/53)) - feat(dashboard): reviewer list as runs-style table, grouped by PR ([#52](https://github.com/CoderHelm/coderhelm/pull/52)) - feat(dashboard): search box for the health-check log-group picker ([#51](https://github.com/CoderHelm/coderhelm/pull/51)) - feat(dashboard): reviewer overhaul UI (risk breakdown, verify, health-v2, log picker) ([#50](https://github.com/CoderHelm/coderhelm/pull/50)) - feat(dashboard): reviewer Teams reminders config ([#49](https://github.com/CoderHelm/coderhelm/pull/49)) - feat(dashboard): reviewer tag mode (semver release vs date marker) ([#48](https://github.com/CoderHelm/coderhelm/pull/48)) - feat(dashboard): reviewer agent UI (config + reviews list + detail) ([#47](https://github.com/CoderHelm/coderhelm/pull/47)) ## July 2026 [#july-2026] ### Agents and API [#agents-and-api-3] - fix(worker): halt + squash CI-fix churn on stall (stop the timeout death) ([#44](https://github.com/CoderHelm/coderhelm-platform/pull/44)) - feat(repos): human-assigned repo roles to disambiguate Jira routing ([#43](https://github.com/CoderHelm/coderhelm-platform/pull/43)) - fix(worker): make Jira repo selection smart via code evidence ([#42](https://github.com/CoderHelm/coderhelm-platform/pull/42)) - fix(worker): defer on writer-slot contention instead of failing the run ([#41](https://github.com/CoderHelm/coderhelm-platform/pull/41)) - fix(auth): land invited teammates on their real team, not their personal team ([#40](https://github.com/CoderHelm/coderhelm-platform/pull/40)) - fix(worker): stop repair runs reverting user pushes ([#39](https://github.com/CoderHelm/coderhelm-platform/pull/39)) ### Dashboard and docs [#dashboard-and-docs-3] - feat(dashboard): repo role dropdown in repo settings ([#46](https://github.com/CoderHelm/coderhelm/pull/46)) ## Tagged releases [#tagged-releases] The platform was tagged during its first weeks: - [`jira-app-production`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/jira-app-production) (2026-10-24): ci: publish the Jira app automatically on every change (#278) - [`v0.6.0`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.6.0) (2026-07-23): execution sandbox: agent verifies against real build/lint/test output (+ Node-version faithfulness) - [`v0.5.1`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.5.1) (2026-07-22): squash run commits at PR creation - [`v0.5.0`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.5.0) (2026-07-22): race-safe branch writes - [`v0.4.0`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.4.0) (2026-07-22): stuck-run recovery + toolchain pin - [`v0.3.3`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.3.3) (2026-07-03): reset & re-run endpoint - [`v0.3.2`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.3.2) (2026-07-03): durable run cancellation - [`v0.3.1`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.3.1) (2026-07-03): human-closed PRs stop the run; never reopen/process - [`v0.3.0`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.3.0) (2026-07-03): restore_file tool: byte-exact file recovery without LLM round-trip - [`v0.2.4`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.2.4) (2026-07-03): awaiting_ci cap measures time-in-state - [`v0.2.3`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.2.3) (2026-07-03): stale in-flight runs no longer block ticket triggers - [`v0.2.2`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.2.2) (2026-07-03): feedback CI handoff: conflict pushes go awaiting_ci; skip path marks green draft PRs ready - [`v0.2.1`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.2.1) (2026-07-03): stale run-error clearing; re-review reopens closed PRs and strips the Partial title marker - [`v0.2.0`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.2.0) (2026-07-03): pipeline-quality overhaul: fail-closed gates, syntax gate, atomic edits, salvage, security fixes, Opus 4.8 - [`v0.1.1`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.1.1) (2026-07-03): repo routing: bare-name matches demoted to LLM hint - [`v0.1.0`](https://github.com/CoderHelm/coderhelm-platform/releases/tag/v0.1.0) (2026-07-02): repo-snapshot search, trigger gate, run-lifecycle overhaul # Agents Source: https://docs.coderhelm.com/concepts/agents The planner, the coder and the reviewer, which model each uses, and what each may touch. A run is carried out by several agents, each a Claude model with its own instructions and tools. | Agent | Does | Model setting | | --- | --- | --- | | **Planner** | Triage, the plan, and plan chat. Reads code, the code graph, memories, skills and connections; never writes. | Planning & reviews | | **Coder** | Writes the change, runs the build and tests in the sandbox, fixes CI failures and answers feedback. | Writing code | | **Reviewer** | Reviews CoderHelm's own pull requests and your team's (see [The PR reviewer](/getting-started/reviewer)). | Planning & reviews | | **Writer** | Pull request descriptions, replies to comments, and release notes. | Planning & reviews | Choose the models on **AI Models** (admins only). The models on offer are Claude Fable 5.1, Opus 5.5, Sonnet 5.5 and Haiku 4.5, plus older models for teams that pinned one. A model that Anthropic retires runs as its replacement automatically. ## What agents can touch [#what-agents-can-touch] - **Your code**: read through the GitHub App. Changes are pushed only to `coderhelm/` branches and arrive as pull requests. - **The sandbox**: builds, linters and tests run in an isolated build environment with no credentials and no access to your systems. - **Your data**: only through [data sources](/concepts/data-sources) and [team tools](/concepts/skills#team-tools), which are read-only. - **Outside tools**: only through [connections](/concepts/connections) an admin switched on. ## Team agents [#team-agents] Your team can add its own agents, written as Markdown files in a skill repo. A team agent is a specialist the main agents can ask, for example "the payments expert". Team agents answer questions with read-only tools; they never write code. See [Skills](/concepts/skills#agents). ## Instructions [#instructions] Besides skills, admins can set plain-text instructions in **Settings**, for the whole team or one repository: general instructions, rules, the voice for PR descriptions and comments, and git conventions (branch, commit and pull request title templates). # Code graph Source: https://docs.coderhelm.com/concepts/code-graph A map of each repository, where things are defined, who calls them and what imports what, used by every agent. The **code graph** is a map of a repository: where each function, class and type is defined, who calls it, and which files import which. The planner, the coder, the reviewer and CI fixes all use it, so they can follow a change through the codebase instead of guessing from file names. Open **Code Graph** to explore it: search for a symbol and see its definition, callers and neighbors. - Every repository CoderHelm works on gets a graph, and it updates on every push to the default branch. - Each repository has its own switch on the Code Graph page, separate from the reviewer. - The graph stores symbol names and references, not copies of your source files. - A build that takes more than 15 minutes is marked failed and retried on the next push. Admins can rebuild a graph by hand. # Connections Source: https://docs.coderhelm.com/concepts/connections Connect outside tools, such as your issue tracker, error tracker or CMS, as MCP servers the agents can use. **Connections** are outside tools the agents can use while they work, through the [Model Context Protocol](https://modelcontextprotocol.io) (MCP). Connect your error tracker and the planner can read the stack trace behind a ticket; connect your design tool and the coder can read the mockup. Open **Integrations**. The page groups everything CoderHelm connects to: code and tickets, cloud, monitoring, docs and design, chat (Slack or Teams), and **Other tools**, the MCP servers. Each card shows **Connected**, **Needs credentials**, **Not connected** or **Not working**. ## Built-in MCP servers [#built-in-mcp-servers] | Server | You provide | | --- | --- | | Figma | API token | | Sentry | Auth token, organization slug | | Linear | API key | | Notion | API key | | Vercel | API token | | Stripe | Secret key | | PostHog | API key, host | | GitLab | API token, base URL | | Neon | API key | | Turso | API token, organization | | Snyk | API token | | LaunchDarkly | Access token | | MongoDB Atlas | Public key, private key, project id | | Grafana | API key, base URL | | Redis | Connection URL | | Upstash | Email, API key | | Sanity | API token, project id | Connecting a server needs an admin. After connecting, use **Test** to check it works. You can add a short prompt per server telling the agents when to use it. ## How keys are kept [#how-keys-are-kept] Keys are encrypted with AWS KMS, with your team and the server bound into the encryption, so a copied value is useless anywhere else. A key is opened only at the moment a call needs it, is never returned by the API, never shown to a model, and never logged. Each server runs only from an approved list of packages, isolated from CoderHelm's own systems. ## Remote servers and OAuth [#remote-servers-and-oauth] Connecting remote MCP servers over HTTP, with OAuth sign-in instead of a pasted key, is being built as part of [plugins](/plugins/connections). Until then, every connection uses a key. # Data sources Source: https://docs.coderhelm.com/concepts/data-sources Give agents read-only access to your databases, APIs, search and logs, so they can check facts instead of guessing. A **data source** lets agents look things up in your systems while they plan, code or review: the real shape of a table, what an API returns, what an error log says. Every data source is read-only, and the setup checks that before it can be switched on. Open **Data sources** (admins only). | Kind | Examples | | --- | --- | | API | A GraphQL API | | REST API | Any JSON API, read with GET | | Database | PostgreSQL, or a Redshift warehouse | | Search | OpenSearch | | Logs | CloudWatch Logs | ## Connect one [#connect-one] **Data sources** → **Connect** walks through five steps: 1. **Give read-only access**: create a read-only user or key, or for AWS, a role in your account (a CloudShell script does it for you). 2. **Choose what to share**: tables, indexes, endpoints or log groups. 3. **Choose what it may use**: which agents and repositories can read it. 4. **Try it**: run a real lookup and see the answer. 5. **Check and turn on**: CoderHelm checks, for example, that the database user can only read. Keys are encrypted with a key bound to your team, opened only for the call that needs them, and never shown again. Every lookup an agent makes is listed under **Data sources** → **Activity**. For lookups your team uses often, define a [team tool](/concepts/skills#team-tools). # How CoderHelm works Source: https://docs.coderhelm.com/concepts The pieces of CoderHelm and how they fit together, on one page. CoderHelm has two parts: a **gateway** that receives events (a labeled issue, a Jira comment, a new push) and serves the dashboard's API, and a **worker** that does the work. Each piece of work is a message on a queue, so a slow run never blocks anything else. ```txt GitHub / Jira / alerts ──► gateway ──► queue ──► worker ──► agents ──► pull request ▲ │ dashboard ──────────┘ └── your code, code graph, memories, skills, data sources, connections ``` | Concept | In one line | | --- | --- | | [Agents](/concepts/agents) | The planner, the coder and the reviewer, each with its own model and tools. | | [Skills](/concepts/skills) | Your team's instructions in Markdown, read from a git repo. | | [Memories](/concepts/memories) | What CoderHelm has learned about each repository. | | [Code graph](/concepts/code-graph) | A map of where things are defined and who calls them. | | [Data sources](/concepts/data-sources) | Read-only access to your databases, APIs, search and logs. | | [Connections](/concepts/connections) | Outside tools (MCP servers) the agents can use. | | [Knowledge bases](/concepts/knowledge) | Documents the agents can search, and a chat that answers from them. | | [Roles](/concepts/roles) | Who on the team can do what. | | [Token limits](/concepts/token-limits) | Monthly caps on new tokens, cache reads and cache writes. | | [Usage and audit](/concepts/usage-and-audit) | What CoderHelm did and what it cost. | Everything CoderHelm reads from your systems is read-only unless a page here says otherwise. Code changes always arrive as a pull request you can review. # Knowledge bases and brain chat Source: https://docs.coderhelm.com/concepts/knowledge Upload documents the agents can search, and ask questions answered from your team's own sources with a citation on every claim. > Coming soon: this page describes work that is not on main yet. This feature is being built and is not on main yet. This page describes it as it is being built and will change before it ships. ## Knowledge bases [#knowledge-bases] A **knowledge base** is a set of documents your team uploads: specs, runbooks, policies, product docs. Admins create bases and upload files (PDF, Word, Markdown, text, CSV, Excel and HTML, up to 25 MB each and 500 files per base). Each file shows as uploading, processing, ready, or failed with the reason. A base can be attached to the whole team or to specific agents (planner, coder, reviewer, plan chat). Attached agents get a tool to search it, so a plan can follow your runbook instead of guessing. A base can be marked as a source of truth, and has its own read role (viewers, members or admins). ## Brain chat [#brain-chat] **Brain** is a chat that answers questions from your team's own sources: knowledge bases, connections, repositories, memories, data sources and skills. You pick which sources to use. - Every claim in an answer has a numbered citation. Click it to see the passage it rests on, where it comes from, and how current it is. - When nothing in the chosen sources supports an answer, it says so ("Not in your sources") instead of making one up. - You can attach a file to a question. - Threads are private until their owner shares them with the team. Viewers can read shared threads, members can ask, and admins manage knowledge bases. Brain's model calls are metered under their own name on the usage page, and count toward your [token limits](/concepts/token-limits). # Memories Source: https://docs.coderhelm.com/concepts/memories What CoderHelm knows about each repository, where it learned it, and how to teach or correct it. CoderHelm keeps **memories** for each repository: short facts it has learned, such as "API handlers return errors as `{ error: string }`" or "never edit the generated client in `src/gen`". The planner and the coder read them on every ticket. Open **Memory** (under Insights) to see them. ## Kinds [#kinds] | Kind | Example | | --- | --- | | How things are done here | Feature flags are added in `flags.ts` and default to off. | | Code style | Use named exports; no default exports. | | How the code is built | The worker and the API share types from `packages/types`. | | Things to avoid | Don't call the payments API from the browser. | | Corrections | The settings page is `settings/page.tsx`, not `account/page.tsx`. | | Other things it learned | Anything else. | ## Where memories come from [#where-memories-come-from] - **From tickets**: when a pull request is closed without merging, or someone says the fix belonged somewhere else, CoderHelm writes down what it got wrong. - **From people**: an admin clicks **Teach it something** and writes one. ## What agents get [#what-agents-get] On each ticket, the planner and the coder get every **pinned** memory, plus the five most relevant others. Pin a memory when every change should know it. ## Change or remove [#change-or-remove] Admins can edit a memory, pin or unpin it, or click **Forget it** to delete it. Filter by All, Pinned, From tickets or From people, and sort by newest or most used. # Roles and permissions Source: https://docs.coderhelm.com/concepts/roles The built-in roles, custom roles your team makes, and the capability behind every action. Everyone on a team has one role. Change roles on **Members** (Settings → Team); the page also shows the full table of who can do what. ## Built-in roles [#built-in-roles] | Role | Can | | --- | --- | | **Viewer** | Read everything on the team; change nothing but their own account. | | **Member** | Work with CoderHelm: plans, runs, reviews and recommendations. | | **Admin** | Run the workspace: repos, integrations, agent settings, the token limit and people. | | **Owner** | Everything, plus account-level changes and managing admins. | ## Capabilities [#capabilities] Every request to CoderHelm is checked in one place, on the server, against the capability its action belongs to. Each capability has a lowest built-in role that holds it. | Lowest role | Capabilities | | --- | --- | | Viewer | `view`, `view_team`, `own_account` | | Member | `plans`, `runs`, `reviews`, `recommendations`, `view_alerts`, `view_integrations` | | Admin | `people`, `roles`, `delete_plans`, `repos`, `agent_settings`, `memory`, `integrations`, `data_sources` (includes team tools and skills), `tests`, `alerts`, `model_provider`, `system`, `budget`, `support` | | Owner | `manage_admins`, `team_name`, `disconnect` (removes Jira or the model key), `reset` | A request without the capability it needs gets `403`, with the name of the missing capability. ## Custom roles [#custom-roles] When the built-in roles don't fit, make your own. For example, a "Release manager" who is a member but can also change reviewer and repository settings, or an "Analyst" who can read everything and manage data sources. 1. On **Members**, under **Custom roles**, click to create a role. 2. Give it a name and a description, start from Viewer, Member or Admin, and tick the capabilities it should hold. New capabilities CoderHelm adds later appear in the editor by themselves. 3. Give the role to people from the role selector, or pick it when you invite someone. The rules, enforced on the server: - Only built-in admins and owners create, edit, delete or give custom roles. A custom role can never manage roles itself. - Owner-only capabilities (account changes, managing admins and owners, renaming the team, reset, disconnecting) and `support` are never offered in a custom role. - Nobody can create, edit or give a role that holds more than they hold, or change someone whose role holds more than theirs. - Deleting a role that people hold asks which role they move to. - Every role created, edited, deleted or given out is recorded in **Role changes**, kept for a year. Everyone else on the team can see the custom roles and what each one can do. A change to a role applies within 30 seconds. ## Invites and approvals [#invites-and-approvals] Invites expire after 30 days; admins can resend them. Some actions need a second person, even an admin: approving a new version of a [team tool](/concepts/skills#team-tools) needs another admin when the team has more than one. # Skills Source: https://docs.coderhelm.com/concepts/skills Teach CoderHelm your team's conventions with Markdown files in a git repo, in the same layout Claude Code uses. A **skill** is a Markdown file of instructions, such as "how we write database migrations" or "our API error format". CoderHelm reads skills from git repositories you connect, and the agents read the ones that matter for each task. Open **Skills** to connect a repository and see every item it holds. ## Repo layout [#repo-layout] CoderHelm reads three kinds of item from a repository's default branch. Each can also sit under `.claude/`, so a repo you already use with Claude Code works as it is. | Kind | Path | What it is | | --- | --- | --- | | Skill | `skills//SKILL.md` | Instructions, plus text files next to it (examples, templates). | | Agent | `agents/.md` | A specialist the main agents can ask. Its body is its instructions. | | Command | `commands/.md` | A named procedure, such as a checklist. | Nothing in a skill repo is ever run. Scripts next to a skill are read as text, never executed. ## Frontmatter [#frontmatter] ```md title="skills/migrations/SKILL.md" --- name: migrations description: How to write a database migration in this codebase. Read before changing any table. --- # Migrations - One migration per pull request. - Every migration has a down step... ``` | Field | Type | Default | Notes | | --- | --- | --- | --- | | `name` | string | The folder name (skills) or file name (agents, commands) | Lowercased; characters other than `a-z 0-9 - _ .` become `-`; up to 64 characters. | | `description` | string | The first line of the body that is not a heading | Up to 240 characters. Agents choose skills by their description, so make it say when to use the skill. | | `tools` or `allowed-tools` | list, or one string split by commas | none | Claude Code tool names, mapped to CoderHelm's own (below). | | `model` | string | none | Agents only. A hint for which model answers. | Claude Code tool names map like this: `Read` → read files, `Edit`/`MultiEdit` → edit files, `Write` → write files, `Grep` → search code, `Glob`/`LS` → list files. Others (shell, web, notebooks, sub-agents) have no equivalent and are reported as missing. ## Limits [#limits] | Limit | Value | | --- | --- | | Repos per team | 5 | | Items per repo | 200 | | Size of one item | 64,000 bytes | | Size of a file next to a skill | 32,000 bytes | | Files per skill | 20 | | Total per repo | 2,000,000 bytes | Files next to a skill must be text (Markdown, JSON, YAML, SQL, code and similar). Anything skipped is listed with the reason. ## Syncing and pinning [#syncing-and-pinning] A repository syncs when you connect it, on every push to its default branch, and when an admin clicks **Sync now**. Only merged code on the default branch is read; pushes to other branches are ignored. Each item records the commit it was read at and a hash of its content, so you can always see exactly which version an agent used. ## The compatibility check [#the-compatibility-check] Skills written for Claude Code often mention tools CoderHelm doesn't have. After each sync, CoderHelm checks every step of every item against your team's real tools, connections and data sources, and marks each requirement: - **Available**: CoderHelm can do it. - **Translated**: it can, with a different tool (named). - **Missing**: it needs something you haven't connected, with what to connect. - **Blocked**: it needs to write somewhere no connected tool can. The check runs again only when the text or your tools change. An admin can choose to use the translated version of an item. ## Always apply [#always-apply] By default agents see a list of skills and read the ones they need. An admin can mark a skill or command **Always apply** so it is given in full, choosing the repositories, the agents (planner, coder, reviewer, PR descriptions, review comments, replies, release notes) and file paths it applies to. Agents can also join reviews as steps (plan, code or prose). ## Agents [#agents] A team agent answers questions from the main agents, in one turn. It only gets read-only tools, worked out from its own `tools:` list; write tools are always blocked. An agent with no `tools:` gets none. Admins can try an agent from its page under **Skills**. ## Team tools [#team-tools] A **team tool** is a named, typed lookup, such as "find an order by id", that agents can call. Each tool reads one [data source](/concepts/data-sources) with a fixed query (SQL, GraphQL, a logs query or an HTTP GET), and its inputs are typed and checked before they are bound into the query, never pasted into it. Find them under **Data sources** → **Team tools**. Define one in the dashboard, or commit it as `.coderhelm/tools/.yaml` on a default branch; a pushed file becomes a proposal and is never switched on by itself. ```yaml title=".coderhelm/tools/order_by_id.yaml" name: order_by_id use_when: You need an order's status and total from its id. source: orders-db kind: sql read: SELECT id, status, total FROM orders WHERE id = :order_id inputs: order_id: type: integer min: 1 example: 1042 max_rows: 1 ``` Every version runs once with its examples, and then another admin must approve that exact version (a team with one admin approves its own). Any edit makes a new version that needs approval again. A tool can also be set to **ask me first**, so each call waits for a person's yes (for up to ten minutes). # Token limits Source: https://docs.coderhelm.com/concepts/token-limits Monthly caps on new tokens, cache reads and cache writes, so a busy month never surprises you. Your team pays Anthropic directly for the tokens CoderHelm uses. **Token limit** (under Account) sets monthly caps so usage can't run away. There are three limits, because the three kinds of token cost very different amounts: | Limit | What it counts | | --- | --- | | **New tokens (input + output)** | Tokens sent to the model for the first time, plus everything the model writes. | | **Cache read tokens** | Input the model reads back from its prompt cache. Much cheaper than new input. | | **Cache write tokens** | Input written into the prompt cache so later calls can read it. | A run re-reads the same code and instructions many times, so most of its input is cache reads. Splitting the limits lets you set a tight cap on the expensive kind without stopping runs over cheap cache reads. ## How limits work [#how-limits-work] - Leave a limit blank (or 0) for no limit. - Each limit is checked on its own. The first one reached pauses new work until the next month starts (UTC). - CoderHelm sends a warning email when a limit reaches 80%, and again at 100%. - The status at the top of the page reads **Under the limits**, **Near a limit** or **Limit reached**. When a limit stops a ticket, CoderHelm comments on it, for example: "You've reached this month's **cache write** limit (… of …). Raise or clear that limit in Settings → Token Limit to continue." Only admins can change limits. Teams that set a single limit before the split keep it until they save the new fields. ## Example [#example] A team that wants to spend at most about the price of 20 million new tokens a month, without counting cheap re-reads, might set: | Limit | Value | | --- | --- | | New tokens | 20,000,000 | | Cache read tokens | blank (no limit) | | Cache write tokens | 10,000,000 | See [Usage and audit](/concepts/usage-and-audit) for where each token went. # Usage and audit Source: https://docs.coderhelm.com/concepts/usage-and-audit What CoderHelm delivered, the tokens it used, and the records of what it looked at and changed. ## Analytics [#analytics] Open **Analytics** for the last 7, 30 or 90 days, or this month, for all repositories or one: - **Is it worth it**: pull requests merged, merge rate, median time to merge, tokens per merged pull request, pull requests merged as written, red CI fixed by CoderHelm, review findings acted on, and failed runs. - **Pull requests opened and merged per day**, and **tokens per day**. Token counts cover all four parts of every model call (new input, cache reads, cache writes and output), including streamed and failed calls. - **Where it struggles**: failed runs grouped by reason, each linked to its run. - **Reviews**: reviews posted and findings raised, by repository. - **Where tickets come from** and **who asks for work**. Each period is compared with the one before it, with notes on what changed. ## Records of what happened [#records-of-what-happened] | Record | Where | What it shows | | --- | --- | --- | | Run log | **Runs** → a run | Every step, tool call and decision in a run. | | Skills activity | **Skills** → Activity | Which agent read which skill, and when. | | Data source activity | **Data sources** → Activity | Every lookup in your systems, by which agent, with what result. | | Auto-merge gate | **Reviewer** → a pull request | Each approval, stop and re-arm, and who did it. | | Support access | **Settings** → **Support access** | When CoderHelm support viewed your workspace (read-only, only after you grant it). | A single audit log that brings these together, and records every plugin action, is being built with [plugins](/plugins/security). # Your first run Source: https://docs.coderhelm.com/getting-started/first-run What CoderHelm does between a ticket and a pull request, stage by stage, and where to watch it. A **run** is one piece of work: one ticket turned into one pull request. Open **Runs** to see every run with its status, and click one for its live log. ## The stages [#the-stages] The run detail page shows each stage as it happens. | Stage | What happens | | --- | --- | | **Triage** | Reads the ticket and its attachments, checks the ticket is clear enough to act on, and picks the repository. | | **Plan** | Searches the code, the [code graph](/concepts/code-graph), [memories](/concepts/memories) and [skills](/concepts/skills), and writes a plan: which files change and how. | | **Build** | Writes the change on a new `coderhelm/` branch. | | **Test** | Runs your build, linter and tests in a sandbox with no credentials, and fixes what fails. | | **Security** | Checks the change for security problems, such as secrets in code or unsafe input handling. | | **Pull request** | Opens a draft pull request that explains the change, links the ticket, and is marked ready when the checks pass. | | **Review** | Reviews its own pull request the way the [PR reviewer](/getting-started/reviewer) reviews yours. | After the pull request is open, two more stages can run: - **CI fix**: if your CI fails on the pull request, CoderHelm reads the failure and pushes a fix. It gives up after 8 automatic fix pushes, so a broken pipeline can't loop forever. - **Feedback**: comment on the pull request (or the ticket) and CoderHelm makes the change you asked for. ## When a run stops [#when-a-run-stops] A run can end without a pull request. The run page always says why in plain words, for example "The ticket doesn't say which page to change". Answer on the ticket and the run starts again. You can also **Retry**, **Reset and re-run** from scratch, or **Cancel** from the run page. New runs also pause when your team reaches a [token limit](/concepts/token-limits). ## Make runs better [#make-runs-better] - Write tickets with a clear goal and a way to check it. - Add [skills](/concepts/skills) with your team's conventions. - Pin [memories](/concepts/memories) for things every change should know. - Set team and repository instructions in **Settings**. # Connect GitHub Source: https://docs.coderhelm.com/getting-started/github Install the CoderHelm GitHub App, choose repositories and give each one a role. CoderHelm works through a GitHub App. The app reads code, opens branches and pull requests, comments on issues and reads CI results. It acts as the `coderhelm` bot, so everything it does is visible in your repository's history. ## Install the app [#install-the-app] 1. In the dashboard, open **Integrations** → **GitHub** and click **Install**. This opens GitHub's install screen for the CoderHelm app. 2. Pick the organization, then **All repositories** or **Only select repositories**. 3. Confirm. Back in the dashboard you see "Connected to *your-org*. *N* repositories synced." If you are not an owner of the organization, GitHub sends an installation request to the owners instead. The dashboard says so, and finishes connecting once an owner approves. To add or remove repositories later, change the app's repository access in GitHub (**Settings** → **GitHub Apps** → **CoderHelm** → **Configure**). CoderHelm picks up the change automatically. ## What the app can do [#what-the-app-can-do] | Permission | Access | Why | | --- | --- | --- | | Contents | Read and write | Read the code, push the `coderhelm/` branch | | Issues | Read and write | Read tickets, comment with progress | | Pull requests | Read and write | Open pull requests, post reviews | | Checks | Read | Read CI results to fix failures | | Metadata | Read | Required by GitHub for every app | It listens for issues, issue and review comments, pull requests and reviews, check runs and suites, workflow runs, pushes and installation changes. Pushes to the default branch keep [skills](/concepts/skills), [team tools](/concepts/skills#team-tools) and the [code graph](/concepts/code-graph) up to date. ## Choose repositories and roles [#choose-repositories-and-roles] Open **Repos**. Every repository the app can see is listed. Switch on the ones CoderHelm should work on. A repository that is off is never changed. Give each repository a **role**, such as `web` or `backend`. A Jira ticket doesn't name a repository, so CoderHelm uses the roles, the ticket's text and your code to pick the right one. A ticket about a broken checkout button goes to the repository with the `web` role, not the API. ## Start a run from GitHub [#start-a-run-from-github] Any of these starts a run on an issue: - Add the label `coderhelm` (any capitalization). - Assign the issue to the CoderHelm bot. - Comment `/coderhelm` at the start of a comment, or mention `@coderhelm` anywhere in one, followed by what you want. CoderHelm never starts a second run while one is already working on the same ticket. Editing a ticket whose pull request is still open sends the edit to that pull request as feedback instead of starting over. # Quickstart Source: https://docs.coderhelm.com/getting-started From a new account to your first CoderHelm pull request in about ten minutes. This page takes you from a new account to a pull request that CoderHelm opened for you. You need admin rights on a GitHub organization (or your own account) and an Anthropic API key. ### Create your account [#create-your-account] Go to [app.coderhelm.com](https://app.coderhelm.com) and sign up with email, Google or GitHub. CoderHelm is in a closed beta: if you see **Join waitlist**, leave your email and you will get an invite. If your GitHub organization already uses CoderHelm, don't create a new workspace. Ask one of its admins to invite you from **Members**. ### Add your Anthropic API key [#add-your-anthropic-api-key] Open **AI Models** in the sidebar (under Configure) and paste your key into **Anthropic API key**. Every model call CoderHelm makes for your team uses this key, so the usage shows up on your own Anthropic bill. On the same page you choose the model for each part of a run: | Part | What it does | Recommended | | --- | --- | --- | | Planning & reviews | Triage, the plan, the self-review and the PR reviewer | Claude Sonnet 5.5 | | Writing code | Writing and fixing the change | Claude Opus 5.5 | Changes apply from the next run. ### Connect GitHub [#connect-github] Open **Integrations**, choose **GitHub** and click **Install**. GitHub asks which repositories CoderHelm may see. Then open **Repos** and switch on the repositories CoderHelm should work on. Details: [Connect GitHub](/getting-started/github). ### Ask for a change [#ask-for-a-change] In one of those repositories, open an issue that describes a small, concrete change. For example: ```md title="Issue: Show the build date in the footer" The site footer should show "Built on " using the date of the build. It should use the same small gray text as the copyright line. ``` Then either add the label `coderhelm` or assign the issue to the CoderHelm bot. Either one starts a run. ### Watch the run [#watch-the-run] Open **Runs** in the dashboard. The run moves through Triage, Plan, Build, Test, Security, Pull request and Review. When it is done there is a draft pull request on a `coderhelm/` branch, linked from the issue and from the run. What each stage does: [Your first run](/getting-started/first-run). ## Next steps [#next-steps] - [Connect Jira](/getting-started/jira) to start runs from Jira tickets. - Turn on the [PR reviewer](/getting-started/reviewer) for your team's own pull requests. - Use [Plans](/getting-started/plans) to split a bigger change into tickets. - Set [token limits](/concepts/token-limits) so a busy month cannot surprise you. # Connect Jira Source: https://docs.coderhelm.com/getting-started/jira Start CoderHelm runs from Jira tickets with the Jira app or a Jira webhook. You can start runs from Jira tickets. CoderHelm reads the ticket (including screenshots attached to it), picks the repository, and posts its progress and the pull request link back on the ticket. Open **Integrations** → **Jira**. Under **How to connect** there are two ways. The Jira app is installed in your Atlassian site. It sends ticket events to CoderHelm, posts comments back, and lets CoderHelm read and create tickets for [plans](/getting-started/plans). It can also read Confluence pages and publish release notes there. 1. **Install the Jira app.** Use the link on the Jira page of the dashboard. You need to be a Jira admin. 2. **Paste your Team ID and secret.** The dashboard shows both. In Jira, open the app's **Coderhelm Settings** admin page and paste them. This links your Jira site to your CoderHelm team. 3. **Label and assign a ticket.** See below. The app listens for tickets being created, assigned, updated and commented on. If you can't install apps in your Jira site, use a plain Jira webhook instead. 1. On the Jira page of the dashboard, generate webhook credentials. You get a URL of the form `https://api.coderhelm.com/webhooks/jira/` and, optionally, a secret. 2. In Jira, go to **Settings** → **System** → **WebHooks** and create a webhook with that URL. Select the issue events (created, updated) and comment events (created). 3. If you generated a secret, add it to the webhook so Jira signs each request. With a webhook, CoderHelm can't post comments back to the ticket or create tickets, so progress shows only in the dashboard. ## Choose projects [#choose-projects] On the same page, switch on the Jira projects CoderHelm should listen to. Tickets in other projects are ignored. If you never change the project list, every project is allowed. ## Start a run from Jira [#start-a-run-from-jira] Add the label `coderhelm` to a ticket and assign it to the CoderHelm user. In practice either one is enough: the label (or any label starting with `coderhelm:`), or an assignee whose name contains "CoderHelm". Write the ticket the way you would for a new teammate: what should change, where it shows up, and how to know it works. Screenshots and mockups help; CoderHelm reads them. A comment on the ticket is handled too. If the run failed, a comment retries it. If the run already opened a pull request, the comment is sent to that pull request as feedback. A status or field change on its own never starts a run. # Plans Source: https://docs.coderhelm.com/getting-started/plans Describe a bigger change in your own words; CoderHelm reads your code and drafts a plan of tickets you can edit before anything runs. A **plan** turns a change too big for one ticket into an ordered list of tasks. Each task becomes a GitHub issue or a Jira ticket, and each one becomes a run. ## Make a plan [#make-a-plan] 1. Open **Plans** → **New plan**. 2. Answer **What do you want to change?** in your own words. For example: "Let people export their invoices as CSV from the billing page." 3. CoderHelm reads your code (and any connected tools, such as your issue tracker or docs) while it writes. You see the plan appear as it streams, and you can keep chatting to change it. 4. Pick where the tasks go: **GitHub Issues**, or **Jira Tickets** once Jira is connected. 5. Click **Save plan**. You can also start from a **template**: save a plan you like as a template, then reuse it from **Templates**. ## Approve and run [#approve-and-run] Open the plan. It has an overview, the tasks, the runs and pull requests made from it, a spec, and a list of what the chat looked at. - **Approve all and start** creates every ticket and starts the runs in order. - Or approve tasks one by one. Approving the last one starts the plan. Nothing is created in GitHub or Jira, and no code changes, until you approve. # The PR reviewer Source: https://docs.coderhelm.com/getting-started/reviewer Turn on CoderHelm's reviewer for your team's pull requests, and control what it checks, when it merges and what it learns. The reviewer reviews pull requests written by people (and by CoderHelm). It posts a real GitHub review, either **Approve** or **Request changes**, with comments on the lines that matter, and a risk level of low, medium or high. Changes that touch migrations, authentication, secrets or payments are always rated high. ## Turn it on [#turn-it-on] 1. Open **Reviewer** → **Reviewer settings** and pick a repository. 2. Switch on **Enable reviewer for this repo**. 3. Keep the **Trigger label** `ch-review`, or change it. Add the label to a pull request to get a review. Once a pull request has the label, every new push is reviewed again. Draft pull requests are skipped until they are marked ready. ## Talk to it on a pull request [#talk-to-it-on-a-pull-request] | Comment | What happens | | --- | --- | | `@coderhelm re-review` | Reviews the latest commit again. GitHub's **Re-request review** button does the same. | | `@coderhelm ` | Answers a question about the change, in the thread. | | `@coderhelm stop auto-merge` | Stops an automatic merge. The stop holds until someone resumes it. | | `@coderhelm resume auto-merge` | Re-arms auto-merge; every check is evaluated again from the start. | ## Settings [#settings] | Section | What you can set | | --- | --- | | Reviews | On or off, trigger label, what to focus on | | Tests | Check the change by running tests; require tests | | CI labels | Labels it may add, labels that must go together, guidance | | Auto-merge | Merge when it approves, merge method, deploy labels, also require a person's approval | | Tags and health check | Tag after merge, tag style and prefix, batch window, health check after merge | | Release notes | Where notes are written: GitHub, a Confluence page, a webhook; a writing guide | | Review reminders | Remind people in Slack or Teams | ## Auto-merge is careful [#auto-merge-is-careful] When auto-merge is on, CoderHelm merges only the exact commit it reviewed and approved, and only after CI passes. A new push means a new review. If anyone stops it, it stays stopped until a person re-arms it. ## It learns from pushback [#it-learns-from-pushback] When someone disagrees with a review (replies under a comment, dismisses the review, merges anyway, or closes the pull request unmerged), CoderHelm waits ten quiet minutes and then decides whether the review was wrong. If it was, it writes one general lesson for that repository or the whole team, and uses it in later reviews. Admins can read and delete lessons on the **Reviewer** page. People can also rate any review with a thumbs up or down. ## Release notes [#release-notes] With release notes on, every release tag gets notes written from the merged pull requests, published to GitHub and, if you set them up, Confluence and email. They are listed on the **Releases** page. # CoderHelm documentation Source: https://docs.coderhelm.com/ Guides and reference for CoderHelm, the AI agent that turns tickets into pull requests, reviews code, and stays on the code after the PR. CoderHelm is an AI coding agent for teams. Assign it a GitHub issue or a Jira ticket and it opens a pull request: it reads your code, plans the change, writes it, runs your build and tests, reviews its own work, and keeps fixing until CI is green. It also reviews your team's pull requests, writes release notes, and watches your logs and tests for problems worth fixing. You bring your own Anthropic API key, so the model calls are billed to you directly and you choose which Claude model does each part of the work. ## Start here [#start-here] Sign up, add your model key, connect GitHub and get your first pull request. Agents, skills, memories, the code graph and the rest, explained. Package instructions, agents and tools for marketing, support or any other team. Run CoderHelm in your own AWS account. Authentication, webhooks and every route the gateway serves. What changed, month by month. ## For agents and tools [#for-agents-and-tools] Every page on this site is also plain Markdown. Add `.md` to a page's URL (for example [/getting-started.md](/getting-started.md)), or send the header `Accept: text/markdown`. The index of all pages is at [/llms.txt](/llms.txt) and the whole site in one file is at [/llms-full.txt](/llms-full.txt). # Budgets and metering Source: https://docs.coderhelm.com/plugins/budgets Every model call a plugin makes is metered and counted against its own monthly limit and the team's. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. Every model call a plugin run makes is metered, like every other call CoderHelm makes, and paid for with the team's own model key. ## A limit for the plugin [#a-limit-for-the-plugin] ```yaml budget: monthly_tokens: 2000000 ``` `monthly_tokens` is the plugin's own monthly limit. The team can change it on the plugin's page under **Monthly token limit**, where it also sees **Tokens used this month**; empty or 0 means no limit of its own. The plugin's usage counts toward the team's [token limits](/concepts/token-limits) too. When either is reached, the plugin stops starting runs until next month, and a run it would have started shows as refused with the reason. ## Keep runs cheap [#keep-runs-cheap] - Put stable text (brand guide, checklists) in skills: on later calls it is read from the prompt cache, which costs far less than new input. - Tell scheduled agents to stop early when there is nothing to do. - Allow only the tools the plugin needs; every tool's description is part of the prompt. # Connections and OAuth Source: https://docs.coderhelm.com/plugins/connections Ask each team to connect the accounts your plugin needs. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. A plugin that saves drafts in a CMS or posts to LinkedIn needs an account to do it with. Declare it as a `connection` setting: ```yaml settings: - key: linkedin type: connection provider: oauth2 scopes: [w_member_social] - key: sanity type: connection provider: mcp ``` `provider` says how the account is connected: `oauth2` signs in with the service, and `mcp` uses an MCP server from the team's **Connections** page. With plugins on, Connections is its own page in the dashboard, listing every MCP server the team has connected and its status. ## Installing grants nothing [#installing-grants-nothing] Installing a plugin never gives it access to anything. The team connects each account separately, and a plugin can only use the tools its manifest grants on that connection: an MCP connection exposes only the tool names in the plugin's `allow` list. ## Tokens stay out of the model [#tokens-stay-out-of-the-model] Connection tokens are sealed like other secrets, added to a request after the model has chosen the call, and never shown to a model or sent back to the dashboard. ## Scopes [#scopes] List the narrowest OAuth scopes the plugin needs. A new version that asks for a new scope or a new connection waits for an admin. # What a plugin is Source: https://docs.coderhelm.com/plugins A plugin packages instructions, agents, tools, triggers and outputs so CoderHelm can do work for any team, with the same safety it applies to code. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. A **plugin** lets a team other than engineering put CoderHelm to work: marketing, support, sales operations, anyone. It brings its own instructions, agents and tools, says what starts it and what it produces, and CoderHelm runs it with the same safety it applies to code: pinned versions, a person's approval before anything goes out, metered tokens and a full record of every step. For example, the [marketing plugin](/plugins/walkthrough) reads each release, drafts a blog post, three LinkedIn posts and an email in the team's brand voice, and waits for an editor to approve one before anything is published. ## A plugin is text plus approved tools [#a-plugin-is-text-plus-approved-tools] A plugin is a folder in a git repo with a small manifest, `plugin.yaml`. It contains no code that CoderHelm runs. - **Skills and agents** are Markdown, in the same format as [skill repos](/concepts/skills) and Claude Code. They are the plugin's behavior. - **Tools** are declared in the manifest, each with a risk level. A tool that isn't declared does not exist for the plugin. - **Settings** are the values each team fills in: a brand guide, an account to post from. - **Triggers** say what starts a run: a person's brief, a schedule, a release. - **Outputs** say what a run produces: drafts to review, and what may be published once approved. ```yaml title="plugin.yaml" name: marketing version: 1.0.0 description: Drafts launch posts from each release for an editor to approve. tools: - ref: mcp:sanity allow: [query_documents, create_draft] risk: write triggers: - on: github.release outputs: - type: draft kinds: [blog, social] ``` Adding a plugin needs no deploy and no code from CoderHelm. Every field is listed in the [manifest reference](/plugins/manifest-reference). ## How a run works [#how-a-run-works] ```txt trigger (brief, schedule, release) └─► plugin run ─► agent with only the granted tools ─► drafts └─► approval ─► publish now or at a set time ``` 1. A trigger starts a run, with the plugin's pinned version, the inputs and who asked. 2. The plugin's agent works with exactly the tools the manifest grants. A repository is optional. 3. What it makes is saved as **drafts** in the review queue (**Plugins** → **Review**). 4. A person approves a specific version of a draft. Only then can a consequential tool, such as publish, run. ## Words used in these docs [#words-used-in-these-docs] | Word | Meaning | | --- | --- | | Plugin | The package: a repo with `plugin.yaml`. | | Source | A git repository plugins come from. An admin adds it on the Plugins page. | | Install | An admin adds a plugin from a source to the team, pinned to an exact version. | | Connection | An outside account the plugin uses (a CMS, LinkedIn). Connected separately from installing. | | Run | One piece of work by a plugin. | | Draft | Something a run made, waiting for review. | | Approval | A person's yes for one exact version of a draft. | ## In the dashboard [#in-the-dashboard] | Page | What it is for | | --- | --- | | **Plugins** | Installed plugins, plugins you can install, plugin sources, and what plugins may do without a person. | | A plugin's page | Its skills, agents and tools; settings; who approves; its monthly token limit; writing a brief. | | **Review** | Drafts waiting for approval. | | **Runs** | Every plugin run and what it produced. | | **Audit log** | Every plugin step in one place. | | **Connections** | The MCP servers your team has connected. A plugin declares which connections it needs; it is not itself a connection. | Plugins are switched on team by team. Until then these pages say "Plugins are not turned on for this team". ## Next [#next] - [Build the marketing plugin](/plugins/walkthrough), start to finish. - [Repo layout](/plugins/layout) and the [manifest reference](/plugins/manifest-reference). - [Security rules](/plugins/security) every plugin runs under. # Repo layout Source: https://docs.coderhelm.com/plugins/layout Where each file of a plugin goes. The layout matches Claude Code plugins and CoderHelm skill repos. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. A plugin is one git repository (or one folder of a [marketplace](/plugins/marketplace) repo) with `plugin.yaml` at its root. | Path | What it is | | --- | --- | | `plugin.yaml` | The manifest. Required. See the [manifest reference](/plugins/manifest-reference). | | `skills//SKILL.md` | Instructions the plugin's agents read, with optional text files next to them. Same format as [skills](/concepts/skills#frontmatter). | | `agents/.md` | The agents that do the work. The body is the agent's instructions; `tools:` in the frontmatter lists the tools it uses. | | `README.md` | For people: what the plugin does and what it needs. Not read by agents. | The `skills` and `agents` fields in the manifest default to `skills/*/SKILL.md` and `agents/*.md`. Change them if your files live elsewhere, for example to share a folder with a Claude Code plugin under `.claude/`. ## Limits [#limits] The same limits as skill repos apply: up to 200 skills and agents, 64,000 bytes per file, 32,000 bytes per file next to a skill, and 2,000,000 bytes in total. ## What doesn't go in the repo [#what-doesnt-go-in-the-repo] Each team's own values never live in the plugin: brand documents, account ids, keys, approvers. They are [settings](/plugins/settings), filled in by each team when it installs the plugin. That is what lets one public plugin serve many teams. # Manifest reference Source: https://docs.coderhelm.com/plugins/manifest-reference Every field of plugin.yaml, with its type, default and rules. Rendered from the same JSON Schema that the validator uses. > Coming soon: this page describes work that is not on main yet. A plugin is described by one file, `plugin.yaml`, at the root of its repo. This page is generated from the manifest's JSON Schema, published at a stable URL: ```txt https://docs.coderhelm.com/schema/plugin-manifest.v1.json ``` Point your editor at it for completion and inline errors. With the YAML extension for VS Code, put this comment on the first line: ```yaml title="plugin.yaml" # yaml-language-server: $schema=https://docs.coderhelm.com/schema/plugin-manifest.v1.json ``` Check a plugin against it before you push with the validator: see [Test a plugin locally](/plugins/testing). ## Top-level fields [#top-level-fields] The plugin.yaml file at the root of a CoderHelm plugin. A plugin is text plus approved tools: its behavior comes from its agents and skills, and this file declares what it may touch. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `name` | string | yes | | The plugin's id. Lowercase letters, digits and `-`, optionally namespaced by publisher as `publisher/name`. Must match `^([a-z0-9][a-z0-9-]\{0,38\}/)?[a-z0-9][a-z0-9-]\{0,63\}$`. Example: `marketing`, `acme/marketing`. | | `version` | string | yes | | The plugin's version, in semantic versioning (`MAJOR.MINOR.PATCH`). Installs are pinned by content hash, so the version is a label for people; raise it whenever you publish. Must match `^(0\|[1-9][0-9]*)\.(0\|[1-9][0-9]*)\.(0\|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$`. Example: `1.2.0`. | | `description` | string | yes | | One line saying what the plugin does. Shown in the catalog and on the plugin's page. At most 240 characters. | | `skills` | list of string | no | `["skills/*/SKILL.md"]` | Paths or globs of the plugin's skills, relative to the plugin's folder. Skills use the same SKILL.md format as skill repos and apply only to this plugin's runs. | | `agents` | list of string | no | `["agents/*.md"]` | Paths or globs of the plugin's agents. Each agent file is Markdown with frontmatter; its body is the agent's instructions. | | `settings` | list of objects | no | `[]` | Values each team fills in on the plugin's page. Values live with the team, never in the plugin. | | `tools` | list of objects | no | `[]` | Every tool the plugin's agents may call. A tool that is not listed here does not exist for a plugin run. | | `triggers` | list of objects | no | `[]` | What starts a run of the plugin, besides a person writing a brief on the plugin's page. | | `outputs` | list of objects | no | `[]` | What a run produces. Drafts wait in the review queue; a publish output sends an approved draft out through a consequential tool. | | `budget` | object | no | | The plugin's own monthly token limit. The team can change it on the plugin's page, and the team's limits apply too. | Fields not listed here are refused, so a typo fails loudly instead of being ignored. ## settings[] [#settings] Values each team fills in on the plugin's page. Values live with the team, never in the plugin. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `key` | string | yes | | The setting's name. Lowercase letters, digits and `_`, starting with a letter. Must match `^[a-z][a-z0-9_]\{0,63\}$`. | | `type` | `string` \| `secret` \| `connection` | yes | | `string` is a value the team types. `secret` is sealed, never shown again once saved, and never given to a model. `connection` asks the team to connect an account. | | `provider` | string | no | | For a `connection`: how the account is connected, such as `oauth2`. Example: `oauth2`. | | `scopes` | list of string | no | | For an OAuth connection: the scopes asked for. Adding a scope in a new version waits for an admin. | | `sensitive` | boolean | no | `false` | Keep the value out of every prompt and never send it back to the dashboard. `secret` and `connection` settings are always sensitive. | A `connection` setting needs `provider`. `secret` and `connection` settings are always sensitive. ## tools[] [#tools] Every tool the plugin's agents may call. A tool that is not listed here does not exist for a plugin run. Each entry is one of two shapes. ### Tools from an MCP server [#tools-from-an-mcp-server] Tools from an MCP server the team has on its Connections page. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `ref` | string | yes | | `mcp:\`: the connection's MCP server. Must match `^mcp:[a-z0-9][a-z0-9_-]*$`. Example: `mcp:sanity`. | | `allow` | list of string | yes | | Tool names, or `*` globs, from that server the plugin may call. Everything else on the server is hidden from the run. | | `risk` | `read` \| `write` \| `consequential` | no | `"read"` | The highest risk among the allowed tools. | ### A built-in or plugin-defined tool [#a-built-in-or-plugin-defined-tool] A built-in CoderHelm tool, or a tool the plugin defines. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `name` | string | yes | | Lowercase letters, digits and `_`. Agents call the tool by this name. Must match `^[a-z][a-z0-9_]\{0,63\}$`. | | `kind` | `builtin` \| `http` | yes | | `builtin` is one of CoderHelm's own tools, such as reading release notes. `http` is a tool the plugin defines that calls an outside service with the team's connection. | | `description` | string | no | | When an agent should use the tool. At most 240 characters. | | `risk` | `read` \| `write` \| `consequential` | yes | | `read` only looks. `write` changes something a person can still review, such as a draft in a CMS. `consequential` reaches people or money (publish, send, post) and runs only after an approval. | ### Risk levels [#risk-levels] `read` only looks. `write` changes something a person can still review, such as a draft in a CMS. `consequential` reaches people or money (publish, send, post) and runs only after an approval. ## triggers[] [#triggers] What starts a run of the plugin, besides a person writing a brief on the plugin's page. ### `on: manual` [#on-manual] A person starts a run from the plugin's page by filling in a short form. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `on` | `"manual"` | yes | | | | `form` | map | no | `\{"brief":"text"\}` | The form's fields: `text` for a box to write in, or a list of choices to pick from. | ### `on: schedule` [#on-schedule] Runs on a schedule. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `on` | `"schedule"` | yes | | | | `cron` | string | yes | | Five-field cron: minute, hour, day of month, month, day of week. Must match `^\S+( \S+)\{4\}$`. Example: `0 14 * * MON`. | ### `on: github.release` [#on-githubrelease] Runs when a release is published on a GitHub repo the team connected. The run gets the release notes CoderHelm wrote. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `on` | `"github.release"` | yes | | | ## outputs[] [#outputs] What a run produces. Drafts wait in the review queue; a publish output sends an approved draft out through a consequential tool. ### `type: draft` [#type-draft] | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `type` | `"draft"` | yes | | | | `kinds` | list of `blog` \| `social` \| `email` \| `image` \| `action` | yes | | The kinds of draft a run may save. `action` is a step to take, such as an update to a record, rather than something to read. | ### `type: publish` [#type-publish] | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `type` | `"publish"` | yes | | | | `via` | string | yes | | The name of a `consequential` tool from `tools` that sends an approved draft out. Must match `^[a-z][a-z0-9_]\{0,63\}$`. | | `approval` | object | no | | The approval a draft needs before it is published. The person who asked for a draft never approves it. | #### approval [#approval] | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `role` | string | no | | Who should approve, as a short name such as `marketing_editor`. The team lists the actual approvers on the plugin's page. Must match `^[a-z][a-z0-9_]\{0,63\}$`. | | `min` | integer | no | `1` | How many different people must approve. | ## budget [#budget] The plugin's own monthly token limit. The team can change it on the plugin's page, and the team's limits apply too. | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `monthly_tokens` | integer | no | | Tokens the plugin may use per month. Empty or 0 means no limit of its own. | # Private marketplace Source: https://docs.coderhelm.com/plugins/marketplace Give your team a catalog of approved plugins from your own git repository. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. A private marketplace is a plugin source with several plugins in it: one repository, one folder per plugin, each folder with its own `plugin.yaml`. ```txt your-org/coderhelm-plugins ├── marketing/ │ └── plugin.yaml ├── support-replies/ │ └── plugin.yaml └── sales-notes/ └── plugin.yaml ``` Make the repository private and readable by your team's GitHub App, then add it as a source on the **Plugins** page as `your-org/coderhelm-plugins`. Its plugins appear under **Plugins you can install**, and installing one goes through the usual steps: an admin installs, a second admin approves when there are two, and connections are made separately. ## Keep it vetted [#keep-it-vetted] - Protect the repository's default branch and require review, since merging is publishing. - Run the [validator](/plugins/testing) in the repository's CI for every folder. - Have the source follow a release branch or a tag, not your working branch. - Keep each plugin's team-specific values in settings. # Outputs, drafts and approvals Source: https://docs.coderhelm.com/plugins/outputs What a plugin run produces, how drafts are reviewed, and how nothing goes out without an approval of the exact version. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. ## Drafts [#drafts] A run saves what it makes as **drafts**. Declare the kinds a run may save: ```yaml outputs: - type: draft kinds: [blog, social, email] ``` Kinds are `blog`, `social`, `email`, `image` and `action` (a step to take, such as an update to a record). Drafts wait in **Plugins** → **Review**: "Read one, edit it if needed, then approve it to go out now or at a time you pick." | Status | Means | | --- | --- | | Draft | Saved by the run. | | In review | Waiting for an approver. | | Approved | An approver said yes to this exact version. | | Scheduled | Approved for a set time; it can be cancelled until then. | | Published | Sent out by the publish tool, with a link to the result. | | Rejected | Turned down. | | Stopped | Stopped for good: nothing from this draft can go out. | | Cancelled | A scheduled publish was cancelled. | | Failed | The publish tool reported an error. | Editing a draft saves a new version. An approval waiting on the old version moves to the new one and must be given again. ## Publishing [#publishing] ```yaml outputs: - type: publish via: publish_post # a consequential tool from `tools` approval: role: marketing_editor # who should approve min: 1 # how many different people ``` A `publish` output names the consequential tool that sends an approved draft out. That tool runs only: 1. after the required number of approvers say yes, 2. with the exact version they approved, 3. approved by people other than the one who asked for the draft, 4. now (**Approve and publish now**), or at the time the approver picked (**Approve for that time**). A scheduled publish can be cancelled until its time (**Cancel publish**); the draft stays approved in the history, and approving it again picks a new time. **Stop for good** is permanent: nothing from that draft can be approved or go out afterwards, even if it is edited. ## Who approves [#who-approves] The team lists the approvers on the plugin's page, under **Who approves what goes out**: one email per line, and how many approvals are needed. With nobody listed, admins approve. The person who asked for a draft never approves it. Approvers can approve from the review queue, from a card in Slack or Teams, or from a link in an email. # Publishing Source: https://docs.coderhelm.com/plugins/publishing Share a plugin with other teams, in your organization or publicly. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. Publishing a plugin means putting it where teams can install it. There is no upload step and no review queue at CoderHelm: a plugin is published by merging it to the default branch of a repository teams can read. ## Checklist [#checklist] 1. **Validate it.** `node validate-plugin.mjs .` passes with no errors. See [Test a plugin locally](/plugins/testing). 2. **Run it on a test team** with a manual brief, and read the drafts. 3. **No team data in the repo.** Brand documents, account ids, keys and approvers are settings. 4. **Narrow tools.** List exact tool names in `allow`, not `*`. Mark each tool's real risk. 5. **A README** that says what the plugin does, which connections it needs, and what each setting is for. 6. **Raise `version`.** 7. **Merge to the default branch.** ## Where to publish [#where-to-publish] - **Your organization**: a private repository, or a folder in your [private marketplace](/plugins/marketplace). - **Everyone**: a public repository. Any team can install it by name. Teams that already installed the plugin get the new version under the [update rules](/plugins/versioning). # Public and private repos Source: https://docs.coderhelm.com/plugins/repos Install plugins from public or private repositories, and how each one stays up to date. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. Plugins come from **plugin sources**: git repositories an admin adds on the **Plugins** page. Each source is read at a pinned commit. | | Public repository | Private repository | | --- | --- | --- | | How you add it | Its public GitHub address | `owner/name`, for a repository your team's GitHub App can read | | Who sees it | Your team | Your team only; private repositories stay private to your team | A source can hold one plugin at its root, or several in folders. Its plugins appear under **Plugins you can install**. ## Following changes [#following-changes] Each source, and each installed plugin, follows a branch, a tag or one commit. CoderHelm checks sources for changes and shows when it last checked. - **Take new versions on their own**: new versions are picked up by themselves. Wording changes apply; anything that widens what the plugin can do still waits for an admin ([Versioning and updates](/plugins/versioning)). - **Pin to a commit**: the plugin stays on one version until someone moves it. ## Removing a source [#removing-a-source] When a source is removed, its plugins stop showing in the catalog. Plugins already installed from it keep their current version. ## Forking [#forking] To change a public plugin for your team, fork it into your own organization and add the fork as a source. Your team's own values belong in [settings](/plugins/settings), so most teams never need to fork. # Security rules Source: https://docs.coderhelm.com/plugins/security The rules every plugin runs under, enforced in code rather than by the plugin's instructions. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. Plugins can reach outside systems and real people, so the rules below are enforced by CoderHelm itself. A plugin's instructions can't relax them, and neither can a model that has been tricked by text it read. 1. **No plugin code runs.** A plugin is text plus declared tools. Scripts in a plugin repo are never executed. 2. **Only declared tools exist.** A tool missing from `plugin.yaml` can't be called, by any agent, in any run. 3. **Every tool has a risk level**, shown on the plugin's page, and the team sees it before installing. 4. **Consequential actions need a person.** Publish, send and post run only after an approval of the exact version of the draft, from someone other than the requester. A stop is permanent. 5. **Each team caps autonomy.** The team chooses whether plugins only read, or may also save drafts, without a person. 6. **Installing grants nothing.** Connections are made separately, shared or per person. 7. **Secrets never reach the model.** Secrets, connection tokens and sensitive settings are sealed with KMS, added to requests after the model chose the call, and never sent back to the dashboard. 8. **Widening needs approval.** New or wider tools, triggers, connections or outputs wait for an admin. 9. **Installs are pinned** to exact content, with a second admin's approval when the team has two. 10. **Everything is metered** and counted against the plugin's and the team's token limits. 11. **Everything is recorded.** The **Audit log** page shows every plugin step in one place: who or what started it, which version ran, each tool and how much it could do, who approved, and what happened. ## Roles [#roles] | Capability | Lowest role | | --- | --- | | `plugins.install` | Admin | | `plugins.run` | Member | | Approving a plugin's drafts | The people listed on the plugin's page (admins when nobody is listed) | ## Reporting a problem [#reporting-a-problem] If you find a way around one of these rules, email security@coderhelm.com rather than opening a public issue. # Settings and secrets Source: https://docs.coderhelm.com/plugins/settings Declare the values each team fills in for your plugin, and keep secrets away from the model. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. Settings are the values that differ between teams: a brand guide, an account to post from. You declare them in the manifest; each team fills them in on the plugin's page. Values live with the team, never in the plugin. ```yaml settings: - key: brand_voice_doc type: string - key: crm_api_key type: secret - key: linkedin type: connection provider: oauth2 scopes: [w_member_social] ``` ## Types [#types] | Type | What the team does | Notes | | --- | --- | --- | | `string` | Types a value. | Agents can read it, unless `sensitive: true`. | | `secret` | Pastes a value once. | Sealed, never shown again once saved, never given to a model. | | `connection` | Connects an account. | See [Connections and OAuth](/plugins/connections). Needs `provider`. | Every field is in the [manifest reference](/plugins/manifest-reference#settings). ## Sensitive values [#sensitive-values] A `secret`, a `connection`, or any setting with `sensitive: true` is never put in a prompt and never sent back to the dashboard; the page only shows whether it is set ("Set. Enter a new value to replace it."). Like CoderHelm's other keys, these values are encrypted with AWS KMS with the team bound into the encryption, and opened only for the call that needs them. ## Missing values [#missing-values] A plugin whose settings or connections are not filled in can't do the work that needs them. Name your settings so a person knows what to enter, and explain each one in your plugin's README. # Skills, agents and tools Source: https://docs.coderhelm.com/plugins/skills-agents-tools How a plugin's agents are written, which tools they may call, and what read, write and consequential mean. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. ## Skills [#skills] A plugin's skills are ordinary [SKILL.md files](/concepts/skills#frontmatter): a name, a description that says when to use it, and instructions. They apply only to this plugin's runs; other plugins and the coding agents don't see them. Use skills for what stays true across runs: the brand voice, a checklist, the format of a support reply. ## Agents [#agents] An agent file is Markdown with frontmatter. The body is the agent's instructions for a run. You write launch content for the team's product. ## What you get [#what-you-get] - On a release: read the release notes CoderHelm wrote, and the merged pull requests in it, with `get_release_notes`. - On the weekly schedule: the releases since last Monday. If there were none, stop and save nothing. - On a brief: the person's brief and the channels they picked. ## What you do [#what-you-do] 1. Read the `brand-voice` and `launch-checklist` skills. 2. Look up earlier posts on the same feature with `query_documents`, so you do not repeat them. 3. Write one draft per channel: - **blog**: save it in Sanity with `create_draft`, then save a `blog` draft that links to it. - **social**: three LinkedIn variants as separate `social` drafts. - **email**: one `email` draft with a subject line. 4. Run the launch checklist on each draft and fix what fails. ## What you never do [#what-you-never-do] - Never call `publish_post` yourself. Publishing happens only after an editor approves a draft, and CoderHelm makes that call with the approved text. - Never invent numbers, customers or quotes. | Field | Meaning | | --- | --- | | `name` | The agent's id. Defaults to the file name. | | `description` | One line saying what it does. | | `tools` | The tools it uses. Each must be granted in `plugin.yaml`; the [validator](/plugins/testing) refuses any that aren't. | The plugin's page in the dashboard lists its skills and agents under **Skills and agents**. ## Tools [#tools] Tools are declared in the manifest's `tools` list, in one of two shapes. **Tools from an MCP server** on the team's Connections page. List the tool names (or `*` globs) the plugin may call; every other tool on that server is hidden from the run. ```yaml tools: - ref: mcp:sanity allow: [get_document, query_documents, create_draft] risk: write ``` **Named tools**: one of CoderHelm's built-in tools (`kind: builtin`), or a tool the plugin defines to call an outside service with the team's connection (`kind: http`). ```yaml tools: - name: get_release_notes kind: builtin risk: read - name: publish_post kind: http description: Publish an approved post to the company's LinkedIn page. risk: consequential ``` The plugin's page shows every tool and its risk under **What it can do**. ## Risk levels [#risk-levels] Every tool has one of three risk levels. | Risk | Means | Runs | | --- | --- | --- | | `read` | Only looks: search, fetch, list. | Whenever the agent calls it. | | `write` | Changes something a person can still review before anyone sees it, such as a draft in a CMS. | Only if the team lets plugins save drafts without a person (below). | | `consequential` | Reaches people or money: publish, send, post. | Only through a `publish` output, after a person approves the exact version of a draft. | ## What may happen without a person [#what-may-happen-without-a-person] Each team chooses, on the **Plugins** page, the most a plugin may do on its own: - **Plugins only read without a person**: every write waits for a yes too. - **Plugins may save drafts without a person** (read and save drafts). Publishing, sending and posting always wait for an approval, whatever the team picks. A tool missing from the manifest can't be called, by any agent, in any run. # Test a plugin locally Source: https://docs.coderhelm.com/plugins/testing Check plugin.yaml, your skills and your agents with the validator before you push. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. The validator checks a plugin folder the way CoderHelm will when you install it. It needs only Node.js 20 or newer. ```bash curl -fsSLO https://docs.coderhelm.com/tools/validate-plugin.mjs node validate-plugin.mjs path/to/your-plugin ``` The file is a single script with its dependencies bundled in. It is built from the same [JSON Schema](/plugins/manifest-reference) this site publishes, on every build of these docs. ## What it checks [#what-it-checks] 1. `plugin.yaml` against the manifest schema: required fields, types, allowed values, and no unknown fields (a typo fails instead of being ignored). 2. Every `skills` and `agents` glob matches at least one file. 3. Every file fits the limits (64,000 bytes per skill or agent; 200 items; 2,000,000 bytes in all). 4. Each agent's `tools:` are granted in `plugin.yaml`. 5. `{settings.key}` and `{input}` placeholders name a real setting or input, and `request.connection` names a `connection` setting. 6. A `publish` output goes through a `consequential` tool, and a `read` tool only uses `GET`. Warnings point out things that work but are probably mistakes, such as an input that no request uses, or `allow: ["*"]`. ## Output [#output] ```txt $ node validate-plugin.mjs ./marketing ok marketing 1.0.0 ``` ```txt $ node validate-plugin.mjs ./broken error tools.publish_post: `{txt}` names no input error agents/rogue.md: tool `delete_document` is not granted in plugin.yaml `tools` 2 errors: the plugin would be refused. ``` It exits with status 1 when there are errors, so it can run in CI: ```yaml title=".github/workflows/plugin.yml" name: Plugin on: [push, pull_request] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: curl -fsSLO https://docs.coderhelm.com/tools/validate-plugin.mjs - run: node validate-plugin.mjs . ``` ## Editor checks [#editor-checks] Point your editor at the schema for completion and inline errors as you type. With the YAML extension for VS Code, start `plugin.yaml` with: ```yaml # yaml-language-server: $schema=https://docs.coderhelm.com/schema/plugin-manifest.v1.json ``` ## Try it on a test team [#try-it-on-a-test-team] The validator checks the package; only a run checks the behavior. Add your repository as a source on a test team, follow your working branch, install the plugin, start it with a brief, and read the run and its drafts. Nothing can be published without an approval, so a test run is safe. # Triggers Source: https://docs.coderhelm.com/plugins/triggers Start a plugin run from a person's brief, on a schedule, or when a release is published. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. Anyone who can use plugins can start a run from the plugin's page with **Write a brief**: "What should it write, for whom, and what must it mention?" They can also pick a **Repository (optional)**, for work that is about one repository's changes. `triggers` adds more ways to start a run. ## Manual brief form [#manual-brief-form] ```yaml triggers: - on: manual form: brief: text channels: [linkedin, blog, email] ``` Each form field is `text` (a box to write in) or a list of choices to pick from. The run receives the answers and who asked. That person can never approve the run's output. ## Schedule [#schedule] ```yaml triggers: - on: schedule cron: "0 14 * * MON" ``` `cron` has five fields: minute, hour, day of month, month, day of week. A scheduled run that finds nothing to do should say so and save nothing; write that into the agent's instructions. Turning a plugin off, or removing it, stops its schedules. ## Release [#release] ```yaml triggers: - on: github.release ``` Runs when a release is published on a GitHub repository the team connected. The run gets the [release notes](/getting-started/reviewer#release-notes) CoderHelm wrote for it. ## Runs [#runs] Every run is listed under **Plugins** → **Runs**, with what started it (manual, schedule or release), the plugin version, who asked, the tokens used and the drafts it saved. A run is queued, running, completed, failed, or refused (for example when a limit is reached), with the reason. Adding a trigger in a new version waits for an admin. See [Versioning and updates](/plugins/versioning). # Versioning and updates Source: https://docs.coderhelm.com/plugins/versioning How plugins are pinned, which changes apply by themselves, and which wait for an admin. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. ## Installs are pinned [#installs-are-pinned] When an admin installs a plugin, it is pinned to the exact content of that version (a hash of the package) and the commit it came from. If the team has two or more admins, a second admin approves the install ("Install waiting for a second admin"). `version` in `plugin.yaml` is a label for people. Raise it whenever you publish a change; CoderHelm goes by the content. ## What applies by itself, and what waits [#what-applies-by-itself-and-what-waits] From the plugin's page: "Wording changes apply on their own and are logged. A version that adds or widens tools, triggers, connections or outputs waits for an admin." | Change in a new version | What happens | | --- | --- | | Wording: skills, agent instructions, descriptions | Applies by itself, and is logged. | | A new or wider tool (a new tool, a longer `allow` list, a higher `risk`) | Waits for an admin. | | A new trigger | Waits for an admin. | | A new connection or OAuth scope | Waits for an admin. | | A new or wider output | Waits for an admin. | While an update waits, the plugin keeps running on the version already approved. The waiting update lists exactly what widened, for example "adds tool publish_post (consequential)", with what was added, removed and changed. ## Following a branch, a tag or a commit [#following-a-branch-a-tag-or-a-commit] Each plugin follows a branch, a tag or one commit of its source, and **Take new versions on their own** decides whether new versions are picked up by themselves (still under the rules above). **Pin to a commit** freezes a plugin on one version. See [Public and private repos](/plugins/repos). ## Semantic versions [#semantic-versions] Use `MAJOR.MINOR.PATCH`: - **Patch** for wording fixes. - **Minor** for new abilities (which wait for an admin). - **Major** when settings change in a way teams must act on. # Build the marketing plugin Source: https://docs.coderhelm.com/plugins/walkthrough A full walkthrough, from an empty repo to a plugin that drafts launch posts from each release and publishes after an editor approves. > Coming soon: this page describes work that is not on main yet. Plugins are being built and switched on team by team; they are not on main yet. This page follows the work in progress and will be updated when plugins ship. In this walkthrough you build a plugin that: - reads each new release (and a weekly schedule, and briefs from people), - drafts a blog post in your CMS, three LinkedIn posts and an email, in your brand voice, - waits for an editor to approve a post, then publishes it to LinkedIn at the time they pick. The finished plugin is in the docs repository at [`docs/examples/marketing`](https://github.com/CoderHelm/coderhelm/tree/main/docs/examples/marketing). The files on this page are included from it, and the docs' tests validate it on every build, so what you read here is what passes. ### Create the repo [#create-the-repo] ```bash mkdir marketing-plugin && cd marketing-plugin git init mkdir -p skills/brand-voice skills/launch-checklist agents ``` ### Write the brand voice skill [#write-the-brand-voice-skill] The skill holds what is true for every draft. It refers to the team's own guide, a setting, rather than containing any brand's text. # Brand voice [#brand-voice] The team's own voice guide is in the `brand_voice_doc` setting. Follow it first. These rules apply when the guide says nothing: - Write to one reader, in the second person ("you"). - Lead with what changed for the reader, then how it works. - Short sentences. One idea per paragraph. - Name the feature the way the product names it. - No superlatives you cannot prove. Never use a claim listed in the `banned_claims` setting. - Every claim about the product must come from the release notes or a merged pull request. If it is not there, leave it out. ## Length [#length] | Channel | Length | | -------- | ------------------------------ | | LinkedIn | 40 to 120 words, one link | | Blog | 300 to 700 words, one heading per change | | Email | Subject under 60 characters; body under 150 words | ### Add a checklist skill [#add-a-checklist-skill] A second skill the agent runs over each draft before saving it. # Launch checklist [#launch-checklist] Before saving any draft, check that it: 1. Names the release (the tag) and links to its notes. 2. Says who the change is for. 3. Has one clear next step for the reader, such as "Try it from Settings". 4. Contains no claim from `banned_claims` and nothing the release notes do not support. 5. Fits the length for its channel in the brand voice skill. If a check fails, fix the draft. If it cannot be fixed from the sources, say so in the draft's note to the editor. ### Write the agent [#write-the-agent] The agent's instructions say what it gets for each trigger, what to produce, and what it must never do. Its `tools:` list names only tools the manifest will grant. You write launch content for the team's product. ## What you get [#what-you-get] - On a release: read the release notes CoderHelm wrote, and the merged pull requests in it, with `get_release_notes`. - On the weekly schedule: the releases since last Monday. If there were none, stop and save nothing. - On a brief: the person's brief and the channels they picked. ## What you do [#what-you-do] 1. Read the `brand-voice` and `launch-checklist` skills. 2. Look up earlier posts on the same feature with `query_documents`, so you do not repeat them. 3. Write one draft per channel: - **blog**: save it in Sanity with `create_draft`, then save a `blog` draft that links to it. - **social**: three LinkedIn variants as separate `social` drafts. - **email**: one `email` draft with a subject line. 4. Run the launch checklist on each draft and fix what fails. ## What you never do [#what-you-never-do] - Never call `publish_post` yourself. Publishing happens only after an editor approves a draft, and CoderHelm makes that call with the approved text. - Never invent numbers, customers or quotes. ### Write the manifest [#write-the-manifest] Now declare everything the plugin needs. ```yaml title="plugin.yaml" # yaml-language-server: $schema=https://docs.coderhelm.com/schema/plugin-manifest.v1.json name: marketing version: 1.0.0 description: Drafts launch posts, emails and blog updates from each release, in your brand voice, for an editor to approve. skills: - skills/*/SKILL.md agents: - agents/*.md settings: - key: brand_voice_doc type: string - key: banned_claims type: string - key: sanity type: connection provider: mcp - key: linkedin type: connection provider: oauth2 scopes: [w_member_social] sensitive: true tools: - name: get_release_notes kind: builtin description: Read the release notes CoderHelm wrote for a release, with its merged pull requests. risk: read - ref: mcp:sanity allow: [get_document, query_documents, create_draft] risk: write - name: publish_post kind: http description: Publish an approved post to the company's LinkedIn page. risk: consequential triggers: - on: github.release - on: schedule cron: "0 14 * * MON" - on: manual form: brief: text channels: [linkedin, blog, email] outputs: - type: draft kinds: [blog, social, email] - type: publish via: publish_post approval: role: marketing_editor min: 1 budget: monthly_tokens: 2000000 ``` Section by section: - **settings**: the brand guide and banned claims are values the team types; the agent reads them. \`sanity\` and \`linkedin\` are accounts the team connects. - **tools**: \`get_release_notes\` is a built-in read tool. From Sanity, only three tools, at \`write\` risk because drafts there are not public. \`publish_post\` is the plugin's own tool, \`consequential\` because it reaches the public, and it signs in with the team's \`linkedin\` connection. - **triggers**: every release, Mondays at 14:00, and a brief form with a list of channels. - **outputs**: three kinds of draft, and publishing through \`publish_post\` once one approver says yes. - **budget**: at most 2 million tokens a month, unless the team changes it. ### Validate [#validate] \`\`\`bash curl -fsSLO https://docs.coderhelm.com/tools/validate-plugin.mjs node validate-plugin.mjs . \`\`\` \`\`\`txt ok marketing 1.0.0 \`\`\` Try breaking it: change \`publish_post\`'s \`risk\` to \`write\` and the validator refuses, because a publish output must go through a consequential tool. Add \`delete_document\` to the agent's \`tools:\` and it refuses again, because the manifest doesn't grant it. ### Push and install [#push-and-install] Push the repo to GitHub. Then, in CoderHelm: 1. An admin opens **Plugins**, adds the repository under **Plugin sources** (its public address, or \`owner/name\` if your GitHub App can read it), and picks the branch, tag or commit to follow. 2. **marketing** appears under **Plugins you can install**. The admin installs it; with two or more admins, a second admin approves. 3. On the plugin's page, the team fills in \`brand_voice_doc\` and \`banned_claims\`, connects Sanity (on **Connections**) and LinkedIn, and lists the editors under **Who approves what goes out**. ### Run it [#run-it] Start it by hand first: on the plugin's page, under **Write a brief**, ask for "Announce the new export button", pick channels and click **Start the run**. Or publish a release on a connected repository. The run reads the release notes, checks earlier posts in Sanity, and saves the drafts. If the team turned on Slack or Teams notices, a card goes to the channel. ### Approve and publish [#approve-and-publish] An editor (not the person who asked) opens **Plugins** → **Review**, edits one LinkedIn variant (which saves a new version), and approves it for Tuesday at 10:00 with **Approve for that time**. On Tuesday, CoderHelm calls \`publish_post\` with exactly the approved text. Until then, anyone allowed can **Cancel publish**. The **Audit log** shows the trigger, the plugin version, each tool call and its risk, the editor's approval and the result. ## Where to go next [#where-to-go-next] - Add a `email` publish tool for your email provider, with its own approval. - Add a read tool for post analytics from your connections, so next week's run can see what worked. - Put the plugin in your [private marketplace](/plugins/marketplace) for other teams. # Self-hosting Source: https://docs.coderhelm.com/self-host Run CoderHelm in your own AWS account. The guides are being written and will appear here. > Coming soon: this page describes work that is not on main yet. The self-hosting guides live with the code they describe, in [`docs/self-host/`](https://github.com/CoderHelm/coderhelm-platform/tree/main/docs/self-host) of the platform repo. This site pulls them in each time it is built, from the commit pinned in `docs/platform.lock.json`, so they always match that code. That folder is not on the pinned commit yet (`637aaa459db2`). Once it is, the guides replace this page. ## What CoderHelm runs on today [#what-coderhelm-runs-on-today] CoderHelm is two repos, both public: - [`CoderHelm/coderhelm-platform`](https://github.com/CoderHelm/coderhelm-platform): the backend. Rust services on AWS Lambda (ARM64), deployed with AWS CDK. - [`CoderHelm/coderhelm`](https://github.com/CoderHelm/coderhelm): the dashboard, the marketing site and these docs. Static Next.js exports on S3 and CloudFront. The platform uses Lambda, API Gateway, SQS, DynamoDB, S3, KMS, Secrets Manager, Cognito, SES, EventBridge, CodeBuild, CloudWatch, SNS and Bedrock (for embeddings), plus a GitHub App and, for Jira, an Atlassian Forge app. Models are called through the Anthropic API with each team's own key. Until the guides land, the platform's [README](https://github.com/CoderHelm/coderhelm-platform#readme) lists the tools needed to build it.