Skip to content

docs: streamline quickstart and add JavaScript snippets#815

Merged
leo-notte merged 6 commits into
mainfrom
docs/quickstart-skill-js-snippets
May 12, 2026
Merged

docs: streamline quickstart and add JavaScript snippets#815
leo-notte merged 6 commits into
mainfrom
docs/quickstart-skill-js-snippets

Conversation

@leo-notte
Copy link
Copy Markdown
Contributor

@leo-notte leo-notte commented May 12, 2026

Summary

  • Compact the docs homepage and quickstart entry points
  • Add a human-facing fast setup panel plus agent-only setup instructions
  • Point SDK quickstart cards to the concept quick-start sections
  • Convert concept-page examples to Python/JavaScript CodeGroups

Checks

  • git diff --check -- .
  • uv run pytest tests/test_snippets.py::test_snippets_are_autogenerated tests/test_snippets.py::test_no_snippets_outside_folder

Stacked on #814.


Note

Streamlines the docs homepage and quickstart: collapses index.mdx to a compact intro + card group, adds a human-facing "fast setup" copy-prompt panel for AI coding agents, rewrites the agent-facing quickstart as step-by-step CLI instructions, converts concept-page code examples from Python-only to Python/JavaScript CodeGroups, and fixes the sniptest tooling to skip manually-edited MDX files.

Written by Mendral for commit cf12555.

Summary by CodeRabbit

  • Documentation

    • Many docs updated with multi-language examples and focused Quick Starts for agents, sessions, and scraping; docs landing and quickstart content rewritten to highlight a unified workflow and add an API Reference link.
    • SDK reference pages now present audience-specific (human vs agent) view variants for return/type links.
  • New Features

    • Fast-setup UI added with clipboard copy and collapsible setup instructions.
  • Style

    • New styling and copy-confirmation animation for the fast-setup component.
  • Chores

    • Docs banner updated to recommend the new workflow; docs generation now preserves manually edited pages.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cb591a67-de14-463a-ae15-36119dd30ece

📥 Commits

Reviewing files that changed from the base of the PR and between 459adcc and d48032e.

📒 Files selected for processing (67)
  • docs/src/llms.txt
  • docs/src/scripts/apply_agent_md_notice.py
  • docs/src/sdk-reference/agentsclient/async_watch_logs.mdx
  • docs/src/sdk-reference/agentsclient/async_watch_logs_and_wait.mdx
  • docs/src/sdk-reference/agentsclient/create_function.mdx
  • docs/src/sdk-reference/agentsclient/function_code.mdx
  • docs/src/sdk-reference/agentsclient/index.mdx
  • docs/src/sdk-reference/agentsclient/list.mdx
  • docs/src/sdk-reference/agentsclient/run.mdx
  • docs/src/sdk-reference/agentsclient/run_custom.mdx
  • docs/src/sdk-reference/agentsclient/start.mdx
  • docs/src/sdk-reference/agentsclient/status.mdx
  • docs/src/sdk-reference/agentsclient/stop.mdx
  • docs/src/sdk-reference/agentsclient/wait.mdx
  • docs/src/sdk-reference/agentsclient/watch_logs.mdx
  • docs/src/sdk-reference/agentsclient/watch_logs_and_wait.mdx
  • docs/src/sdk-reference/misc/domnode.mdx
  • docs/src/sdk-reference/misc/interactiondomnode.mdx
  • docs/src/sdk-reference/misc/nottefunction.mdx
  • docs/src/sdk-reference/misc/nottepersona.mdx
  • docs/src/sdk-reference/misc/nottevault.mdx
  • docs/src/sdk-reference/misc/remotefilestorage.mdx
  • docs/src/sdk-reference/misc/remotesession.mdx
  • docs/src/sdk-reference/notteclient/index.mdx
  • docs/src/sdk-reference/notteclient/scrape.mdx
  • docs/src/sdk-reference/nottefunction/fork.mdx
  • docs/src/sdk-reference/nottefunction/get_run.mdx
  • docs/src/sdk-reference/nottefunction/index.mdx
  • docs/src/sdk-reference/nottefunction/replay.mdx
  • docs/src/sdk-reference/nottefunction/run.mdx
  • docs/src/sdk-reference/nottefunction/stop_run.mdx
  • docs/src/sdk-reference/nottepersona/aemails.mdx
  • docs/src/sdk-reference/nottepersona/asms.mdx
  • docs/src/sdk-reference/nottepersona/create_number.mdx
  • docs/src/sdk-reference/nottepersona/delete_number.mdx
  • docs/src/sdk-reference/nottepersona/emails.mdx
  • docs/src/sdk-reference/nottepersona/index.mdx
  • docs/src/sdk-reference/nottepersona/sms.mdx
  • docs/src/sdk-reference/nottevault/credential_fields_to_dict.mdx
  • docs/src/sdk-reference/nottevault/get_credit_card.mdx
  • docs/src/sdk-reference/nottevault/get_credit_card_async.mdx
  • docs/src/sdk-reference/nottevault/index.mdx
  • docs/src/sdk-reference/nottevault/replace_credentials.mdx
  • docs/src/sdk-reference/remoteagent/async_watch_logs_and_wait.mdx
  • docs/src/sdk-reference/remoteagent/index.mdx
  • docs/src/sdk-reference/remoteagent/replay.mdx
  • docs/src/sdk-reference/remoteagent/run.mdx
  • docs/src/sdk-reference/remoteagent/start.mdx
  • docs/src/sdk-reference/remoteagent/status.mdx
  • docs/src/sdk-reference/remoteagent/stop.mdx
  • docs/src/sdk-reference/remoteagent/wait.mdx
  • docs/src/sdk-reference/remoteagent/watch_logs.mdx
  • docs/src/sdk-reference/remoteagent/watch_logs_and_wait.mdx
  • docs/src/sdk-reference/remoteagentfallback/index.mdx
  • docs/src/sdk-reference/remotefilestorage/index.mdx
  • docs/src/sdk-reference/remotefilestorage/list_downloaded_files.mdx
  • docs/src/sdk-reference/remotefilestorage/list_uploaded_files.mdx
  • docs/src/sdk-reference/remotesession/debug_info.mdx
  • docs/src/sdk-reference/remotesession/execute.mdx
  • docs/src/sdk-reference/remotesession/get_cookies.mdx
  • docs/src/sdk-reference/remotesession/index.mdx
  • docs/src/sdk-reference/remotesession/observe.mdx
  • docs/src/sdk-reference/remotesession/replay.mdx
  • docs/src/sdk-reference/remotesession/scrape.mdx
  • docs/src/sdk-reference/remotesession/set_cookies.mdx
  • docs/src/sdk-reference/remotesession/status.mdx
  • docs/src/sdk-reference/remotesession/viewer_notebook.mdx
