Skip to content

feat(docs): consolidate hand-written docs into top-level docs/ with export pipeline - #1856

Merged
dylan-savage merged 16 commits into
fix/docsfrom
feat/docs-consolidation
Aug 6, 2026
Merged

dylan-savage merged 16 commits into
fix/docsfrom
feat/docs-consolidation

Conversation

@dylan-savage

@dylan-savage dylan-savage commented Aug 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Consolidates all hand-written documentation into a top-level docs/ tree as the single source of truth, with builder-managed exports for files that must also live elsewhere. Node docs stay co-located (they're schema-coupled and generated). builder docs:build page count is unchanged at every commit (Staged 179 pages, 125 nodes, 6 mounts).

New layout

Section Contents Notes
docs/product/ site spine: quickstart, concepts, integrations, examples, evaluate, glossary, … from packages/docs/content-static/
docs/clients/{typescript,python,vscode}/ per-client guides + that client's readme.md guides from per-package docs/ trees
docs/mcp/ MCP surface docs + readme.md own top-level section
docs/agents/ ROCKETRIDE_* agent docs exported to .rocketride/docs/ (local, gitignored)
docs/stubs/ assistant-stub templates unchanged; consumed by vsix packaging
docs/internal/ contributor docs (ex README-*.md) + engine-protocol/ engine/WS protocol docs from packages/server/docs/

Export pipeline

  • ./builder docs:export writes the committed, header-carrying package READMEs (packages/client-{typescript,python,mcp}/README.md — previously gitignored and generated by per-package build steps, now tracked; the three .gitignore entries are removed) and materializes .rocketride/docs/.
  • ./builder docs:check fails on drift between sources and committed copies; wired into ci.yml (PR gate via ruff-check → ci-ok) and docs.yml (which also gains docs/** + the three README dest paths as triggers).
  • The VS Code marketplace readme (docs/clients/vscode/readme.md) keeps its existing package-time copy mechanism (gitignored dest, not in the export map).
  • Legacy build-time README copy steps in the three client packages were removed (typescript) or re-pointed to the committed exports (python, mcp) — client-*:build all green.

Image consolidation (added after PR opened)

Top-level images/ moved to docs/images/ (17 files, git renames). An exhaustive reference audit (all tracked md/mdx, both syntaxes + JSX props) confirmed this folder was the only image store docs reference; all 21 source references rewritten (root README relative paths + main/develop-pinned raw.githubusercontent URLs) and generated package READMEs refreshed via docs:export. Not moved, deliberately: packages/docs/static/img/ (Docusaurus theme assets, served site-absolute — the <ThemedImage> in use-cases.mdx is untouched) and apps/aparavi-ui/src/assets/ (component-local). Note: the rewritten …/main/docs/images/… URLs resolve once this reaches main at release — until then, published npm/PyPI readmes keep rendering from main's current layout, so nothing breaks in the interim.

Also in this change

  • gather.js gains a central DOCS_ROOT_MOUNTS table for the top-level tree (with readme.md files skipped from site staging, tested); the five per-package docs: mount declarations are removed (the generated pipeline-reference mount stays).
  • docs/images/ deleted; all references stripped.
  • Doc-location rules rewritten in .claude/CLAUDE.md, .cursorrules, AGENTS.md; new docs/README.md folder guide.
  • Incidental: the README- link fix in .github/SUPPORT.md also repaired a pre-existing broken relative path.

Verification

docs:test 42/42 (incl. new gather root-mount and export tests, TDD) · docs:check green (incl. fresh-clone simulation) · docs:build parity at every commit · client-typescript:build / client-python:build / client-mcp:build green with READMEs verified in tarball/wheel.

Deferred follow-ups (non-blocking)

  • Harden DOCS_ROOT_MOUNTS with isValidMount().
  • Drop now-stale packages/*/docs/** / apps/*/docs/** trigger globs in docs.yml.

Design + audit trail: claude/tasks/docs-revamp/ (local).

🤖 Generated with Claude Code

dylan-savage and others added 12 commits August 5, 2026 15:53
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID and forum thread ID. Do not edit or delete.

@github-actions github-actions Bot added docs Documentation ci/cd CI/CD and build system builder Node builder tooling and ./builder workflows labels Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • develop
  • release/.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d3dbcb1b-bc59-4406-9f24-479a3c7b3666

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR centralizes documentation under docs/, adds generated package README exports, updates documentation gathering, and introduces docs:export and docs:check commands. It also adds extensive product, SDK, MCP, VS Code, engine, integration, and contributor documentation.

Changes

Documentation centralization

Layer / File(s) Summary
Repository rules and CI validation
.claude/CLAUDE.md, .cursorrules, AGENTS.md, .github/workflows/*, docs/README.md
Documentation mappings now use centralized source paths. CI runs documentation drift checks.
Client and MCP documentation
docs/clients/*, docs/mcp/*, docs/clients/vscode/*
Added SDK, MCP, and VS Code usage, API, protocol, installation, and integration documentation.
Internal and MCP guides
docs/internal/*, docs/agents/*
Added engine, builder, node testing, n8n, protocol, Shell-UI, client, and pre-commit documentation.
Product documentation
docs/product/*
Added product overview, quickstart, concepts, integrations, examples, deployment, security, CLI, glossary, and troubleshooting pages.
Package exports and validation
packages/docs/*, packages/client-*/README.md, packages/*/scripts/tasks.js, packages/server/scripts/tasks.js
Added centralized export and drift-check logic. Package README sources and co-located documentation mounts now use the new workflow. Tests cover file exports, directory exports, stale files, drift detection, and centralized gathering.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

Suggested labels: module:client-python, module:client-typescript, module:client-mcp, module:vscode, module:server

Suggested reviewers: jmaionchi, rod-christensen, stepmikhaylov, kwit75

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: consolidating documentation into top-level docs/ and adding an export pipeline.
✨ 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 feat/docs-consolidation

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.

@dylan-savage
dylan-savage changed the base branch from develop to fix/docs August 6, 2026 01:03
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 42

🤖 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/clients/python/readme.md`:
- Around line 1-2: Add a top-level heading before the banner in
docs/clients/python/readme.md (lines 1-2), using the title “RocketRide Python
SDK”; make the same change in docs/clients/typescript/readme.md (lines 1-2) with
“RocketRide TypeScript SDK”.
- Around line 540-549: The custom DAP examples are not self-contained because
their connection and token variables are undefined. In
docs/clients/python/readme.md lines 540-549, define uri, auth, and my_token
before constructing the RocketRideClient or request; in
docs/clients/typescript/readme.md lines 461-473, define auth, uri, and myToken
before their use, preserving each example’s existing client setup and request
flow.
- Around line 153-160: Update the Python context-manager example around
RocketRideClient to import the os module before using os.environ, ensuring the
example runs without a NameError when copied.
- Around line 401-405: Update the Python example in
docs/clients/python/readme.md at lines 401-405 and the TypeScript example in
docs/clients/typescript/readme.md at lines 351-359 to pass the pipeline
configuration directly to client.use: use my_pipeline_config in Python and
myPipelineConfig in TypeScript, removing the extra pipeline wrapper while
preserving the surrounding example flow.

In `@docs/clients/typescript/methods/database-sequelize.md`:
- Around line 80-91: Update the Sequelize model definition for User and its
findAll query so they agree on the active field: either declare active in the
model with the appropriate type or remove the active filter, ensuring the
example does not reference an undocumented column.

In `@docs/clients/typescript/methods/deploy.md`:
- Around line 153-160: Update the rollback example after the team-prod
deployment to obtain the actual prior deployed version from deployment history
or the versions() API, rather than calculating artifact.version! - 1; pass that
recorded version to client.deploy.deploy while leaving the publish and initial
deployment flow unchanged.

In `@docs/clients/typescript/methods/get-task-status.md`:
- Around line 21-40: Update the TypeScript getTaskStatus documentation to
include the optional options parameter with timeout?: number | false in the
method signature and parameter table. Document the default timeout as 15000 and
state that false disables the per-call timeout override, while leaving the
Python documentation unchanged.

In `@docs/clients/typescript/methods/send.md`:
- Line 36: Add blank lines immediately before and after each fenced Python
signature block for send(), send_files(), and pipe() in
docs/clients/typescript/methods/send.md at lines 36-36, 114-114, and 221-221 to
satisfy MD031.

In `@docs/clients/typescript/methods/use.md`:
- Around line 130-139: Update the example flow around client.use() to inspect
result['errors'] after validation and call use() only when the validation
succeeds; preserve the existing behavior for handling validation failures.

In `@docs/clients/typescript/methods/validate.md`:
- Around line 30-34: Update the TypeScript validate signature example to use
valid object-literal syntax by replacing `source?` with `source` or `source:
undefined`, while preserving the existing validate call structure.

In `@docs/clients/typescript/readme.md`:
- Around line 301-308: Align the Answer documentation with the example by
documenting the instance APIs new Answer(), setAnswer(), isJson(), getJson(),
and getText() alongside Answer.parsePython, using the exported Answer API and
the co-located package README as the reference for accurate signatures and
descriptions.

In `@docs/clients/vscode/deployment-webview.md`:
- Around line 25-33: Update the correlation-style documentation to distinguish
acknowledgment-only mutation actionResult replies from result-bearing RPC
replies. Revise the statement that all …Result messages contain only requestId
and error, and explicitly preserve the pipeline or result payloads for
deploy:artifactResult, deployment:previewResult, and deployment:validateResult.

In `@docs/clients/vscode/usage.md`:
- Around line 67-71: Update the documented `.env` lifecycle for development
self-hosted connections so `ROCKETRIDE_APIKEY` is removed when disconnecting,
the engine exits, or switching to cloud; revise the surrounding guidance to
reflect automatic cleanup and avoid instructing users to remove it manually.
Preserve the existing sync behavior and exclusions for unsupported connection
types.

In `@docs/internal/apps.md`:
- Line 44: Label every currently unlabeled fenced block with the appropriate
language identifier: use text in docs/internal/apps.md at lines 44, 87, 246, and
847; use text at line 69 and bash at lines 93, 116, 125, 148, and 162 in
docs/internal/engine-protocol/crash-reporting.md; use text in docs/mcp/index.md
at line 74 and docs/mcp/readme.md at line 32.

In `@docs/internal/builder.md`:
- Around line 967-972: Update each incremental-build skip condition around
hasSourceChanged and exists, including the examples near the referenced
locations, to also require !ctx.options?.force. Preserve the existing
unchanged-source and output-exists checks while allowing builder ... --force to
continue with the build.

In `@docs/internal/clients.md`:
- Around line 74-76: Correct the license links in docs/internal/clients.md lines
74-76 and docs/internal/builder.md line 1884 by changing ../LICENSE to
../../LICENSE or another valid repository license URL.
- Around line 21-25: Update the SDK table links in the clients documentation to
reference the centralized sources docs/clients/typescript/readme.md,
docs/clients/python/readme.md, and docs/mcp/readme.md instead of the
README-*-client.md targets, preserving the existing TypeScript, Python, and MCP
rows.

In `@docs/internal/engine-protocol/crash-reporting.md`:
- Around line 94-109: Update the minidump-stackwalk setup to use a specific
rust-minidump release instead of the floating latest endpoint, retrieve that
release’s checksum metadata, and verify the downloaded archive before
extraction. Keep extraction and the privileged install in place only after
checksum validation, using the existing download/install flow and
release-specific artifact name.
- Around line 166-167: Update the minidump base-address extraction command so
the `$bin` path is passed to Python as data via an environment variable or
standard input, not interpolated into the Python source string; preserve the
existing module filename matching and base_addr lookup behavior.
- Around line 163-169: Update the gdbdump function’s converted-core handling to
avoid the predictable /tmp/$(basename "$dmp").core path: create a unique
temporary file with mktemp, ensure conversion cannot follow an
attacker-controlled symlink, and register a cleanup trap to remove the temporary
core on exit while preserving the existing gdb invocation.

In `@docs/internal/engine-protocol/index.md`:
- Around line 20-42: Update the Message format/Requests documentation to state
that binary data is sent as raw bytes after the JSON header rather than embedded
in the JSON object. Add a concrete subcommand "write" request example showing
the JSON header and subsequent binary payload framing, so non-SDK clients can
construct valid requests.
- Around line 21-25: Clarify the token flow in the Auth section of index.md by
making the documented examples consistent: show the authenticated frame, the
open response containing its task token, and a subsequent task request using
that token, or explicitly state that open intentionally uses the API key in
arguments.token.

In `@docs/internal/engine-protocol/observability.md`:
- Around line 107-111: Update the authoritative SDK type references in the
observability documentation to include the packages/ directory, using
packages/client-typescript/src/client/types/events.ts,
packages/client-python/src/rocketride/types/events.py, and the corresponding
task module paths so contributors can open them directly.

In `@docs/internal/node-schema.md`:
- Around line 16-18: Update the rendered link text for the README-nodes.md and
README-node-testing.md links in docs/internal/node-schema.md lines 16-18, the
README-nodes.md link in docs/internal/node-schema.md lines 57-58, and the
README-builder.md link in docs/internal/index.md lines 41-43 to use their
centralized filenames, while preserving each link target and surrounding
documentation.

In `@docs/internal/node-testing.md`:
- Around line 27-34: Update the builder command examples throughout
docs/internal/node-testing.md, including the quick-start, contract-test, and
integration-test examples, to invoke the repository-local script with ./builder
instead of builder. Keep the existing commands and descriptions unchanged
otherwise.
- Around line 27-28: Add a blank line before every fenced code block in
docs/internal/node-testing.md at the reported locations, including the block
following “Run tests:” and the additional listed ranges, to satisfy the MD031
markdownlint rule without changing the code block contents.

In `@docs/internal/nodes.md`:
- Line 15: Update the link labels in docs/internal/nodes.md that target
node-testing.md, including both occurrences, replacing the stale
README-node-testing.md text with Node testing documentation or node-testing.md
while leaving the targets unchanged.

In `@docs/mcp/index.md`:
- Around line 133-140: Update the MCP dependency documentation to match the
published Python contract: in docs/mcp/index.md lines 133-140 and
docs/mcp/readme.md lines 59-65, replace rocketride-client-python with
rocketride>=1.0.4 while keeping the rocketride-mcp installation package
unchanged. docs/internal/clients.md lines 21-25 requires no direct change
because its rocketride-mcp reference already matches the workspace package name.

In `@docs/product/concepts/agents-tools-skills.md`:
- Around line 31-43: Remove the JavaScript // comments from the JSON pipeline
example containing agent_1, llm_1, and tool_1, leaving only valid JSON; preserve
the explanations in the surrounding prose.

In `@docs/product/concepts/execution-model.md`:
- Around line 25-45: Update the “Lane types” section to include the documented
documents lane and define how vector outputs are represented, or explicitly
label the table as non-exhaustive. Keep the lane flow rules consistent with the
chosen scope so valid Qdrant document connections are not presented as invalid.

In `@docs/product/concepts/nodes.md`:
- Around line 52-57: Update the “Swap providers, keep the pipeline” section to
qualify provider swaps: only providers with compatible node contracts, including
class type, supported lanes, control connections, and required configuration,
can preserve the pipeline shape. State that the pipeline must be validated after
changing an LLM or vector-store provider.
- Around line 66-72: Update the “Next steps” section in the markdown so the ##
heading starts at column zero and every top-level list item uses consistent,
zero-level indentation. Preserve the existing links and item text.

In `@docs/product/evaluate/understanding.md`:
- Around line 8-9: Update the opening description of RocketRide’s moving parts
to replace the vague quantity “a small number” with “a few” or “some,” while
preserving the rest of the sentence.

In `@docs/product/glossary.md`:
- Around line 9-92: Update every glossary entry heading in the document,
including Pipeline through WebSocket protocol, from level-three headings (`###`)
to level-two headings (`##`). Preserve the entry content and links unchanged.

In `@docs/product/integrations/aparavi-aql.md`:
- Around line 69-71: Declare the fenced AQL example as SQL by adding the sql
language identifier to its opening code fence, leaving the query content
unchanged.

In `@docs/product/integrations/firecrawl.md`:
- Around line 29-34: Update firecrawl_wrapper’s HTTP 429 retry handling to
enforce a maximum retry count or deadline instead of retrying indefinitely.
Ensure sleeping and retry loops honor task cancellation, and raise or return a
clear rate-limit error once the configured limit is exhausted while preserving
the existing 5xx retry behavior.

In `@docs/product/integrations/neo4j.md`:
- Around line 51-63: Update the Neo4j configuration example’s userpass
credentials to include the required password field alongside user, using a
clearly marked placeholder value.

In `@docs/product/integrations/postgres.md`:
- Around line 68-99: The natural-language Q&A wiring uses the wrong lane between
llm_1 and db_1. Update the db_1 input to consume the LLM’s documented answers
output, or otherwise reorder the graph so db_1 receives questions from a
question-producing node; keep the target_1 answers connection consistent with
the resulting output lanes.

In `@docs/product/integrations/qdrant.md`:
- Around line 90-96: Align the Qdrant configuration example’s serverName with
the documented tool namespace by setting it to qdrant, or update the tool names
to match the configured localhost value. Keep the namespace explanation and tool
table consistent with the selected identifier.

In `@docs/product/quickstart.mdx`:
- Around line 39-42: Update the hard-coded “50+” count in the “Browse nodes”
card to match the canonical node count used by the nodes documentation, or
remove the count and use a shared source of truth. Keep the card’s existing link
and descriptive content unchanged.

In `@docs/product/self-hosting.md`:
- Around line 84-95: Update the startup commands in the self-hosting
documentation to use --host=127.0.0.1 by default for both Linux/macOS and
Windows. Move the 0.0.0.0 binding into a clearly protected external-deployment
example and include the required TLS/authentication controls there.

In `@packages/client-mcp/README.md`:
- Around line 1-4: Update the source document used by the generated MCP README,
docs/mcp/readme.md, by adding a level-one heading and a language identifier such
as text to the diagram fenced block. Then run ./builder docs:export to
regenerate packages/client-mcp/README.md, without editing the generated README
directly.
🪄 Autofix

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: ASSERTIVE

Plan: Pro Plus

Run ID: 5969e77c-8763-4bba-9dc1-bf41a704a164

📥 Commits

Reviewing files that changed from the base of the PR and between 44b5190 and 251501d.

⛔ Files ignored due to path filters (3)
  • docs/images/canvas.png is excluded by !**/*.png
  • docs/images/n8n-configuration-ux.jpg is excluded by !**/*.jpg
  • docs/images/trace.png is excluded by !**/*.png
📒 Files selected for processing (92)
  • .claude/CLAUDE.md
  • .cursorrules
  • .github/SUPPORT.md
  • .github/workflows/ci.yml
  • .github/workflows/docs.yml
  • .gitignore
  • AGENTS.md
  • apps/vscode/scripts/tasks.js
  • docs/README.md
  • docs/agents/ROCKETRIDE_COMPONENT_REFERENCE.md
  • docs/clients/python/analytics.md
  • docs/clients/python/index.md
  • docs/clients/python/log.md
  • docs/clients/python/readme.md
  • docs/clients/typescript/analytics.md
  • docs/clients/typescript/index.md
  • docs/clients/typescript/methods/database-sequelize.md
  • docs/clients/typescript/methods/deploy.md
  • docs/clients/typescript/methods/get-task-status.md
  • docs/clients/typescript/methods/log.md
  • docs/clients/typescript/methods/send.md
  • docs/clients/typescript/methods/terminate.md
  • docs/clients/typescript/methods/use.md
  • docs/clients/typescript/methods/validate.md
  • docs/clients/typescript/readme.md
  • docs/clients/vscode/deployment-webview.md
  • docs/clients/vscode/google-oauth.md
  • docs/clients/vscode/index.md
  • docs/clients/vscode/installation.md
  • docs/clients/vscode/readme.md
  • docs/clients/vscode/usage.md
  • docs/internal/apps.md
  • docs/internal/builder.md
  • docs/internal/clients.md
  • docs/internal/engine-protocol/crash-reporting.md
  • docs/internal/engine-protocol/index.md
  • docs/internal/engine-protocol/observability.md
  • docs/internal/engine.md
  • docs/internal/index.md
  • docs/internal/n8n.md
  • docs/internal/node-schema.md
  • docs/internal/node-testing.md
  • docs/internal/nodes.md
  • docs/internal/pre-commit-hooks.md
  • docs/mcp/index.md
  • docs/mcp/readme.md
  • docs/product/cli.mdx
  • docs/product/cloud.md
  • docs/product/concepts/advanced-agents.md
  • docs/product/concepts/agents-tools-skills.md
  • docs/product/concepts/best-practices.md
  • docs/product/concepts/error-handling.md
  • docs/product/concepts/execution-model.md
  • docs/product/concepts/nodes.md
  • docs/product/concepts/performance.md
  • docs/product/concepts/pipelines.md
  • docs/product/concepts/runtime-engine.md
  • docs/product/concepts/security-model.md
  • docs/product/evaluate/security.md
  • docs/product/evaluate/understanding.md
  • docs/product/evaluate/use-cases.mdx
  • docs/product/evaluate/why-rocketride.md
  • docs/product/examples/document-extraction.md
  • docs/product/examples/rag-pipeline.md
  • docs/product/examples/webhook-pipeline.md
  • docs/product/glossary.md
  • docs/product/ide-extensions/overview.md
  • docs/product/index.mdx
  • docs/product/integrations/anthropic.md
  • docs/product/integrations/aparavi-aql.md
  • docs/product/integrations/firecrawl.md
  • docs/product/integrations/neo4j.md
  • docs/product/integrations/postgres.md
  • docs/product/integrations/qdrant.md
  • docs/product/quickstart.mdx
  • docs/product/self-hosting.md
  • docs/product/troubleshooting.md
  • docs/skills/.gitkeep
  • examples/README.md
  • nodes/src/nodes/tool_n8n/README.md
  • packages/client-mcp/README.md
  • packages/client-mcp/scripts/tasks.js
  • packages/client-python/README.md
  • packages/client-python/scripts/tasks.js
  • packages/client-typescript/README.md
  • packages/client-typescript/scripts/tasks.js
  • packages/docs/scripts/lib/export.js
  • packages/docs/scripts/lib/gather.js
  • packages/docs/scripts/tasks.js
  • packages/docs/src/lib/export.test.mjs
  • packages/docs/src/lib/gather.test.mjs
  • packages/server/scripts/tasks.js
💤 Files with no reviewable changes (6)
  • packages/server/scripts/tasks.js
  • docs/clients/typescript/index.md
  • .gitignore
  • docs/clients/python/index.md
  • docs/clients/vscode/index.md
  • docs/clients/vscode/readme.md

Comment thread docs/clients/python/readme.md Outdated
Comment on lines +1 to +2
<p align="center">
<img src="https://raw.githubusercontent.com/rocketride-org/rocketride-server/main/images/banner-python.png" alt="RocketRide Python SDK" width="900">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a top-level heading to both package READMEs.

Both README sources start with centered image markup, which triggers MD041 and weakens document navigation.

  • docs/clients/python/readme.md#L1-L2: add # RocketRide Python SDK before the banner.
  • docs/clients/typescript/readme.md#L1-L2: add # RocketRide TypeScript SDK before the banner.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

📍 Affects 2 files
  • docs/clients/python/readme.md#L1-L2 (this comment)
  • docs/clients/typescript/readme.md#L1-L2
🤖 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/clients/python/readme.md` around lines 1 - 2, Add a top-level heading
before the banner in docs/clients/python/readme.md (lines 1-2), using the title
“RocketRide Python SDK”; make the same change in
docs/clients/typescript/readme.md (lines 1-2) with “RocketRide TypeScript SDK”.

Source: Linters/SAST tools

Comment on lines +153 to +160
**Example:**

```python
async with RocketRideClient(uri='wss://api.rocketride.ai', auth=os.environ['ROCKETRIDE_APIKEY']) as client:
result = await client.use(filepath='pipeline.pipe')
token = result['token']
await client.send(token, 'Hello, pipeline!')
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Import os in the context-manager example.

Line 156 uses os.environ, but this code block does not import os. A reader who copies the example gets NameError.

🤖 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/clients/python/readme.md` around lines 153 - 160, Update the Python
context-manager example around RocketRideClient to import the os module before
using os.environ, ensuring the example runs without a NameError when copied.

Comment on lines +401 to +405
async def main():
async with RocketRideClient(uri='wss://api.rocketride.ai', auth='my-key') as client:
result = await client.use(pipeline={'pipeline': my_pipeline_config})
token = result['token']
await client.send(token, '{"data": 1}')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
git ls-files | rg '^docs/clients/(python|typescript)/readme\.md$' || true

echo
echo "== python readmes around use examples =="
sed -n '360,420p' docs/clients/python/readme.md

echo
echo "== ts readmes around use examples =="
sed -n '320,370p' docs/clients/typescript/readme.md

echo
echo "== search for rocketride use in docs/sdks/source (if present) =="
rg -n "def use|async def use|RocketRideClient|pipeline.*pipeline|use\(" docs -S || true

Repository: rocketride-org/rocketride-server

Length of output: 50390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== local source files for Python client use implementation =="
git ls-files | rg '(^|/)rocketride(_sdk)?|python|sdk|client|pipelines' | rg '\.(py|ts|tsx|js|jsx)$' | head -200

echo
echo "== search exact use implementation candidates =="
rg -n "async def use|def use|async def start_pipeline|execute|arguments.*pipeline|pipeline.*pipeline" -S --glob '*.py' --glob '*.ts' --glob '*.tsx' | head -200

echo
echo "== focused API docs around use options =="
sed -n '180,205p' docs/clients/python/readme.md
sed -n '160,185p' docs/clients/typescript/readme.md

Repository: rocketride-org/rocketride-server

Length of output: 10466


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== python client outline =="
ast-grep outline packages/client-python/src/rocketride/client.py --view expanded || true

echo
echo "== python client execution/use sections =="
rg -n -C 8 "async def use|def use|pipeline.*pipe|pipeline.*source|pipe.*pipeline|send_request|useExisting|use_existing|pipeline: PipelineConfig|PipelineConfig" packages/client-python/src/rocketride -S

echo
echo "== typescript client use implementation snippets =="
rg -n -C 8 "use\\(|PipelineConfig|filepath|useExisting|pipeline:" packages/client-typescript/src/client -S packages/client-typescript/src/app-sdk -S

echo
echo "== exact lines in focused client files =="
sed -n '1,220p' packages/client-typescript/src/client/client.ts | rg -n -C 6 "use\\(|PipelineConfig|filepath|pipeline" || true

Repository: rocketride-org/rocketride-server

Length of output: 50391


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== python mixin execution =="
sed -n '1,220p' packages/client-python/src/rocketride/mixins/execution.py

echo
echo "== TypeScript client core execution DAP =="
rg -n -C 10 "rrext_execute|execute|filepath|pipeline|useExisting|useExistingTrue" packages/client-typescript/src/client/core -S packages/client-typescript/src/client/client.ts -S

echo
echo "== TypeScript app SDK use signature =="
sed -n '1,220p' packages/client-typescript/src/app-sdk/index.ts

Repository: rocketride-org/rocketride-server

Length of output: 50391


Pass a flat pipeline object in both SDK examples.

client.use(pipeline=...) / { pipeline: ... } expects the pipeline config directly, not the file-wrapper form. This extra nesting makes the Python and TypeScript examples pass the wrong payload; use client.use(pipeline=my_pipeline_config) / { pipeline: myPipelineConfig } instead.

📍 Affects 2 files
  • docs/clients/python/readme.md#L401-L405 (this comment)
  • docs/clients/typescript/readme.md#L351-L359
🤖 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/clients/python/readme.md` around lines 401 - 405, Update the Python
example in docs/clients/python/readme.md at lines 401-405 and the TypeScript
example in docs/clients/typescript/readme.md at lines 351-359 to pass the
pipeline configuration directly to client.use: use my_pipeline_config in Python
and myPipelineConfig in TypeScript, removing the extra pipeline wrapper while
preserving the surrounding example flow.

Comment on lines +540 to +549
async def main():
client = RocketRideClient(uri='https://api.rocketride.ai', auth='my-key')
await client.connect()
services = await client.get_services()
print('Available:', list(services.keys()))
ocr = await client.get_service('ocr')
if ocr:
print('OCR schema:', ocr.get('schema'))
req = client.build_request('rrext_ping', token=my_token)
res = await client.request(req, timeout=5000)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make both custom DAP examples self-contained.

Both snippets use connection and token variables without defining them.

  • docs/clients/python/readme.md#L540-L549: define uri, auth, and my_token.
  • docs/clients/typescript/readme.md#L461-L473: define auth, uri, and myToken.
📍 Affects 2 files
  • docs/clients/python/readme.md#L540-L549 (this comment)
  • docs/clients/typescript/readme.md#L461-L473
🤖 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/clients/python/readme.md` around lines 540 - 549, The custom DAP
examples are not self-contained because their connection and token variables are
undefined. In docs/clients/python/readme.md lines 540-549, define uri, auth, and
my_token before constructing the RocketRideClient or request; in
docs/clients/typescript/readme.md lines 461-473, define auth, uri, and myToken
before their use, preserving each example’s existing client setup and request
flow.

Comment on lines +301 to +308
## Answer

Used to parse chat response content. The client does not attach an `Answer` instance to the pipeline result; you read the response body and, if needed, use these static helpers to extract JSON or code from AI text (which often includes markdown or code fences).

| Method | Signature | Description |
| -------------------- | ------------------------------------ | ------------------------------------------------------- |
| `Answer.parsePython` | `parsePython(value: string): string` | Extracts Python code from a code block in the response. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate files =="
git ls-files | rg '(^|/)readme\.md$|packages/client-typescript/docs|Answer|answer' | head -200

echo
echo "== Relevant docs/clients/typescript/readme.md sections =="
sed -n '240,330p' docs/clients/typescript/readme.md

echo
echo "== Find Answer source references =="
rg -n "class Answer|interface Answer|type Answer|Answer|parsePython|setAnswer|getJson|isJson|getText" docs packages/client-typescript -S | head -300

Repository: rocketride-org/rocketride-server

Length of output: 19029


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Behavioral/source-shape verifier: extract Answer symbol declarations and method signatures from tracked code
python3 - <<'PY'
from pathlib import Path
import re

files = [p for p in Path('.').rglob('*') if p.is_file() and '.git' not in p.parts and p.suffix in {'.ts','.tsx','.js','.jsx','.d.ts','.md'}]
for p in files:
    text = p.read_text(errors='ignore')
    if 'Answer' not in text:
        continue
    if any(part.startswith('node_modules') for part in p.parts):
        continue
    lines = text.splitlines()
    for i,l in enumerate(lines,1):
        if re.search(r'\bAnswer\b', l):
            print(f"{p}:{i}:{l}")
PY

Repository: rocketride-org/rocketride-server

Length of output: 38958


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== TypeScript client Answer definition =="
sed -n '84,176p' packages/client-typescript/src/client/schema/Question.ts

echo
echo "== TypeScript generated declaration =="
sed -n '77,135p' packages/client-typescript/dist/types/schema/Question.d.ts

echo
echo "== docs/clients/typescript/readme.md Answer example region if present =="
sed -n '437,535p' docs/clients/typescript/readme.md

echo
echo "== docs/clients/typescript/readme.md existing Answer reference region =="
sed -n '291,310p' docs/clients/typescript/readme.md

Repository: rocketride-org/rocketride-server

Length of output: 7619


Align the Answer reference with the example.

The example uses new Answer(), setAnswer(), isJson(), getJson(), and getText(), but the Markdown reference only documents Answer.parsePython. Document these instance APIs, or change the example to use static parsing only, because Answer is exported from rocketrideschema/packages/client-typescript and packages/client-typescript/README.md is the co-located generated package readme.

🤖 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/clients/typescript/readme.md` around lines 301 - 308, Align the Answer
documentation with the example by documenting the instance APIs new Answer(),
setAnswer(), isJson(), getJson(), and getText() alongside Answer.parsePython,
using the exported Answer API and the co-located package README as the reference
for accurate signatures and descriptions.

Comment thread docs/internal/node-schema.md Outdated
Comment on lines +16 to +18
> For the catalog of all nodes and how they wire together, see
> [README-nodes.md](README-nodes.md). For testing, see
> [README-node-testing.md](README-node-testing.md).
> [README-nodes.md](nodes.md). For testing, see
> [README-node-testing.md](node-testing.md).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove old README filenames from rendered link text.

The documentation targets now use centralized filenames, but several labels still expose the old README-* names.

  • docs/internal/node-schema.md#L16-L18: rename the README-nodes.md and README-node-testing.md labels.
  • docs/internal/node-schema.md#L57-L58: rename the README-nodes.md label.
  • docs/internal/index.md#L41-L43: rename the README-builder.md label.
📍 Affects 2 files
  • docs/internal/node-schema.md#L16-L18 (this comment)
  • docs/internal/node-schema.md#L57-L58
  • docs/internal/index.md#L41-L43
🤖 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/internal/node-schema.md` around lines 16 - 18, Update the rendered link
text for the README-nodes.md and README-node-testing.md links in
docs/internal/node-schema.md lines 16-18, the README-nodes.md link in
docs/internal/node-schema.md lines 57-58, and the README-builder.md link in
docs/internal/index.md lines 41-43 to use their centralized filenames, while
preserving each link target and surrounding documentation.

Comment thread docs/internal/nodes.md Outdated
> This catalog is compiled by hand from the `services*.json` definitions on `develop`
> (118 node directories → 148 services). For node testing, see
> [README-node-testing.md](README-node-testing.md).
> [README-node-testing.md](node-testing.md).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the stale link labels.

The target is now node-testing.md, but both labels still say README-node-testing.md. Use Node testing documentation or node-testing.md.

Also applies to: 326-326

🤖 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/internal/nodes.md` at line 15, Update the link labels in
docs/internal/nodes.md that target node-testing.md, including both occurrences,
replacing the stale README-node-testing.md text with Node testing documentation
or node-testing.md while leaving the targets unchanged.

Comment thread packages/client-mcp/README.md Outdated
Comment on lines +1 to +4
<!-- GENERATED by `./builder docs:export` — DO NOT EDIT. Source: docs/mcp/readme.md -->

<p align="center">
<img src="https://raw.githubusercontent.com/rocketride-org/rocketride-server/main/images/banner-mcp.png" alt="RocketRide MCP Server" width="900">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the Markdown lint violations in the source document.

Add a level-one heading to docs/mcp/readme.md. Add a language identifier such as text to the diagram fence. Then run ./builder docs:export to regenerate this package README. Do not edit this generated copy directly.

As per coding guidelines, update docs/mcp/readme.md and export the generated package README.

Also applies to: 34-46

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 3-3: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 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 `@packages/client-mcp/README.md` around lines 1 - 4, Update the source document
used by the generated MCP README, docs/mcp/readme.md, by adding a level-one
heading and a language identifier such as text to the diagram fenced block. Then
run ./builder docs:export to regenerate packages/client-mcp/README.md, without
editing the generated README directly.

Sources: Coding guidelines, Linters/SAST tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review continued from previous batch...

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

🛑 Comments failed to post (34)
docs/clients/typescript/methods/database-sequelize.md (1)

80-91: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the model and query agree on the active field.

The model declares only id, name, and email, but findAll() filters on active. Add active to the model or remove the filter. The current copy-paste example can fail when the target table does not contain the undocumented column.

🤖 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/clients/typescript/methods/database-sequelize.md` around lines 80 - 91,
Update the Sequelize model definition for User and its findAll query so they
agree on the active field: either declare active in the model with the
appropriate type or remove the active filter, ensuring the example does not
reference an undocumented column.
docs/clients/typescript/methods/deploy.md (1)

153-160: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the recorded prior version for rollback.

artifact.version! - 1 does not guarantee the previous deployed version. It can select an unpublished version or a different artifact when versions are not contiguous. Read the prior version from deployment history or versions(), then pass that exact version to deploy().

🤖 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/clients/typescript/methods/deploy.md` around lines 153 - 160, Update the
rollback example after the team-prod deployment to obtain the actual prior
deployed version from deployment history or the versions() API, rather than
calculating artifact.version! - 1; pass that recorded version to
client.deploy.deploy while leaving the publish and initial deployment flow
unchanged.
docs/clients/typescript/methods/get-task-status.md (1)

21-40: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document the TypeScript timeout option.

getTaskStatus() accepts options?: { timeout?: number | false }. The default is 15000, and false disables the per-call timeout override, as shown in packages/client-typescript/src/client/client.ts:1622-1636. Add this public parameter to the signature and parameter table.

🤖 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/clients/typescript/methods/get-task-status.md` around lines 21 - 40,
Update the TypeScript getTaskStatus documentation to include the optional
options parameter with timeout?: number | false in the method signature and
parameter table. Document the default timeout as 15000 and state that false
disables the per-call timeout override, while leaving the Python documentation
unchanged.
docs/clients/typescript/methods/send.md (1)

36-36: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add blank lines around the fenced code blocks.

Each fence starts immediately after the preceding content and triggers MD031. Add one blank line before and after each fence.

  • docs/clients/typescript/methods/send.md#L36-L36: add spacing around the send() Python signature fence.
  • docs/clients/typescript/methods/send.md#L114-L114: add spacing around the send_files() Python signature fence.
  • docs/clients/typescript/methods/send.md#L221-L221: add spacing around the pipe() Python signature fence.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 36-36: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

📍 Affects 1 file
  • docs/clients/typescript/methods/send.md#L36-L36 (this comment)
  • docs/clients/typescript/methods/send.md#L114-L114
  • docs/clients/typescript/methods/send.md#L221-L221
🤖 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/clients/typescript/methods/send.md` at line 36, Add blank lines
immediately before and after each fenced Python signature block for send(),
send_files(), and pipe() in docs/clients/typescript/methods/send.md at lines
36-36, 114-114, and 221-221 to satisfy MD031.

Source: Linters/SAST tools

docs/clients/typescript/methods/use.md (1)

130-139: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Check the validation result before starting the pipeline.

The example says to validate first, but it calls client.use() unconditionally. If result['errors'] is non-empty, it still starts the invalid pipeline. Call use() only when validation succeeds.

🤖 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/clients/typescript/methods/use.md` around lines 130 - 139, Update the
example flow around client.use() to inspect result['errors'] after validation
and call use() only when the validation succeeds; preserve the existing behavior
for handling validation failures.
docs/clients/typescript/methods/validate.md (1)

30-34: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the TypeScript signature example.

source? is not valid object-literal syntax. Use source for a variable or source: undefined.

🤖 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/clients/typescript/methods/validate.md` around lines 30 - 34, Update the
TypeScript validate signature example to use valid object-literal syntax by
replacing `source?` with `source` or `source: undefined`, while preserving the
existing validate call structure.
docs/clients/vscode/deployment-webview.md (1)

25-33: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Separate acknowledgment replies from result-bearing RPC replies.

Lines 29-30 say every …Result reply contains only requestId and error. However, deploy:artifactResult, deployment:previewResult, and deployment:validateResult also carry pipeline or result at lines 48, 80, and 82. State that only mutation actionResult replies are acknowledgment-only.

🤖 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/clients/vscode/deployment-webview.md` around lines 25 - 33, Update the
correlation-style documentation to distinguish acknowledgment-only mutation
actionResult replies from result-bearing RPC replies. Revise the statement that
all …Result messages contain only requestId and error, and explicitly preserve
the pipeline or result payloads for deploy:artifactResult,
deployment:previewResult, and deployment:validateResult.
docs/clients/vscode/usage.md (1)

67-71: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked markdown files under docs/clients/vscode:"
git ls-files docs/clients/vscode/**/*.md docs/clients/vscode/readme.md | sed -n '1,80p'

echo
echo "Search for env sync / ROCKETRIDE_APIKEY in VS Code docs and code:"
rg -n "syncs the workspace|\\bROCKETRIDE_APIKEY\\b|\\.env|Python SDK|typescript sdk|typescript SDK|deployment connections|connect|cloud connections" docs clients src . -g '!node_modules' -g '!dist' -g '!build' | sed -n '1,240p'

echo
echo "Locate likely implementation files:"
fd -i 'env|connection|rocketride|sync' . | sed -n '1,200p'

Repository: rocketride-org/rocketride-server

Length of output: 34566


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository root files:"
find . -maxdepth 3 \( -type f -o -type d \) | sed 's#^\./##' | sort | sed -n '1,240p'

echo
echo "Tracked files top-level:"
git ls-files | sed -n '1,200p'

echo
echo "Search all tracked files for .env API key sync behavior:"
rg -n "syncs the workspace|\\.env|ROCKETRIDE_APIKEY|auto-populates|auto-fill|read-only|permissions|chmod|fchmod|unlink|fs\\.write|fs\\.readFileSync|writeFileSync|api:key|apikey" $(git ls-files) | sed -n '1,240p'

Repository: rocketride-org/rocketride-server

Length of output: 42333


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked implementation files under apps/vscode:"
git ls-files apps/vscode | sort | sed -n '1,240p'

echo
echo "Search apps/vscode tracked files for .env / env sync / API key behavior:"
rg -n "\\.env|WORKSPACE|ROCKETRIDE_APIKEY|apiKey|apikey|sync|writefile|writeFileSync|unlink|chmod|permissions|onDisconnect|Disconnect from Server|connect" $(git ls-files apps/vscode) | sed -n '1,260p'

echo
echo "Candidate source files containing env key references (bounded):"
for f in $(git ls-files apps/vscode | rg 'src/.*\.(ts|js|tsx)$|src/.*\.(mjs)$' | sed -n '1,160p'); do
  if rg -q "ROCKETRIDE_APIKEY|\\.env|onDisconnect|Disconnect" "$f"; then
    echo "--- $f"
    wc -l "$f"
  fi
done

Repository: rocketride-org/rocketride-server

Length of output: 45422


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "apps/vscode/src/shared/util/envFile.ts:"
cat -n apps/vscode/src/shared/util/envFile.ts

echo
echo "apps/vscode/src/shared/util/envVarCheck.ts:"
cat -n apps/vscode/src/shared/util/envVarCheck.ts

echo
echo "apps/vscode/src/test/envFile.test.ts:"
cat -n apps/vscode/src/test/envFile.test.ts

echo
echo "Call sites for updateWorkspaceEnvFile / envFile module:"
rg -n "updateWorkspaceEnvFile|envFile|ROCKETRIDE_APIKEY_KEY|ROCKETRIDE_URI" apps/vscode/src | sed -n '1,220p'

echo
echo "connection lifecycle around connects/disconnects/env refresh:"
cat -n apps/vscode/src/connection/connection.ts | sed -n '760,960p'

Repository: rocketride-org/rocketride-server

Length of output: 30429


Sensitive Data Exposure (CWE-922)

Reachability: External

Avoid keeping stale self-hosted credentials on disk.

The extension writes ROCKETRIDE_APIKEY to the workspace .env for development self-hosted connections, but it does not remove the key when disconnecting, exiting, or switching to cloud. Git ignore does not protect local readers, backups, or other processes that auto-load .env. Remove this entry on disconnect or make sync opt-in with clear restricted permissions and warning text.

🤖 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/clients/vscode/usage.md` around lines 67 - 71, Update the documented
`.env` lifecycle for development self-hosted connections so `ROCKETRIDE_APIKEY`
is removed when disconnecting, the engine exits, or switching to cloud; revise
the surrounding guidance to reflect automatic cleanup and avoid instructing
users to remove it manually. Preserve the existing sync behavior and exclusions
for unsupported connection types.
docs/internal/apps.md (1)

44-44: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add language identifiers to all unlabeled fenced blocks.

  • docs/internal/apps.md#L44-L44, #L87-L87, #L246-L246, #L847-L847: use text.
  • docs/internal/engine-protocol/crash-reporting.md#L69-L69: use text; the remaining listed blocks should use bash.
  • docs/mcp/index.md#L74-L74 and docs/mcp/readme.md#L32-L32: use text.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 44-44: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

📍 Affects 4 files
  • docs/internal/apps.md#L44-L44 (this comment)
  • docs/internal/apps.md#L87-L87
  • docs/internal/apps.md#L246-L246
  • docs/internal/apps.md#L847-L847
  • docs/internal/engine-protocol/crash-reporting.md#L69-L69
  • docs/internal/engine-protocol/crash-reporting.md#L93-L93
  • docs/internal/engine-protocol/crash-reporting.md#L116-L116
  • docs/internal/engine-protocol/crash-reporting.md#L125-L125
  • docs/internal/engine-protocol/crash-reporting.md#L148-L148
  • docs/internal/engine-protocol/crash-reporting.md#L162-L162
  • docs/mcp/index.md#L74-L74
  • docs/mcp/readme.md#L32-L32
🤖 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/internal/apps.md` at line 44, Label every currently unlabeled fenced
block with the appropriate language identifier: use text in
docs/internal/apps.md at lines 44, 87, 246, and 847; use text at line 69 and
bash at lines 93, 116, 125, 148, and 162 in
docs/internal/engine-protocol/crash-reporting.md; use text in docs/mcp/index.md
at line 74 and docs/mcp/readme.md at line 32.

Source: Linters/SAST tools

docs/internal/builder.md (1)

967-972: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the incremental examples honor --force.

These conditions skip the build whenever the source hash is unchanged and the output exists. Add !ctx.options?.force to each skip condition so builder ... --force works as documented.

Also applies to: 1124-1128, 1521-1527

🤖 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/internal/builder.md` around lines 967 - 972, Update each
incremental-build skip condition around hasSourceChanged and exists, including
the examples near the referenced locations, to also require !ctx.options?.force.
Preserve the existing unchanged-source and output-exists checks while allowing
builder ... --force to continue with the build.
docs/internal/clients.md (2)

21-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Point the SDK table at the centralized documentation files.

The supplied sources are docs/clients/typescript/readme.md, docs/clients/python/readme.md, and docs/mcp/readme.md, but these links target README-*-client.md files that are not shown in the centralized tree.

🤖 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/internal/clients.md` around lines 21 - 25, Update the SDK table links in
the clients documentation to reference the centralized sources
docs/clients/typescript/readme.md, docs/clients/python/readme.md, and
docs/mcp/readme.md instead of the README-*-client.md targets, preserving the
existing TypeScript, Python, and MCP rows.

74-76: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the relative license links under docs/internal/.

  • docs/internal/clients.md#L74-L76: change ../LICENSE to ../../LICENSE or a valid repository license URL.
  • docs/internal/builder.md#L1884-L1884: change ../LICENSE to ../../LICENSE or a valid repository license URL.
📍 Affects 2 files
  • docs/internal/clients.md#L74-L76 (this comment)
  • docs/internal/builder.md#L1884-L1884
🤖 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/internal/clients.md` around lines 74 - 76, Correct the license links in
docs/internal/clients.md lines 74-76 and docs/internal/builder.md line 1884 by
changing ../LICENSE to ../../LICENSE or another valid repository license URL.
docs/internal/engine-protocol/crash-reporting.md (3)

94-109: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
sed -n '80,120p' docs/internal/engine-protocol/crash-reporting.md || true

echo
echo "== nearby commands with temp installs/priv esc =="
rg -n "sudo install|curl .*github|git clone|tar -xJ|tar -x|g\\+\\+" docs/internal/engine-protocol/crash-reporting.md || true

echo
echo "== repo files maybe about docs check/build =="
git ls-files | rg '(^|/)(Makefile|package\.json|pyproject\.toml|README.*|docs)' | sed -n '1,120p'

Repository: rocketride-org/rocketride-server

Length of output: 6922


🌐 Web query:

rust-minidump releases minidump-stackwalk tar.xz checksum sign

💡 Result:

The rust-minidump project provides SHA-256 checksums for its released artifacts, including minidump-stackwalk files (such as.tar.xz and.zip), but does not provide cryptographic signatures (e.g., GPG/PGP signatures) for these releases [1][2][3]. For each release on GitHub, the project includes a dedicated.sha256 file for each downloadable archive [1]. These files can be used to verify the integrity of the downloaded minidump-stackwalk archives by comparing the computed SHA-256 hash of the downloaded file against the hash provided in the corresponding.sha256 file [1][2]. Example verification workflow: 1. Download the artifact (e.g., minidump-stackwalk-x86_64-unknown-linux-gnu.tar.xz) and its corresponding checksum file (minidump-stackwalk-x86_64-unknown-linux-gnu.tar.xz.sha256) from the GitHub release page [1]. 2. Verify the integrity using the sha256sum command: sha256sum -c minidump-stackwalk-x86_64-unknown-linux-gnu.tar.xz.sha256 [1] The project does not currently implement PGP/GPG signing for its release artifacts [1][2][3].

Citations:


Security Misconfiguration (CWE-494): Download of Code Without Integrity Check

Reachability: External

Verify prebuilt tools before privileged installation.

The rust-minidump fetch uses latest, extracts directly to /tmp, and installs with sudo without a pinned release or integrity check. Pin a release and verify the artifact checksum from that release before tar -xJ -C /tmp and sudo install.

🤖 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/internal/engine-protocol/crash-reporting.md` around lines 94 - 109,
Update the minidump-stackwalk setup to use a specific rust-minidump release
instead of the floating latest endpoint, retrieve that release’s checksum
metadata, and verify the downloaded archive before extraction. Keep extraction
and the privileged install in place only after checksum validation, using the
existing download/install flow and release-specific artifact name.

163-169: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect the documented helper and any nearby call sites for attacker control.
fd -a 'crash-reporting\.md$' . | while read -r f; do
  echo "===== $f ====="
  wc -l "$f"
  sed -n '120,200p' "$f" | cat -n
done

# Check whether $dmp passes directly to minidump-2-core and the core path is user-controlled.
python3 - <<'PY'
from pathlib import Path
import re

for p in Path('.').rglob('crash-reporting.md'):
    if any(part == '.git' for part in p.parts):
        continue
    s = p.read_text()
    m = re.search(r'gdbdump\(\)\{(?s).*?\n\}', s)
    print(f"\nfile={p}")
    print(m.group(0) if m else "gdbdump not found")
PY

# Demonstrative shell behavior: show that the current shell redirection follows a symlink.
tmpdir="$(mktemp -d)"
attacker="/tmp/attacker-core-$(basename "$tmpdir").core"
target="$tmpdir/pwned"
rm -f "$attacker" "$target"
touch "$target"
ln -sf "$target" "$attacker"
(dmp="$tmpdir/mypid.dmp"; core="/tmp/$(basename "$dmp").core"; rm -f "$core"; touch "$core") >/dev/null 2>&1
core="/tmp/$(basename "$attacker").core"
rm -f "$core" "$target"
echo "shell_1_after_setup=$(test -L /tmp/check1.core && test -L /tmp/check1.core && echo yes || echo no)" 2>/dev/null || true
if (dmp="/etc/issue"; core="/tmp/$(basename "$dmp").core"; : > "$core") >/dev/null 2>&1; then
  echo "shell_2_follows_symlink=$(test -f /tmp/issue && echo yes || echo no)"
  rm -f /tmp/issue /tmp/check1.core /tmp/checkissue.core "$attacker" "$target"
else
  echo "shell_2_follows_symlink=no"
fi
rm -rf "$tmpdir"

Repository: rocketride-org/rocketride-server

Length of output: 4055


🌐 Web query:

bash redirection follows symlink /tmp > symlink behavior cat /dev/null > symlink security

💡 Result:

Bash redirection follows symbolic links by design [1][2]. When you perform a redirection (e.g., command > symlink or cat /dev/null > symlink), the underlying operating system system calls (such as open) resolve the path [1][2]. If the target of the redirection is a symbolic link, the shell and the kernel typically follow that link to the destination file and operate on the destination [1][2]. Security Implications: 1. File Overwriting and TOCTOU: Because bash follows symlinks, a malicious actor who can create symlinks in a directory where a privileged process writes can redirect that process to overwrite sensitive files (e.g., /etc/passwd or system logs) [3][4][5]. This is a classic Time-of-Check-Time-of-Use (TOCTOU) vulnerability [6][5]. 2. Protected Symlinks: Many modern Linux systems mitigate this risk by implementing "protected symlinks" (controlled via /proc/sys/fs/protected_symlinks) [5]. When enabled (often set to 1 by default), the kernel restricts the following of symlinks in world-writable sticky directories (like /tmp), preventing users from following links they do not own to files they cannot otherwise access [5]. 3. History Clearing/Evidence Tampering: The pattern cat /dev/null > symlink or ln -sf /dev/null symlink is frequently used in malicious contexts to evade detection by "blackholing" logs or command history files (like ~/.bash_history) [7][8][9]. By pointing a log file to /dev/null via a symlink, any data subsequently written to that path is discarded [8][9]. Best Practices: - Avoid writing to user-controlled directories (like /tmp) if you require security guarantees. - Ensure that system logs and sensitive files have restricted permissions to prevent unauthorized users from replacing them with symlinks. - Be aware that redirecting to a symbolic link that points to a non-existent file will result in the creation of the file at the destination path if the directory exists [10]. If the target does not exist, the shell will treat it as a new file creation [10].

Citations:


🌐 Web query:

bash redirection open O_NOFOLLOW /tmp core dump follow symlink behavior

💡 Result:

The O_NOFOLLOW flag is used in Linux system calls (specifically open(2)) to prevent the kernel from following a symbolic link if it is the terminal (final) component of a path [1][2]. When O_NOFOLLOW is applied, the open operation fails with an ELOOP error if the final component is a symbolic link [1][2]. However, a critical limitation of O_NOFOLLOW is that it only protects the terminal component of a path [1][3]. If a symbolic link exists in any non-terminal component (e.g., in a directory path), the kernel still follows it [1][3]. This behavior has historically led to security vulnerabilities, including symlink attacks where a privileged process might be tricked into writing to or creating files in unintended locations [3][4][5]. Regarding Bash redirections and core dumps: 1. Bash Redirections: Bash standard output redirection (e.g., > or >>) does not inherently apply O_NOFOLLOW [6]. If an attacker creates a symbolic link at the target path, a process (even one with elevated privileges) using standard Bash redirection will typically follow that link and write to the target it points to, provided the process has the necessary permissions [6]. 2. Core Dumps: The Linux kernel has specific protections for core dumps to prevent symlink-based attacks [7][8]. When the kernel writes a core dump, it generally ensures the target file is not a symbolic link and performs checks to prevent overwriting files that are not regular files or have multiple hard links [7][8]. Historically, patches were introduced to the Linux kernel (such as using O_NOFOLLOW and checking link counts) specifically to harden the core dump process against symlink manipulation [9][8]. Modern Linux systems manage core dump naming and location primarily through the sysctl interface (kernel.core_pattern), which is the recommended way to handle core dumps safely [9]. In summary, while O_NOFOLLOW provides protection against terminal symbolic links [1], it is insufficient to prevent vulnerabilities caused by symbolic links in directory paths [3]. Developers and system administrators should rely on more robust path-traversal prevention methods, such as using openat(2) with O_NOFOLLOW, resolving paths explicitly, or using filesystem-level security controls [3][5][10].

Citations:


🌐 Web query:

gnu coreutils minidump-2-core source create file symlink protections O_NOFOLLOW

💡 Result:

The terms mentioned refer to two distinct technical contexts: the security practices within GNU Coreutils and the utility minidump-2-core used for crash debugging [1][2][3]. 1. GNU Coreutils and O_NOFOLLOW In GNU Coreutils, O_NOFOLLOW is a critical flag used to prevent Time-of-Check to Time-of-Use (TOCTOU) vulnerabilities when interacting with file system paths [2][4]. It ensures that an open operation fails if the trailing component of a path is a symbolic link, preventing the utility from inadvertently following a symlink created or swapped by an attacker [4]. For instance, GNU cp employs O_NOFOLLOW when opening source files to ensure that the file being read matches the metadata previously checked [2]. Recent discussions and CVE reports have highlighted that failure to consistently use O_NOFOLLOW—as seen in some alternative implementations like uutils—can lead to security bypasses where a regular file is replaced by a symlink after the initial check [2][5]. Coreutils frequently uses this flag in combination with openat and fstatat to maintain security during directory traversal and file manipulation [3][6]. 2. minidump-2-core minidump-2-core is a tool primarily associated with Google Breakpad, not GNU Coreutils [1][7]. It is used to convert minidump crash files (often generated by applications like Chromium) into core dump files that can be analyzed using standard debuggers like GDB [8][9]. It does not inherently share the symlink protection logic of GNU Coreutils, as its function is format conversion rather than general-purpose file system management [1][10]. Recent updates to minidump-2-core have focused on preserving NT_FILE notes to improve GDB's ability to locate debug symbols and PIE displacement, rather than file-system-level symlink hardening [11][7].

Citations:


🌐 Web query:

breakpad minidump-2-core.cc create file open O_NOFOLLOW O_TRUNC write

💡 Result:

In the Google Breakpad source code, specifically within the src/tools/linux/md2core/minidump-2-core.cc file, the tool opens the output file using the open system call with the following flags: O_WRONLY, O_CREAT, and O_TRUNC [1]. The code snippet from minidump-2-core.cc is: options->out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0664); [1] The O_NOFOLLOW flag is not used in this specific open call in minidump-2-core.cc [1]. For context, these flags function as follows on Linux: - O_WRONLY: Opens the file for write-only access [2]. - O_CREAT: Creates the file if it does not exist [2]. - O_TRUNC: If the file already exists and is a regular file, it truncates the file to zero length [2]. While O_NOFOLLOW is a standard POSIX flag that prevents the open call from succeeding if the trailing component of the path is a symbolic link [2], it is absent from the file-opening logic in this Breakpad tool [1].

Citations:


🌐 Web query:

Breakpad minidump-2-core.cc O_NOFOLLOW output file open

💡 Result:

The Google Breakpad tool minidump-2-core (located at src/tools/linux/md2core/minidump-2-core.cc) does not use the O_NOFOLLOW flag when opening the output file [1][2][3]. By design, this utility primarily reads a minidump file and outputs the generated core dump to standard output (stdout), as indicated by the usage documentation: "Usage: minidump-2-core [-v] 1234.dmp > core" [4][2]. While the command-line interface provides an option (-o) to write the coredump to a specified file, the implementation does not utilize O_NOFOLLOW in its file opening operations [1]. O_NOFOLLOW is a POSIX/Linux flag for the open system call that causes the operation to fail if the path being opened is a symbolic link, a mechanism used to prevent symlink-based security vulnerabilities [5]. Although this flag is available in many environments [6], it is not present in the source code of minidump-2-core.cc [1][3]. If you are modifying this tool and intend to use O_NOFOLLOW, ensure your target platform supports it, or implement a wrapper if cross-platform compatibility (such as with systems lacking O_NOFOLLOW) is required [7].

Citations:


🌐 Web query:

Breakpad md2core minidump-2-core.cc output_file open O_NOFOLLOW O_TRUNC

💡 Result:

In the Google Breakpad source code, the tool md2core (specifically the minidump-2-core.cc file) uses the open system call with the flags O_WRONLY | O_CREAT | O_TRUNC to create or overwrite the output core file [1]. These flags perform the following operations: - O_WRONLY: Opens the file for write-only access [2]. - O_CREAT: Creates the file if it does not already exist [2]. - O_TRUNC: If the file already exists and is a regular file, it truncates the file to length 0, effectively overwriting it [2]. The O_NOFOLLOW flag is not typically used in this specific open call within the master branch of minidump-2-core.cc [1]. If O_NOFOLLOW were present, it would cause the open to fail if the path provided were a symbolic link [2]. The minidump-2-core utility is designed to convert a Linux minidump file into a core file that can be read by debuggers like GDB [3][4][5]. If an output file is specified, the tool attempts to open it for writing using the aforementioned flags; if the output file is not specified or is provided as "-", it defaults to using STDOUT_FILENO [1].

Citations:


Security Misconfiguration (CWE-377): Insecure Temporary File

Reachability: External

Use O_NOFOLLOW or avoid predictable /tmp paths for the converted core.

$dmp determines /tmp/$(basename "$dmp").core, and minidump-2-core opens the output with O_WRONLY | O_CREAT | O_TRUNC without rejecting symlinks. If an attacker can place a symlink at that path in /tmp, the core conversion can truncate or overwrite the symlink target. Generate the core path with mktemp/O_NOFOLLOW and add a cleanup trap.

🤖 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/internal/engine-protocol/crash-reporting.md` around lines 163 - 169,
Update the gdbdump function’s converted-core handling to avoid the predictable
/tmp/$(basename "$dmp").core path: create a unique temporary file with mktemp,
ensure conversion cannot follow an attacker-controlled symlink, and register a
cleanup trap to remove the temporary core on exit while preserving the existing
gdb invocation.

166-167: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the referenced example and nearby context without altering the repository.
if [ -f docs/internal/engine-protocol/crash-reporting.md ]; then
  echo "== file exists =="
  wc -l docs/internal/engine-protocol/crash-reporting.md
  echo "== lines 130-190 =="
  sed -n '130,190p' docs/internal/engine-protocol/crash-reporting.md | nl -ba -v130
else
  echo "missing docs/internal/engine-protocol/crash-reporting.md"
fi

# Demonstrate the deterministic injection behavior for the exact source pattern used.
python3 - <<'PY'
import subprocess, os, tempfile

bad_paths = [
    "bin;print('INJECTED');x='",
    "bin';print('INJECTED') #='",
]

for path in bad_paths:
    snippet = f"import json,sys,os;b=os.path.basename('{path}');print(next(m['base_addr'] for m in json.load(sys.stdin)['modules'] if b in (m['filename'] or '')))"
    try:
        subprocess.run(["python3", "-c", snippet], input=b"{}", capture_output=True, text=True, timeout=2)
        print("path:", repr(path), "-> no exception (unexpected)")
    except Exception as exc:
        print("path:", repr(path), "python code:", repr(snippet), "exception type:", type(exc).__name__)
        print("stderr first 200 chars:", exc.stderr[:200])
PY

Repository: rocketride-org/rocketride-server

Length of output: 301


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== lines 130-190 =="
awk 'NR>=130 && NR<=190 { printf "%5d\t%s\n", NR, $0 }' docs/internal/engine-protocol/crash-reporting.md

echo "== exact snippet around referenced lines =="
awk 'NR>=162 && NR<=172 { printf "%5d\t%s\n", NR, $0 }' docs/internal/engine-protocol/crash-reporting.md

echo "== deterministic injection behavior for exact source pattern =="
python3 - <<'PY'
import subprocess

for path in [
    'bin;print("INJECTED");x="',
    "bin';print('INJECTED') #='",
]:
    snippet = f"import json,sys,os;b=os.path.basename('{path}');print(next(m['base_addr'] for m in json.load(sys.stdin)['modules'] if b in (m['filename'] or '')))"
    try:
        result = subprocess.run(
            ["python3", "-c", snippet],
            input=b"{}",
            capture_output=True,
            text=True,
            timeout=2,
        )
        print("path:", repr(path), "exit_code:", result.returncode, "stdout:", result.stdout.strip())
    except Exception as exc:
        print("path:", repr(path), "exception:", type(exc).__name__, "stderr:", exc.stderr.strip())
PY

Repository: rocketride-org/rocketride-server

Length of output: 4519


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== deterministic Python source injection behavior with stdin encoded text =="
python3 - <<'PY'
import subprocess

for path in [
    'bin;print("INJECTED")\nx="',
    "bin';print('INJECTED') #='",
]:
    snippet = f"import json,sys,os;b=os.path.basename('{path}');print(next(m['base_addr'] for m in json.load(sys.stdin)['modules'] if b in (m['filename'] or '')))"
    print("path:", repr(path))
    print("python code:", repr(snippet), "\n")
    result = subprocess.run(["python3", "-c", snippet], input="{}", capture_output=True, text=True, timeout=2)
    print("stdout:", result.stdout.strip())
    print("stderr:", result.stderr.strip())
    print("---")
PY

echo "== static check for injection indicators in snippet =="
python3 - <<'PY'
from pathlib import Path
text = Path("docs/internal/engine-protocol/crash-reporting.md").read_text()
needle = "b=os.path.basename('$bin')"; print("needle found:", needle in text)
PY

Repository: rocketride-org/rocketride-server

Length of output: 1285


Injection (CWE-94): Improper Control of Generation of Code ('Code Injection')

Reachability: External

Pass $bin to Python as data, not source code.

A quote in $bin can terminate the Python string and execute injected statements. Pass the path through an environment variable or standard input.

🤖 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/internal/engine-protocol/crash-reporting.md` around lines 166 - 167,
Update the minidump base-address extraction command so the `$bin` path is passed
to Python as data via an environment variable or standard input, not
interpolated into the Python source string; preserve the existing module
filename matching and base_addr lookup behavior.
docs/internal/engine-protocol/index.md (2)

20-42: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
fd -a 'index\.md$' docs/internal/engine-protocol || true

echo "== target excerpt =="
if [ -f docs/internal/engine-protocol/index.md ]; then
  nl -ba docs/internal/engine-protocol/index.md | sed -n '1,140p'
fi

echo "== engine protocol references to data/payload/base64/frame =="
rg -n --glob '*.md' 'engine protocol|data|payload|binary|frame|base64|WebSocket|open|read|write|json' docs/internal/engine-protocol .github docs/internal 2>/dev/null | head -n 200

echo "== files under docs/internal/engine-protocol =="
find docs/internal/engine-protocol -type f -print | sort

Repository: rocketride-org/rocketride-server

Length of output: 311


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== target excerpt =="
if [ -f docs/internal/engine-protocol/index.md ]; then
  cat -n docs/internal/engine-protocol/index.md | sed -n '1,180p'
fi

echo "== engine protocol references to data/payload/base64/frame/binary =="
rg -n --glob '*.md' 'engine protocol|raw file|file bytes|payload|binary|frame|base64|data"|"data|WebSocket|open|read|write|json' docs/internal/engine-protocol docs/internal .github 2>/dev/null || true

echo "== files under docs/internal/engine-protocol =="
find docs/internal/engine-protocol -type f -print | sort

echo "== all protocol files =="
find docs/internal -type f -print | sort

Repository: rocketride-org/rocketride-server

Length of output: 48069


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== search engine protocol implementation references to rrext_process write/data/auth =="
rg -n 'rrext_process|DAP|HandleDAP|data|Base64|base64|binary|write|auth|websocket|WebSocket|JsonMessage|jsonMessage' . \
  -g '!node_modules' -g '!dist' -g '!build' -g '!coverage' -g '!*.min.js' | head -n 300

echo "== files matching protocol-related names =="
git ls-files | rg -i 'protocol|dap|engine|service|websocket|client|sdk' | sed -n '1,200p'

Repository: rocketride-org/rocketride-server

Length of output: 44820


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in apps/chat-ui/src/hooks/clientSingleton.ts apps/dropper-ui/src/hooks/clientSingleton.ts apps/test-ui/src/engine.ts apps/vscode/src/shared/types/protocol.ts apps/vscode/src/engine/service/engine-service.ts; do
  if [ -f "$f" ]; then
    echo "== $f =="
    wc -l "$f"
    sed -n '1,240p' "$f" | cat -n
  fi
done

Repository: rocketride-org/rocketride-server

Length of output: 50390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate DAP transport/client implementation files =="
git ls-files | rg -E '(^|/)(DAPClient|DAP|dap|websocket|WebSocket|engine-client|protocol)\.(ts|tsx|mjs|js|py|cpp)$' || true

echo "== search send/write/base64 encoding in candidate transport/client dirs =="
rg -n -i 'base64|Buffer|Uint8Array|ArrayBuffer|write\(|send\(|stringFrom|toBase6|WebSocket|writeRequest|DAPClient|Request|arguments|data' \
  $(git ls-files | rg -E '(^|/)(DAPClient|DAP|dap|websocket|WebSocket|engine-client|protocol)\.(ts|tsx|mjs|js|py|cpp)$' | tr '\n' ' ') \
  --max-count 200 || true

Repository: rocketride-org/rocketride-server

Length of output: 614


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== all source files by likely transport/client names =="
find . \( -path './node_modules' -o -path './dist' -o -path './build' \) -prune -o \
  \( -type f \( -path '*DAPClient*' -o -path '*DAP*' -o -path '*dap*' -o -path '*WebSocket*' -o -path '*websocket*' -o -path '*engine-client*' -o -path '*protocol*' \) \
     \( -name '*.ts' -o -name '*.tsx' -o -name '*.mjs' -o -name '*.js' -o -name '*.py' -o -name '*.cpp' \) \) \
  -print | sort | sed -n '1,160p'

echo "== exact searches =="
rg -n 'class DAPClient|function DAPClient|DAPClient|writeRequest|sendRequest|data.*base64|toBase64|fromBase64|Buffer\.from|Buffer\.encoding|Uint8Array|ArrayBuffer|textDecoder|textEncoder|message.data|arguments.data|websocket|WebSocket' \
  apps packages nodes server apps/vscode src packages 2>/dev/null \
  --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!coverage' | sed -n '1,260p'

Repository: rocketride-org/rocketride-server

Length of output: 33167


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== TypeScript TransportBase and TransportWebSocket relevant source =="
sed -n '80,135p' packages/client-typescript/src/client/core/TransportBase.ts
sed -n '550,620p' packages/client-typescript/src/client/core/TransportWebSocket.ts

echo "== Python DAP transport relevant source =="
rg -n -A80 -B20 'data|bytes|arguments|WebSocket|rrext_process|write|base64|encoding' packages/client-python/src/rocketride/core packages/ai/src/ai/common/dap | sed -n '1,260p'

echo "== read-only behavioral model from source snippets =="
python3 - <<'PY'
from pathlib import Path
base = Path('packages/client-typescript/src/client/core')
for path in ['TransportBase.ts', 'TransportWebSocket.ts']:
    text = (base / path).read_text()
    print(f'== {path} contains textEncoder/header/blob/prefixed binary? ==')
    for needle in ['TextEncoder', 'header', 'blob', 'Uint8Array', 'data instanceof Uint8Array', 'message.arguments?.data']:
        print(f'{needle}: {needle in text}')
PY

Repository: rocketride-org/rocketride-server

Length of output: 29660


Document the binary data framing mode.

data is transmitted as raw binary after the JSON header, not as an in-JSON value. Add an example/request body for subcommand: "write" or a write example so non-SDK clients know how to construct valid requests.

🤖 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/internal/engine-protocol/index.md` around lines 20 - 42, Update the
Message format/Requests documentation to state that binary data is sent as raw
bytes after the JSON header rather than embedded in the JSON object. Add a
concrete subcommand "write" request example showing the JSON header and
subsequent binary payload framing, so non-SDK clients can construct valid
requests.

21-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files 'docs/internal/engine-protocol/*' || true

echo
echo "index.md relevant sections:"
if [ -f docs/internal/engine-protocol/index.md ]; then
  nl -ba docs/internal/engine-protocol/index.md | sed -n '1,120p'
fi

echo
echo "Search for auth/open/token mentions in engine protocol docs:"
rg -n "auth|open|token|ROCKETRIDE_APIKEY|ROCKETRIDE_URI|arguments" docs/internal/engine-protocol -S || true

echo
echo "Search code examples/references for engine protocol auth/open request shapes:"
rg -n '"auth"|auth"|open"|ROCKETRIDE_APIKEY|ROCKETRIDE_URI|arguments\.token' -S . \
  -g '!node_modules' -g '!dist' -g '!build' | head -n 200

Repository: rocketride-org/rocketride-server

Length of output: 382


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Index.md around relevant lines:"
nl -ba docs/internal/engine-protocol/index.md | sed -n '1,80p'

echo
echo "All engine-protocol docs files:"
git ls-files 'docs/internal/engine-protocol/*'

Repository: rocketride-org/rocketride-server

Length of output: 242


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Index.md lines 1-90:"
awk '{printf "%5d\t%s\n", NR, $0}' docs/internal/engine-protocol/index.md | sed -n '1,90p'

echo
echo "All engine-protocol docs files:"
git ls-files 'docs/internal/engine-protocol/*'

echo
echo "Relevant doc mentions:"
rg -n -C 3 '(auth|open|token|ROCKETRIDE_APIKEY|ROCKETRIDE_URI|arguments)' docs/internal/engine-protocol/index.md docs/internal/engine-protocol -S || true

echo
echo "Code/example references:"
rg -n -C 2 '(auth|open|token|ROCKETRIDE_APIKEY|ROCKETRIDE_URI|arguments)' . \
  -g '!node_modules' -g '!dist' -g '!build' -g '!*.lock' | head -n 240 || true

Repository: rocketride-org/rocketride-server

Length of output: 41315


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate WebSocket/SDK files:"
git ls-files | rg '(^|/)websocket|rocker|rocket|sdk|client|engine' | head -n 200

echo
echo "Search for rrext_process/open request construction:"
rg -n -C 3 'rrext_process|subcommand.*open|subcommand":\s*"open|arguments.*token|token.*seq|seq.*token|TASK_STATUS|TASK' packages scripts tools packages packages | head -n 300 || true

Repository: rocketride-org/rocketride-server

Length of output: 8984


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "RRExt process/open token construction:"
rg -n -C 4 'rrext_process|subcommand.*open|subcommand":\s*"open|arguments.*token|token.*seq|seq.*token|use|send|write|terminate|close' packages/client-python packages/client-mcp apps packages nodes apps/vscode/src/rocketride packages/ai -S | head -n 600 || true

echo
echo "WebSocket implementation candidates:"
git ls-files | rg '(websocket|wss|WebSocket|rocketride).*\.(ts|js|py|mjs|tsx)$' | head -n 200

echo
echo "Client implementation snippets around WebSocket:"
for f in $(git ls-files | rg 'packages/(client-python|client-mcp)/src/rocketride|packages/client-mcp/src/rocketride_mcp|packages/ai/src/ai/modules|apps/vscode/src/engine' | head -n 200); do
  if rg -q 'rrext_process|open|write|token' "$f" 2>/dev/null; then
    echo "--- $f"
    rg -n -C 3 'rrext_process|open|write|token|WebSocket|send' "$f" | head -n 120
  fi
done | head -n 1200

Repository: rocketride-org/rocketride-server

Length of output: 50391


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Python client call/open snippets:"
python3 - <<'PY'
from pathlib import Path
for p in Path('packages/client-python/src/rocketride').rglob('*.py'):
    text = p.read_text(errors='ignore')
    if 'rrext_process' in text or 'subcommand' in text and 'open' in text:
        print(f'-- {p}')
        for i, line in enumerate(text.splitlines(), 1):
            if any(k in line for k in ['rrext_process', 'subcommand', 'token', 'use', 'send', 'terminate', '_run']):
                start=max(1,i-4); end=min(len(text.splitlines()), i+5)
                lines=text.splitlines()
                print(f'{start}-{end}:')
                for j in range(start,end+1):
                    print(f'{j}\t{lines[j-1]}')
PY

echo
echo "MCP/client snippets around open token:"
python3 - <<'PY'
from pathlib import Path
for subdir in ('packages/client-mcp/src/rocketride_mcp','packages/client-python/src/rocketride'):
    path=Path(subdir)
    if not path.exists(): continue
    for fn in path.rglob('*'):
        if not fn.is_file(): continue
        text=fn.read_text(errors='ignore')
        if 'subcommand' in text and 'open' in text:
            print(f'-- {fn}')
            for i,line in enumerate(text.splitlines(),1):
                if any(s in line for s in ['rrext_process','subcommand','open','token','WebSocket','WebSocketClient','send']):
                    lines=text.splitlines()
                    for j in range(max(1,i-4), min(len(lines), i+8)+1):
                        print(f'{j}\t{lines[j-1]}')
PY

echo
echo "Candidate implementation snippets filtered:"
python3 - <<'PY'
patterns=['rrext_process','task_token','body.*task','open.*token']
for fn in ['packages/client-python/src/rocketride/client.py','packages/client-python/src/rocketride/mixins/use.py','packages/client-mcp/src/rocketride_mcp/server.py']:
    p=Path(fn)
    if not p.exists(): continue
    print(f'-- {fn}')
    try:
        lines=p.read_text(errors='ignore').splitlines()
    except Exception as e:
        print(e)
        continue
    for i,line in enumerate(lines,1):
        if any(q in line for q in patterns):
            for j in range(max(1,i-6), min(len(lines), i+10)+1):
                print(f'{j}\t{lines[j-1]}')
PY

Repository: rocketride-org/rocketride-server

Length of output: 50389


Clarify the open token flow.

The auth text says task requests must use the token returned by open, but the open request example sends $ROCKETRIDE_APIKEY as arguments.token. Add the authenticated frame, the open response, and a later request, or state that open intentionally uses the API key.

🤖 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/internal/engine-protocol/index.md` around lines 21 - 25, Clarify the
token flow in the Auth section of index.md by making the documented examples
consistent: show the authenticated frame, the open response containing its task
token, and a subsequent task request using that token, or explicitly state that
open intentionally uses the API key in arguments.token.
docs/internal/engine-protocol/observability.md (1)

107-111: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use repository paths for the authoritative SDK types.

The listed paths omit packages/, while the SDKs are located under packages/client-typescript and packages/client-python. Update the references to paths that contributors can open directly.

🤖 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/internal/engine-protocol/observability.md` around lines 107 - 111,
Update the authoritative SDK type references in the observability documentation
to include the packages/ directory, using
packages/client-typescript/src/client/types/events.ts,
packages/client-python/src/rocketride/types/events.py, and the corresponding
task module paths so contributors can open them directly.
docs/internal/node-testing.md (2)

27-28: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the MD031 fenced-block warnings.

Add a blank line before each fenced code block at the reported locations. This is required by the configured markdownlint rule.

Also applies to: 92-93, 100-101, 140-141, 178-179, 183-184

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 28-28: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 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/internal/node-testing.md` around lines 27 - 28, Add a blank line before
every fenced code block in docs/internal/node-testing.md at the reported
locations, including the block following “Run tests:” and the additional listed
ranges, to satisfy the MD031 markdownlint rule without changing the code block
contents.

Source: Linters/SAST tools


27-34: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the repository-local builder command.

The neighboring internal setup guide uses ./builder, but this file repeatedly uses builder. A clean checkout does not place the repository root on PATH. Use ./builder in the quick-start, contract-test, and integration-test examples, or document the required global installation.

Also applies to: 408-440

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 28-28: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 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/internal/node-testing.md` around lines 27 - 34, Update the builder
command examples throughout docs/internal/node-testing.md, including the
quick-start, contract-test, and integration-test examples, to invoke the
repository-local script with ./builder instead of builder. Keep the existing
commands and descriptions unchanged otherwise.
docs/mcp/index.md (1)

133-140: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(docs/mcp/(index\.md|readme\.md)|docs/internal/clients\.md|.*README.*\.md|.*pyproject\.toml|.*setup\.py|.*setup\.cfg|.*release.*|.*CHANGELOG.*|.*VERSION.*)' 

echo
echo "== targeted docs snippets =="
for f in docs/mcp/index.md docs/mcp/readme.md docs/internal/clients.md; do
  if [ -f "$f" ]; then
    echo "--- $f"
    nl -ba "$f" | sed -n '1,220p' | rg -n -C 4 'python 3.10|rocketride-mcp|rocketride-client-python|rocketride|python-client|mcp-client|clients\.md|Document|--'
  else
    echo "missing $f"
  fi
done

echo
echo "== package dependency declarations =="
git ls-files | rg '(^|/)(pyproject\.toml|setup\.py|setup\.cfg|requirements.*|Pipfile|poetry\.lock|pnpm-lock\.yaml|package\.json|yarn\.lock)$' | while read -r f; do
  echo "--- $f"
  rg -n -C 2 'rocketride(-client-)?python|rocketride-mcp|rocketride|python_requires|requires-python' "$f" || true
done

Repository: rocketride-org/rocketride-server

Length of output: 6991


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tracked markdown docs mentioning rocketride packages =="
rg -n 'rocketride(-client-python|-mcp)?\s*(>=|>|=|<|~|==|>=? )?[0-9]|requires.*python|Python 3\.10' docs README.md docs/mcp docs/internal -g '*.md' || true

echo
echo "== exact lines with rocketride occurrences in relevant files =="
python3 - <<'PY'
from pathlib import Path
roots = ['docs/mcp/index.md','docs/mcp/readme.md','docs/internal/clients.md','README-python-client.md','README-mcp-client.md','README-typescript-client.md']
for r in roots:
    p=Path(r)
    if p.exists():
        print(f'--- {r}')
        lines=p.read_text(errors='replace').splitlines()
        for i,l in enumerate(lines,1):
            if 'rocketride' in l.lower():
                print(f'{i}: {l}')
PY

Repository: rocketride-org/rocketride-server

Length of output: 13050


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== client-mcp pyproject =="
cat packages/client-mcp/pyproject.toml

echo
echo "== client-python pyproject =="
cat packages/client-python/pyproject.toml

echo
echo "== workspace pyproject snippets =="
python3 - <<'PY'
from pathlib import Path
for p in Path('.').rglob('pyproject.toml'):
    if '.git' in p.parts:
        continue
    txt=p.read_text(errors='replace').splitlines()
    hits=[i for i,l in enumerate(txt,1) if 'rocketride-client-python' in l or 'rocketride-mcp' in l or '[tool.poetry.dependencies' in l or 'packages/client-python' in l]
    if hits:
        print(f'--- {p}')
        for i in hits:
            start=max(1,i-3); end=min(len(txt),i+5)
            for n in range(start,end+1):
                print(f'{n}: {txt[n-1]}')
PY

Repository: rocketride-org/rocketride-server

Length of output: 4140


Use the published MCP Python dependency contract.

packages/client-mcp/pyproject.toml declares rocketride>=1.0.4, not rocketride-client-python. Update the MCP docs to:

  • docs/mcp/index.md
  • docs/mcp/readme.md

docs/internal/clients.md#L21-L25 uses rocketride-mcp, which matches the workspace package name.

📍 Affects 3 files
  • docs/mcp/index.md#L133-L140 (this comment)
  • docs/mcp/readme.md#L59-L65
  • docs/internal/clients.md#L21-L25
🤖 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/mcp/index.md` around lines 133 - 140, Update the MCP dependency
documentation to match the published Python contract: in docs/mcp/index.md lines
133-140 and docs/mcp/readme.md lines 59-65, replace rocketride-client-python
with rocketride>=1.0.4 while keeping the rocketride-mcp installation package
unchanged. docs/internal/clients.md lines 21-25 requires no direct change
because its rocketride-mcp reference already matches the workspace package name.
docs/product/concepts/agents-tools-skills.md (1)

31-43: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

awk '/^```json$/{inside=1; next} inside && /^```$/{exit} inside{print}' \
  docs/product/concepts/agents-tools-skills.md | jq empty

Repository: rocketride-org/rocketride-server

Length of output: 231


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '25,48p' docs/product/concepts/agents-tools-skills.md | cat -n

Repository: rocketride-org/rocketride-server

Length of output: 1211


Make the pipeline example valid JSON.

The json block includes JavaScript // comments, which are invalid JSON. Remove the comments and keep the explanations in the surrounding prose so users can copy the example into a .pipe file without parse errors.

🤖 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/product/concepts/agents-tools-skills.md` around lines 31 - 43, Remove
the JavaScript // comments from the JSON pipeline example containing agent_1,
llm_1, and tool_1, leaving only valid JSON; preserve the explanations in the
surrounding prose.
docs/product/concepts/execution-model.md (1)

25-45: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Complete or qualify the lane-type table.

This page presents the table as the lane-type catalog, but it omits documents, which this PR uses in docs/product/concepts/best-practices.md Lines 91-92 and docs/product/integrations/qdrant.md Lines 67-71. The transformation section also introduces vectors without defining their lane representation. Add all supported lane types, or label the table as non-exhaustive. Otherwise users can treat a valid Qdrant connection as invalid.

Based on the lane definitions in docs/product/concepts/best-practices.md and docs/product/integrations/qdrant.md, documents is a documented lane but is absent here.

🤖 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/product/concepts/execution-model.md` around lines 25 - 45, Update the
“Lane types” section to include the documented documents lane and define how
vector outputs are represented, or explicitly label the table as non-exhaustive.
Keep the lane flow rules consistent with the chosen scope so valid Qdrant
document connections are not presented as invalid.
docs/product/concepts/nodes.md (2)

52-57: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restrict provider swaps to compatible node contracts.

Lines 18-19 state that provider determines supported lanes, but Lines 54-57 say that changing providers does not change the pipeline shape. A provider change can alter class type, lanes, control connections, and required configuration. State that only providers with compatible contracts can be swapped, and require validation after the change.

Based on the provider and lane statements in Lines 18-19, provider changes are not inherently shape-preserving.

🤖 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/product/concepts/nodes.md` around lines 52 - 57, Update the “Swap
providers, keep the pipeline” section to qualify provider swaps: only providers
with compatible node contracts, including class type, supported lanes, control
connections, and required configuration, can preserve the pipeline shape. State
that the pipeline must be validated after changing an LLM or vector-store
provider.

66-72: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the heading and list indentation.

## Next steps has a leading space, and the list items use inconsistent indentation. This triggers MD023 and MD005. Remove leading spaces from the heading and all top-level list items.

Proposed formatting fix
- ## Next steps
+## Next steps
 
- - [Nodes](/nodes): what sits on each lane.
- [Agents & tools](/concepts/agents-tools-skills): the control-plane nodes.
- [Execution model](/concepts/execution-model): how lanes carry data between
-  nodes.
- [Pipeline JSON reference](/pipeline-reference): every field of a node.
+- [Nodes](/nodes): what sits on each lane.
+- [Agents & tools](/concepts/agents-tools-skills): the control-plane nodes.
+- [Execution model](/concepts/execution-model): how lanes carry data between
+  nodes.
+- [Pipeline JSON reference](/pipeline-reference): every field of a node.

Based on markdownlint-cli2 output, Line 66 violates MD023 and Lines 69-72 violate MD005.

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 66-66: Headings must start at the beginning of the line

(MD023, heading-start-left)


[warning] 69-69: Inconsistent indentation for list items at the same level
Expected: 1; Actual: 0

(MD005, list-indent)


[warning] 70-70: Inconsistent indentation for list items at the same level
Expected: 1; Actual: 0

(MD005, list-indent)


[warning] 72-72: Inconsistent indentation for list items at the same level
Expected: 1; Actual: 0

(MD005, list-indent)

🤖 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/product/concepts/nodes.md` around lines 66 - 72, Update the “Next steps”
section in the markdown so the ## heading starts at column zero and every
top-level list item uses consistent, zero-level indentation. Preserve the
existing links and item text.

Source: Linters/SAST tools

docs/product/glossary.md (1)

9-92: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use H2 headings for glossary entries.

The first glossary entry skips from H1 to H3. Change each ### entry heading to ## so the page has a valid heading hierarchy.

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 9-9: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 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/product/glossary.md` around lines 9 - 92, Update every glossary entry
heading in the document, including Pipeline through WebSocket protocol, from
level-three headings (`###`) to level-two headings (`##`). Preserve the entry
content and links unchanged.

Source: Linters/SAST tools

docs/product/integrations/aparavi-aql.md (1)

69-71: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Declare the code-block language.

Mark this AQL example as sql. This resolves MD040 and enables syntax highlighting.

Proposed fix
-```
+```sql
 SELECT cols FROM STORE [WHERE cond] [WHICH CONTAIN 'term'] [GROUP BY col] [HAVING cond] [ORDER BY col ASC|DESC] [LIMIT n]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.


🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 69-69: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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/product/integrations/aparavi-aql.md` around lines 69 - 71, Declare the
fenced AQL example as SQL by adding the sql language identifier to its opening
code fence, leaving the query content unchanged.

Source: Linters/SAST tools

docs/product/integrations/firecrawl.md (1)

29-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

fd -HI '^tool_firecrawl$' nodes | while IFS= read -r node_dir; do
  ast-grep outline "$node_dir" --items all || true
  rg -n -C 6 '429|retry|sleep|timeout|cancel|FirecrawlApp' "$node_dir"
done

Repository: rocketride-org/rocketride-server

Length of output: 8673


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the exact file and the wrapper implementation context.
wc -l docs/product/integrations/firecrawl.md nodes/src/nodes/tool_firecrawl/utils.py nodes/src/nodes/tool_firecrawl/README.md
sed -n '1,80p' docs/product/integrations/firecrawl.md
sed -n '1,105p' nodes/src/nodes/tool_firecrawl/utils.py
sed -n '1,120p' nodes/src/nodes/tool_firecrawl/README.md

# Search for wrapper call sites and abort/cancellation handling in the Firecrawl node.
rg -n -C 8 'firecrawl_wrapper|`@tool_function`|cancel|abort|Timeout|signal|Thread|Task|firecrawl' nodes/src/nodes/tool_firecrawl

Repository: rocketride-org/rocketride-server

Length of output: 28476


Bound rate-limit retries.

firecrawl_wrapper catches the 429 rate-limit exception and loops with time.sleep(base_delay) without an attempt limit, cancellation, or timeout. Add a retry deadline or maximum retry count, allow task cancellation to stop retries, and return a clear rate-limit error after exhaustion.

🤖 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/product/integrations/firecrawl.md` around lines 29 - 34, Update
firecrawl_wrapper’s HTTP 429 retry handling to enforce a maximum retry count or
deadline instead of retrying indefinitely. Ensure sleeping and retry loops honor
task cancellation, and raise or return a clear rate-limit error once the
configured limit is exhausted while preserving the existing 5xx retry behavior.
docs/product/integrations/neo4j.md (1)

51-63: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add the required password to the userpass example.

The sample selects auth_method: "userpass" but omits password. The documented connectivity probe will fail unless the driver receives credentials.

Proposed fix
     "auth_method": "userpass",
     "user": "neo4j",
+    "password": "${NEO4J_PASSWORD}",
     "database": "neo4j",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.


🤖 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/product/integrations/neo4j.md` around lines 51 - 63, Update the Neo4j
configuration example’s userpass credentials to include the required password
field alongside user, using a clearly marked placeholder value.
docs/product/integrations/postgres.md (1)

68-99: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fix the lane in the Q&A example.

llm_1 receives a questions lane, and db_1 then requests a questions lane from llm_1. docs/product/concepts/execution-model.md Lines 41-45 state that an LLM transforms questions into answers. The example can therefore fail lane validation or send the wrong payload. Feed db_1 from a node that emits questions, or reorder the graph and use the actual output lane.

Based on docs/product/concepts/execution-model.md Lines 41-45, an LLM output is documented as answers, not questions.

🤖 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/product/integrations/postgres.md` around lines 68 - 99, The
natural-language Q&A wiring uses the wrong lane between llm_1 and db_1. Update
the db_1 input to consume the LLM’s documented answers output, or otherwise
reorder the graph so db_1 receives questions from a question-producing node;
keep the target_1 answers connection consistent with the resulting output lanes.
docs/product/integrations/qdrant.md (1)

90-96: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use one identifier for the Qdrant tool namespace.

The configuration example sets serverName to localhost, but this section says tool names are namespaced by serverName and then uses qdrant.search, qdrant.upsert, and qdrant.delete. With the shown configuration, the names would be localhost.search, localhost.upsert, and localhost.delete. Set the sample serverName to qdrant, or use the actual names in the tool table. If serverName is the host, document a separate namespace field.

Based on the configuration and tool-name statements in Lines 34-43 and Lines 90-96, the sample namespace does not match the documented tool names.

🤖 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/product/integrations/qdrant.md` around lines 90 - 96, Align the Qdrant
configuration example’s serverName with the documented tool namespace by setting
it to qdrant, or update the tool names to match the configured localhost value.
Keep the namespace explanation and tool table consistent with the selected
identifier.
docs/product/quickstart.mdx (1)

39-42: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove or update the node count.

This card says 50+ nodes, while docs/product/concepts/nodes.md says 100+ nodes. Use one source of truth or remove the hard-coded count. The current mismatch makes the catalog inconsistent.

Based on docs/product/concepts/nodes.md Lines 61-64, the two product pages publish different catalog counts.

🤖 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/product/quickstart.mdx` around lines 39 - 42, Update the hard-coded
“50+” count in the “Browse nodes” card to match the canonical node count used by
the nodes documentation, or remove the count and use a shared source of truth.
Keep the card’s existing link and descriptive content unchanged.
docs/product/evaluate/understanding.md (1)

8-9: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use a precise quantity.

Replace “a small number” with “a few” or “some”. The current phrase is vague.

🧰 Tools
🪛 LanguageTool

[style] ~8-~8: Specify a number, remove phrase, use “a few”, or use “some”
Context: ...nderstanding RocketRide RocketRide has a small number of moving parts. Once you know how they fi...

(SMALL_NUMBER_OF)

🤖 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/product/evaluate/understanding.md` around lines 8 - 9, Update the
opening description of RocketRide’s moving parts to replace the vague quantity
“a small number” with “a few” or “some,” while preserving the rest of the
sentence.

Source: Linters/SAST tools

docs/product/self-hosting.md (1)

84-95: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== self-hosting relevant slice =="
sed -n '60,150p' docs/product/self-hosting.md

printf '\n== search for host token TLS auth references in self-hosting =="n'
rg -n "0\.0\.0\.0|--host|5565|token|TLS|TLS|authentication|authenticate|auth" docs/product/self-hosting.md

printf '\n== protocol/auth references =="n'
rg -n "WebSocket protocol|local engine|no token|token|TLS|TLS|authentication" docs/product docs/protocols 2>/dev/null || true

printf '\n== engine startup option references in docs =="n'
rg -n "\-\-host|--host|engine\.exe|/ai/eaas\.py|port 5565|5565" docs -g '*.md' || true

Repository: rocketride-org/rocketride-server

Length of output: 16312


Security And Privacy (CWE-16)

Reachability: External · Exploitability: Moderate

Use 127.0.0.1 as the default engine bind address.

The startup commands map --host=0.0.0.0 to every network interface, while the local-deployment path says the engine typically needs no token and adds TLS/authentication only after external exposure. Keep the default bound to 127.0.0.1 and put 0.0.0.0 in a protected deployment example with the required TLS/auth controls.

🤖 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/product/self-hosting.md` around lines 84 - 95, Update the startup
commands in the self-hosting documentation to use --host=127.0.0.1 by default
for both Linux/macOS and Windows. Move the 0.0.0.0 binding into a clearly
protected external-deployment example and include the required
TLS/authentication controls there.

dylan-savage and others added 3 commits August 6, 2026 11:39
All doc-referenced images now live under docs/. Root README relative
paths and main/develop-pinned raw.githubusercontent URLs rewritten;
generated package READMEs refreshed via docs:export. Orphans
(banner-root, screenshot-ide, screenshot-sdk) carried over unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ternal docs

CodeRabbit bucket-1 findings plus three broken links the sweep surfaced:
README-vscode.md and README-*-client.md references now point at the new
clients/ and mcp/ locations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verified each finding against current SDK/node code before fixing:
- H1s, fence languages, MD031 blank lines, heading levels (lint batch)
- Example correctness: import os, double-wrapped pipeline args (4 sites),
  undefined vars, Answer instance API documented from Question.ts,
  validate-gated use(), deploy rollback to recorded version,
  getTaskStatus/validate signatures from client.ts
- Config correctness: postgres questions-lane wiring (both examples),
  qdrant serverName->host, neo4j password field, execution-model
  documents lane, node count 100+
- Security-hardening in crash-reporting.md examples (pinned checksum
  install, mktemp, env-var instead of interpolation), self-hosting
  default host now 127.0.0.1
- builder.md skip conditions include --force; LICENSE link depth (2 files)
- Generated package READMEs refreshed via docs:export

Deferred as code-behavior (not doc) issues: firecrawl unbounded 429
retry, vscode ROCKETRIDE_APIKEY persistence on disconnect.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dylan-savage

Copy link
Copy Markdown
Collaborator Author

CodeRabbit findings addressed in 87daf9b + c52cfa0 — each verified against current SDK/node source before fixing (several were fixed at root cause rather than as cited, e.g. postgres questions-lane wiring, qdrant serverName→host, deploy rollback to the recorded version).

Two findings are deliberately not fixed here because they describe real code behavior that the docs report accurately — fixing them means changing application code, out of scope for this docs PR:

  • tool_firecrawl retries 429s without a cap (nodes/src/nodes/tool_firecrawl/utils.py) — needs a follow-up code ticket.
  • The VS Code extension persists ROCKETRIDE_APIKEY in .env after disconnect — doc already gives the manual-removal guidance; behavior change would belong to apps/vscode.

🤖 Generated with Claude Code

@dylan-savage
dylan-savage merged commit 64f9df5 into fix/docs Aug 6, 2026
1 check passed
@dylan-savage
dylan-savage deleted the feat/docs-consolidation branch August 6, 2026 20:12
dylan-savage added a commit that referenced this pull request Sep 14, 2026
…+ CI gates, node migration, new site (#2139)

* feat(docs): consolidate hand-written docs into top-level docs/ with export pipeline (#1856)

* feat(docs): move spine pages to docs/product/, re-point gather

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): mount client/mcp/engine docs from top-level docs/ tree

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): move contributor docs to docs/internal/

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): add docs:export/docs:check; readme sources under docs/

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): docs:check skips gitignored export destinations

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): commit exported package READMEs (un-gitignore)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): remove docs/images and all references

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): restore list spacing in vscode docs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: update doc-location rules, folder guide, CI drift gate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(docs): trigger docs workflow on top-level docs/ changes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(clients): source package READMEs from committed docs:export copies

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): close CI drift-gate gap, restore .pipe rule bullet

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: drop reserved skills/ section from docs/ tree

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: move top-level images/ into docs/images/

