diff --git a/.agents/references/terminology.md b/.agents/references/terminology.md
index 1520dce2c..2c0199bb6 100644
--- a/.agents/references/terminology.md
+++ b/.agents/references/terminology.md
@@ -67,6 +67,9 @@ For the summary of the most critical terms (core features, Automation Platform t
- **Tab Configs** — Reusable TOML-based tab layout definitions that launch preconfigured terminal sessions.
*Usage note:* Capitalize as a feature name.
+- **Launch Configuration** / **Launch Configurations** — The legacy, YAML-based way to save a configuration of windows, tabs, and panes. Replaced by Tab Configs; existing Launch Configurations still work but aren't being extended.
+ *Usage note:* Capitalize as a feature name, including in headings ("Creating a Launch Configuration"). Use "Tab Configs" for new content.
+
- **Vertical Tabs** — The sidebar-based tab management panel that replaces the horizontal tab bar.
*Usage note:* Capitalize as a feature name.
@@ -108,6 +111,12 @@ For the summary of the most critical terms (core features, Automation Platform t
- **Active AI** — The feature that proactively surfaces fixes and next actions based on terminal errors, inputs, and outputs. Covers Prompt Suggestions, Next Command predictions, and Suggested Code Diffs.
*Usage note:* Always capitalize "Active AI" — it is a proper feature name and the label of the Settings toggle. Write the full capability as **Active AI Recommendations**, matching the page title. Lowercase the following word only when it is a plain common noun rather than part of the name, as in "Active AI features" or "the Active AI toggle".
+- **Computer Use** — The capability that lets agents interact with a desktop environment (screenshots, clicks, typing) inside a sandboxed cloud environment.
+ *Usage note:* Capitalize as a feature name, including in headings ("Enabling Computer Use", "How Computer Use works").
+
+- **Full Terminal Use** — The capability that lets an agent attach to and drive interactive terminal programs (for example `psql`, `vim`, a dev server) by reading live PTY output.
+ *Usage note:* Capitalize as a feature name, including in headings.
+
## Coding terms (Warp features)
- **Code** — Warp's coding experience for agent-assisted changes (editing, diffs, code review).
@@ -275,6 +284,9 @@ Not every "Oz" in the docs is stale. These are deliberate and correct until
- **Automation Platform** — Warp's cloud agent platform, covering environments, integrations, orchestration, self-hosting, and the Agent API/SDK. Renamed from "Oz" on 2026-08-18.
*Usage note:* See "Automation Platform terminology" above for the full entry and the article rule. Always write it as `{VARS.WARP_AUTOMATION_PLATFORM}` / `{{WARP_AUTOMATION_PLATFORM}}`, never as a literal string, so a future rename stays a one-line change.
+- **Direct backend** — The self-hosted worker backend that runs cloud agent tasks directly on the worker host, without Docker or Kubernetes. One of three self-hosting backends alongside the Docker and Kubernetes backends.
+ *Usage note:* Capitalize "Direct" as part of the compound proper term, including in headings ("Start the worker with the Direct backend"); lowercase "backend" as the common noun.
+
## Warp Factories terminology
### The product/instance rule
@@ -344,6 +356,9 @@ Docs match the screen; the fix belongs in the app.
- **command-line** — hyphenated when used as an adjective
- **Git repository** or **repo** — not "git repository" (capitalize "Git")
- **macOS** — not "Mac OS" or "Mac"
+- **Zero Data Retention (ZDR)** — Warp's agreements with contracted LLM providers not to train on or retain customer data. Capitalize as a proper term, including in headings ("Zero Data Retention (ZDR)"); keep the "(ZDR)" acronym on first mention in a section.
+- **SSO (Single Sign-On)** — Authentication through an organization's identity provider (Okta, Microsoft Entra ID, Google Workspace, or any SAML 2.0/OIDC provider). Always capitalize the acronym "SSO"; capitalize "Single Sign-On" when spelled out as the feature name.
+- **Bring Your Own LLM (BYOLLM)** — Warp Enterprise's routing of agent inference through a customer's own cloud infrastructure (AWS Bedrock or Google Cloud via Gemini Enterprise). Capitalize as a proper feature name, including in headings; keep the "(BYOLLM)" acronym on first mention in a section. Distinct from BYOK (Bring Your Own API Key), a self-serve, user-level feature.
## Branded and informal terms
@@ -387,3 +402,6 @@ Docs match the screen; the fix belongs in the app.
- **GitHub App** — GitHub's installation/auth mechanism used for repo access in integrations
- **Linear** — capitalize
- **Slack** — capitalize
+- **Bitbucket Data Center** — Atlassian's official self-hosted Bitbucket edition name (alongside Bitbucket Server and Bitbucket Cloud). Capitalize all three words, including in headings ("Bitbucket Data Center / Server").
+- **Workload Identity Pool and Provider** — GCP's IAM resources for federating external identities. Capitalize as GCP's official term, including in headings.
+- **Workload Identity Federation** — GCP's mechanism for granting external identities access without a long-lived service account key. Capitalize as GCP's official term, including in headings.
diff --git a/.agents/skills/missing_docs/references/feature_surface_map.md b/.agents/skills/missing_docs/references/feature_surface_map.md
index 04b46853a..6a08c96d3 100644
--- a/.agents/skills/missing_docs/references/feature_surface_map.md
+++ b/.agents/skills/missing_docs/references/feature_surface_map.md
@@ -43,6 +43,9 @@ CodeFindReplace -> src/content/docs/code/code-editor/find-and-replace.md
VimCodeEditor -> src/content/docs/code/code-editor/code-editor-vim-keybindings.md
McpServer -> src/content/docs/agents/capabilities/mcp.mdx
McpOauth -> src/content/docs/agents/capabilities/mcp.mdx
+# Factory MCP (the hosted MCP endpoint agents use to work with a factory) is
+# GA and documented on the Factory MCP page and related factories/* pages.
+FactoryMcp -> src/content/docs/factories/factory-mcp.mdx
ImageAsContext -> src/content/docs/agents/local-agents/agent-context/images-as-context.mdx
SelectionAsContext -> src/content/docs/agents/local-agents/agent-context/selection-as-context.mdx
DiffSetAsContext -> src/content/docs/agents/local-agents/agent-context/selection-as-context.mdx
@@ -242,11 +245,6 @@ OscHyperlinks -> src/content/docs/terminal/more-features/files-and-links.mdx
# MCP reference (and the cloud agent MCP schema page).
WellKnownMcpIds -> src/content/docs/reference/cli/mcp-servers.mdx
-# Auto-attaches the Warp-hosted Factory MCP server to agent sessions with no
-# manual setup. Promoted dogfood -> GA; that zero-config behavior is documented
-# in the "Connect and authenticate" section of the Factory MCP page.
-FactoryMcp -> src/content/docs/factories/factory-mcp.mdx
-
## CLI commands -> doc pages
# Top-level Oz CLI commands
diff --git a/.agents/skills/style_lint/SKILL.md b/.agents/skills/style_lint/SKILL.md
index b2c518a52..ce83acc60 100644
--- a/.agents/skills/style_lint/SKILL.md
+++ b/.agents/skills/style_lint/SKILL.md
@@ -85,14 +85,19 @@ This skill checks broader formatting and terminology. The `validate_ui_refs` ski
## Tests
-Three checks have regression suites, because each is a narrow rule where the
-hard part is not firing on legitimate text. Run them after touching any of
-these checks:
+Several checks have regression suites, because each is a narrow rule where the
+hard part is not firing on legitimate text. Run the relevant one(s) after
+touching the corresponding check:
```bash
python3 .agents/skills/style_lint/test_platform_determiner.py
python3 .agents/skills/style_lint/test_factory_proper_noun.py
+python3 .agents/skills/style_lint/test_hardcoded_var_exemptions.py
+python3 .agents/skills/style_lint/test_header_case_sentence_boundary.py
+python3 .agents/skills/style_lint/test_product_casing_word_boundary.py
+python3 .agents/skills/style_lint/test_proper_feature_names_third_party.py
python3 .agents/skills/style_lint/test_tone_checks.py
+python3 .agents/skills/style_lint/test_context_aware_terminology.py
```
## Dependencies
diff --git a/.agents/skills/style_lint/style_lint.py b/.agents/skills/style_lint/style_lint.py
index 4ced5b013..76822ac5f 100644
--- a/.agents/skills/style_lint/style_lint.py
+++ b/.agents/skills/style_lint/style_lint.py
@@ -40,6 +40,16 @@
"Oz CLI", "Oz Platform", "Project Rules",
"Slash Commands", "Terminal Mode", "Universal Input", "Warp Drive",
"Warp Platform", "Automation Platform", "Warp Factories", "Factory MCP",
+ "Computer Use", "Full Terminal Use", "Zero Data Retention", "Single Sign-On",
+ "Blocks", "Block", "Tab Configs", "Tab Config",
+ "Launch Configuration", "Launch Configurations",
+ # Warp's own feature name.
+ "Bring Your Own LLM",
+ # Third-party/technical proper nouns. style_lint's proper-noun protection
+ # is scoped to Warp's own product names by design; these are narrow,
+ # named exceptions rather than a generalization of that scope.
+ "Bitbucket Data Center", "Workload Identity Pool and Provider",
+ "Workload Identity Federation", "Direct backend",
}
# Terminology: wrong → right (case-sensitive checks)
@@ -448,6 +458,22 @@ def _normalize_link_text(text: str) -> str:
return text.strip(" \t\n\r.,:;!?()[]{}\"'")
+def _strip_markdown_destinations(line: str) -> str:
+ """Remove Markdown image/link destination text, keeping the associated
+ human-visible alt/link text in place.
+
+ A destination is a literal filename or URL (e.g. the
+ "Blocklist-with-review-changes.png" in
+ ``),
+ not prose -- casing and deprecated-term checks must not fire on it. The
+ `` / `[text](...)` syntax is identical for images and links,
+ so `](...)` -> `]` strips the destination from both while leaving the
+ bracketed text (and the leading `!` for images) for the surrounding
+ prose checks to scan normally.
+ """
+ return re.sub(r"\]\([^)]*\)", "]", line)
+
+
def _meaningful_words(text: str) -> List[str]:
"""Return lowercase words that carry semantic meaning for comparisons."""
stopwords = {"a", "an", "and", "for", "in", "of", "on", "the", "to", "with", "x"}
@@ -569,6 +595,24 @@ def check_ui_element_backticks(lines: List[str], filepath: str) -> List[Issue]:
return issues
+# Marks the end of a rendered sentence within a single header/line: a
+# `.`/`!`/`?`, optionally followed by a closing quote or bracket. A header can
+# legitimately contain more than one sentence (e.g. a two-question FAQ title
+# or a comment-hidden boundary), and only the very first word of *each*
+# sentence is sentence-initial -- not just the first word of the whole line.
+_SENTENCE_END_RE = re.compile(r'[.!?]["\')\]]*$')
+
+
+def _sentence_start_indices(words: List[str]) -> set:
+ """Return word indices that start a sentence: index 0, plus any word
+ immediately following another word ending in `.`, `!`, or `?`."""
+ starts = {0}
+ for idx in range(1, len(words)):
+ if _SENTENCE_END_RE.search(words[idx - 1]):
+ starts.add(idx)
+ return starts
+
+
def _to_sentence_case(text: str) -> str:
"""Convert header text to sentence case, preserving proper feature names and acronyms."""
skip_words = {"I", "A", "API", "CLI", "SDK", "SSH", "UI", "URL", "PR", "CI", "CD"}
@@ -584,9 +628,11 @@ def _to_sentence_case(text: str) -> str:
for j in range(len(fn_words)):
protected[start + j] = True
+ sentence_starts = _sentence_start_indices(words)
+
result = []
for idx, w in enumerate(words):
- if idx == 0 or protected[idx]:
+ if idx in sentence_starts or protected[idx]:
result.append(w)
continue
clean = re.sub(r"[^a-zA-Z]", "", w)
@@ -615,10 +661,16 @@ def check_header_case(lines: List[str], filepath: str) -> List[Issue]:
words = text.split()
if len(words) < 2:
continue
- # Count capitalized non-first words (excluding proper feature names, short words)
+ # Count capitalized non-first words (excluding proper feature names,
+ # short words, and the first word of any later sentence in the same
+ # header -- a header can contain more than one sentence, e.g. a
+ # two-question FAQ title, and each one gets its own capitalized start).
skip_words = {"I", "A", "API", "CLI", "SDK", "SSH", "UI", "URL", "PR", "CI", "CD"}
+ sentence_starts = _sentence_start_indices(words)
title_case_count = 0
- for w in words[1:]:
+ for idx, w in enumerate(words):
+ if idx in sentence_starts:
+ continue
clean = re.sub(r"[^a-zA-Z]", "", w)
if not clean or clean in skip_words or len(clean) <= 2:
continue
@@ -857,33 +909,68 @@ def check_callout_syntax(lines: List[str], filepath: str) -> List[Issue]:
return issues
+def _word_bounded_pattern(term: str) -> re.Pattern:
+ """Compile a case-sensitive pattern that only matches `term` as a whole
+ word/phrase, not as a substring of a longer token.
+
+ A plain `str.find` (the previous implementation) matched "agent mode"
+ inside "agent model", since "agent mode" is literally a substring of
+ "agent model" -- and corrupted it into "Agent Model" on `--fix`. A plain
+ `\\b...\\b` regex doesn't fully fix this either: `\\b` requires a
+ transition to/from a word character, which fails for terms ending in
+ punctuation (e.g. "A.I." followed by a space or end of line has no such
+ transition). Lookarounds that only check the adjacent character is not a
+ word character work for both cases regardless of the term's own leading
+ or trailing characters.
+ """
+ return re.compile(r"(? List[Issue]:
- """Check for incorrect product name casing."""
+ """Check for incorrect product name casing.
+
+ Tracks complete fenced code blocks (not just a line that happens to start
+ with a backtick) so a wrong-cased term inside a multi-line code fence --
+ e.g. a literal `/Applications/Warp.app/Contents/MacOS/stable` path in a
+ shell snippet -- is left alone as executable/literal text. Markdown
+ image/link destinations are stripped for the same reason: a filename in a
+ link target is not prose, even though the line itself is not code.
+ """
issues = []
+ in_code_block = False
for i, line in enumerate(lines, 1):
- # Skip code blocks
- if line.strip().startswith("```") or line.strip().startswith("`"):
+ stripped = line.strip()
+ if stripped.startswith("```"):
+ in_code_block = not in_code_block
+ continue
+ if in_code_block or stripped.startswith("`"):
continue
- for wrong, (right, note) in PRODUCT_CASING.items():
- # Case-sensitive search
- idx = line.find(wrong)
- while idx != -1:
+ prose_line = _strip_markdown_destinations(line)
+ for pattern, wrong, right, note in _PRODUCT_CASING_PATTERNS:
+ for _ in pattern.finditer(prose_line):
issues.append(Issue(
filepath, i, "product-casing",
f"\"{wrong}\" → \"{right}\" ({note})",
"warning", fixable=True, fix_from=wrong, fix_to=right,
))
- idx = line.find(wrong, idx + len(wrong))
- for wrong, (right, note) in EXTERNAL_CASING.items():
- idx = line.find(wrong)
- while idx != -1:
+ for pattern, wrong, right, note in _EXTERNAL_CASING_PATTERNS:
+ for _ in pattern.finditer(prose_line):
issues.append(Issue(
filepath, i, "external-casing",
f"\"{wrong}\" → \"{right}\" ({note})",
"warning", fixable=True, fix_from=wrong, fix_to=right,
))
- idx = line.find(wrong, idx + len(wrong))
return issues
@@ -914,13 +1001,25 @@ def check_oz_terms(lines: List[str], filepath: str) -> List[Issue]:
def check_deprecated_terms(lines: List[str], filepath: str) -> List[Issue]:
- """Check for deprecated terminology (whitelist/blacklist/blocklist)."""
+ """Check for deprecated terminology (whitelist/blacklist/blocklist).
+
+ Tracks complete fenced code blocks (see check_product_casing) and strips
+ Markdown image/link destinations so a literal filename like
+ "Blocklist-with-review-changes.png" in a link target is not flagged as
+ prose using the deprecated term.
+ """
issues = []
+ in_code_block = False
for i, line in enumerate(lines, 1):
- if line.strip().startswith("```") or line.strip().startswith("`"):
+ stripped = line.strip()
+ if stripped.startswith("```"):
+ in_code_block = not in_code_block
continue
+ if in_code_block or stripped.startswith("`"):
+ continue
+ prose_line = _strip_markdown_destinations(line)
for pattern, suggestion in DEPRECATED_TERMS:
- for m in re.finditer(pattern, line, re.IGNORECASE):
+ for m in re.finditer(pattern, prose_line, re.IGNORECASE):
issues.append(Issue(
filepath, i, "deprecated-term",
f"Avoid \"{m.group(0)}\" → {suggestion}",
@@ -1296,11 +1395,16 @@ def check_factory_proper_noun(lines: List[str], filepath: str) -> List[Issue]:
continue
if any(phrase in line for phrase in FACTORY_ALLOWED_PHRASES):
continue
- # Strip inline code, link targets, and HTML/JSX attributes: a slug like
- # `/factories/factory-as-code/` or an `alt="..."` value is not prose.
+ # Strip inline code, link targets, HTML/JSX attributes, and JSX/MDX
+ # comments: a slug like `/factories/factory-as-code/` or an
+ # `alt="..."` value is not prose, and a `{/* ... */}` comment renders
+ # to nothing, so the text right after one is not mid-sentence just
+ # because the raw source has no space/punctuation there -- the actual
+ # sentence boundary can be hidden inside the stripped comment.
prose = re.sub(r"`[^`]*`", "", line)
prose = re.sub(r"\]\([^)]*\)", "]", prose)
prose = re.sub(r'\w+="[^"]*"', "", prose)
+ prose = re.sub(r"\{/\*.*?\*/\}", "", prose)
for m in FACTORY_BARE.finditer(prose):
before = prose[:m.start()]
after = prose[m.end():]
diff --git a/.agents/skills/style_lint/test_context_aware_terminology.py b/.agents/skills/style_lint/test_context_aware_terminology.py
new file mode 100644
index 000000000..0d1db72c4
--- /dev/null
+++ b/.agents/skills/style_lint/test_context_aware_terminology.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+"""Regression cases for context-aware scanning in check_product_casing and
+check_deprecated_terms (REV-38 rework cycle 3, PR #583).
+
+The formal PR #583 review rejected the PR because `style_lint.py --all`
+still flagged:
+1. `Blocklist` in `code/code-review.mdx:64` -- the literal image filename
+ `Blocklist-with-review-changes.png` inside a Markdown image's link
+ destination, not prose.
+2. `MacOS` in `sending-us-feedback.mdx:75,78` -- literal executable paths
+ (`/Applications/Warp.app/Contents/MacOS/stable`) inside fenced ```bash
+ code blocks.
+
+Both checks only skipped a line that itself started with a backtick/fence
+marker, so a multi-line fenced code block's *interior* lines (which don't
+start with a backtick) and a Markdown link/image destination on an otherwise
+prose line were both scanned as prose. The fix tracks complete fenced code
+block spans and strips Markdown link/image destinations before matching,
+while still scanning the surrounding human-visible prose normally. Run this
+after touching `check_product_casing`, `check_deprecated_terms`, or
+`_strip_markdown_destinations`.
+"""
+import importlib.util
+import pathlib
+import sys
+
+HERE = pathlib.Path(__file__).parent
+spec = importlib.util.spec_from_file_location("style_lint", HERE / "style_lint.py")
+style_lint = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(style_lint)
+
+# (check function, lines, should_flag, description)
+CASES = [
+ # --- deprecated-term (blocklist -> denylist) ---
+ (
+ style_lint.check_deprecated_terms,
+ ["```", "add the user to the blocklist config", "```"],
+ False,
+ "'blocklist' inside a fenced code block must not be flagged",
+ ),
+ (
+ style_lint.check_deprecated_terms,
+ [""],
+ False,
+ "'Blocklist' inside a Markdown image destination must not be flagged",
+ ),
+ (
+ style_lint.check_deprecated_terms,
+ ["Add the user to the blocklist before continuing."],
+ True,
+ "genuine 'blocklist' in prose is still flagged",
+ ),
+ # --- external-casing (MacOS -> macOS), via check_product_casing ---
+ (
+ style_lint.check_product_casing,
+ ["```bash", "RUST_LOG=info /Applications/Warp.app/Contents/MacOS/stable", "```"],
+ False,
+ "'MacOS' inside a fenced code block must not be flagged",
+ ),
+ (
+ style_lint.check_product_casing,
+ ["[Installer](https://example.com/downloads/MacOS/installer.dmg)"],
+ False,
+ "'MacOS' inside a Markdown link destination must not be flagged",
+ ),
+ (
+ style_lint.check_product_casing,
+ ["This build only runs on MacOS."],
+ True,
+ "genuine 'MacOS' in prose is still flagged",
+ ),
+]
+
+
+def main() -> int:
+ failures = 0
+ for check_fn, lines, should_flag, description in CASES:
+ issues = check_fn(lines, "test.mdx")
+ flagged = bool(issues)
+ ok = flagged == should_flag
+ if not ok:
+ failures += 1
+ print(f" [{'PASS' if ok else 'FAIL'}] {description:<70} flagged={flagged}")
+
+ print()
+ if failures:
+ print(f"{failures} of {len(CASES)} cases regressed.")
+ return 1
+ print(f"All {len(CASES)} cases behave correctly.")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/.agents/skills/style_lint/test_factory_proper_noun.py b/.agents/skills/style_lint/test_factory_proper_noun.py
index cb1e264e2..8c0ef4d8e 100644
--- a/.agents/skills/style_lint/test_factory_proper_noun.py
+++ b/.agents/skills/style_lint/test_factory_proper_noun.py
@@ -37,6 +37,8 @@
"definite article plus a capital"),
("Review the Factory metrics before deciding.", True,
"mid-sentence attributive use of the banned form"),
+ ("Review the {/* internal */} Factory metrics before deciding.", True,
+ "mid-sentence even with an adjacent stripped JSX/MDX comment"),
# --- the singular product name, always wrong ---
("A run executing inside a Warp Factory is tracked.", True,
"singular product name mid-sentence"),
@@ -57,6 +59,8 @@
("| **Factory definition** | The definition files |", False, "table-cell-initial"),
("The tab is read-only. Factory owners can still edit it.", False,
"initial after a sentence boundary"),
+ ("Verify before merging. {/* internal reviewer note, strips to nothing */}Factory definitions sync the same way.", False,
+ "sentence-initial after a stripped JSX/MDX comment"),
# --- sanctioned exceptions ---
("Send work through the Factory MCP.", False, "Factory MCP is the shipped feature name"),
("Send work through the Warp Factory MCP.", False,
diff --git a/.agents/skills/style_lint/test_header_case_sentence_boundary.py b/.agents/skills/style_lint/test_header_case_sentence_boundary.py
new file mode 100644
index 000000000..357f66b75
--- /dev/null
+++ b/.agents/skills/style_lint/test_header_case_sentence_boundary.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+"""Regression cases for check_header_case's sentence-boundary handling.
+
+A header is normally sentence case: only the very first word is capitalized.
+But a header can legitimately contain more than one rendered sentence (a
+two-question FAQ title, for example), and each sentence gets its own
+capitalized first word. Before this test existed, `check_header_case` and
+`_to_sentence_case` only ever protected word index 0, so a rework on PR #583
+found this had silently lowercased the second sentence's leading word in a
+two-question FAQ heading ("...yet. How does billing work?" -> "...yet. how
+does billing work?"). Run this after touching `_to_sentence_case`,
+`check_header_case`, or `_sentence_start_indices`.
+"""
+import importlib.util
+import pathlib
+import sys
+
+HERE = pathlib.Path(__file__).parent
+spec = importlib.util.spec_from_file_location("style_lint", HERE / "style_lint.py")
+style_lint = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(style_lint)
+
+# (header text without the leading '#'s, should_flag, description)
+CASES = [
+ ("Enabling Computer Use", False,
+ "single sentence, fully protected proper feature name"),
+ ("My co-workers are using Warp but were not on a Team Together yet. How does billing work?", True,
+ "two-sentence FAQ title; genuine Title Case words (Team, Together) in the first sentence trigger the fix"),
+ ("Is Warp Fully Free? No it Requires a plan", True,
+ "second sentence starts right after a question mark, with a genuine mid-sentence Title Case word (Requires) later in that sentence"),
+]
+
+# (header text, expected fixed text) -- the fix must lowercase genuine
+# mid-sentence Title Case words while preserving the capital that starts the
+# second sentence.
+FIX_CASES = [
+ (
+ "My co-workers are using Warp but were not on a Team Together yet. How does billing work?",
+ "My co-workers are using warp but were not on a team together yet. How does billing work?",
+ ),
+ (
+ "Is Warp Fully Free? No it Requires a plan",
+ "Is warp fully free? No it requires a plan",
+ ),
+]
+
+
+def main() -> int:
+ failures = 0
+ for text, should_flag, description in CASES:
+ line = f"## {text}"
+ issues = style_lint.check_header_case([line], "test.mdx")
+ flagged = bool(issues)
+ ok = flagged == should_flag
+ if not ok:
+ failures += 1
+ print(f" [{'PASS' if ok else 'FAIL'}] {description:<90} flagged={flagged}")
+
+ for text, expected_fixed in FIX_CASES:
+ fixed = style_lint._to_sentence_case(text)
+ ok = fixed == expected_fixed
+ if not ok:
+ failures += 1
+ print(f" [{'PASS' if ok else 'FAIL'}] fix preserves the second sentence's capital: {fixed!r}")
+
+ total = len(CASES) + len(FIX_CASES)
+ print()
+ if failures:
+ print(f"{failures} of {total} cases regressed.")
+ return 1
+ print(f"All {total} cases behave correctly.")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/.agents/skills/style_lint/test_product_casing_word_boundary.py b/.agents/skills/style_lint/test_product_casing_word_boundary.py
new file mode 100644
index 000000000..8687aea95
--- /dev/null
+++ b/.agents/skills/style_lint/test_product_casing_word_boundary.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+"""Regression cases for check_product_casing's word-boundary matching.
+
+`check_product_casing` used to find wrong-casing terms with a plain
+`str.find`, which matches a term as a substring of a longer word. Since
+"agent mode" is literally a substring of "agent model", this corrupted
+"Switch the base agent model" into "Switch the base Agent Model" on
+`--fix` (found during the PR #583 rework, REV-38). A plain `\\b...\\b`
+regex does not fully fix this either: `\\b` requires a transition to/from a
+word character, which fails for terms ending in punctuation (e.g. "A.I."
+followed by a space or end of line has no such transition). The fix uses
+lookarounds that only check the adjacent character is not a word character,
+which handles both cases. Run this after touching `check_product_casing`,
+`_word_bounded_pattern`, `PRODUCT_CASING`, or `EXTERNAL_CASING`.
+"""
+import importlib.util
+import pathlib
+import sys
+
+HERE = pathlib.Path(__file__).parent
+spec = importlib.util.spec_from_file_location("style_lint", HERE / "style_lint.py")
+style_lint = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(style_lint)
+
+CASES = [
+ # (text, should_flag, description)
+ ("Switch the base agent model", False,
+ "'agent mode' must not match inside 'agent model'"),
+ ("Switch the base agent mode", True,
+ "genuine 'agent mode' still flagged"),
+ ("Toggle agent modes for different tasks", False,
+ "'agent mode' must not match inside plural 'agent modes'"),
+ ("This uses A.I. today", True,
+ "'A.I.' followed by a space still flagged despite ending in punctuation"),
+ ("This uses A.I.s today", False,
+ "'A.I.' must not match inside 'A.I.s'"),
+ ("I use Warp Terminal daily", True, "genuine 'Warp Terminal' still flagged"),
+ ("Uses MacOSX for testing", False, "'MacOS' must not match inside 'MacOSX'"),
+ ("Uses MacOS for testing", True, "genuine 'MacOS' still flagged"),
+]
+
+
+def main() -> int:
+ failures = 0
+ for text, should_flag, description in CASES:
+ issues = style_lint.check_product_casing([text], "test.mdx")
+ flagged = bool(issues)
+ ok = flagged == should_flag
+ if not ok:
+ failures += 1
+ print(f" [{'PASS' if ok else 'FAIL'}] {description:<70} flagged={flagged}")
+
+ print()
+ if failures:
+ print(f"{failures} of {len(CASES)} cases regressed.")
+ return 1
+ print(f"All {len(CASES)} cases behave correctly.")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/.agents/skills/style_lint/test_proper_feature_names_third_party.py b/.agents/skills/style_lint/test_proper_feature_names_third_party.py
new file mode 100644
index 000000000..864d380c1
--- /dev/null
+++ b/.agents/skills/style_lint/test_proper_feature_names_third_party.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+"""Regression cases for PROPER_FEATURE_NAMES entries added on PR #583 (REV-38).
+
+`check_header_case` mistakenly flagged and lowercased several correctly
+capitalized proper nouns in headings, because they weren't in
+PROPER_FEATURE_NAMES: Warp's own "Bring Your Own LLM (BYOLLM)" feature name,
+and third-party/technical proper nouns ("Bitbucket Data Center", GCP's
+"Workload Identity Pool and Provider" / "Workload Identity Federation", and
+Warp's own "Direct backend" self-hosting term). style_lint's proper-noun
+protection is scoped to Warp's own product names by design and does not
+generalize to third-party proper nouns -- these are narrow, named exceptions,
+not a broadening of that scope. Run this after touching PROPER_FEATURE_NAMES
+or check_header_case.
+"""
+import importlib.util
+import pathlib
+import sys
+
+HERE = pathlib.Path(__file__).parent
+spec = importlib.util.spec_from_file_location("style_lint", HERE / "style_lint.py")
+style_lint = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(style_lint)
+
+# (header text without the leading '#'s, should_flag, description)
+CASES = [
+ ("Bring Your Own LLM (BYOLLM)", False, "Warp's own BYOLLM feature name"),
+ ('Does Warp support other model routers or "Bring Your Own LLM"?', False,
+ "BYOLLM phrase mid-sentence inside quotes"),
+ ("Bitbucket Data Center / Server", False, "Atlassian's official edition name"),
+ ("Step 1: Create a Workload Identity Pool and Provider", False,
+ "GCP's official IAM resource name"),
+ ("Step 3: Enable Workload Identity Federation in your cloud agent environment", False,
+ "GCP's official federation mechanism name"),
+ ("2. Start the worker with the Direct backend", False,
+ "Warp's own self-hosting backend name"),
+ # A generic Title Case header unrelated to any of these terms must still flag.
+ ("This Is A Generic Title Case Heading", True,
+ "unrelated Title Case header is still caught"),
+]
+
+
+def main() -> int:
+ failures = 0
+ for text, should_flag, description in CASES:
+ line = f"### {text}"
+ issues = style_lint.check_header_case([line], "test.mdx")
+ flagged = bool(issues)
+ ok = flagged == should_flag
+ if not ok:
+ failures += 1
+ print(f" [{'PASS' if ok else 'FAIL'}] {description:<60} flagged={flagged}")
+
+ print()
+ if failures:
+ print(f"{failures} of {len(CASES)} cases regressed.")
+ return 1
+ print(f"All {len(CASES)} cases behave correctly.")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/src/content/docs/agents/capabilities/computer-use/testing-and-recordings.mdx b/src/content/docs/agents/capabilities/computer-use/testing-and-recordings.mdx
index 6155e2b41..eda8dd70c 100644
--- a/src/content/docs/agents/capabilities/computer-use/testing-and-recordings.mdx
+++ b/src/content/docs/agents/capabilities/computer-use/testing-and-recordings.mdx
@@ -85,7 +85,7 @@ An agent walks through a critical user journey, such as the "New run" creation f
Example prompt:
```text
-Build the Oz web app and walk through the entire "New run" creation flow end to end. Exercise every entrypoint into the flow: the primary New run button, the command palette, and any contextual entrypoints. Then step through each stage from opening the New run surface to submitting a run.
+Build the Oz web app and walk through the entire "New run" creation flow end to end. Exercise every entrypoint into the flow: the primary New run button, the Command Palette, and any contextual entrypoints. Then step through each stage from opening the New run surface to submitting a run.
```
This gives you a reproducible, time-stamped clip of the flow that can be archived, diffed across releases, or shared with the team as a baseline.
diff --git a/src/content/docs/agents/cli/input-and-shell-commands.mdx b/src/content/docs/agents/cli/input-and-shell-commands.mdx
index eb256a607..0121bc587 100644
--- a/src/content/docs/agents/cli/input-and-shell-commands.mdx
+++ b/src/content/docs/agents/cli/input-and-shell-commands.mdx
@@ -41,7 +41,7 @@ The [slash commands reference](/agents/cli/reference/#slash-commands) lists ever
Press `↑` with the cursor on the first row of the input to open the history menu.
-* **What's listed** - In agent mode, the menu combines your previous prompts and shell commands in one list, with commands marked by a `!` prefix. In [shell mode](#shell-mode), the menu lists commands only.
+* **What's listed** - In Agent Mode, the menu combines your previous prompts and shell commands in one list, with commands marked by a `!` prefix. In [shell mode](#shell-mode), the menu lists commands only.
* **Preview** - Moving the selection previews each entry in the input and switches the input to the matching mode: recalled commands run as shell commands, and recalled prompts go to the agent.
* **Submit** - `Enter` runs the selection immediately. It doesn't insert it for editing.
* **Dismiss** - `Esc` restores what you had typed. Pressing `↓` past the newest entry does the same.
@@ -71,7 +71,7 @@ Attach images to a prompt so the agent can analyze them:
* **Paste an image** - Copy an image to your clipboard and press `Ctrl+V`.
* **Paste or drop a file path** - Paste the path to an image file, or drag the file onto your terminal window to insert its path. Absolute paths, paths relative to the working directory, and `~` paths all resolve.
-Supported formats are PNG, JPEG, GIF, and WebP. Attaching an image locks the input to agent mode, since images are sent to the agent rather than the shell.
+Supported formats are PNG, JPEG, GIF, and WebP. Attaching an image locks the input to Agent Mode, since images are sent to the agent rather than the shell.
Attached images appear in an attachment bar above the input. Press `Tab` to focus the bar, `Backspace` to remove the selected attachment, and `Esc` to return to the input.
@@ -95,14 +95,14 @@ Voice input in the CLI uses the same transcription service as the Warp app. See
The CLI shows its shortcuts in context, so you rarely need to memorize them:
* **Placeholder hints** - An empty input shows the key triggers for the current mode.
-* **Shortcuts menu** - Type `?` in an empty input to open a shortcuts overview. Its contents adapt to what you're doing: agent mode lists the menu triggers and input history, shell mode shows how to return to agent mode, and extra sections appear during multi-agent sessions or agent-controlled terminal use. Press `Esc`, or start typing, to close it.
+* **Shortcuts menu** - Type `?` in an empty input to open a shortcuts overview. Its contents adapt to what you're doing: Agent Mode lists the menu triggers and input history, shell mode shows how to return to Agent Mode, and extra sections appear during multi-agent sessions or agent-controlled terminal use. Press `Esc`, or start typing, to close it.
## Shell mode
The input is agent-first: by default, pressing `Enter` sends your text to the agent as a prompt. Use shell mode to run a command instead:
1. Press `!` at the start of the input. The prompt marker changes from `>` to `!`, and the statusline below the input shows **Shell mode**.
-2. Run a command. The input returns to agent mode afterward.
+2. Run a command. The input returns to Agent Mode afterward.
To leave shell mode without running a command, press `Esc`, or press `Backspace` at the start of the input. Any text you typed stays in the input.
@@ -118,9 +118,9 @@ Out of the box, the CLI never guesses what your input is: everything goes to the
* **Toggle detection** - Run `/natural-language-detection` to turn detection on or off. The statusline confirms the change, and the setting persists across sessions.
* **Automatic classification** - With detection on, the CLI classifies your input as you type. When the input looks like a shell command (for example, `git status`), the input switches to shell mode, and `Enter` runs it as a command. Everything else is sent to the agent.
-* **Ambiguous input** - Short or ambiguous input stays in agent mode, and a single word switches to shell mode only when it matches a command available in your shell.
+* **Ambiguous input** - Short or ambiguous input stays in Agent Mode, and a single word switches to shell mode only when it matches a command available in your shell.
-The prompt marker and statusline always show the current mode before you press `Enter`. If detection classifies input differently than you intended, press `Esc` to switch back to agent mode, or press `!` at the start of the input to force shell mode.
+The prompt marker and statusline always show the current mode before you press `Enter`. If detection classifies input differently than you intended, press `Esc` to switch back to Agent Mode, or press `!` at the start of the input to force shell mode.
## Long-running and interactive commands
diff --git a/src/content/docs/agents/cli/quickstart.mdx b/src/content/docs/agents/cli/quickstart.mdx
index 5a8846e70..13b369e84 100644
--- a/src/content/docs/agents/cli/quickstart.mdx
+++ b/src/content/docs/agents/cli/quickstart.mdx
@@ -97,7 +97,7 @@ You can run shell commands directly without leaving the CLI.
Type `!` at the start of an empty input to switch to shell mode. The footer shows **Shell mode**. Type a command, such as `git status`, and press `Enter`. To go back to prompting the agent, press `Backspace` on the empty input.
-To run recognized shell commands without the `!` prefix, run `/natural-language-detection` to turn on natural language detection. The CLI then classifies input as you type: recognized commands switch to shell mode, while natural-language prompts stay in agent mode. The prompt marker and statusline show the active mode before you press `Enter`.
+To run recognized shell commands without the `!` prefix, run `/natural-language-detection` to turn on natural language detection. The CLI then classifies input as you type: recognized commands switch to shell mode, while natural-language prompts stay in Agent Mode. The prompt marker and statusline show the active mode before you press `Enter`.
See [Input and shell commands](/agents/cli/input-and-shell-commands/) for long-running commands, interactive programs, and full-screen apps.
diff --git a/src/content/docs/guides/agent-workflows/how-to-review-prs-like-a-senior-dev.mdx b/src/content/docs/guides/agent-workflows/how-to-review-prs-like-a-senior-dev.mdx
index 038bdc03f..2434d7ce5 100644
--- a/src/content/docs/guides/agent-workflows/how-to-review-prs-like-a-senior-dev.mdx
+++ b/src/content/docs/guides/agent-workflows/how-to-review-prs-like-a-senior-dev.mdx
@@ -91,7 +91,7 @@ If you want the agent's findings pre-formatted for rapid scanning, useful for as
```
Review this pull request and format your response for rapid scanning. Follow the structure below.
-### 1. Risk Assessment
+### 1. Risk assessment
**Overall Risk:** HIGH | MEDIUM | LOW
**Complexity:** [Simple | Moderate | Complex | Very Complex]
@@ -100,7 +100,7 @@ Review this pull request and format your response for rapid scanning. Follow the
---
-### 2. Critical Issues
+### 2. Critical issues
_If none, write "None found."_
#### 1. [ISSUE TITLE]
diff --git a/src/content/docs/guides/build-an-app-in-warp/building-warps-input-with-warp.mdx b/src/content/docs/guides/build-an-app-in-warp/building-warps-input-with-warp.mdx
index 6bf2c01d7..24cbb664a 100644
--- a/src/content/docs/guides/build-an-app-in-warp/building-warps-input-with-warp.mdx
+++ b/src/content/docs/guides/build-an-app-in-warp/building-warps-input-with-warp.mdx
@@ -28,7 +28,7 @@ Most people were excited, but engineering resources were stretched thin — focu
So I thought: _“What if I just Warp it?”_
-#### 1. Locating the Git Diff chip code
+#### 1. Locating the Git diff chip code
Inside the universal input, there’s a small Git Diff chip — it shows your current branch and open changes. It was one pixel too tall. That tiny visual bug drove me nuts, so I used Warp to find where it lived.
diff --git a/src/content/docs/guides/configuration/how-to-create-project-rules-for-an-existing-project-astro-typescript-tailwind.mdx b/src/content/docs/guides/configuration/how-to-create-project-rules-for-an-existing-project-astro-typescript-tailwind.mdx
index 2ef3cd46e..1378473cc 100644
--- a/src/content/docs/guides/configuration/how-to-create-project-rules-for-an-existing-project-astro-typescript-tailwind.mdx
+++ b/src/content/docs/guides/configuration/how-to-create-project-rules-for-an-existing-project-astro-typescript-tailwind.mdx
@@ -70,7 +70,7 @@ Share Your Brewfiles is an Astro-based website that allows developers to share a
* `exchangeCodeForAccessToken.ts` - GitHub OAuth token exchange
* `logSearch.json.ts` - Analytics for search functionality
-### Core Library Functions (`src/lib/`)
+### Core library functions (`src/lib/`)
* `generatePersonality.ts` - Complex algorithm that analyzes brewfile packages and assigns personality types (15 different personalities)
* `personalityBuckets.ts` - Defines personality type metadata and descriptions
* `validateBrewfileData.ts` - Data validation for brewfile uploads
@@ -124,7 +124,7 @@ curl "http://localhost:4321/api/getRankedPackages.json"
## Architecture Notes
-### Personality Generation System
+### Personality generation system
The core feature analyzes brewfile packages against a curated dictionary (`labelledBrewfiles.ts`) that categorizes packages by:
- Developer type (Backend, Frontend, DevOps, Security, Data, General)
- Package characteristics (AI tools, organization tools, customization, popularity rank)
@@ -138,7 +138,7 @@ The system calculates percentage distributions and applies complex rules to assi
- Real-time personality generation happens asynchronously after uploads
- GitHub OAuth integration for user authentication
-### Path Alias System
+### Path alias system
Uses TypeScript path mapping with `@/*` pointing to `./src/*` for clean imports.
### Astro Configuration
@@ -147,27 +147,27 @@ Uses TypeScript path mapping with `@/*` pointing to `./src/*` for clean imports.
- Sitemap generation for SEO
- Prefetch enabled for performance
-## Development Environment Setup
+## Development environment setup
### Prerequisites
- Node.js (version compatible with Astro 4)
- Access to Firebase project (config is in source but consider security implications)
- GitHub OAuth app for testing upload functionality
-### Local Development Notes
+### Local development notes
- The site uses server-side rendering so API routes work in development
- Firebase config is currently in source code - be aware of security implications
- GitHub OAuth integration requires valid access tokens for uploads
- Personality generation is computationally expensive with large datasets
-### Custom Tailwind Configuration
+### Custom Tailwind configuration
- Dark theme with custom color palette (`bkg: #111111`)
- Custom accent colors (teal, orange, green, pink, blue variants)
- Marquee animations for scrolling elements
- Responsive typography with fluid scaling
- Container queries support
-## File Structure Navigation
+## File structure navigation
- src/
- pages/
@@ -182,20 +182,20 @@ Uses TypeScript path mapping with `@/*` pointing to `./src/*` for clean imports.
- firebase/ Firebase configuration
-## Common Development Tasks
+## Common development tasks
-### Adding New Personality Types
+### Adding new personality types
1. Update `DeveloperPersonalityType` enum in `src/types/personality.ts`
2. Add detection function in `src/lib/generatePersonality.ts`
3. Update `personalityBuckets.ts` with new personality metadata
4. Add corresponding image to `public/images/`
-### Modifying Package Analysis
+### Modifying package analysis
- Update `labelledBrewfiles.ts` to modify package categorization
- Adjust percentage thresholds in personality detection functions
- Test with different brewfile compositions
-### API Route Development
+### API route development
- All routes in `src/pages/api/` become serverless functions on Vercel
- Use `export const prerender = false;` for dynamic routes
- Handle errors consistently with try/catch blocks
diff --git a/src/content/docs/guides/configuration/how-to-set-up-self-serve-data-analytics-with-skills.mdx b/src/content/docs/guides/configuration/how-to-set-up-self-serve-data-analytics-with-skills.mdx
index 75407b869..0fc27420a 100644
--- a/src/content/docs/guides/configuration/how-to-set-up-self-serve-data-analytics-with-skills.mdx
+++ b/src/content/docs/guides/configuration/how-to-set-up-self-serve-data-analytics-with-skills.mdx
@@ -27,7 +27,7 @@ In this 40-minute livestream, Warp's data team demonstrates the workflow end-to-
-## 1. Install the two Skills
+## 1. Install the two skills
Warp automatically discovers any Skill stored under `.agents/skills/` in your repo, so committing the two directories makes them available to every teammate's Agent runs. Clone the public [warpdotdev/oz-skills](https://github.com/warpdotdev/oz-skills) repo and copy the two Skill directories into your own dbt repo:
diff --git a/src/content/docs/guides/external-tools/github-mcp-summarizing-open-prs-and-creating-gh-issues.mdx b/src/content/docs/guides/external-tools/github-mcp-summarizing-open-prs-and-creating-gh-issues.mdx
index 45178c69f..c27e2ef2b 100644
--- a/src/content/docs/guides/external-tools/github-mcp-summarizing-open-prs-and-creating-gh-issues.mdx
+++ b/src/content/docs/guides/external-tools/github-mcp-summarizing-open-prs-and-creating-gh-issues.mdx
@@ -38,7 +38,7 @@ The GitHub MCP Server lets Warp agents read, write, and automate tasks in your G
---
-### Step 3. Workflow 1 — Summarize all open PRs
+### Step 3. Workflow 1 — summarize all open PRs
Use Warp’s agent to summarize pull requests:
@@ -52,7 +52,7 @@ Perfect for daily PR triage or stand-ups.
---
-### Step 4. Workflow 2 — Create GitHub issues from TODOs
+### Step 4. Workflow 2 — create GitHub issues from TODOs
Use a saved prompt to automate issue creation.
diff --git a/src/content/docs/support-and-community/community/open-source-licenses.mdx b/src/content/docs/support-and-community/community/open-source-licenses.mdx
index f0a5c9b30..b594eb71f 100644
--- a/src/content/docs/support-and-community/community/open-source-licenses.mdx
+++ b/src/content/docs/support-and-community/community/open-source-licenses.mdx
@@ -1247,7 +1247,7 @@ sidebar:
| Windows Terminal | MIT |
| GitHub Desktop | MIT |
-## Full License Text
+## Full license text
```text
Third-Party Licenses for Warp
diff --git a/src/content/docs/support-and-community/privacy-and-security/privacy.mdx b/src/content/docs/support-and-community/privacy-and-security/privacy.mdx
index 18910b0d6..6bbad39ca 100644
--- a/src/content/docs/support-and-community/privacy-and-security/privacy.mdx
+++ b/src/content/docs/support-and-community/privacy-and-security/privacy.mdx
@@ -82,9 +82,9 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `AI Execution Profile: Removed From Denylist` | An item was removed from an AI execution profile denylist |
| `AI Execution Profile: Setting Updated` | An AI execution profile setting was updated |
| `AI Input Not Sent` | The AI input was not sent |
-| `AI Suggested Rule Added` | Clicked the Add Suggested Rule button in the AI blocklist |
+| `AI Suggested Rule Added` | Clicked the Add Suggested Rule button in the AI denylist |
| `AI Suggested Rule Content Changed` | Content changed by the user in the suggested rule dialog |
-| `AI Suggested Rule Edited` | Clicked the Edit Suggested Rule button in the AI blocklist |
+| `AI Suggested Rule Edited` | Clicked the Edit Suggested Rule button in the AI denylist |
| `AI.ProviderCredential.Changed` | A user added or removed a model-provider credential |
| `AIAutonomy.AutoexecutedRequestedCommand` | Autoexecuted an Agent Mode requested command |
| `AIAutonomy.ChangedAgentModeAskUserQuestionPermission` | Changed Agent Mode permission for asking user questions |
@@ -102,7 +102,7 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `Agent Mode Setup Banner Accepted` | Agent Mode setup banner accepted |
| `Agent Mode Setup Banner Dismissed` | Agent Mode setup banner dismissed |
| `Agent Mode Setup Project Scoped Rules Action` | User clicked a button in the Agent Mode setup project scoped rules step |
-| `Agent Mode.Setup Codebase Context Action` | User clicked a button in the Agent Mode setup codebase context step |
+| `Agent Mode.Setup Codebase Context Action` | User clicked a button in the Agent Mode setup Codebase Context step |
| `Agent Predict` | Completed an Agent Predict prediction |
| `Agent Toolbar Dismissed` | User dismissed the use-agent toolbar |
| `AgentManagement.AgentTypeSelectorOpened` | User opened the agent type selector from agent management |
@@ -114,9 +114,9 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `AgentManagement.ConversationOpened` | User opened a conversation |
| `AgentManagement.DetailsPanelContinueLocally` | User clicked Continue locally in the details panel |
| `AgentManagement.DetailsViewed` | User clicked View details |
-| `AgentManagement.DismissSetupGuide` | User dismissed the ambient agent setup guide |
+| `AgentManagement.DismissSetupGuide` | User dismissed the cloud agent setup guide |
| `AgentManagement.FilterChanged` | User changed a filter in the management view |
-| `AgentManagement.OpenSetupGuide` | User opened the ambient agent setup guide |
+| `AgentManagement.OpenSetupGuide` | User opened the cloud agent setup guide |
| `AgentManagement.SessionLinkCopied` | User copied a session link |
| `AgentManagement.SetupGuideDocsLink` | User clicked a docs URL in the setup guide |
| `AgentManagement.SetupGuideStepCopy` | User copied a workflow step from the setup guide |
@@ -144,21 +144,21 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `AgentMode.Code.SuggestedEditAcceptClicked` | User selected Accept for a code diff suggestion in Agent Mode |
| `AgentMode.Code.SuggestedEditReceived` | Agent Mode suggested a code edit |
| `AgentMode.Code.SuggestedEditResolved` | Agent Mode pending code edit suggestion resolved |
-| `AgentMode.CreatedAIBlock` | Created an AI block in agent mode |
+| `AgentMode.CreatedAIBlock` | Created an AI block in Agent Mode |
| `AgentMode.Error` | Received an error when getting Agent Mode response |
| `AgentMode.ExecutedWarpDrivePrompt` | Executed a saved prompt. |
| `AgentMode.ExitedShellProcess` | An agent-requested command caused the shell process to exit |
| `AgentMode.FileGlob.Failed` | The file glob tool failed to complete |
| `AgentMode.FileGlob.Succeeded` | The file glob tool completed successfully |
-| `AgentMode.FullEmbedCodebaseContextSearch.Failed` | Failed to search full embed codebase context |
-| `AgentMode.FullEmbedCodebaseContextSearch.Success` | Successfully searched full embed codebase context |
+| `AgentMode.FullEmbedCodebaseContextSearch.Failed` | Failed to search full embed Codebase Context |
+| `AgentMode.FullEmbedCodebaseContextSearch.Success` | Successfully searched full embed Codebase Context |
| `AgentMode.Grep.Failed` | The grep tool failed to complete |
| `AgentMode.Grep.Succeeded` | The grep tool completed successfully |
| `AgentMode.MerkleTreeSnapshot.Diff.Failed` | Failed to diff merkle tree snapshot |
| `AgentMode.MerkleTreeSnapshot.Diff.Success` | Successfully diffed merkle tree snapshot |
| `AgentMode.MerkleTreeSnapshot.Rebuild.Failed` | Failed to rebuild merkle tree from snapshot |
| `AgentMode.MerkleTreeSnapshot.Rebuild.Success` | Successfully rebuilt merkle tree from snapshot |
-| `AgentMode.OpenedCitation` | Opened a citation that was surfaced in agent mode |
+| `AgentMode.OpenedCitation` | Opened a citation that was surfaced in Agent Mode |
| `AgentMode.Orchestration.AgentProposedConfig` | An agent-authored orchestration config snapshot first became visible to the user on a plan card |
| `AgentMode.Orchestration.Entered` | Orchestration was activated in a conversation via /orchestrate or a run_agents confirmation card surfacing. Plan-card entries are tracked separately via AgentProposedConfig + PlanConfigApprovalToggled. |
| `AgentMode.Orchestration.PillBarInteraction` | User interacted with the orchestration pill bar (switch, pin, open in pane/tab, stop, kill, etc.) |
@@ -170,10 +170,10 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `AgentMode.RequestRetrySucceeded` | Agent Mode request succeeded after retrying following an initial error |
| `AgentMode.SetupCreateEnvironmentAction` | User clicked a button in the Agent Mode setup create environment step |
| `AgentMode.SurfacedCitations` | Agent mode used and cited external sources that were used in its response |
-| `AgentMode.SyncCodebaseContext.BuildTree.Failed` | Failed to build merkle tree for codebase context |
-| `AgentMode.SyncCodebaseContext.BuildTree.Success` | Successfully built merkle tree for codebase context |
-| `AgentMode.SyncCodebaseContext.Failed` | Failed to sync codebase context |
-| `AgentMode.SyncCodebaseContext.Success` | Successfully synced codebase context |
+| `AgentMode.SyncCodebaseContext.BuildTree.Failed` | Failed to build merkle tree for Codebase Context |
+| `AgentMode.SyncCodebaseContext.BuildTree.Success` | Successfully built merkle tree for Codebase Context |
+| `AgentMode.SyncCodebaseContext.Failed` | Failed to sync Codebase Context |
+| `AgentMode.SyncCodebaseContext.Success` | Successfully synced Codebase Context |
| `AgentMode.ToggleAutoDetectionSetting` | Toggled the setting that enables or disables natural language auto-detection in the input. |
| `AgentNotification.Shown` | An agent notification was shown to the user (toast or mailbox) |
| `AgentTip Clicked` | User clicked a link or action in an Agent Tip |
@@ -191,7 +191,7 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `AmbientAgent.ConcurrencyModal.Dismissed` | User dismissed the cloud agent capacity modal |
| `AmbientAgent.ConcurrencyModal.Opened` | User opened the cloud agent capacity modal |
| `AmbientAgent.ConcurrencyModal.UpgradeClicked` | User clicked the upgrade button in the cloud agent capacity modal |
-| `AmbientAgent.DispatchFailed` | Ambient agent failed to dispatch or encountered an error |
+| `AmbientAgent.DispatchFailed` | Cloud agent failed to dispatch or encountered an error |
| `AmbientAgent.EnvironmentSettings.CreatedEnvironment` | User created a new environment |
| `AmbientAgent.EnvironmentSettings.DeletedEnvironment` | User deleted an environment |
| `AmbientAgent.EnvironmentSettings.Image.Suggested` | Docker image was suggested for an environment |
@@ -234,7 +234,7 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `CLI.Execute.Agent.List` | Listed agents from the Warp CLI |
| `CLI.Execute.Agent.Profile.List` | Listed agent profiles from the Warp CLI |
| `CLI.Execute.Agent.Run` | Ran an agent from the Warp CLI |
-| `CLI.Execute.Agent.RunAmbient` | Ran an ambient agent from the Warp CLI |
+| `CLI.Execute.Agent.RunAmbient` | Ran a cloud agent from the Warp CLI |
| `CLI.Execute.Agent.Skills` | Listed agent skills from the Warp CLI |
| `CLI.Execute.Agent.Update` | Updated an agent from the Warp CLI |
| `CLI.Execute.ApiKey.Create` | Created an API key from the Warp CLI |
@@ -346,8 +346,8 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `CodexModal.Opened` | User opened the Codex modal |
| `CodexModal.UseCodexClicked` | User clicked 'Use Codex' in the Codex modal |
| `Command File Run` | Opened a .cmd or unix executable file and ran it directly in Warp |
-| `Command Palette Search Accepted` | Accepted a command palette search result |
-| `Command Palette Search Exited` | Exited command palette search without accepting a result |
+| `Command Palette Search Accepted` | Accepted a Command Palette search result |
+| `Command Palette Search Exited` | Exited Command Palette search without accepting a result |
| `Command Search Exited` | Exited command search (universal search panel to search) without accepting a result |
| `Command Search Opened` | Opened command search (universal search panel to search) |
| `Command Search Result Accepted` | Accepted command search result |
@@ -549,7 +549,7 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `SSH Remote Server Choice Do Not Ask Again Toggled` | Toggled the 'Don't ask me this again' checkbox on the SSH remote-server choice block |
| `Save Launch Config` | Saved current launch configuration of windows, tabs, and panes |
| `Select App Icon` | Selected app icon |
-| `Select Command Palette Option` | Selected option from command palette (i.e. CMD-P) |
+| `Select Command Palette Option` | Selected option from Command Palette (i.e. CMD-P) |
| `Select Cursor Type` | Selected cursor type |
| `Select Navigation Palette Item` | Selected session from the Session Navigation Palette (search across panes, tabs, and windows) |
| `Select Theme` | Selected theme |
@@ -601,7 +601,7 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `Thin Strokes Setting Changed` | Changed thin strokes setting in settings -> Appearance |
| `Tier Limit Hit` | User hit the tier limit for a feature |
| `Toggle Active AI Enablement` | Toggled active AI enablement. |
-| `Toggle Agent Mode Codebase Context` | Toggled on/off the enablement of codebase context usage for Agent Mode. |
+| `Toggle Agent Mode Codebase Context` | Toggled on/off the enablement of Codebase Context usage for Agent Mode. |
| `Toggle Agent Mode Query Suggestions Setting` | Toggled on/off the prompt suggestions setting |
| `Toggle Approvals Modal` | Opened or closed teams modal |
| `Toggle Block Filter Case Sensitivity` | Toggled on/off case sensitivity within the block filter editor |
@@ -609,7 +609,7 @@ If you're a [Team](/knowledge-and-collaboration/teams/) admin, the deletion flow
| `Toggle Block Filter Query` | Toggled on/off a block filter query |
| `Toggle Block Filter Regex` | Toggled on/off regex within the block filter editor |
| `Toggle Code Suggestions Setting` | Toggled on/off the code suggestions setting |
-| `Toggle Codebase Context Autoindexing` | Toggled on/off the enablement of autoindexing for codebase context. |
+| `Toggle Codebase Context Autoindexing` | Toggled on/off the enablement of autoindexing for Codebase Context. |
| `Toggle Dim Inactive Panes` | Whether the dim inactive panes feature has been toggled |
| `Toggle Focus Pane On Hover` | Toggled on/off focus pane on hover feature, which causes panes to automatically focus when hovering over them |
| `Toggle Git Operations Autogen Setting` | Toggled on/off the git operations autogen setting |
diff --git a/src/content/docs/support-and-community/privacy-and-security/secret-redaction.mdx b/src/content/docs/support-and-community/privacy-and-security/secret-redaction.mdx
index 224dcc53d..30efaa35d 100644
--- a/src/content/docs/support-and-community/privacy-and-security/secret-redaction.mdx
+++ b/src/content/docs/support-and-community/privacy-and-security/secret-redaction.mdx
@@ -19,7 +19,7 @@ Warp ships with a [list of recommended regex](/support-and-community/privacy-and
By default, identified secrets will be displayed with a strikethrough visual treatment, i.e. ` echo`` `` `~~`password`~~.
-If instead you'd prefer to visually hide the secrets as well, i.e. `echo ********`, the setting to obfuscate secrets with asterisks can be found in **Settings** > **Privacy** > **Secret redaction** > **Hide secrets in blocklist**.
+If instead you'd prefer to visually hide the secrets as well, i.e. `echo ********`, the setting to obfuscate secrets with asterisks can be found in **Settings** > **Privacy** > **Secret redaction** > **Hide secrets in denylist**.
Clicking on a secret will display a tooltip that lets you reveal the secret or copy the secret's contents. When trying to copy terminal output containing secrets, it will be copied as asterisks (e.g. `echo password` becomes `echo ********`) unless revealed or copied from the tooltip. Secret redaction is not applied in [Session Sharing](/agents/local-agents/session-sharing/#secrets-in-shared-sessions) — treat a shared session like sharing your screen.
diff --git a/src/content/docs/terminal/blocks/sticky-command-header.mdx b/src/content/docs/terminal/blocks/sticky-command-header.mdx
index b98adf97f..4091550f3 100644
--- a/src/content/docs/terminal/blocks/sticky-command-header.mdx
+++ b/src/content/docs/terminal/blocks/sticky-command-header.mdx
@@ -11,7 +11,7 @@ import VideoEmbed from '@components/VideoEmbed.astro';
For long-running commands that take up the full screen, the sticky header only shows after you start scrolling up. This is to prevent the header from blocking the top part of the output for commands like `git log` that simulate full-screen apps.
:::
-## How to access Sticky Command Header
+## How to access sticky command header
@@ -34,13 +34,13 @@ For long-running commands that take up the full screen, the sticky header only s
-## How to use Sticky Command Header
+## How to use sticky command header
* If a Block has a large output ( e.g. `seq 1 1000`), the header of the Block will show on the top of the active Window, Tab, or Pane.
* Click on the Sticky Command Header to quickly jump to the top of the Block.
* While active you can also minimize the Sticky Command Header on the active pane by clicking the UP/DOWN arrow in the middle of the header.
-## How Sticky Command Header works
+## How sticky command header works
diff --git a/src/content/docs/terminal/sessions/session-navigation.mdx b/src/content/docs/terminal/sessions/session-navigation.mdx
index 6b897c4e7..1c03ff2b1 100644
--- a/src/content/docs/terminal/sessions/session-navigation.mdx
+++ b/src/content/docs/terminal/sessions/session-navigation.mdx
@@ -8,7 +8,7 @@ sidebar:
---
import VideoEmbed from '@components/VideoEmbed.astro';
-## How to access Session Navigation
+## How to access session navigation
1. Open the Session Navigation palette with the [Command Palette](/terminal/command-palette/), click on **session >\_** or type in "sessions:".
2. Jump to a session by using your mouse or the `UP ↑`/`DOWN ↓` arrow keys and `ENTER`.
diff --git a/src/content/docs/terminal/sessions/session-restoration.mdx b/src/content/docs/terminal/sessions/session-restoration.mdx
index fc8353673..dd3a735a8 100644
--- a/src/content/docs/terminal/sessions/session-restoration.mdx
+++ b/src/content/docs/terminal/sessions/session-restoration.mdx
@@ -13,7 +13,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
Session restoration allows you to quickly pick up where you left off in your previous terminal session.
-## How to access Session Restoration
+## How to access session restoration
* Session Restoration comes enabled by default in Warp.