✅ Files skipped from review due to trivial changes (55)
  • docs/src/sdk-reference/agentsclient/status.mdx
  • docs/src/sdk-reference/remoteagent/stop.mdx
  • docs/src/sdk-reference/nottevault/get_credit_card_async.mdx
  • docs/src/sdk-reference/agentsclient/watch_logs_and_wait.mdx
  • docs/src/sdk-reference/agentsclient/wait.mdx
  • docs/src/sdk-reference/agentsclient/function_code.mdx
  • docs/src/sdk-reference/agentsclient/async_watch_logs_and_wait.mdx
  • docs/src/sdk-reference/nottefunction/get_run.mdx
  • docs/src/sdk-reference/remotesession/replay.mdx
  • docs/src/sdk-reference/remotesession/viewer_notebook.mdx
  • docs/src/sdk-reference/remotesession/debug_info.mdx
  • docs/src/sdk-reference/nottevault/get_credit_card.mdx
  • docs/src/sdk-reference/agentsclient/async_watch_logs.mdx
  • docs/src/sdk-reference/agentsclient/list.mdx
  • docs/src/sdk-reference/agentsclient/watch_logs.mdx
  • docs/src/sdk-reference/nottepersona/asms.mdx
  • docs/src/sdk-reference/misc/nottevault.mdx
  • docs/src/sdk-reference/nottepersona/sms.mdx
  • docs/src/sdk-reference/nottepersona/delete_number.mdx
  • docs/src/sdk-reference/remotesession/status.mdx
  • docs/src/sdk-reference/remotefilestorage/list_uploaded_files.mdx
  • docs/src/sdk-reference/remotesession/get_cookies.mdx
  • docs/src/sdk-reference/remoteagent/wait.mdx
  • docs/src/sdk-reference/remoteagent/watch_logs.mdx
  • docs/src/sdk-reference/remoteagent/replay.mdx
  • docs/src/sdk-reference/agentsclient/create_function.mdx
  • docs/src/sdk-reference/notteclient/scrape.mdx
  • docs/src/sdk-reference/nottepersona/create_number.mdx
  • docs/src/sdk-reference/nottefunction/replay.mdx
  • docs/src/sdk-reference/remoteagent/index.mdx
  • docs/src/sdk-reference/nottevault/credential_fields_to_dict.mdx
  • docs/src/sdk-reference/remoteagent/status.mdx
  • docs/src/llms.txt
  • docs/src/sdk-reference/remoteagent/async_watch_logs_and_wait.mdx
  • docs/src/sdk-reference/nottevault/replace_credentials.mdx
  • docs/src/sdk-reference/nottepersona/emails.mdx
  • docs/src/sdk-reference/agentsclient/run.mdx
  • docs/src/sdk-reference/misc/remotefilestorage.mdx
  • docs/src/sdk-reference/misc/remotesession.mdx
  • docs/src/sdk-reference/nottepersona/aemails.mdx
  • docs/src/sdk-reference/remoteagentfallback/index.mdx
  • docs/src/sdk-reference/remotesession/set_cookies.mdx
  • docs/src/sdk-reference/remoteagent/watch_logs_and_wait.mdx
  • docs/src/sdk-reference/remotefilestorage/index.mdx
  • docs/src/sdk-reference/misc/nottefunction.mdx
  • docs/src/sdk-reference/misc/nottepersona.mdx
  • docs/src/sdk-reference/notteclient/index.mdx
  • docs/src/sdk-reference/agentsclient/run_custom.mdx
  • docs/src/sdk-reference/agentsclient/start.mdx
  • docs/src/sdk-reference/misc/domnode.mdx
  • docs/src/sdk-reference/nottefunction/fork.mdx
  • docs/src/sdk-reference/agentsclient/stop.mdx
  • docs/src/sdk-reference/misc/interactiondomnode.mdx
  • docs/src/sdk-reference/remotesession/scrape.mdx
  • docs/src/sdk-reference/remoteagent/run.mdx