All doc-referenced images now live under docs/. Root README relative
paths and main/develop-pinned raw.githubusercontent URLs rewritten;
generated package READMEs refreshed via docs:export. Orphans
(banner-root, screenshot-ide, screenshot-sdk) carried over unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: fix stale README-* link labels and broken post-move links in internal docs

CodeRabbit bucket-1 findings plus three broken links the sweep surfaced:
README-vscode.md and README-*-client.md references now point at the new
clients/ and mcp/ locations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address CodeRabbit review findings across doc sources

Verified each finding against current SDK/node code before fixing:
- H1s, fence languages, MD031 blank lines, heading levels (lint batch)
- Example correctness: import os, double-wrapped pipeline args (4 sites),
  undefined vars, Answer instance API documented from Question.ts,
  validate-gated use(), deploy rollback to recorded version,
  getTaskStatus/validate signatures from client.ts
- Config correctness: postgres questions-lane wiring (both examples),
  qdrant serverName->host, neo4j password field, execution-model
  documents lane, node count 100+
- Security-hardening in crash-reporting.md examples (pinned checksum
  install, mktemp, env-var instead of interpolation), self-hosting
  default host now 127.0.0.1
- builder.md skip conditions include --force; LICENSE link depth (2 files)
- Generated package READMEs refreshed via docs:export

Deferred as code-behavior (not doc) issues: firecrawl unbounded 429
retry, vscode ROCKETRIDE_APIKEY persistence on disconnect.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): documentation schemas, validators, CI gates, and docs tree cleanup (#1912)

* docs(agents): make AGENTS.md the single-source contributor router

AGENTS.md becomes the one canonical guide: repo overview, task routing
table into docs/, common commands (absorbed from .claude/CLAUDE.md),
conventions, and the documentation rules. .claude/CLAUDE.md becomes an
@AGENTS.md import and .cursorrules a pointer, eliminating the three
divergent copies of the doc-location rules. A nested nodes/AGENTS.md
gives agents working in the nodes tree the README schema and validator
command with zero indirection. docs/README.md references the
documentation contracts in docs/internal/.

* docs(nodes): add node README schema and deterministic validator

docs/internal/node-readme-schema.md defines the per-node README contract:
a fixed section set where services*.json triggers decide which sections
are required (invoke→Connections, lanes→Lanes, tool∈classType→As a tool,
≥2 profiles→Profiles, gpu→Requirements, restricted capabilities→
Limitations), core sections for every node (summary, What it does,
Configuration usage guidance, Example pipelines), and optional sections
with placement rules (About vendor, Authentication, Notes, Upstream
docs). The generated ROCKETRIDE:GENERATED:PARAMS region owns the field
reference; hand-written Configuration is usage guidance only.

scripts/validate-node-readme.py enforces the structural rules per node:
section presence/order, forbidden-when-untriggered, table parity against
declared invoke keys/lanes/profiles, and warnings when a field with
objective complexity signals lacks a detail subsection. Multi-service
directories are merged; fragment-only files (no protocol) are skipped.

* docs(nodes): migrate six sample node READMEs to the README schema

llm_anthropic, db_postgres, tool_github, store_qdrant, ocr, and
agent_deepagent restructured to the schema in
docs/internal/node-readme-schema.md. Content-preserving: existing prose
kept, sections reordered into the canonical layout, bespoke headings
folded into their owning sections or Notes, and the generated
ROCKETRIDE:GENERATED:PARAMS regions untouched byte-for-byte.

Substantive fixes made along the way:
- llm_anthropic: Profiles table now lists all 21 declared profiles
  (previously 7 — Opus 5, Fable 5, Sonnet 5, 4.8 variants, latest
  aliases and 3 Haiku were declared in services.json but undocumented)
- tool_github: removed a duplicated all-tools table that shadowed the
  per-group tool tables; grouped tables are now the single source
- All six gain Example pipelines; db_postgres gains the Limitations
  section its noremote capability requires; vendor nodes gain About
  sections

Validator: Profiles parity accepts key-or-title in the first two
columns; grouped detail subsections satisfy the complex-field check via
token containment. Schema: preset services with identical wiring may be
documented once (db_postgres/Supabase case).

* ci(docs): advisory node README schema check + CodeRabbit doc rules

New node-docs CI job runs scripts/validate-node-readme.py over the node
tree on every PR. Advisory for now (continue-on-error, not in ci-ok):
the corpus is mid-migration to the schema, so the job surfaces results
without blocking merges; flipping it to a hard gate is a two-line change
once migration completes.

CodeRabbit path_instructions direct review attention where the
deterministic validator cannot reach: prose accuracy of node READMEs
against code/services*.json (structure is machine-checked), and
Python/TypeScript client-doc parity.

* docs(clients): client readme schema, parity checker, and parity fixes

docs/internal/client-readme-schema.md codifies the shared section order
the Python and TypeScript readmes already follow, fixes the insertion
points for language-specific sections, and states the parity rule: any
documented method/type/exception exists in both readmes (snake_case and
camelCase compare equal) or carries a language-specific marker.

scripts/validate-client-docs.py enforces it deterministically: section
presence/order/ownership plus API symbol parity harvested from method
tables across the six shared API sections.

Parity gaps it found, fixed against client source:
- python readme was missing the attach/detach/is_attached/login/logout/
  is_authenticated/set_env connection lifecycle (implemented in
  mixins/connection.py, previously undocumented) and Answer.setAnswer
- typescript readme was missing Question.addGoal (Question.ts:264)
- dap_request (python convenience) and withConnection (typescript
  convenience) marked language-specific with cross-references

Package READMEs regenerated via docs:export; docs:check green;
docs:build page count unchanged (179 pages, 125 nodes, 6 mounts).

* refactor(docs): split protocols out, rename internal to development

The docs/ tree is organized by audience, but docs/internal/ was a mixed
bag: it held the WebSocket protocol surface (published to the site as
Protocols > WebSocket) alongside contributor-only material, and an
integration guide that belonged with the other integrations.

- New docs/protocols/ holds both members of the site's Protocols section:
  websocket/ (was docs/internal/engine-protocol/) and mcp/ (was docs/mcp/).
  The section's two halves previously lived in unrelated trees.
- docs/internal/ -> docs/development/. Every file that remains is
  contributor documentation: setup, builder, engine internals, node
  authoring, pre-commit hooks. The old name also read as company-private
  in a public repository, which is the opposite of the signal contributor
  docs should send.
- docs/internal/n8n.md -> docs/product/integrations/n8n.md and onto the
  spine, joining the six existing integration guides. Prepared for
  publication: frontmatter added, repo-relative links rewritten to site
  routes or blob/develop URLs, and a reference to a local-only test
  harness removed.

Every folder under docs/ is now entirely published or entirely not.
docs/README.md documents that invariant and groups the sections by it.

Paths updated in gather.js (mounts + root glob), export.js (MCP readme
source), spine.js (integrations), AGENTS.md, nodes/AGENTS.md,
docs/README.md, .coderabbit.yaml, ci.yml, SUPPORT.md, examples/README.md,
tool_n8n's README, both validators, and the regenerated MCP package README.
Both validators also reformatted to the repo's ruff style.

Verification: docs:test 42/42, docs:check in sync, docs:build green,
docs:gather 180 pages (179 + the newly published n8n page) / 125 nodes /
6 mounts. Node and client validators unchanged in behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(docs): build the docs site on doc-touching PRs; run client parity checker

Review of the doc-CI surface found two genuine gaps; everything else was
judged adequate or deliberately rejected to avoid CI sprawl.

Gap 1: the docs site was only ever built AFTER merge (docs.yml on push to
develop), so deterministic breakage — broken internal links, docs/ files
not covered by a mount, spine entries without a page — merged clean and
failed on develop's deploy. New path-filtered docs-build job runs
docs:test + docs:build on PRs touching doc sources, wired into ci-ok
(skip-tolerant, same pattern as helm/shell-contract). Blocking is
justified: every failure mode is deterministic, no network flakiness.

Gap 2: scripts/validate-client-docs.py was committed but nothing executed
it. Added to the advisory node-docs job (renamed 'Doc schemas (advisory)').

Rejected as sprawl: an external-link checker (network-flaky by
construction), prose/spell linting (noise on a technical corpus), a
separate node-site-coverage check and a docs-folder-invariant check (both
subsumed — the first by the advisory schema validator, the second by
docs:build's unmounted-file abort now running on PRs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* docs(nodes): ship example bundles for seven nodes, then park the requirement (#1960)

* docs(agents): make AGENTS.md the single-source contributor router

AGENTS.md becomes the one canonical guide: repo overview, task routing
table into docs/, common commands (absorbed from .claude/CLAUDE.md),
conventions, and the documentation rules. .claude/CLAUDE.md becomes an
@AGENTS.md import and .cursorrules a pointer, eliminating the three
divergent copies of the doc-location rules. A nested nodes/AGENTS.md
gives agents working in the nodes tree the README schema and validator
command with zero indirection. docs/README.md references the
documentation contracts in docs/internal/.

* docs(nodes): add node README schema and deterministic validator

docs/internal/node-readme-schema.md defines the per-node README contract:
a fixed section set where services*.json triggers decide which sections
are required (invoke→Connections, lanes→Lanes, tool∈classType→As a tool,
≥2 profiles→Profiles, gpu→Requirements, restricted capabilities→
Limitations), core sections for every node (summary, What it does,
Configuration usage guidance, Example pipelines), and optional sections
with placement rules (About vendor, Authentication, Notes, Upstream
docs). The generated ROCKETRIDE:GENERATED:PARAMS region owns the field
reference; hand-written Configuration is usage guidance only.

scripts/validate-node-readme.py enforces the structural rules per node:
section presence/order, forbidden-when-untriggered, table parity against
declared invoke keys/lanes/profiles, and warnings when a field with
objective complexity signals lacks a detail subsection. Multi-service
directories are merged; fragment-only files (no protocol) are skipped.

* docs(nodes): migrate six sample node READMEs to the README schema

llm_anthropic, db_postgres, tool_github, store_qdrant, ocr, and
agent_deepagent restructured to the schema in
docs/internal/node-readme-schema.md. Content-preserving: existing prose
kept, sections reordered into the canonical layout, bespoke headings
folded into their owning sections or Notes, and the generated
ROCKETRIDE:GENERATED:PARAMS regions untouched byte-for-byte.

Substantive fixes made along the way:
- llm_anthropic: Profiles table now lists all 21 declared profiles
  (previously 7 — Opus 5, Fable 5, Sonnet 5, 4.8 variants, latest
  aliases and 3 Haiku were declared in services.json but undocumented)
- tool_github: removed a duplicated all-tools table that shadowed the
  per-group tool tables; grouped tables are now the single source
- All six gain Example pipelines; db_postgres gains the Limitations
  section its noremote capability requires; vendor nodes gain About
  sections

Validator: Profiles parity accepts key-or-title in the first two
columns; grouped detail subsections satisfy the complex-field check via
token containment. Schema: preset services with identical wiring may be
documented once (db_postgres/Supabase case).

* ci(docs): advisory node README schema check + CodeRabbit doc rules

New node-docs CI job runs scripts/validate-node-readme.py over the node
tree on every PR. Advisory for now (continue-on-error, not in ci-ok):
the corpus is mid-migration to the schema, so the job surfaces results
without blocking merges; flipping it to a hard gate is a two-line change
once migration completes.

CodeRabbit path_instructions direct review attention where the
deterministic validator cannot reach: prose accuracy of node READMEs
against code/services*.json (structure is machine-checked), and
Python/TypeScript client-doc parity.

* docs(clients): client readme schema, parity checker, and parity fixes

docs/internal/client-readme-schema.md codifies the shared section order
the Python and TypeScript readmes already follow, fixes the insertion
points for language-specific sections, and states the parity rule: any
documented method/type/exception exists in both readmes (snake_case and
camelCase compare equal) or carries a language-specific marker.

scripts/validate-client-docs.py enforces it deterministically: section
presence/order/ownership plus API symbol parity harvested from method
tables across the six shared API sections.

Parity gaps it found, fixed against client source:
- python readme was missing the attach/detach/is_attached/login/logout/
  is_authenticated/set_env connection lifecycle (implemented in
  mixins/connection.py, previously undocumented) and Answer.setAnswer
- typescript readme was missing Question.addGoal (Question.ts:264)
- dap_request (python convenience) and withConnection (typescript
  convenience) marked language-specific with cross-references

Package READMEs regenerated via docs:export; docs:check green;
docs:build page count unchanged (179 pages, 125 nodes, 6 mounts).

* refactor(docs): split protocols out, rename internal to development

The docs/ tree is organized by audience, but docs/internal/ was a mixed
bag: it held the WebSocket protocol surface (published to the site as
Protocols > WebSocket) alongside contributor-only material, and an
integration guide that belonged with the other integrations.

- New docs/protocols/ holds both members of the site's Protocols section:
  websocket/ (was docs/internal/engine-protocol/) and mcp/ (was docs/mcp/).
  The section's two halves previously lived in unrelated trees.
- docs/internal/ -> docs/development/. Every file that remains is
  contributor documentation: setup, builder, engine internals, node
  authoring, pre-commit hooks. The old name also read as company-private
  in a public repository, which is the opposite of the signal contributor
  docs should send.
- docs/internal/n8n.md -> docs/product/integrations/n8n.md and onto the
  spine, joining the six existing integration guides. Prepared for
  publication: frontmatter added, repo-relative links rewritten to site
  routes or blob/develop URLs, and a reference to a local-only test
  harness removed.

Every folder under docs/ is now entirely published or entirely not.
docs/README.md documents that invariant and groups the sections by it.

Paths updated in gather.js (mounts + root glob), export.js (MCP readme
source), spine.js (integrations), AGENTS.md, nodes/AGENTS.md,
docs/README.md, .coderabbit.yaml, ci.yml, SUPPORT.md, examples/README.md,
tool_n8n's README, both validators, and the regenerated MCP package README.
Both validators also reformatted to the repo's ruff style.

Verification: docs:test 42/42, docs:check in sync, docs:build green,
docs:gather 180 pages (179 + the newly published n8n page) / 125 nodes /
6 mounts. Node and client validators unchanged in behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(docs): build the docs site on doc-touching PRs; run client parity checker

Review of the doc-CI surface found two genuine gaps; everything else was
judged adequate or deliberately rejected to avoid CI sprawl.

Gap 1: the docs site was only ever built AFTER merge (docs.yml on push to
develop), so deterministic breakage — broken internal links, docs/ files
not covered by a mount, spine entries without a page — merged clean and
failed on develop's deploy. New path-filtered docs-build job runs
docs:test + docs:build on PRs touching doc sources, wired into ci-ok
(skip-tolerant, same pattern as helm/shell-contract). Blocking is
justified: every failure mode is deterministic, no network flakiness.

Gap 2: scripts/validate-client-docs.py was committed but nothing executed
it. Added to the advisory node-docs job (renamed 'Doc schemas (advisory)').

Rejected as sprawl: an external-link checker (network-flaky by
construction), prose/spell linting (noise on a technical corpus), a
separate node-site-coverage check and a docs-folder-invariant check (both
subsumed — the first by the advisory schema validator, the second by
docs:build's unmounted-file abort now running on PRs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): shipped example bundle — screenshot + downloadable .pipe per node

Every node's Example pipelines section now opens with a shipped example:
a minimal runnable pipeline committed as example.pipe next to the node,
a canvas screenshot of that same pipeline (example.png), and a shields.io
download badge. Readers browsing the docs see the node wired on the
canvas and can download the .pipe straight into their own canvas.

- Schema: the standalone optional screenshot (formerly under What it
  does) is folded into Example pipelines as part of the bundle. Authors
  reference example.png / example.pipe by bare relative name so node
  folders stay self-contained and GitHub renders them natively.
- gather.js: stageNodeMarkdown rewrites those two refs to develop-pinned
  repository URLs when staging site pages (raw for the image, blob for
  the .pipe download) — same pattern as the generated Source link.
  Verified end-to-end on a staged page.
- Validator: bundle is all-or-nothing (pipe file, screenshot file, embed,
  download link + alt text) — any part present makes every part required;
  nothing at all is a warning until the node's bundle lands. New nodes
  must ship it (CodeRabbit instruction added).

docs:test 42/42, staging parity (180 pages / 125 nodes / 6 mounts),
6 samples still pass (now with the expected bundle warning), ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(nodes): move Example pipelines above the reference sections; migrate agent_llamaindex

Example pipelines now sits directly under What it does, so a reader sees
what the node is, a canvas screenshot, and a downloadable .pipe before any
reference tables. Schema sections renumbered; the six migrated samples
reordered to match.

agent_llamaindex migrated to the schema: About LlamaIndex, three example
pipelines, Connections/Lanes/As a tool tables matching services.json, and
Configuration reduced to usage guidance — the duplicated hand-written
field table is gone (the generated Schema table owns it), with detail
subsections for the three fields that need them (Agent description as the
parent-agent selection signal, Instructions, Require tool call as the
fabrication guard). Loop internals and SSE progress moved under Notes.

7/125 nodes pass. docs:test 42/42, staging parity, ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): trigger the example bundle on references, ship agent_llamaindex's .pipe

The all-or-nothing rule counted a loose file as a bundle part, so
committing example.pipe before its screenshot existed would fail the node
— blocking the natural two-step path (author the pipeline, screenshot it
later). The trigger is now a README *reference*: referencing either half
obliges the other and every referenced file must exist (no broken links,
never a half-rendered README), while an unreferenced file is a warning
naming what is present and what is still needed.

agent_llamaindex's example.pipe is the existing, working
examples/agent-llamaindex.pipe — chat -> agent (llm_anthropic on the llm
channel, tool_http_request on tool) -> response_answers — rather than an
authored approximation. Its screenshot and the two references land when
the pipeline is captured on the canvas.

Verified all three paths: unreferenced file warns, a lone badge fails,
a referenced-but-missing file fails. docs:test 42/42, staging parity,
7/125 nodes pass, ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(nodes): ship example.pipe for all seven migrated nodes; fix a broken example

Every migrated node now carries the .pipe half of its example bundle, so
completing each one is capture-a-screenshot plus two pasted lines.
docs/development/example-bundle-todo.md holds the per-node instructions,
the exact markdown to paste (alt text written per node), and provenance.

Three are existing working pipelines copied from examples/:
agent_llamaindex <- agent-llamaindex.pipe, ocr <- document-processor.pipe,
store_qdrant <- rag-pipeline.pipe. The other four (llm_anthropic,
db_postgres, tool_github, agent_deepagent) were authored from those proven
shapes and statically validated: every provider is a declared node
protocol, every input lane is one the upstream node produces, every control
channel is declared in the target's invoke. They are unrun — opening each
on the canvas for its screenshot is the verification step.

Also fixes examples/document-processor.pipe, which referenced provider
'anonymize' while the node declares 'anonymize_text' — a broken example
that predates this branch. All 17 files in examples/ now reference only
real providers.

7/125 nodes pass, each with the expected unreferenced-bundle warning.
docs:test 42/42, staging parity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(docs): centre the example screenshot and download button, matching the root README

The markdown image form rendered left-aligned at natural size; the root
README gets its look from an HTML block, so node examples now use the same
house style: a centred div with a width=100% screenshot above the
shields.io download button. Safe on the docs site because Docusaurus is
configured markdown.format 'detect', so .md is parsed as CommonMark rather
than MDX (tags are still self-closed for portability).

- gather.js: the staging rewrite now matches HTML attribute forms (src=,
  href=) as well as markdown targets, so the centred block resolves to
  repository URLs on the site. The shields.io URL is deliberately untouched.
- Validator accepts either form and reads alt text out of the img tag, so
  the alt-text requirement still holds.
- Schema documents the HTML block as house style and records why the link
  stays relative: the VS Code extension registers a custom editor for
  *.pipe, so clicking the button in the IDE opens the pipeline directly on
  the canvas — an absolute URL would bounce the reader to a browser.
- agent_llamaindex converted, its example.png committed, and its first
  example corrected to describe the pipeline actually shipped (chat +
  tool_http_request, not webhook + tool_tavily). First fully complete
  bundle in the repo.
- Checklist snippets regenerated in the new form.

docs:build green (HTML compiles on the site), docs:test 42/42, 7/125 nodes
pass, ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): keep the example block renderable in the VS Code preview

The raw-HTML form centred correctly on GitHub but rendered as empty space
in the VS Code / Cursor markdown preview: that preview rewrites relative
paths only for markdown-syntax images, so an <img src="example.png"> is
left unresolved and blocked. The IDE is the surface where the download
button matters most (clicking it opens the pipeline on the canvas), so it
cannot be the one that breaks.

Blank lines inside the wrapper fix it. A blank line ends the HTML block per
CommonMark, so the image and badge parse as markdown — resolving in the
preview — while the surrounding div still centres them, and GitHub scales
the screenshot to the content width on its own. Renders in all three
surfaces: IDE preview, GitHub, and the docs site.

Schema records why the blank lines are load-bearing so nobody tidies them
away. Checklist snippets regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(nodes): complete shipped example bundles

* docs(nodes): park the Example pipelines section and its bundle checks

The shipped-example bundle (canvas screenshot + downloadable .pipe) is
complete for seven nodes but is a per-node manual step, and it blocks the
migration of the remaining ~120 READMEs behind screenshot capture. Park
the requirement so the migration can proceed on prose alone.

`## Example pipelines` is commented out in the schema with its full text
preserved in place, and the validator's bundle checks are commented out
alongside it — un-parking is uncommenting both and re-numbering the
schema's sections.

The section stays in the validator's CANONICAL_ORDER, so it remains
tolerated in its slot rather than flagged as an unknown heading: the
seven migrated nodes keep their examples and keep passing. It is simply
no longer required. gather.js keeps rewriting relative example refs for
the staged site — inert with nothing to rewrite, needed when this returns.

* ci: scope the doc schema checks to fix/docs, leave the shared pipeline alone

The doc schema work added four things to config that every branch shares:
a docs path filter and two new jobs in ci.yml, a pnpm install plus a
docs:check step bolted onto the always-on ruff-check job, and two path
instructions in .coderabbit.yaml. None of that belongs on develop while
the schemas are still being rolled out — and the ruff-check change in
particular would have added an install and a docs build to every pull
request in the repository, not just documentation ones.

ci.yml is restored byte-for-byte to its pre-branch state, so merging
fix/docs into develop is now a no-op for the shared pipeline.

The same checks now live in .github/workflows/docs-schemas.yml, which
triggers only on pull requests and pushes targeting fix/docs. It stays
inert on develop even after this branch merges. Validators are advisory
(the node corpus is mid-migration and would paint every PR red); the
site build and export drift gate are blocking, since both pass today.

CodeRabbit has no per-branch config file, but it reads .coderabbit.yaml
from a pull request's base branch — so adding fix/docs to base_branches
here enables review for PRs into this branch while develop keeps using
its own copy. That entry and the two doc path instructions are fenced
with TEMPORARY markers to be removed in the fix/docs -> develop PR.

* ci: drop the unusable workflow_dispatch trigger from the doc schema checks

workflow_dispatch only fires when the workflow file lives on the
repository's default branch. This file is deliberately scoped to
fix/docs and is meant never to reach develop, so the trigger could
never have worked — gh confirms it with 'workflow not found on the
default branch'. Removed rather than left as dead configuration.

* chore: drop agent stubs the VS Code extension planted in this repo

The extension's agent installer (apps/vscode/src/agents/) writes AI
assistant instruction files into whatever workspace is open, on startup,
with rocketride.integrations.autoAgentIntegration defaulting to true. It
adds its own .rocketride/ docs directory to .gitignore but not the stubs
it plants, so three of them were swept into b7c9918f, and its
marker-based merge appended a thirtieth-line block to AGENTS.md because
that file had no ROCKETRIDE markers to replace.

That block is the reason CodeRabbit flagged AGENTS.md as
self-contradicting on #1960: line 21 sends contributors to
docs/agents/ROCKETRIDE_QUICKSTART.md while the appended block made
.rocketride/docs/ROCKETRIDE_README.md step 1. AGENTS.md is the
contributor router, and .rocketride/docs/ is customer-facing SDK
documentation — the wrong guidance for someone working on the engine.

Removes the three files and the appended block, and gitignores the stub
targets not already covered (.cursor/ and .claude/* already were, which
is the only reason the Cursor stub never landed). AGENTS.md cannot be
gitignored, so the installer is also disabled in .vscode/settings.json,
which is tracked and therefore fixes this for everyone who opens the
repo rather than one machine.

The underlying extension bug is not fixed here.

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* ci(docs): scope the node schema check to the PR's diff, and make it blocking (#1971)

* ci(docs): gate the node schema on the PR's own diff, and make it blocking

The corpus-wide run was advisory because 109 of 124 nodes fail the schema
today, so a hard gate would have been red on every PR from the day it was
added. But a check that has always failed is a check nobody reads, and the
day it fails for a new reason looks identical to the two hundred days
before it. The interesting failures were going to be buried under
structural noise like "unknown heading '## Modes'".

Scoping it to the nodes the PR actually touches inverts that: green by
default, so red means this PR broke something. It also lets the check be
a hard gate immediately rather than waiting on a 109-node cleanup to
finish before it protects anything, and the backlog drains on its own —
touching a node obliges you to bring its README along — while never being
able to grow.

services*.json counts as a trigger alongside README.md, since the metadata
is what decides which sections are required or forbidden; a metadata-only
change can invalidate a README nobody edited. That also closes the gap
where the docs path filter watched only README.md.

--all keeps a home in a new informational job that writes pass/fail counts
to the run summary, where a large number is a trend line rather than a
merge blocker. Retire that job when the count reaches zero.

Checked against the existing docs:check gate to be sure two checks cannot
disagree about what a good README is: docs:check verifies that exported
client package READMEs match their docs/ sources, which is export drift,
not document structure. No overlap.

Verified under bash (CI's shell, not the zsh this was written in, which
does not word-split unquoted variables): 8 nodes detected from the diff,
all pass, exit 0; including an unmigrated node exits 1.

* ci(docs): stop the scoped schema gate failing on a diff with no node files

Two bugs CodeRabbit caught in the previous commit, both reproduced before
fixing.

Under `set -euo pipefail`, grep exits 1 when nothing matches, so a PR that
touched no node README or services*.json died on the command substitution
before reaching the empty check that was meant to report a clean skip.
Since that job is now blocking, an unrelated PR into fix/docs would have
been blocked outright. The `-d` test in the trailing loop had the same
shape when the last candidate was a deleted node.

`grep -c` already prints 0 when it matches nothing and exits 1 as well, so
`|| echo 0` emitted a second zero and the run summary rendered "0 0".

Verified: empty diff reaches the skip path and exits 0; the real diff still
resolves 8 nodes; counts render as a single 0.

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>

* fix(docs): stop the node validator eating underscores in identifiers (#1973)

`table_col` stripped `[*_`]` from every table cell to remove markdown
decoration before comparing names against services*.json. Underscores are
markdown emphasis, but they are also legal in the identifiers this
function exists to compare, so the strip silently corrupted them:
`_source` became `source` and no longer matched the lane that declared it.

Caught on tool_pipe, whose README was correct and failed anyway. Thirteen
nodes carry an underscore in a lane, connection, or profile name, and the
LLM family is the worst affected — `gemini-2_5-flash`, `llama3_2-vision-11b`,
`ai21_jamba-1_5-large` — so this would have produced a wave of false
failures on the largest batch still to come.

Profiles masked the bug because their comparison falls back to fuzzy
containment across two columns; lanes and connections compare strictly,
so they failed outright.

Emphasis is now only removed when a pair of underscores wraps the whole
cell, which is the only case where an underscore is decoration rather than
part of a name. Verified against `_source`, `z_score`, `gemini-2_5-flash`,
`streamable_http`, `_emphasised_`, and both the `*(default)*` and
`_(default)_` markers already in use. No change to the corpus pass count.

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>

* refactor(docs): reorganize docs/ by audience and retire duplicated pages (#1969)

* refactor(docs): reorganize docs/ by audience and retire duplicated pages

Collapses docs/ to three top-level folders keyed by who reads them, brings all
five clients under one roof, and removes the hand-written pages that duplicated
generated node documentation.

docs/
  public/       humans outside the repo: typescript, python, vscode, mcp, n8n
                (each with a distribution README.md and assets/), product/ (the
                site spine), assets/
  development/  contributors; never published, no exceptions
  agents/       AI assistants: ROCKETRIDE_*.md, stubs/, skills/

clients/, protocols/, stubs/ and images/ are dissolved. Site mount destinations
are unchanged, so no published URL moves except where noted below.

Five clients, one place. mcp graduates from protocols/ to a client folder (its
README already was the published rocketride-mcp README). n8n joins as the fifth:
packages/n8n-nodes/README.md is now generated by docs:export like the other
three, so it can no longer drift.

Integration pages retired. Six of seven pages under product/integrations were
node-README duplicates at 73-90% overlap, and postgres.md had already drifted
into publishing Supabase instructions that the db_postgres README says will fail
to resolve. All six are deleted and redirected to their node pages; n8n survives
because it documents webhook ingress, credential-vault and human-in-the-loop
flows that no single node README can own.

development/ is now genuinely internal. Its websocket docs split by audience:
the wire-protocol reference (external integrators) moved to the site spine and
keeps its URLs, while crash-reporting.md (lldb, breakpad) is unpublished. apps.md
split likewise, its published-SDK half becoming develop/apps with shell-ui
imports normalized to rocketride/app-sdk. gather no longer sweeps development/
at all, so it cannot publish by accident. The remainder is grouped by subsystem
(builder/, engine/, nodes/, clients/, apps/).

product/ regrouped. The real quickstart was filed under Evaluate while
/quickstart was an empty card grid pointing at it; it is now a landing page with
the tutorial split into an IDE walkthrough and an SDK guide. Loose root files
became operate/ (cloud, self-hosting, troubleshooting) and reference/ (cli,
glossary, pipeline-reference).

Broken distribution assets fixed. Every banner in the published READMEs pointed
at a main-pinned raw URL for a path that had never existed there, so all of them
404 on npm, PyPI and the Marketplace. They now target the per-client assets/
paths; the root README uses relative paths that resolve on any branch.

New guardrail: a doc id is a public URL here, and a spine id with no backing file
used to publish a silent "coming soon" page. assertNoUnexpectedPlaceholders now
fails the build and names the offending id, with an allowlist for intentional
stubs. It caught four moved URLs hardcoded in the site footer during this work.

Also adds development/docs-pipeline.md and development/ci-gates.md, deletes a
service catalog that had drifted to 118/148 against a real 143/163, and fixes
setup-guide and root-file link depths.

Verified: docs:build 176 pages / 125 nodes / 5 mounts, docs:check in sync,
docs:test 48/48, validate-client-docs.py passing, docs:export idempotent. 14
retired routes all have emitted redirects.

* docs: address CodeRabbit review on #1969

Twelve of thirteen findings accepted; several were symptoms of wider problems
and were fixed at the root.

Wrong technical claims, verified against the source and rewritten:
- Data lanes and agent tools were described as mutually exclusive. Nine of
  27 `tool` services declare lanes, and validate-node-readme.py gates the two
  sections independently. Replaced with a 2x2 matrix.
- The node loader contract was pseudocode for a `MyNode`/`process()` API that
  does not exist. python-instance.cpp requires `IInstance`, python-global.cpp
  treats `IGlobal` as optional, and bindMethod binds callbacks by name from a
  24-entry list, silently no-oping on a typo. Replaced with a working
  three-file template.
- `./builder test server` is not an alias for the server tests: bare args fan
  out to every module. Corrected here and two more sites in index.md.

Host and path corrections:
- The SDK `uri` examples used cloud.rocketride.ai, which is the web console.
  The API host is api.rocketride.ai (CONST_DEFAULT_WEB_CLOUD in both SDKs
  since #1078). Only SDK/URI contexts were changed; ~20 sites across the
  Python, TypeScript and VS Code pages, which had drifted away from the
  package READMEs that were already correct.
- The exported agent doc linked into docs/development/, which docs:export
  never copies to .rocketride/docs/. Repointed at a sibling exported doc and
  published URLs.
- docs.rocketride.ai -> .org in apps/index.md, matching docusaurus.config.ts.

Also: documented the four app-SDK methods missing from the API list, corrected
the n8n trigger's authentication description (it declares no credentials, only
a `secret` parameter checked against the Authorization header), fixed rsbuild
dependency drift in the app template, normalized bare `builder` to `./builder`
in 14 places, tagged three untagged code fences, and ran prettier over
redirects.ts (all 702 entry lines predated this PR; array data verified
identical before and after).

Rejected: the suggestion to unify updateEditorViewState and
updateEditorViewport. They are distinct methods with different signatures in
both Documents.tsx and shell-api/v0.d.ts; unifying them would introduce a bug.
Also rejected `npx` -> `pnpm exec`, which the apps' own tasks.js contradict.

Two source-level issues found and left for separate PRs: app-sdk/index.ts is
missing four methods the runtime exposes, and tool_firecrawl/README.md was
already schema-nonconformant.

* docs(nodes): migrate the tool_ family to the README schema (#1974)

* docs(nodes): migrate tool_apify, tool_bland_ai, tool_chartjs, tool_cognee, tool_daytona, tool_deepl to the README schema

* docs(nodes): migrate tool_exa_search, tool_filesystem, tool_firecrawl, tool_git, tool_guild, tool_http_request to the README schema

* docs(nodes): migrate tool_laserdata_memory, tool_mcp_client, tool_mem0, tool_n8n, tool_oura, tool_pipe to the README schema

* docs(nodes): migrate tool_google_workspace, tool_pipedrive, tool_python, tool_slack, tool_tavily, tool_v0, tool_xtrace_memory to the README schema

* docs(tool_pipedrive): clarify bearer token format

* docs(nodes): use American spelling in tool_n8n

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>

* docs(nodes): migrate the LLM family with progressive model tables (#2022)

* docs(nodes): migrate LLM family with progressive model tables

* docs(nodes): settle the Profiles contract before the other families rebase

This PR's schema and validator changes become the rules the five in-flight
node-README PRs are held to, so four gaps get closed here rather than after
74 more nodes have adopted them.

Each protocol-bearing service keeps its own default. A second registration is
a separate node to the engine — a branded preset, a second provider, a second
backend — so its preconfig.default is a fact about that service, not a
competing claim about the primary one. The old single-default rule false-failed
cloud_tts (#1975) and store_elasticsearch (#1970), which are correct as
written, and it also hid a real defect here: llm_openai_api's Nebius default
llama-3-3-70b rendered unmarked, and the intro bolded a title the metadata
does not declare. Both fixed. Four tests cover the multi-service case; there
were none.

The visible-table rule said "until the table reaches six rows" while the
validator enforced "at most six", so ten of twelve large-layout nodes
under-fill against the written text. Six is now stated as a ceiling, not a
quota, with an explicit clause for the nodes that front several vendors'
catalogues — llm_bedrock was collapsing Llama 4 Scout and Maverick while
showing Llama 3.3 above the fold, which that clause now forbids and this
change corrects.

How a row names its profile is now stated: the declared key as code, or the
declared title reproduced exactly, one form per node. That is what the
validator already enforced through resolve_profile_row, but leaving it
unwritten is why guardrails (#1978) fails on re-cased display names.

The default marker is **(default)**. The validator stays decoration-agnostic
so pages using *(default)* keep passing; the schema now says which to write.

No regression across the 124-node corpus: same failure set before and after.
21 validator tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* docs(nodes): migrate the store_ family to the README schema (#1970)

* docs(nodes): migrate store family to README schema

* docs(nodes): name each store profile default in its Profiles intro

#2022 landed the tightened Profiles contract: every protocol-bearing service's
declared default has to appear before the first table, with its key and its
title in bold, and be marked on its row. Six of the store nodes marked the row
but never named the default in prose, so they fail the new validator.

store_elasticsearch registers two backends with two separate defaults —
Elasticsearch defaults to self-managed, OpenSearch to local. Both rows were
already marked, which read as a contradiction with nothing explaining it; the
intro now says which default belongs to which service. That shape is what the
new multi-service clause in the schema describes.

store_qdrant is not part of this migration — it was already on fix/docs and
already passing the old validator — but it is the same one-line fix in the same
family and it fails the new rules, so it is folded in here rather than left as
an orphan nothing re-checks.

Default markers switched from *(default)* to **(default)**, which is the form
the schema now specifies. The validator accepts either.

All nine store nodes pass; 21 validator tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* docs(nodes): migrate the small node families to the README schema (#1975)

* docs(cloud_tts): seed the generated params region so the node reaches the docs site

gather.js stages a node only when its README carries the
ROCKETRIDE:GENERATED:PARAMS marker, and nodes:docs-generate refuses to
create one (resolveDocPath returns null without it), so a node that never
had the marker can never acquire it on its own. cloud_tts was in that
state and has been invisible on the site.

Seeded an empty marker pair and ran the generator to fill it, which
produced both service tables (ElevenLabs and OpenAI). Content is entirely
machine-generated; nothing here is hand-written.

* docs(nodes): migrate agent_crewai, agent_langchain, agent_rocketride, cloud_tts, db_clickhouse, db_mysql to the README schema

* docs(nodes): migrate embedding_image, embedding_openai, embedding_transformer, embedding_video, graph_arango, graph_falkordb to the README schema

* docs(nodes): migrate graph_hydradb, graph_neo4j, memory_internal, memory_persistent, preprocessor_code, preprocessor_langchain, preprocessor_llm to the README schema

* fix(docs): clarify supported OpenAI embedding profiles

* fix(docs): document embedding API key resolution

* fix(docs): list custom node profiles

* docs(nodes): bring the small families up to the new Profiles contract

Nine nodes fail the contract #2022 landed. Most need only the intro sentence
naming the declared default, but three carried real gaps:

embedding_transformer and memory_persistent never listed their `custom`
profile, so a profile the configuration panel offers was undocumented.
memory_persistent went further and explained the omission in prose; the row is
now present and that sentence says what `custom` is for instead.

embedding_openai rendered its declared context window as "8191 tokens." in a
semantic column, which the validator compares against the metadata value. The
column is now `Context tokens` carrying the number alone.

cloud_tts registers OpenAI and ElevenLabs with a default each. Both rows were
marked with nothing explaining why there were two; the intro now names each
default and the service it belongs to. Its Profile column also mixed bare keys
for one provider with key-plus-title for the other — every row now uses the
declared title, one convention per node as the schema asks.

Profile titles are padded to align in the configuration panel's dropdown
('Text Small   - ...', 'Text Large   - ...'). That alignment is deliberate and
belongs in services.json, but requiring a README to reproduce it verbatim in
bold prose is not reasonable, so title matching now collapses whitespace runs
on both sides. Two tests cover it, including that a genuine wording mismatch
still fails.

All 19 nodes in this PR pass; 23 validator tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(preprocessor_code): correct the parser cache's scope

The README said the parser cache is retained for the lifetime of the global
node instance. languageParsers is declared as a class attribute on
PreProcessor (code.py:166) and the write at code.py:235 is an item assignment,
so it mutates the class-level dict rather than rebinding a per-instance one. A
grammar loaded once is therefore reused by every instance in the process and
outlives any single global node instance.

Raised by CodeRabbit on #1975.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* docs(nodes): migrate the media nodes, and document eight that never had a README (#1976)

* docs(nodes): migrate detect_segment, face_detection, pose_estimation, video_composer to the README schema

* docs(nodes): migrate background_removal, caption, depth_estimate, detect to the README schema

* docs(nodes): migrate accessibility_describe, frame_grabber, image_cleanup, thumbnail to the README schema

* docs(nodes): migrate audio_player, audio_transcribe, audio_tts, twelvelabs to the README schema

* docs(nodes): seed generated params regions for the eight newly documented nodes

These nodes had no README at all, so they had no marker region either, and
nodes:docs-generate cannot create one (resolveDocPath returns null when the
marker is absent). Seeded an empty pair per node and ran the generator to
fill it. Content is entirely machine-generated.

* fix(docs): clarify audio player video input

* fix(docs): clarify background removal output size

* fix(docs): label RT-DETR fallback link

* docs(nodes): bring the media nodes up to the new Profiles contract

Eight nodes needed the intro sentence naming the declared default, which is
all the new contract asks of this family — no missing rows, no semantic-column
mismatches, no multi-service defaults. Markers switched to **(default)**.

The review also turned up a boilerplate problem worth fixing while the family
is open. Four ## Requirements sections opened with "This node is marked as
GPU-capable. Its metadata declares local CPU, Apple Silicon (MPS), and CUDA
operation" and closed with a variant of "The source does not specify VRAM
requirements or relative CPU performance." Both halves describe the metadata
and the writing process rather than the node: a reader who opens ## Requirements
wants to know what hardware to provision, and being told what the source failed
to mention answers nothing. Those sections now say where inference runs and what
the device lock does, and stop. depth_estimate keeps the one fact the closer was
carrying — its output is relative depth, not calibrated distance.

Same fix in two other places: caption pointed at sibling nodes via "the node
metadata directs object-detection use cases to Object Detection", and
audio_player attributed its own truncation note to "The source notes that...".

All 16 nodes pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>

* docs(nodes): migrate the text, NLP, and document-parsing nodes (#1977)

* docs(nodes): migrate dictionary, extract_data, extract_facts, ner to the README schema

* docs(nodes): migrate anomaly_detector, anonymize, answer_documents, currency_convert_explicit to the README schema

* docs(nodes): migrate prompt, question, schema_validate, summarization to the README schema

* docs(nodes): migrate landing_ai, llamaparse, reducto, vectorizer to the README schema

* docs(landing_ai): seed the generated params region so the node reaches the docs site

Last of the thirteen nodes gather.js was silently skipping. Its two variant
sub-pages (extract, parse) were hidden with it, since variants are only
staged once their parent is.

* fix(docs): clarify anonymizer classifier fallback

* fix(docs): use canonical LlamaParse links

* fix(docs): document JSON scalar lane metadata

* fix(docs): use American spelling consistently

* fix(docs): clarify severity fallback warnings

* docs(nodes): bring the text family up to the new Profiles contract

Three nodes fail the contract #2022 landed. anomaly_detector needs only the
intro sentence naming the declared default; anonymize and ner also never listed
their `custom` profile, so a model choice the configuration panel offers was
undocumented in both.

The review turned up a second, larger thing. Seven nodes carried an
`## About RocketRide` section. That slot is for third-party services a node
wraps, and RocketRide is not third-party: on a page inside RocketRide's own
documentation, "RocketRide connects data-processing components into pipelines"
tells a reader nothing, and the sentence after it describes what the node does,
which is what `## What it does` is for and where each of these already says it.
Each one also dragged along an `## Upstream docs` link back to
docs.rocketride.org — circular, and present only because `## About` requires
that section. Both are removed from all seven.

question's `## Requirements` said the node "is marked GPU-capable in its
metadata, but its implementation only strips text". A reader opening that
section wants to know what to provision, not what the metadata claims, so it
now says the node needs no hardware of its own and that any GPU requirement
belongs downstream.

All 16 nodes pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* docs(nodes): migrate the infrastructure and I/O nodes (#1978)

* docs(nodes): migrate local_text_output, telegram, text_output, webhook to the README schema

* docs(nodes): migrate autopipe, core, remote, response to the README schema

* docs(nodes): migrate aparavi_aql, rocketride_graph, rocketride_sql, rocketride_vector to the README schema

* docs(nodes): migrate guardrails, rerank_cohere, search_exa to the README schema

* fix(docs): explain local-only node execution

* docs(guardrails): document custom profile

* docs(search-exa): warn against production mock bypass

* docs(webhook): clarify endpoint security constraints

* docs(nodes): bring the infrastructure nodes up to the new Profiles contract

guardrails named its profiles "Basic", "Strict" and "Custom" — display names
the metadata never declares, so no row resolved to a profile and the declared
default was not marked on any of them. Rows now use the declared keys, and the
prose that referred to the display names follows. remote and rerank_cohere
needed the intro sentence; rerank_cohere also described its `custom` profile in
a trailing sentence rather than listing it, so a profile the configuration
panel offers had no row.

Five nodes carried an `## About` section that was not about a third-party
service. webhook and local_text_output were filler — "RocketRide is the
pipeline system that hosts this node", "Python provides the filesystem
functions used by this node" — and each dragged along an `## Upstream docs`
link back to docs.rocketride.org that existed only because `## About` requires
that section.

The three managed-database nodes were different: their About carried a real
fact, that RocketRide provisions a per-tenant database and the node resolves it
from the signed-in identity rather than from connection fields. That is
configuration guidance, and each `## Configuration` already gestured at it, so
it moves there in full rather than being dropped.

search_exa said the same thing twice: the third paragraph of `## What it does`
restated `## Notes` → URL safety almost sentence for sentence, and took the
section to nine sentences. The summary now states the guarantee and points at
Notes, which keeps the detail and regains the address classes the summary had
been carrying.

All 15 nodes pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* docs(nodes): clear the last three nodes the migration PRs did not cover (#2124)

These three were already on fix/docs before the six family migrations, so no
PR owned them and nothing re-validated them once #2022 tightened the contract.

ocr was not a documentation problem. Its table is the best-formed profile
table in the corpus — twelve profiles with the key and the title in separate
columns — but the first column is headed "Profile key", which PROFILE_HEADERS
did not alias, so every row resolved to an empty cell and the validator
reported all twelve profiles missing and twelve unknown rows. The alias is
added, with a test, because separating key from title is a shape worth
supporting rather than a mistake to correct. ocr additionally needed its
default marked and its title in the intro.

tool_mcp_client registers MCP Client and the Butterbase preset, each with its
own default, and only the RocketRide one was marked — so the Butterbase
preset's default was undocumented. Both are now marked and named.

tool_laserdata_memory needed the intro sentence.

All 124 nodes pass; 24 validator tests pass.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* docs(mcp): split MCP docs into stdio and http, retire the module doc

The MCP docs described only the stdio PyPI package, while the HTTP MCP
server merged from develop (PR #1880) carried its docs as a 613-line
co-located doc.md — the wrong depth for a public surface, in a location
the docs tree does not allow.

- docs/public/mcp/ now holds two folders: stdio/ and http/, each with a
  README.md, rendered in the sidebar as an MCP category with two pages.
  The two near-duplicate stdio docs (README.md export source + index.md
  site page) are merged into stdio/README.md, which serves as both the
  /protocols/mcp/stdio page and the packages/client-mcp README source
  (regenerated copy included).
- docs/public/mcp/http/README.md is a new public doc sized to how
  GitHub, Sentry, and Linear document their hosted MCP servers:
  endpoint, auth in two sentences, per-client setup, the 27 tools by
  capability group, example prompts, resources, widgets, self-hosting
  env vars, security, FAQ.
- packages/ai/src/ai/modules/mcp/doc.md is deleted; the few contributor
  facts that live nowhere else (engine-client seam, credentials-catalog
  builder gates, widget workspace) move to
  docs/development/engine/mcp-module.md. Everything else stays in git
  history.
- Pipeline: DOCS_ROOT_MOUNTS split per folder; a README.md at a mount
  root with no index sibling is now gathered as that mount's page (the
  blanket export-source skip is otherwise unchanged); export mapping,
  spine, redirects, footer link, and spine tests updated; stale
  /protocols/mcp links retargeted to /protocols/mcp/stdio.

Verified: docs:build (broken-link gate), docs:check, spine tests,
validate-client-docs.py all green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: fix accuracy drift across the docs tree from a full code-verified audit

Every fix traces to a finding confirmed against source by an independent
adversarial verification pass (10 audit lanes, 10 verifiers, 10 fix
executors; ~252 confirmed fixes applied, 12 refuted findings dropped).

Highlights:
- SDK docs (TS/Python): remove fictional APIs and behavior (.env
  auto-parsing, exponential backoff, Answer.parseJson, dapRequest, MIME
  table), correct signatures/defaults, add missing parameter rows
- Examples: pipeline samples now validate (components key, real
  providers/fields, embedded question lanes for qdrant)
- WebSocket protocol pages: correct wire commands, token semantics,
  response shapes, event names; document the run-log continuum
- VS Code docs: migrate to the grouped settings schema, real command
  surface and workflows
- Development docs: builder module table from live --list output,
  ci-gates matches actual CI, runnable command fixes
- Operate/reference: ROCKETRIDE_APIKEY vs ROCKETRIDE_AUTH scoping, CLI
  table corrections, working tar command
- Regenerated client-mcp/client-python/client-typescript READMEs via
  docs:export

Gates: docs:build (broken-link check), docs:check, validate-client-docs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(agents): land the pipeline-builder skill set in docs/agents/skills/ (#2125)

* docs(agents): land the pipeline-builder skill set in docs/agents/skills/

First occupants of the reserved skills directory: the five hand-written
pipeline-builder skills (orchestrator + design/configure/run/debug) plus
MCP_TOOL_CONTRACT.md, the frozen tool-name/result-shape contract against the
27-tool HTTP MCP server surface.

The skills are weak-model-first: verification by tools (validate_pipeline is
the compiler, the run result is the proof) and hard gates (Waiting = STOP,
cost approval, 17 forcing functions in GATE_PROTOCOL.md) rather than model
intelligence. Bundled L1 node index regenerated 2026-08-25 from a live
v3.3.1 engine (124 nodes, matches this branch's README corpus).

Deliberately not exported by docs:export (subdirectories are excluded);
README documents the layout and the future export hook. Bundled shims
conformed to repo ruff style; anti-example keys shortened to obvious
placeholders that clear the gitleaks rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(agents): apply review fixes to the pipeline-builder skill set

Code-verified review fixes on top of the initial drop:

- MCP_TOOL_CONTRACT: error envelope is {error_type, message, hint}; add
  pipelineTraceLevel to run_pipeline/run_dropper_pipe inputs (server
  default summary); list_integrations detail key is 'setup'
- L1 node index reconciled against the branch's node corpus: 167
  providers (renamed graph nodes, store tool flags, missing lanes, 45
  absent providers added); meta provenance + counts synced
- Error strings now match what the code emits verbatim (or are worded
  as symptom patterns): 'The service <provider> was not found',
  'references unknown component id', 'input has unknown lane',
  'Connection closed unexpectedly', 'Pipeline is already running.'
- ${ROCKETRIDE_*} prefix requirement restored in PIPELINE_ANTIPATTERNS
  and the rules summary (non-prefixed refs come back <REDACTED>)
- Shims: MIT headers, corrupt-cache reads follow the ERROR_JSON
  contract, fetch-doc docstring drift fixed, cross-skill hint path
- New tools/generate-index.py — the index regenerator three docs
  reference (SDK get_services(), atomic writes, --dry-run)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Krish Garg <krish.garg@rocketride.ai>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Dylan Savage <dylanmsavage@hotmail.com>

* docs: restyle the site, restructure the IA, and finish the content revamp (#2138)

* feat(docs): restyle the docs site to the RocketRide marketing design language

Port the marketing/cloud landing look onto the Docusaurus theme: the
red-orange star (#F93822) as sole accent over a warm paper field with a
dot grid (light) or the Abyss Deep near-black (dark); Ubuntu Mono
uppercase kickers; squared surfaces with hairline borders; contrast-
inversion hovers on cards and sidebar rows; a hard-orange-offset CTA
block; a floating form-fitting dark sidebar panel; and a rocket-mark
"you are here" indicator on the page TOC. Rebuild the homepage as a
Dify-style hero + numbered card sections using new global Card/CardGrid
MDX components.

Cascade notes: the build injects Infima/theme rules at (2,x,y) hacked
specificity and wraps CSS in cascade layers, so overrides variously
match the :not(#\#) hack, exceed it, or pin with !important — each case
is documented inline in custom.css.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): make sidebar group kickers readable in the mobile drawer

The sidebar menu markup is reused by the mobile navbar drawer, whose
surface is light — the white kicker text scoped to the menu vanished
there. Kickers now default to the star orange (readable on the drawer
in both themes); only the dark desktop panel re-whitens them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(site): restructure the IA into journey order (phases 1-3)

Rebuild the docs spine around the reader journey — Get Started, Concepts,
Clients, Guides, Examples, Nodes, Connect, Deploy & Operate, Reference,
Support & Community — and make the docs/public/product/ tree, doc ids, and
URLs one namespace again.

- Move 12 pages, split 4 by audience (performance, error-handling, apps,
  cli)…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builder Node builder tooling and ./builder workflows ci/cd CI/CD and build system docs Documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant