From 4a03cbab3d9d84e58e9c6478f35cbbb57f5dd95d Mon Sep 17 00:00:00 2001 From: Ammar Date: Sat, 6 Dec 2025 15:17:59 -0600 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=A4=96=20docs:=20sync=20generated=20s?= =?UTF-8?q?nippets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/{AGENTS.md => AGENTS.mdx} | 6 +- docs/{README.md => README.mdx} | 6 +- docs/{STYLE.md => STYLE.mdx} | 0 ...t-identity.md => agentic-git-identity.mdx} | 14 +- docs/{benchmarking.md => benchmarking.mdx} | 0 docs/{cli.md => cli.mdx} | 0 ...t-management.md => context-management.mdx} | 4 +- docs/{fork.md => fork.mdx} | 0 docs/{index.md => index.mdx} | 0 docs/{init-hooks.md => init-hooks.mdx} | 0 docs/{install.md => install.mdx} | 15 +- ...ruction-files.md => instruction-files.mdx} | 0 docs/{keybinds.md => keybinds.mdx} | 5 +- docs/{models.md => models.mdx} | 22 +++ docs/{mux-codes.md => mux-codes.mdx} | 0 ...project-secrets.md => project-secrets.mdx} | 0 .../{prompting-tips.md => prompting-tips.mdx} | 0 docs/{runtime.md => runtime.mdx} | 0 docs/runtime/{local.md => local.mdx} | 12 +- docs/runtime/{ssh.md => ssh.mdx} | 4 +- docs/runtime/{worktree.md => worktree.mdx} | 0 docs/{storybook.md => storybook.mdx} | 0 docs/{system-prompt.md => system-prompt.mdx} | 1 - docs/{telemetry.md => telemetry.mdx} | 0 docs/{vim-mode.md => vim-mode.mdx} | 0 ...code-extension.md => vscode-extension.mdx} | 0 ...why-parallelize.md => why-parallelize.mdx} | 0 docs/{workspaces.md => workspaces.mdx} | 0 fmt.mk | 6 +- scripts/gen_docs.ts | 153 ++++++++++++++++++ scripts/sync_system_prompt_docs.sh | 59 ------- 31 files changed, 228 insertions(+), 79 deletions(-) rename docs/{AGENTS.md => AGENTS.mdx} (97%) rename docs/{README.md => README.mdx} (87%) rename docs/{STYLE.md => STYLE.mdx} (100%) rename docs/{agentic-git-identity.md => agentic-git-identity.mdx} (87%) rename docs/{benchmarking.md => benchmarking.mdx} (100%) rename docs/{cli.md => cli.mdx} (100%) rename docs/{context-management.md => context-management.mdx} (97%) rename docs/{fork.md => fork.mdx} (100%) rename docs/{index.md => index.mdx} (100%) rename docs/{init-hooks.md => init-hooks.mdx} (100%) rename docs/{install.md => install.mdx} (79%) rename docs/{instruction-files.md => instruction-files.mdx} (100%) rename docs/{keybinds.md => keybinds.mdx} (95%) rename docs/{models.md => models.mdx} (84%) rename docs/{mux-codes.md => mux-codes.mdx} (100%) rename docs/{project-secrets.md => project-secrets.mdx} (100%) rename docs/{prompting-tips.md => prompting-tips.mdx} (100%) rename docs/{runtime.md => runtime.mdx} (100%) rename docs/runtime/{local.md => local.mdx} (62%) rename docs/runtime/{ssh.md => ssh.mdx} (95%) rename docs/runtime/{worktree.md => worktree.mdx} (100%) rename docs/{storybook.md => storybook.mdx} (100%) rename docs/{system-prompt.md => system-prompt.mdx} (99%) rename docs/{telemetry.md => telemetry.mdx} (100%) rename docs/{vim-mode.md => vim-mode.mdx} (100%) rename docs/{vscode-extension.md => vscode-extension.mdx} (100%) rename docs/{why-parallelize.md => why-parallelize.mdx} (100%) rename docs/{workspaces.md => workspaces.mdx} (100%) create mode 100644 scripts/gen_docs.ts delete mode 100755 scripts/sync_system_prompt_docs.sh diff --git a/docs/AGENTS.md b/docs/AGENTS.mdx similarity index 97% rename from docs/AGENTS.md rename to docs/AGENTS.mdx index 9abdccd372..711becab2f 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.mdx @@ -36,7 +36,7 @@ gh pr view --json mergeable,mergeStateStatus | jq '.' ## Documentation Rules -- No free-floating Markdown. User docs live in `docs/` (read `docs/README.md`, add pages to `docs.json` navigation, use standard Markdown + mermaid). Developer/test notes belong inline as comments. +- No free-floating Markdown. User docs live in `docs/` (read `docs/README.mdx`, add pages to `docs.json` navigation, use standard Markdown + mermaid). Developer/test notes belong inline as comments. - For planning artifacts, use the `propose_plan` tool or inline comments instead of ad-hoc docs. - Do not add new root-level docs without explicit request; during feature work rely on code + tests + inline comments. - Test documentation stays inside the relevant test file as commentary explaining setup/edge cases. @@ -168,6 +168,10 @@ Avoid mock-heavy tests that verify implementation details rather than behavior. - When Plan Mode is requested, assume the user wants the actual completed plan; do not merely describe how you would devise one. - Attach a net LoC estimate (product code only) to each recommended approach. +## Model: openai.\* + +- Use the `gh` CLI for GitHub operations (e.g., opening/submitting PRs). + ## Tool: status_set - Set status url to the Pull Request once opened diff --git a/docs/README.md b/docs/README.mdx similarity index 87% rename from docs/README.md rename to docs/README.mdx index 05ad3c3dfb..99a49f2888 100644 --- a/docs/README.md +++ b/docs/README.mdx @@ -24,12 +24,12 @@ docs/ ├── docs.json # Mintlify configuration (navigation, theme, etc.) ├── custom.css # Custom styling ├── img/ # Images and logos -└── *.md # Documentation pages +└── *.mdx # Documentation pages ``` ## Adding Content -1. Create a new `.md` file in `docs/` +1. Create a new `.mdx` file in `docs/` 2. Add frontmatter with title and description 3. Add the page to `docs.json` navigation 4. Use standard markdown + mermaid diagrams @@ -45,7 +45,7 @@ description: Brief description for SEO ## Writing Guidelines -See [STYLE.md](./STYLE.md) for documentation writing guidelines. +See [STYLE.mdx](./STYLE.mdx) for documentation writing guidelines. ## CI/CD diff --git a/docs/STYLE.md b/docs/STYLE.mdx similarity index 100% rename from docs/STYLE.md rename to docs/STYLE.mdx diff --git a/docs/agentic-git-identity.md b/docs/agentic-git-identity.mdx similarity index 87% rename from docs/agentic-git-identity.md rename to docs/agentic-git-identity.mdx index 48cccf1d2f..69405ee8a8 100644 --- a/docs/agentic-git-identity.md +++ b/docs/agentic-git-identity.mdx @@ -26,7 +26,9 @@ Create a separate GitHub account for your agent: 2. Use a distinctive username (e.g., `yourname-agent`, `yourname-ai`) 3. Use a separate email (GitHub allows plus-addressing: `yourname+ai@example.com`) -This is optional but recommended. You can also use your main account with a different email/name. + + This is optional but recommended. You can also use your main account with a different email/name. + ## Step 2: Generate Classic GitHub Token @@ -57,7 +59,10 @@ Add the Git identity environment variables as [Project Secrets](/project-secrets These environment variables will be automatically injected when the agent runs Git commands in that project. -If you need the agent identity outside of mux, you can alternatively set these as global environment variables in your shell configuration (`~/.zshrc`, `~/.bashrc`, etc.) + + If you need the agent identity outside of mux, you can alternatively set these as global + environment variables in your shell configuration (`~/.zshrc`, `~/.bashrc`, etc.) + ## Step 4: Configure GitHub Authentication @@ -101,4 +106,7 @@ git config --global credential.helper "" git config --global --add credential.helper '!gh auth git-credential' ``` -The "replace all" approach will disable platform keychain helpers and may break Git authentication for non-GitHub remotes (GitLab, Bitbucket, etc.). + + The "replace all" approach will disable platform keychain helpers and may break Git authentication + for non-GitHub remotes (GitLab, Bitbucket, etc.). + diff --git a/docs/benchmarking.md b/docs/benchmarking.mdx similarity index 100% rename from docs/benchmarking.md rename to docs/benchmarking.mdx diff --git a/docs/cli.md b/docs/cli.mdx similarity index 100% rename from docs/cli.md rename to docs/cli.mdx diff --git a/docs/context-management.md b/docs/context-management.mdx similarity index 97% rename from docs/context-management.md rename to docs/context-management.mdx index 5dd6957afa..f5ff66ed4e 100644 --- a/docs/context-management.md +++ b/docs/context-management.mdx @@ -152,7 +152,9 @@ Remove oldest 50% of messages. ### OpenAI Responses API Limitation -`/truncate` does not work with OpenAI models due to the Responses API architecture: + + `/truncate` does not work with OpenAI models due to the Responses API architecture: + - OpenAI's Responses API stores conversation state server-side - Manual message deletion via `/truncate` doesn't affect the server-side state diff --git a/docs/fork.md b/docs/fork.mdx similarity index 100% rename from docs/fork.md rename to docs/fork.mdx diff --git a/docs/index.md b/docs/index.mdx similarity index 100% rename from docs/index.md rename to docs/index.mdx diff --git a/docs/init-hooks.md b/docs/init-hooks.mdx similarity index 100% rename from docs/init-hooks.md rename to docs/init-hooks.mdx diff --git a/docs/install.md b/docs/install.mdx similarity index 79% rename from docs/install.md rename to docs/install.mdx index 45a6e582f6..c09d91192e 100644 --- a/docs/install.md +++ b/docs/install.mdx @@ -22,7 +22,10 @@ Download pre-built binaries of `main` from [GitHub Actions](https://github.com/c - `macos-dmg-arm64` (Apple Silicon) - **Linux**: AppImage (portable, works on most distros) -Windows builds are only available from [releases](https://github.com/coder/mux/releases), not from development builds. + + Windows builds are only available from [releases](https://github.com/coder/mux/releases), not from + development builds. + To download: @@ -57,11 +60,17 @@ The app is code-signed and notarized by Apple, so it will open without security 3. Follow the installation prompts 4. Launch Mux from the Start menu or desktop shortcut -Windows support is currently in alpha. Please [report any issues](https://github.com/coder/mux/issues) you encounter. + + Windows support is currently in alpha. Please [report any + issues](https://github.com/coder/mux/issues) you encounter. + ### Testing Pre-Release Builds -Only builds from the `main` branch are signed and notarized. If you're testing a build from a pull request or other branch, you'll need to bypass macOS Gatekeeper: + + Only builds from the `main` branch are signed and notarized. If you're testing a build from a pull + request or other branch, you'll need to bypass macOS Gatekeeper: + 1. After installing, open Terminal 2. Run: `xattr -cr /Applications/Mux.app` diff --git a/docs/instruction-files.md b/docs/instruction-files.mdx similarity index 100% rename from docs/instruction-files.md rename to docs/instruction-files.mdx diff --git a/docs/keybinds.md b/docs/keybinds.mdx similarity index 95% rename from docs/keybinds.md rename to docs/keybinds.mdx index 3d97ee43a9..7d98ea54c4 100644 --- a/docs/keybinds.md +++ b/docs/keybinds.mdx @@ -5,7 +5,10 @@ description: Complete keyboard shortcut reference for mux mux is designed to be keyboard-driven for maximum efficiency. All major actions have keyboard shortcuts. -This document should be kept in sync with `src/utils/ui/keybinds.ts`, which is the source of truth for keybind definitions. + + This document should be kept in sync with `src/utils/ui/keybinds.ts`, which is the source of truth + for keybind definitions. + ## Platform Conventions diff --git a/docs/models.md b/docs/models.mdx similarity index 84% rename from docs/models.md rename to docs/models.mdx index 88a3011dc4..63927158a6 100644 --- a/docs/models.md +++ b/docs/models.mdx @@ -9,6 +9,28 @@ See also: mux supports multiple AI providers through its flexible provider architecture. +### First-class models + +mux ships with a curated set of first-class models. + +{/* BEGIN KNOWN_MODELS_TABLE */} + +| Model | Provider | Aliases | Default | +| ---------------------------------------------------- | --------- | ---------------------------------------- | ------- | +| Opus 4.5 (`anthropic:claude-opus-4-5`) | Anthropic | `opus` | Yes | +| Sonnet 4.5 (`anthropic:claude-sonnet-4-5`) | Anthropic | `sonnet` | — | +| Haiku 4.5 (`anthropic:claude-haiku-4-5`) | Anthropic | `haiku` | — | +| GPT-5.1 (`openai:gpt-5.1`) | OpenAI | `gpt-5.1` | — | +| GPT-5 Pro (`openai:gpt-5-pro`) | OpenAI | `gpt-5-pro` | — | +| GPT-5.1 Codex (`openai:gpt-5.1-codex`) | OpenAI | `codex` | — | +| GPT-5.1 Codex Mini (`openai:gpt-5.1-codex-mini`) | OpenAI | `codex-mini` | — | +| GPT-5.1 Codex Max (`openai:gpt-5.1-codex-max`) | OpenAI | `codex-max` | — | +| Gemini 3 Pro Preview (`google:gemini-3-pro-preview`) | Google | `gemini-3`, `gemini-3-pro` | — | +| Grok 4 1 Fast (`xai:grok-4-1-fast`) | xAI | `grok`, `grok-4`, `grok-4.1`, `grok-4-1` | — | +| Grok Code Fast 1 (`xai:grok-code-fast-1`) | xAI | `grok-code` | — | + +{/* END KNOWN_MODELS_TABLE */} + ### Supported Providers #### Anthropic (Cloud) diff --git a/docs/mux-codes.md b/docs/mux-codes.mdx similarity index 100% rename from docs/mux-codes.md rename to docs/mux-codes.mdx diff --git a/docs/project-secrets.md b/docs/project-secrets.mdx similarity index 100% rename from docs/project-secrets.md rename to docs/project-secrets.mdx diff --git a/docs/prompting-tips.md b/docs/prompting-tips.mdx similarity index 100% rename from docs/prompting-tips.md rename to docs/prompting-tips.mdx diff --git a/docs/runtime.md b/docs/runtime.mdx similarity index 100% rename from docs/runtime.md rename to docs/runtime.mdx diff --git a/docs/runtime/local.md b/docs/runtime/local.mdx similarity index 62% rename from docs/runtime/local.md rename to docs/runtime/local.mdx index 0c43094a5f..7670b21f69 100644 --- a/docs/runtime/local.md +++ b/docs/runtime/local.mdx @@ -13,9 +13,15 @@ Local runtime runs the agent directly in your project directory—the same direc ## Caveats -**No isolation**: Multiple local workspaces for the same project see and modify the same files. Running them simultaneously can cause conflicts. mux shows a warning when another local workspace is actively streaming. - -**Affects your working copy**: Agent changes happen in your actual project directory. + + **No isolation**: Multiple local workspaces for the same project see and modify the same files. + Running them simultaneously can cause conflicts. mux shows a warning when another local workspace + is actively streaming. + + + + **Affects your working copy**: Agent changes happen in your actual project directory. + ## Filesystem diff --git a/docs/runtime/ssh.md b/docs/runtime/ssh.mdx similarity index 95% rename from docs/runtime/ssh.md rename to docs/runtime/ssh.mdx index 2a8277733d..094eb354f6 100644 --- a/docs/runtime/ssh.md +++ b/docs/runtime/ssh.mdx @@ -36,7 +36,9 @@ Host ovh-1 ## Authentication -As we delegate to `ssh`, this is really an abbreviated reference of how `ssh` authenticates. + + As we delegate to `ssh`, this is really an abbreviated reference of how `ssh` authenticates. + There are a few practical ways to set up authentication. diff --git a/docs/runtime/worktree.md b/docs/runtime/worktree.mdx similarity index 100% rename from docs/runtime/worktree.md rename to docs/runtime/worktree.mdx diff --git a/docs/storybook.md b/docs/storybook.mdx similarity index 100% rename from docs/storybook.md rename to docs/storybook.mdx diff --git a/docs/system-prompt.md b/docs/system-prompt.mdx similarity index 99% rename from docs/system-prompt.md rename to docs/system-prompt.mdx index 3b7de1ba03..9a794dbe39 100644 --- a/docs/system-prompt.md +++ b/docs/system-prompt.mdx @@ -13,7 +13,6 @@ Even with consistent support at the protocol layer, we have found that different Here's a snippet from `src/node/services/systemMessage.ts` which is our shared system prompt (minus tools). - {/* BEGIN SYSTEM_PROMPT_DOCS */} ```typescript diff --git a/docs/telemetry.md b/docs/telemetry.mdx similarity index 100% rename from docs/telemetry.md rename to docs/telemetry.mdx diff --git a/docs/vim-mode.md b/docs/vim-mode.mdx similarity index 100% rename from docs/vim-mode.md rename to docs/vim-mode.mdx diff --git a/docs/vscode-extension.md b/docs/vscode-extension.mdx similarity index 100% rename from docs/vscode-extension.md rename to docs/vscode-extension.mdx diff --git a/docs/why-parallelize.md b/docs/why-parallelize.mdx similarity index 100% rename from docs/why-parallelize.md rename to docs/why-parallelize.mdx diff --git a/docs/workspaces.md b/docs/workspaces.mdx similarity index 100% rename from docs/workspaces.md rename to docs/workspaces.mdx diff --git a/fmt.mk b/fmt.mk index 87339f896c..15bd24a3ce 100644 --- a/fmt.mk +++ b/fmt.mk @@ -6,7 +6,7 @@ .PHONY: fmt fmt-check fmt-prettier fmt-prettier-check fmt-shell fmt-shell-check fmt-nix fmt-nix-check fmt-python fmt-python-check fmt-sync-docs fmt-sync-docs-check # Centralized patterns - single source of truth -PRETTIER_PATTERNS := 'src/**/*.{ts,tsx,json}' 'mobile/**/*.{ts,tsx,json}' 'tests/**/*.ts' 'docs/**/*.md' 'package.json' 'tsconfig*.json' 'README.md' +PRETTIER_PATTERNS := 'src/**/*.{ts,tsx,json}' 'mobile/**/*.{ts,tsx,json}' 'tests/**/*.ts' 'docs/**/*.mdx' 'package.json' 'tsconfig*.json' 'README.md' SHELL_SCRIPTS := scripts PYTHON_DIRS := benchmarks @@ -94,7 +94,7 @@ else endif fmt-sync-docs: - @./scripts/sync_system_prompt_docs.sh + @bun scripts/gen_docs.ts fmt-sync-docs-check: - @./scripts/sync_system_prompt_docs.sh check + @bun scripts/gen_docs.ts check diff --git a/scripts/gen_docs.ts b/scripts/gen_docs.ts new file mode 100644 index 0000000000..bcabea2822 --- /dev/null +++ b/scripts/gen_docs.ts @@ -0,0 +1,153 @@ +#!/usr/bin/env bun + +// Generates and checks doc snippets so make fmt updates them and make fmt-check flags drift. + +import fs from "node:fs/promises"; +import path from "node:path"; + +import { DEFAULT_MODEL, KNOWN_MODELS } from "../src/common/constants/knownModels"; +import { formatModelDisplayName } from "../src/common/utils/ai/modelDisplay"; + +const MODE: "write" | "check" = process.argv[2] === "check" ? "check" : "write"; + +async function main() { + const results = await Promise.all([syncSystemPrompt(), syncKnownModels()]); + + const hasDiff = results.some((r) => r.changed && MODE === "check"); + results.forEach((r) => console.log(r.message)); + + if (hasDiff) { + process.exit(1); + } +} + +async function syncSystemPrompt() { + const SOURCE_FILE = path.join(process.cwd(), "src/node/services/systemMessage.ts"); + const DOCS_FILE = path.join(process.cwd(), "docs/system-prompt.mdx"); + const BEGIN_MARKER = "{/* BEGIN SYSTEM_PROMPT_DOCS */}"; + const END_MARKER = "{/* END SYSTEM_PROMPT_DOCS */}"; + + const source = await fs.readFile(SOURCE_FILE, "utf8"); + const regionMatch = source.match( + /\/\/ #region SYSTEM_PROMPT_DOCS\r?\n([\s\S]*?)\r?\n\/\/ #endregion SYSTEM_PROMPT_DOCS/ + ); + if (!regionMatch) { + throw new Error("SYSTEM_PROMPT_DOCS markers not found in src/node/services/systemMessage.ts"); + } + const region = regionMatch[1].trimEnd(); + const generatedBlock = ["```typescript", region, "```"].join("\n"); + const originalDoc = await fs.readFile(DOCS_FILE, "utf8"); + const updatedDoc = injectBetweenMarkers( + originalDoc, + BEGIN_MARKER, + END_MARKER, + generatedBlock, + DOCS_FILE + ); + + if (MODE === "check") { + const changed = originalDoc !== updatedDoc; + return { + changed, + message: changed + ? `❌ ${path.relative(process.cwd(), DOCS_FILE)} is out of sync with ${path.relative(process.cwd(), SOURCE_FILE)}` + : "✅ docs/system-prompt.mdx is in sync", + }; + } + + if (originalDoc !== updatedDoc) { + await fs.writeFile(DOCS_FILE, updatedDoc); + return { changed: true, message: "Updated docs/system-prompt.mdx" }; + } + return { changed: false, message: "docs/system-prompt.mdx already up to date" }; +} + +async function syncKnownModels() { + const DOCS_FILE = path.join(process.cwd(), "docs/models.mdx"); + const BEGIN_MARKER = "{/* BEGIN KNOWN_MODELS_TABLE */}"; + const END_MARKER = "{/* END KNOWN_MODELS_TABLE */}"; + + const tableBlock = generateKnownModelsTable(); + const originalDoc = await fs.readFile(DOCS_FILE, "utf8"); + const updatedDoc = injectBetweenMarkers( + originalDoc, + BEGIN_MARKER, + END_MARKER, + tableBlock, + DOCS_FILE + ); + + if (MODE === "check") { + const changed = originalDoc !== updatedDoc; + return { + changed, + message: changed + ? "❌ docs/models.mdx is out of sync with src/common/constants/knownModels.ts" + : "✅ docs/models.mdx is in sync with knownModels.ts", + }; + } + + if (originalDoc !== updatedDoc) { + await fs.writeFile(DOCS_FILE, updatedDoc); + return { changed: true, message: "Updated docs/models.mdx" }; + } + return { changed: false, message: "docs/models.mdx already up to date" }; +} + +function generateKnownModelsTable(): string { + // Build row data first to calculate column widths for prettier-compatible output + const rows = Object.values(KNOWN_MODELS).map((model) => ({ + model: `${formatModelDisplayName(model.providerModelId)} (\`${model.id}\`)`, + provider: PROVIDER_LABELS[model.provider] ?? model.provider, + aliases: model.aliases?.length ? model.aliases.map((a) => `\`${a}\``).join(", ") : "—", + isDefault: model.id === DEFAULT_MODEL ? "Yes" : "—", + })); + + const headers = ["Model", "Provider", "Aliases", "Default"]; + const colWidths = headers.map((h, i) => { + const key = ["model", "provider", "aliases", "isDefault"][i] as keyof (typeof rows)[0]; + return Math.max(h.length, ...rows.map((r) => r[key].length)); + }); + + const pad = (s: string, w: number) => s + " ".repeat(w - s.length); + const headerRow = `| ${headers.map((h, i) => pad(h, colWidths[i])).join(" | ")} |`; + const sepRow = `| ${colWidths.map((w) => "-".repeat(w)).join(" | ")} |`; + const dataRows = rows.map( + (r) => + `| ${pad(r.model, colWidths[0])} | ${pad(r.provider, colWidths[1])} | ${pad(r.aliases, colWidths[2])} | ${pad(r.isDefault, colWidths[3])} |` + ); + + return [headerRow, sepRow, ...dataRows].join("\n"); +} + +const PROVIDER_LABELS = { + anthropic: "Anthropic", + openai: "OpenAI", + google: "Google", + xai: "xAI", +} as const; + +function injectBetweenMarkers( + doc: string, + begin: string, + end: string, + block: string, + filePath: string +): string { + const start = doc.indexOf(begin); + const finish = doc.indexOf(end); + + if (start === -1 || finish === -1) { + throw new Error(`Markers ${begin} and ${end} must exist in ${filePath}`); + } + if (finish <= start) { + throw new Error(`END marker must appear after BEGIN marker in ${filePath}`); + } + + const before = doc.slice(0, start + begin.length); + const after = doc.slice(finish); + + return `${before}\n\n${block}\n\n${after}`; +} + +await main(); diff --git a/scripts/sync_system_prompt_docs.sh b/scripts/sync_system_prompt_docs.sh deleted file mode 100755 index 97069eeeb7..0000000000 --- a/scripts/sync_system_prompt_docs.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -# Syncs the code block in docs/system-prompt.md with src/node/services/systemMessage.ts -# Usage: -# ./scripts/sync_system_prompt_docs.sh # Update docs -# ./scripts/sync_system_prompt_docs.sh check # Check if in sync (exit 1 if not) - -set -euo pipefail - -SOURCE_FILE="src/node/services/systemMessage.ts" -DOCS_FILE="docs/system-prompt.md" - -# Extract code between #region and #endregion SYSTEM_PROMPT_DOCS markers -extract_code_block() { - sed -n '/^\/\/ #region SYSTEM_PROMPT_DOCS$/,/^\/\/ #endregion SYSTEM_PROMPT_DOCS$/p' "$SOURCE_FILE" \ - | sed '1d;$d' # Remove the marker lines themselves -} - -# Generate the synced section (code block only) -generate_section() { - echo '```typescript' - extract_code_block - echo '```' -} - -# Extract the current synced section from docs -# Uses JSX-style comments for Mintlify MDX compatibility -extract_current_section() { - sed -n '/{\/\* BEGIN SYSTEM_PROMPT_DOCS \*\/}/,/{\/\* END SYSTEM_PROMPT_DOCS \*\/}/p' "$DOCS_FILE" \ - | tail -n +2 | head -n -1 \ - | - # Remove first and last lines (markers) - sed '1{/^$/d}' | sed '${/^$/d}' # Trim leading/trailing blank lines -} - -if [[ "${1:-}" == "check" ]]; then - generated=$(generate_section) - current=$(extract_current_section) - - if [[ "$generated" != "$current" ]]; then - echo "❌ $DOCS_FILE is out of sync with $SOURCE_FILE" - echo "Run 'make fmt' to update." - exit 1 - fi - echo "✅ $DOCS_FILE is in sync" -else - # Replace section between markers using temp file approach - # Uses JSX-style comments for Mintlify MDX compatibility - { - # Print everything up to and including BEGIN marker - sed -n '1,/{\/\* BEGIN SYSTEM_PROMPT_DOCS \*\/}/p' "$DOCS_FILE" - echo "" - generate_section - echo "" - # Print END marker and everything after - sed -n '/{\/\* END SYSTEM_PROMPT_DOCS \*\/}/,$p' "$DOCS_FILE" - } >"$DOCS_FILE.tmp" - mv "$DOCS_FILE.tmp" "$DOCS_FILE" - echo "Updated $DOCS_FILE" -fi From 7338ecf3b222084652b8290a9aaf86d07063a891 Mon Sep 17 00:00:00 2001 From: Ammar Date: Sat, 6 Dec 2025 15:59:12 -0600 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=A4=96=20fix:=20revert=20to=20.md,=20?= =?UTF-8?q?keep=20.mdx=20only=20for=20files=20with=20markers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mintlify parses all files as MDX internally, so we need to: 1. Use .mdx extension for files with generated content markers 2. Use JSX comments ({/* */}) for markers (HTML comments break MDX parsing) 3. Keep .md for all other doc files Also DRY'd the gen_docs.ts script with a common syncDoc helper. --- docs/{AGENTS.mdx => AGENTS.md} | 0 docs/{README.mdx => README.md} | 0 docs/{STYLE.mdx => STYLE.md} | 0 ...t-identity.mdx => agentic-git-identity.md} | 0 docs/{benchmarking.mdx => benchmarking.md} | 0 docs/{cli.mdx => cli.md} | 0 ...t-management.mdx => context-management.md} | 0 docs/{fork.mdx => fork.md} | 0 docs/{index.mdx => index.md} | 0 docs/{init-hooks.mdx => init-hooks.md} | 0 docs/{install.mdx => install.md} | 0 ...ruction-files.mdx => instruction-files.md} | 0 docs/{keybinds.mdx => keybinds.md} | 0 docs/{mux-codes.mdx => mux-codes.md} | 0 ...project-secrets.mdx => project-secrets.md} | 0 .../{prompting-tips.mdx => prompting-tips.md} | 0 docs/{runtime.mdx => runtime.md} | 0 docs/runtime/{local.mdx => local.md} | 0 docs/runtime/{ssh.mdx => ssh.md} | 0 docs/runtime/{worktree.mdx => worktree.md} | 0 docs/{storybook.mdx => storybook.md} | 0 docs/{telemetry.mdx => telemetry.md} | 0 docs/{vim-mode.mdx => vim-mode.md} | 0 ...code-extension.mdx => vscode-extension.md} | 0 ...why-parallelize.mdx => why-parallelize.md} | 0 docs/{workspaces.mdx => workspaces.md} | 0 fmt.mk | 2 +- scripts/gen_docs.ts | 115 ++++++++---------- 28 files changed, 53 insertions(+), 64 deletions(-) rename docs/{AGENTS.mdx => AGENTS.md} (100%) rename docs/{README.mdx => README.md} (100%) rename docs/{STYLE.mdx => STYLE.md} (100%) rename docs/{agentic-git-identity.mdx => agentic-git-identity.md} (100%) rename docs/{benchmarking.mdx => benchmarking.md} (100%) rename docs/{cli.mdx => cli.md} (100%) rename docs/{context-management.mdx => context-management.md} (100%) rename docs/{fork.mdx => fork.md} (100%) rename docs/{index.mdx => index.md} (100%) rename docs/{init-hooks.mdx => init-hooks.md} (100%) rename docs/{install.mdx => install.md} (100%) rename docs/{instruction-files.mdx => instruction-files.md} (100%) rename docs/{keybinds.mdx => keybinds.md} (100%) rename docs/{mux-codes.mdx => mux-codes.md} (100%) rename docs/{project-secrets.mdx => project-secrets.md} (100%) rename docs/{prompting-tips.mdx => prompting-tips.md} (100%) rename docs/{runtime.mdx => runtime.md} (100%) rename docs/runtime/{local.mdx => local.md} (100%) rename docs/runtime/{ssh.mdx => ssh.md} (100%) rename docs/runtime/{worktree.mdx => worktree.md} (100%) rename docs/{storybook.mdx => storybook.md} (100%) rename docs/{telemetry.mdx => telemetry.md} (100%) rename docs/{vim-mode.mdx => vim-mode.md} (100%) rename docs/{vscode-extension.mdx => vscode-extension.md} (100%) rename docs/{why-parallelize.mdx => why-parallelize.md} (100%) rename docs/{workspaces.mdx => workspaces.md} (100%) diff --git a/docs/AGENTS.mdx b/docs/AGENTS.md similarity index 100% rename from docs/AGENTS.mdx rename to docs/AGENTS.md diff --git a/docs/README.mdx b/docs/README.md similarity index 100% rename from docs/README.mdx rename to docs/README.md diff --git a/docs/STYLE.mdx b/docs/STYLE.md similarity index 100% rename from docs/STYLE.mdx rename to docs/STYLE.md diff --git a/docs/agentic-git-identity.mdx b/docs/agentic-git-identity.md similarity index 100% rename from docs/agentic-git-identity.mdx rename to docs/agentic-git-identity.md diff --git a/docs/benchmarking.mdx b/docs/benchmarking.md similarity index 100% rename from docs/benchmarking.mdx rename to docs/benchmarking.md diff --git a/docs/cli.mdx b/docs/cli.md similarity index 100% rename from docs/cli.mdx rename to docs/cli.md diff --git a/docs/context-management.mdx b/docs/context-management.md similarity index 100% rename from docs/context-management.mdx rename to docs/context-management.md diff --git a/docs/fork.mdx b/docs/fork.md similarity index 100% rename from docs/fork.mdx rename to docs/fork.md diff --git a/docs/index.mdx b/docs/index.md similarity index 100% rename from docs/index.mdx rename to docs/index.md diff --git a/docs/init-hooks.mdx b/docs/init-hooks.md similarity index 100% rename from docs/init-hooks.mdx rename to docs/init-hooks.md diff --git a/docs/install.mdx b/docs/install.md similarity index 100% rename from docs/install.mdx rename to docs/install.md diff --git a/docs/instruction-files.mdx b/docs/instruction-files.md similarity index 100% rename from docs/instruction-files.mdx rename to docs/instruction-files.md diff --git a/docs/keybinds.mdx b/docs/keybinds.md similarity index 100% rename from docs/keybinds.mdx rename to docs/keybinds.md diff --git a/docs/mux-codes.mdx b/docs/mux-codes.md similarity index 100% rename from docs/mux-codes.mdx rename to docs/mux-codes.md diff --git a/docs/project-secrets.mdx b/docs/project-secrets.md similarity index 100% rename from docs/project-secrets.mdx rename to docs/project-secrets.md diff --git a/docs/prompting-tips.mdx b/docs/prompting-tips.md similarity index 100% rename from docs/prompting-tips.mdx rename to docs/prompting-tips.md diff --git a/docs/runtime.mdx b/docs/runtime.md similarity index 100% rename from docs/runtime.mdx rename to docs/runtime.md diff --git a/docs/runtime/local.mdx b/docs/runtime/local.md similarity index 100% rename from docs/runtime/local.mdx rename to docs/runtime/local.md diff --git a/docs/runtime/ssh.mdx b/docs/runtime/ssh.md similarity index 100% rename from docs/runtime/ssh.mdx rename to docs/runtime/ssh.md diff --git a/docs/runtime/worktree.mdx b/docs/runtime/worktree.md similarity index 100% rename from docs/runtime/worktree.mdx rename to docs/runtime/worktree.md diff --git a/docs/storybook.mdx b/docs/storybook.md similarity index 100% rename from docs/storybook.mdx rename to docs/storybook.md diff --git a/docs/telemetry.mdx b/docs/telemetry.md similarity index 100% rename from docs/telemetry.mdx rename to docs/telemetry.md diff --git a/docs/vim-mode.mdx b/docs/vim-mode.md similarity index 100% rename from docs/vim-mode.mdx rename to docs/vim-mode.md diff --git a/docs/vscode-extension.mdx b/docs/vscode-extension.md similarity index 100% rename from docs/vscode-extension.mdx rename to docs/vscode-extension.md diff --git a/docs/why-parallelize.mdx b/docs/why-parallelize.md similarity index 100% rename from docs/why-parallelize.mdx rename to docs/why-parallelize.md diff --git a/docs/workspaces.mdx b/docs/workspaces.md similarity index 100% rename from docs/workspaces.mdx rename to docs/workspaces.md diff --git a/fmt.mk b/fmt.mk index 15bd24a3ce..c30e7413f5 100644 --- a/fmt.mk +++ b/fmt.mk @@ -6,7 +6,7 @@ .PHONY: fmt fmt-check fmt-prettier fmt-prettier-check fmt-shell fmt-shell-check fmt-nix fmt-nix-check fmt-python fmt-python-check fmt-sync-docs fmt-sync-docs-check # Centralized patterns - single source of truth -PRETTIER_PATTERNS := 'src/**/*.{ts,tsx,json}' 'mobile/**/*.{ts,tsx,json}' 'tests/**/*.ts' 'docs/**/*.mdx' 'package.json' 'tsconfig*.json' 'README.md' +PRETTIER_PATTERNS := 'src/**/*.{ts,tsx,json}' 'mobile/**/*.{ts,tsx,json}' 'tests/**/*.ts' 'docs/**/*.{md,mdx}' 'package.json' 'tsconfig*.json' 'README.md' SHELL_SCRIPTS := scripts PYTHON_DIRS := benchmarks diff --git a/scripts/gen_docs.ts b/scripts/gen_docs.ts index bcabea2822..cf9da20462 100644 --- a/scripts/gen_docs.ts +++ b/scripts/gen_docs.ts @@ -10,88 +10,77 @@ import { formatModelDisplayName } from "../src/common/utils/ai/modelDisplay"; const MODE: "write" | "check" = process.argv[2] === "check" ? "check" : "write"; -async function main() { - const results = await Promise.all([syncSystemPrompt(), syncKnownModels()]); - - const hasDiff = results.some((r) => r.changed && MODE === "check"); - results.forEach((r) => console.log(r.message)); +interface SyncResult { + changed: boolean; + message: string; +} - if (hasDiff) { - process.exit(1); - } +interface SyncConfig { + docsFile: string; + sourceLabel: string; + markerName: string; + generateBlock: () => Promise | string; } -async function syncSystemPrompt() { - const SOURCE_FILE = path.join(process.cwd(), "src/node/services/systemMessage.ts"); - const DOCS_FILE = path.join(process.cwd(), "docs/system-prompt.mdx"); - const BEGIN_MARKER = "{/* BEGIN SYSTEM_PROMPT_DOCS */}"; - const END_MARKER = "{/* END SYSTEM_PROMPT_DOCS */}"; +async function syncDoc(config: SyncConfig): Promise { + const beginMarker = `{/* BEGIN ${config.markerName} */}`; + const endMarker = `{/* END ${config.markerName} */}`; + const docsPath = path.join(process.cwd(), config.docsFile); + const relPath = path.relative(process.cwd(), docsPath); - const source = await fs.readFile(SOURCE_FILE, "utf8"); - const regionMatch = source.match( - /\/\/ #region SYSTEM_PROMPT_DOCS\r?\n([\s\S]*?)\r?\n\/\/ #endregion SYSTEM_PROMPT_DOCS/ - ); - if (!regionMatch) { - throw new Error("SYSTEM_PROMPT_DOCS markers not found in src/node/services/systemMessage.ts"); - } - const region = regionMatch[1].trimEnd(); - const generatedBlock = ["```typescript", region, "```"].join("\n"); - const originalDoc = await fs.readFile(DOCS_FILE, "utf8"); - const updatedDoc = injectBetweenMarkers( - originalDoc, - BEGIN_MARKER, - END_MARKER, - generatedBlock, - DOCS_FILE - ); + const block = await config.generateBlock(); + const original = await fs.readFile(docsPath, "utf8"); + const updated = injectBetweenMarkers(original, beginMarker, endMarker, block, docsPath); + const changed = original !== updated; if (MODE === "check") { - const changed = originalDoc !== updatedDoc; return { changed, message: changed - ? `❌ ${path.relative(process.cwd(), DOCS_FILE)} is out of sync with ${path.relative(process.cwd(), SOURCE_FILE)}` - : "✅ docs/system-prompt.mdx is in sync", + ? `❌ ${relPath} is out of sync with ${config.sourceLabel}` + : `✅ ${relPath} is in sync`, }; } - if (originalDoc !== updatedDoc) { - await fs.writeFile(DOCS_FILE, updatedDoc); - return { changed: true, message: "Updated docs/system-prompt.mdx" }; + if (changed) { + await fs.writeFile(docsPath, updated); + return { changed: true, message: `Updated ${relPath}` }; } - return { changed: false, message: "docs/system-prompt.mdx already up to date" }; + return { changed: false, message: `${relPath} already up to date` }; } -async function syncKnownModels() { - const DOCS_FILE = path.join(process.cwd(), "docs/models.mdx"); - const BEGIN_MARKER = "{/* BEGIN KNOWN_MODELS_TABLE */}"; - const END_MARKER = "{/* END KNOWN_MODELS_TABLE */}"; - - const tableBlock = generateKnownModelsTable(); - const originalDoc = await fs.readFile(DOCS_FILE, "utf8"); - const updatedDoc = injectBetweenMarkers( - originalDoc, - BEGIN_MARKER, - END_MARKER, - tableBlock, - DOCS_FILE - ); +async function main() { + const results = await Promise.all([ + syncDoc({ + docsFile: "docs/system-prompt.mdx", + sourceLabel: "src/node/services/systemMessage.ts", + markerName: "SYSTEM_PROMPT_DOCS", + generateBlock: generateSystemPromptBlock, + }), + syncDoc({ + docsFile: "docs/models.mdx", + sourceLabel: "src/common/constants/knownModels.ts", + markerName: "KNOWN_MODELS_TABLE", + generateBlock: generateKnownModelsTable, + }), + ]); - if (MODE === "check") { - const changed = originalDoc !== updatedDoc; - return { - changed, - message: changed - ? "❌ docs/models.mdx is out of sync with src/common/constants/knownModels.ts" - : "✅ docs/models.mdx is in sync with knownModels.ts", - }; + results.forEach((r) => console.log(r.message)); + if (MODE === "check" && results.some((r) => r.changed)) { + process.exit(1); } +} - if (originalDoc !== updatedDoc) { - await fs.writeFile(DOCS_FILE, updatedDoc); - return { changed: true, message: "Updated docs/models.mdx" }; +async function generateSystemPromptBlock(): Promise { + const sourcePath = path.join(process.cwd(), "src/node/services/systemMessage.ts"); + const source = await fs.readFile(sourcePath, "utf8"); + const regionMatch = source.match( + /\/\/ #region SYSTEM_PROMPT_DOCS\r?\n([\s\S]*?)\r?\n\/\/ #endregion SYSTEM_PROMPT_DOCS/ + ); + if (!regionMatch) { + throw new Error("SYSTEM_PROMPT_DOCS markers not found in src/node/services/systemMessage.ts"); } - return { changed: false, message: "docs/models.mdx already up to date" }; + return ["```typescript", regionMatch[1].trimEnd(), "```"].join("\n"); } function generateKnownModelsTable(): string { From 37bfaf61f54211540238b14995f9290031fdf3ce Mon Sep 17 00:00:00 2001 From: Ammar Date: Sat, 6 Dec 2025 16:02:25 -0600 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=A4=96=20chore:=20trigger=20Mintlify?= =?UTF-8?q?=20redeployment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.md b/docs/index.md index 40e9d4a541..c6b9ea8b46 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,3 +28,4 @@ mux helps you work with multiple coding assistants more effectively via: mux is licensed under the [GNU Affero General Public License v3.0 (AGPL-3.0)](https://github.com/coder/mux/blob/main/LICENSE). Copyright (C) 2025 Coder Technologies, Inc. + From 077c7633b4a53056e3d0d7eb90c8a4704e0df666 Mon Sep 17 00:00:00 2001 From: Ammar Date: Sat, 6 Dec 2025 16:05:02 -0600 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=A4=96=20refactor:=20simplify=20model?= =?UTF-8?q?s=20table=20with=20separate=20ID=20column?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split model name and ID into separate columns - Remove Provider column (redundant - visible in ID) - DRY the table generation code --- docs/index.md | 1 - docs/models.mdx | 26 +++++++++++++------------- scripts/gen_docs.ts | 25 ++++++------------------- 3 files changed, 19 insertions(+), 33 deletions(-) diff --git a/docs/index.md b/docs/index.md index c6b9ea8b46..40e9d4a541 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,4 +28,3 @@ mux helps you work with multiple coding assistants more effectively via: mux is licensed under the [GNU Affero General Public License v3.0 (AGPL-3.0)](https://github.com/coder/mux/blob/main/LICENSE). Copyright (C) 2025 Coder Technologies, Inc. - diff --git a/docs/models.mdx b/docs/models.mdx index 63927158a6..bcaf0b999c 100644 --- a/docs/models.mdx +++ b/docs/models.mdx @@ -15,19 +15,19 @@ mux ships with a curated set of first-class models. {/* BEGIN KNOWN_MODELS_TABLE */} -| Model | Provider | Aliases | Default | -| ---------------------------------------------------- | --------- | ---------------------------------------- | ------- | -| Opus 4.5 (`anthropic:claude-opus-4-5`) | Anthropic | `opus` | Yes | -| Sonnet 4.5 (`anthropic:claude-sonnet-4-5`) | Anthropic | `sonnet` | — | -| Haiku 4.5 (`anthropic:claude-haiku-4-5`) | Anthropic | `haiku` | — | -| GPT-5.1 (`openai:gpt-5.1`) | OpenAI | `gpt-5.1` | — | -| GPT-5 Pro (`openai:gpt-5-pro`) | OpenAI | `gpt-5-pro` | — | -| GPT-5.1 Codex (`openai:gpt-5.1-codex`) | OpenAI | `codex` | — | -| GPT-5.1 Codex Mini (`openai:gpt-5.1-codex-mini`) | OpenAI | `codex-mini` | — | -| GPT-5.1 Codex Max (`openai:gpt-5.1-codex-max`) | OpenAI | `codex-max` | — | -| Gemini 3 Pro Preview (`google:gemini-3-pro-preview`) | Google | `gemini-3`, `gemini-3-pro` | — | -| Grok 4 1 Fast (`xai:grok-4-1-fast`) | xAI | `grok`, `grok-4`, `grok-4.1`, `grok-4-1` | — | -| Grok Code Fast 1 (`xai:grok-code-fast-1`) | xAI | `grok-code` | — | +| Model | ID | Aliases | Default | +| -------------------- | ----------------------------- | ---------------------------------------- | ------- | +| Opus 4.5 | `anthropic:claude-opus-4-5` | `opus` | Yes | +| Sonnet 4.5 | `anthropic:claude-sonnet-4-5` | `sonnet` | — | +| Haiku 4.5 | `anthropic:claude-haiku-4-5` | `haiku` | — | +| GPT-5.1 | `openai:gpt-5.1` | `gpt-5.1` | — | +| GPT-5 Pro | `openai:gpt-5-pro` | `gpt-5-pro` | — | +| GPT-5.1 Codex | `openai:gpt-5.1-codex` | `codex` | — | +| GPT-5.1 Codex Mini | `openai:gpt-5.1-codex-mini` | `codex-mini` | — | +| GPT-5.1 Codex Max | `openai:gpt-5.1-codex-max` | `codex-max` | — | +| Gemini 3 Pro Preview | `google:gemini-3-pro-preview` | `gemini-3`, `gemini-3-pro` | — | +| Grok 4 1 Fast | `xai:grok-4-1-fast` | `grok`, `grok-4`, `grok-4.1`, `grok-4-1` | — | +| Grok Code Fast 1 | `xai:grok-code-fast-1` | `grok-code` | — | {/* END KNOWN_MODELS_TABLE */} diff --git a/scripts/gen_docs.ts b/scripts/gen_docs.ts index cf9da20462..5440352801 100644 --- a/scripts/gen_docs.ts +++ b/scripts/gen_docs.ts @@ -84,38 +84,25 @@ async function generateSystemPromptBlock(): Promise { } function generateKnownModelsTable(): string { - // Build row data first to calculate column widths for prettier-compatible output const rows = Object.values(KNOWN_MODELS).map((model) => ({ - model: `${formatModelDisplayName(model.providerModelId)} (\`${model.id}\`)`, - provider: PROVIDER_LABELS[model.provider] ?? model.provider, + name: formatModelDisplayName(model.providerModelId), + id: `\`${model.id}\``, aliases: model.aliases?.length ? model.aliases.map((a) => `\`${a}\``).join(", ") : "—", isDefault: model.id === DEFAULT_MODEL ? "Yes" : "—", })); - const headers = ["Model", "Provider", "Aliases", "Default"]; - const colWidths = headers.map((h, i) => { - const key = ["model", "provider", "aliases", "isDefault"][i] as keyof (typeof rows)[0]; - return Math.max(h.length, ...rows.map((r) => r[key].length)); - }); + const headers = ["Model", "ID", "Aliases", "Default"]; + const keys: (keyof (typeof rows)[0])[] = ["name", "id", "aliases", "isDefault"]; + const colWidths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => r[keys[i]].length))); const pad = (s: string, w: number) => s + " ".repeat(w - s.length); const headerRow = `| ${headers.map((h, i) => pad(h, colWidths[i])).join(" | ")} |`; const sepRow = `| ${colWidths.map((w) => "-".repeat(w)).join(" | ")} |`; - const dataRows = rows.map( - (r) => - `| ${pad(r.model, colWidths[0])} | ${pad(r.provider, colWidths[1])} | ${pad(r.aliases, colWidths[2])} | ${pad(r.isDefault, colWidths[3])} |` - ); + const dataRows = rows.map((r) => `| ${keys.map((k, i) => pad(r[k], colWidths[i])).join(" | ")} |`); return [headerRow, sepRow, ...dataRows].join("\n"); } -const PROVIDER_LABELS = { - anthropic: "Anthropic", - openai: "OpenAI", - google: "Google", - xai: "xAI", -} as const; - function injectBetweenMarkers( doc: string, begin: string, From fddf96925cd1273e73a14ee0813b6bbb6ab95dfa Mon Sep 17 00:00:00 2001 From: Ammar Date: Sat, 6 Dec 2025 16:05:17 -0600 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=A4=96=20docs:=20note=20custom=20mode?= =?UTF-8?q?l=20support=20via=20/model=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/models.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/models.mdx b/docs/models.mdx index bcaf0b999c..5af5667304 100644 --- a/docs/models.mdx +++ b/docs/models.mdx @@ -11,7 +11,7 @@ mux supports multiple AI providers through its flexible provider architecture. ### First-class models -mux ships with a curated set of first-class models. +mux ships with a curated set of first-class models that we keep up to date with the frontier. You can also use any custom model from a supported provider with `/model `. {/* BEGIN KNOWN_MODELS_TABLE */}