Walkthrough

Reworks many documentation pages and snippets: replaces single-language auto-generated MDX snippets with multi-language <CodeGroup> examples (adding JavaScript/zod variants), swaps Quick Start snippets on concept pages (agents → web agent, scraping → Hacker News, sessions → CDP session), updates docs landing/quickstart content and banner text, adds a .notte-fast-setup CSS component, prevents overwriting manually edited MDX in docs/src/sniptest/generate.py, enhances apply_agent_md_notice.py with whitespace normalization and SDK-page discovery, and adjusts numerous SDK-reference MDX files to render audience-specific Visibility links for return types and method cards.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • nottelabs/notte#773: Modifies documentation Quick Start snippets and imports (web agent, scraping_hackernews, CDPSession) that overlap the Quick Start snippet swaps in this PR.
  • nottelabs/notte#478: Large docs/snippet updates around scraping and client API usage that relate to the multi-language scraping snippet conversions here.
  • nottelabs/notte#740: Agent API/lifecycle changes that overlap agent snippet edits (agent.run usage and related lifecycle docs) present in this PR.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes: documentation improvements focusing on quickstart streamlining and JavaScript snippet additions across multiple files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/quickstart-skill-js-snippets

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@leo-notte leo-notte changed the base branch from docs/notte-skill-workflow to main May 12, 2026 00:44
mendral-app[bot]

This comment was marked as outdated.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 12, 2026

Greptile Summary

This PR streamlines the docs homepage and quickstart into a more focused entry point, and converts all concept-page code examples from Python-only snippets to Python/JavaScript <CodeGroup> tabs.

  • Homepage & quickstart restructure: index.mdx is collapsed to a brief intro + card group; quickstart.mdx gains a human-facing "fast setup" copy-prompt panel (with a custom CSS component) and a separate agent-facing step-by-step CLI walkthrough under <Visibility for=\"agents\">.
  • JavaScript snippets added: All 20+ snippet files across agents/, scraping/, and pages/ are wrapped in <CodeGroup> blocks with matching JavaScript tabs using notte-sdk and zod for schema definitions.
  • Bug fix in step_limits.mdx: max_steps is now correctly passed to agent.run() rather than the Agent() constructor, fixing the pre-existing issue flagged in previous review rounds.

Confidence Score: 5/5

Docs-only change; no runtime code paths are affected and the JavaScript snippets are consistent with the existing Python examples.

All changes are documentation and CSS. The JavaScript snippets faithfully mirror the Python counterparts, the step_limits bug is correctly addressed, and the fast-setup component is self-contained. The only findings are quality nits on the clipboard handler and a maintainability note about duplicated prompt text.

docs/src/quickstart.mdx — the clipboard write is fire-and-forget with no error path, and the setup prompt text is triplicated across the file.

Important Files Changed

