|
| 1 | +--- |
| 2 | +name: sync-openapi-spec |
| 3 | +description: >- |
| 4 | + Sync the public Oz Agent API OpenAPI spec from warp-server into the docs |
| 5 | + repo, regenerating `developers/agent-api-openapi.yaml` (the file that |
| 6 | + powers the Scalar API reference at `docs.warp.dev/api`). Use when the |
| 7 | + warp-server public API has changed, when the Scalar reference looks |
| 8 | + stale, or on a scheduled cadence to keep the public API docs aligned |
| 9 | + with the canonical spec. |
| 10 | +--- |
| 11 | + |
| 12 | +# Sync OpenAPI Spec |
| 13 | + |
| 14 | +Keep `developers/agent-api-openapi.yaml` in sync with the canonical spec at `warp-server/public_api/openapi.yaml`. |
| 15 | + |
| 16 | +**Direction:** warp-server → docs. The server spec is the source of truth. The docs file is a curated subset (drops `memory_stores`/`harness-support` and a handful of internal `agent` paths) that Scalar renders on `docs.warp.dev/api`. |
| 17 | + |
| 18 | +## Repos |
| 19 | + |
| 20 | +This skill requires two repos in the agent's environment: |
| 21 | + |
| 22 | +- `warpdotdev/warp-server` — source of truth (`public_api/openapi.yaml`) |
| 23 | +- `warpdotdev/docs` — Scalar-facing copy (`developers/agent-api-openapi.yaml`) |
| 24 | + |
| 25 | +## Prerequisites |
| 26 | + |
| 27 | +- Both repos checked out, with `warp-server` reachable from the docs repo (default assumption: sibling directories — `../warp-server/public_api/openapi.yaml`) |
| 28 | +- Python 3 with `pyyaml` installed (`pip install pyyaml` or `pip install --break-system-packages pyyaml` in managed environments) |
| 29 | +- `gh` CLI authenticated against `warpdotdev/docs` |
| 30 | + |
| 31 | +## Workflow |
| 32 | + |
| 33 | +### Step 1: Self-test |
| 34 | + |
| 35 | +Run the script's self-test first to confirm `pyyaml` is available and the transform logic still passes: |
| 36 | + |
| 37 | +```bash |
| 38 | +python3 .agents/skills/sync-openapi-spec/scripts/sync_openapi.py --mode self-test |
| 39 | +``` |
| 40 | + |
| 41 | +Expected output: `self-test: OK`. If this fails, fix the script before going further. |
| 42 | + |
| 43 | +### Step 2: Diff source against target |
| 44 | + |
| 45 | +```bash |
| 46 | +python3 .agents/skills/sync-openapi-spec/scripts/sync_openapi.py \ |
| 47 | + --mode diff \ |
| 48 | + --source ../warp-server/public_api/openapi.yaml \ |
| 49 | + --target developers/agent-api-openapi.yaml |
| 50 | +``` |
| 51 | + |
| 52 | +The script prints structural drift grouped into: |
| 53 | +- Paths added/removed/modified relative to the expected docs subset |
| 54 | +- Component schemas added/removed/modified |
| 55 | +- Top-level changes (`openapi`, `info`, `servers`) |
| 56 | +- Unclassified tags or paths (anything not covered by `EXCLUDED_TAGS` or the `agent`/`schedules` allowlist) |
| 57 | + |
| 58 | +If the script reports `In sync. No changes needed.`, stop here. |
| 59 | + |
| 60 | +### Step 3: Triage unclassified items |
| 61 | + |
| 62 | +Any line prefixed with `!` flags a tag or path the policy doesn't recognize. Do NOT auto-include or auto-drop these. For each one: |
| 63 | +1. Read the corresponding handler in `warp-server/router/handlers/public_api/` to confirm whether the endpoint is intended to be public. |
| 64 | +2. If the endpoint is public-facing, leave the policy alone — the script will include it on the next `apply`. |
| 65 | +3. If the endpoint should remain hidden, extend `EXCLUDED_TAGS` or `EXCLUDED_PATHS` in `scripts/sync_openapi.py` and update `references/sync-policy.md` to record the rationale. |
| 66 | +4. Re-run `--mode diff` until no `!` lines remain. |
| 67 | + |
| 68 | +### Step 4: Apply the regenerated subset |
| 69 | + |
| 70 | +```bash |
| 71 | +python3 .agents/skills/sync-openapi-spec/scripts/sync_openapi.py \ |
| 72 | + --mode apply \ |
| 73 | + --source ../warp-server/public_api/openapi.yaml \ |
| 74 | + --target developers/agent-api-openapi.yaml |
| 75 | +``` |
| 76 | + |
| 77 | +This rewrites `developers/agent-api-openapi.yaml` with the regenerated subset. Apply mode validates every `$ref` in the output before writing the file: if any reference is unresolved, the script exits with code 3 and refuses to write. On success it prints `All $refs resolve in the regenerated spec.` |
| 78 | + |
| 79 | +### Step 5: Validate the regenerated spec |
| 80 | + |
| 81 | +Apply mode already catches unresolved `$ref`s (see Step 4). Run these as belt-and-braces integration checks: |
| 82 | + |
| 83 | +```bash |
| 84 | +# Astro picks up the new YAML and parses it through Scalar's runtime. |
| 85 | +npm run build |
| 86 | +``` |
| 87 | + |
| 88 | +Optional, recommended when many schemas changed (full OpenAPI lint): |
| 89 | +```bash |
| 90 | +npx @redocly/cli lint developers/agent-api-openapi.yaml |
| 91 | +``` |
| 92 | + |
| 93 | +If `npm run build` fails, the most common cause is a malformed path or missing `description` field. Schema-ref breakage is already prevented by Step 4's validator. |
| 94 | + |
| 95 | +### Step 6: Commit and open a PR |
| 96 | + |
| 97 | +```bash |
| 98 | +git checkout -b sync-openapi-spec/YYYY-MM-DD |
| 99 | +git add developers/agent-api-openapi.yaml |
| 100 | +git commit -m "docs: sync agent-api-openapi.yaml from warp-server |
| 101 | +
|
| 102 | +Co-Authored-By: Oz <oz-agent@warp.dev>" |
| 103 | +git push origin sync-openapi-spec/YYYY-MM-DD |
| 104 | +``` |
| 105 | + |
| 106 | +Open a draft PR with: |
| 107 | +- **Title:** `docs: sync agent-api-openapi.yaml from warp-server` |
| 108 | +- **Body:** include the full output from Step 2 (paths/schemas added/removed/modified) so reviewers can see exactly what changed and why. |
| 109 | +- **Labels:** `documentation` |
| 110 | + |
| 111 | +Use `report_pr` to surface the PR link. |
| 112 | + |
| 113 | +### Step 7: Report |
| 114 | + |
| 115 | +Summarize: |
| 116 | +- Source commit SHA used (capture with `cd ../warp-server && git rev-parse HEAD`) |
| 117 | +- Number of paths added / removed / modified in the regenerated subset |
| 118 | +- Number of schemas added / removed / modified |
| 119 | +- Any items flagged for triage and how they were resolved |
| 120 | +- Or confirm `In sync. No changes needed.` |
| 121 | + |
| 122 | +## Sync policy |
| 123 | + |
| 124 | +The policy is encoded in `scripts/sync_openapi.py` as `EXCLUDED_TAGS` and `EXCLUDED_PATHS`. See `references/sync-policy.md` for the rationale behind each entry and the rules for adding new ones. |
| 125 | + |
| 126 | +## Schedule |
| 127 | + |
| 128 | +Run on demand whenever `warp-server/public_api/openapi.yaml` has changed materially since the last docs sync, or on a weekly cadence as a safety net. |
| 129 | + |
| 130 | +## Troubleshooting |
| 131 | + |
| 132 | +### `ModuleNotFoundError: No module named 'yaml'` |
| 133 | +Install pyyaml: `pip install pyyaml`. On Debian-based images with externally managed Python, use `pip install --break-system-packages pyyaml`. |
| 134 | + |
| 135 | +### `error: source spec not found at ...` |
| 136 | +The `warp-server` repo isn't where the script expected. Pass `--source /absolute/path/to/warp-server/public_api/openapi.yaml`. |
| 137 | + |
| 138 | +### `--mode apply` exits with code 3 and "unresolved $refs" |
| 139 | +Apply mode refuses to write the target if any `$ref` in the regenerated spec doesn't resolve to a defined component. The script's recursive `$ref` walker is supposed to keep transitive references (`allOf`/`oneOf`/`anyOf`/`items`/`additionalProperties`/etc.) reachable, so this means either: |
| 140 | +- The source spec itself has a dangling reference (fix it in `warp-server`), or |
| 141 | +- The walker is missing a reference shape (file a bug against the script). |
| 142 | + |
| 143 | +The error output lists the offending JSON pointer paths so you can locate the reference quickly. Apply will not overwrite `developers/agent-api-openapi.yaml` while this fails. |
| 144 | + |
| 145 | +### Diff shows changes that aren't in the source spec |
| 146 | +Make sure `../warp-server` is on the branch you intended to compare against (usually `develop`). Run `cd ../warp-server && git status -sb && git --no-pager log -1` to confirm. |
| 147 | + |
| 148 | +## References |
| 149 | + |
| 150 | +- `scripts/sync_openapi.py` — the diff/apply tool |
| 151 | +- `references/sync-policy.md` — exclusion policy and how to extend it |
| 152 | +- `../warp-server/.agents/skills/update-open-api-spec/SKILL.md` — server-side workflow for editing the canonical spec |
| 153 | +- `../../../src/pages/api.astro` — how the docs site loads the YAML into Scalar |
0 commit comments