# docsfy > Turn any Git repo into a polished docs site you can generate, track, and share in minutes --- Source: generate-your-first-docs-site.md # Generate Your First Docs Site You want a working docs site quickly so you can prove your setup, sign in, and see a real result before tuning anything else. This guide uses the checked-in Docker path and a small public repository so you can get to a searchable site in one short flow. ## Prerequisites - Docker with Compose - An `ADMIN_KEY` you choose, at least 16 characters long - A Git repository URL over HTTPS or SSH - At least one working provider and model where docsfy runs > **Note:** The checked-in container image installs the `claude`, `gemini`, and `cursor` CLIs. Your first generation still needs a provider/model pair that can authenticate and run in that environment. ## Quick Example ```shell cp .env.example .env ``` ```dotenv ADMIN_KEY= SECURE_COOKIES=false ``` ```shell docker compose up --build -d curl http://localhost:8000/health ``` ```text Login URL: http://localhost:8000/login Username: admin Password: New Generation Repository URL: https://github.com/myk-org/for-testing-only Branch: main Provider: cursor Model: gpt-5.4-xhigh-fast Force full regeneration: off ``` Sign in, click `Generate`, wait for the run to reach `Ready`, then click `View Documentation`. In the docs tab, use the search field or press `Ctrl+K` / `Cmd+K` to confirm the site is searchable. > **Tip:** On a brand-new server, the `Model` field may have no suggestions yet. Type the model name manually and continue. ## Step-by-Step 1. Prepare your local config. ```shell cp .env.example .env ``` Set these values in `.env`: ```dotenv ADMIN_KEY= SECURE_COOKIES=false ``` For the fastest first run, keep the checked-in provider and model defaults from `.env.example` unless you already know you need a different pair. > **Warning:** `ADMIN_KEY` is required, and the server rejects values shorter than 16 characters. 2. Start docsfy. ```shell docker compose up --build -d ``` ```shell curl http://localhost:8000/health ``` The app listens on `http://localhost:8000`. The compose file mounts `./data` into the container, so your database and generated docs survive restarts. > **Note:** The first build can take a few minutes because it builds the frontend and installs runtime dependencies. If the health check fails immediately, wait a bit and run it again. 3. Sign in as the built-in admin. Open `http://localhost:8000/login`, enter username `admin`, and enter your `ADMIN_KEY` in the `Password` field. After a successful sign-in, the dashboard opens and `New Generation` is available right away. 4. Start your first generation. Click `New Generation`, then enter these values: ```text Repository URL: https://github.com/myk-org/for-testing-only Branch: main Provider: cursor Model: gpt-5.4-xhigh-fast Force full regeneration: off ``` Then click `Generate`. A small public HTTPS repository is the easiest first run because it avoids private Git access and branch guesswork. If your environment is already set up for a different working provider, switch the provider and model before you submit. See [Generating Documentation](generate-documentation.html) for the full field-by-field workflow. 5. Wait for the run to finish. docsfy opens the new variant detail view automatically and updates it in real time. When the status changes to `Ready`, the page shows `View Documentation`. See [Tracking Generation Progress](track-generation-progress.html) if you want the full meaning of each stage and status. 6. Open the docs and test search. Click `View Documentation` to open the generated site in a new tab. The finished site includes sidebar navigation and search, so you can click the search field or press `Ctrl+K` / `Cmd+K`, search for a term from the repo, and jump straight to a result. ```mermaid flowchart LR A[Copy .env.example] --> B[Set ADMIN_KEY and SECURE_COOKIES] B --> C[Run docker compose up --build -d] C --> D[Sign in as admin] D --> E[Generate for-testing-only] E --> F[Wait for Ready] F --> G[Open docs and search] ``` ## Advanced Usage ### Use Another Provider Or Model The checked-in defaults are `cursor` and `gpt-5.4-xhigh-fast`. If your docsfy environment is already working with `claude` or `gemini` instead, change those two fields before you click `Generate`. If the model list is empty, type the model name manually. Suggestions appear only after successful generations have already recorded known models. ### Generate Another Branch Replace `main` with another branch when you need a different variant. | Use | Avoid | Why | | --- | --- | --- | | `main` | `.hidden` | Branches must start with a letter or number. | | `release-1.x` | `release/1.x` | `/` is rejected. | | `v2.0.1` | `../etc/passwd` | Traversal-like names are rejected. | See [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) for the multi-variant workflow. ### Restart Or Change Defaults Use this to stop the stack without deleting your saved data: ```shell docker compose down ``` Start it again with: ```shell docker compose up -d ``` Use this when you want to watch server output: ```shell docker compose logs -f docsfy ``` To change the built-in admin password or the default provider/model for future runs, edit `.env` and restart the stack. See [Configuration Reference](configuration-reference.html) for the full setting list. ### Other Workflows See [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) for a non-container setup. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) if you want a terminal-first workflow. After your repository changes, see [Regenerating After Code Changes](regenerate-after-code-changes.html). ## Troubleshooting - If the container exits immediately, `ADMIN_KEY` is missing or too short. Set it in `.env`, then start the stack again. - If the login page works but you bounce back to `/login` on plain `http://localhost`, set `SECURE_COOKIES=false` in `.env`, then restart. - If the generation switches to `Error` almost immediately, the selected provider/model is not ready in the environment running docsfy. Pick a working pair or see [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html). - If the repository URL is rejected, use a hosted Git URL such as `https://github.com/org/repo`, `https://github.com/org/repo.git`, or `git@github.com:org/repo.git`. The dashboard quick-start flow is for remote Git URLs, not local filesystem paths. - If the branch name is rejected, use a single branch segment such as `main`, `dev`, or `release-1.x`. Branch names with `/` are rejected. - If the `Model` field shows no suggestions, type the model name manually and continue. ## Related Pages - [Generating Documentation](generate-documentation.html) - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) --- Source: install-and-run-docsfy-without-docker.md # Install and Run docsfy Without Docker You want `docsfy` running straight from a local checkout so you can use the web app and CLI without a container. This setup is useful when you want a normal Python and Node workflow, faster frontend iteration, or direct access to the AI CLIs on your machine. ## Prerequisites - A local clone of the repository, with your shell at the repo root - Python `3.12` or newer - `uv` - Node.js and `npm` - `git` - One supported AI provider CLI installed and signed in on the same machine and as the same user that will run `docsfy-server`: `claude`, `gemini`, or `cursor` ## Quick Example ```bash cp .env.example .env ``` ```dotenv ADMIN_KEY=change-this-to-a-16-plus-character-password AI_PROVIDER=cursor AI_MODEL=gpt-5.4-xhigh-fast AI_CLI_TIMEOUT=60 LOG_LEVEL=INFO DATA_DIR=data SECURE_COOKIES=false ``` ```bash uv sync --frozen cd frontend npm ci npm run build cd .. uv run docsfy-server ``` In another terminal: ```bash curl http://localhost:8000/health ``` Then open `http://localhost:8000/login` and sign in with username `admin` and the same `ADMIN_KEY` value from `.env`. > **Note:** `DATA_DIR=data` keeps the database and generated output in a writable local folder, and `SECURE_COOKIES=false` is required for browser login over plain `http://localhost`. If you plan to generate docs with `claude` or `gemini`, replace `AI_PROVIDER` and `AI_MODEL` before your first run. ## Step-by-Step 1. Install the Python environment. ```bash uv sync --frozen ``` Run all `uv run ...` commands from the repo root after this so both `docsfy-server` and `docsfy` use the project environment. 2. Create a local `.env`. ```bash cp .env.example .env ``` ```dotenv ADMIN_KEY=change-this-to-a-16-plus-character-password AI_PROVIDER=cursor AI_MODEL=gpt-5.4-xhigh-fast AI_CLI_TIMEOUT=60 LOG_LEVEL=INFO DATA_DIR=data SECURE_COOKIES=false ``` | Put in `.env` | Set when you start the server | | --- | --- | | `ADMIN_KEY`, `AI_PROVIDER`, `AI_MODEL`, `AI_CLI_TIMEOUT`, `LOG_LEVEL`, `DATA_DIR`, `SECURE_COOKIES` | `HOST`, `PORT`, `DEBUG` | - `ADMIN_KEY` is required and must be at least 16 characters long. - `DATA_DIR=data` keeps local state in a writable project folder instead of a system path like `/data`. - `SECURE_COOKIES=false` lets the browser keep the login session on `http://localhost`. - Change `AI_PROVIDER` and `AI_MODEL` now if you are using `claude` or `gemini` instead of `cursor`. See [Configuration Reference](configuration-reference.html) for every supported setting. > **Note:** Start `docsfy-server` from the repo root so it picks up `.env`. 3. Build the browser UI that the server will serve. ```bash cd frontend npm ci npm run build cd .. ``` This creates the frontend files that `http://localhost:8000/` and `http://localhost:8000/login` need in a normal local run. 4. Start the server. ```bash uv run docsfy-server ``` By default, the server listens on `127.0.0.1:8000`, so `http://localhost:8000` works locally. ```mermaid flowchart LR A[Copy .env] --> B[Install dependencies] B --> C[Build frontend] C --> D[Start docsfy-server] D --> E[Open /login] D --> F[Check /health] ``` > **Warning:** Before you start a generation, the selected provider CLI must already be installed, on `PATH`, and signed in for the same OS user that started `docsfy-server`. 5. Verify the server from the browser and the CLI. ```bash curl http://localhost:8000/health ``` A successful response confirms the backend is up. After that, open `http://localhost:8000/login` and sign in as `admin` with the same `ADMIN_KEY`. Set up the CLI once: ```bash uv run docsfy config init ``` Use these values when prompted: - Profile name: `dev` - Server URL: `http://localhost:8000` - Username: `admin` - Password: the same value as `ADMIN_KEY` Then verify the saved profile: ```bash uv run docsfy health ``` > **Tip:** `docsfy config init` creates `~/.config/docsfy/config.toml` for you, so later CLI commands can keep using your local `http://localhost:8000` server without re-entering the connection details. 6. Start using the local server. ```bash uv run docsfy list ``` If you have not generated anything yet, `No projects found.` is normal on a fresh install. See [Generating Documentation](generate-documentation.html) when you are ready to create your first docs site, and see [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) or [CLI Command Reference](cli-command-reference.html) for the next CLI steps. ## Advanced Usage ### Choose a built UI or a live-reload UI | When you want | Backend | Frontend | Open | | --- | --- | --- | --- | | One local server that serves the built app | `uv run docsfy-server` | `cd frontend && npm ci && npm run build` | `http://localhost:8000` | | Live frontend reload while you work on the UI | `DEBUG=true uv run docsfy-server` | `cd frontend && API_TARGET=http://localhost:8000 npm run dev` | `http://localhost:5173` | ```bash DEBUG=true uv run docsfy-server ``` ```bash cd frontend API_TARGET=http://localhost:8000 npm run dev ``` Open `http://localhost:5173`. The Vite dev server proxies `/api`, `/docs`, and `/health` to the backend on port `8000`. > **Note:** The commented `DEV_MODE` line in `.env.example` is for the container entrypoint. For a direct local run, start the backend and Vite yourself. ### Change the bind address or port ```bash HOST=0.0.0.0 PORT=9000 DEBUG=true uv run docsfy-server ``` Use this when you want another port, LAN access, or automatic backend reload during development. ### Tune local generation defaults ```dotenv AI_PROVIDER=gemini AI_MODEL=gemini-2.5-pro AI_CLI_TIMEOUT=120 MAX_CONCURRENT_PAGES=4 ``` Use these settings when you want a different default provider or model, a longer CLI timeout, or lower local parallelism on a smaller machine. See [Configuration Reference](configuration-reference.html) for the full list. ## Troubleshooting - If `docsfy-server` exits immediately, make sure `ADMIN_KEY` is set and at least 16 characters long. - If browser login keeps returning to `/login` on `http://localhost`, set `SECURE_COOKIES=false` in `.env`, then restart the server. - If the browser says the frontend is not built, run `cd frontend && npm ci && npm run build`, then restart `uv run docsfy-server`. - If you get permission errors under `/data`, point `DATA_DIR` at a writable local folder such as `data`. - If a generation fails before it really starts, the selected `claude`, `gemini`, or `cursor` CLI is usually missing, signed out, or installed for a different user than the one running `docsfy-server`. - If `uv run docsfy health` fails before connecting, finish `uv run docsfy config init` first so the CLI has a saved local profile. See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) for deeper setup and runtime failures. ## Related Pages - [Configuration Reference](configuration-reference.html) - [Configuring AI Providers and Models](configure-ai-providers-and-models.html) - [Generating Documentation](generate-documentation.html) - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) --- Source: generate-documentation.md # Generating Documentation Use the dashboard to start a documentation run for a Git repository and get it into a successful `Generating` state with the fewest possible inputs. This is the fastest way to confirm that your repo URL, branch, and AI settings are accepted before you wait for the full documentation build. ## Prerequisites - A running docsfy server - A signed-in `user` or `admin` account - A remote Git repository URL in HTTPS or SSH form - Git access from the docsfy server if the repository is private or uses SSH - A provider/model pair that already works on your server > **Note:** If you still need the setup and first sign-in path, see [Generate Your First Docs Site](generate-your-first-docs-site.html). ## Quick Example ```text Repository URL: https://github.com/myk-org/for-testing-only Branch: main Provider: cursor Model: gpt-5.4-xhigh-fast Force full regeneration: off ``` Click `Generate`. A successful start shows `Generation started for for-testing-only`, adds the repository to the sidebar, and opens the new run with status `Generating`. > **Tip:** If your server is already set up for a different provider, change only `Provider` and `Model` and keep the rest of the example the same. ## Step-by-Step 1. Open the form. In the sidebar, click `New Generation`. This action is available to `user` and `admin` accounts. 2. Enter the repository URL. Paste a remote URL such as `https://github.com/myk-org/for-testing-only`. docsfy uses the repository name from that URL as the project name in the sidebar. > **Tip:** A public HTTPS repository is the easiest first run because it avoids extra Git authentication setup. 3. Leave the branch as `main`. `main` is the default for new runs. Use a different branch only when you want a separate run for that branch. > **Warning:** Branch names cannot contain `/`. Use `release-1.x`, not `release/1.x`. 4. Choose the AI settings. `Provider` offers `claude`, `gemini`, and `cursor`, and it opens on `cursor`. If `Model` is blank, enter `gpt-5.4-xhigh-fast` for the default setup, or type the model that matches the provider you actually use. > **Tip:** The `Model` field accepts typed values, so you can start a run even when no suggestions are shown yet. 5. Leave `Force full regeneration` off. This is the normal first-run choice. Turn it on only when you want a clean rebuild of an existing run. 6. Start the run. Click `Generate`. On success, the main panel switches from the form to the new run. 7. Confirm that the run started correctly. Look for the `Generating` status badge at the top of the detail view. If you want to follow the run until it finishes, see [Tracking Generation Progress](track-generation-progress.html). ```mermaid flowchart LR A[Click New Generation] --> B[Paste repo URL] B --> C[Confirm branch, provider, and model] C --> D[Click Generate] D --> E[Run opens in the dashboard] E --> F[Status shows Generating] ``` ## Advanced Usage ### Remote URL formats ```text https://github.com/myk-org/for-testing-only https://github.com/myk-org/for-testing-only.git git@github.com:myk-org/for-testing-only.git ``` The dashboard accepts HTTPS URLs and `git@...` SSH URLs with a hostname. It does not accept bare local paths, and it rejects URLs that target `localhost` or private network addresses. > **Note:** SSH URLs work only if the machine running docsfy already has Git access to that host. ### Normal run vs clean rebuild | Setting | When to use it | What to expect | | --- | --- | --- | | `Force full regeneration` off | First runs and routine retries | docsfy can reuse existing work when it makes sense | | `Force full regeneration` on | Clean rebuilds after a bad result or when you want to ignore earlier cached output | docsfy rebuilds that run from scratch | A non-force rerun can finish quickly and show `Documentation is already up to date.` when nothing changed. ### Suggestions in the form - Branch suggestions appear only after there is already a successful run for the same repository name. - Model suggestions appear only after there is already a successful run for that provider. - You can type a branch or model manually even when there are no suggestions. ### Common alternatives - To create a separate run for another branch or model, see [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html). - To start runs from a terminal instead of the dashboard, see [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html). ## Troubleshooting - `New Generation` is missing: your account is probably `viewer`. Only `user` and `admin` accounts can start runs. - The form says `Please enter a repository URL`: enter the full HTTPS or SSH Git URL, not just the repository name. - The repository URL is rejected: use a remote URL with a hostname such as `https://github.com/org/repo` or `git@github.com:org/repo.git`. - The branch is rejected: use a branch that starts with a letter or number and contains only letters, numbers, `.`, `_`, or `-`. - The run will not start because the variant is already being generated: wait for that exact branch/provider/model combination to finish, or abort it and try again. - The run switches to `Error` quickly: the selected provider, model, branch, or repository access is not working on the server. See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html). ## Related Pages - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [Configuring AI Providers and Models](configure-ai-providers-and-models.html) - [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) --- Source: track-generation-progress.md # Tracking Generation Progress Use docsfy's live progress views to decide whether a generation is moving normally, already finished, or worth stopping before it spends more time and AI usage. This page shows the fastest ways to watch a run in the dashboard and from the CLI. ## Prerequisites - Start a generation first if you do not already have one running. See [Generating Documentation](generate-documentation.html). - For terminal examples, configure the `docsfy` CLI first. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html). - Use a `user` or `admin` account if you may need to abort a run. `viewer` can monitor a run but cannot stop it. ## Quick Example ```shell docsfy generate https://github.com/myk-org/for-testing-only --provider gemini --model gemini-2.5-flash --watch ``` Run this when you want one command that starts a generation and keeps printing progress until it reaches `ready`, `error`, or `aborted`. ## Step-by-Step ### 1. Open the exact variant you want to watch In the dashboard sidebar, expand the repository and branch, then select the provider/model variant. Collapsed repository groups still show how many variants are ready, generating, failed, or aborted, which makes active work easy to spot when you have several variants. ### 2. Check the status first | Status | What it means | What to do | | --- | --- | --- | | `Generating` | The run is still active. | Keep watching, or abort if you started the wrong run. | | `Ready` | The docs finished successfully. | Open or download the finished variant. | | `Error` | The run failed. | Read the message, fix the problem, and start again. | | `Aborted` | A user stopped the run. | Review the message and regenerate if needed. | ### 3. Use the activity log and page counter together Stay on the variant detail view while the run is active. The Activity Log and progress bar update live, so you do not need to refresh the page manually. ```mermaid flowchart LR A[cloning] --> B{next step} B --> C[planning] B --> D[incremental_planning] B --> E[up_to_date] C --> F[generating_pages] D --> F F --> G[validating] G --> H[cross_linking] H --> I[rendering] I --> J[ready] ``` | CLI stage | What you will see in the dashboard | What it means | | --- | --- | --- | | `cloning` | `Cloning repository...` | docsfy is preparing the repository source. | | `planning` | `Planning documentation structure...` | docsfy is building a full docs plan. | | `incremental_planning` | `Planning incremental update...` | docsfy is deciding what can be reused from an earlier run. | | `generating_pages` | `Generating page X of Y...` and `Generated page X of Y` | docsfy is writing or updating pages. | | `validating` | `Validating documentation against codebase...` | docsfy is checking the generated pages against the repository. | | `cross_linking` | `Adding cross-page links...` | docsfy is fixing cross-page references. | | `rendering` | `Rendering documentation site...` | docsfy is building the final site. | | `up_to_date` | `Documentation is already up to date.` | Nothing changed that required a rebuild. | > **Note:** The progress bar appears only after planning finishes, because docsfy does not know the total page count until the plan exists. ### 4. Know when a run is actually finished `X of Y pages` measures page generation only. If the counter reaches `Y of Y` and the status still says `Generating`, docsfy is usually finishing `validating`, `cross_linking`, or `rendering`. A healthy run does not have to increase the page counter every second. It is still healthy if the stage changes, the activity log keeps moving, or it finishes quickly as already up to date. > **Tip:** Treat `Ready` as the real finish line. A run can hit `100%` page generation before the final site is fully built. ### 5. Recognize the fast successful case If a regenerate finishes quickly and the ready view says `Documentation is already up to date.`, the run succeeded without rebuilding pages. This is normal when the source content did not change in a way that requires new docs output. If you see `Planning incremental update...` instead of full planning, docsfy is reusing earlier work. That is also a normal, healthy path. ### 6. Abort when the run is clearly the wrong one Click `Abort Generation`, confirm the dialog, and wait for the status to change to `Aborted`. Use this when you started the wrong branch, model, or repository, or when you want to stop a duplicate run and start over cleanly. > **Warning:** Aborting discards in-flight progress for that run. ## Advanced Usage ```shell docsfy status for-testing-only --branch main --provider gemini --model gemini-2.5-flash ``` Use this when a run is already in progress and you want a snapshot of its status, stage, page count, last update time, commit, and any error message. ```shell docsfy list --status generating ``` Use this to scan all active runs from the terminal. The table includes the page count and generation ID, which is useful when the same repository has multiple active variants. ```shell docsfy status docsfy abort ``` Copy the generation ID from the sidebar or the variant details when you want to inspect or stop one exact run without typing the full repository, branch, provider, and model combination. ```shell docsfy abort for-testing-only --branch main --provider gemini --model gemini-2.5-flash ``` Use the fully specified abort command when more than one variant of the same repository might be running. ```shell docsfy abort for-testing-only ``` Use the short form only when exactly one active variant matches that project name. Incremental runs can start with some pages already counted, because docsfy may reuse unchanged pages from the previous variant. That is expected behavior, not a stuck progress bar. > **Tip:** The Activity Log keeps auto-scrolling only while you are already near the bottom, so you can scroll up to inspect earlier steps without losing your place. > **Tip:** If live updates pause briefly, leave the page open for a moment. The dashboard retries automatically and falls back to periodic refresh if needed. See [CLI Command Reference](cli-command-reference.html) for full command syntax. If you intentionally run several branches or model combinations at the same time, see [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html). ## Troubleshooting - **`Abort Generation` is missing:** You are probably signed in as `viewer`. `viewer` can monitor accessible variants, but only `user` and `admin` can stop a run. - **The progress bar says `100%` but the run still shows `Generating`:** Page writing is done, but docsfy is still validating, cross-linking, or rendering. Wait for `Ready`, `Error`, or `Aborted`. - **`docsfy abort ` says multiple active variants were found:** Run it again with `--branch`, `--provider`, and `--model`, or use the generation ID. - **The run changed from `Generating` to `Error` after a restart:** docsfy marks interrupted runs as failed with `Server restarted during generation` instead of leaving them stuck forever. Start the run again. - **Abort says the generation already finished or that abort is still in progress:** Refresh the status, wait a few seconds, and retry only if the variant still shows `Generating`. See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) for deeper failure diagnosis. ## Related Pages - [Generating Documentation](generate-documentation.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [Regenerating After Code Changes](regenerate-after-code-changes.html) - [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) --- Source: view-and-download-docs.md # Viewing and Downloading Docs You want to open a ready docs site, move through it quickly, and save the exact output as a static bundle. That lets you review the generated docs inside docsfy first, then keep the same files offline or publish them on another static host. ## Prerequisites - At least one docs variant is in `Ready`. If you still need to create one, see [Generating Documentation](generate-documentation.html). - You can sign in to the docsfy web app. - If you want terminal downloads, the CLI is configured to reach your server. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html). ## Quick Example ```text /docs/for-testing-only/main/gemini/gemini-2.5-flash/ ``` ```shell docsfy download for-testing-only --branch main --provider gemini --model gemini-2.5-flash mkdir -p published-docs tar -xzf for-testing-only-main-gemini-gemini-2.5-flash-docs.tar.gz --strip-components=1 -C published-docs ``` Open that docs path on your docsfy server to browse one exact finished build. Download the matching archive when you want that same build in a folder you can keep, copy to another machine, or publish elsewhere. ## Step-by-Step 1. Decide whether you want the newest ready docs for a project or one exact variant. | Use this when you want... | Open in the browser | Download it | Archive name | |---|---|---|---| | The newest ready docs you can access for a project | `/docs//` | `docsfy download ` | `-docs.tar.gz` | | One exact branch/provider/model build | `/docs/////` | `docsfy download --branch --provider --model ` | `----docs.tar.gz` | > **Warning:** The short project form can change as newer ready variants finish. Use the exact variant form when you need a stable bookmark, review link, or published artifact. 2. Open the docs site from the dashboard. Select the ready variant you want, then click **View Documentation** to open that exact variant in a new tab. If a run is still working, wait until it reaches `Ready`. See [Tracking Generation Progress](track-generation-progress.html) for the live status workflow. 3. Move around the docs site with the built-in navigation tools. Use the left sidebar to jump between sections and pages, use the search field or the **Search** button in the top bar to find matching pages and text, and use **On this page**, when it appears, to jump between headings in the current page. At the bottom of a page, use **Previous** and **Next** to keep reading in order. 4. Download the same site as a static archive. ```shell docsfy download --branch --provider --model ``` In the web app, the ready variant panel has a **Download** button that starts the same `.tar.gz` download. In the CLI, omit the variant flags only when you want the newest ready variant for that project instead of one exact build. If you need help choosing a branch or model before you download, see [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html). 5. Extract the archive into the folder you want to keep or publish. ```shell mkdir -p published-docs tar -xzf .tar.gz --strip-components=1 -C published-docs ``` After extraction, `published-docs/` contains the site entry page, page HTML files, static assets, the search index, and the bundled LLM-friendly files. Keep the whole folder together so styling, search, navigation, and footer links continue to work whether you keep it offline or publish it elsewhere. ```mermaid flowchart LR A[Ready variant] --> B[Open in browser] B --> C[Use sidebar, search, and page navigation] A --> D[Download tar.gz] D --> E[Extract into a folder] E --> F[Keep offline or publish] ``` > **Tip:** The extracted bundle includes `.nojekyll`, so it can be published directly on GitHub Pages-style static hosts. ## Advanced Usage ### Direct Links and Automation ```text /docs///// /api/projects/////download ``` Use the exact variant form when you want everyone to see the same branch, provider, and model. For raw route details and scripted downloads, see [HTTP API and WebSocket Reference](http-api-and-websocket-reference.html). ### Extract with the CLI Instead of Keeping the Archive ```shell docsfy download --branch --provider --model --output ./published-docs ``` With `--output`, the CLI downloads and extracts the archive for you. The extracted files stay inside the archive's top-level folder, so point your static host at the folder that contains `index.html`. See [CLI Command Reference](cli-command-reference.html) for the full flag list. ### Publish the Full Bundle, Not Just the Landing Page Keep these files in the published copy: - `assets/` for styling and client-side behavior - `search-index.json` for built-in search - `llms.txt` and `llms-full.txt` for the bundled AI-friendly copies - the generated page `.md` files if you want the links inside `llms.txt` to keep working > **Warning:** Once you publish the files outside docsfy, docsfy sign-in and project access rules no longer protect them. Use your static host, CDN, or reverse proxy if the published copy must stay private. ### Handle Multiple Owners as an Admin ```shell docsfy download --branch --provider --model --owner ``` ```text /docs/////?owner= ``` If multiple owners have the same project name and variant, choose the owner explicitly so you open or download the right copy. For access and sharing rules, see [Managing Users and Access](manage-users-and-access.html). ## Troubleshooting - If opening a docs URL sends you to the login page, sign in to the web app first. - If a signed-in user gets `404`, there may be no ready variant for that link, or that user may not have access to the project. - If `docsfy download` says `--branch`, `--provider`, and `--model` must be provided together, either supply all three or omit all three. - If the published copy loads without styling or search, upload the whole extracted folder, not just `index.html`. - If an admin is told to specify an owner, use the exact variant form and choose the owner explicitly. - If the docs you opened are not the variant you expected, use the exact variant form instead of the short project form. - If you need help with readiness, access, or failed downloads, see [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html). ## Related Pages - [Tracking Generation Progress](track-generation-progress.html) - [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) - [HTTP API and WebSocket Reference](http-api-and-websocket-reference.html) - [Managing Users and Access](manage-users-and-access.html) --- Source: configure-ai-providers-and-models.md # Configuring AI Providers and Models You want each generation to use the provider and model you intended, whether you start it from the web app or the CLI. Picking the pair deliberately keeps runs predictable, makes the right variant easy to find later, and avoids accidental fallback to server defaults. ## Prerequisites - A running docsfy server with at least one working AI provider. - Permission to start generations as a `user` or `admin`. - If you use the CLI, a configured CLI profile. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html). - If you want to change server defaults, access to the server environment or `.env`. See [Configuration Reference](configuration-reference.html). - If provider setup is not working yet, see [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) or [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html). ## Quick Example ```shell docsfy models --provider cursor docsfy generate https://github.com/myk-org/for-testing-only \ --provider cursor \ --model gpt-5.4-xhigh-fast ``` The first command shows what docsfy already knows about `cursor` models. The second command starts a run with an explicit provider/model pair, so the request cannot silently fall back to something else. ## Step-by-Step ```mermaid flowchart LR A[Server defaults] --> B[CLI run with omitted values] C[Successful Ready generations] --> D[Known model suggestions] D --> E[Web app model field] F[Explicit provider and model] --> G[Exact variant used for the run] B --> G E --> G ``` 1. Review or set the server defaults. ```dotenv AI_PROVIDER=cursor AI_MODEL=gpt-5.4-xhigh-fast AI_CLI_TIMEOUT=60 ``` These values are the server-side fallback when a run does not supply a provider, a model, or a timeout. After you change them, restart `docsfy-server`. See [Configuration Reference](configuration-reference.html) for the full settings list. 2. Check how defaults and known models appear. ```shell docsfy models docsfy models --provider gemini ``` | Surface | What you can choose or see | How defaults appear | | --- | --- | --- | | Web app `New Generation` | Fixed provider list: `claude`, `gemini`, `cursor`; model suggestions for the selected provider; typed model names | The form does not mark the server default provider or model | | `docsfy models` | All supported providers and known models | `(default)` marks the server default provider and model | | `docsfy generate` | `--provider` and `--model`, or omitted values | Any missing value is filled by the server default | > **Note:** Known models come from successful `Ready` generations. They are not a live catalog of every model your provider account could use. > **Tip:** On a brand-new server, `docsfy models` can show `(no models used yet)` and the web app model suggestions can be empty. You can still type a model manually. 3. Start the run with an explicit pair when you want a predictable result. ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash ``` In the web app, open `New Generation`, choose `gemini`, then choose or type `gemini-2.5-flash` before you click `Generate`. For the rest of the run flow, see [Generating Documentation](generate-documentation.html). > **Tip:** After you change the provider in the web app, check the `Model` field again before you submit. 4. Confirm the exact variant after the run starts. ```shell docsfy status for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash ``` Use all three selectors together when you want one exact variant. This matters most after you try multiple providers or models for the same repository. See [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) for the full variant workflow. 5. Use server defaults only when you mean to. ```shell docsfy models docsfy generate https://github.com/myk-org/for-testing-only ``` This CLI example omits both flags, so the server applies its current default provider and model. If you want the same pair from the web app, check it with `docsfy models` first, then select those values manually. > **Warning:** Avoid setting only one of the two values. If you pass `--provider` without `--model`, or leave the web app model field blank, the server fills only the missing side. That can produce a provider/model combination you did not intend. ## Advanced Usage Use this table when you want to avoid the most common mismatches: | Goal | Safe choice | Risky choice | | --- | --- | --- | | Use the server default pair from the CLI | Omit both `--provider` and `--model` | Set only one of them | | Start a specific run in the web app | Choose the provider and choose or type the model | Change the provider and assume the model still matches | | Try a model that is not suggested yet | Type the exact model name manually | Wait for it to appear before trying it | | Confirm what docsfy has learned | Run `docsfy models` | Assume suggestions are a live provider catalog | The web app model field is free-form. If the model you want is not suggested yet, type it exactly and start the run anyway. After a generation reaches `Ready`, that model becomes part of docsfy’s known-model list for that provider. It then appears in `docsfy models` and in later web app suggestions for that provider. The web app remembers the repository URL, branch, and `Force full regeneration` checkbox in the current browser session, but it does not keep your provider or model choice. Each new form starts on `cursor`, so re-check both fields every time if you usually run with `claude` or `gemini`. For filtering or automation, use the CLI directly: ```shell docsfy models --provider gemini docsfy models --json ``` See [CLI Command Reference](cli-command-reference.html) for the full command syntax. ## Troubleshooting - `docsfy models` shows `(no models used yet)`: the server can still be healthy. It only means there is no successful `Ready` generation recorded yet for that provider. - The web app started on `cursor` again: expected. Provider and model are not remembered between runs. - The CLI shows the default pair, but the web app does not: expected. The web app does not mark server defaults. - A run used the wrong model: start the next run with both provider and model set explicitly, then verify it with `docsfy status`. - Generation fails immediately even though the provider is visible in the web app: that provider list is fixed and does not prove the provider CLI is installed or signed in. See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html). - New defaults seem ignored: restart `docsfy-server` after changing `AI_PROVIDER`, `AI_MODEL`, or `AI_CLI_TIMEOUT`. ## Related Pages - [Configuration Reference](configuration-reference.html) - [Generating Documentation](generate-documentation.html) - [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) --- Source: regenerate-after-code-changes.md # Regenerating After Code Changes You want the docs to match the latest commit without wasting time on pages that do not need to change. The normal rerun path lets docsfy reuse earlier work when it can, while the forced path gives you a clean rebuild when you need to start over. ## Prerequisites - A ready docs variant already exists for the same repository, branch, provider, and model. If not, see [Generating Documentation](generate-documentation.html). - The changes you want documented are pushed to the remote branch. The dashboard and CLI regenerate from the Git URL, not from your local working tree. - `user` or `admin` access if you are using the dashboard. - For CLI examples, a configured `docsfy` connection. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html). ## Quick Example ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash ``` Run the same repository, branch, provider, and model again after you push code changes. With `--force` omitted, docsfy tries to reuse the existing variant before it decides to rebuild everything. ## Step-by-Step 1. Check the exact variant you want to refresh. ```shell docsfy status for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash ``` Use all three selectors together so you do not refresh the wrong variant. In the CLI, `for-testing-only` is the project name derived from the Git URL; in the dashboard, open that ready variant first. > **Note:** This page is about refreshing the same variant after code changes. If you want a different branch or model on purpose, see [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html). 2. Start a normal regenerate first. ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash \ --watch ``` In the dashboard, open the variant, leave `Force full regeneration` unchecked, and click `Regenerate`. This is the best default because docsfy can skip unchanged work or reuse earlier output automatically. > **Tip:** Start without force unless you already know you need a clean rebuild. If reuse is not possible, docsfy falls back to a full rebuild on its own. 3. Watch the rerun until it reaches `ready`. ```shell docsfy status for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash ``` If nothing changed, the rerun can finish quickly and the dashboard shows **Documentation is already up to date.** If the docs do need refreshing, let the run finish and confirm the updated `Commit`, `Status`, and `Pages` values. See [Tracking Generation Progress](track-generation-progress.html) for stage meanings. 4. Open or download the refreshed docs. When the variant is `ready`, open or download the site the same way you would after any successful run. See [Viewing and Downloading Docs](view-and-download-docs.html) for that next step. 5. Force a clean rebuild when you need one. ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash \ --force \ --watch ``` In the dashboard, check `Force full regeneration` before you click `Regenerate`. Use this when output looks stale, a previous run failed, or you want docsfy to ignore cached page output and rebuild the same variant in place from zero. ## Advanced Usage ```mermaid flowchart TD A[Regenerate same variant without force] --> B{Anything new to document?} B -- No --> C[Ready immediately: already up to date] B -- Yes --> D{Can docsfy reuse earlier work?} D -- Yes --> E[incremental_planning] E --> F[Regenerate only affected pages] D -- No --> G[Full rebuild automatically] F --> H[Ready] G --> H I[Regenerate with force] --> G ``` | Situation | What docsfy does | | --- | --- | | Same commit as the last ready run for that variant | Finishes as `ready` without rebuilding pages | | New commit, but no file changes to document | Finishes as `ready` and treats the docs as already up to date | | New commit, previous ready copy of that variant can be reused | Reuses the existing plan and unchanged pages, then regenerates only the affected pages | | New commit, but reuse cannot be worked out safely | Falls back to a full rebuild automatically | | `--force` or `Force full regeneration` | Clears cached page output and rebuilds from scratch | A few details matter in practice: - A normal rerun can show `incremental_planning` instead of `planning`. That is the reuse path, not an error. - A forced rerun resets page progress and rebuilds the variant from zero. - In the dashboard, variants in `error` or `aborted` state reopen with `Force full regeneration` already enabled. - If you want a new branch or model instead of refreshing the same one, see [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html). ## Troubleshooting - **The rerun finished almost immediately:** docsfy decided the selected variant was already current. That can mean the commit is unchanged, or a new commit did not produce any file changes that require new docs. Run again with force if you still want a clean rebuild. - **A normal rerun is taking as long as a first build:** docsfy may have fallen back to a full rebuild. Check the current stage with `docsfy status ...`; if you see `planning` rather than `incremental_planning`, that is expected fallback behavior. See [Tracking Generation Progress](track-generation-progress.html) for the stage names. - **You get an `already being generated` error:** wait for that exact variant to finish, or abort it first. ```shell docsfy abort for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.5-flash ``` - **The refreshed docs do not include your latest local edits:** push those changes to the remote branch and rerun. The dashboard and CLI do not read unpublished local working tree changes. - **The regenerate controls are missing in the dashboard:** your account is probably `viewer`. Ask for `user` or `admin` access. - **The rerun fails instead of reaching `ready`:** inspect the exact variant error, then see [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html). ## Related Pages - [Generating Documentation](generate-documentation.html) - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) --- Source: regenerate-for-new-branches-and-models.md # Regenerating for New Branches and Models You want a separate docs variant for another branch or AI model so you can compare outputs, keep release-specific docs, or grab a precise build later without overwriting the version you already use. docsfy can reuse finished work to make this faster, but the result depends on whether you changed the branch, the provider/model, or turned on a full rebuild. ## Prerequisites - A running docsfy server and an account with write access. - A repository URL that the server can clone. - A provider and model that work in your environment. - Optional: a configured `docsfy` CLI profile. See [Generating Documentation](generate-documentation.html) for the basic first-run flow, or [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) if you need CLI setup first. ## Quick Example ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch dev \ --provider gemini \ --model gemini-2.5-flash ``` This creates a separate `dev/gemini/gemini-2.5-flash` variant for the same repository instead of changing an existing `main` variant. ## Step-by-step 1. Create the branch variant you want. ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch dev \ --provider gemini \ --model gemini-2.5-flash \ --watch ``` In the web app, use `New Generation`, keep the same repository URL, type the new branch, pick the provider and model, and start the run. This is the branch-changing path in the UI. > **Note:** If you omit `--branch`, docsfy uses `main`. > **Tip:** Branch suggestions only come from ready variants for that repository. You can still type a new branch even if it is not listed yet. 2. Create a different provider/model variant on the same branch. ```shell docsfy generate https://github.com/myk-org/for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.0-flash ``` In the web app, open the ready variant and use `Regenerate Documentation`. That form keeps the selected branch fixed and lets you change the provider or model. 3. Check exactly which variant you have before you open or download it. ```shell docsfy status for-testing-only docsfy status for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.0-flash ``` The first command lists every variant for that repository. The second command targets one exact branch, provider, and model combination. In the web app, variants are grouped by branch in the sidebar. Expand the repository, open the `@branch` group you want, and select the provider/model row. 4. Open or download the exact variant you asked for. ```shell docsfy download for-testing-only \ --branch main \ --provider gemini \ --model gemini-2.0-flash ``` In the web app, the `View Documentation` and `Download` buttons on a selected variant already use that exact branch/provider/model. In the CLI, add `--output` if you want the archive extracted into a directory instead of saved as a `.tar.gz` file. 5. Choose whether you want reuse or a clean rebuild. | Change you make | Without `--force` | With `--force` | | --- | --- | --- | | Same branch, same provider/model | Updates that same variant. If the commit is unchanged, docsfy marks it as already up to date. | Rebuilds that same variant from scratch. | | Same branch, different provider/model | Reuses the newest ready variant on that branch when possible, then replaces the older source variant after the new one is ready. | Builds the new variant from scratch and keeps the existing variant. | | Different branch | Creates a separate branch variant. The first ready variant on that branch does not reuse a ready variant from another branch. | Still creates a separate branch variant. Use this when you want a clean rebuild of that branch variant. | > **Warning:** A non-force provider/model switch on the same branch is replacement behavior, not side-by-side storage. If you want to keep both variants on that branch, turn on `Force full regeneration`. ## Advanced Usage ```mermaid flowchart TD A[Start a generation] --> B{Same branch?} B -- No --> C[Create a separate branch variant] C --> D[Future reuse stays on that branch] B -- Yes --> E{Same provider and model?} E -- Yes --> F{Force enabled?} F -- No --> G[Reuse current variant when possible] G --> H{Same commit or no file changes?} H -- Yes --> I[Mark variant up to date] H -- No --> J[Reuse plan and unchanged pages when possible] F -- Yes --> K[Full rebuild in place] E -- No --> L{Force enabled?} L -- No --> M[Reuse newest ready variant on that branch] M --> N{Same commit?} N -- Yes --> O[Copy existing docs artifacts] N -- No --> P[Reuse unchanged cached pages when possible] O --> Q[Replace older source variant] P --> Q L -- Yes --> R[Build a new variant and keep the existing one] ``` Use the exact form when precision matters: | Goal | Command or URL | What you get | | --- | --- | --- | | Open the latest ready docs for a repo | `/docs/for-testing-only/` | The most recently generated ready variant | | Open one exact variant | `/docs/for-testing-only/dev/gemini/gemini-2.5-flash/` | Only that branch/provider/model | | Download the latest ready docs for a repo | `docsfy download for-testing-only` | The most recently generated ready variant | | Download one exact variant | `docsfy download for-testing-only --branch dev --provider gemini --model gemini-2.5-flash` | Only that branch/provider/model | ```shell docsfy models --provider gemini ``` Use this when you need the current provider defaults and the known model names from completed generations. The web app uses the same ready-variant history to populate model suggestions. A few edge cases matter in practice: - Same-commit provider/model switches without force can finish by copying the previous docs artifacts, so the new variant can be identical to the old one. - New commits on the same branch can reuse the existing plan and unchanged pages when docsfy can tell what changed. If it cannot reuse safely, it falls back to a full regeneration automatically. - The same replacement rules apply whether you change just the model or switch providers too. - In the web app, `error` and `aborted` variants reopen `Regenerate Documentation` with `Force full regeneration` enabled by default. - If you copied a generation ID from the sidebar or variant detail view, `docsfy status` and `docsfy download` accept that ID too, so you do not have to retype the branch, provider, and model. See [Tracking Generation Progress](track-generation-progress.html) for live stage details, [CLI Command Reference](cli-command-reference.html) for full flag syntax, [Configuration Reference](configuration-reference.html) for server defaults, and [HTTP API and WebSocket Reference](http-api-and-websocket-reference.html) if you need to automate this flow. ## Troubleshooting - A branch like `release/v2.0` is rejected: docsfy does not allow `/` in branch names. Use something like `release-v2.0` or `release-1.x`. - The wrong docs opened or downloaded: you probably used the default project route or `docsfy download` without branch/provider/model selectors. Use the fully qualified form when you need one exact variant. - A branch or model is missing from the suggestion list: only ready variants populate those lists. Type the value manually, or run `docsfy models --provider gemini`. - The old provider/model variant disappeared after a switch: that is expected after a same-branch non-force switch. Rerun with `--force` if you want both variants to remain. - The run ends in `Clone failed`, or the branch never appears: verify that the branch exists in the remote repository and that the server can access that repository. See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) for broader setup and runtime failures. ## Related Pages - [Generating Documentation](generate-documentation.html) - [Configuring AI Providers and Models](configure-ai-providers-and-models.html) - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) --- Source: manage-docsfy-from-the-cli.md # Managing docsfy from the CLI Run docsfy from a terminal when you want to save a profile, start a docs run, watch it finish, and fetch the result without opening the web app. That keeps repeat work fast in remote shells, local terminals, and simple scripts. ## Prerequisites - A running docsfy server you can reach - The `docsfy` command installed on your machine. If you still need local setup, see [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html). - An API key for that server - A `user` or `admin` key if you want to run `generate`, `abort`, or `delete` - A Git repository URL the server can reach ## Quick Example ```shell docsfy config init docsfy health docsfy generate https://github.com/myk-org/for-testing-only --watch docsfy status for-testing-only docsfy download for-testing-only --output ./site ``` Replace `https://github.com/myk-org/for-testing-only` with the repository you want to document. The rest of the flow stays the same. ```mermaid flowchart LR A[Save profile] --> B[Check server] B --> C[Start generation] C --> D[Watch progress] D --> E[Inspect variants] E --> F[Download output] ``` ## Step-by-step 1. Save a reusable profile. ```shell docsfy config init docsfy config show ``` When `docsfy config init` asks for `Password`, enter your API key. For the built-in admin account, the username is `admin`. ```toml [default] server = "dev" [servers.dev] url = "http://localhost:8000" username = "admin" password = "" ``` The first profile you create becomes the default. Later profiles are added without changing that default automatically. > **Note:** Profiles live in `~/.config/docsfy/config.toml`. `docsfy config show` masks the saved key, but the file stores the full value, so keep it private. See [Configuration Reference](configuration-reference.html) for the full profile format. 2. Confirm that the CLI is pointing at the right server. ```shell docsfy health ``` A working connection prints the server URL and `Status: ok`. Run this first whenever you switch environments or update a profile. 3. Start a generation and watch it live. ```shell docsfy generate https://github.com/myk-org/for-testing-only --watch ``` Use an HTTPS or SSH Git URL. If you omit `--branch`, docsfy uses `main`. If you omit `--provider` and `--model`, the server uses its current defaults. Later commands use the repository name from the URL, with any `.git` suffix removed, so this repository becomes `for-testing-only`. ```text Project: for-testing-only Branch: main Status: generating Generation ID: Watching generation progress... [generating] cloning [generating] planning [generating] generating_pages (3 pages) Generation complete! (9 pages) ``` Save the generation ID if you want an exact handle for later commands. The exact stage list and page counts vary by run. See [Tracking Generation Progress](track-generation-progress.html) for the meaning of each stage. > **Tip:** If you want `--watch` to follow one exact variant from the start, run `docsfy models` first and pass both `--provider` and `--model` to `docsfy generate`. > **Warning:** `docsfy generate` accepts a remote Git URL, not a local path. Branch names cannot contain `/`, so use `release-1.x` instead of `release/1.x`. 4. Inspect the variants you can access. ```shell docsfy list docsfy status for-testing-only docsfy status ``` `docsfy list` prints one row per variant, including `NAME`, `BRANCH`, `PROVIDER`, `MODEL`, `STATUS`, `OWNER`, `PAGES`, and `GEN ID`. `docsfy status` shows the fuller detail view, including stage, last update time, short commit, and any error message. > **Tip:** Use the generation ID from `docsfy generate` or `docsfy list` when you want the exact variant without retyping branch, provider, and model. 5. Download the finished output. ```shell docsfy download for-testing-only docsfy download --output ./site ``` | Command | What you get | | --- | --- | | `docsfy download for-testing-only` | A `.tar.gz` archive for the latest ready variant you can access, saved in your current directory. | | `docsfy download --output ./site` | One exact variant, downloaded and extracted directly into `./site`. | Without `--output`, the archive name is `-docs.tar.gz`. With `--output`, docsfy creates the target directory if needed and extracts the archive there. ## Advanced Usage ### Switch profiles or override them for one command ```shell docsfy config set default.server prod docsfy --server prod health docsfy --host docsfy.example.com --port 443 -u admin -p health ``` Use `--server` when you already saved multiple profiles. Use `--host`, `--port`, `-u`, and `-p` before the subcommand when you need a one-off connection without changing the saved file. | Command | Meaning of `-p` | | --- | --- | | `docsfy --server prod -p health` | API key/password, because it appears before the subcommand. | | `docsfy status for-testing-only -p cursor` | AI provider, because it appears after `status`. | > **Tip:** Put global connection flags before the subcommand. ### Pick an exact provider, model, or branch ```shell docsfy models docsfy models --provider cursor docsfy generate https://github.com/myk-org/for-testing-only --branch dev --force docsfy status for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast docsfy download for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast --output ./site ``` Use `docsfy models` to see the current default provider and model, plus model names the server already knows about. A provider can show `(no models used yet)` until a ready variant has been generated with it. Replace `cursor` and `gpt-5.4-xhigh-fast` with the values your server reports. Use `--force` when you want a full rebuild instead of reusing existing artifacts. If you intentionally keep separate outputs for other branches or models, see [Regenerating for New Branches and Models](regenerate-for-new-branches-and-models.html). ### Stop or clean up runs ```shell docsfy abort for-testing-only docsfy abort docsfy delete --yes docsfy delete for-testing-only --all --yes ``` Project-level `abort` is convenient when only one active variant matches that project name. Use a generation ID when more than one run might be active, or when you want copy-paste-safe cleanup. `docsfy delete ... --all --yes` removes every variant of that project that belongs to you. If you only want one variant, delete by generation ID instead. ### Use JSON output for scripts ```shell docsfy list --status ready --json docsfy status for-testing-only --json docsfy models --provider cursor --json ``` These commands return JSON instead of table or plain-text output, which is easier to pipe into your own scripts. See [CLI Command Reference](cli-command-reference.html) for the full flag list. ### Disambiguate same-name projects as an admin ```shell docsfy status shared-name --branch main --provider claude --model opus --owner alice docsfy download shared-name --branch main --provider claude --model opus --owner alice --output ./site ``` Use `--owner` only with fully specified variant commands. It helps when the same project name exists under more than one owner and you need one exact copy. ## Troubleshooting - `No server configured`: run `docsfy config init`, or pass `--host`, `--port`, `-u`, and `-p` before the subcommand. - `Server unreachable` or a redirect error: check the saved URL with `docsfy config show`, then rerun `docsfy health`. - `Write access required`: the API key belongs to a `viewer`; use a `user` or `admin` account for `generate`, `abort`, and `delete`. - `Invalid branch name`: branch names cannot contain `/`; use `release-1.x` instead. - A project name points to more than one possible variant, or a run is already active: run `docsfy list`, then retry with the generation ID or a fully specified variant selector. - `Variant not ready`: wait until `docsfy status ...` shows `ready`, then download again. - A repository URL that points to `localhost` or another private-network host is rejected: use a remote the server can reach. See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) for broader setup and generation failures. ## Related Pages - [CLI Command Reference](cli-command-reference.html) - [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) - [Configuration Reference](configuration-reference.html) - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) --- Source: manage-users-and-access.md # Managing Users and Access Use this page when you need to onboard teammates, give them the smallest role that still lets them work, and share only the docs they should see. That keeps readers out of generation and admin workflows while still letting writers and admins do their jobs. ## Prerequisites - An `admin` account. The built-in admin signs in as `admin`. - If you use the CLI, a working profile or one-off connection flags. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) for details. - A project that already exists before you try to share it. See [Generating Documentation](generate-documentation.html) for details. ## Quick Example ```shell docsfy admin users create alice --role viewer docsfy admin access grant my-repo --username alice --owner admin docsfy admin access list my-repo --owner admin ``` This creates a read-only teammate, shares `admin`'s `my-repo` project with them, and confirms the grant. The password docsfy prints is the same secret the user will use to sign in on the web and authenticate from the CLI. ## Step-by-Step 1. Pick the role before you create the account. | Role | Best for | Can generate, abort, or delete docs? | Can manage users and access? | | --- | --- | --- | --- | | `admin` | Platform owners and delegated admins | Yes | Yes | | `user` | Teammates who generate and maintain their own docs | Yes, for their own projects | No | | `viewer` | Read-only readers | No | No | Role controls what someone can do. Project access controls which docs they can see. ```mermaid flowchart LR A[Choose a role] --> B[What the user can do] C[Grant project access] --> D[Which docs they can open] ``` > **Tip:** Start with `viewer` unless the person needs to generate or delete docs. 2. Create the user. ```shell docsfy admin users create alice --role viewer docsfy admin users list ``` Usernames must be 2-50 characters and use letters, numbers, dots, hyphens, or underscores. The name `admin` is reserved. docsfy shows the generated password once and does not show it again later. If you prefer the browser, admins can create accounts from the `Users` screen. > **Warning:** Save the password before you dismiss the output or dialog, then share it over a secure channel. 3. Grant access to the project the user should see. ```shell docsfy admin access grant my-repo --username alice --owner admin docsfy admin access list my-repo --owner admin ``` Use the real project owner in `--owner`. That matters whenever more than one person has a project with the same name. | Grant | What the user gets | | --- | --- | | `my-repo` with `--owner admin` | All variants of `my-repo` owned by `admin`, across branches and provider/model combinations | | `my-repo` with `--owner alice` | Only Alice's copy of `my-repo`, not anyone else's | Shared access does not transfer ownership. Non-admin users can open and download shared docs, but they still cannot delete or administer someone else's project. After the grant, the shared project appears alongside the user's own projects. See [Viewing and Downloading Docs](view-and-download-docs.html) for the read-only workflow. 4. Rotate a password when access changes. ```shell docsfy admin users rotate-key alice docsfy admin users rotate-key alice --new-key "alice-2026-password-rotate" ``` Use the first form when you want docsfy to generate a fresh password for you. Use `--new-key` only when you need a planned replacement, and make sure it is at least 16 characters long. Rotation invalidates the old password immediately and signs the user out of their current sessions. After you hand off the new password, the user signs in again with that value. Named users, including `viewer` accounts and created `admin` accounts, can also use `Change Password` in the dashboard sidebar for self-service rotation. The built-in `admin` account is the exception; change `ADMIN_KEY` for that account instead. 5. Revoke one project or remove the user completely. ```shell docsfy admin access revoke my-repo --username alice --owner admin docsfy admin users delete alice --yes ``` | If you want to... | Use | | --- | --- | | Keep the account but hide one project's docs | `docsfy admin access revoke ...` | | Remove the account and all of its access | `docsfy admin users delete ... --yes` | Revoking access removes only that one owner's project from the user's view. Deleting a user removes the account, ends their sessions, removes their access grants, and removes projects they owned. ## Advanced Usage ### Same project name, different owners ```shell docsfy admin access grant shared-name --username alice --owner team-a docsfy admin access grant shared-name --username alice --owner team-b ``` These are two separate grants. docsfy shares access by project name plus owner, not by one specific branch or model. If two owners each have a `shared-name` project, grant only the owner you actually want to expose. Add the second grant only when the user should see both copies. ### Built-in admin and created admin accounts behave differently | Account type | Sign in as | Can use admin tools? | Can change its own password from the dashboard? | | --- | --- | --- | --- | | Built-in admin | `admin` | Yes | No | | Created admin user | Their own username | Yes | Yes | Use a created `admin` account when you want a named administrator with their own rotatable password. Use the built-in `admin` account for initial setup or recovery. ### Rotate the built-in admin password carefully ```dotenv ADMIN_KEY= ``` Use a value at least 16 characters long, change it in your deployment environment or `.env`, then restart docsfy. See [Configuration Reference](configuration-reference.html) for the setting itself. > **Warning:** Changing `ADMIN_KEY` does more than rotate the built-in `admin` login. Previously issued passwords for created users stop working too, so plan a coordinated rotation and hand out replacement passwords right away. ## Troubleshooting - `No server configured`: run `docsfy config init`, or use `--host`, `--port`, `-u`, and `-p` before the subcommand. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) for details. - `Project not found` when granting access: generate the project first, and make sure `--owner` matches the account that owns it. See [Generating Documentation](generate-documentation.html) for details. - `Write access required`: the account is `viewer`, which is read-only by design. Use `user` or `admin` for generation and deletion tasks. - `Cannot delete your own account`: sign in as a different admin to remove that user. - `Cannot delete user while generation is in progress`: wait for the run to finish, or stop it first. See [Tracking Generation Progress](track-generation-progress.html) for details. - Sent back to the login page right after a password change: that is expected. Sign in again with the new password. - The built-in `admin` account cannot change its own password from the dashboard: change `ADMIN_KEY` instead. See [Configuration Reference](configuration-reference.html) for details. ## Related Pages - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) - [CLI Command Reference](cli-command-reference.html) - [Generating Documentation](generate-documentation.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [HTTP API and WebSocket Reference](http-api-and-websocket-reference.html) --- Source: fix-setup-and-generation-problems.md # Fixing Setup and Generation Problems You want docsfy to accept your sign-in, start a run, and get that run back to `ready` instead of failing on login, provider setup, repo validation, or a stuck variant. Use these checks to isolate the real cause quickly so you only retry after fixing the right thing. ## Prerequisites - A running docsfy server. - A valid admin key or user API key. - A Git repository URL the server can reach. - If you use the CLI, either a saved profile from `docsfy config init` or explicit `--host`, `--port`, `-u`, and `-p` flags. ## Quick Example ```bash docsfy health docsfy models docsfy generate https://github.com/myk-org/for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast --force --watch docsfy status for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast ``` Use the public `for-testing-only` repository first. If this works, your server connection, credentials, repo input, and basic generation path are all working. If your server defaults are different, substitute the provider and model shown by `docsfy models`. If you just need the normal first-run path instead of troubleshooting, see [Generate Your First Docs Site](generate-your-first-docs-site.html). ```mermaid flowchart TD A[Run will not start or finish] --> B{Can docsfy reach the server?} B -->|No| C[Fix saved URL or start the server] B -->|Yes| D{Can you sign in?} D -->|No| E[Fix username or API key] D -->|Yes| F{Does the run fail immediately?} F -->|Yes| G[Check provider CLI, repo URL, and branch] F -->|No| H[Inspect the exact variant] H --> I{Status} I -->|generating| J[Wait or abort that variant] I -->|error| K[Read Error and rerun with --force] I -->|ready| L[Open or download docs] ``` ## Step-by-Step ### 1. Confirm the server target ```bash docsfy config show docsfy health ``` `docsfy config show` should point at the server you expect. `docsfy health` should return `Status: ok`. If the config is missing, run `docsfy config init`. When it asks for `Password`, enter your admin key or user API key. See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) for the full CLI setup flow. If `docsfy health` says `Server unreachable`, fix the saved URL, host, or port. If it says the server redirected you somewhere else, the CLI is pointed at the wrong address. ### 2. Fix login before anything else | Sign-in type | Username | Password field | | --- | --- | --- | | Built-in admin | `admin` | `ADMIN_KEY` | | Named user | your exact username | your API key | The browser login form always labels the secret as `Password`, but named users must still enter their API key there. The built-in admin only works when the username is literally `admin`. > **Warning:** If login works once and then you keep landing back on `/login` on plain `http://localhost`, set `SECURE_COOKIES=false` and restart the server. Keep `SECURE_COOKIES=true` for HTTPS deployments. > **Note:** Browser and CLI sign-in are separate. A working browser session does not fix a broken CLI profile, and a working CLI profile does not refresh an expired browser session. ### 3. Verify the AI tool can actually run ```bash docsfy models docsfy generate https://github.com/myk-org/for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast --force ``` Use only `claude`, `gemini`, or `cursor` as provider names. `docsfy models` shows the server defaults and any models docsfy has already seen in ready runs. A provider or model appearing in the UI or in `docsfy models` is not a live health check. Those suggestions come from previous ready variants, so a new generation can still fail immediately if the provider CLI is missing, not signed in, or cannot use that model. On a brand-new server, `docsfy models` can show `(no models used yet)` and still be healthy. If you run docsfy without Docker, make sure the provider CLI you selected is installed and authenticated on the server machine, then restart the server. See [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) for the setup steps. ### 4. Recheck the repo URL and branch ```bash docsfy generate https://github.com/myk-org/for-testing-only --branch dev --force ``` Use a real Git remote with a hostname. The supported remote formats are direct HTTPS or SSH URLs such as `https://github.com/org/repo.git` and `git@github.com:org/repo.git`. Bare local paths, `localhost` URLs, and URLs that resolve to private network addresses are rejected before generation starts. If you only need the standard run flow, see [Generating Documentation](generate-documentation.html). | Use this | Not this | Why | | --- | --- | --- | | `main` | `.hidden` | The branch must start with a letter or number. | | `release-1.x` | `release/1.x` | Slashes are rejected. | | `v2.0.1` | `../repo` | `..` and traversal-like names are rejected. | If you omit `--branch`, docsfy uses `main`. If the branch name is valid but cloning still fails, confirm that branch really exists in the remote repository. ### 5. Recover the exact variant that failed ```bash docsfy status for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast docsfy abort for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast docsfy generate https://github.com/myk-org/for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast --force --watch ``` Always inspect the exact `branch` / `provider` / `model` combination you are fixing. The same repository can have multiple variants at once, and only one of them may be stuck or broken. | Status | What it means | What to do next | | --- | --- | --- | | `generating` | The run is still active | Wait, or abort that exact variant before retrying. | | `ready` | The docs finished successfully | Open or download the docs. See [Viewing and Downloading Docs](view-and-download-docs.html). | | `error` | The run stopped | Read the `Error` field, fix the cause, then rerun with `--force`. | | `aborted` | The run was stopped on purpose | Start a new run if you still need this variant. | If a run comes back `ready` with an `up_to_date` stage, nothing is broken. docsfy decided the existing docs already match the current repository state. Where the run stopped helps you narrow the cause. Problems in or before `cloning` usually point to repo or provider setup, while later failures are best diagnosed from the variant’s `Error` field. See [Tracking Generation Progress](track-generation-progress.html) for the fuller stage-by-stage view. ## Advanced Usage ### Recheck the server settings that affect troubleshooting ```env ADMIN_KEY= AI_PROVIDER=cursor AI_MODEL=gpt-5.4-xhigh-fast AI_CLI_TIMEOUT=120 SECURE_COOKIES=false ``` `ADMIN_KEY` is required and must be at least 16 characters long. `AI_CLI_TIMEOUT` must be greater than zero, so increase it if the provider CLI starts slowly instead of failing outright. `SECURE_COOKIES=false` is only for plain local HTTP. For normal HTTPS deployments, switch it back to `true`. See [Configuration Reference](configuration-reference.html) for the full settings list. ### Use generation IDs to target the exact run ```bash docsfy status docsfy abort ``` Every run gets a generation ID, and the CLI accepts that ID anywhere it normally accepts a project name. This is the cleanest way to inspect or abort one specific run when names, branches, or models are easy to mix up. ### Disambiguate admin actions by owner ```bash docsfy status for-testing-only --branch main --provider cursor --model gpt-5.4-xhigh-fast --owner ``` Admins can see more than one owner’s copy of the same variant. If you hit a `Multiple owners found` error, rerun the command with `--owner`. ### When `--watch` is the only thing failing ```bash docsfy generate https://github.com/myk-org/for-testing-only --branch main --force --watch docsfy status for-testing-only ``` The CLI `--watch` mode depends on the WebSocket connection. If it times out or disconnects, the server-side generation may still be running, so fall back to `docsfy status` before assuming the run failed. ### When a branch or model is missing from the web app suggestions The branch and model fields accept typed values. Their suggestion lists only include branches and models from previous ready variants, so a missing suggestion does not mean the value is invalid. ### If you use a local repository path Local-path generation is an admin-only flow. The path must be absolute, it must exist, it must contain a `.git` directory, and the checked-out branch must match the branch you requested. ### If you automate outside the CLI Use the same recovery sequence: confirm server reachability, authenticate, start one exact variant, then poll that variant until it reaches `ready`, `error`, or `aborted`. See [HTTP API and WebSocket Reference](http-api-and-websocket-reference.html) for the integration endpoints. ## Troubleshooting | Problem | What to do | | --- | --- | | `Invalid username or password` | Use `admin` only with `ADMIN_KEY`. For named users, use the exact username that owns the API key. | | You keep getting sent back to `/login` on local HTTP | Set `SECURE_COOKIES=false`, restart the server, and sign in again. | | `Session expired. Redirecting to login...` | Sign in again. Browser sessions last 8 hours. | | `Server unreachable` or a redirect error in the CLI | Recheck `docsfy config show` and `docsfy health`, then fix the saved server URL, host, or port. | | `docsfy models` shows a model, but generation still fails immediately | Treat the model list as history, not proof the provider CLI is healthy. Install or re-authenticate the selected provider CLI, then retry. | | Repo input is rejected before clone starts | Use a direct remote URL with a hostname. Bare local paths, `localhost`, and private-network repo URLs are rejected. | | `Invalid branch name` | Use a branch that starts with a letter or number and only contains letters, numbers, `.`, `_`, or `-`. Replace `/` with `-`. | | `Variant '...' is already being generated` | Wait for that exact variant to finish, or abort it before starting another run. | | `Multiple active variants found` or `Multiple owners found` | Rerun `status` or `abort` with `--branch`, `--provider`, and `--model`, and add `--owner` when needed. | | `--watch` times out or the WebSocket closes | Check `docsfy status`; the generation may still be running. | | Generate, abort, or delete is missing or returns `Write access required` | Your account is read-only. Use a `user` or `admin` account for write actions. | | The app says `Frontend not built` | Build the frontend with `cd frontend && npm run build`, then restart the server. | See [CLI Command Reference](cli-command-reference.html) for the full CLI syntax. ## Related Pages - [Generate Your First Docs Site](generate-your-first-docs-site.html) - [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) - [Configuring AI Providers and Models](configure-ai-providers-and-models.html) - [Tracking Generation Progress](track-generation-progress.html) - [Configuration Reference](configuration-reference.html) --- Source: cli-command-reference.md # CLI Command Reference > **Tip:** For task-oriented command sequences, see [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html). ## Global Command ### `docsfy` Root command for all CLI operations. **Syntax:** `docsfy [GLOBAL OPTIONS] [ARGS] [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `--server`, `-s` | string | `None` | Server profile name from `~/.config/docsfy/config.toml`. | | `--host` | string | `None` | Overrides the configured host. Builds the URL as `://:`. | | `--port` | integer | `8000` when `--host` is used | Overrides the port used with `--host`. | | `--username`, `-u` | string | `None` | Stored connection username. The CLI resolves and stores it, but requests authenticate with the password/API key bearer token. | | `--password`, `-p` | string | `None` | Password or API key sent as `Authorization: Bearer `. | > **Note:** Put global options before the subcommand. In `docsfy -p health`, `-p` means global `--password`. In `docsfy status my-repo -p cursor`, `-p` means command-level `--provider`. > **Note:** Connection resolution order is: explicit global flags, then `--server`, then `[default].server` in `~/.config/docsfy/config.toml`. > **Note:** Server-backed commands print `Error: Server redirected to . Check the server URL.` for redirects, or `Error (): ` for HTTP errors, then exit `1`. ```shell $ docsfy --server prod health Server: https://docs.example.com Status: ok ``` **Return value/effect:** - Running `docsfy` with no arguments prints help. - If `--host` is used without `--port`, the CLI uses port `8000`. - If `--host` is used with a selected profile whose URL starts with `http://`, the generated URL keeps `http`; otherwise it uses `https`. - If no connection can be resolved, the CLI exits `1`. ## Configuration Commands > **Note:** These commands read and write `~/.config/docsfy/config.toml`. See [Configuration Reference](configuration-reference.html) for the file layout. ### `docsfy config init` Creates or updates a server profile interactively. **Syntax:** `docsfy config init` | Name | Type | Default | Description | | --- | --- | --- | --- | | `Profile name` | prompt/string | `dev` | Profile key written under `servers.`. | | `Server URL` | prompt/string | Required | Base docsfy server URL. | | `Username` | prompt/string | Required | Username stored with the profile. | | `Password` | prompt/string | Required | Password or API key stored with hidden input. | ```shell $ docsfy config init Profile name [dev]: prod Server URL: https://docs.example.com Username: admin Password: Profile 'prod' saved to /home/alice/.config/docsfy/config.toml ``` **Return value/effect:** - Writes `~/.config/docsfy/config.toml`. - Creates `~/.config/docsfy` with owner-only permissions and writes the file with owner read/write only. - The first saved profile becomes `[default].server`. - Adding later profiles does not change the existing default automatically. ### `docsfy config show` Prints the current config file and all saved profiles. **Syntax:** `docsfy config show` | Name | Type | Default | Description | | --- | --- | --- | --- | | `—` | `—` | `—` | No positional arguments or command-specific options. | ```shell $ docsfy config show Config file: /home/alice/.config/docsfy/config.toml Default server: dev [dev] (default) URL: https://docs.example.com Username: admin Password: se*** ``` **Return value/effect:** - Prints the config file path, default server, and each configured profile. - Masks passwords as the first 2 characters plus `***`; passwords 2 characters or shorter print as `***`. - Exits `1` if the config file is missing. - Exits `1` if the config file exists but is invalid TOML. ### `docsfy config set` Writes a single dotted config key. **Syntax:** `docsfy config set ` | Name | Type | Default | Description | | --- | --- | --- | --- | | `key` | string | Required | Dotted config key. Must start with `default.` or `servers.`. | | `value` | string | Required | Value written to the target key. | | `default.server` | config key | `None` | Sets the default profile name. | | `servers..url` | config key | `None` | Sets a profile's server URL. | | `servers..username` | config key | `None` | Sets a profile's username. | | `servers..password` | config key | `None` | Sets a profile's password or API key. | ```shell $ docsfy config set default.server prod Updated default.server $ docsfy config set servers.prod.url https://docs.example.com Updated servers.prod.url ``` **Return value/effect:** - Writes the updated config file to disk. - Creates missing nested dictionaries along the dotted key path. - Accepts any dotted key under `default.` or `servers.` and writes it as-is. - Exits `1` if the config file is missing. - Exits `1` if `key` does not start with `default.` or `servers.`. ## Project Commands > **Note:** `status`, `abort`, `delete`, and `download` accept either a project name or a canonical generation ID (UUID). A generation ID resolves to the exact variant before the command runs. > **Warning:** `generate`, `abort`, and `delete` require write access. Keys with the `viewer` role receive `403 Write access required.` ### `docsfy health` Checks whether the configured server responds to `/health`. **Syntax:** `docsfy health` | Name | Type | Default | Description | | --- | --- | --- | --- | | `—` | `—` | `—` | No positional arguments or command-specific options. | ```shell $ docsfy health Server: https://docs.example.com Status: ok ``` **Return value/effect:** - Prints `Server: `. - Prints `Status: ` when the server returns JSON. - If the server responds with non-JSON, prints the HTTP status and the first 200 characters of the response body, then exits `1`. - If the server cannot be reached, prints `Server unreachable: ` and exits `1`. ### `docsfy generate` Starts documentation generation for a remote Git repository. **Syntax:** `docsfy generate [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `repo-url` | string | Required | Remote Git URL. Accepted forms are `https://host/org/repo(.git)` and `git@host:org/repo(.git)`. Localhost and private-network targets are rejected. | | `--branch`, `-b` | string | `main` | Branch to generate. Must match `^[a-zA-Z0-9][a-zA-Z0-9._-]*$`; `/` and `..` are rejected. | | `--provider` | string | `None` | AI provider. Accepted values are `claude`, `gemini`, and `cursor`. If omitted, the server default is used. | | `--model`, `-m` | string | `None` | AI model name. If omitted, the server default is used. | | `--force`, `-f` | boolean | `false` | Forces a full regeneration. | | `--watch`, `-w` | boolean | `false` | After submission, opens a WebSocket and streams progress until completion, failure, or abort. | ```shell $ docsfy generate https://github.com/acme/my-repo.git --branch dev --provider claude --model sonnet-4 --watch Project: my-repo Branch: dev Status: generating Generation ID: 123e4567-e89b-12d3-a456-426614174000 Watching generation progress... [generating] planning [generating] generating_pages (4 pages) Generation complete! (12 pages) ``` **Return value/effect:** - Submits the generation request and prints `Project`, `Branch`, `Status`, and `Generation ID`. - With `--watch`, the initial summary prints first, then progress messages stream until the run becomes `ready`, `error`, or `aborted`. - Typical watch messages are `Watching generation progress...`, `[] ( pages)`, `Generation complete!`, `Generation failed: ...`, and `Generation was aborted.`. - If the CLI cannot determine the final provider/model needed for `--watch`, it prints a warning after submission and leaves the generation running. - Watch failures do not cancel the generation request that was already accepted. ### `docsfy list` Lists project variants visible to the current key. **Syntax:** `docsfy list [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `--status` | string | `None` | Exact status filter. Current project statuses include `generating`, `ready`, `error`, and `aborted`. | | `--provider` | string | `None` | Exact AI provider filter. | | `--json` | boolean | `false` | Prints JSON instead of a table. | ```shell $ docsfy list --status ready NAME BRANCH PROVIDER MODEL STATUS OWNER PAGES GEN ID ------- ------ -------- ------------------ ------ ----- ----- ------------------------------------ my-repo main cursor gpt-5.4-xhigh-fast ready admin 12 123e4567-e89b-12d3-a456-426614174000 ``` **Return value/effect:** - Default output is a table with columns `NAME`, `BRANCH`, `PROVIDER`, `MODEL`, `STATUS`, `OWNER`, `PAGES`, and `GEN ID`. - `--json` prints a pretty-printed JSON array of project records. - If no projects match, prints `No projects found.` ### `docsfy status` Shows one variant or all variants for a project. **Syntax:** `docsfy status [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | Required | Project name or canonical generation ID. A generation ID resolves the exact variant and owner automatically. | | `--branch`, `-b` | string | `None` | Branch filter. When combined with `--provider` and `--model`, selects one exact variant. | | `--provider`, `-p` | string | `None` | Provider filter. When combined with `--branch` and `--model`, selects one exact variant. | | `--model`, `-m` | string | `None` | Model filter. When combined with `--branch` and `--provider`, selects one exact variant. | | `--owner` | string | `None` | Admin-only owner disambiguation for exact variant lookups. Ignored when listing all variants for a project. | | `--json` | boolean | `false` | Prints JSON instead of human-readable output. | ```shell $ docsfy status my-repo Project: my-repo Variants: 2 main/cursor/gpt-5.4-xhigh-fast ID: 123e4567-e89b-12d3-a456-426614174000 Status: ready Owner: admin Pages: 12 Updated: 2026-04-18T10:00:00 Commit: abcdef12 ``` **Return value/effect:** - With all of `--branch`, `--provider`, and `--model`, prints one exact variant. - Otherwise, prints all matching variants for the project after applying any filters. - Human-readable output shows `ID`, `Status`, `Owner`, and any available `Pages`, `Updated`, `Commit`, `Stage`, and `Error` fields. - Commit SHAs are truncated to the first 8 characters. - `--json` prints either a single variant object or `{"name": "", "variants": [...]}`. - If no variants match, prints `No variants found for ''.` ### `docsfy abort` Aborts an active generation. **Syntax:** `docsfy abort [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | Required | Project name or canonical generation ID. A generation ID resolves the exact variant and owner automatically. | | `--branch`, `-b` | string | `None` | Branch of the variant to abort. Must be used together with `--provider` and `--model`. | | `--provider`, `-p` | string | `None` | Provider of the variant to abort. Must be used together with `--branch` and `--model`. | | `--model`, `-m` | string | `None` | Model of the variant to abort. Must be used together with `--branch` and `--provider`. | | `--owner` | string | `None` | Admin-only owner disambiguation for exact variant aborts. Ignored by project-wide abort. | ```shell $ docsfy abort my-repo -b main -p cursor -m gpt-5.4-xhigh-fast Aborted generation for 'my-repo/main/cursor/gpt-5.4-xhigh-fast'. ``` **Return value/effect:** - With no variant selector, aborts one active generation by project name. - With all of `--branch`, `--provider`, and `--model`, aborts that exact variant. - If only some of the variant selectors are provided, exits `1` with an error. - Successful output is `Aborted generation for ''.` - Project-wide aborts can return HTTP `409` when multiple active variants exist for the same project name. ### `docsfy delete` Deletes one variant or all variants for a project. **Syntax:** `docsfy delete [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | Required | Project name or canonical generation ID. A generation ID resolves the exact variant and owner automatically. | | `--branch`, `-b` | string | `None` | Branch of the variant to delete. Required for exact variant deletion unless `--all` is used. | | `--provider`, `-p` | string | `None` | Provider of the variant to delete. Required for exact variant deletion unless `--all` is used. | | `--model`, `-m` | string | `None` | Model of the variant to delete. Required for exact variant deletion unless `--all` is used. | | `--owner` | string | `None` | Project owner. Required for admin deletions. | | `--all` | boolean | `false` | Deletes all variants of the project. Cannot be combined with variant selectors. | | `--yes`, `-y` | boolean | `false` | Skips the confirmation prompt. | > **Warning:** This removes the selected database record(s) and deletes the corresponding on-disk project directory, including cached pages and rendered site output. ```shell $ docsfy delete my-repo -b main -p cursor -m gpt-5.4-xhigh-fast --yes Deleted variant 'my-repo/main/cursor/gpt-5.4-xhigh-fast'. $ docsfy delete my-repo --all --yes Deleted all variants of 'my-repo'. ``` **Return value/effect:** - Without `--yes`, prompts before deleting. - If the prompt is declined, prints `Aborted.` and exits `0`. - Exact variant deletion prints `Deleted variant '///'.` - `--all` prints `Deleted all variants of ''.` - If no exact variant selector is provided and `--all` is not used, exits `1`. - If `name` is a generation ID and `--all` is used, the CLI resolves it to the project name and prints a warning before deleting all variants. ### `docsfy download` Downloads generated docs as a tarball or extracts them into a directory. **Syntax:** `docsfy download [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | Required | Project name or canonical generation ID. A generation ID resolves the exact variant and owner automatically. | | `--branch`, `-b` | string | `None` | Branch of the variant to download. Must be used together with `--provider` and `--model`. | | `--provider`, `-p` | string | `None` | Provider of the variant to download. Must be used together with `--branch` and `--model`. | | `--model`, `-m` | string | `None` | Model of the variant to download. Must be used together with `--branch` and `--provider`. | | `--owner` | string | `None` | Admin-only owner disambiguation for exact variant downloads. Ignored by project-wide default download. | | `--output`, `-o` | path/string | `None` | Output directory to extract into. If omitted, the CLI saves a `.tar.gz` archive in the current directory. | ```shell $ docsfy download my-repo -b main -p cursor -m gpt-5.4-xhigh-fast --output ./site Extracted to site $ docsfy download my-repo Downloaded to /work/my-repo-docs.tar.gz ``` **Return value/effect:** - With all of `--branch`, `--provider`, and `--model`, downloads that exact ready variant. - With no variant selector, downloads the latest accessible ready variant. - Without `--output`, saves an archive named `-docs.tar.gz` or `----docs.tar.gz` in the current directory. - With `--output`, creates the target directory if needed, extracts the archive there, and prints `Extracted to `. - If only some variant selectors are provided, exits `1`. - Variant-specific downloads return HTTP `400` if the selected variant is not `ready`. ### `docsfy models` Lists valid providers and server-known model names. **Syntax:** `docsfy models [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `--provider`, `-P` | string | `None` | Restricts output to one provider. Current providers are `claude`, `gemini`, and `cursor`. | | `--json`, `-j` | boolean | `false` | Prints JSON instead of human-readable output. | ```shell $ docsfy models Provider: claude sonnet-4 Provider: gemini (no models used yet) Provider: cursor (default) gpt-5.4-xhigh-fast (default) ``` **Return value/effect:** - Plain-text output prints one section per provider. - The default provider is marked with `(default)`. - The default model under the default provider is marked with ` (default)`. - Providers with no ready models print ` (no models used yet)`. - `--json` prints the server payload; filtered JSON still includes `default_provider` and `default_model`. - Unknown providers print `Unknown provider: ` and exit `1`. ## Admin Commands > **Warning:** All `admin` commands require an admin API key. Non-admin keys receive `403 Admin access required.` ### `docsfy admin users list` Lists all users. **Syntax:** `docsfy admin users list [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `--json` | boolean | `false` | Prints JSON instead of a table. | ```shell $ docsfy admin users list USERNAME ROLE CREATED -------- ----- ------------------- alice user 2026-04-18T09:00:00 bob admin 2026-04-18T09:30:00 ``` **Return value/effect:** - Default output is a table with columns `USERNAME`, `ROLE`, and `CREATED`. - `CREATED` is printed as the first 19 characters of the timestamp. - `--json` prints a pretty-printed JSON array of user records. - If no users exist, prints `No users found.` ### `docsfy admin users create` Creates a user and prints the API key once. **Syntax:** `docsfy admin users create [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | Required | Username to create. Must match `^[a-zA-Z0-9][a-zA-Z0-9._-]{1,49}$`. The name `admin` is reserved. | | `--role`, `-r` | string | `user` | User role. Accepted values are `admin`, `user`, and `viewer`. | | `--json` | boolean | `false` | Prints JSON instead of human-readable output. | ```shell $ docsfy admin users create alice --role viewer User created: alice Role: viewer API Key: docsfy_TfM8Qn1x... Save this API key -- it will not be shown again. ``` **Return value/effect:** - Creates the user and generates a new API key. - Auto-generated API keys start with `docsfy_`. - Default output prints `User created`, `Role`, `API Key`, and `Save this API key -- it will not be shown again.` - `--json` prints an object with `username`, `api_key`, and `role`. ### `docsfy admin users delete` Deletes a user. **Syntax:** `docsfy admin users delete [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | Required | Username to delete. | | `--yes`, `-y` | boolean | `false` | Skips the confirmation prompt. | ```shell $ docsfy admin users delete alice --yes Deleted user 'alice'. ``` **Return value/effect:** - Without `--yes`, prompts before deleting. - If the prompt is declined, prints `Aborted.` and exits `0`. - Successful output is `Deleted user ''.` - Deletion removes the user record, invalidates sessions, deletes owned projects, removes access-control entries, and removes the user's project directory if it exists. - The current admin account cannot delete itself. - Deletion is blocked while that user has an active generation. ### `docsfy admin users rotate-key` Rotates a user's API key. **Syntax:** `docsfy admin users rotate-key [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | Required | Username whose API key will be rotated. | | `--new-key` | string | `None` | Custom API key. If omitted, the server generates one. Custom keys must be at least 16 characters long. | | `--json` | boolean | `false` | Prints JSON instead of human-readable output. | ```shell $ docsfy admin users rotate-key alice User: alice New API Key: docsfy_JvQk9L2... Save this API key -- it will not be shown again. ``` **Return value/effect:** - Generates a new API key unless `--new-key` is supplied. - Invalidates all existing sessions for that user. - Default output prints `User`, `New API Key`, and `Save this API key -- it will not be shown again.` - `--json` prints an object with `username` and `new_api_key`. ### `docsfy admin access list` Lists all users who can access a project. **Syntax:** `docsfy admin access list --owner [OPTIONS]` | Name | Type | Default | Description | | --- | --- | --- | --- | | `project` | string | Required | Project name. | | `--owner` | string | Required | Project owner whose access grants will be listed. | | `--json` | boolean | `false` | Prints JSON instead of human-readable output. | ```shell $ docsfy admin access list my-repo --owner admin Project: my-repo Owner: admin Users with access: alice, bob ``` **Return value/effect:** - Default output prints `Project`, `Owner`, and either `Users with access: ...` or `No access grants.` - `--json` prints an object with `project`, `owner`, and `users`. ### `docsfy admin access grant` Grants a user access to all variants of a project owned by a specific user. **Syntax:** `docsfy admin access grant --username --owner ` | Name | Type | Default | Description | | --- | --- | --- | --- | | `project` | string | Required | Project name. | | `--username` | string | Required | Username to grant access to. | | `--owner` | string | Required | Owner of the project being shared. | ```shell $ docsfy admin access grant my-repo --username alice --owner admin Granted 'alice' access to 'my-repo' (owner: admin). ``` **Return value/effect:** - Successful output is `Granted '' access to '' (owner: ).` - The target user must exist. - The project must exist for the specified owner. - Duplicate grants are ignored by the server. ### `docsfy admin access revoke` Revokes a user's access to a project. **Syntax:** `docsfy admin access revoke --username --owner ` | Name | Type | Default | Description | | --- | --- | --- | --- | | `project` | string | Required | Project name. | | `--username` | string | Required | Username to revoke access from. | | `--owner` | string | Required | Owner of the project whose grant will be removed. | ```shell $ docsfy admin access revoke my-repo --username alice --owner admin Revoked 'alice' access to 'my-repo' (owner: admin). ``` **Return value/effect:** - Successful output is `Revoked '' access to '' (owner: ).` - Removes the matching access-control entry if it exists. ## Related Pages - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) - [Configuration Reference](configuration-reference.html) - [Configuring AI Providers and Models](configure-ai-providers-and-models.html) - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) --- Source: http-api-and-websocket-reference.md # HTTP API and WebSocket Reference > **Note:** Examples use `http://localhost:8000`. Host, port, cookie security, and default AI settings are configurable. See [Configuration Reference](configuration-reference.html) for deployment settings. ## Authentication Protected HTTP routes accept either `Authorization: Bearer ` or a valid `docsfy_session` cookie. The WebSocket endpoint accepts either the same session cookie or `?token=` in the connection URL. | Name | Type | Default | Description | | --- | --- | --- | --- | | `Authorization` | HTTP header | none | `Bearer ` or `Bearer `. Accepted on protected `/api/*` routes and `/docs/*` file routes. | | `docsfy_session` | cookie | none | Opaque session token created by `POST /api/auth/login`. Cookie attributes: `HttpOnly`, `SameSite=Strict`, `Max-Age=28800`; `Secure` follows the server `secure_cookies` setting. | | `token` | query string | none | Raw `ADMIN_KEY` or user API key for `ws://.../api/ws`. | ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/api/projects ``` ```javascript const ws = new WebSocket("ws://localhost:8000/api/ws?token="); ``` Authenticates protected HTTP requests and the WebSocket handshake. Access rules: | Role or identity | Read project data | Generate, abort, delete | Admin endpoints | Key rotation | | --- | --- | --- | --- | --- | | `admin` DB user | Yes | Yes | Yes | Yes | | Bootstrap `ADMIN_KEY` identity | Yes | Yes | Yes | No | | `user` | Yes | Yes, for owned variants only | No | Yes | | `viewer` | Yes | No | No | Yes | > **Warning:** Project and variant read routes return `404` instead of `403` when a resource exists but is not accessible to the caller. > **Warning:** Unauthenticated `/docs/*` requests with `Accept: text/html` receive `302 /login`. Other unauthenticated `/docs/*` requests receive `401 {"detail":"Unauthorized"}`. ## Common response objects ### `ProjectVariant` object Used by project listing, project lookup, generation lookup, and WebSocket `sync` payloads. | Name | Type | Description | | --- | --- | --- | | `name` | string | Project name derived from `repo_url` or the basename of `repo_path`. | | `branch` | string | Git branch for this variant. | | `ai_provider` | string | AI provider used for generation. | | `ai_model` | string | AI model used for generation. | | `owner` | string | Variant owner username. May be an empty string for legacy ownerless rows. | | `repo_url` | string | Stored source value. For local generation, this is the submitted `repo_path`. | | `status` | string | Variant status. See the status table below. | | `current_stage` | string or `null` | Current generation stage, or `null` when not set. | | `last_commit_sha` | string or `null` | Commit SHA used for the most recent successful generation. | | `last_generated` | string or `null` | Last successful generation timestamp in `YYYY-MM-DD HH:MM:SS` format. | | `page_count` | integer | Current or final page count. | | `error_message` | string or `null` | Terminal error text for `error` or `aborted` variants. | | `plan_json` | string or `null` | Stringified JSON plan. This field is not parsed for you. | | `generation_id` | string or `null` | Hyphenated UUID that identifies the variant. | | `created_at` | string | Row creation timestamp in `YYYY-MM-DD HH:MM:SS` format. | | `updated_at` | string | Last update timestamp in `YYYY-MM-DD HH:MM:SS` format. | Status values: | Value | Description | | --- | --- | | `generating` | Generation is active. | | `ready` | A rendered site is available. | | `error` | Generation failed. | | `aborted` | Generation was cancelled. | `current_stage` values: | Value | Appears in | Description | | --- | --- | --- | | `cloning` | HTTP, WebSocket `progress` | Cloning or opening the source repository. | | `incremental_planning` | HTTP, WebSocket `progress` | Selecting pages for incremental regeneration. | | `planning` | HTTP, WebSocket `progress` | Building the initial page plan. | | `generating_pages` | HTTP, WebSocket `progress` | Generating page markdown. | | `validating` | HTTP, WebSocket `progress` | Validating generated pages. | | `cross_linking` | HTTP, WebSocket `progress` | Fixing and adding internal links. | | `rendering` | HTTP, WebSocket `progress` | Rendering the final static site. | | `up_to_date` | HTTP only | The variant already matched the current commit and was marked ready without regenerating content. | | `null` | HTTP | No stage is currently set. | ```json { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "admin", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": "{\"project_name\":\"for-testing-only\",\"tagline\":\"Test repo\",\"navigation\":[]}", "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ``` Returns a complete stored variant record. See [Tracking Generation Progress](track-generation-progress.html) for the dashboard view of these states. ### `ProjectsCollection` object Used by `GET /api/projects`, `GET /api/status`, and WebSocket `sync`. | Name | Type | Description | | --- | --- | --- | | `projects` | array of `ProjectVariant` | Visible variants for the caller, including non-ready variants. | | `known_models` | object | Ready models grouped by provider. This list is global, not access-filtered. | | `known_branches` | object | Ready branches grouped by project name. Admins see all owners; non-admin callers see only their own ready branches. | ```json { "projects": [ { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "admin", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": null, "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ], "known_models": { "claude": ["opus"], "cursor": ["gpt-5.4-xhigh-fast"] }, "known_branches": { "for-testing-only": ["main", "dev"] } } ``` Returns a full snapshot for listing and refresh flows. ### Error body Most explicit HTTP errors use a `detail` field. Request validation failures use FastAPI's default `422` body, where `detail` is an array. ```json {"detail": "Unauthorized"} ``` ```json { "detail": [ { "type": "value_error", "loc": ["body", "branch"], "msg": "Value error, Invalid branch name: 'release/1.0'. Branch names cannot contain slashes — use hyphens instead (e.g., release-1.x).", "input": "release/1.0" } ] } ``` Returns machine-readable error data for non-2xx responses. ## Health and discovery ### `GET /health` Public health check. Auth: `Public` No parameters. ```bash curl http://localhost:8000/health ``` ```json {"status": "ok"} ``` Returns `200 OK` when the service is up. ### `GET /api/models` Public discovery endpoint for supported providers, server defaults, and known ready models. Auth: `Public` No parameters. Response body: | Name | Type | Description | | --- | --- | --- | | `providers` | array of strings | Supported provider IDs. The current set is `claude`, `gemini`, `cursor`. | | `default_provider` | string | Server default provider used when `POST /api/generate` omits `ai_provider`. | | `default_model` | string | Server default model used when `POST /api/generate` omits `ai_model`. | | `known_models` | object | Ready models grouped by provider. | ```bash curl http://localhost:8000/api/models ``` ```json { "providers": ["claude", "gemini", "cursor"], "default_provider": "cursor", "default_model": "gpt-5.4-xhigh-fast", "known_models": { "claude": ["opus"], "gemini": ["pro"] } } ``` Returns `200 OK`. `known_models` is derived from ready variants only. ## Authentication endpoints ### `POST /api/auth/login` Create a session cookie and return the authenticated identity. Auth: `Public` Body parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | none | Login name. Use `admin` only when authenticating with the bootstrap `ADMIN_KEY`. | | `api_key` | string | none | Bootstrap `ADMIN_KEY` or a stored user API key. | Response body: | Name | Type | Description | | --- | --- | --- | | `username` | string | Authenticated username. | | `role` | string | `admin`, `user`, or `viewer`. | | `is_admin` | boolean | `true` for the bootstrap admin identity and DB-backed admin users. | Response headers: | Name | Value | Description | | --- | --- | --- | | `Set-Cookie` | `docsfy_session=...` | Creates the `docsfy_session` cookie for browser and WebSocket session auth. | ```bash curl -i -X POST http://localhost:8000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","api_key":""}' ``` ```json { "username": "admin", "role": "admin", "is_admin": true } ``` Returns `200 OK` and sets `docsfy_session`. For DB users, `username` must match the owner of the submitted API key. Returns `400` for malformed or non-object JSON, and `401` for invalid credentials. ### `POST /api/auth/logout` Delete the current session cookie and remove its server-side session row if present. Auth: `Public` No parameters. ```bash curl -X POST \ -b "docsfy_session=" \ http://localhost:8000/api/auth/logout ``` ```json {"ok": true} ``` Returns `200 OK`. The response always clears `docsfy_session`, even when no valid session existed. ### `GET /api/auth/me` Return the current authenticated identity. Auth: `Bearer token or session cookie` No parameters. ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/api/auth/me ``` ```json { "username": "alice", "role": "viewer", "is_admin": false } ``` Returns `200 OK` with the active identity, or `401` when unauthenticated. ### `POST /api/auth/rotate-key` Rotate the current DB-backed user's API key. Auth: `Bearer token or session cookie` Body parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `new_key` | string | auto-generated | Optional replacement API key. Must be at least 16 characters when provided. | Response body: | Name | Type | Description | | --- | --- | --- | | `username` | string | Rotated username. | | `new_api_key` | string | New raw API key. | Response headers: | Name | Value | Description | | --- | --- | --- | | `Cache-Control` | `no-store` | Prevents caching of the returned secret. | | `Set-Cookie` | expired `docsfy_session` | Clears the current session cookie. | ```bash curl -X POST http://localhost:8000/api/auth/rotate-key \ -b "docsfy_session=" \ -H "Content-Type: application/json" \ -d '{"new_key":"my-very-secure-custom-password-123"}' ``` ```json { "username": "alice", "new_api_key": "my-very-secure-custom-password-123" } ``` Returns `200 OK`, invalidates all sessions for that user, and clears the caller's `docsfy_session`. Returns `400` for malformed JSON, non-object JSON, short custom keys, or when the caller is the bootstrap `ADMIN_KEY` identity. ## Project listing and lookup ### `GET /api/projects` and `GET /api/status` List visible project variants and the known ready models and branches. Auth: `Bearer token or session cookie` No parameters. ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/api/projects ``` ```json { "projects": [ { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "alice", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": null, "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ], "known_models": { "claude": ["opus"] }, "known_branches": { "for-testing-only": ["main", "dev"] } } ``` Returns a `ProjectsCollection` object. Admins see all variants. Non-admin callers see owned variants plus any variants shared with them. `GET /api/status` is a direct alias of `GET /api/projects`. ### `GET /api/projects/by-id/{generation_id}` Look up a variant by generation UUID. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `generation_id` | string | none | Hyphenated UUID from `POST /api/generate` or a stored `ProjectVariant.generation_id`. | ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/api/projects/by-id/5bf1495b-b6fa-4318-841c-dced628a2c5b ``` ```json { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "alice", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": null, "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ``` Returns a `ProjectVariant` object. Returns `400` for invalid UUID format and `404` when the generation ID does not exist or is not visible to the caller. ### `GET /api/projects/{name}` List all visible variants for one project name. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. Must start with an alphanumeric character and can contain letters, digits, `.`, `_`, and `-`. | ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/api/projects/for-testing-only ``` ```json { "name": "for-testing-only", "variants": [ { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "alice", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": null, "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ] } ``` Returns all visible variants for that project name. Admins see all owners. Non-admin callers see owned variants plus shared variants. Returns `404` when no visible variants exist. ### `GET /api/projects/{name}/{branch}/{provider}/{model}` Look up one variant by project name, branch, provider, and model. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | | `branch` | string | none | Branch name. Branches cannot contain `/` and must match `^[a-zA-Z0-9][a-zA-Z0-9._-]*$`. | | `provider` | string | none | Stored AI provider ID. | | `model` | string | none | Stored AI model ID. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Admin-only owner disambiguation. Ignored for non-admin callers. | ```bash curl -H "Authorization: Bearer " \ "http://localhost:8000/api/projects/for-testing-only/main/claude/opus?owner=alice" ``` ```json { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "alice", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": null, "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ``` Returns a `ProjectVariant` object. Returns `404` when the variant does not exist or is not visible, and `409` when an admin lookup is ambiguous across multiple owners. ## Generation and control ### `POST /api/generate` Start documentation generation for a remote Git repository or an admin-supplied local Git path. Auth: `admin` or `user` Body parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `repo_url` | string | none | Remote Git URL. Accepted forms are `http://host/org/repo`, `https://host/org/repo`, and `git@host:org/repo`, with optional `.git`. Exactly one of `repo_url` or `repo_path` is required. | | `repo_path` | string | none | Absolute local Git repository path. Admin only. Exactly one of `repo_url` or `repo_path` is required. | | `ai_provider` | string | server default | AI provider. Valid values: `claude`, `gemini`, `cursor`. | | `ai_model` | string | server default | AI model name. | | `ai_cli_timeout` | integer | server default | Per-call AI CLI timeout, in seconds. Must be greater than `0`. | | `force` | boolean | `false` | Force full regeneration instead of reusing cached content. | | `branch` | string | `main` | Branch to generate. Slashes are rejected. | > **Note:** The request body does not include a `project_name` field. docsfy derives the project name from `repo_url` or the basename of `repo_path`. > **Warning:** `repo_url` targets that point to localhost or private network addresses are rejected. > **Warning:** `repo_path` must exist, be absolute, and contain a `.git` directory. Common rejection cases: | Condition | Status | Result | | --- | --- | --- | | Neither `repo_url` nor `repo_path` provided | `422` | FastAPI validation error | | Both `repo_url` and `repo_path` provided | `422` | FastAPI validation error | | Invalid `repo_url`, non-absolute `repo_path`, or invalid `branch` | `422` | FastAPI validation error | | `repo_path` used by non-admin caller | `403` | Rejected before local path lookup | | `repo_path` does not exist or is not a Git repo | `400` | Request rejected | | Invalid `ai_provider` | `400` | Request rejected | | Same owner/name/branch/provider/model already generating | `409` | Duplicate active generation | Response body: | Name | Type | Description | | --- | --- | --- | | `project` | string | Derived project name. | | `status` | string | Always `generating` on acceptance. | | `branch` | string | Resolved branch for the new run. | | `generation_id` | string | Hyphenated UUID for the variant. | ```bash curl -X POST http://localhost:8000/api/generate \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "repo_url": "https://github.com/myk-org/for-testing-only", "ai_provider": "claude", "ai_model": "opus", "branch": "main", "force": false }' ``` ```json { "project": "for-testing-only", "status": "generating", "branch": "main", "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b" } ``` Returns `202 Accepted`. The server creates or updates the variant row immediately, then sends WebSocket `progress`, `status_change`, and `sync` messages to admins, the project owner, and users with access to that project/owner pair. ### `POST /api/projects/{name}/abort` Abort the only active generation matching a project name. Auth: `admin` or `user` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | No query or body parameters. > **Warning:** This route is not deterministic when more than one active variant exists for the same project name. Use the variant-scoped abort route for automation. ```bash curl -X POST \ -H "Authorization: Bearer " \ http://localhost:8000/api/projects/for-testing-only/abort ``` ```json {"aborted": "for-testing-only"} ``` Returns `200 OK` when one matching active generation is cancelled. Non-admin callers can abort only their own active runs. Returns `404` when no active generation exists and `409` when more than one active variant exists or cancellation has not completed yet. ### `POST /api/projects/{name}/{branch}/{provider}/{model}/abort` Abort one active variant. Auth: `admin` or `user` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | | `branch` | string | none | Branch name. | | `provider` | string | none | AI provider. | | `model` | string | none | AI model. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Admin-only owner disambiguation when the active variant belongs to another owner or multiple owners have the same active variant. Ignored for non-admin callers. | ```bash curl -X POST \ -H "Authorization: Bearer " \ "http://localhost:8000/api/projects/for-testing-only/main/claude/opus/abort?owner=alice" ``` ```json {"aborted": "for-testing-only/main/claude/opus"} ``` Returns `200 OK` when the matching task is cancelled. Returns `404` when no active generation matches, and `409` when the lookup is ambiguous or cancellation is still in progress. Successful aborts produce a terminal `status_change` and a follow-up `sync`. ## Deletion ### `DELETE /api/projects/{name}` Delete all variants for one project name. Auth: `admin` or `user` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Required for admin callers. Ignored for non-admin callers, who can delete only their own variants. Use an empty value (`?owner=`) to target a legacy ownerless row. | ```bash curl -X DELETE \ -H "Authorization: Bearer " \ "http://localhost:8000/api/projects/for-testing-only?owner=alice" ``` ```json {"deleted": "for-testing-only"} ``` Returns `200 OK` after deleting all variants for the target owner and project name. Returns `404` when nothing matches and `409` when any matching variant is still generating. A successful delete sends a WebSocket `sync`. ### `DELETE /api/projects/{name}/{branch}/{provider}/{model}` Delete one variant. Auth: `admin` or `user` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | | `branch` | string | none | Branch name. | | `provider` | string | none | AI provider. | | `model` | string | none | AI model. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Required for admin callers. Ignored for non-admin callers, who can delete only their own variants. Use an empty value (`?owner=`) to target a legacy ownerless row. | ```bash curl -X DELETE \ -H "Authorization: Bearer " \ "http://localhost:8000/api/projects/for-testing-only/main/claude/opus?owner=alice" ``` ```json {"deleted": "for-testing-only/main/claude/opus"} ``` Returns `200 OK` after deleting the matching variant. Returns `404` when the variant does not exist and `409` when the variant is still generating. A successful delete sends a WebSocket `sync`. ## Downloads and generated files ### `GET /api/projects/{name}/download` Download a tarball for the newest accessible ready variant of a project. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | No query parameters. > **Warning:** This route resolves the newest accessible ready variant. For deterministic automation, use the variant-scoped download route. Response headers: | Name | Value | Description | | --- | --- | --- | | `Content-Type` | `application/gzip` | Gzip-compressed tar archive. | | `Content-Disposition` | `attachment; filename="-docs.tar.gz"` | Suggested download filename. | ```bash curl -OJ \ -H "Authorization: Bearer " \ http://localhost:8000/api/projects/for-testing-only/download ``` Returns the generated site as a tarball. Returns `404` when no accessible ready variant exists or the site directory is missing, and may return `409` when the newest accessible variant is ambiguous across owners. ### `GET /api/projects/{name}/{branch}/{provider}/{model}/download` Download a tarball for one variant. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | | `branch` | string | none | Branch name. | | `provider` | string | none | AI provider. | | `model` | string | none | AI model. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Admin-only owner disambiguation when more than one owner has the same variant. Ignored for non-admin callers. | Response headers: | Name | Value | Description | | --- | --- | --- | | `Content-Type` | `application/gzip` | Gzip-compressed tar archive. | | `Content-Disposition` | `attachment; filename="----docs.tar.gz"` | Suggested download filename. | ```bash curl -OJ \ -H "Authorization: Bearer " \ "http://localhost:8000/api/projects/for-testing-only/main/claude/opus/download?owner=alice" ``` Returns the generated site for that variant. Returns `400` when the variant exists but is not `ready`, `404` when the variant or site is missing, and `409` when an admin lookup is ambiguous across owners. ### `GET /docs/{project}/{path:path}` Serve a file from the newest accessible ready variant. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `project` | string | none | Project name. | | `path` | string | `index.html` when the resolved path is empty | File path inside the generated site, such as `index.html`, `search-index.json`, or `assets/style.css`. | No query parameters. > **Warning:** This route resolves the newest accessible ready variant. For deterministic automation, use the variant-scoped docs route. ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/docs/for-testing-only/search-index.json ``` Returns raw file bytes from the generated site. Returns `404` when no accessible docs are available or the file does not exist, `403` when the resolved file path escapes the generated site directory, and may return `409` when the newest accessible variant is ambiguous across owners. ### `GET /docs/{project}/{branch}/{provider}/{model}/{path:path}` Serve a file from one variant. Auth: `Bearer token or session cookie` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `project` | string | none | Project name. | | `branch` | string | none | Branch name. | | `provider` | string | none | AI provider. | | `model` | string | none | AI model. | | `path` | string | `index.html` when the resolved path is empty | File path inside the generated site. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Admin-only owner disambiguation when more than one owner has the same variant. Ignored for non-admin callers. | ```bash curl -H "Authorization: Bearer " \ "http://localhost:8000/docs/for-testing-only/main/claude/opus/index.html?owner=alice" ``` Returns raw file bytes from the requested variant. Returns `404` when the variant or file does not exist, `403` when the resolved file path escapes the site directory, and `409` when an admin lookup is ambiguous across owners. ## Admin endpoints ### `GET /api/admin/users` List all users. Auth: `admin` No parameters. Response body: | Name | Type | Description | | --- | --- | --- | | `users` | array | User rows without API key hashes. Each row contains `id`, `username`, `role`, and `created_at`. | ```bash curl -H "Authorization: Bearer " \ http://localhost:8000/api/admin/users ``` ```json { "users": [ { "id": 1, "username": "alice", "role": "user", "created_at": "2026-04-18 12:00:00" } ] } ``` Returns `200 OK`. Non-admin callers receive `403`. ### `POST /api/admin/users` Create a new user and return its raw API key. Auth: `admin` Body parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | none | Username. Must be 2-50 characters, start with an alphanumeric character, and use only letters, digits, `.`, `_`, and `-`. `admin` is reserved. | | `role` | string | `user` | User role. Valid values: `admin`, `user`, `viewer`. | Response body: | Name | Type | Description | | --- | --- | --- | | `username` | string | Created username. | | `api_key` | string | New raw API key. | | `role` | string | Assigned role. | Response headers: | Name | Value | Description | | --- | --- | --- | | `Cache-Control` | `no-store` | Prevents caching of the returned secret. | ```bash curl -X POST http://localhost:8000/api/admin/users \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"username":"alice","role":"viewer"}' ``` ```json { "username": "alice", "api_key": "docsfy_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "role": "viewer" } ``` Returns `200 OK`. Returns `400` for invalid usernames, reserved `admin`, duplicate users, invalid roles, or malformed JSON. ### `DELETE /api/admin/users/{username}` Delete a user. Auth: `admin` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | none | Existing username to delete. | ```bash curl -X DELETE \ -H "Authorization: Bearer " \ http://localhost:8000/api/admin/users/alice ``` ```json {"deleted": "alice"} ``` Returns `200 OK` after deleting the user, all of their sessions, any owned projects, access grants they received, access grants to their projects, and their project directory. Returns `400` when an admin tries to delete their own account, `404` when the user does not exist, and `409` when that user has an active generation. ### `POST /api/admin/users/{username}/rotate-key` Rotate another user's API key. Auth: `admin` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | none | Existing username to rotate. | Body parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `new_key` | string | auto-generated | Optional replacement API key. Must be at least 16 characters when provided. | Response body: | Name | Type | Description | | --- | --- | --- | | `username` | string | Rotated username. | | `new_api_key` | string | New raw API key. | Response headers: | Name | Value | Description | | --- | --- | --- | | `Cache-Control` | `no-store` | Prevents caching of the returned secret. | ```bash curl -X POST http://localhost:8000/api/admin/users/alice/rotate-key \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"new_key":"admin-chosen-password-long"}' ``` ```json { "username": "alice", "new_api_key": "admin-chosen-password-long" } ``` Returns `200 OK` and invalidates all sessions for the target user. Returns `400` for invalid custom keys or malformed JSON and `404` when the user does not exist. ### `GET /api/admin/projects/{name}/access` List users who have access to a project/owner pair. Auth: `admin` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Required project owner. Access grants are scoped by owner, not just by project name. | ```bash curl -H "Authorization: Bearer " \ "http://localhost:8000/api/admin/projects/for-testing-only/access?owner=alice" ``` ```json { "project": "for-testing-only", "owner": "alice", "users": ["bob", "carol"] } ``` Returns `200 OK` with usernames sorted alphabetically. Returns `400` when `owner` is missing and `403` for non-admin callers. ### `POST /api/admin/projects/{name}/access` Grant a user read access to all variants of a project owned by one owner. Auth: `admin` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | Body parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `username` | string | none | Target username that will receive access. | | `owner` | string | none | Required project owner. The grant applies to this `name` and this owner only. | ```bash curl -X POST http://localhost:8000/api/admin/projects/for-testing-only/access \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"username":"bob","owner":"alice"}' ``` ```json { "granted": "for-testing-only", "username": "bob", "owner": "alice" } ``` Returns `200 OK`. Returns `400` for malformed JSON or missing fields, `404` when the target user does not exist or the project/owner pair does not exist, and sends a WebSocket `sync` to the target user's active connections. ### `DELETE /api/admin/projects/{name}/access/{username}` Revoke a user access grant for one project/owner pair. Auth: `admin` Path parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | none | Project name. | | `username` | string | none | Username to revoke. | Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `owner` | string | none | Required project owner. | ```bash curl -X DELETE \ -H "Authorization: Bearer " \ "http://localhost:8000/api/admin/projects/for-testing-only/access/bob?owner=alice" ``` ```json { "revoked": "for-testing-only", "username": "bob", "owner": "alice" } ``` Returns `200 OK` and sends a WebSocket `sync` to the target user's active connections. Returns `400` when `owner` is missing and `403` for non-admin callers. This route is idempotent: it does not error when the grant is already absent. ## WebSocket ### WebSocket `/api/ws` Real-time stream of project snapshots and generation updates. Auth: `docsfy_session` cookie or `?token=` Query parameters: | Name | Type | Default | Description | | --- | --- | --- | --- | | `token` | string | none | Optional raw `ADMIN_KEY` or user API key. Use this for non-browser clients that cannot send the session cookie. | Connection behavior: | Item | Value | | --- | --- | | Initial server message | `sync` | | Server heartbeat | `{"type":"ping"}` every 30 seconds | | Required client response | `{"type":"pong"}` | | Pong timeout | 10 seconds | | Max missed pongs | 2 | | Unauthenticated close code | `1008` | | Missed-pong close code | `1001` | | Broadcast recipients | Admins, the project owner, and users granted access to that project/owner pair | ```javascript const ws = new WebSocket("ws://localhost:8000/api/ws?token="); ws.onmessage = (event) => { const message = JSON.parse(event.data); if (message.type === "ping") { ws.send(JSON.stringify({ type: "pong" })); return; } console.log(message); }; ``` Opens a live subscription. The server sends a full `sync` immediately after connect, then incremental messages as projects change. ### `sync` message Full snapshot message. Fields: | Name | Type | Description | | --- | --- | --- | | `type` | string | Always `sync`. | | `projects` | array of `ProjectVariant` | Full visible project snapshot. | | `known_models` | object | Same structure as `GET /api/projects`. | | `known_branches` | object | Same structure as `GET /api/projects`. | ```json { "type": "sync", "projects": [ { "name": "for-testing-only", "branch": "main", "ai_provider": "claude", "ai_model": "opus", "owner": "alice", "repo_url": "https://github.com/myk-org/for-testing-only", "status": "ready", "current_stage": null, "last_commit_sha": "abc123def456", "last_generated": "2026-04-18 12:34:56", "page_count": 12, "error_message": null, "plan_json": null, "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b", "created_at": "2026-04-18 12:00:00", "updated_at": "2026-04-18 12:34:56" } ], "known_models": { "claude": ["opus"] }, "known_branches": { "for-testing-only": ["main", "dev"] } } ``` Sent immediately after connect and again after access changes, deletions, and terminal generation refreshes. ### `progress` message Incremental update for an in-progress generation. Fields: | Name | Type | Description | | --- | --- | --- | | `type` | string | Always `progress`. | | `name` | string | Project name. | | `branch` | string | Branch name. | | `provider` | string | AI provider. | | `model` | string | AI model. | | `owner` | string | Variant owner. | | `status` | string | Current in-progress status. The current implementation sends `generating`. | | `current_stage` | string, optional | Current stage, such as `cloning`, `planning`, or `generating_pages`. | | `page_count` | integer, optional | Current generated page count. | | `plan_json` | string, optional | Stringified plan JSON once planning is available. | | `error_message` | string, optional | Error text when present during an in-progress update. | | `generation_id` | string, optional | Variant UUID. | ```json { "type": "progress", "name": "for-testing-only", "branch": "main", "provider": "claude", "model": "opus", "owner": "alice", "status": "generating", "current_stage": "generating_pages", "page_count": 4, "plan_json": "{\"project_name\":\"for-testing-only\",\"tagline\":\"Test repo\",\"navigation\":[]}", "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b" } ``` Sent during non-terminal stages. Clients should merge this message by the tuple `(name, branch, provider, model, owner)`. ### `status_change` message Terminal update for a variant. Fields: | Name | Type | Description | | --- | --- | --- | | `type` | string | Always `status_change`. | | `name` | string | Project name. | | `branch` | string | Branch name. | | `provider` | string | AI provider. | | `model` | string | AI model. | | `owner` | string | Variant owner. | | `status` | string | Terminal status: `ready`, `error`, or `aborted`. | | `page_count` | integer, optional | Final page count when available. | | `last_generated` | string, optional | Completion timestamp when `status` is `ready`. | | `last_commit_sha` | string, optional | Final commit SHA when available. | | `error_message` | string, optional | Error or abort text when available. | | `generation_id` | string, optional | Variant UUID. | ```json { "type": "status_change", "name": "for-testing-only", "branch": "main", "provider": "claude", "model": "opus", "owner": "alice", "status": "ready", "page_count": 12, "last_generated": "2026-04-18 12:34:56", "last_commit_sha": "abc123def456", "generation_id": "5bf1495b-b6fa-4318-841c-dced628a2c5b" } ``` Sent when a variant reaches a terminal state. A full `sync` may follow. ### `ping` message Server heartbeat message. Fields: | Name | Type | Description | | --- | --- | --- | | `type` | string | Always `ping`. | ```json {"type": "ping"} ``` Sent every 30 seconds per open connection. Clients should respond with `pong`. ### `pong` message Client heartbeat response. Fields: | Name | Type | Description | | --- | --- | --- | | `type` | string | Always `pong`. | ```json {"type": "pong"} ``` Acknowledges the most recent server `ping`. If the server misses 2 consecutive pongs, it closes the connection with code `1001`. ## Related Pages - [Configuration Reference](configuration-reference.html) - [Generating Documentation](generate-documentation.html) - [Tracking Generation Progress](track-generation-progress.html) - [Viewing and Downloading Docs](view-and-download-docs.html) - [Managing Users and Access](manage-users-and-access.html) --- Source: configuration-reference.md # Configuration Reference Server runtime settings are loaded from environment variables. CLI profiles are stored in `~/.config/docsfy/config.toml`. ## Admin and Server Settings ### Server environment variables Settings loaded during application startup and request handling. | Name | Type | Default | Description | | --- | --- | --- | --- | | `ADMIN_KEY` | string | `""` | Required built-in admin secret. The built-in admin username is `admin`. Startup fails if this value is empty or shorter than 16 characters. | | `AI_PROVIDER` | string | `cursor` | Default provider used when a generation request omits `ai_provider`. Accepted values: `claude`, `gemini`, `cursor`. | | `AI_MODEL` | string | `gpt-5.4-xhigh-fast` | Default model used when a generation request omits `ai_model`. | | `AI_CLI_TIMEOUT` | integer | `60` | Positive timeout value passed to AI CLI calls when a generation request omits `ai_cli_timeout`. | | `MAX_CONCURRENT_PAGES` | integer | `10` | Maximum parallel AI CLI calls during page generation and validation. Must be greater than `0`. | | `DATA_DIR` | path | `/data` | Base directory for `docsfy.db` and generated project artifacts. | | `SECURE_COOKIES` | boolean | `true` | Controls the `Secure` flag on the `docsfy_session` cookie. | ```dotenv ADMIN_KEY= AI_PROVIDER=cursor AI_MODEL=gpt-5.4-xhigh-fast AI_CLI_TIMEOUT=60 MAX_CONCURRENT_PAGES=10 DATA_DIR=/data SECURE_COOKIES=true ``` Effect: `ADMIN_KEY` enables built-in admin access and is also used as the HMAC secret for stored user API keys. `AI_PROVIDER`, `AI_MODEL`, and `AI_CLI_TIMEOUT` apply when a generation request omits those fields. `DATA_DIR` changes the runtime storage root. `SECURE_COOKIES` changes whether browser sessions require HTTPS. > **Warning:** Changing `ADMIN_KEY` invalidates existing stored user API keys. > **Note:** On plain `http://localhost`, browser sessions do not persist unless `SECURE_COOKIES=false`. ### `docsfy-server` Direct launcher environment read by `docsfy.main.run()`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `HOST` | string | `127.0.0.1` | Bind host used by `docsfy-server`. | | `PORT` | integer | `8000` | Bind port used by `docsfy-server`. | | `DEBUG` | string | unset | When set to `true`, starts uvicorn with reload enabled. | ```bash HOST=0.0.0.0 PORT=9000 DEBUG=true docsfy-server ``` Effect: Starts the server on the requested interface and port. `DEBUG=true` enables backend autoreload. > **Note:** The checked-in container entrypoint does not use `HOST`, `PORT`, or `DEBUG`; it always starts uvicorn on `0.0.0.0:8000`. ## Sessions and Storage ### `docsfy_session` Browser session cookie used for authenticated UI and WebSocket traffic. | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | `docsfy_session` | Cookie name. | | `value` | string | generated | Opaque session token. The raw API key is not stored in the cookie. | | `HttpOnly` | boolean | `true` | Browser JavaScript cannot read the cookie. | | `SameSite` | string | `strict` | Same-site policy. | | `Secure` | boolean | `true` | Controlled by `SECURE_COOKIES`. | | `Max-Age` | integer | `28800` | Session lifetime in seconds. | | `server storage` | string | SHA-256 hash | The `sessions` table stores a SHA-256 hash of the token, not the raw token. | ```http Set-Cookie: docsfy_session=; HttpOnly; SameSite=strict; Max-Age=28800; Secure ``` Effect: Authenticates browser requests until logout, expiry, or API key rotation. Logout and user key rotation delete the current session. ### Runtime storage layout Files and directories rooted under `DATA_DIR`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `DATA_DIR/docsfy.db` | file | `/data/docsfy.db` | SQLite database containing projects, users, access grants, and sessions. | | `DATA_DIR/projects/` | directory | `/data/projects/` | Root directory for generated variants. | | `DATA_DIR/projects//////` | directory | derived | Per-variant working directory. Empty owners are stored as `_default`. | | `.../plan.json` | file | derived | Saved documentation plan for the variant. | | `.../site/` | directory | derived | Rendered static site served under `/docs/...`. | | `.../cache/pages/` | directory | derived | Cached page markdown used for regeneration. | ```text /data/docsfy.db /data/projects/alice/my-repo/main/claude/opus/plan.json /data/projects/alice/my-repo/main/claude/opus/site/index.html /data/projects/alice/my-repo/main/claude/opus/cache/pages/introduction.md ``` Effect: `init_db()` creates `docsfy.db` and `projects/` if they do not exist. Generated docs, cached pages, and saved plans are read from and written to this tree. > **Note:** Branch, provider, and model values become path segments. Path traversal values such as `/`, `\`, `..`, or leading `.` are rejected. ## Ports and Containers ### Default ports Network ports used by the checked-in launchers and development tools. | Name | Type | Default | Description | | --- | --- | --- | --- | | `8000` | TCP port | `8000` | Application server, REST API, docs serving, and `/health`. | | `5173` | TCP port | `5173` | Vite development server used by `npm run dev` and container `DEV_MODE=true`. | ```text http://localhost:8000/ http://localhost:5173/ ``` Effect: `8000` is the application port in direct runs and container runs. `5173` is only used for frontend development. > **Note:** The container image exposes both `8000` and `5173` and uses `curl -f http://localhost:8000/health` as its health check. ### `docker-compose.yaml` Checked-in Compose service definition for containerized runs. | Name | Type | Default | Description | | --- | --- | --- | --- | | `services.docsfy.build.context` | path | `.` | Build context used for the image. | | `services.docsfy.build.dockerfile` | path | `Dockerfile` | Dockerfile used for the build. | | `services.docsfy.ports[0]` | string | `"8000:8000"` | Maps the backend port to the host. | | `services.docsfy.ports[1]` | string | commented | Optional `"5173:5173"` mapping for Vite development mode. | | `services.docsfy.volumes[0]` | string | `"./data:/data"` | Persists database and generated docs on the host. | | `services.docsfy.volumes[1]` | string | commented | Optional `"./frontend:/app/frontend"` bind mount for live frontend development. | | `services.docsfy.env_file` | path | `.env` | Loads environment variables into the container. | | `services.docsfy.environment.ADMIN_KEY` | string | `${ADMIN_KEY}` | Passes the admin secret into the container environment. | | `services.docsfy.environment.DEV_MODE` | string | commented | Optional development mode toggle. | | `services.docsfy.restart` | string | `unless-stopped` | Container restart policy. | ```yaml services: docsfy: build: context: . dockerfile: Dockerfile ports: - "8000:8000" # - "5173:5173" volumes: - ./data:/data # - ./frontend:/app/frontend env_file: - .env environment: - ADMIN_KEY=${ADMIN_KEY} # - DEV_MODE=true restart: unless-stopped ``` Effect: Builds the local image and runs the server with persistent storage at `./data`. Uncommenting the development lines enables frontend hot-reload access from the host. > **Warning:** `ADMIN_KEY` must resolve to a non-empty value of at least 16 characters or the application exits during startup. > **Note:** If you change `DATA_DIR`, update the container-side volume target so it matches the new storage root. ## CLI Profiles ### `~/.config/docsfy/config.toml` Local CLI profile file used by `docsfy`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `path` | path | `~/.config/docsfy/config.toml` | CLI profile file. | | `directory mode` | file mode | `0700` | Permission mode applied to `~/.config/docsfy/` when the CLI writes it. | | `file mode` | file mode | `0600` | Permission mode applied to `config.toml` when the CLI writes it. | | `[default].server` | string | unset | Default profile name used when `--server` is omitted. | | `[servers.].url` | string | unset | Base URL for the named server profile. | | `[servers.].username` | string | unset | Username stored with the profile. | | `[servers.].password` | string | unset | API key stored with the profile and used as the CLI Bearer token. | ```toml [default] server = "dev" [servers.dev] url = "http://localhost:8000" username = "admin" password = "" ``` Effect: The CLI resolves connection details from this file before running commands. The stored `password` value is sent as the Bearer token for API requests. > **Warning:** `password` is stored verbatim in `config.toml`. > **Note:** `username` is stored with the profile, but CLI authentication uses the password/API key as the Bearer token. ### `docsfy config init` Interactive profile creation. | Name | Type | Default | Description | | --- | --- | --- | --- | | `Profile name` | prompt | `dev` | Profile name written under `[servers.]`. | | `Server URL` | prompt | none | Base URL for the target server. | | `Username` | prompt | none | Username stored with the profile. | | `Password` | prompt | none | API key stored with the profile. Input is hidden. | ```text $ docsfy config init Profile name [dev]: dev Server URL: http://localhost:8000 Username: admin Password: Profile 'dev' saved to ~/.config/docsfy/config.toml ``` Effect: Creates or updates the named profile. If `[default].server` is not already set, it is set to the new profile name. If a default already exists, `init` adds the new profile without changing the current default. ### `docsfy config show` Profile inspection command. | Name | Type | Default | Description | | --- | --- | --- | --- | | `command-specific options` | none | none | This command has no command-specific flags. | ```bash docsfy config show ``` Effect: Prints the config file path, default profile, saved profiles, and masked passwords. Passwords are displayed as `***` or the first two characters followed by `***`. ### `docsfy config set` Nested value update command. | Name | Type | Default | Description | | --- | --- | --- | --- | | `key` | string | none | Nested key to update. Must start with `default.` or `servers.`. | | `value` | string | none | Value written to the target key. | ```bash docsfy config set default.server prod docsfy config set servers.prod.url https://docsfy.example.com docsfy config set servers.prod.password ``` Effect: Updates `config.toml` in place. Missing nested tables are created automatically. > **Tip:** CLI connection resolution only reads `[default].server`, `servers..url`, `servers..username`, and `servers..password`. ### `docsfy` global connection options Global options accepted before any CLI command. | Name | Type | Default | Description | | --- | --- | --- | --- | | `--server`, `-s` | string | unset | Selects a named profile from `[servers]`. | | `--host` | string | unset | Overrides the resolved host. If the selected profile URL starts with `http://`, the CLI keeps `http`; otherwise it uses `https`. | | `--port` | integer | `8000` when `--host` is used | Port used with `--host`. | | `--username`, `-u` | string | profile value | Overrides the resolved username. | | `--password`, `-p` | string | profile value | Overrides the resolved API key. | ```bash docsfy --server prod health docsfy --host myhost --port 9000 -u admin -p health ``` Effect: Resolution order is explicit CLI flags, then the `--server` profile, then `[default].server`. If no connection can be resolved, or the named profile does not exist, the CLI exits with an error. ## Local Development ### Frontend development proxy Vite development server settings from `frontend/vite.config.ts`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `API_TARGET` | URL | `http://localhost:8000` | Backend target for Vite proxying. | | `server.host` | string | `0.0.0.0` | Vite bind host. | | `server.port` | integer | `5173` | Vite bind port. | | `proxy./api` | route | enabled | Proxies API requests to `API_TARGET`. WebSocket proxying is enabled. | | `proxy./docs` | route | enabled | Proxies docs asset requests to `API_TARGET`. | | `proxy./health` | route | enabled | Proxies health checks to `API_TARGET`. | ```bash cd frontend API_TARGET=http://localhost:8000 npm run dev ``` Effect: Starts Vite on `5173` and forwards API, docs, health, and WebSocket traffic to the backend target. ### Container `DEV_MODE` Development mode handled by `entrypoint.sh`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `DEV_MODE` | string | unset | When `true`, the entrypoint runs `npm ci`, starts Vite in the background, and starts uvicorn with `--reload --reload-dir /app/src`. | | `backend bind` | host:port | `0.0.0.0:8000` | Fixed backend bind used by the container entrypoint. | | `frontend bind` | port | `5173` | Vite port used in development mode. | | `frontend mount` | path | commented in Compose | Optional `./frontend:/app/frontend` bind mount for live frontend changes. | ```yaml services: docsfy: ports: - "8000:8000" - "5173:5173" volumes: - ./data:/data - ./frontend:/app/frontend environment: - DEV_MODE=true ``` Effect: Starts the backend and Vite together inside the container. Backend code reloads from `/app/src`. Frontend live changes require the frontend bind mount. > **Note:** When `DEV_MODE` is not `true`, the container serves the prebuilt frontend from `frontend/dist`. > **Note:** If `frontend/dist/index.html` is missing and Vite is not running, non-API routes return `404` with `Frontend not built. Run: cd frontend && npm run build`. ## Related Pages - See [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) for details. - See [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) for details. - See [CLI Command Reference](cli-command-reference.html) for details. - See [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) for details. ## Related Pages - [Install and Run docsfy Without Docker](install-and-run-docsfy-without-docker.html) - [Managing docsfy from the CLI](manage-docsfy-from-the-cli.html) - [CLI Command Reference](cli-command-reference.html) - [Configuring AI Providers and Models](configure-ai-providers-and-models.html) - [Fixing Setup and Generation Problems](fix-setup-and-generation-problems.html) ---