Filename Overview
docs/src/quickstart.mdx Major restructure: adds JSX fast-setup panel with clipboard copy button, adds agent-only step-by-step CLI instructions, moves SDK examples to concept-page card links; the setup prompt text is duplicated across three locations (JS array, accordion, agents visibility block)
docs/src/style.css Adds 130 lines of CSS for the new .notte-fast-setup component; clean, well-structured with dark/light mode variants and responsive breakpoints
docs/src/index.mdx Homepage compacted from 65 to 9 lines of prose; removes inline quickstart steps, replaces OpenAPI Spec card with API Reference card, adds wide mode
docs/src/snippets/agents/step_limits.mdx Converts to CodeGroup with Python/JavaScript tabs; fixes the pre-existing bug where max_steps was passed to Agent constructor instead of run() — now correctly passed to agent.run() in both language tabs
docs/src/snippets/agents/structured_output_example.mdx Adds JavaScript tab using zod for schema definition; response_format receives the Zod schema object, consistent with the Python Pydantic model pattern
docs/src/snippets/scraping/session_based.mdx Adds JavaScript tab that correctly mirrors the Python session-based scraping pattern with login flow and session context manager equivalent
docs/src/docs.json Banner text updated to reflect the recommended skill + SDK workflow; minor wording change only
docs/src/concepts/agents.mdx Swaps AgentQuickstart snippet import for the new WebAgent quickstart snippet; one-line change
docs/src/concepts/scraping.mdx Replaces generic Quickstart snippet with more specific ScrapingHackerNews example; updates section intro text accordingly
docs/src/concepts/sessions.mdx Replaces SessionsPython snippet with CDPSession quickstart snippet; one-line swap

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
docs/src/quickstart.mdx:100-113
`navigator.clipboard.writeText()` returns a Promise that can reject (e.g., if the page is served in a non-secure context, or the browser denies clipboard permission). Because the call isn't awaited and there's no `.catch()`, the button always shows "Copied" regardless of whether the write actually succeeded — leaving the user thinking the prompt is on their clipboard when it isn't.

```suggestion
        navigator.clipboard.writeText(notteSetupPrompt).then(() => {
          button.classList.add("is-copied");

          if (label) {
            label.textContent = "Copied";
          }

          window.setTimeout(() => {
            button.classList.remove("is-copied");

            if (label) {
              label.textContent = "Copy setup prompt";
            }
          }, 1600);
        }).catch(() => {
          if (label) {
            label.textContent = "Copy failed — try again";
          }

          window.setTimeout(() => {
            if (label) {
              label.textContent = "Copy setup prompt";
            }
          }, 2000);
        });
```

### Issue 2 of 2
docs/src/quickstart.mdx:190-259
**Setup prompt duplicated in three places**

The setup prompt text lives in three separate locations: the `notteSetupPrompt` JS array (used for clipboard copy), the `<Accordion title="View setup prompt">` block, and the `<Visibility for="agents">` section. All three are currently in sync, but a future edit to one will silently diverge from the others — the clipboard payload will no longer match what the user reads on screen. If keeping these separate is intentional, a short comment noting they must be kept in sync would help future editors.

Reviews (2): Last reviewed commit: "Address PR review feedback" | Re-trigger Greptile

Comment thread docs/src/snippets/agents/step_limits.mdx
Comment thread docs/src/snippets/agents/step_limits.mdx
@leo-notte leo-notte force-pushed the docs/quickstart-skill-js-snippets branch from e2b353b to 47ccb61 Compare May 12, 2026 01:26
@2027-evals
Copy link
Copy Markdown

2027-evals Bot commented May 12, 2026

✅ Eval complete for commit d48032e

URL Mapping
docs.notte.cc notte-docs-quickstart-skill-js-snippets.mintlify.app

Ran evals with prompts:

📈 +2.5 pts · Getting Started — B (80.2/100) from B (77.7) · View metrics

Prompt text:

Use Notte to run a headless browser session. Follow the quickstart at https://notte.cc/ to set up a project that:

  1. Creates a cloud browser session
  2. Connects to it using Playwright, Puppeteer, or the Notte SDK
  3. Navigates to https://news.ycombinator.com
  4. Extracts the titles of the top 5 stories
  5. Prints them to stdout

Verdict:

Notte has best-in-class AI discoverability infrastructure but a thin SDK usage reference that causes unnecessary exploration for the critical CDP connection pattern.

