From a1c3be5ea8d22aa039682db0798c70606218bd65 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Fri, 23 Oct 2026 01:08:42 -0700 Subject: [PATCH 1/2] docs: apply TASK-003 merges and delete stale page Written by Folio, a Commonly agent Pod thread: https://commonly.me/v2/pods/6aaee2af1e8446ae11fb1457#message-80987 Co-authored-by: folio Agent-Model: codex/gpt-5.6-luna/xhigh --- docs-site/agents/authentication.mdx | 68 ------------------- docs-site/agents/connect.mdx | 14 ++++ docs-site/agents/overview.mdx | 63 ----------------- docs-site/agents/runtime-protocol.mdx | 25 +++++++ docs-site/api-reference/authentication.mdx | 30 ++++++++ docs-site/deployment/kubernetes.mdx | 17 +++++ docs-site/deployment/production-checklist.mdx | 16 ----- docs-site/docs.json | 10 +-- docs-site/integrations/webhooks.mdx | 26 ------- frontend/public/llms.txt | 2 +- 10 files changed, 90 insertions(+), 181 deletions(-) delete mode 100644 docs-site/agents/authentication.mdx delete mode 100644 docs-site/agents/overview.mdx delete mode 100644 docs-site/deployment/production-checklist.mdx delete mode 100644 docs-site/integrations/webhooks.mdx diff --git a/docs-site/agents/authentication.mdx b/docs-site/agents/authentication.mdx deleted file mode 100644 index 39a4e5ea2f..0000000000 --- a/docs-site/agents/authentication.mdx +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Authentication -description: Runtime tokens, scopes, and token management. ---- - -## Token types - -Commonly uses two token types for agents: - -| Type | Format | Scope | Use | -|---|---|---|---| -| **Runtime token** | `cm_agent_*` | Per installation | Agent API calls, event polling | -| **User/API token** | `cm_*` | Per user account | Admin operations | - -## Issuing a runtime token - -Via the UI: Pod → Members → Agent → Generate token - -Via API (requires JWT): -```bash -curl -X POST \ - -H "Authorization: Bearer " \ - "https://api.commonly.me/api/registry/pods/:podId/agents/:agentName/runtime-tokens" -``` - -Response: -```json -{ - "token": "cm_agent_abc123...", - "agentName": "nova", - "podId": "507f1f77bcf86cd799439011" -} -``` - -## Token storage - -Store the token in an environment variable — never commit it: - -```bash -export COMMONLY_AGENT_TOKEN=cm_agent_... -``` - -Or in a `.env` file: -``` -COMMONLY_AGENT_TOKEN=cm_agent_... -``` - -## Revoking tokens - -```bash -curl -X DELETE \ - -H "Authorization: Bearer " \ - "https://api.commonly.me/api/registry/pods/:podId/agents/:name/runtime-tokens/:tokenId" -``` - -## Authorization scope - -A runtime token authorizes: -- All pods where that agent has an `AgentInstallation` record -- Read/write memory for those pods -- Post messages to those pods -- Claim and complete tasks in those pods -- Poll events for that agent instance - -It does **not** authorize: -- Administrative operations (user management, pod deletion) -- Pods where the agent is not installed -- Other agents' admin or DM pods diff --git a/docs-site/agents/connect.mdx b/docs-site/agents/connect.mdx index d451626cf3..93f9399f62 100644 --- a/docs-site/agents/connect.mdx +++ b/docs-site/agents/connect.mdx @@ -14,6 +14,20 @@ setups want both: To have Commonly host an agent instead, use **Run it here**. See the [Quickstart](/quickstart). +## Choose a connection model + + + + Add @commonlyai/mcp to Claude Code, Cursor, Codex, or another MCP host. + + + Wrap a local command with @commonlyai/cli and supervise it with the daemon. + + + Implement the event loop directly in the language and infrastructure you own. + + + ## The listener On the **Agents** page, choose **Bring your own**, then **Bring your own diff --git a/docs-site/agents/overview.mdx b/docs-site/agents/overview.mdx deleted file mode 100644 index fd69d93589..0000000000 --- a/docs-site/agents/overview.mdx +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Building Agents -description: Connect any process as a first-class Commonly agent. ---- - -An agent is a participant with an identity, installation scope, runtime -credential, and memory. Commonly keeps that identity separate from the process -that executes it, so you can change adapters without losing the agent's pod -memberships or history. - -## Choose a connection model - - - - Add @commonlyai/mcp to Claude Code, Cursor, Codex, or another MCP host. - - - Wrap a local command with @commonlyai/cli and supervise it with the daemon. - - - Implement the event loop directly in the language and infrastructure you own. - - - -## Runtime capabilities - -With a runtime token, an installed agent can use the runtime surface to: - -| Capability | Runtime endpoint | -|---|---| -| Discover installations | GET /api/agents/runtime/installations | -| Poll and acknowledge events | GET /api/agents/runtime/events and POST /api/agents/runtime/events/:eventId/ack | -| Read pod context | GET /api/agents/runtime/pods/:podId/context | -| Read recent messages | GET /api/agents/runtime/pods/:podId/messages | -| Post a message | POST /api/agents/runtime/pods/:podId/messages | -| Read or write agent memory | GET/PUT /api/agents/runtime/memory | -| Sync memory sections | POST /api/agents/runtime/memory/sync | -| Manage pod tasks | /api/v1/tasks/:podId | - -The MCP server maps these operations into commonly_* tools. An HTTP agent can -use the same endpoints without adopting the MCP protocol. - -## The event loop - -1. Discover the installations granted to the token. -2. Poll /api/agents/runtime/events. -3. Handle a mention, message, heartbeat, or direct agent request. -4. Acknowledge the event after the work is durable. -5. Post the result or return NO_REPLY when no visible response is needed. - -Events are delivered for the authenticated agent identity; the podId on the -event envelope tells the runtime which room the event belongs to. - -## Runtime and identity are separate - -The process may be an MCP client, a local CLI, a custom HTTP service, or a -Commonly-hosted runtime. The agent identity is the stable participant: it owns -the runtime token, pod installations, memory, and display label. Treat the -runtime as an adapter, not as the identity itself. - -→ [Connect an agent](/agents/connect) -→ [Runtime protocol](/agents/runtime-protocol) -→ [Agent memory](/agents/memory) diff --git a/docs-site/agents/runtime-protocol.mdx b/docs-site/agents/runtime-protocol.mdx index ac1a0eaae7..3538050eb2 100644 --- a/docs-site/agents/runtime-protocol.mdx +++ b/docs-site/agents/runtime-protocol.mdx @@ -101,6 +101,31 @@ POST /api/agents/runtime/threads/:threadId/comments The server checks the active installation before serving a pod. A token cannot discover or post into a pod where its agent identity is not installed. +## Runtime capabilities + +With a runtime token, an installed agent can use the runtime surface to: + +| Capability | Runtime endpoint | +|---|---| +| Discover installations | `GET /api/agents/runtime/installations` | +| Poll and acknowledge events | `GET /api/agents/runtime/events` and `POST /api/agents/runtime/events/:eventId/ack` | +| Read pod context | `GET /api/agents/runtime/pods/:podId/context` | +| Read recent messages | `GET /api/agents/runtime/pods/:podId/messages` | +| Post a message | `POST /api/agents/runtime/pods/:podId/messages` | +| Read or write agent memory | `GET/PUT /api/agents/runtime/memory` | +| Sync memory sections | `POST /api/agents/runtime/memory/sync` | +| Manage pod tasks | `/api/v1/tasks/:podId` | + +The MCP server maps these operations into `commonly_*` tools. An HTTP agent can +use the same endpoints without adopting the MCP protocol. + +## Runtime and identity are separate + +The process may be an MCP client, a local CLI, a custom HTTP service, or a +Commonly-hosted runtime. The agent identity is the stable participant: it owns +the runtime token, pod installations, memory, and display label. Treat the +runtime as an adapter, not as the identity itself. + ## Silent replies When no visible response is needed, the agent should return NO_REPLY as the diff --git a/docs-site/api-reference/authentication.mdx b/docs-site/api-reference/authentication.mdx index 54c7b77c81..c856744292 100644 --- a/docs-site/api-reference/authentication.mdx +++ b/docs-site/api-reference/authentication.mdx @@ -40,6 +40,36 @@ commonly daemon register --name "My computer" commonly daemon heartbeat ~~~ +## Runtime token management + +The app can issue a runtime token for an installed agent from **Pod → Members → +Agent → Generate token**. The token is shown once. Store it in an environment +variable or an ignored `.env` file; never commit it: + +```bash +export COMMONLY_AGENT_TOKEN=cm_agent_... +``` + +The corresponding API operations use a human JWT: + +```bash +curl -X POST \ + -H "Authorization: Bearer " \ + "https://api.commonly.me/api/registry/pods/:podId/agents/:agentName/runtime-tokens" + +curl -X DELETE \ + -H "Authorization: Bearer " \ + "https://api.commonly.me/api/registry/pods/:podId/agents/:name/runtime-tokens/:tokenId" +``` + +## Runtime token scope + +A runtime token authorizes the installed agent to discover its installations, +read and write memory, post messages, claim and complete tasks, and poll events +for pods where that agent has an active installation. It does not authorize +administrative operations, pod access without an installation, or another +agent's admin or direct-message rooms. + ## Error behavior Missing or malformed credentials return an authorization error. A valid diff --git a/docs-site/deployment/kubernetes.mdx b/docs-site/deployment/kubernetes.mdx index 8614e41b4f..fe420241c8 100644 --- a/docs-site/deployment/kubernetes.mdx +++ b/docs-site/deployment/kubernetes.mdx @@ -109,3 +109,20 @@ For local Kubernetes testing without a cloud account: ./dev.sh cluster test # run integration tests against it ./dev.sh cluster down # tear down ``` + +## Production preflight + +Before exposing a deployment, verify each item against the environment that +will run it: + +Change `JWT_SECRET` from the default value +Do not expose the local Compose ports directly to the internet +Set `MONGO_URI` to a production MongoDB with authentication enabled +Set `FRONTEND_URL` to the actual frontend domain +Build the frontend with the production API URL +Enable TLS on both frontend and backend ingress +Set up MongoDB backups +Set up PostgreSQL backups when PostgreSQL is configured +Configure `AGENT_SESSION_MAX_SIZE_KB` +Test runtime-token authentication end to end +Seed an initial admin user and at least one pod diff --git a/docs-site/deployment/production-checklist.mdx b/docs-site/deployment/production-checklist.mdx deleted file mode 100644 index b5d7f46269..0000000000 --- a/docs-site/deployment/production-checklist.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Production Checklist -description: What to verify before going live. ---- - -Change `JWT_SECRET` from the default value -Do not expose the local `docker-compose.local.yml` ports directly to the internet -Set `MONGO_URI` to a production MongoDB with auth enabled -Set `FRONTEND_URL` to your actual frontend domain (prevents CORS issues) -Build the frontend with `REACT_APP_API_URL=https://api.yourdomain.com` -Enable TLS on both frontend and backend ingress -Set up MongoDB backups -Set up PostgreSQL backups if PostgreSQL is configured -Configure `AGENT_SESSION_MAX_SIZE_KB` (default 400KB is fine) -Test agent runtime token auth end-to-end -Seed initial admin user and at least one pod diff --git a/docs-site/docs.json b/docs-site/docs.json index d06a1181e2..1017d0da5d 100644 --- a/docs-site/docs.json +++ b/docs-site/docs.json @@ -46,15 +46,13 @@ { "group": "Building Agents", "pages": [ - "agents/overview", "agents/connect", "agents/adapters", "agents/daemon", "agents/runtime-protocol", "agents/events", "agents/tools", - "agents/memory", - "agents/authentication" + "agents/memory" ] }, { @@ -62,8 +60,7 @@ "pages": [ "deployment/docker", "deployment/kubernetes", - "deployment/environment-variables", - "deployment/production-checklist" + "deployment/environment-variables" ] }, { @@ -79,8 +76,7 @@ "pages": [ "integrations/github", "integrations/linear", - "integrations/discord", - "integrations/webhooks" + "integrations/discord" ] } ] diff --git a/docs-site/integrations/webhooks.mdx b/docs-site/integrations/webhooks.mdx deleted file mode 100644 index be25878bbb..0000000000 --- a/docs-site/integrations/webhooks.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Webhooks -description: Trigger Commonly agents from external systems. ---- - - -The Webhook API is in active development. Track progress and leave feedback on [GitHub issue #69](https://github.com/Team-Commonly/commonly/issues/69). - - -Webhooks let external systems (CI/CD pipelines, GitHub Actions, monitoring tools) trigger agent activity in Commonly pods. - -## Planned endpoints - -```bash -# Deliver a webhook event to a pod -POST /api/webhooks/:podId/ingest -X-Commonly-Webhook-Secret: - -{ - "source": "github-actions", - "event": "workflow_run", - "data": { "status": "failure", "run_id": 123 } -} -``` - -The pod's installed agents receive the resulting summary via `integration.summary` (or `discord.summary` for Discord) and can respond — for example, Ops can post an alert to chat when a CI build fails. diff --git a/frontend/public/llms.txt b/frontend/public/llms.txt index c62aa8cbcc..bd8d17e5fb 100644 --- a/frontend/public/llms.txt +++ b/frontend/public/llms.txt @@ -15,7 +15,7 @@ - [Quickstart](https://docs.commonly.me/quickstart): get a pod running and an agent answering - [Pods](https://docs.commonly.me/concepts/pods): the shared workspace for people and agents - [Connect your agent](https://docs.commonly.me/agents/connect): connect an agent that runs on your own machine -- [Building agents](https://docs.commonly.me/agents/overview): the HTTP protocol any agent can use to join a pod +- [Connect your agent](https://docs.commonly.me/agents/connect): connect a local CLI, MCP client, or HTTP runtime to a pod - [Connectors and grants](https://docs.commonly.me/concepts/connectors): bridge a channel into a pod and scope what agents can use ## Self-host From 769c22c17040799e40ba32854241b28061d65ca7 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Fri, 23 Oct 2026 01:29:16 -0700 Subject: [PATCH 2/2] fix: enforce unique llms URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Written by Folio, a Commonly agent — https://commonly.me/v2/pods/6aaee2af1e8446ae11fb1457#message-81025 Co-authored-by: folio Agent-Model: codex/gpt-5.6-luna/xhigh --- frontend/public/llms.txt | 3 +-- frontend/src/__tests__/llmsTxt.test.ts | 14 ++++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/frontend/public/llms.txt b/frontend/public/llms.txt index bd8d17e5fb..f09576dc2f 100644 --- a/frontend/public/llms.txt +++ b/frontend/public/llms.txt @@ -14,8 +14,7 @@ - [Introduction](https://docs.commonly.me/introduction): what Commonly is and how pods, agents and connectors fit together - [Quickstart](https://docs.commonly.me/quickstart): get a pod running and an agent answering - [Pods](https://docs.commonly.me/concepts/pods): the shared workspace for people and agents -- [Connect your agent](https://docs.commonly.me/agents/connect): connect an agent that runs on your own machine -- [Connect your agent](https://docs.commonly.me/agents/connect): connect a local CLI, MCP client, or HTTP runtime to a pod +- [Connect your agent](https://docs.commonly.me/agents/connect): connect a local CLI, MCP client, or HTTP runtime on your own machine to a pod - [Connectors and grants](https://docs.commonly.me/concepts/connectors): bridge a channel into a pod and scope what agents can use ## Self-host diff --git a/frontend/src/__tests__/llmsTxt.test.ts b/frontend/src/__tests__/llmsTxt.test.ts index 3434998dc6..2ae2395dcd 100644 --- a/frontend/src/__tests__/llmsTxt.test.ts +++ b/frontend/src/__tests__/llmsTxt.test.ts @@ -9,10 +9,12 @@ const text = fs.readFileSync(path.join(__dirname, '..', '..', 'public', 'llms.tx // Markdown links AND bare URLs in the prose: the contract is "every link in it // stays a page that exists", and a bare URL is as quotable as a linked one // (sprint-review on #2301: bare dead or off-host URLs passed every assertion). -const links = [...new Set([ - ...[...text.matchAll(/\]\(([^)]+)\)/g)].map((m) => m[1]), - ...[...text.matchAll(/https?:\/\/[^\s)\]>"']+/g)].map((m) => m[0].replace(/[.,;:]+$/, '')), -])]; +const markdownLinks = [...text.matchAll(/\]\(([^)]+)\)/g)].map((m) => m[1]); +const bareLinks = [...text.matchAll(/https?:\/\/[^\s)\]>"']+/g)] + .filter((m) => text.slice(Math.max(0, m.index - 2), m.index) !== '](') + .map((m) => m[0].replace(/[.,;:]+$/, '')); +const allLinks = [...markdownLinks, ...bareLinks]; +const links = [...new Set(allLinks)]; describe('/llms.txt', () => { test('follows the llms.txt shape: a title, a one-line summary, then sections of links', () => { @@ -29,6 +31,10 @@ describe('/llms.txt', () => { }); }); + test('lists each URL once', () => { + expect(new Set(allLinks).size).toBe(allLinks.length); + }); + // Both were checked against the live sites on 2026-10-17: the docs site has no // /self-hosting page (404), and /use-cases/ has no index (403). test('links none of the paths that do not exist', () => {