diff --git a/docs/system-prompt.md b/docs/system-prompt.md
index 8ca2d5879c..b422eb8526 100644
--- a/docs/system-prompt.md
+++ b/docs/system-prompt.md
@@ -6,17 +6,17 @@ To that end, we're built on the [Vercel AI SDK](https://ai-sdk.dev/providers/ai-
Even with consistent support at the protocol layer, we have found that different models react very differently to the same set of tools and instructions. So, **we strive to minimize the system prompt and let users figure out the prompting trade-offs**.
-Here's a snippet from `src/services/systemMessage.ts` which is our shared system prompt (minus tools).
+Here's a snippet from `src/node/services/systemMessage.ts` which is our shared system prompt (minus tools).
-
+
```typescript
// The PRELUDE is intentionally minimal to not conflict with the user's instructions.
// mux is designed to be model agnostic, and models have shown large inconsistency in how they
// follow instructions.
-const PRELUDE = `
+const PRELUDE = `
-You are a coding agent.
+You are a coding agent called Mux. You may find information about yourself here: https://mux.coder.com/.
Your Assistant messages display in Markdown with extensions for mermaidjs and katex.
@@ -30,14 +30,20 @@ When creating mermaid diagrams:
Use GitHub-style \`/\` tags to create collapsible sections for lengthy content, error traces, or supplementary information. Toggles help keep responses scannable while preserving detail.
+
+
+When the user asks you to remember something:
+- If it's about the general codebase: encode that lesson into the project's AGENTS.md file, matching its existing tone and structure.
+- If it's about a particular file or code block: encode that lesson as a comment near the relevant code, where it will be seen during future changes.
+
`;
-function buildEnvironmentContext(runtime: Runtime, workspacePath: string): string {
- const isWorktree = runtime instanceof LocalRuntime;
-
- if (isWorktree) {
- return `
+/**
+ * Build environment context XML block describing the workspace.
+ */
+function buildEnvironmentContext(workspacePath: string): string {
+ return `
You are in a git worktree at ${workspacePath}
@@ -47,16 +53,7 @@ You are in a git worktree at ${workspacePath}
- You are meant to do your work isolated from the user and other agents
`;
- } else {
- return `
-
-You are in a git repository at ${workspacePath}
-
-- This IS a git repository - run git commands directly (no cd needed)
-- Tools run here automatically
-- You are meant to do your work isolated from the user and other agents
-
-`;
- }
}
```
+
+
diff --git a/fmt.mk b/fmt.mk
index 3da2ff1684..87339f896c 100644
--- a/fmt.mk
+++ b/fmt.mk
@@ -3,7 +3,7 @@
# This file contains all code formatting logic.
# Included by the main Makefile.
-.PHONY: fmt fmt-check fmt-prettier fmt-prettier-check fmt-shell fmt-shell-check fmt-nix fmt-nix-check fmt-python fmt-python-check
+.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'
@@ -18,10 +18,10 @@ SHFMT := $(shell command -v shfmt 2>/dev/null)
NIX := $(shell command -v nix 2>/dev/null)
UVX := $(shell command -v uvx 2>/dev/null || (test -x $(HOME)/.local/bin/uvx && echo $(HOME)/.local/bin/uvx))
-fmt: fmt-prettier fmt-shell fmt-python fmt-nix
+fmt: fmt-prettier fmt-shell fmt-python fmt-nix fmt-sync-docs
@echo "==> All formatting complete!"
-fmt-check: fmt-prettier-check fmt-shell-check fmt-python-check fmt-nix-check
+fmt-check: fmt-prettier-check fmt-shell-check fmt-python-check fmt-nix-check fmt-sync-docs-check
@echo "==> All formatting checks passed!"
fmt-prettier:
@@ -92,3 +92,9 @@ else
exit 1; \
fi
endif
+
+fmt-sync-docs:
+ @./scripts/sync_system_prompt_docs.sh
+
+fmt-sync-docs-check:
+ @./scripts/sync_system_prompt_docs.sh check
diff --git a/scripts/sync_system_prompt_docs.sh b/scripts/sync_system_prompt_docs.sh
new file mode 100755
index 0000000000..3ec1a19ee9
--- /dev/null
+++ b/scripts/sync_system_prompt_docs.sh
@@ -0,0 +1,57 @@
+#!/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
+extract_current_section() {
+ sed -n '//,//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
+ {
+ # Print everything up to and including BEGIN marker
+ sed -n '1,//p' "$DOCS_FILE"
+ echo ""
+ generate_section
+ echo ""
+ # Print END marker and everything after
+ sed -n '//,$p' "$DOCS_FILE"
+ } >"$DOCS_FILE.tmp"
+ mv "$DOCS_FILE.tmp" "$DOCS_FILE"
+ echo "Updated $DOCS_FILE"
+fi
diff --git a/src/node/services/systemMessage.ts b/src/node/services/systemMessage.ts
index 6817c02bad..e021cbac79 100644
--- a/src/node/services/systemMessage.ts
+++ b/src/node/services/systemMessage.ts
@@ -15,10 +15,6 @@ import { getAvailableTools } from "@/common/utils/tools/toolDefinitions";
// NOTE: keep this in sync with the docs/models.md file
-// The PRELUDE is intentionally minimal to not conflict with the user's instructions.
-// mux is designed to be model agnostic, and models have shown large inconsistency in how they
-// follow instructions.
-
function sanitizeSectionTag(value: string | undefined, fallback: string): string {
const normalized = (value ?? "")
.toLowerCase()
@@ -36,9 +32,14 @@ function buildTaggedSection(
const tag = sanitizeSectionTag(rawTagValue, fallback);
return `\n\n<${tag}>\n${content}\n${tag}>`;
}
+
+// #region SYSTEM_PROMPT_DOCS
+// The PRELUDE is intentionally minimal to not conflict with the user's instructions.
+// mux is designed to be model agnostic, and models have shown large inconsistency in how they
+// follow instructions.
const PRELUDE = `
-You are a coding agent.
+You are a coding agent called Mux. You may find information about yourself here: https://mux.coder.com/.
Your Assistant messages display in Markdown with extensions for mermaidjs and katex.
@@ -52,6 +53,12 @@ When creating mermaid diagrams:
Use GitHub-style \`/\` tags to create collapsible sections for lengthy content, error traces, or supplementary information. Toggles help keep responses scannable while preserving detail.
+
+
+When the user asks you to remember something:
+- If it's about the general codebase: encode that lesson into the project's AGENTS.md file, matching its existing tone and structure.
+- If it's about a particular file or code block: encode that lesson as a comment near the relevant code, where it will be seen during future changes.
+
`;
@@ -70,6 +77,7 @@ You are in a git worktree at ${workspacePath}
`;
}
+// #endregion SYSTEM_PROMPT_DOCS
/**
* Get the system directory where global mux configuration lives.