docugate 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,494 +1,503 @@
1
- # docugate
2
-
3
- DocuGate publishes documentation straight from the markdown in your GitHub repositories. This package is its command line, and it does three things:
4
-
5
- - **Keeps the docs true.** `docugate sync` reads what changed in your code, works out which pages that made wrong, and opens a pull request with the fix. Nobody has to remember to update the docs. [More](#docs-that-keep-up-with-your-code).
6
- - **Explains your app.** A walkthrough pill on your running app shows any developer what each element on screen is and where its data comes from. [More](#tours).
7
- - **Checks the result.** `docugate check` reads your docs and tours the way DocuGate will, so problems show up in CI instead of on the published page.
8
-
9
- ```sh
10
- npm i -g docugate
11
- docugate # opens DocuGate in your terminal: pick what to do next
12
- ```
13
-
14
- Type `docugate` on its own and it opens, the way `claude` does: where your account, docs and space stand, and every next step in a list, with the one worth doing now under Enter. Arrow keys pick; in Git Bash and other terminals without them, type the number.
15
-
16
- ---
17
-
18
- ## Quick start, step by step
19
-
20
- Follow these in order. Every question during setup is a numbered choice: type
21
- the number and press Enter, or just press Enter for the suggested one.
22
-
23
- **1. Open your project's folder.**
24
-
25
- ```sh
26
- cd my-app
27
- ```
28
-
29
- Use the root of the repository: the folder with `.git` and `package.json` in
30
- it. If your frontend and backend are two repositories, do steps 1 to 3 in each.
31
-
32
- **2. Install DocuGate in the project.**
33
-
34
- ```sh
35
- npm i docugate
36
- ```
37
-
38
- Like any other package: everyone who clones the project gets the same version,
39
- and CI too. (A repository with no `package.json`, like a Go or Python backend,
40
- can install the command on the computer instead with `npm i -g docugate`, and
41
- then drop the `npx` from the commands below.)
42
-
43
- **3. Set everything up.**
44
-
45
- ```sh
46
- npx docugate init
47
- ```
48
-
49
- It asks, one at a time:
50
-
51
- | Question | What to choose |
52
- | --- | --- |
53
- | What is in this repository? | **1** Frontend, **2** Backend, or **3** Both (a `frontend/` and a `backend/` folder in one repository). It suggests one from your folders. |
54
- | Sign in to DocuGate? | **1** opens your browser to sign in with GitHub. You come back to your editor when it is done. **2** skips it; `docugate login` does it later. |
55
- | Where should the documentation live? | **1** creates a new space, with a new GitHub repository on your account to hold its markdown (`<project>-docs`, with a first page). Or pick one of your spaces. The pill then links to the published docs. |
56
- | How often should DocuGate check your docs still match the code? | On every push, daily (suggested, fewer AI runs), weekly, or never. The answer is saved as `freshness`; `docugate sync init` then adds the GitHub Action that does the checking. |
57
- | Set up the tour: which AI should write it? | **1** IBM Bob reads your code and writes the tour. **2** IBM watsonx is coming soon. **3** skips it; you can write the tour in the browser. Frontend and both only. |
58
- | Add the DocuGate pill to your app? | **1** adds a few lines to your `index.html` or Next.js layout that load the pill in development only. |
59
-
60
- IBM Bob reads its API key from the `BOB_API_KEY` environment variable. If you
61
- saved it under another name (say `IBM_BOB_KEY`), setup finds it and asks before
62
- using it. If there is none, setup opens the page where you create a key and lets you paste it for
63
- that one run; DocuGate never saves it. To set it for good (then open a new terminal):
64
-
65
- ```powershell
66
- [Environment]::SetEnvironmentVariable("BOB_API_KEY", "<key>", "User") # Windows
67
- export BOB_API_KEY=<key> # macOS, Linux
68
- ```
69
-
70
- Setup writes `docugate.json` and `.docugate/tour/`. Commit both, so the next
71
- person who clones the repository needs no setup. When setup finishes it starts
72
- the tour server in the background, so the pill is there the first time you open
73
- the app (`--no-serve` skips that).
74
-
75
- **4. Run your app as usual, and open it.**
76
-
77
- ```sh
78
- npm run dev
79
- ```
80
-
81
- Setup added a `predev` script, so `npm run dev` starts the DocuGate tour server
82
- first (one line, "DocuGate tour ready") and then your app. The pill only
83
- appears while that server runs, which is why it never shows in production.
84
-
85
- The DocuGate pill sits in the bottom-right corner. Click it:
86
-
87
- - **Walkthrough** lists the page's steps with your progress. Click a step to
88
- go to it, the pencil to fix it, or **Add a step**.
89
- - **Inspector** is one switch. With it on, click anything: you see what it is
90
- and where its data comes from, and you can edit it. Click something with no
91
- explanation yet, and the same click lets you add one.
92
-
93
- Every change is saved straight into `.docugate/tour/`, so it shows up in `git diff`.
94
-
95
- **5. Keep the tour true.**
96
-
97
- ```sh
98
- npx docugate check
99
- ```
100
-
101
- It checks every step against the code and warns about any that went stale,
102
- for example after a rename. Put it in CI so a stale tour fails the build (see
103
- [Keeping tours true](#keeping-tours-true)).
104
-
105
- **Later, when you need them:**
106
-
107
- ```sh
108
- npx docugate # the menu: pick what to do next
109
- npx docugate status # where things stand, and what to do next
110
- npx docugate sync # update the docs from what changed in the code
111
- npx docugate login # sign in again, or on a new computer
112
- npx docugate whoami # who am I signed in as?
113
- npx docugate tour init # let IBM Bob write tours for screens that have none
114
- npx docugate tour install # add the pill again (--remove takes it out)
115
- npx docugate tour serve # start the tour server by hand
116
- npx docugate logout # disconnect this computer
117
- ```
118
-
119
- **Something not working?**
120
-
121
- | You see | Do this |
122
- | --- | --- |
123
- | No pill in the app | Start the app with `npm run dev` (it starts the tour server), or run `npx docugate tour serve`, then refresh the page. |
124
- | Bob can't run | Choose IBM Bob again in `docugate init` to paste a key, or install Bob Shell: https://bob.ibm.com/docs/shell/getting-started/install-and-setup |
125
- | Port 4178 is busy | `docugate tour serve --port 4179` and `docugate tour install --port 4179` |
126
- | "Already set up in ..." | You ran it in a subfolder. Run commands from the folder it names. |
127
-
128
- ---
129
-
130
- ## A developer space
131
-
132
- ```sh
133
- docugate developers
134
- ```
135
-
136
- One guided run sets up the docs developers read before they build on your API:
137
-
138
- 1. Signs you in, if you are not.
139
- 2. Finds your OpenAPI file (`openapi.json`, `.yaml`, `swagger.*`) and says how many endpoints it describes.
140
- 3. Writes the first pages, `index.md`, `quickstart.md`, `authentication.md` and `errors.md`, in `docs/developers/`, where they are missing. It never overwrites a file.
141
- 4. Offers to commit and push them, since a space reads GitHub, not your disk.
142
- 5. Creates a public space for them, or uses the one that already reads this repository, and saves it in `docugate.json`.
143
-
144
- On Pro it carries on:
145
-
146
- 6. Claims a subdomain such as `acme.trydocugate.site`, live at once.
147
- 7. Asks where the API console sends requests from: the reader's browser, or through DocuGate with no CORS setup.
148
- 8. Switches on API keys, with a scope per OpenAPI tag to start from, makes the verify secret, offers to put it in `.env` when git ignores that file, and prints the lines your Express, Hono or Fastify backend needs.
149
-
150
- Everything it sets stays editable in the space's settings on [trydocugate.site](https://www.trydocugate.site/dashboard).
151
-
152
- ## Docs that keep up with your code
153
-
154
- Documentation goes stale because updating it is a chore nobody owns. `docugate sync` does the chore: it reads what changed in the code, finds the pages those changes made wrong, asks an AI model to correct them, and gives you the edits to review.
155
-
156
- ```sh
157
- npx docugate sync --dry-run # free and instant: which pages are probably out of date
158
- npx docugate sync # write the edits into your docs folder
159
- npx docugate sync --pr # push them and open a pull request instead
160
- ```
161
-
162
- `sync` needs an AI key of your own, in `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` (set `DOCUGATE_AI_BASE_URL` to use another OpenAI-compatible service). It talks to the provider directly: nothing goes through DocuGate's servers, and it works without a DocuGate account.
163
-
164
- **What it does, step by step**
165
-
166
- 1. **Reads the changes** from git: the commits and a trimmed diff of each changed file, since the last sync. The first run looks back a day, a week or one commit, depending on `freshness`. `--since 7d`, a branch or a commit overrides it. Documentation, lockfiles, build output, binaries and anything that looks like a secret (`.env`, `*.pem`, files named `secret` or `credentials`) are never read.
167
- 2. **Finds the pages that are affected.** A page counts when it names a changed file, mentions something the change added or removed (a function, a route, an environment variable), or is pinned to that code in `sync.map`. This part is free, and it is all `--dry-run` does.
168
- 3. **Asks the model** for the new text of those pages, and only those. It is told to change what the diff requires and nothing else, to invent nothing, and to treat the code as data rather than instructions.
169
- 4. **Checks the answer before writing it.** An edit is dropped unless it is a markdown page inside your docs folder, within 300 pages, without front matter. After writing, `docugate check` runs again, and an edit that breaks a link is put back as it was.
170
- 5. **Hands it over.** With `--pr` the edits go on one branch, `docugate/sync`, and one pull request that lists every page and why it changed. Each run updates that same pull request rather than opening another. Nothing is ever merged for you, and closing the pull request changes nothing. The sync moves forward only when you merge it.
171
-
172
- **Make it automatic**
173
-
174
- ```sh
175
- npx docugate sync init
176
- ```
177
-
178
- This writes `.github/workflows/docugate-sync.yml`, timed by `freshness` in `docugate.json`:
179
-
180
- | `freshness` | When it runs |
181
- | --- | --- |
182
- | `push` | On every push to your default branch. |
183
- | `daily` | Every day. |
184
- | `weekly` | Every Monday (the default). |
185
- | `off` | Never. No workflow is written. |
186
-
187
- Do two things on GitHub, once: add your AI key as a repository secret named `ANTHROPIC_API_KEY` (or `OPENAI_API_KEY`), and under Settings, Actions, General, tick "Allow GitHub Actions to create and approve pull requests". `sync init` prints both steps. The workflow is pinned to the version that wrote it, so a new release never changes what your CI does by surprise; run `sync init --force` to upgrade it. A sync's own commits never start another sync.
188
-
189
- **A heads-up on your own machine**
190
-
191
- ```sh
192
- npx docugate sync hook install
193
- ```
194
-
195
- After every commit, a git hook runs `sync --dry-run` and, if pages look out of date, says so in one line. It sends nothing, changes nothing and never fails a commit. `sync hook remove` takes it out.
196
-
197
- **Settings**, in `docugate.json`:
198
-
199
- ```json
200
- {
201
- "freshness": "weekly",
202
- "sync": {
203
- "provider": "anthropic",
204
- "model": "claude-sonnet-5-5",
205
- "include": ["server/**", "src/**"],
206
- "exclude": ["**/*.test.ts"],
207
- "map": { "docs/api.md": ["server/routes/**"] },
208
- "maxFiles": 10,
209
- "digest": false
210
- }
211
- }
212
- ```
213
-
214
- | Key | Meaning |
215
- | --- | --- |
216
- | `provider` | `anthropic` or `openai`. Defaults to whichever key is set. |
217
- | `model` | The model to use. |
218
- | `include` / `exclude` | Path globs for the code worth documenting. `*` stays within a folder, `**` crosses folders. |
219
- | `map` | Pin a page to the code it documents, when its text never names the files. DocuGate does not read front matter, so this is where that link lives. |
220
- | `maxFiles` | The most pages one run may change (10). |
221
- | `digest` | Also write a short "what changed" page, `changes/<date>.md`, for each run. |
222
-
223
- `sync` also lists tour stops that no longer match the code. It only reports them: a tour is yours, and DocuGate never edits one.
224
-
225
- **When it says no**
226
-
227
- | You see | Do this |
228
- | --- | --- |
229
- | "No AI key found" | Set `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` where you run it, or as an Actions secret. |
230
- | "shallow clone" | In GitHub Actions, set `fetch-depth: 0` on the checkout step. `sync init` already does. |
231
- | Pushed, but no pull request | Allow Actions to create pull requests (above), or set `GITHUB_TOKEN` when running it by hand. |
232
- | "Skipped: the changes only touch documentation" | Working as intended. A merged sync, or a docs-only change, never starts a sync. |
233
-
234
- ---
235
-
236
- ## Moving around
237
-
238
- Run `docugate` in a terminal and you get a menu: arrow keys to move, type to search, Enter to run, Esc to leave. It shows where you are (signed in or not, how many pages, how far the docs are behind the code) and puts the step worth taking next under Enter, with a dot beside it. Not connected to DocuGate yet? Connecting your account is that step. When a command finishes, the menu comes back.
239
-
240
- - `docugate status` prints the same picture: your account, your docs, the sync (last run, whether the workflow and hook are on, how many commits and pages are behind), your tour, and one line saying what to do next. `--json` is for scripts.
241
- - `docugate help <command>`, or `docugate <command> --help`, shows one command's options and examples.
242
- - Mistype and it helps: `docugate chekc` suggests `check`, and an option a command does not have is an error with the nearest real one, not silently ignored.
243
- - `docugate completion powershell|bash|zsh` prints a completion script.
244
- - In CI, in a pipe, or with `--no-input`, nothing is ever asked: the menu does not open, the help prints as plain text, and a command that needs an answer fails with what to do. To use your DocuGate account in CI, set `DOCUGATE_TOKEN`.
245
-
246
- ---
247
-
248
- ## Tours
249
-
250
- A tour helps a developer who is new to a codebase see what each element on screen is and where its data comes from. For each screen there is one markdown file in `.docugate/tour/`. Each file has front matter with a `route` and a `title`, then one `##` section per stop.
251
-
252
- **Example stop:**
253
-
254
- ```markdown
255
- ---
256
- route: /invoices/:id
257
- title: Invoice detail
258
- ---
259
-
260
- ## Total
261
- target: [data-tour="invoice-total"]
262
- data: GET /api/invoices/:id → total
263
- code: frontend/src/screens/InvoiceDetail.tsx
264
- source: backend/src/billing.ts
265
- docs: https://example.com/docs/billing
266
-
267
- The amount due: the subtotal plus tax, computed by `totals()` in the backend.
268
- ```
269
-
270
- Fields:
271
-
272
- | Field | Required | Meaning |
273
- | --- | --- | --- |
274
- | `target` | yes | CSS selector for the element. Prefer `[data-tour="…"]`. |
275
- | `data` | no | Request and field: `METHOD /path → field`. |
276
- | `code` | yes | File that renders the element, relative to the repository root. |
277
- | `source` | no | File where the value is computed, when that is elsewhere. |
278
- | `docs` | no | URL to relevant documentation. |
279
-
280
- The prose paragraph after the fields explains what the element is and why its value is what it is.
281
-
282
- Tour files are yours. `docugate tour init` never overwrites a file that already exists.
283
-
284
- ---
285
-
286
- ## The pill
287
-
288
- When `docugate tour serve` is running, the pill sits in a corner of your app,
289
- like the Next.js dev indicator. Drag it to any corner. Click it for two things:
290
-
291
- - **Walkthrough.** The page's steps as a checklist with progress. Start from
292
- any step: the page dims, a ring marks the element, and a card says what it
293
- is and where its data comes from. Each step has a pencil to fix it, and
294
- **Add a step** adds one.
295
- - **Inspector.** One switch. With it on, clicking an element shows its step,
296
- with **Edit** to correct what the AI or anyone else got wrong, and **Remove**.
297
- Clicking an element with no step lets you add it, and tells you which
298
- `data-tour` attribute to put on it. Code and source files open in your
299
- editor at the element's line.
300
-
301
- The pill shows on every page while the server runs, including pages with no
302
- tour yet, so their first step can be added from the browser.
303
-
304
- `docugate tour install` adds the pill for you. It only loads when the app runs
305
- on `localhost` and the tour server answers, so it never shows in production.
306
-
307
- ---
308
-
309
- ## Keeping tours true
310
-
311
- A tour is only useful while it is true, so `docugate check` verifies every claim in `.docugate/tour/` against the code. For each stop it warns when:
312
-
313
- - the `code` file, or the `source` file, no longer exists;
314
- - the `code` file, and the files it imports, no longer mention the endpoint in `data`;
315
- - the `code` file no longer contains the `data-tour` value in `target` (a value passed through a prop counts);
316
- - a required field is missing, or two stops on one screen point at the same element.
317
-
318
- Rename `invoice-total` in a component and `check` tells you which stop went stale.
319
-
320
- It checks your docs folder too:
321
-
322
- - **Errors:** broken links between pages, links that leave the docs folder, two files that become the same URL, an unreadable `docugate.json`, an empty docs folder, or more than 300 pages.
323
- - **Warnings:** pages with no `# Title`, front matter, `.mdx` files, no landing page, and `sidebar` entries that match nothing.
324
-
325
- It exits with 1 when there are errors. Add `--strict` to fail on warnings too, which is how stale tour stops fail a build.
326
-
327
- Use it in CI:
328
-
329
- ```yaml
330
- # .github/workflows/docs.yml
331
- name: Docs
332
- on: [push, pull_request]
333
- jobs:
334
- check:
335
- runs-on: ubuntu-latest
336
- steps:
337
- - uses: actions/checkout@v4
338
- - uses: actions/setup-node@v4
339
- with:
340
- node-version: 22
341
- - run: npx docugate@0.2 check --strict
342
- ```
343
-
344
- Pin the version in CI, as above. Without a pin, the rules being enforced can change between two runs of the same workflow, which turns a green build red with nothing in the commit to explain it.
345
-
346
- ---
347
-
348
- ## Commands
349
-
350
- | Command | Main flags | What it does |
351
- | --- | --- | --- |
352
- | `docugate` | | In a terminal: the menu. Elsewhere: the help. |
353
- | `docugate status` | `--json` | Where things stand: account, docs, sync and tour, and what to do next. |
354
- | `docugate sync` | `--dry-run`, `--since <when>`, `--pr`, `--yes`, `--max-files <n>`, `--model <name>`, `--quiet` | Update the docs from what changed in the code. |
355
- | `docugate sync init` | `--freshness push\|daily\|weekly\|off`, `--force` | Add the GitHub Action that runs sync on a schedule or on every push. |
356
- | `docugate sync hook install` | | Tell you after each commit which pages the code left behind. |
357
- | `docugate sync hook remove` | | Remove that hook. |
358
- | `docugate init` | `--dir`, `--title`, `--role frontend\|backend\|both`, `--yes`, `--no-serve` | Set up this repository for DocuGate (interactive). |
359
- | `docugate developers` | `--dir`, `--yes` | Set up a developer space: API reference, guides and keys (interactive). |
360
- | `docugate check` | `--dir`, `--strict` | Check docs and tour files the way DocuGate will read them. |
361
- | `docugate help [command]` | | Every command, or one command's options and examples. |
362
- | `docugate completion <shell>` | | Print a completion script for bash, zsh or powershell. |
363
- | `docugate openapi` | `--from`, `--out`, `--include`, `--exclude`, `--redact`, `--check` | Prepare an OpenAPI spec for the API reference. |
364
- | `docugate login` | | Sign in to DocuGate with GitHub. |
365
- | `docugate logout` | | Sign out and delete saved credentials. |
366
- | `docugate whoami` | | Print the currently signed-in user. |
367
- | `docugate tour init` | `--max-cost <n>`, `--team-id <id>` | Write the first tour with IBM Bob (uses Bob Shell). |
368
- | `docugate tour serve` | `--port <n>` (default 4178), `--background` | Start the local server that serves tour data for the pill. |
369
- | `docugate tour install` | `--port <n>`, `--remove` | Add (or remove) the pill loader from your app's HTML or layout. |
370
- | `docugate tour export <file>` | | Write every tour screen to a single JSON file. |
371
-
372
- Run every command from the root of your repository. Every command also takes
373
- `--help`, and `--no-input` (which CI implies) to make sure it never stops to
374
- ask a question: it fails with what to do instead.
375
-
376
- ---
377
-
378
- ## Try it on the demo
379
-
380
- Clone [docugate-demo](https://github.com/Docugate/docugate-demo), a small full-stack app with a pre-written tour:
381
-
382
- ```sh
383
- git clone https://github.com/Docugate/docugate-demo
384
- cd docugate-demo
385
-
386
- # install dependencies and start the app
387
- npm install
388
- npm run dev
389
- ```
390
-
391
- In a second terminal:
392
-
393
- ```sh
394
- cd docugate-demo
395
- docugate tour serve
396
- ```
397
-
398
- Open the app in the browser. The pill appears in the bottom-right corner.
399
-
400
- Or try it without installing anything: https://docugate-demo.vercel.app/invoices/inv_1004. The hosted demo reads a copy of the tour, so editing is turned off there.
401
-
402
- ---
403
-
404
- ## Several repositories in one space
405
-
406
- A space can merge docs from a frontend, a backend, and a mobile app into one set of pages. `docugate init` connects the repository it runs in to one of your spaces once you are signed in; you can also add repositories from a space's settings on [trydocugate.site](https://www.trydocugate.site/dashboard).
407
-
408
- Run `init` and `check` in each repository that contributes docs, and answer the role question in each: the tour lives in the frontend, and its `source` lines can point into the backend. Every one gets its own `docugate.json`, naming its own docs folder. `check` reads the repository it is run in, which is why its 300-page limit is per repository rather than per space.
409
-
410
- See [Merging repositories](https://www.trydocugate.site/docs/merging-repositories).
411
-
412
- ---
413
-
414
- ## `openapi`
415
-
416
- Takes the OpenAPI 3 spec your backend already produces and writes the version you want published: only the public paths, without sensitive fields, with keys in a stable order so it reviews cleanly in a pull request.
417
-
418
- ```sh
419
- docugate openapi --from http://localhost:3000/openapi.json \
420
- --exclude "/internal/**" --redact passwordHash --out openapi.json
421
- ```
422
-
423
- - `--from`: a `.json`, `.yaml` or `.yml` file, or a URL serving one.
424
- - `--include` / `--exclude`: path globs; `*` matches within one segment and `**` matches across segments. Both can be repeated.
425
- - `--redact`: a property name to remove from every schema and example. Can be repeated.
426
- - `--check`: do not write anything; exit with 1 if the committed file is out of date. Useful in CI.
427
-
428
- Instead of passing flags every time, set the same options in `docugate.json`:
429
-
430
- ```json
431
- {
432
- "docsDir": "docs",
433
- "api": {
434
- "generate": {
435
- "from": "http://localhost:3000/openapi.json",
436
- "output": "openapi.json",
437
- "exclude": ["/internal/**"],
438
- "redact": ["passwordHash"]
439
- }
440
- }
441
- }
442
- ```
443
-
444
- ---
445
-
446
- ## Checking API keys from your backend
447
-
448
- If you publish an API's docs on DocuGate Enterprise, the people reading them can generate an API key on the page. Your backend asks DocuGate whether each key is valid, with a secret from your space's settings, so a key you revoke stops on its next request. This package carries that check. It is separate from the command and has no dependencies of its own.
449
-
450
- ```ts
451
- import { requireKey } from 'docugate/express' // or 'docugate/hono', 'docugate/fastify'
452
-
453
- app.use('/api', requireKey({ secret: process.env.DOCUGATE_VERIFY_SECRET! }))
454
- ```
455
-
456
- The verified key is on `req.docugateKey` (Express and Fastify) or `c.get('docugateKey')` (Hono): who holds it, its scopes, and what is left of its allowance. Anything else, in any framework, can call the check directly:
457
-
458
- ```ts
459
- import { verifyKey } from 'docugate/keys'
460
-
461
- const verdict = await verifyKey(key, { secret: process.env.DOCUGATE_VERIFY_SECRET! })
462
- if (!verdict.valid) return deny(verdict.code) // REVOKED, EXPIRED, USAGE_EXCEEDED, ...
463
- ```
464
-
465
- `verifyKey` answers for every key, valid or not, and throws a `KeyServiceError` only when it could not get an answer. By default every request asks DocuGate, which is what makes a revoked key stop at once; `cacheSeconds` trades that for speed, and `failOpen` decides what happens when DocuGate cannot be reached (by default, the request is refused). The options, the exact request, and what each result means are in [API keys](https://www.trydocugate.site/docs/api-keys).
466
-
467
- ---
468
-
469
- ## `docugate.json`
470
-
471
- One per repository, at its root.
472
-
473
- | Key | Meaning |
474
- | --- | --- |
475
- | `docsDir` | The folder DocuGate reads. Defaults to `docs`. |
476
- | `title` | The space's title. |
477
- | `role` | Repository role: `frontend`, `backend`, or `both`. Set by `docugate init`. |
478
- | `freshness` | How often the docs are checked against the code: `push`, `daily`, `weekly` or `off`. Set by `docugate init` or `docugate sync init`, which writes the GitHub Action to match. |
479
- | `sync` | Settings for `docugate sync`; see [Docs that keep up with your code](#docs-that-keep-up-with-your-code). The DocuGate site ignores it. |
480
- | `sidebar` | File and folder names in the order the sidebar should show them. Orders this repository's own pages, not the whole space. |
481
- | `api.generate` | Defaults for `docugate openapi`. |
482
- | `api.spec` | Where the OpenAPI file is, for a repository that does not keep it at `openapi.json` in the root or the docs folder. DocuGate draws an [API reference](https://www.trydocugate.site/docs/api-reference) from it. |
483
-
484
- ---
485
-
486
- ## Built with IBM Bob
487
-
488
- The tour and pill began as DocuGate's entry to the IBM Bob 2.0 hackathon (lablab.ai, September 25 to 27, 2026), and IBM Bob still writes the first tour (`docugate tour init` runs it through Bob Shell, in a Tour Writer mode that may only edit `.docugate/tour/` and never changes a tour file you already have). Demo video: https://youtu.be/mgLUA-0r5MM. Live demo: https://docugate-demo.vercel.app/invoices/inv_1004
489
-
490
- ---
491
-
492
- ## Licence
493
-
494
- MIT
1
+ # docugate
2
+
3
+ DocuGate publishes documentation straight from the markdown in your GitHub repositories. This package is its command line, and it does three things:
4
+
5
+ - **Keeps the docs true.** `docugate sync` reads what changed in your code, works out which pages that made wrong, and opens a pull request with the fix. Nobody has to remember to update the docs. [More](#docs-that-keep-up-with-your-code).
6
+ - **Explains your app.** A walkthrough pill on your running app shows any developer what each element on screen is and where its data comes from. [More](#tours).
7
+ - **Checks the result.** `docugate check` reads your docs and tours the way DocuGate will, so problems show up in CI instead of on the published page.
8
+
9
+ ```sh
10
+ npm i -g docugate
11
+ docugate # opens DocuGate in your terminal: pick what to do next
12
+ ```
13
+
14
+ Type `docugate` on its own and it opens, the way `claude` does: where your account, docs and space stand, and every next step in a list, with the one worth doing now under Enter. Arrow keys pick; in Git Bash and other terminals without them, type the number.
15
+
16
+ ---
17
+
18
+ ## Quick start, step by step
19
+
20
+ Follow these in order. Every question during setup is a numbered choice: type
21
+ the number and press Enter, or just press Enter for the suggested one.
22
+
23
+ **1. Open your project's folder.**
24
+
25
+ ```sh
26
+ cd my-app
27
+ ```
28
+
29
+ Use the root of the repository: the folder with `.git` and `package.json` in
30
+ it. If your frontend and backend are two repositories, do steps 1 to 3 in each.
31
+
32
+ **2. Install DocuGate in the project.**
33
+
34
+ ```sh
35
+ npm i docugate
36
+ ```
37
+
38
+ Like any other package: everyone who clones the project gets the same version,
39
+ and CI too. (A repository with no `package.json`, like a Go or Python backend,
40
+ can install the command on the computer instead with `npm i -g docugate`, and
41
+ then drop the `npx` from the commands below.)
42
+
43
+ **3. Set everything up.**
44
+
45
+ ```sh
46
+ npx docugate init
47
+ ```
48
+
49
+ It asks, one at a time:
50
+
51
+ | Question | What to choose |
52
+ | --- | --- |
53
+ | What is in this repository? | **1** Frontend, **2** Backend, or **3** Both (a `frontend/` and a `backend/` folder in one repository). It suggests one from your folders. |
54
+ | Sign in to DocuGate? | **1** opens your browser to sign in with GitHub. You come back to your editor when it is done. **2** skips it; `docugate login` does it later. |
55
+ | Where should the documentation live? | **1** creates a new space, with a new GitHub repository on your account to hold its markdown (`<project>-docs`, with a first page). Or pick one of your spaces. The pill then links to the published docs. |
56
+ | How often should DocuGate check your docs still match the code? | On every push, daily (suggested, fewer AI runs), weekly, or never. The answer is saved as `freshness`; `docugate sync init` then adds the GitHub Action that does the checking. |
57
+ | Set up the tour: which AI should write it? | **1** IBM Bob reads your code and writes the tour. **2** IBM watsonx is coming soon. **3** skips it; you can write the tour in the browser. Frontend and both only. |
58
+ | Add the DocuGate pill to your app? | **1** adds a few lines to your `index.html` or Next.js layout that load the pill in development only. |
59
+
60
+ IBM Bob reads its API key from the `BOB_API_KEY` environment variable. If you
61
+ saved it under another name (say `IBM_BOB_KEY`), setup finds it and asks before
62
+ using it. If there is none, setup opens the page where you create a key and lets you paste it for
63
+ that one run; DocuGate never saves it. To set it for good (then open a new terminal):
64
+
65
+ ```powershell
66
+ [Environment]::SetEnvironmentVariable("BOB_API_KEY", "<key>", "User") # Windows
67
+ export BOB_API_KEY=<key> # macOS, Linux
68
+ ```
69
+
70
+ Setup writes `docugate.json` and `.docugate/tour/`. Commit both, so the next
71
+ person who clones the repository needs no setup. When setup finishes it starts
72
+ the tour server in the background, so the pill is there the first time you open
73
+ the app (`--no-serve` skips that).
74
+
75
+ **4. Run your app as usual, and open it.**
76
+
77
+ ```sh
78
+ npm run dev
79
+ ```
80
+
81
+ Setup added a `predev` script, so `npm run dev` starts the DocuGate tour server
82
+ first (one line, "DocuGate tour ready") and then your app. The pill only
83
+ appears while that server runs, which is why it never shows in production.
84
+
85
+ The DocuGate pill sits in the bottom-right corner. Click it:
86
+
87
+ - **Walkthrough** lists the page's steps with your progress. Click a step to
88
+ go to it, the pencil to fix it, or **Add a step**.
89
+ - **Inspector** is one switch. With it on, click anything: you see what it is
90
+ and where its data comes from, and you can edit it. Click something with no
91
+ explanation yet, and the same click lets you add one.
92
+
93
+ Every change is saved straight into `.docugate/tour/`, so it shows up in `git diff`.
94
+
95
+ **5. Keep the tour true.**
96
+
97
+ ```sh
98
+ npx docugate check
99
+ ```
100
+
101
+ It checks every step against the code and warns about any that went stale,
102
+ for example after a rename. Put it in CI so a stale tour fails the build (see
103
+ [Keeping tours true](#keeping-tours-true)).
104
+
105
+ **Later, when you need them:**
106
+
107
+ ```sh
108
+ npx docugate # the menu: pick what to do next
109
+ npx docugate status # where things stand, and what to do next
110
+ npx docugate sync # update the docs from what changed in the code
111
+ npx docugate login # sign in again, or on a new computer
112
+ npx docugate whoami # who am I signed in as?
113
+ npx docugate tour init # let IBM Bob write tours for screens that have none
114
+ npx docugate tour install # add the pill again (--remove takes it out)
115
+ npx docugate tour serve # start the tour server by hand
116
+ npx docugate logout # disconnect this computer
117
+ ```
118
+
119
+ **Something not working?**
120
+
121
+ | You see | Do this |
122
+ | --- | --- |
123
+ | No pill in the app | Start the app with `npm run dev` (it starts the tour server), or run `npx docugate tour serve`, then refresh the page. |
124
+ | Bob can't run | Choose IBM Bob again in `docugate init` to paste a key, or install Bob Shell: https://bob.ibm.com/docs/shell/getting-started/install-and-setup |
125
+ | Port 4178 is busy | `docugate tour serve --port 4179` and `docugate tour install --port 4179` |
126
+ | "Already set up in ..." | You ran it in a subfolder. Run commands from the folder it names. |
127
+
128
+ ---
129
+
130
+ ## A developer space
131
+
132
+ ```sh
133
+ docugate developers
134
+ ```
135
+
136
+ One guided run sets up the docs developers read before they build on your API:
137
+
138
+ 1. Signs you in, if you are not.
139
+ 2. Finds your OpenAPI file (`openapi.json`, `.yaml`, `swagger.*`) and says how many endpoints it describes.
140
+ 3. Writes the first pages, `index.md`, `quickstart.md`, `authentication.md` and `errors.md`, in `docs/developers/`, where they are missing. It never overwrites a file.
141
+ 4. Offers to commit and push them, since a space reads GitHub, not your disk.
142
+ 5. Creates a public space for them, or uses the one that already reads this repository, and saves it in `docugate.json`.
143
+
144
+ On Pro it carries on:
145
+
146
+ 6. Claims a subdomain such as `acme.trydocugate.site`, live at once.
147
+ 7. Asks where the API console sends requests from: the reader's browser, or through DocuGate with no CORS setup.
148
+ 8. Switches on API keys, with a scope per OpenAPI tag to start from, makes the verify secret, offers to put it in `.env` when git ignores that file, and prints the lines your Express, Hono or Fastify backend needs.
149
+
150
+ Everything it sets stays editable in the space's settings on [trydocugate.site](https://www.trydocugate.site/dashboard).
151
+
152
+ ## Docs that keep up with your code
153
+
154
+ Documentation goes stale because updating it is a chore nobody owns. `docugate sync` does the chore: it reads what changed in the code, finds the pages those changes made wrong, asks an AI model to correct them, and gives you the edits to review.
155
+
156
+ ```sh
157
+ npx docugate sync --dry-run # free and instant: which pages are probably out of date
158
+ npx docugate sync # write the edits into your docs folder
159
+ npx docugate sync --pr # push them and open a pull request instead
160
+ ```
161
+
162
+ `sync` needs an AI key of your own, in `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` (set `DOCUGATE_AI_BASE_URL` to use another OpenAI-compatible service). It talks to the provider directly: nothing goes through DocuGate's servers, and it works without a DocuGate account.
163
+
164
+ **What it does, step by step**
165
+
166
+ 1. **Reads the changes** from git: the commits and a trimmed diff of each changed file, since the last sync. The first run looks back a day, a week or one commit, depending on `freshness`. `--since 7d`, a branch or a commit overrides it. Documentation, lockfiles, build output, binaries and anything that looks like a secret (`.env`, `*.pem`, files named `secret` or `credentials`) are never read.
167
+ 2. **Finds the pages that are affected.** A page counts when it names a changed file, mentions something the change added or removed (a function, a route, an environment variable), or is pinned to that code in `sync.map`. This part is free, and it is all `--dry-run` does.
168
+ 3. **Asks the model** for the new text of those pages, and only those. It is told to change what the diff requires and nothing else, to invent nothing, and to treat the code as data rather than instructions.
169
+ 4. **Checks the answer before writing it.** An edit is dropped unless it is a markdown page inside your docs folder, within 300 pages, without front matter. After writing, `docugate check` runs again, and an edit that breaks a link is put back as it was.
170
+ 5. **Hands it over.** With `--pr` the edits go on one branch, `docugate/sync`, and one pull request that lists every page and why it changed. Each run updates that same pull request rather than opening another. Nothing is ever merged for you, and closing the pull request changes nothing. The sync moves forward only when you merge it.
171
+
172
+ **Make it automatic**
173
+
174
+ ```sh
175
+ npx docugate sync init
176
+ ```
177
+
178
+ This writes `.github/workflows/docugate-sync.yml`, timed by `freshness` in `docugate.json`:
179
+
180
+ | `freshness` | When it runs |
181
+ | --- | --- |
182
+ | `push` | On every push to your default branch. |
183
+ | `daily` | Every day. |
184
+ | `weekly` | Every Monday (the default). |
185
+ | `off` | Never. No workflow is written. |
186
+
187
+ Do two things on GitHub, once: add your AI key as a repository secret named `ANTHROPIC_API_KEY` (or `OPENAI_API_KEY`), and under Settings, Actions, General, tick "Allow GitHub Actions to create and approve pull requests". `sync init` prints both steps. The workflow is pinned to the version that wrote it, so a new release never changes what your CI does by surprise; run `sync init --force` to upgrade it. A sync's own commits never start another sync.
188
+
189
+ **A heads-up on your own machine**
190
+
191
+ ```sh
192
+ npx docugate sync hook install
193
+ ```
194
+
195
+ After every commit, a git hook runs `sync --dry-run` and, if pages look out of date, says so in one line. It sends nothing, changes nothing and never fails a commit. `sync hook remove` takes it out.
196
+
197
+ **Settings**, in `docugate.json`:
198
+
199
+ ```json
200
+ {
201
+ "freshness": "weekly",
202
+ "sync": {
203
+ "provider": "anthropic",
204
+ "model": "claude-sonnet-5-5",
205
+ "include": ["server/**", "src/**"],
206
+ "exclude": ["**/*.test.ts"],
207
+ "map": { "docs/api.md": ["server/routes/**"] },
208
+ "maxFiles": 10,
209
+ "digest": false
210
+ }
211
+ }
212
+ ```
213
+
214
+ | Key | Meaning |
215
+ | --- | --- |
216
+ | `provider` | `anthropic` or `openai`. Defaults to whichever key is set. |
217
+ | `model` | The model to use. |
218
+ | `include` / `exclude` | Path globs for the code worth documenting. `*` stays within a folder, `**` crosses folders. |
219
+ | `map` | Pin a page to the code it documents, when its text never names the files. DocuGate does not read front matter, so this is where that link lives. |
220
+ | `maxFiles` | The most pages one run may change (10). |
221
+ | `digest` | Also write a short "what changed" page, `changes/<date>.md`, for each run. |
222
+
223
+ `sync` also lists tour stops that no longer match the code. It only reports them: a tour is yours, and DocuGate never edits one.
224
+
225
+ **When it says no**
226
+
227
+ | You see | Do this |
228
+ | --- | --- |
229
+ | "No AI key found" | Set `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` where you run it, or as an Actions secret. |
230
+ | "shallow clone" | In GitHub Actions, set `fetch-depth: 0` on the checkout step. `sync init` already does. |
231
+ | Pushed, but no pull request | Allow Actions to create pull requests (above), or set `GITHUB_TOKEN` when running it by hand. |
232
+ | "Skipped: the changes only touch documentation" | Working as intended. A merged sync, or a docs-only change, never starts a sync. |
233
+
234
+ ---
235
+
236
+ ## Moving around
237
+
238
+ Run `docugate` in a terminal and you get a menu: arrow keys to move, type to search, Enter to run, Esc to leave. It shows where you are (signed in or not, how many pages, how far the docs are behind the code) and puts the step worth taking next under Enter, with a dot beside it. Not connected to DocuGate yet? Connecting your account is that step. When a command finishes, the menu comes back.
239
+
240
+ - `docugate status` prints the same picture: your account, your docs, the sync (last run, whether the workflow and hook are on, how many commits and pages are behind), your tour, and one line saying what to do next. `--json` is for scripts.
241
+ - `docugate help <command>`, or `docugate <command> --help`, shows one command's options and examples.
242
+ - Mistype and it helps: `docugate chekc` suggests `check`, and an option a command does not have is an error with the nearest real one, not silently ignored.
243
+ - `docugate completion powershell|bash|zsh` prints a completion script.
244
+ - In CI, in a pipe, or with `--no-input`, nothing is ever asked: the menu does not open, the help prints as plain text, and a command that needs an answer fails with what to do. To use your DocuGate account in CI, set `DOCUGATE_TOKEN`.
245
+
246
+ ---
247
+
248
+ ## Tours
249
+
250
+ A tour helps a developer who is new to a codebase see what each element on screen is and where its data comes from. For each screen there is one markdown file in `.docugate/tour/`. Each file has front matter with a `route` and a `title`, then one `##` section per stop.
251
+
252
+ **Example stop:**
253
+
254
+ ```markdown
255
+ ---
256
+ route: /invoices/:id
257
+ title: Invoice detail
258
+ ---
259
+
260
+ ## Total
261
+ target: [data-tour="invoice-total"]
262
+ data: GET /api/invoices/:id → total
263
+ code: frontend/src/screens/InvoiceDetail.tsx
264
+ source: backend/src/billing.ts
265
+ docs: https://example.com/docs/billing
266
+
267
+ The amount due: the subtotal plus tax, computed by `totals()` in the backend.
268
+ ```
269
+
270
+ Fields:
271
+
272
+ | Field | Required | Meaning |
273
+ | --- | --- | --- |
274
+ | `target` | yes | CSS selector for the element. Prefer `[data-tour="…"]`. |
275
+ | `data` | no | Request and field: `METHOD /path → field`. |
276
+ | `code` | yes | File that renders the element, relative to the repository root. |
277
+ | `source` | no | File where the value is computed, when that is elsewhere. |
278
+ | `docs` | no | URL to relevant documentation. |
279
+
280
+ The prose paragraph after the fields explains what the element is and why its value is what it is.
281
+
282
+ Tour files are yours. `docugate tour init` never overwrites a file that already exists.
283
+
284
+ ---
285
+
286
+ ## The pill
287
+
288
+ When `docugate tour serve` is running, the pill sits in a corner of your app,
289
+ like the Next.js dev indicator. Drag it to any corner. Click it for two things:
290
+
291
+ - **Walkthrough.** The page's steps as a checklist with progress. Start from
292
+ any step: the page dims, a ring marks the element, and a card says what it
293
+ is and where its data comes from. Each step has a pencil to fix it, and
294
+ **Add a step** adds one.
295
+ - **Inspector.** One switch. With it on, clicking an element shows its step,
296
+ with **Edit** to correct what the AI or anyone else got wrong, and **Remove**.
297
+ Clicking an element with no step lets you add it, and tells you which
298
+ `data-tour` attribute to put on it. Code and source files open in your
299
+ editor at the element's line.
300
+
301
+ The pill shows on every page while the server runs, including pages with no
302
+ tour yet, so their first step can be added from the browser.
303
+
304
+ `docugate tour install` adds the pill for you. It only loads when the app runs
305
+ on `localhost` and the tour server answers, so it never shows in production.
306
+
307
+ ---
308
+
309
+ ## Keeping tours true
310
+
311
+ A tour is only useful while it is true, so `docugate check` verifies every claim in `.docugate/tour/` against the code. For each stop it warns when:
312
+
313
+ - the `code` file, or the `source` file, no longer exists;
314
+ - the `code` file, and the files it imports, no longer mention the endpoint in `data`;
315
+ - the `code` file no longer contains the `data-tour` value in `target` (a value passed through a prop counts);
316
+ - a required field is missing, or two stops on one screen point at the same element.
317
+
318
+ Rename `invoice-total` in a component and `check` tells you which stop went stale.
319
+
320
+ It checks your docs folder too:
321
+
322
+ - **Errors:** broken links between pages, links that leave the docs folder, two files that become the same URL, an unreadable `docugate.json`, an empty docs folder, or more than 300 pages.
323
+ - **Warnings:** pages with no `# Title`, front matter, `.mdx` files, no landing page, and `sidebar` entries that match nothing.
324
+
325
+ It exits with 1 when there are errors. Add `--strict` to fail on warnings too, which is how stale tour stops fail a build.
326
+
327
+ Use it in CI:
328
+
329
+ ```yaml
330
+ # .github/workflows/docs.yml
331
+ name: Docs
332
+ on: [push, pull_request]
333
+ jobs:
334
+ check:
335
+ runs-on: ubuntu-latest
336
+ steps:
337
+ - uses: actions/checkout@v4
338
+ - uses: actions/setup-node@v4
339
+ with:
340
+ node-version: 22
341
+ - run: npx docugate@0.2 check --strict
342
+ ```
343
+
344
+ Pin the version in CI, as above. Without a pin, the rules being enforced can change between two runs of the same workflow, which turns a green build red with nothing in the commit to explain it.
345
+
346
+ ---
347
+
348
+ ## Commands
349
+
350
+ | Command | Main flags | What it does |
351
+ | --- | --- | --- |
352
+ | `docugate` | | In a terminal: the menu. Elsewhere: the help. |
353
+ | `docugate status` | `--json` | Where things stand: account, docs, sync and tour, and what to do next. |
354
+ | `docugate sync` | `--dry-run`, `--since <when>`, `--pr`, `--yes`, `--max-files <n>`, `--model <name>`, `--quiet` | Update the docs from what changed in the code. |
355
+ | `docugate sync init` | `--freshness push\|daily\|weekly\|off`, `--force` | Add the GitHub Action that runs sync on a schedule or on every push. |
356
+ | `docugate sync hook install` | | Tell you after each commit which pages the code left behind. |
357
+ | `docugate sync hook remove` | | Remove that hook. |
358
+ | `docugate init` | `--dir`, `--title`, `--role frontend\|backend\|both`, `--yes`, `--no-serve` | Set up this repository for DocuGate (interactive). |
359
+ | `docugate developers` | `--dir`, `--yes` | Set up a developer space: API reference, guides and keys (interactive). |
360
+ | `docugate check` | `--dir`, `--strict` | Check docs and tour files the way DocuGate will read them. |
361
+ | `docugate help [command]` | | Every command, or one command's options and examples. |
362
+ | `docugate completion <shell>` | | Print a completion script for bash, zsh or powershell. |
363
+ | `docugate openapi` | `--from`, `--out`, `--include`, `--exclude`, `--redact`, `--check` | Prepare an OpenAPI spec for the API reference. |
364
+ | `docugate login` | | Sign in to DocuGate with GitHub. |
365
+ | `docugate logout` | | Sign out and delete saved credentials. |
366
+ | `docugate connect` | `--project`, `--section`, `--frequency`, `--type`, `--backend-dir`, `--no-audit`, `--yes` | Connect this codebase to a project, and publish its docs with the project's. |
367
+ | `docugate audit` | `--fail-on`, `--json` | Check this project’s packages for known vulnerabilities. |
368
+ | `docugate whoami` | | Print the currently signed-in user. |
369
+ | `docugate tour init` | `--max-cost <n>`, `--team-id <id>` | Write the first tour with IBM Bob (uses Bob Shell). |
370
+ | `docugate tour serve` | `--port <n>` (default 4178), `--background` | Start the local server that serves tour data for the pill. |
371
+ | `docugate tour install` | `--port <n>`, `--remove` | Add (or remove) the pill loader from your app's HTML or layout. |
372
+ | `docugate tour export <file>` | | Write every tour screen to a single JSON file. |
373
+
374
+ Run every command from the root of your repository. Every command also takes
375
+ `--help`, and `--no-input` (which CI implies) to make sure it never stops to
376
+ ask a question: it fails with what to do instead.
377
+
378
+ ---
379
+
380
+ ## Try it on the demo
381
+
382
+ Clone [docugate-demo](https://github.com/Docugate/docugate-demo), a small full-stack app with a pre-written tour:
383
+
384
+ ```sh
385
+ git clone https://github.com/Docugate/docugate-demo
386
+ cd docugate-demo
387
+
388
+ # install dependencies and start the app
389
+ npm install
390
+ npm run dev
391
+ ```
392
+
393
+ In a second terminal:
394
+
395
+ ```sh
396
+ cd docugate-demo
397
+ docugate tour serve
398
+ ```
399
+
400
+ Open the app in the browser. The pill appears in the bottom-right corner.
401
+
402
+ Or try it without installing anything: https://docugate-demo.vercel.app/invoices/inv_1004. The hosted demo reads a copy of the tour, so editing is turned off there.
403
+
404
+ ---
405
+
406
+ ## One project, several codebases
407
+
408
+ A project is one set of docs fed by its codebases: a frontend and a backend, in two repositories or as two folders of one. Run `docugate connect` in each of them:
409
+
410
+ ```bash
411
+ cd server && npx docugate connect # pick the project, or start a new one
412
+ cd ../public && npx docugate connect # pick the same project
413
+ ```
414
+
415
+ The first codebase's docs sit at the top of the project's space; each one after it gets a section named after what it is (`frontend/`, `backend/`), so two pages with the same name cannot clash. A docs folder the space already reads is not added twice. Change the sections, or add repositories by hand, in a space's settings on [trydocugate.site](https://www.trydocugate.site/dashboard). Feeding one project from several codebases needs Pro or an organization plan.
416
+
417
+ Run `init` and `check` in each repository that contributes docs, and answer the role question in each: the tour lives in the frontend, and its `source` lines can point into the backend. Every one gets its own `docugate.json`, naming its own docs folder. `check` reads the repository it is run in, which is why its 300-page limit is per repository rather than per space.
418
+
419
+ See [Merging repositories](https://www.trydocugate.site/docs/merging-repositories).
420
+
421
+ ---
422
+
423
+ ## `openapi`
424
+
425
+ Takes the OpenAPI 3 spec your backend already produces and writes the version you want published: only the public paths, without sensitive fields, with keys in a stable order so it reviews cleanly in a pull request.
426
+
427
+ ```sh
428
+ docugate openapi --from http://localhost:3000/openapi.json \
429
+ --exclude "/internal/**" --redact passwordHash --out openapi.json
430
+ ```
431
+
432
+ - `--from`: a `.json`, `.yaml` or `.yml` file, or a URL serving one.
433
+ - `--include` / `--exclude`: path globs; `*` matches within one segment and `**` matches across segments. Both can be repeated.
434
+ - `--redact`: a property name to remove from every schema and example. Can be repeated.
435
+ - `--check`: do not write anything; exit with 1 if the committed file is out of date. Useful in CI.
436
+
437
+ Instead of passing flags every time, set the same options in `docugate.json`:
438
+
439
+ ```json
440
+ {
441
+ "docsDir": "docs",
442
+ "api": {
443
+ "generate": {
444
+ "from": "http://localhost:3000/openapi.json",
445
+ "output": "openapi.json",
446
+ "exclude": ["/internal/**"],
447
+ "redact": ["passwordHash"]
448
+ }
449
+ }
450
+ }
451
+ ```
452
+
453
+ ---
454
+
455
+ ## Checking API keys from your backend
456
+
457
+ If you publish an API's docs on DocuGate Enterprise, the people reading them can generate an API key on the page. Your backend asks DocuGate whether each key is valid, with a secret from your space's settings, so a key you revoke stops on its next request. This package carries that check. It is separate from the command and has no dependencies of its own.
458
+
459
+ ```ts
460
+ import { requireKey } from 'docugate/express' // or 'docugate/hono', 'docugate/fastify'
461
+
462
+ app.use('/api', requireKey({ secret: process.env.DOCUGATE_VERIFY_SECRET! }))
463
+ ```
464
+
465
+ The verified key is on `req.docugateKey` (Express and Fastify) or `c.get('docugateKey')` (Hono): who holds it, its scopes, and what is left of its allowance. Anything else, in any framework, can call the check directly:
466
+
467
+ ```ts
468
+ import { verifyKey } from 'docugate/keys'
469
+
470
+ const verdict = await verifyKey(key, { secret: process.env.DOCUGATE_VERIFY_SECRET! })
471
+ if (!verdict.valid) return deny(verdict.code) // REVOKED, EXPIRED, USAGE_EXCEEDED, ...
472
+ ```
473
+
474
+ `verifyKey` answers for every key, valid or not, and throws a `KeyServiceError` only when it could not get an answer. By default every request asks DocuGate, which is what makes a revoked key stop at once; `cacheSeconds` trades that for speed, and `failOpen` decides what happens when DocuGate cannot be reached (by default, the request is refused). The options, the exact request, and what each result means are in [API keys](https://www.trydocugate.site/docs/api-keys).
475
+
476
+ ---
477
+
478
+ ## `docugate.json`
479
+
480
+ One per repository, at its root.
481
+
482
+ | Key | Meaning |
483
+ | --- | --- |
484
+ | `docsDir` | The folder DocuGate reads. Defaults to `docs`. |
485
+ | `title` | The space's title. |
486
+ | `role` | Repository role: `frontend`, `backend`, or `both`. Set by `docugate init`. |
487
+ | `freshness` | How often the docs are checked against the code: `push`, `daily`, `weekly` or `off`. Set by `docugate init` or `docugate sync init`, which writes the GitHub Action to match. |
488
+ | `sync` | Settings for `docugate sync`; see [Docs that keep up with your code](#docs-that-keep-up-with-your-code). The DocuGate site ignores it. |
489
+ | `sidebar` | File and folder names in the order the sidebar should show them. Orders this repository's own pages, not the whole space. |
490
+ | `api.generate` | Defaults for `docugate openapi`. |
491
+ | `api.spec` | Where the OpenAPI file is, for a repository that does not keep it at `openapi.json` in the root or the docs folder. DocuGate draws an [API reference](https://www.trydocugate.site/docs/api-reference) from it. |
492
+
493
+ ---
494
+
495
+ ## Built with IBM Bob
496
+
497
+ The tour and pill began as DocuGate's entry to the IBM Bob 2.0 hackathon (lablab.ai, September 25 to 27, 2026), and IBM Bob still writes the first tour (`docugate tour init` runs it through Bob Shell, in a Tour Writer mode that may only edit `.docugate/tour/` and never changes a tour file you already have). Demo video: https://youtu.be/mgLUA-0r5MM. Live demo: https://docugate-demo.vercel.app/invoices/inv_1004
498
+
499
+ ---
500
+
501
+ ## Licence
502
+
503
+ MIT