Docs: the Project tab and organization secret visibility across the reference (#94)
* Docs: the Project tab across the API reference, MCP, audit log, limits and the agent overviews #90 added the Projects page. The generated API reference had no descriptions for its six endpoints (and the task list's new queued and active filters), the MCP page's tool table lacked project and project_posts, the audit log lacked project.memory and project.settings, Limits lacked the queue and size limits, and the overview still said Tasks tab. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016q5wwBFck8JHq14gHUM2CL * Docs: organization secret visibility in the API reference and the secrets context #91 documented visibility on the Secrets page. The API reference still said an organization secret reaches every repository, and had no descriptions for the new get, selection and add/remove endpoints; the expressions page said the same of secrets.<NAME>. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016q5wwBFck8JHq14gHUM2CL --------- Co-authored-by: Claude <noreply@anthropic.com>
Canberk Demirci authored · GitHub committed signed1 parent 3675d7acommit 5702919f285d50efbfd3c4953219aa7ea4abc4edBrowse files
8 files changed+76−8
Files (8)
- apps/diffinery/docs/actions/expressions.md+1−1
- apps/diffinery/docs/agents/mcp.md+2−0
- apps/diffinery/docs/agents/overview.md+2−1
- apps/diffinery/docs/concepts.md+1−1
- apps/diffinery/docs/index.md+1−0
- apps/diffinery/docs/reference/limits.md+4−0
- apps/diffinery/docs/security/audit-log.md+2−0
- apps/diffinery/src/docs/api-meta.ts+63−5
modifiedapps/diffinery/docs/actions/expressions.md+1−1View file
| @@ -276,7 +276,7 @@ | ||
| 276 | 276 | |
| 277 | 277 | | Property | Value | |
| 278 | 278 | | --- | --- | |
| 279 | -| `secrets.<NAME>` | A repository secret, or an organization secret of the repository's owner. A repository secret wins over an organization secret with the same name. In a job with `environment:`, the environment's secrets win over both (pull request runs, and some runs whose code came from an agent, don't get environment secrets; see [environment](/docs/actions/workflow-syntax#environment)). | | |
| 279 | +| `secrets.<NAME>` | A repository secret, or an organization secret shared with the repository (by its `visibility`; see [Organization secrets](/docs/actions/secrets-and-variables#organization-secrets)). A repository secret wins over an organization secret with the same name. In a job with `environment:`, the environment's secrets win over both (pull request runs, and some runs whose code came from an agent, don't get environment secrets; see [environment](/docs/actions/workflow-syntax#environment)). | | |
| 280 | 280 | | `secrets.GITHUB_TOKEN` | The job's token. What it may do follows the job's `permissions:`; see [GITHUB_TOKEN permissions](/docs/actions/workflow-permissions). | |
| 281 | 281 | | `secrets.DIFFINERY_TOKEN` | The same job token, under a Diffinery name. | |
| 282 | 282 |
modifiedapps/diffinery/docs/agents/mcp.md+2−0View file
| @@ -133,6 +133,8 @@ | ||
| 133 | 133 | | `today` | Yes | Your morning view: pull requests that need you, your agents' open pull requests and where each stands, and what merged, was released or failed in the last 24 hours. See [Today](/docs/agents/today) | Any token | |
| 134 | 134 | | `agent_tasks` | Yes | Agent tasks: with `owner` and `repo` that repository's, without them the ones you started (an agent: the ones it runs). See [Agent tasks](/docs/agents/tasks) | Write on the repository; any token for your own | |
| 135 | 135 | | `agent_task` | Yes | One agent task (`owner`, `repo`, `number`) with its runs, pull request and transcript after `after` | Write | |
| 136 | +| `project` | Yes | The repository's [project](/docs/agents/projects): its task board, memory and settings | Write | | |
| 137 | +| `project_posts` | Yes | The project's conversation after `after`, or the latest 100 lines | Write | | |
| 136 | 138 | | `list_repos` | Yes | Repositories visible to you, optionally filtered by `owner` | Any token | |
| 137 | 139 | | `get_organization` | Yes | An organization's `login` and `name`; to its members, its agents, agents of its members and site administrators also `default_repository_permission` (the base permission members get on its repositories) | Any token | |
| 138 | 140 | | `list_invitations` | Yes | Pending invitations to a repository (`owner` and `repo`), an organization (`org`) or the instance (neither), each with an `id` | Admin on the repository; organization owner or admin; site administrator | |
modifiedapps/diffinery/docs/agents/overview.md+2−1View file
| @@ -214,7 +214,8 @@ | ||
| 214 | 214 | |
| 215 | 215 | ## Agent tasks, agent review and Today |
| 216 | 216 | |
| 217 | -- **[Agent tasks](/docs/agents/tasks)**: on a repository's **Tasks** tab, give one of your agents a goal. Diffinery runs Claude Code or Codex (on their own providers, or via [OpenRouter](/docs/agents/tasks#openrouter) on a model you choose) or your own command in a sandbox as that agent, with your own model API key (saved under **Settings → Model access**, and never placed in the sandbox), then pushes a branch and opens a pull request for review. | |
| 217 | +- **[Agent tasks](/docs/agents/tasks)**: on a repository's **Project** tab, give one of your agents a goal. Diffinery runs Claude Code or Codex (on their own providers, or via [OpenRouter](/docs/agents/tasks#openrouter) on a model you choose) or your own command in a sandbox as that agent, with your own model API key (saved under **Settings → Model access**, and never placed in the sandbox), then pushes a branch and opens a pull request for review. | |
| 218 | +- **[Projects](/docs/agents/projects)**: the Project tab shows a repository's tasks on a board, with a conversation, a shared memory every task reads, project instructions, and a limit on how many tasks run at once. | |
| 218 | 219 | - **[Agent review](/docs/agents/review)**: one of your agents reviews pull requests for bugs, security issues and logic errors, like Cursor's Bugbot. It posts inline findings and an **Agent review** check, and **Fix it** starts a task that pushes the fix. |
| 219 | 220 | - **[Today](/docs/agents/today)**: the first page after signing in, also `GET /api/v3/diffinery/today` and the `today` MCP tool. It shows the pull requests that need you, your agents' open pull requests and tasks, and what merged, was released or failed in the last 24 hours. |
| 220 | 221 |
modifiedapps/diffinery/docs/concepts.md+1−1View file
| @@ -45,7 +45,7 @@ | ||
| 45 | 45 | - A workflow run whose code came from an agent (the agent triggered it, pushed the branch last, or opened the pull request, and re-runs and `workflow_run` followers of such a run) acts as the agent, so a workflow can't carry agent-written code past these rules. |
| 46 | 46 | - It can import from GitHub only into an organization it or its owner administers, its imports never bypass push protection, and they skip variables, secret names and environments. |
| 47 | 47 | |
| 48 | -Agents work through the [MCP server](/docs/agents/mcp), the REST API, the CLI and Git. Diffinery can also run one for you: an [agent task](/docs/agents/tasks) gives one of your agents a goal and runs Claude Code, Codex or your own command with your own model key, then opens a pull request, and [agent review](/docs/agents/review) has one review pull requests for bugs. [Today](/docs/agents/today), the first page after signing in, shows what needs you and what your agents are doing. See [Agents](/docs/agents/overview). | |
| 48 | +Agents work through the [MCP server](/docs/agents/mcp), the REST API, the CLI and Git. Diffinery can also run one for you: an [agent task](/docs/agents/tasks) gives one of your agents a goal and runs Claude Code, Codex or your own command with your own model key, then opens a pull request, a repository's [project](/docs/agents/projects) puts its tasks on a board with shared memory and instructions, and [agent review](/docs/agents/review) has one review pull requests for bugs. [Today](/docs/agents/today), the first page after signing in, shows what needs you and what your agents are doing. See [Agents](/docs/agents/overview). | |
| 49 | 49 | |
| 50 | 50 | ### People imported from GitHub |
| 51 | 51 |
modifiedapps/diffinery/docs/index.md+1−0View file
| @@ -15,6 +15,7 @@ | ||
| 15 | 15 | | Run CI | [Actions overview](/docs/actions/overview) and [Workflow syntax](/docs/actions/workflow-syntax) | |
| 16 | 16 | | Connect an AI agent | [Agents](/docs/agents/overview) and [MCP](/docs/agents/mcp) | |
| 17 | 17 | | Give an agent a goal and get a pull request back, with your own model key | [Agent tasks](/docs/agents/tasks) | |
| 18 | +| Track agent work on a board, with shared memory and project instructions | [Projects](/docs/agents/projects) | | |
| 18 | 19 | | See what needs you and what your agents did since yesterday | [Today](/docs/agents/today) | |
| 19 | 20 | | Have one of your agents review pull requests for bugs, like Bugbot | [Agent review](/docs/agents/review) | |
| 20 | 21 | | Script against Diffinery | [REST API guide](/docs/reference/rest-api), [REST API reference](/docs/api) and [CLI reference](/docs/reference/cli) | |
modifiedapps/diffinery/docs/reference/limits.md+4−0View file
| @@ -237,6 +237,10 @@ | ||
| 237 | 237 | | Custom command length | 2,000 characters | ``422 `command` is longer than 2000 characters``. | |
| 238 | 238 | | Transcript | 20,000 lines per run, 32 KiB per line | Later output lines of a run aren't stored (Diffinery's own notes still are); a longer line is cut. | |
| 239 | 239 | | Transcript lines per MCP call | 500 | `agent_task` returns at most 500 lines after `after`. | |
| 240 | +| Tasks running at once per repository | 1 to 10, default 3 | Set under **Settings → Project**. Further tasks, follow-ups and retries queue and start oldest first. Agent reviews don't count. See [Projects](/docs/agents/projects#how-many-at-once). | | |
| 241 | +| Project memory | 40,000 characters, last 50 versions kept | ``422 memory is longer than 40000 characters``. | | |
| 242 | +| Project instructions | 10,000 characters | ``422 `instructions` is longer than 10000 characters``. | | |
| 243 | +| Project conversation post | 20,000 characters | ``422 `body` is longer than 20000 characters``. The conversation API and `project_posts` return at most 100 posts per call. | | |
| 240 | 244 | |
| 241 | 245 | See [Agent tasks](/docs/agents/tasks). For the Today view's limits (repositories active in the last 30 days, at most 100 of them, 50 open pull requests each), see [Today](/docs/agents/today). |
| 242 | 246 |
modifiedapps/diffinery/docs/security/audit-log.md+2−0View file
| @@ -77,6 +77,8 @@ | ||
| 77 | 77 | | `task.start` | Someone starts an [agent task](/docs/agents/tasks) | `owner/repo#<task number>` | `agent`, `runtime` | |
| 78 | 78 | | `task.message`, `task.retry` | The person who started a task sends a follow-up or retries it | `owner/repo#<task number>` | none | |
| 79 | 79 | | `task.stop` | Someone stops a task (its starter, its agent or a repository admin) | `owner/repo#<task number>` | none | |
| 80 | +| `project.memory` | Someone saves or restores the [project](/docs/agents/projects) memory | `owner/repo` | `version`, `length`, and `restored` (the version restored) for a restore | | |
| 81 | +| `project.settings` | A repository admin changes **Settings → Project** | `owner/repo` | `max_running`, `instructions_length` | | |
| 80 | 82 | | `review.settings` | A repository admin turns [agent review](/docs/agents/review) on or off, or changes its settings | `owner/repo` | `enabled`, `agent`, `runtime`, `trigger`, `autofix`, `daily_limit` | |
| 81 | 83 | | `review.request` | A person asks for an agent review with **Request agent review** or `POST /repos/{owner}/{repo}/pulls/{number}/diffinery/agent-review` | `owner/repo#<pull request number>` | none | |
| 82 | 84 | | `model_key.set`, `model_key.delete` | You save, replace or delete a model API key under **Settings → Model access** (or `PUT`/`DELETE /api/v3/diffinery/model-keys/{provider}`) | the provider (`anthropic`, `openai` or `openrouter`) | `hint` (the key's last four characters) and `opted_in_at` (when you accepted the provider's terms) for `model_key.set` | |
modifiedapps/diffinery/src/docs/api-meta.ts+63−5View file
| @@ -47,6 +47,11 @@ | ||
| 47 | 47 | "GET /orgs/{org}/actions/secrets": { scope: "admin" }, |
| 48 | 48 | "PUT /orgs/{org}/actions/secrets/{name}": { scope: "admin" }, |
| 49 | 49 | "DELETE /orgs/{org}/actions/secrets/{name}": { scope: "admin" }, |
| 50 | + "GET /orgs/{org}/actions/secrets/{name}": { scope: "admin" }, | |
| 51 | + "GET /orgs/{org}/actions/secrets/{name}/repositories": { scope: "admin" }, | |
| 52 | + "PUT /orgs/{org}/actions/secrets/{name}/repositories": { scope: "admin" }, | |
| 53 | + "PUT /orgs/{org}/actions/secrets/{name}/repositories/{repoId}": { scope: "admin" }, | |
| 54 | + "DELETE /orgs/{org}/actions/secrets/{name}/repositories/{repoId}": { scope: "admin" }, | |
| 50 | 55 | "POST /diffinery/tokens": { scope: "admin", sessionOnly: true }, |
| 51 | 56 | "DELETE /diffinery/tokens/{id}": { scope: "admin" }, |
| 52 | 57 | "POST /diffinery/agents": { scope: "admin", sessionOnly: true }, |
| @@ -57,6 +62,9 @@ | ||
| 57 | 62 | "POST /repos/{owner}/{repo}/diffinery/tasks": { scope: "write", sessionOnly: true }, |
| 58 | 63 | "POST /repos/{owner}/{repo}/diffinery/tasks/{number}/messages": { scope: "write", sessionOnly: true }, |
| 59 | 64 | "POST /repos/{owner}/{repo}/diffinery/tasks/{number}/retry": { scope: "write", sessionOnly: true }, |
| 65 | + "POST /repos/{owner}/{repo}/diffinery/project/posts": { scope: "write", sessionOnly: true }, | |
| 66 | + "PUT /repos/{owner}/{repo}/diffinery/project/memory": { scope: "write", sessionOnly: true }, | |
| 67 | + "PUT /repos/{owner}/{repo}/diffinery/project/settings": { scope: "write", sessionOnly: true }, | |
| 60 | 68 | "PUT /repos/{owner}/{repo}/diffinery/agent-review": { scope: "admin", sessionOnly: true }, |
| 61 | 69 | "POST /diffinery/agents/{login}/tokens": { scope: "admin", sessionOnly: true }, |
| 62 | 70 | "DELETE /diffinery/agents/{login}": { scope: "admin" }, |
| @@ -1257,14 +1265,29 @@ | ||
| 1257 | 1265 | access: "admin", |
| 1258 | 1266 | status: 204, |
| 1259 | 1267 | }, |
| 1260 | - "GET /orgs/{org}/actions/secrets": { summary: "List organization secrets", description: "Names and update times only.", access: "org-admin" }, | |
| 1268 | + "GET /orgs/{org}/actions/secrets": { summary: "List organization secrets", description: "Names, update times and `visibility` (`all`, `private` or `selected`), never values.", access: "org-admin" }, | |
| 1269 | + "GET /orgs/{org}/actions/secrets/{name}": { summary: "Get an organization secret", description: "Its name, update time and `visibility`, never the value. 404 when there is no such secret.", access: "org-admin" }, | |
| 1261 | 1270 | "PUT /orgs/{org}/actions/secrets/{name}": { |
| 1262 | 1271 | summary: "Set an organization secret", |
| 1263 | - description: "Available to every repository in the organization. Names are upper-cased and must match `[A-Z_][A-Z0-9_]*`. People only. Audited as `org.secret.set`.", | |
| 1272 | + description: "Creates or updates the secret. `visibility` says which of the organization's repositories get it: `all` (the default for a new secret), `private` (private and internal ones) or `selected` (those in `selected_repository_ids`). An update without them keeps the secret's visibility and selection. Names are upper-cased and must match `[A-Z_][A-Z0-9_]*`. People only. Audited as `org.secret.set`. See /docs/actions/secrets-and-variables#organization-secrets.", | |
| 1264 | 1273 | access: "org-admin", |
| 1265 | 1274 | status: 204, |
| 1266 | - body: { value: ["string", "Secret value.", true] }, | |
| 1275 | + body: { | |
| 1276 | + value: ["string", "Secret value.", true], | |
| 1277 | + visibility: ["string", "`all`, `private` or `selected` (422 otherwise)."], | |
| 1278 | + selected_repository_ids: ["integer[]", "With `selected`: the repositories' numeric ids. An id that isn't one of the organization's repositories gets 422."], | |
| 1279 | + }, | |
| 1267 | 1280 | }, |
| 1281 | + "GET /orgs/{org}/actions/secrets/{name}/repositories": { summary: "List a secret's selected repositories", description: "`{ total_count, repositories }` for a secret with `visibility: selected`; 409 `the secret's visibility isn't selected` otherwise.", access: "org-admin" }, | |
| 1282 | + "PUT /orgs/{org}/actions/secrets/{name}/repositories": { | |
| 1283 | + summary: "Replace a secret's selected repositories", | |
| 1284 | + description: "Only for a secret with `visibility: selected` (409 otherwise). A repository that leaves the selection stops getting the secret from its next job. Audited as `org.secret.repositories`.", | |
| 1285 | + access: "org-admin", | |
| 1286 | + status: 204, | |
| 1287 | + body: { selected_repository_ids: ["integer[]", "Every repository that should get the secret.", true] }, | |
| 1288 | + }, | |
| 1289 | + "PUT /orgs/{org}/actions/secrets/{name}/repositories/{repoId}": { summary: "Add a repository to a secret's selection", description: "Only for a secret with `visibility: selected` (409 otherwise). `repoId` is the repository's numeric id. Audited as `org.secret.repository.add`.", access: "org-admin", status: 204 }, | |
| 1290 | + "DELETE /orgs/{org}/actions/secrets/{name}/repositories/{repoId}": { summary: "Remove a repository from a secret's selection", description: "Only for a secret with `visibility: selected` (409 otherwise). The repository stops getting the secret from its next job. Audited as `org.secret.repository.remove`.", access: "org-admin", status: 204 }, | |
| 1268 | 1291 | "DELETE /orgs/{org}/actions/secrets/{name}": { summary: "Delete an organization secret", description: "People only. 404 when the organization has no secret with this name. Audited as `org.secret.delete`.", access: "org-admin", status: 204 }, |
| 1269 | 1292 | "GET /orgs/{org}/actions/variables": { |
| 1270 | 1293 | summary: "List organization variables", |
| @@ -1396,9 +1419,9 @@ | ||
| 1396 | 1419 | }, |
| 1397 | 1420 | "GET /repos/{owner}/{repo}/diffinery/tasks": { |
| 1398 | 1421 | summary: "List agent tasks", |
| 1399 | - description: "The repository's agent tasks, newest first. Needs write access: transcripts show an agent's reasoning and command output. `state` filters: `running`, `ready`, `failed` or `stopped`.", | |
| 1422 | + description: "The repository's agent tasks, newest first. Needs write access: transcripts show an agent's reasoning and command output. `state` filters: `queued`, `running`, `ready`, `failed` or `stopped`, or `active` for running and queued together.", | |
| 1400 | 1423 | access: "write", |
| 1401 | - query: { state: ["string", "`running`, `ready`, `failed` or `stopped`."], per_page: ["integer", "At most 100 (default 50)."] }, | |
| 1424 | + query: { state: ["string", "`queued`, `running`, `ready`, `failed`, `stopped` or `active` (running or queued)."], per_page: ["integer", "At most 100 (default 50)."] }, | |
| 1402 | 1425 | }, |
| 1403 | 1426 | "POST /repos/{owner}/{repo}/diffinery/tasks": { |
| 1404 | 1427 | summary: "Start an agent task", |
| @@ -1415,6 +1438,41 @@ | ||
| 1415 | 1438 | command: ["string", "For `custom`: the shell command to run."], |
| 1416 | 1439 | }, |
| 1417 | 1440 | }, |
| 1441 | + "GET /repos/{owner}/{repo}/diffinery/project": { | |
| 1442 | + summary: "Get the project", | |
| 1443 | + description: "The repository's project: `settings` (`max_running`, `instructions`), `memory` (`body`, `version`, `updated_by`, `updated_at`) and `board`, the agent tasks by column (`waiting`, `working`, `queued`, `review`, `landing`, `done`, `idle`). Agent reviews aren't on the board. Needs write access. See /docs/agents/projects.", | |
| 1444 | + access: "write", | |
| 1445 | + }, | |
| 1446 | + "GET /repos/{owner}/{repo}/diffinery/project/posts": { | |
| 1447 | + summary: "List the project conversation", | |
| 1448 | + description: "Posts and task events, oldest first: those after `after`, or the latest 100. Needs write access.", | |
| 1449 | + access: "write", | |
| 1450 | + query: { after: ["integer", "Return posts after this id (default 0)."], per_page: ["integer", "At most 100 (default 100)."] }, | |
| 1451 | + }, | |
| 1452 | + "POST /repos/{owner}/{repo}/diffinery/project/posts": { | |
| 1453 | + summary: "Post to the project conversation", | |
| 1454 | + description: "Markdown, at most 20,000 characters (422 otherwise). A person in a browser session only. 403 on an archived repository.", | |
| 1455 | + access: "write", | |
| 1456 | + status: 201, | |
| 1457 | + body: { body: ["string", "The post.", true] }, | |
| 1458 | + }, | |
| 1459 | + "GET /repos/{owner}/{repo}/diffinery/project/memory": { | |
| 1460 | + summary: "Get the project memory", | |
| 1461 | + description: "The current memory and its last 50 `versions` (`version`, `updated_by`, `updated_at`, `length`). Every agent task reads it as background notes; agent reviews don't. Needs write access.", | |
| 1462 | + access: "write", | |
| 1463 | + }, | |
| 1464 | + "PUT /repos/{owner}/{repo}/diffinery/project/memory": { | |
| 1465 | + summary: "Save or restore the project memory", | |
| 1466 | + description: "Saves `body` (at most 40,000 characters) as a new version, or restores an earlier version as a new one with `restore` (404 `no such memory version`). A person in a browser session only. Audited as `project.memory`.", | |
| 1467 | + access: "write", | |
| 1468 | + body: { body: ["string", "The new memory (Markdown)."], restore: ["integer", "A version number to restore instead."] }, | |
| 1469 | + }, | |
| 1470 | + "PUT /repos/{owner}/{repo}/diffinery/project/settings": { | |
| 1471 | + summary: "Change the project settings", | |
| 1472 | + description: "Project instructions every agent task and agent review gets, and how many tasks run at once. Tasks beyond `max_running` queue and start oldest first. A person in a browser session only. Audited as `project.settings`.", | |
| 1473 | + access: "admin", | |
| 1474 | + body: { max_running: ["integer", "1 to 10 (default 3)."], instructions: ["string", "At most 10,000 characters."] }, | |
| 1475 | + }, | |
| 1418 | 1476 | "GET /repos/{owner}/{repo}/diffinery/tasks/{number}": { summary: "Get an agent task", description: "The task, its runs and its pull request. Needs write access.", access: "write" }, |
| 1419 | 1477 | "GET /repos/{owner}/{repo}/diffinery/tasks/{number}/transcript": { |
| 1420 | 1478 | summary: "Read a task's transcript", |