diff --git a/.agents/references/terminology.md b/.agents/references/terminology.md index 8c3dd2038..edf662704 100644 --- a/.agents/references/terminology.md +++ b/.agents/references/terminology.md @@ -4,6 +4,8 @@ Use this glossary everywhere you write about Warp. Keep definitions short, concr For the summary of the most critical terms (core features, Oz terms, terms to avoid), see the [Terminology standards](../../AGENTS.md#terminology-standards) section of AGENTS.md. This file is the full canonical reference. +> **Product name variables**: Product names are defined in `src/data/vars.ts`. When writing new content, use `{VARS.WARP_AGENT_CLI}` (body prose) or `{{WARP_AGENT_CLI}}` (frontmatter) rather than hardcoding product names. See the ["Content variables" section of AGENTS.md](../../AGENTS.md#content-variables) for full usage instructions. + ## Core product terms - **Agent** / **Agents** — Warp's AI feature for turning natural language into actions (answers, commands, code changes, and workflows). diff --git a/.agents/skills/draft_docs/SKILL.md b/.agents/skills/draft_docs/SKILL.md index 8d93f9e5a..41fccc5a5 100644 --- a/.agents/skills/draft_docs/SKILL.md +++ b/.agents/skills/draft_docs/SKILL.md @@ -85,6 +85,8 @@ Use source code to verify technical behavior, understand feature implementation, These rules are frequently violated by agents. Apply them carefully during drafting: +- **Product name variables** — For any product name in `src/data/vars.ts`, use the variable instead of the hardcoded string. Add `import { VARS } from '@data/vars';` immediately after the frontmatter closing `---`. Use `{VARS.KEY}` in MDX prose (e.g. `{VARS.WARP_AGENT_CLI}` not "Oz CLI"). Use `{{TOKEN}}` directly in frontmatter YAML values (e.g. `title: "{{WARP_AGENT_CLI}} reference"`). Key vars: `WARP_AGENT_CLI`, `WARP_AUTOMATION_PLATFORM`, `WEB_APP`, `WEB_APP_URL`, `DASHBOARD`, `AGENT_MODE`, `WARP_DRIVE`. See `src/data/vars.ts` for the full list. + - **Sentence case for all headings (H1–H4)** — Capitalize only the first word and proper feature names. ✅ `## How it works` ❌ `## How It Works` - **Descriptive, specific headings** — Beyond correct case, a heading should name the specific topic so readers and agents can scan the page and extract a self-contained answer. ✅ `## How key type affects billing and GitHub access` ❌ `## More details` - **Bold + dash format for list items** — `* **Term** - Description`, not `* Term: Description` @@ -122,6 +124,7 @@ Before presenting the draft, verify against the quality checklist in `AGENTS.md` - [ ] Instructions include expected outcomes - [ ] Procedures are scannable: dense sections are split into numbered steps, short bullets, or concise subsections - [ ] UI surfaces and product terms use canonical names from `.agents/references/terminology.md` +- [ ] Product names with a corresponding entry in `src/data/vars.ts` use the variable syntax (`{VARS.KEY}` in prose, `{{TOKEN}}` in frontmatter) — not hardcoded strings - [ ] If AEO-driven, the draft follows the AEO brief, uses source vocabulary naturally, and avoids duplicative or junk-drawer coverage - [ ] Images have descriptive alt text diff --git a/.agents/skills/draft_feature_doc/SKILL.md b/.agents/skills/draft_feature_doc/SKILL.md index 87b94d73e..b4233c95f 100644 --- a/.agents/skills/draft_feature_doc/SKILL.md +++ b/.agents/skills/draft_feature_doc/SKILL.md @@ -9,7 +9,7 @@ Draft a feature documentation page that combines conceptual and procedural conte ## Workflow -Follow the workflow in `.warp/skills/draft_docs/SKILL.md`, using the **feature-doc template** at `.warp/templates/feature-doc.md`. +Follow the workflow in `.agents/skills/draft_docs/SKILL.md`, using the **feature-doc template** at `.agents/templates/feature-doc.md`. ## Content type rules @@ -31,6 +31,12 @@ All headings (H1–H4) must use **sentence case**: capitalize only the first wor - ❌ `## Configuring Your Environment` - ❌ `## Agent Mode Settings` +## Product name variables + +For any product name in `src/data/vars.ts`, use the variable — never hardcode the string. The template already includes the `[VARS]` instruction block that shows exactly where to add the import. Key reminder: +- Prose: `{VARS.WARP_AGENT_CLI}` (not "Oz CLI") +- Frontmatter title/description: `{{WARP_AGENT_CLI}}` + ## Existing examples Read 2-3 of these strong examples to match the existing pattern: diff --git a/.agents/skills/review-docs-pr/SKILL.md b/.agents/skills/review-docs-pr/SKILL.md index 6a4b46b57..a4d823fd7 100644 --- a/.agents/skills/review-docs-pr/SKILL.md +++ b/.agents/skills/review-docs-pr/SKILL.md @@ -26,7 +26,8 @@ Focus on: 3. **Content quality**: Check for clarity, accuracy, proper frontmatter, and appropriate use of headers/lists. 4. **Code snippets**: Verify that any code examples, commands, or configuration snippets are correct and will work as documented. If you're unsure about technical details, use the `answer_question` skill to verify against the docs or search the source code. 5. **Astro Starlight structure**: Verify `src/sidebar.ts` updates if files were added, moved, or renamed, and that redirects are added to vercel.json (redirects) when needed. -6. **AEO/source-data fit**: For docs changes that target AEO, SEO, Peec recommendations, AI search prompts, or content gaps, check whether the PR has a clear source-data rationale, uses query vocabulary naturally, avoids junk-drawer coverage, and updates or links existing docs instead of creating duplicative content. +6. **Product name variables**: Check whether any product names with a corresponding entry in `src/data/vars.ts` are hardcoded as literal strings instead of using `{VARS.KEY}` (prose) or `{{TOKEN}}` (frontmatter). Key strings to watch for: "Oz CLI", "Oz web app", "oz.warp.dev", "Oz dashboard", "Oz run". Flag as `⚠️ [IMPORTANT]` if a new file adds these without using the variable system. For existing files, flag as `💡 [SUGGESTION]`. +7. **AEO/source-data fit**: Provide actionable, constructive feedback. Focus on documentation quality issues, not code bugs. diff --git a/.agents/skills/style_lint/SKILL.md b/.agents/skills/style_lint/SKILL.md index da2dcce4b..ae442c1f3 100644 --- a/.agents/skills/style_lint/SKILL.md +++ b/.agents/skills/style_lint/SKILL.md @@ -60,6 +60,7 @@ python3 .agents/skills/style_lint/style_lint.py --all --fix --create-pr - **Deprecated terminology**: "whitelist" (→ "allowlist"), "blacklist"/"blocklist" (→ "denylist") - **External product names**: "Github" (→ "GitHub"), "github actions" (→ "GitHub Actions"), "MacOS" (→ "macOS"), "A.I." (→ "AI") - **Unrecognized terms** (warning): Bolded terms that look like product names but aren't in `terminology.md`. Flags candidates for glossary addition — not errors, just suggestions. +- **Hardcoded product name strings**: Product name strings that have a corresponding key in `src/data/vars.ts` but appear as literal text rather than variable syntax. Reports instances of known strings like "Oz CLI", "Oz web app", "oz.warp.dev", "Oz dashboard", "Oz run" (any value currently in `src/data/vars.ts`) in body prose and frontmatter. These are flagged as `⚠️ [IMPORTANT]` in PR context and reported (not auto-fixed) — they should use `{VARS.KEY}` in prose and `{{TOKEN}}` in frontmatter. ## Auto-fix behavior diff --git a/.agents/skills/style_lint/style_lint.py b/.agents/skills/style_lint/style_lint.py index e5b29eac7..d6169a298 100644 --- a/.agents/skills/style_lint/style_lint.py +++ b/.agents/skills/style_lint/style_lint.py @@ -71,6 +71,20 @@ (r"\bblocklist\b", "Use 'denylist'"), ] +# Rename-sensitive product name strings that should use src/data/vars.ts variables +# instead of being hardcoded. Keep this list in sync with vars.ts: only include +# entries whose values are expected to change at a product rename. Stable feature +# names (AGENT_MODE, WARP_DRIVE, etc.) are intentionally excluded. +# +# Each entry: (literal_string, var_key, suggestion) +RENAME_SENSITIVE_VAR_STRINGS: List[Tuple[str, str, str]] = [ + ("Oz CLI", "WARP_AGENT_CLI", "{VARS.WARP_AGENT_CLI} in prose or {{WARP_AGENT_CLI}} in frontmatter"), + ("Oz web app", "WEB_APP", "{VARS.WEB_APP} in prose or {{WEB_APP}} in frontmatter"), + ("oz.warp.dev", "WEB_APP_URL", "{VARS.WEB_APP_URL} in prose or {{WEB_APP_URL}} in frontmatter"), + ("Oz dashboard", "DASHBOARD", "{VARS.DASHBOARD} in prose or {{DASHBOARD}} in frontmatter"), + ("Oz run", "PLATFORM_RUN", "{VARS.PLATFORM_RUN} in prose or {{PLATFORM_RUN}} in frontmatter"), +] + # Oz terms to avoid (case-insensitive patterns) OZ_TERMS_TO_AVOID = [ (r"\bagent identities\b", "Use 'agents' or 'cloud agents' unless referring to legacy API names in code"), @@ -92,7 +106,7 @@ DEFAULT_SLACK_CHANNEL = os.environ.get("GROWTH_DOCS_SLACK_CHANNEL_ID", "") -TERMINOLOGY_FILE = Path(".warp/references/terminology.md") +TERMINOLOGY_FILE = Path(".agents/references/terminology.md") STANDARD_SCREENSHOT_WIDTHS = {"300px", "350px", "375px", "563px"} @@ -852,6 +866,36 @@ def check_unrecognized_terms(lines: List[str], filepath: str, glossary: set) -> return issues +def check_hardcoded_vars(lines: List[str], filepath: str) -> List[Issue]: + """Flag hardcoded product name strings that should use the vars system. + + Strings listed in RENAME_SENSITIVE_VAR_STRINGS are expected to change at + product rename time. Using them as literals (instead of {VARS.KEY} in prose + or {{TOKEN}} in frontmatter) means they won't update when vars.ts changes. + + Skips fenced code blocks and inline code spans so that CLI examples like + `oz.warp.dev` in a code fence are not flagged. + """ + issues = [] + in_code_block = False + for i, line in enumerate(lines, 1): + if line.strip().startswith("```"): + in_code_block = not in_code_block + continue + if in_code_block: + continue + # Strip inline code spans so backtick-wrapped references are not flagged + prose_line = re.sub(r"`[^`]+`", "", line) + for literal, var_key, suggestion in RENAME_SENSITIVE_VAR_STRINGS: + if literal in prose_line: + issues.append(Issue( + filepath, i, "hardcoded-var", + f'Hardcoded "{literal}" should use {suggestion} (see src/data/vars.ts)', + "warning", + )) + return issues + + # Cache glossary terms once at module level _glossary_cache: Optional[set] = None @@ -880,6 +924,7 @@ def run_all_checks(filepath: Path) -> List[Issue]: issues.extend(check_product_casing(lines, str(filepath))) issues.extend(check_oz_terms(lines, str(filepath))) issues.extend(check_deprecated_terms(lines, str(filepath))) + issues.extend(check_hardcoded_vars(lines, str(filepath))) issues.extend(check_unrecognized_terms(lines, str(filepath), _get_glossary())) return issues diff --git a/.agents/templates/conceptual.md b/.agents/templates/conceptual.md index 6cd6158a6..998030500 100644 --- a/.agents/templates/conceptual.md +++ b/.agents/templates/conceptual.md @@ -1,9 +1,14 @@ --- -title: [Feature or concept name — sentence case. Title convention: noun or "About [subject]". The title field renders as the page H1; do not add a separate H1 in the body.] +title: [Feature or concept name — sentence case. Title convention: noun or "About [subject]". The title field renders as the page H1; do not add a separate H1 in the body. + Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] description: >- [1-2 sentences: what the concept/feature is + why it matters. - Write as a standalone summary for search results. Lead with user benefit.] + Write as a standalone summary for search results. Lead with user benefit. + Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] [Opening paragraph: What this feature/concept is and its primary benefit. 1-3 sentences. Lead with what the user gains from understanding this.] diff --git a/.agents/templates/faq.md b/.agents/templates/faq.md index a1e32ac4a..428a8d8b7 100644 --- a/.agents/templates/faq.md +++ b/.agents/templates/faq.md @@ -1,8 +1,12 @@ --- description: >- [1-2 sentences: what topic area these FAQs cover. - Example: "Answers to common questions about cloud agents, billing, and environments."] + Example: "Answers to common questions about cloud agents, billing, and environments." + Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] # [Title — sentence case. Title convention: "[Feature] FAQs" or "Frequently asked questions"] diff --git a/.agents/templates/feature-doc.md b/.agents/templates/feature-doc.md index 01fe19a84..4f3d24cac 100644 --- a/.agents/templates/feature-doc.md +++ b/.agents/templates/feature-doc.md @@ -1,8 +1,13 @@ --- description: >- [1-2 sentences: what the feature does + primary user benefit. - Lead with the benefit, include key terms for SEO.] + Lead with the benefit, include key terms for SEO. + Use {{TOKEN}} syntax here for any product names that have a var in src/data/vars.ts. + Example: "Use the {{WARP_AGENT_CLI}} to run agents."] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] # [Feature name — sentence case, capitalize only the first word and proper feature names] diff --git a/.agents/templates/guide-page.md b/.agents/templates/guide-page.md index 01ad20242..31c93e133 100644 --- a/.agents/templates/guide-page.md +++ b/.agents/templates/guide-page.md @@ -10,6 +10,8 @@ description: >- [AEO GUIDANCE: If this guide is based on Peec, answer-engine prompts, search-query data, or AEO goals, create an AEO brief first using `.agents/skills/aeo_brief/SKILL.md`. Use the brief to preserve high-intent vocabulary naturally, translate awkward source-data phrasing into developer-friendly docs language, and decide whether this should be a new guide or an update to an existing page.] import VideoEmbed from '@components/VideoEmbed.astro'; +{/* VARS: Also add the line below if this guide references product names from src/data/vars.ts. Then use {VARS.KEY} in prose. Use {{TOKEN}} in frontmatter YAML values above. See AGENTS.md → Content variables. */} +{/* import { VARS } from '@data/vars'; */} diff --git a/.agents/templates/procedural.md b/.agents/templates/procedural.md index ea740663a..d74281967 100644 --- a/.agents/templates/procedural.md +++ b/.agents/templates/procedural.md @@ -1,8 +1,12 @@ --- description: >- [1-2 sentences: what the reader will accomplish. - Task-oriented: "Create and manage X" or "Configure Y for Z."] + Task-oriented: "Create and manage X" or "Configure Y for Z." + Use {{TOKEN}} syntax here for any product names that have a var in src/data/vars.ts.] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] # [Task-oriented title — sentence case. Title convention: gerund, e.g., "Configuring X" or "Managing X"] diff --git a/.agents/templates/quickstart.md b/.agents/templates/quickstart.md index 1cb9d3628..771b52dab 100644 --- a/.agents/templates/quickstart.md +++ b/.agents/templates/quickstart.md @@ -1,8 +1,12 @@ --- description: >- [1-2 sentences: what the reader will accomplish + time estimate. - Example: "Learn how to run your first cloud agent in ~10 minutes."] + Example: "Learn how to run your first cloud agent in ~10 minutes." + Use {{TOKEN}} syntax here for any product names that have a var in src/data/vars.ts.] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] # [Descriptive title — sentence case. Title convention: "[Feature] quickstart" or "Quickstart for [product]". Do NOT use a bare "Quickstart" — include the feature name.] diff --git a/.agents/templates/reference.md b/.agents/templates/reference.md index 01a5eea76..86205039b 100644 --- a/.agents/templates/reference.md +++ b/.agents/templates/reference.md @@ -1,8 +1,12 @@ --- description: >- [1-2 sentences: what is documented and how to use this reference. - Example: "Use the Oz CLI to run, configure, and manage agents from the terminal."] + Example: "Use the {{WARP_AGENT_CLI}} to run, configure, and manage agents from the terminal." + Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] # [Title — sentence case. Title convention: noun describing contents, e.g., "CLI commands", "Keyboard shortcuts"] diff --git a/.agents/templates/troubleshooting.md b/.agents/templates/troubleshooting.md index ea91da9ec..573d1b178 100644 --- a/.agents/templates/troubleshooting.md +++ b/.agents/templates/troubleshooting.md @@ -1,8 +1,12 @@ --- description: >- [1-2 sentences describing common issues covered on this page. - Example: "Solutions for common issues with cloud agents, environments, and integrations."] + Example: "Solutions for common issues with cloud agents, environments, and integrations." + Use {{TOKEN}} syntax for any product names in src/data/vars.ts.] --- +[VARS: Add this line immediately after the closing --- above if this page references any product names from src/data/vars.ts. Then use {VARS.KEY} for those names in the prose below. +`import { VARS } from '@data/vars';` +See AGENTS.md → Content variables for the full variable list and usage rules.] # [Title — sentence case. Title convention: "Troubleshooting [feature]" or "Known issues with [feature]"] diff --git a/AGENTS.md b/AGENTS.md index c6656f517..757975d9c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,7 +15,7 @@ This guide establishes standards for writing Warp documentation. It covers voice - **Confident without jargon**: Explain technical concepts clearly without oversimplifying ### Language guidelines -- Use consistent terminology throughout (see [Terminology standards](#terminology-standards) and the full glossary in `.warp/references/terminology.md`) +- Use consistent terminology throughout (see [Terminology standards](#terminology-standards) and the full glossary in `.agents/references/terminology.md`) - Em dashes are acceptable for occasional variation in narrative/conceptual text, but use sparingly - Never use em dashes in procedural or instructional text @@ -590,7 +590,7 @@ Each template includes inline HTML comments explaining what to put in each secti ## Terminology standards -Use these terms consistently throughout all documentation. For the full canonical glossary with usage notes, see `.warp/references/terminology.md`. +Use these terms consistently throughout all documentation. For the full canonical glossary with usage notes, see `.agents/references/terminology.md`. ### Core features @@ -675,6 +675,41 @@ Product feature names retain their standard capitalization. Match the exact casi - **Settings** (capitalized when referring to the Settings panel) - **Command Palette** (capitalized) +## Content variables +Product names and key strings are defined in `src/data/vars.ts` as the `VARS` object. Updating a value there propagates it to every page that uses the variable — both frontmatter and body prose — on the next build. This makes future renames a one-line change. +### Option A — body prose (MDX imports) +After the closing `---` of the frontmatter block (not inside it), add the import as the first line of the file body. Then use `{VARS.KEY}` inline in prose. TypeScript catches typos at compile time. +```mdx +--- +title: "{{WARP_AGENT_CLI}} reference" +description: "Use the {{WARP_AGENT_CLI}} to run and manage agents." +--- +import { VARS } from '@data/vars'; + +Use the {VARS.WARP_AGENT_CLI} to run agents from the command line. +``` +Note: this example also shows Option B in the frontmatter (`{{WARP_AGENT_CLI}}`). Both can appear in the same file — Option B covers the frontmatter YAML, Option A covers the body prose. +### Option B — frontmatter (Vite transform) +Use `{{TOKEN}}` placeholders directly in frontmatter YAML values (`title`, `description`, `sidebar.label`, etc.). The `warp-vars-transform` Vite plugin substitutes them before any parser runs. +```yaml +--- +title: Getting started with {{WARP_AGENT_CLI}} +description: Learn how to use the {{WARP_AGENT_CLI}} to run and manage agents. +--- +``` +The build fails with a clear error if a token is unrecognized — for example, `{{WARP_AGNT_CLI}}` in frontmatter would surface as an unresolved token error. Validation applies to frontmatter only; body prose may legitimately contain `{{...}}` patterns as code examples. +### When to use vars +Use a variable for: +- Product and platform names that have changed before or are likely to change (e.g., `WARP_AGENT_CLI`, `WEB_APP`, `DASHBOARD`) +- Feature names used in many pages (e.g., `AGENT_MODE`, `WARP_DRIVE`) +- URLs that may change with a rebrand (e.g., `WEB_APP_URL`, `CONTACT_SALES_URL`) +Do **not** create variables for generic stable terms like "terminal," "command," or "repository." +### Adding a new variable +Add the key-value pair to `src/data/vars.ts` only. Both Option A (TypeScript import) and Option B (Vite transform) pick it up automatically. +### Important constraints +- **Do NOT** use `{{TOKEN}}` syntax in MDX body prose — it's only for frontmatter YAML. The Vite plugin runs before MDX parsing; curly-brace expressions in body prose are MDX syntax, not plugin tokens. +- **Do NOT** use `{VARS.x}` expressions in frontmatter — MDX expressions don't evaluate in YAML frontmatter. +- **Key naming rule**: Keys are stable identifiers. Use the future or conceptual name as the key (e.g., `WARP_AGENT_CLI`), not the current brand name that may be retired. The value holds the current string. ## SEO and AEO (AI Engine Optimization) All documentation should be written with search discoverability in mind — both for traditional search engines (Google) and AI engines (ChatGPT, Gemini, Perplexity, Copilot). @@ -705,7 +740,7 @@ Before publishing any documentation, verify: - [ ] Link sentences provide enough context for readers, search engines, and agents to understand the destination - [ ] `VideoEmbed` components include specific `title` props that describe the video content - [ ] Code examples are tested and accurate -- [ ] Terminology and product names match the glossary (`.warp/references/terminology.md`) +- [ ] Terminology and product names match the glossary (`.agents/references/terminology.md`) - [ ] Cross-references to related features are included - [ ] Instructions include expected outcomes after key steps - [ ] First references to prerequisites, tools, or surfaces include inline context diff --git a/astro.config.mjs b/astro.config.mjs index fb9ad8fd4..c579201c9 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -7,6 +7,7 @@ import starlight from '@astrojs/starlight'; import starlightLlmsTxt from 'starlight-llms-txt'; import starlightSidebarTopics from 'starlight-sidebar-topics'; import pageTitleOverride from './src/plugins/page-title-override.ts'; +import { varsTransformPlugin } from './src/plugins/vars-transform.ts'; import vercel from '@astrojs/vercel'; import { sidebarTopics } from './src/sidebar.ts'; import docsMarkdownIntegration from './src/integrations/docs-markdown-integration.js'; @@ -185,4 +186,7 @@ export default defineConfig({ docsMarkdownIntegration(), ], adapter: vercel(), + vite: { + plugins: [varsTransformPlugin()], + }, }); diff --git a/src/data/vars.ts b/src/data/vars.ts new file mode 100644 index 000000000..a9447ff45 --- /dev/null +++ b/src/data/vars.ts @@ -0,0 +1,29 @@ +// src/data/vars.ts +// Single source of truth for product names and key strings. +// To rename: update the value here. Body prose (MDX imports) and +// frontmatter (Vite transform) update automatically on next build. +// +// Key naming rule: keys are stable identifiers, not current brand names. +// Use the future/conceptual name as the key; the value holds the current string. + +export const VARS = { + // Platform — keys named for upcoming Warp branding; values are current Oz names + WARP_AUTOMATION_PLATFORM: "Oz", // value → "Warp Automation Platform" at rename + WARP_AGENT_CLI: "Oz CLI", // value → "Warp Agent CLI" at rename + WEB_APP: "Oz web app", // future name TBD + WEB_APP_URL: "https://oz.warp.dev", // value → "https://app.warp.dev" at rename + DASHBOARD: "Oz dashboard", // future name TBD + PLATFORM_RUN: "Oz run", // future name TBD + + // Feature names (stable — keys and values expected to remain unchanged) + AGENT_MODE: "Agent Mode", + WARP_DRIVE: "Warp Drive", + WARP_TERMINAL: "Warp Terminal", + + // Billing (stable) + CREDITS: "credits", + ADD_ON_CREDITS: "Add-on Credits", + + // URLs + CONTACT_SALES_URL: "https://www.warp.dev/contact-sales", +} as const; diff --git a/src/plugins/vars-transform.ts b/src/plugins/vars-transform.ts new file mode 100644 index 000000000..19401b023 --- /dev/null +++ b/src/plugins/vars-transform.ts @@ -0,0 +1,53 @@ +import type { Plugin } from 'vite'; +import { VARS } from '../data/vars.js'; + +/** + * Vite transform plugin that replaces `{{TOKEN}}` placeholders in .mdx + * frontmatter with values from src/data/vars.ts before any parser sees + * the content. + * + * IMPORTANT: substitution is restricted to the frontmatter block only + * (the content between the opening and closing `---` delimiters). Body + * prose and code fences are left untouched, so authors can document or + * example the `{{TOKEN}}` syntax without it being silently rewritten. + * + * Use `{{TOKEN}}` only in frontmatter YAML (title, description, sidebar.label). + * For MDX body prose, import VARS directly instead: + * import { VARS } from '@data/vars'; + * ...{VARS.WARP_AGENT_CLI}... + * + * If any `{{...}}` tokens remain unresolved in the frontmatter after + * substitution, the build fails with the file path and token name. + */ +export function varsTransformPlugin(): Plugin { + return { + name: 'warp-vars-transform', + transform(code, id) { + if (!id.endsWith('.mdx')) return null; + + // Isolate the frontmatter block (between the opening and closing ---). + // Body prose and code fences are captured in `body` and passed through + // unchanged so {{TOKEN}} examples in documentation are not rewritten. + const frontmatterRegex = /^(---\n[\s\S]*?\n---)(\n?[\s\S]*)$/; + const match = code.match(frontmatterRegex); + if (!match) return null; // No frontmatter — nothing to substitute. + + let frontmatter = match[1]; + const body = match[2]; + + for (const [key, value] of Object.entries(VARS)) { + frontmatter = frontmatter.replaceAll(`{{${key}}}`, value as string); + } + + // Fail the build if any {{TOKEN}} patterns remain unresolved in frontmatter. + const unresolved = frontmatter.match(/\{\{[A-Z_]+\}\}/g); + if (unresolved) { + throw new Error( + `[warp-vars-transform] Unresolved variable token(s) in frontmatter of ${id}: ${unresolved.join(', ')}` + ); + } + + return frontmatter + body; + }, + }; +} diff --git a/tsconfig.json b/tsconfig.json index 0db2ff931..6fcada828 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@components/*": ["src/components/*"] + "@components/*": ["src/components/*"], + "@data/*": ["src/data/*"] } }, "include": [".astro/types.d.ts", "**/*"],