From 716e2de7e318fc29da3207eca3ca229004eb9830 Mon Sep 17 00:00:00 2001 From: rachaelrenk Date: Mon, 20 Jul 2026 20:48:11 +0000 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20add=20product=20name=20variable=20s?= =?UTF-8?q?ystem=20(Phase=201=20=E2=80=94=20infrastructure)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a hybrid variable system that makes future product renames (e.g., Oz → Warp branding) a one-line change in src/data/vars.ts. Changes: - src/data/vars.ts: single source of truth for product names and URLs. Keys are stable future-facing identifiers; values hold current Oz names. - src/plugins/vars-transform.ts: Vite plugin that substitutes {{TOKEN}} placeholders in .mdx frontmatter before any parser runs, with frontmatter-scoped validation to catch typos at build time. - tsconfig.json: adds @data/* path alias alongside @components/*. - astro.config.mjs: registers varsTransformPlugin in vite.plugins. - AGENTS.md: adds 'Content variables' section (before SEO/AEO) with Option A (MDX import) and Option B (frontmatter) usage docs; fixes three .warp/references/terminology.md paths → .agents/references/. - .agents/references/terminology.md: adds note pointing to the vars system and AGENTS.md for usage instructions. No existing .mdx content is modified — infrastructure only. Co-Authored-By: Oz --- .agents/references/terminology.md | 2 ++ AGENTS.md | 36 +++++++++++++++++++++++--- astro.config.mjs | 4 +++ src/data/vars.ts | 29 +++++++++++++++++++++ src/plugins/vars-transform.ts | 42 +++++++++++++++++++++++++++++++ tsconfig.json | 3 ++- 6 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/data/vars.ts create mode 100644 src/plugins/vars-transform.ts 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.md b/AGENTS.md index c6656f517..3f6c26307 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,36 @@ 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 frontmatter block, import `VARS` and use it inline in MDX. TypeScript catches typos at compile time. +```mdx +import { VARS } from '@data/vars'; + +Use the {VARS.WARP_AGENT_CLI} to run agents from the command line. +``` +### 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 +735,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..c7c571fc7 --- /dev/null +++ b/src/plugins/vars-transform.ts @@ -0,0 +1,42 @@ +import type { Plugin } from 'vite'; +import { VARS } from '../data/vars.js'; + +/** + * Vite transform plugin that replaces `{{TOKEN}}` placeholders in .mdx files + * with values from src/data/vars.ts before any parser sees the content. + * + * Use `{{TOKEN}}` syntax only in frontmatter YAML (title, description, + * sidebar.label, etc.). For MDX body prose, import VARS directly instead: + * import { VARS } from '@data/vars'; + * ...{VARS.WARP_AGENT_CLI}... + * + * If any `{{...}}` tokens remain unresolved after substitution, the build + * fails with the file path and unresolved token name to catch typos early. + */ +export function varsTransformPlugin(): Plugin { + return { + name: 'warp-vars-transform', + transform(code, id) { + if (!id.endsWith('.mdx')) return null; + let result = code; + for (const [key, value] of Object.entries(VARS)) { + result = result.replaceAll(`{{${key}}}`, value as string); + } + // Validate only the frontmatter block for unresolved tokens. + // Body prose may legitimately contain {{...}} patterns as code examples + // (e.g., showing secret references), so we only enforce resolution in + // the YAML frontmatter where {{TOKEN}} substitution is actually intended. + const frontmatterMatch = result.match(/^---\n([\s\S]*?)\n---/); + if (frontmatterMatch) { + const frontmatter = frontmatterMatch[1]; + 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 result; + }, + }; +} 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", "**/*"], From 2aec07678be77a871ff0ddbd18bdb6dee37c6422 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:27:15 -0600 Subject: [PATCH 2/5] docs(AGENTS.md): clarify Option A import placement with full file structure example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Show frontmatter → import → prose in one code block so placement is unambiguous. Add note that Options A and B can coexist in the same file. Co-Authored-By: Oz --- AGENTS.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 3f6c26307..757975d9c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -678,12 +678,17 @@ Product feature names retain their standard capitalization. Match the exact casi ## 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 frontmatter block, import `VARS` and use it inline in MDX. TypeScript catches typos at compile time. +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 From 80d31668d21740ca871763c4959d6c9fceaa6726 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:41:58 -0600 Subject: [PATCH 3/5] docs(templates): add product name variable instructions to feature-doc, procedural, and quickstart templates Each template now includes a [VARS] instruction block showing where to add the import statement and how to use {VARS.KEY} in prose and {{TOKEN}} in frontmatter. Co-Authored-By: Oz --- .agents/templates/feature-doc.md | 7 ++++++- .agents/templates/procedural.md | 6 +++++- .agents/templates/quickstart.md | 6 +++++- 3 files changed, 16 insertions(+), 3 deletions(-) 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/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.] From d70605a7c4c4fc9ae80164b48de2ea1b8a48ab5f Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:49:15 -0600 Subject: [PATCH 4/5] docs(templates+skills): extend vars coverage to all templates and key skills Templates: - conceptual.md, faq.md, troubleshooting.md, reference.md: add [VARS] instruction block - guide-page.md: add vars import note alongside existing VideoEmbed import Skills: - draft_docs/SKILL.md: add product name variables rule to critical formatting section (step 6.5) and pre-publish checklist (step 9); this propagates to all draft_* skills that delegate to it - draft_feature_doc/SKILL.md: fix incorrect .warp/ path refs -> .agents/; add explicit Product name variables section - style_lint/SKILL.md: add hardcoded product name strings check to terminology checks section - review-docs-pr/SKILL.md: add product name variables to review focus (step 6) Co-Authored-By: Oz --- .agents/skills/draft_docs/SKILL.md | 3 +++ .agents/skills/draft_feature_doc/SKILL.md | 8 +++++++- .agents/skills/review-docs-pr/SKILL.md | 3 ++- .agents/skills/style_lint/SKILL.md | 1 + .agents/templates/conceptual.md | 9 +++++++-- .agents/templates/faq.md | 6 +++++- .agents/templates/guide-page.md | 2 ++ .agents/templates/reference.md | 6 +++++- .agents/templates/troubleshooting.md | 6 +++++- 9 files changed, 37 insertions(+), 7 deletions(-) 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/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/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/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]"] From a7c1771bb6ef8270fc634e6951915c1b21399e92 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Wed, 22 Jul 2026 12:13:43 -0600 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20address=20Oz=20PR=20review=20?= =?UTF-8?q?=E2=80=94=20restrict=20vars=20substitution=20to=20frontmatter;?= =?UTF-8?q?=20add=20hardcoded-var=20lint=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vars-transform.ts: - Restrict {{TOKEN}} substitution to the frontmatter block only. Previously replaceAll() ran on the entire MDX source, silently rewriting {{TOKEN}} examples in body prose and code fences. Now we extract the frontmatter block (between --- delimiters), substitute only within it, and pass body prose through unchanged. style_lint.py: - Add RENAME_SENSITIVE_VAR_STRINGS constant listing product name strings expected to change at rename time (Oz CLI, Oz web app, oz.warp.dev, etc.) - Add check_hardcoded_vars() function that flags those literal strings in MDX prose/frontmatter (skipping code blocks and inline code spans) - Wire check_hardcoded_vars into run_all_checks() - Fix TERMINOLOGY_FILE path: .warp/references/ -> .agents/references/ Co-Authored-By: Oz --- .agents/skills/style_lint/style_lint.py | 47 ++++++++++++++++++++- src/plugins/vars-transform.ts | 55 +++++++++++++++---------- 2 files changed, 79 insertions(+), 23 deletions(-) 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/src/plugins/vars-transform.ts b/src/plugins/vars-transform.ts index c7c571fc7..19401b023 100644 --- a/src/plugins/vars-transform.ts +++ b/src/plugins/vars-transform.ts @@ -2,41 +2,52 @@ import type { Plugin } from 'vite'; import { VARS } from '../data/vars.js'; /** - * Vite transform plugin that replaces `{{TOKEN}}` placeholders in .mdx files - * with values from src/data/vars.ts before any parser sees the content. + * Vite transform plugin that replaces `{{TOKEN}}` placeholders in .mdx + * frontmatter with values from src/data/vars.ts before any parser sees + * the content. * - * Use `{{TOKEN}}` syntax only in frontmatter YAML (title, description, - * sidebar.label, etc.). For MDX body prose, import VARS directly instead: + * 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 after substitution, the build - * fails with the file path and unresolved token name to catch typos early. + * 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; - let result = code; + + // 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)) { - result = result.replaceAll(`{{${key}}}`, value as string); + frontmatter = frontmatter.replaceAll(`{{${key}}}`, value as string); } - // Validate only the frontmatter block for unresolved tokens. - // Body prose may legitimately contain {{...}} patterns as code examples - // (e.g., showing secret references), so we only enforce resolution in - // the YAML frontmatter where {{TOKEN}} substitution is actually intended. - const frontmatterMatch = result.match(/^---\n([\s\S]*?)\n---/); - if (frontmatterMatch) { - const frontmatter = frontmatterMatch[1]; - 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(', ')}` - ); - } + + // 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 result; + + return frontmatter + body; }, }; }