Friction points:

  • 🔴 The Session class usage pattern (factory method on NotteClient, — .use() callback, accessing s.response.cdp_url for CDP connection) is not clearly documented in quickstart or SDK reference — agent had to introspect compiled SDK source code.
  • 🟡 JavaScript/Node — .js quickstart examples are less prominent than Python examples; the agent had to verify SDK exports programmatically to confirm NotteClient and Session exports.
  • 🟡 The proxy and stealth constructor options for Session are not listed with their accepted values in the quickstart, requiring cross-referencing with the OpenAPI spec — .

Result: B (80.2/100)

delta vs baseline: +2.5 pts

Dimension Baseline This PR
Setup Friction 86 100
Speed 85 83
Efficiency 41 49
Error Recovery 100 100
Doc Quality 80 70

Stats: 2m 9s · 21 tool calls · 0 errors · $1.05

View report → · View trace →


Evaluating agent experience using 2027.dev · View dashboard

mendral-app[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/src/snippets/scraping/extract_lists.mdx (1)

16-16: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Consider making API key handling consistent between examples.

The Python example creates NotteClient() with no arguments (line 16), while the JavaScript example explicitly passes apiKey: process.env.NOTTE_API_KEY (lines 38-40). This inconsistency may confuse users about the recommended approach for API key configuration.

Consider either:

  1. Adding explicit API key configuration to the Python example to match JavaScript
  2. Omitting the explicit API key in JavaScript if both SDKs auto-detect from environment variables
  3. Adding a comment explaining the difference if the SDKs have different conventions
📝 Suggested fix for consistency

If both SDKs support environment variable auto-detection:

 const client = new NotteClient({
-  apiKey: process.env.NOTTE_API_KEY,
 });

Or if explicit configuration is preferred:

+import os
+
-client = NotteClient()
+client = NotteClient(api_key=os.environ["NOTTE_API_KEY"])

Also applies to: 38-40

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/src/snippets/scraping/extract_lists.mdx` at line 16, The examples are
inconsistent: the Python snippet constructs NotteClient() with no args while the
JavaScript example passes apiKey: process.env.NOTTE_API_KEY; pick one consistent
approach and update both snippets accordingly (either explicitly pass the env
var in Python NotteClient(api_key=os.environ["NOTTE_API_KEY"]) and mirror the
same named parameter as in the JS example, or remove the explicit apiKey from
the JS example so both rely on SDK auto-detection). If the SDKs differ, add a
short comment next to NotteClient() and the JS client constructor explaining
that one SDK auto-detects the environment variable while the other requires
explicit config.
🧹 Nitpick comments (4)
docs/src/snippets/scraping/links_and_images.mdx (1)

2-14: ⚡ Quick win

Use distinct variable names for clarity and consistency.

The Python examples reuse the variable name markdown for all four scrape calls, which obscures which result is which. The JavaScript examples use descriptive variable names (markdownWithLinks, markdownWithoutLinks, etc.), which is clearer and models better practice for readers.

♻️ Align Python variable names with JavaScript pattern
 ```python Python
 # Include links (default)
-markdown = client.scrape(url, scrape_links=True)
+markdown_with_links = client.scrape(url, scrape_links=True)
 
 # Exclude links
-markdown = client.scrape(url, scrape_links=False)
+markdown_without_links = client.scrape(url, scrape_links=False)
 
 # Include images in markdown
-markdown = client.scrape(url, scrape_images=True)
+markdown_with_images = client.scrape(url, scrape_images=True)
 
 # Exclude images (default)
-markdown = client.scrape(url, scrape_images=False)
+markdown_without_images = client.scrape(url, scrape_images=False)
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/src/snippets/scraping/links_and_images.mdx around lines 2 - 14, Rename
the repeated variable markdown to distinct descriptive names to match the JS
examples: change the four client.scrape(...) results to markdown_with_links
(client.scrape(url, scrape_links=True)), markdown_without_links
(client.scrape(url, scrape_links=False)), markdown_with_images
(client.scrape(url, scrape_images=True)), and markdown_without_images
(client.scrape(url, scrape_images=False)) so callers can clearly see which
scrape options produced each value.


</details>

</blockquote></details>
<details>
<summary>docs/src/snippets/scraping/extract_lists.mdx (1)</summary><blockquote>

`24-50`: _⚡ Quick win_

**Clarify async context requirement for JavaScript example.**

The JavaScript snippet uses `await` on line 42 without an explicit async function wrapper. While top-level await is valid in ES modules, users who copy-paste this code into a non-module context (e.g., a CommonJS script or script tag) will encounter a syntax error.

Consider one of these approaches:
1. Wrap the code in an async IIFE or function to make it universally compatible
2. Add a comment indicating this requires ES module context with top-level await support




<details>
<summary>♻️ Suggested approaches</summary>

**Option 1: Wrap in async function (universally compatible)**
```diff
 ```javascript JavaScript
 import { z } from 'zod';
 import { NotteClient } from 'notte-sdk';

 const Article = z.object({
   title: z.string(),
   url: z.string(),
   summary: z.string(),
 });

 const ArticleList = z.object({
   articles: z.array(Article),
 });

+(async () => {
 const client = new NotteClient({
   apiKey: process.env.NOTTE_API_KEY,
 });

 const articles = await client.scrape('https://news.example.com', {
   response_format: ArticleList,
   instructions: 'Extract all articles from the homepage',
 });

 for (const article of articles.articles) {
   console.log(`${article.title}: ${article.url}`);
 }
+})();

**Option 2: Add clarifying comment**
```diff
 ```javascript JavaScript
+// This example uses top-level await (requires ES modules)
 import { z } from 'zod';
 import { NotteClient } from 'notte-sdk';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/src/snippets/scraping/extract_lists.mdx` around lines 24 - 50, The
snippet uses top-level await on client.scrape (with symbols NotteClient, client,
and ArticleList) which will break in non-ESM contexts; wrap the usage of await
(the client creation, the await client.scrape call, and the for-loop over
articles.articles) inside an async IIFE (e.g., (async () => { ... })()) to make
it universally compatible, or alternatively add a clear comment above the
imports stating "requires ES modules / top-level await" if you prefer to leave
top-level await in place.
docs/src/snippets/scraping/instructions_only.mdx (1)

19-19: 💤 Low value

Top-level await may not work in all environments.

The example uses await without an async function wrapper. While modern Node.js (v14.8+) and bundlers support top-level await, this may fail in older environments or certain module systems. For documentation examples aimed at broad compatibility, consider wrapping in an async IIFE or noting the requirement.

♻️ Wrap in async function for broader compatibility
 ```javascript JavaScript
 import { NotteClient } from 'notte-sdk';
 
-const client = new NotteClient({
-  apiKey: process.env.NOTTE_API_KEY,
-});
-
-const result = await client.scrape('https://example.com/article', {
-  instructions: 'Extract the article title, author, and publication date',
-});
-
-console.log(result);
+(async () => {
+  const client = new NotteClient({
+    apiKey: process.env.NOTTE_API_KEY,
+  });
+
+  const result = await client.scrape('https://example.com/article', {
+    instructions: 'Extract the article title, author, and publication date',
+  });
+
+  console.log(result);
+})();
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/src/snippets/scraping/instructions_only.mdx at line 19, The example
uses top-level await with client.scrape which can break in older runtimes; wrap
the snippet in an async function/IIFE (e.g., create a minimal async wrapper that
constructs NotteClient, calls client.scrape, and logs the result) or add a short
note that top-level await requires modern Node/bundler support so readers know
to run inside an async context when using NotteClient and the result variable.


</details>

</blockquote></details>
<details>
<summary>docs/src/snippets/scraping/structured_data_response.mdx (1)</summary><blockquote>

`32-32`: _💤 Low value_

**Consider the same top-level await concern.**

This example has the same top-level `await` usage as in `instructions_only.mdx`. For consistency and broader compatibility, consider applying the same async wrapper pattern if you address it in other JavaScript examples.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/src/snippets/scraping/structured_data_response.mdx at line 32, Example
uses top-level await with client.scrape; wrap that call in an async function
(e.g., async function main() { ... } ) or an async IIFE (e.g., (async () => {
... })()) to avoid top-level await and match other examples; move the const
product = await client.scrape(url, { ... }) inside that async wrapper and invoke
the wrapper so the snippet runs in environments without top-level await while
keeping the same client.scrape usage.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @docs/src/quickstart.mdx:

  • Around line 10-80: The same setup markdown is duplicated across the exported
    notteSetupPrompt constant and two rendered blocks (the accordion markdown and
    the agent-facing Visibility block); extract that markdown into a single shared
    MDX snippet (e.g., SetupInstructions component in
    snippets/quickstart/setup_instructions.mdx), import and render
    in place of the inline accordion content and the
    Visibility(for="agents") content, and then have notteSetupPrompt either be
    generated programmatically from that shared source or kept as a minimal copy
    that is produced from the shared snippet to avoid manual duplication; update
    imports/references in the file to use the new SetupInstructions component and
    remove the three inline copies.

In @docs/src/snippets/scraping/data_collection.mdx:

  • Around line 26-53: The snippet incorrectly shows a JavaScript usage of a
    non-existent JS package ("import { NotteClient } from 'notte-sdk'")—remove or
    replace the entire JS block that defines ProductInfo, NotteClient, client.scrape
    and response_format; instead provide a working Python example using the real pip
    package (import from notte_sdk, instantiate NotteClient, call client.scrape in
    Python and validate/output results) or remove the example entirely so docs don’t
    reference the nonexistent JavaScript SDK. Ensure any identifiers from the diff
    (ProductInfo, NotteClient, client.scrape, response_format) are removed or
    replaced with their Python equivalents in the new snippet.

In @docs/src/snippets/scraping/image_extraction.mdx:

  • Line 5: Update the Python snippet to explicitly pass the API key to
    NotteClient by importing os and calling os.getenv("NOTTE_API_KEY") when
    constructing NotteClient (replace the existing client = NotteClient() usage);
    add the import os at the top of the snippet so the os.getenv call resolves.

In @docs/src/snippets/scraping/structured_data_response.mdx:

  • Around line 18-38: The JavaScript example using NotteClient and client.scrape
    with the Product zod schema is incorrect because notte-sdk is Python-only;
    remove the JS code block or replace it with a clear note that the SDK currently
    supports Python only and that NotteClient, client.scrape and the shown import
    are not available in JavaScript/Node.js. Locate the snippet containing the
    Product schema, NotteClient import, and client.scrape usage and either delete
    that code block or prepend a short explanatory sentence clarifying Python-only
    support and linking to the correct Python example instead.

In @docs/src/style.css:

  • Line 150: The CSS uses the color keyword "currentColor" with uppercase C which
    violates stylelint's value-keyword-case rule; update the value in the
    declaration where "border: 0.13em solid currentColor;" is defined to use the
    lowercase "currentcolor" so the property becomes "border: 0.13em solid
    currentcolor;" ensuring consistent keyword casing for the border style.

Outside diff comments:
In @docs/src/snippets/scraping/extract_lists.mdx:

  • Line 16: The examples are inconsistent: the Python snippet constructs
    NotteClient() with no args while the JavaScript example passes apiKey:
    process.env.NOTTE_API_KEY; pick one consistent approach and update both snippets
    accordingly (either explicitly pass the env var in Python
    NotteClient(api_key=os.environ["NOTTE_API_KEY"]) and mirror the same named
    parameter as in the JS example, or remove the explicit apiKey from the JS
    example so both rely on SDK auto-detection). If the SDKs differ, add a short
    comment next to NotteClient() and the JS client constructor explaining that one
    SDK auto-detects the environment variable while the other requires explicit
    config.

Nitpick comments:
In @docs/src/snippets/scraping/extract_lists.mdx:

  • Around line 24-50: The snippet uses top-level await on client.scrape (with
    symbols NotteClient, client, and ArticleList) which will break in non-ESM
    contexts; wrap the usage of await (the client creation, the await client.scrape
    call, and the for-loop over articles.articles) inside an async IIFE (e.g.,
    (async () => { ... })()) to make it universally compatible, or alternatively add
    a clear comment above the imports stating "requires ES modules / top-level
    await" if you prefer to leave top-level await in place.

In @docs/src/snippets/scraping/instructions_only.mdx:

  • Line 19: The example uses top-level await with client.scrape which can break
    in older runtimes; wrap the snippet in an async function/IIFE (e.g., create a
    minimal async wrapper that constructs NotteClient, calls client.scrape, and logs
    the result) or add a short note that top-level await requires modern
    Node/bundler support so readers know to run inside an async context when using
    NotteClient and the result variable.

In @docs/src/snippets/scraping/links_and_images.mdx:

  • Around line 2-14: Rename the repeated variable markdown to distinct
    descriptive names to match the JS examples: change the four client.scrape(...)
    results to markdown_with_links (client.scrape(url, scrape_links=True)),
    markdown_without_links (client.scrape(url, scrape_links=False)),
    markdown_with_images (client.scrape(url, scrape_images=True)), and
    markdown_without_images (client.scrape(url, scrape_images=False)) so callers can
    clearly see which scrape options produced each value.

In @docs/src/snippets/scraping/structured_data_response.mdx:

  • Line 32: Example uses top-level await with client.scrape; wrap that call in an
    async function (e.g., async function main() { ... } ) or an async IIFE (e.g.,
    (async () => { ... })()) to avoid top-level await and match other examples; move
    the const product = await client.scrape(url, { ... }) inside that async wrapper
    and invoke the wrapper so the snippet runs in environments without top-level
    await while keeping the same client.scrape usage.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Path: .coderabbit.yaml

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `b5289bf8-4c24-483e-b772-d93fb6a6f946`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 767ce1108436fc2d3a898564549c487b2376960a and 6752795550fce90fdc3a827c3d074cf3382cffa7.

</details>

<details>
<summary>📒 Files selected for processing (32)</summary>

* `docs/src/concepts/agents.mdx`
* `docs/src/concepts/scraping.mdx`
* `docs/src/concepts/sessions.mdx`
* `docs/src/docs.json`
* `docs/src/index.mdx`
* `docs/src/quickstart.mdx`
* `docs/src/snippets/agents/error_handling.mdx`
* `docs/src/snippets/agents/natural_language_task.mdx`
* `docs/src/snippets/agents/starting_url.mdx`
* `docs/src/snippets/agents/step_limits.mdx`
* `docs/src/snippets/agents/structured_output_example.mdx`
* `docs/src/snippets/pages/linkedin_step.mdx`
* `docs/src/snippets/scraping/content_filtering.mdx`
* `docs/src/snippets/scraping/content_monitoring.mdx`
* `docs/src/snippets/scraping/data_collection.mdx`
* `docs/src/snippets/scraping/extract_lists.mdx`
* `docs/src/snippets/scraping/handle_missing_data.mdx`
* `docs/src/snippets/scraping/image_extraction.mdx`
* `docs/src/snippets/scraping/instructions_only.mdx`
* `docs/src/snippets/scraping/link_placeholders.mdx`
* `docs/src/snippets/scraping/links_and_images.mdx`
* `docs/src/snippets/scraping/nested_structures.mdx`
* `docs/src/snippets/scraping/precise_schemas.mdx`
* `docs/src/snippets/scraping/pydantic_model.mdx`
* `docs/src/snippets/scraping/quick_scrape.mdx`
* `docs/src/snippets/scraping/research_analysis.mdx`
* `docs/src/snippets/scraping/scope_scrapes.mdx`
* `docs/src/snippets/scraping/scoped_scraping.mdx`
* `docs/src/snippets/scraping/session_based.mdx`
* `docs/src/snippets/scraping/specific_instructions.mdx`
* `docs/src/snippets/scraping/structured_data_response.mdx`
* `docs/src/style.css`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread docs/src/quickstart.mdx
Comment thread docs/src/snippets/scraping/data_collection.mdx
Comment thread docs/src/snippets/scraping/image_extraction.mdx
Comment thread docs/src/snippets/scraping/structured_data_response.mdx
Comment thread docs/src/style.css Outdated
- Add run() call to step_limits agent snippets (Python + JS) so
  max_steps is actually exercised
- Fix currentColor → currentcolor CSS keyword casing

Co-Authored-By: Claude <noreply@anthropic.com>
@leo-notte
Copy link
Copy Markdown
Contributor Author

@greptileai review

mendral-app[bot]

This comment was marked as outdated.

- Update step_limits.py tester to include run() call
- Skip regenerating MDX files that were manually edited (no
  auto-generated header), preserving CodeGroup JS blocks
- Change agent list to "etc." in quickstart copy

Co-Authored-By: Claude <noreply@anthropic.com>
mendral-app[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/src/quickstart.mdx`:
- Around line 96-113: The onClick handler currently sets the copied UI state
immediately without checking navigator.clipboard.writeText; modify the handler
around notteSetupPrompt so the UI (button.classList.add("is-copied") and
label.textContent = "Copied") is only applied after writeText succeeds (use
await or .then), and add an error path (catch) that leaves the button unchanged
and updates the label or shows an error message (e.g., "Copy failed" or a
tooltip) so failures (permission/insecure context) are surfaced; ensure the
existing timeout that removes "is-copied" and resets the label only runs for the
success path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ac78660f-efe4-412b-8ff2-cb98a39fcf36

📥 Commits

Reviewing files that changed from the base of the PR and between 1fca5a7 and 459adcc.

📒 Files selected for processing (3)
  • docs/src/quickstart.mdx
  • docs/src/sniptest/generate.py
  • docs/src/testers/agents/step_limits.py

Comment thread docs/src/quickstart.mdx
@leo-notte leo-notte merged commit 58e98af into main May 12, 2026
12 of 14 checks passed
@leo-notte leo-notte deleted the docs/quickstart-skill-js-snippets branch May 12, 2026 02:05
Copy link
Copy Markdown

@mendral-app mendral-app Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The two follow-up commits (d48032e, cf12555) are SDK doc generation alignment fixes with no new logic. All previous feedback was addressed in earlier commits. PR is clean.

Tag @mendral-app with feedback or questions. View session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant