Skip to content

feat: consolidate docs and blogs into web monorepo#2

Open
hallelx2 wants to merge 21 commits into
mainfrom
halleluyaholudele/docs-blogs-monorepo-consolidation
Open

feat: consolidate docs and blogs into web monorepo#2
hallelx2 wants to merge 21 commits into
mainfrom
halleluyaholudele/docs-blogs-monorepo-consolidation

Conversation

@hallelx2

@hallelx2 hallelx2 commented Jun 20, 2026

Copy link
Copy Markdown
Owner

This PR consolidates the vectorless-docs repository and the new vectorless-blog repository into the main web monorepo under apps/docs and apps/blogs. Deprecated/obsolete packages (ts-sdk, openapi, mcp-tools) have been removed, database migrations applied to Neon, and Next.js builds verified.

Summary by Sourcery

Consolidate the standalone docs and blog properties into the main web monorepo by adding a new Fumadocs-powered docs app and a marketing-style blog app, while removing deprecated SDK, OpenAPI, and MCP tools packages.

New Features:

  • Add a new apps/docs Next.js application using Fumadocs for Vectorless documentation, including home, concepts, getting-started, SDK, API, and self-hosting content skeletons.
  • Add a new apps/blogs Next.js application providing a Vectorless marketing blog with featured articles and an interactive retrieval demo UI.

Enhancements:

  • Align shared branding, typography, and layout components across docs and blog apps, including Vectorless mark, hero shader, and Tailwind-based design tokens.

Chores:

  • Remove deprecated packages (ts-sdk, openapi, mcp-tools) and associated config from the monorepo to simplify the codebase.

Summary by CodeRabbit

Release Notes

  • New Features

    • Launched comprehensive documentation site with getting-started guides, core concepts, SDK examples, and API reference
    • Added interactive blog demo application showcasing document ingestion and retrieval workflows
  • Chores

    • Updated React dependencies to latest versions
    • Simplified CI/CD workflows and removed deprecated build infrastructure
    • Consolidated project dependencies for improved consistency

hallelx2 and others added 17 commits June 6, 2026 15:14
Brand-matched Fumadocs (Next.js App Router) documentation site for
docs.vectorless.store.

- Dark theme primary; Geist Sans + Geist Mono + Instrument Serif display
- Blue->pink brand gradient and subtle grid background texture
- Branded landing page (hero, feature grid, quickstart strip)
- Sections: Getting Started, Core Concepts (tree retrieval, no-chunking,
  treewalk, citations), API Reference (placeholder), SDKs (TS/Python/Go),
  Self-hosting (Neon + R2 + QStash + Docker, placeholder)
- Orama search, OG images, llms.txt
- Uses canonical 'treewalk' strategy name (retired 'pageindex')
The Fumadocs site was wrongly built dark-first with a full-page grid
wash and aura/glow pseudo-elements. Restyle it to match the brand
visual identity in vectorless-why/DESIGN.md, which is LIGHT.

- Default theme -> light (RootProvider defaultTheme: 'light').
- Light is now the primary, clean canvas: #FCFCFD, ink #0A0A0A,
  secondary #3F3F46, muted #71717A, hairlines #E5E7EB.
- Remove the heavy body::before grid wash and body::after aura glow.
  Content/docs pages are clean near-white with whitespace.
- Reintroduce only a very faint brand grid rgba(20,86,240,0.06) on the
  landing hero, masked to fade out (.vl-hero-grid).
- Keep the blue->pink signal gradient on exactly one hero line; drop the
  second serif/gradient register on the pull quote (now plain light sans
  with a mono eyebrow caption).
- Mono eyebrows at 0.16em tracking; body weight ~300 per DESIGN.md.
- Quickstart block is now a real dark inset terminal (#0A0A0A) — the one
  place dark is allowed.
- Dark theme retained as an optional toggle, not the default.

Restyle only: nav, sidebar, search, section structure and content
unchanged. pnpm build passes.
The Fumadocs site was wrongly built dark-first with a full-page grid
wash and aura/glow pseudo-elements. Restyle it to match the brand
visual identity in vectorless-why/DESIGN.md, which is LIGHT.

- Default theme -> light (RootProvider defaultTheme: 'light').
- Light is now the primary, clean canvas: #FCFCFD, ink #0A0A0A,
  secondary #3F3F46, muted #71717A, hairlines #E5E7EB.
- Remove the heavy body::before grid wash and body::after aura glow.
  Content/docs pages are clean near-white with whitespace.
- Reintroduce only a very faint brand grid rgba(20,86,240,0.06) on the
  landing hero, masked to fade out (.vl-hero-grid).
- Keep the blue->pink signal gradient on exactly one hero line; drop the
  second serif/gradient register on the pull quote (now plain light sans
  with a mono eyebrow caption).
- Mono eyebrows at 0.16em tracking; body weight ~300 per DESIGN.md.
- Quickstart block is now a real dark inset terminal (#0A0A0A) — the one
  place dark is allowed.
- Dark theme retained as an optional toggle, not the default.

Restyle only: nav, sidebar, search, section structure and content
unchanged. pnpm build passes.
Replace the invented node-graph mark with the canonical logo — blue tile +
white V (M4 4 L12 20 L20 4) + pink focal dot — matching vectorless-dashboard's
icon.tsx; add the matching app favicon. Wordmark in Geist medium.

Closes HAL-191.
Replace the invented node-graph mark with the canonical logo — blue tile +
white V (M4 4 L12 20 L20 4) + pink focal dot — matching vectorless-dashboard's
icon.tsx; add the matching app favicon. Wordmark in Geist medium.

Closes HAL-191.
Elevate the marketing/home surface within the Vectorless light brand:
- Hero: real V mark, staggered precision reveal, refined terminal inset
- New document -> tree -> cited answer SVG motif (hairline, blue path, single pink citation dot; edges draw + nodes snap)
- Feature grid with mono index numbers and hover accent
- Parse/Walk/Cite three-step band
- Refined Instrument-Serif thesis closer with CTA

No new gradients, no dark page bg, no new mark - honors DESIGN.md.
git-subtree-dir: apps/docs
git-subtree-mainline: 040e25c
git-subtree-split: 8eee521
@vercel

vercel Bot commented Jun 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vectorless-web Ready Ready Preview, Comment Jun 20, 2026 5:16pm

@sourcery-ai

sourcery-ai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds new apps/docs and apps/blogs Next.js applications into the web monorepo (Fumadocs-based docs site and a rich marketing/blog experience), wires them into shared branding/LLM tooling, and removes deprecated SDK/openapi/mcp-tools packages from the workspace.

File-Level Changes

Change Details Files
Introduce standalone Vectorless marketing blog app under apps/blogs with a rich animated landing page and Gemini-powered retrieval demo.
  • Create Next.js app shell for blogs including RootLayout, Next config, TS config, Tailwind/PostCSS setup, fonts, and utility hooks/helpers.
  • Implement a single-page blog experience (app/page.tsx) with category filtering, modal article reader, and an interactive retrieval demo wired to mock Gemini-like behaviour using motion/react animations.
  • Add blog-specific package.json and tooling (lint, README, environment template) and allow remote image domains in Next images config.
apps/blogs/app/page.tsx
apps/blogs/app/layout.tsx
apps/blogs/app/globals.css
apps/blogs/next.config.ts
apps/blogs/tsconfig.json
apps/blogs/package.json
apps/blogs/hooks/use-mobile.ts
apps/blogs/lib/utils.ts
apps/blogs/postcss.config.mjs
apps/blogs/eslint.config.mjs
apps/blogs/README.md
apps/blogs/next-env.d.ts
apps/blogs/.env.example
apps/blogs/.eslintrc.json
apps/blogs/.gitignore
apps/blogs/metadata.json
Add a new docs app under apps/docs using Fumadocs, with Vectorless-branded home page, documentation layout, and content structure.
  • Configure Next/Fumadocs integration with MDX source config, search, proxy routes, OG image routes, and LLM text feeds for docs.
  • Implement branded home/landing page (treewalk motif, shader background, GSAP-based hero animations) and docs layout wired to shared nav/logo options.
  • Define global Tailwind CSS theme tokens, typography, and Fumadocs overrides to match Vectorless brand and enforce light-only theme.
  • Add docs metadata (app layout, fonts, shared layout helpers, git config) and TS/ESlint/PostCSS configs for the new app.
  • Seed documentation content hierarchy with MDX pages for introduction, getting started, concepts (tree retrieval, no-chunking, treewalk, citations), SDK overviews for TS/Python/Go, self-hosting guide, and placeholder API reference.
apps/docs/src/app/(home)/page.tsx
apps/docs/src/app/(home)/layout.tsx
apps/docs/src/app/layout.tsx
apps/docs/src/app/global.css
apps/docs/src/app/icon.tsx
apps/docs/src/app/docs/layout.tsx
apps/docs/src/app/docs/[[...slug]]/page.tsx
apps/docs/src/app/og/docs/[...slug]/route.tsx
apps/docs/src/app/llms.mdx/docs/[[...slug]]/route.ts
apps/docs/src/app/llms.txt/route.ts
apps/docs/src/app/llms-full.txt/route.ts
apps/docs/src/app/api/search/route.ts
apps/docs/src/components/HeroShader.tsx
apps/docs/src/components/mdx.tsx
apps/docs/src/app/(home)/treewalk-motif.tsx
apps/docs/src/hooks/useGsap.ts
apps/docs/src/lib/source.ts
apps/docs/src/lib/layout.shared.tsx
apps/docs/src/lib/fonts.ts
apps/docs/src/lib/shared.ts
apps/docs/src/lib/cn.ts
apps/docs/content/docs/index.mdx
apps/docs/content/docs/meta.json
apps/docs/content/docs/getting-started/index.mdx
apps/docs/content/docs/getting-started/quickstart.mdx
apps/docs/content/docs/getting-started/meta.json
apps/docs/content/docs/concepts/index.mdx
apps/docs/content/docs/concepts/tree-retrieval.mdx
apps/docs/content/docs/concepts/no-chunking.mdx
apps/docs/content/docs/concepts/treewalk.mdx
apps/docs/content/docs/concepts/citations.mdx
apps/docs/content/docs/concepts/meta.json
apps/docs/content/docs/sdks/index.mdx
apps/docs/content/docs/sdks/typescript.mdx
apps/docs/content/docs/sdks/python.mdx
apps/docs/content/docs/sdks/go.mdx
apps/docs/content/docs/sdks/meta.json
apps/docs/content/docs/self-hosting/index.mdx
apps/docs/content/docs/self-hosting/meta.json
apps/docs/content/docs/getting-started/meta.json
apps/docs/content/docs/api/index.mdx
apps/docs/content/docs/api/meta.json
apps/docs/README.md
apps/docs/tsconfig.json
apps/docs/package.json
apps/docs/postcss.config.mjs
apps/docs/eslint.config.mjs
apps/docs/source.config.ts
apps/docs/proxy.ts
Wire shared branding, fonts, and metadata across docs/blog apps and adjust workspace tooling.
  • Define shared Vectorless fonts (Geist Sans/Mono, Instrument Serif) and logo mark components used across the docs home, layout, and favicon.
  • Standardize nav links and git metadata in layout.shared.tsx and shared.ts, ensuring docs link back to the main engine repo and control plane.
  • Enforce light-only theme and Mintlify-style appearance via global CSS, including grid-paper background, hero gradients, and typography utilities.
  • Add or update config files (tsconfig, ESLint, PostCSS) and Tailwind integrations for the new apps to build correctly in the monorepo.
apps/docs/src/lib/fonts.ts
apps/docs/src/lib/layout.shared.tsx
apps/docs/src/lib/shared.ts
apps/docs/src/app/icon.tsx
apps/docs/src/app/global.css
apps/docs/package.json
apps/docs/tsconfig.json
apps/docs/postcss.config.mjs
apps/docs/eslint.config.mjs
apps/docs/next.config.mjs
apps/blogs/app/layout.tsx
apps/blogs/app/globals.css
apps/blogs/next.config.ts
apps/blogs/tsconfig.json
apps/blogs/postcss.config.mjs
apps/blogs/eslint.config.mjs
Remove deprecated packages (ts-sdk, openapi, mcp-tools) and their artifacts from the monorepo.
  • Delete deprecated TypeScript SDK package including source, tests, build configs, and metadata.
  • Delete OpenAPI package containing the engine OpenAPI YAML and package.json.
  • Delete MCP tools package including handlers, tools, types, and build configs.
  • Rely on new placeholder docs/API sections instead of maintaining these deprecated packages.
packages/ts-sdk/**
packages/openapi/**
packages/mcp-tools/**

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds two new Next.js apps (apps/blogs and apps/docs), removes the packages/mcp-tools, packages/ts-sdk, and packages/openapi packages entirely, simplifies CI commands to workspace-level pnpm invocations, and pins React package versions via pnpm overrides.

Changes

Monorepo Maintenance: CI, React Pins, and Legacy Package Removal

Layer / File(s) Summary
CI simplification and React version pinning
.github/workflows/ci.yml, package.json, apps/web/package.json
Lint/typecheck/build steps are replaced with workspace-level pnpm typecheck, pnpm lint, and pnpm build commands; the separate publish-ts-sdk.yml workflow is deleted; root package.json adds a pnpm.overrides block pinning React runtime and type versions; apps/web React deps are bumped to match.
Remove mcp-tools, ts-sdk, and openapi packages
packages/mcp-tools/src/*, packages/mcp-tools/..., packages/ts-sdk/src/*, packages/ts-sdk/..., packages/openapi/openapi.yaml, packages/openapi/package.json
All source files, schemas, handlers, error classes, HTTP transport, retry logic, upload helpers, build configs, and package manifests for packages/mcp-tools, packages/ts-sdk, and packages/openapi are deleted with no replacement.

New apps/blogs AI Demo Application

Layer / File(s) Summary
Package manifest, tooling config, and environment
apps/blogs/package.json, apps/blogs/tsconfig.json, apps/blogs/.eslintrc.json, apps/blogs/eslint.config.mjs, apps/blogs/postcss.config.mjs, apps/blogs/next.config.ts, apps/blogs/.env.example, apps/blogs/.gitignore, apps/blogs/next-env.d.ts, apps/blogs/metadata.json
Defines the @vectorless/blog package with Next.js scripts and dependency list; configures TypeScript, ESLint, and PostCSS; Next.js config enables standalone output, permits picsum.photos remote images, and conditionally disables HMR; .env.example documents GEMINI_API_KEY and APP_URL.
Root layout, global styles, and shared utilities
apps/blogs/app/globals.css, apps/blogs/app/layout.tsx, apps/blogs/lib/utils.ts, apps/blogs/hooks/use-mobile.ts
globals.css imports Tailwind, sets @theme color/font tokens, base html/body styles, and the .grid-paper utility; layout.tsx mounts three Google Fonts as CSS variables and exports metadata; lib/utils.ts exports cn(); hooks/use-mobile.ts exports useIsMobile() via matchMedia.
Blog index page with article drawer and terminal sandbox
apps/blogs/app/page.tsx
BlogPage defines domain types and hardcoded posts/authors, manages state for category filtering, a slide-out article drawer, and a timed ingestion/retrieval terminal modal. AnimatePresence from motion/react drives all animated transitions.

New apps/docs Fumadocs Documentation Site

Layer / File(s) Summary
Package manifest, tooling config, and MDX source setup
apps/docs/package.json, apps/docs/tsconfig.json, apps/docs/eslint.config.mjs, apps/docs/postcss.config.mjs, apps/docs/next.config.mjs, apps/docs/source.config.ts, apps/docs/proxy.ts, apps/docs/.gitignore, apps/docs/README.md
Defines @vectorless/docs with fumadocs-driven scripts; configures TypeScript, ESLint, PostCSS, and Next.js with fumadocs-mdx; source.config.ts declares the docs loader with page/meta schemas and markdown postprocessing; proxy.ts rewrites .md suffix and markdown-preferred requests to content.md paths.
Shared constants, fonts, source loader, and layout base
apps/docs/src/lib/shared.ts, apps/docs/src/lib/fonts.ts, apps/docs/src/lib/cn.ts, apps/docs/src/lib/source.ts, apps/docs/src/lib/layout.shared.tsx
shared.ts exports appName, route constants, and gitConfig; fonts.ts defines three localFont instances and fontVariables; source.ts wires the Fumadocs loader and exports getPageImage, getPageMarkdownUrl, and getLLMText; layout.shared.tsx exports VectorlessMark and baseOptions() for reuse across layouts.
Root layout, global CSS, MDX components, and favicon
apps/docs/src/app/layout.tsx, apps/docs/src/app/global.css, apps/docs/src/components/mdx.tsx, apps/docs/src/app/icon.tsx
layout.tsx renders RootProvider with forcedTheme: 'light'; global.css defines brand @theme tokens, forces light mode, and overrides Fumadocs prose/sidebar/TOC/callout/code/card styles; mdx.tsx exports getMDXComponents merging fumadocs defaults with Tabs/Steps/Cards; icon.tsx generates the 32×32 PNG favicon.
Animated home page and GSAP hook
apps/docs/src/hooks/useGsap.ts, apps/docs/src/components/HeroShader.tsx, apps/docs/src/app/(home)/treewalk-motif.tsx, apps/docs/src/app/(home)/layout.tsx, apps/docs/src/app/(home)/page.tsx
useGsap.ts exports useGsapEffect/useScopedRef; HeroShader gates GrainGradient via reduced-motion and IntersectionObserver; TreewalkMotif renders an inline SVG document-to-cited-answer illustration; the home page renders a GSAP-animated hero, motif section, features grid, and footer.
Docs pages, search, OG, and LLM route handlers
apps/docs/src/app/docs/layout.tsx, apps/docs/src/app/docs/[[...slug]]/page.tsx, apps/docs/src/app/api/search/route.ts, apps/docs/src/app/og/docs/[...slug]/route.tsx, apps/docs/src/app/llms.txt/route.ts, apps/docs/src/app/llms-full.txt/route.ts, apps/docs/src/app/llms.mdx/docs/[[...slug]]/route.ts
Docs layout wires DocsLayout with source page tree; the [[...slug]] page renders MDX with relative links and exports generateStaticParams/generateMetadata with OG image; search, OG, llms.txt, llms-full.txt, and llms.mdx routes serve their respective content from the source loader.
MDX documentation content pages
apps/docs/content/docs/**
Full MDX content and meta.json files added for: docs index, getting-started (overview + quickstart), core concepts (tree-retrieval, no-chunking, treewalk, citations), API reference, SDK pages (TypeScript, Python, Go), and self-hosting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 Hopping through the monorepo with glee,
Old packages gone — the tree is now free!
A blog for demos, a docs site in bloom,
With GSAP and treewalk, there's plenty of room.
Citations are real, no chunking in sight,
This rabbit merged code from morning to night! 🌸

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: consolidate docs and blogs into web monorepo' accurately and specifically describes the primary objective of this changeset, which involves integrating the vectorless-docs and vectorless-blog repositories as apps/docs and apps/blogs into the main monorepo.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch halleluyaholudele/docs-blogs-monorepo-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 and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The blog landing page (apps/blogs/app/page.tsx) has grown very large and mixes data, layout, and interactive demo logic in a single component; consider extracting the blog post data, vector illustrations, and the retrieval demo into separate modules/hooks to keep the page component focused and easier to reason about.
  • The Vectorless logo/mark is implemented in multiple places (apps/docs/src/lib/layout.shared.tsx, (home)/page.tsx, apps/web, and blog); it would be more maintainable to centralize this into a shared component so future brand tweaks only need to be made in one place.
  • The new blog app’s package.json pulls in several dependencies that aren’t used by the current codebase (e.g. @google/genai, @hookform/resolvers, firebase-tools); trimming these will keep installs faster and reduce maintenance surface area.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The blog landing page (`apps/blogs/app/page.tsx`) has grown very large and mixes data, layout, and interactive demo logic in a single component; consider extracting the blog post data, vector illustrations, and the retrieval demo into separate modules/hooks to keep the page component focused and easier to reason about.
- The Vectorless logo/mark is implemented in multiple places (`apps/docs/src/lib/layout.shared.tsx`, `(home)/page.tsx`, `apps/web`, and blog); it would be more maintainable to centralize this into a shared component so future brand tweaks only need to be made in one place.
- The new blog app’s `package.json` pulls in several dependencies that aren’t used by the current codebase (e.g. `@google/genai`, `@hookform/resolvers`, `firebase-tools`); trimming these will keep installs faster and reduce maintenance surface area.

## Individual Comments

### Comment 1
<location path="apps/blogs/next.config.ts" line_range="25-26" />
<code_context>
+  output: process.env.NEXT_STANDALONE === 'true' ? 'standalone' : undefined,
+  transpilePackages: ['motion'],
+  webpack: (config, {dev}) => {
+    // HMR is disabled in AI Studio via DISABLE_HMR env var.
+    // Do not modify�file watching is disabled to prevent flickering during agent edits.
+    if (dev && process.env.DISABLE_HMR === 'true') {
+      config.watchOptions = {
</code_context>
<issue_to_address>
**nitpick (typo):** Fix the mojibake em dash in the webpack comment to avoid encoding noise.

The line `// Do not modifyâ��file watching is disabled...` contains a mis-encoded em dash. Please change it to `// Do not modify—file watching is disabled...` to keep the comment readable and avoid encoding artifacts.

```suggestion
    // HMR is disabled in AI Studio via DISABLE_HMR env var.
    // Do not modify—file watching is disabled to prevent flickering during agent edits.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread apps/blogs/next.config.ts
Comment on lines +25 to +26
// HMR is disabled in AI Studio via DISABLE_HMR env var.
// Do not modify—file watching is disabled to prevent flickering during agent edits.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nitpick (typo): Fix the mojibake em dash in the webpack comment to avoid encoding noise.

The line // Do not modifyâ��file watching is disabled... contains a mis-encoded em dash. Please change it to // Do not modify—file watching is disabled... to keep the comment readable and avoid encoding artifacts.

Suggested change
// HMR is disabled in AI Studio via DISABLE_HMR env var.
// Do not modify�file watching is disabled to prevent flickering during agent edits.
// HMR is disabled in AI Studio via DISABLE_HMR env var.
// Do not modify—file watching is disabled to prevent flickering during agent edits.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 15

Caution

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

⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)

10-22: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add explicit permissions block to follow least-privilege principle.

The workflow uses default permissions which are overly broad. GitHub Actions should explicitly declare minimal required permissions.

🔒 Proposed fix to add permissions block
 lint-and-typecheck:
   name: Lint & Typecheck
   runs-on: ubuntu-latest
+  permissions:
+    contents: read
   steps:
🤖 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 @.github/workflows/ci.yml around lines 10 - 22, The lint-and-typecheck
workflow job is missing an explicit permissions block, which allows overly broad
default permissions. Add a permissions block to the lint-and-typecheck job that
specifies only the minimal required permissions. For this job which only needs
to checkout and read the repository contents, add a permissions block with
contents set to read. This follows the least-privilege principle by explicitly
declaring only the necessary permissions required for the job to execute.

Source: Linters/SAST tools

🧹 Nitpick comments (6)
apps/blogs/app/page.tsx (2)

614-618: 💤 Low value

Add referrerPolicy="no-referrer" for consistency.

The author avatar image at line 520-523 includes referrerPolicy="no-referrer", but the same image element in the article drawer (line 615) is missing it. Apply the same policy for consistency.

🔧 Proposed fix
                       <img 
                         src={activeArticle.author.avatarUrl} 
                         alt={activeArticle.author.name}
                         className="object-cover w-full h-full"
+                        referrerPolicy="no-referrer"
                       />
🤖 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 `@apps/blogs/app/page.tsx` around lines 614 - 618, The img element displaying
activeArticle.author.avatarUrl in the article drawer section is missing the
referrerPolicy attribute for consistency. Add the referrerPolicy="no-referrer"
attribute to the img element with className "object-cover w-full h-full" to
match the implementation of the same avatar image element that appears earlier
in the component at line 520-523.

699-699: ⚡ Quick win

Avoid as any type assertion.

The as any cast bypasses TypeScript's type safety. Instead, define a union type or use a type-safe assertion.

🔧 Proposed fix
+type DocId = 'vectorless-whitepaper.pdf' | 'fastify-manual.md' | 'terms-of-service.docx';
+
 const [selectedDoc, setSelectedDoc] = useState<'vectorless-whitepaper.pdf' | 'fastify-manual.md' | 'terms-of-service.docx'>('vectorless-whitepaper.pdf');

 // ...

-                          onClick={() => setSelectedDoc(doc.id as any)}
+                          onClick={() => setSelectedDoc(doc.id as DocId)}

Or refactor the document list to be typed:

                     {[
-                      { id: 'vectorless-whitepaper.pdf', size: '2.4 MB', type: 'PDF' },
-                      { id: 'fastify-manual.md', size: '480 KB', type: 'Markdown' },
-                      { id: 'terms-of-service.docx', size: '1.1 MB', type: 'Word Doc' }
+                      { id: 'vectorless-whitepaper.pdf' as const, size: '2.4 MB', type: 'PDF' },
+                      { id: 'fastify-manual.md' as const, size: '480 KB', type: 'Markdown' },
+                      { id: 'terms-of-service.docx' as const, size: '1.1 MB', type: 'Word Doc' }
                     ].map((doc) => {
🤖 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 `@apps/blogs/app/page.tsx` at line 699, Remove the `as any` type assertion from
the onClick handler where setSelectedDoc is called with doc.id. Instead, examine
the actual type of doc.id and the expected parameter type of setSelectedDoc
function. Either refactor the document list to ensure doc.id has the correct
type that matches setSelectedDoc's parameter type, or define a union type that
safely captures the possible types of doc.id without resorting to the unsafe `as
any` cast.
apps/blogs/package.json (1)

15-15: 💤 Low value

Consider removing autoprefixer (redundant with Tailwind v4).

Tailwind CSS v4 includes built-in Lightning CSS integration that handles vendor prefixes automatically. The separate autoprefixer dependency is likely redundant unless you have non-Tailwind CSS that requires it.

🤖 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 `@apps/blogs/package.json` at line 15, Remove the autoprefixer dependency from
the package.json file by deleting the line containing "autoprefixer": "^10.4.21"
in the dependencies section. Verify that your project is using Tailwind CSS v4
(check tailwind.config.js or similar configuration file to confirm it's v4) and
that there are no custom CSS files outside of Tailwind that require autoprefixer
functionality. After removal, you may need to run npm install or your package
manager's equivalent to update the lock file and ensure Tailwind's built-in
vendor prefixing handles all necessary browser compatibility.
apps/blogs/hooks/use-mobile.ts (1)

5-21: ⚖️ Poor tradeoff

Potential SSR hydration mismatch and inconsistent breakpoint logic.

The hook has several issues:

  1. Hydration mismatch risk: Initial state is undefined, coerced to false via !!isMobile (line 20). During SSR or initial render, this returns false, but after setTimeout fires, it may switch to true, causing a visual flicker.

  2. Inconsistent breakpoint checks: The matchMedia listener uses window.innerWidth < MOBILE_BREAKPOINT (line 11), but should use mql.matches to stay consistent with the media query definition.

  3. Missing SSR guard: If this hook is called during SSR, accessing window (line 9) will throw a runtime error.

  4. Unnecessary setTimeout: The zero-delay timeout is a workaround that indicates a deeper architectural issue.

♻️ Recommended fix
 export function useIsMobile() {
-  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
+  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
+    typeof window !== 'undefined' 
+      ? window.innerWidth < MOBILE_BREAKPOINT
+      : undefined
+  )

   React.useEffect(() => {
     const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
     const onChange = () => {
-      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
+      setIsMobile(mql.matches)
     }
     mql.addEventListener("change", onChange)
-    setTimeout(() => {
-      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
-    }, 0)
+    setIsMobile(mql.matches)
     return () => mql.removeEventListener("change", onChange)
   }, [])

   return !!isMobile
 }

Alternatively, consider using a library like react-responsive for more robust media query hooks.

🤖 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 `@apps/blogs/hooks/use-mobile.ts` around lines 5 - 21, The useIsMobile hook has
SSR safety and hydration consistency issues. First, add a guard to check if
window exists before accessing it to prevent SSR errors. Second, replace the
window.innerWidth comparison with mql.matches to ensure consistent breakpoint
logic between the matchMedia listener and initial state. Third, initialize
isMobile to false instead of undefined to prevent hydration mismatches between
server and client renders. Fourth, remove the setTimeout call as it's
unnecessary when using mql.matches for state synchronization, and ensure the
return statement properly coerces the boolean value.
apps/blogs/postcss.config.mjs (1)

3-6: ⚡ Quick win

Drop autoprefixer unless you still target legacy browsers.

Tailwind 4's PostCSS pipeline already handles prefixing, so this extra plugin is redundant for the modern app stack here.

Suggested cleanup
   plugins: {
     '`@tailwindcss/postcss`': {},
-    autoprefixer: {},
   },
🤖 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 `@apps/blogs/postcss.config.mjs` around lines 3 - 6, Remove the autoprefixer
plugin from the plugins object in the postcss.config.mjs file. Since Tailwind
4's PostCSS pipeline already handles CSS prefixing automatically, the redundant
autoprefixer entry should be deleted, leaving only the '`@tailwindcss/postcss`'
plugin in the configuration.
apps/docs/src/lib/layout.shared.tsx (1)

51-51: 💤 Low value

GitHub URL inconsistency with gitConfig.

The githubUrl hardcodes vectorless-engine as the repository name, but gitConfig.repo (from shared.ts) is set to vectorless-docs. This creates an inconsistency where gitConfig is defined but not used consistently.

If the intent is to link to the engine repository from the docs site, consider either:

  1. Renaming gitConfig.repo to gitConfig.docsRepo and adding gitConfig.engineRepo, or
  2. Adding a comment explaining why gitConfig.repo differs from the UI links
♻️ Proposed refactor for clarity
 export const gitConfig = {
   user: 'hallelx2',
-  repo: 'vectorless-docs',
+  docsRepo: 'vectorless-docs',
+  engineRepo: 'vectorless-engine',
   branch: 'main',
 };

Then in layout.shared.tsx:

-    githubUrl: `https://github.com/${gitConfig.user}/vectorless-engine`,
+    githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.engineRepo}`,

And update the Engine link:

-        url: 'https://github.com/hallelx2/vectorless-engine',
+        url: `https://github.com/${gitConfig.user}/${gitConfig.engineRepo}`,
🤖 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 `@apps/docs/src/lib/layout.shared.tsx` at line 51, The githubUrl hardcodes
'vectorless-engine' as the repository name, but this is inconsistent with
gitConfig.repo which is set to 'vectorless-docs' in shared.ts. To fix this
inconsistency, refactor the gitConfig object in shared.ts to distinguish between
the docs repository and engine repository by renaming gitConfig.repo to
gitConfig.docsRepo and adding a new gitConfig.engineRepo property set to
'vectorless-engine'. Then update the githubUrl assignment in layout.shared.tsx
to use gitConfig.engineRepo instead of the hardcoded 'vectorless-engine' string.
🤖 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 `@apps/blogs/.env.example`:
- Line 4: Remove the double quotes from the example secret values in the
.env.example file. Update GEMINI_API_KEY and the other API key placeholder
mentioned (line 9) by removing the surrounding quotes so the raw values are
shown without quotes. This prevents users from accidentally copying the quotes
as part of their actual secrets when pasting values into their .env
configuration.

In `@apps/blogs/metadata.json`:
- Line 5: The metadata.json file falsely claims the
MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API capability, but the actual
implementation in the blog app uses mocked responses in the handleRetrieve
function rather than any real Gemini API integration. Remove the
MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API entry from the majorCapabilities array
in metadata.json to accurately reflect that the app does not use server-side
Gemini API functionality.

In `@apps/blogs/next.config.ts`:
- Line 22: The conditional output logic in next.config.ts expects the
NEXT_STANDALONE environment variable to be set to 'true' to generate
.next/standalone, but this variable is not being configured in the CI and
deployment environments. Add NEXT_STANDALONE=true to the build environment in
.github/workflows/ci.yml and to the relevant service configurations in
docker-compose files to ensure the standalone output mode is actually generated
during builds and available for deployments that depend on it.

In `@apps/blogs/README.md`:
- Around line 1-20: Replace the AI Studio template boilerplate content in the
README with documentation specific to the Vectorless blog app. Remove the Google
AI Studio app URL reference (line 9), update the environment setup instructions
to reference .env.example instead of .env.local (line 18) and clarify that the
app does not require a Gemini API key, and replace the AI Studio banner image
(line 2) with appropriate Vectorless branding to match the actual application
purpose and technology stack.

In `@apps/docs/content/docs/index.mdx`:
- Around line 48-50: The description property in the API Reference card
(title="API Reference" with href="/docs/api") currently states the API reference
is "generated from the engine's OpenAPI spec", but since this PR removes the
packages/openapi package, this description is now outdated and misleading.
Update the description text to accurately reflect the current source and purpose
of the API reference without referencing the OpenAPI spec generation.

In `@apps/docs/content/docs/sdks/go.mdx`:
- Around line 13-15: The Go module import path
`github.com/hallelx2/vectorless-go` in the go get command is invalid and returns
a 404 error from the module proxy, causing the installation to fail for users.
Verify the correct and currently published module path for the Go SDK and update
the go get command with the valid module path in the code snippet.

In `@apps/docs/content/docs/sdks/typescript.mdx`:
- Around line 45-57: In the streaming example under the Streaming section,
replace the Node.js-specific process.stdout.write call with a runtime-agnostic
approach such as console.log to handle the token text output. This ensures the
example works consistently across both Node.js and edge runtime environments
without requiring separate examples for different runtimes.

In `@apps/docs/content/docs/self-hosting/index.mdx`:
- Line 55: The docker run command uses the mutable `:latest` tag for the
ghcr.io/hallelx2/vectorless-engine image reference, which prevents reproducible
deployments and makes rollbacks difficult. Replace the `:latest` tag with a
specific version number (e.g., `:v1.0.0` or `:0.1.0`) or a digest hash to pin
the exact image being deployed. This ensures consistent, reproducible behavior
across deployments and enables safe version rollbacks when needed.

In `@apps/docs/proxy.ts`:
- Around line 14-29: The proxy function in proxy.ts is unused and needs to be
integrated into Next.js's middleware pipeline. Rename proxy.ts to middleware.ts
and move it to either the project root directory or the src/ directory
(depending on your project structure) so Next.js 16 can recognize and
automatically load it as middleware. If the proxy function is no longer needed
and won't be used, simply delete the proxy.ts file instead.

In `@apps/docs/README.md`:
- Around line 36-41: In the Design section of the README, update the theme
description that currently states "Dark theme primary" to accurately reflect
that the docs app is light-first with an optional dark toggle. Replace the
inaccurate theme designation with text that correctly describes the actual theme
implementation and user experience of the application.

In `@apps/docs/src/app/`(home)/page.tsx:
- Line 292: The Link component with the text "Status" currently uses href="#" as
a placeholder, which creates a dead navigation link in production. Either
replace the href="#" with a real destination URL pointing to a valid status
page, or if this should not be a navigation link at all, convert it from a Link
component to regular HTML text wrapped in a span or div element while preserving
the existing className styling.

In `@apps/docs/src/app/global.css`:
- Line 6: The Tailwind source scanning configuration in global.css only targets
ts and tsx files, which excludes content/**.mdx documentation files from being
scanned for utility classes, causing those classes to be purged from the output.
Modify the `@source` directive to include the content directory and mdx files by
updating the pattern to also scan documentation markdown files alongside the
existing TypeScript sources.

In `@apps/docs/src/app/layout.tsx`:
- Around line 21-24: The theme configuration object in the layout component has
theming disabled with enabled set to false and forcedTheme set to light, which
prevents users from switching between light and dark themes. To enable theme
switching functionality, change the enabled property to true and adjust the
forcedTheme setting appropriately to allow the theme toggle to work. This will
restore the ability for users to switch themes if dark mode is intended as an
optional choice.

In `@apps/docs/src/app/llms.txt/route.ts`:
- Around line 6-8: The GET function returns a Response without an explicit
Content-Type header, which causes the endpoint to be unreliable for clients
expecting plain-text. Modify the Response constructor in the GET function to
include a headers object with the Content-Type set to "text/plain" so that
clients can properly identify the response format.

In `@apps/docs/src/app/og/docs/`[...slug]/route.tsx:
- Around line 9-27: In the generateStaticParams() function, remove the lang:
page.locale property from the returned object since the route pattern
/og/docs/[...slug] does not have a [lang] segment. The function should only
return slug: getPageImage(page).segments. Additionally, investigate why
slug.slice(0, -1) is needed in the GET function while
getPageImage(page).segments appends 'image.png', and either clarify or fix this
contract mismatch between the helper function and route expectations.

---

Outside diff comments:
In @.github/workflows/ci.yml:
- Around line 10-22: The lint-and-typecheck workflow job is missing an explicit
permissions block, which allows overly broad default permissions. Add a
permissions block to the lint-and-typecheck job that specifies only the minimal
required permissions. For this job which only needs to checkout and read the
repository contents, add a permissions block with contents set to read. This
follows the least-privilege principle by explicitly declaring only the necessary
permissions required for the job to execute.

---

Nitpick comments:
In `@apps/blogs/app/page.tsx`:
- Around line 614-618: The img element displaying activeArticle.author.avatarUrl
in the article drawer section is missing the referrerPolicy attribute for
consistency. Add the referrerPolicy="no-referrer" attribute to the img element
with className "object-cover w-full h-full" to match the implementation of the
same avatar image element that appears earlier in the component at line 520-523.
- Line 699: Remove the `as any` type assertion from the onClick handler where
setSelectedDoc is called with doc.id. Instead, examine the actual type of doc.id
and the expected parameter type of setSelectedDoc function. Either refactor the
document list to ensure doc.id has the correct type that matches
setSelectedDoc's parameter type, or define a union type that safely captures the
possible types of doc.id without resorting to the unsafe `as any` cast.

In `@apps/blogs/hooks/use-mobile.ts`:
- Around line 5-21: The useIsMobile hook has SSR safety and hydration
consistency issues. First, add a guard to check if window exists before
accessing it to prevent SSR errors. Second, replace the window.innerWidth
comparison with mql.matches to ensure consistent breakpoint logic between the
matchMedia listener and initial state. Third, initialize isMobile to false
instead of undefined to prevent hydration mismatches between server and client
renders. Fourth, remove the setTimeout call as it's unnecessary when using
mql.matches for state synchronization, and ensure the return statement properly
coerces the boolean value.

In `@apps/blogs/package.json`:
- Line 15: Remove the autoprefixer dependency from the package.json file by
deleting the line containing "autoprefixer": "^10.4.21" in the dependencies
section. Verify that your project is using Tailwind CSS v4 (check
tailwind.config.js or similar configuration file to confirm it's v4) and that
there are no custom CSS files outside of Tailwind that require autoprefixer
functionality. After removal, you may need to run npm install or your package
manager's equivalent to update the lock file and ensure Tailwind's built-in
vendor prefixing handles all necessary browser compatibility.

In `@apps/blogs/postcss.config.mjs`:
- Around line 3-6: Remove the autoprefixer plugin from the plugins object in the
postcss.config.mjs file. Since Tailwind 4's PostCSS pipeline already handles CSS
prefixing automatically, the redundant autoprefixer entry should be deleted,
leaving only the '`@tailwindcss/postcss`' plugin in the configuration.

In `@apps/docs/src/lib/layout.shared.tsx`:
- Line 51: The githubUrl hardcodes 'vectorless-engine' as the repository name,
but this is inconsistent with gitConfig.repo which is set to 'vectorless-docs'
in shared.ts. To fix this inconsistency, refactor the gitConfig object in
shared.ts to distinguish between the docs repository and engine repository by
renaming gitConfig.repo to gitConfig.docsRepo and adding a new
gitConfig.engineRepo property set to 'vectorless-engine'. Then update the
githubUrl assignment in layout.shared.tsx to use gitConfig.engineRepo instead of
the hardcoded 'vectorless-engine' string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: da21b349-7a1f-4455-b0e5-75419ceb58b3

📥 Commits

Reviewing files that changed from the base of the PR and between a13e1dc and eaf1f4f.

⛔ Files ignored due to path filters (9)
  • apps/blogs/src/assets/images/golf_bag_coat_1781964385599.jpg is excluded by !**/*.jpg
  • apps/blogs/src/assets/images/golf_bg_1781964406657.jpg is excluded by !**/*.jpg
  • apps/blogs/src/assets/images/golf_lying_grass_1781964368724.jpg is excluded by !**/*.jpg
  • apps/docs/src/fonts/Geist.woff2 is excluded by !**/*.woff2
  • apps/docs/src/fonts/GeistMono.woff2 is excluded by !**/*.woff2
  • apps/docs/src/fonts/InstrumentSerif-Italic.ttf is excluded by !**/*.ttf
  • apps/docs/src/fonts/InstrumentSerif.ttf is excluded by !**/*.ttf
  • apps/web/public/Vectorless-Whitepaper.pdf is excluded by !**/*.pdf
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (96)
  • .github/workflows/ci.yml
  • .github/workflows/publish-ts-sdk.yml
  • apps/blogs/.env.example
  • apps/blogs/.eslintrc.json
  • apps/blogs/.gitignore
  • apps/blogs/README.md
  • apps/blogs/app/globals.css
  • apps/blogs/app/layout.tsx
  • apps/blogs/app/page.tsx
  • apps/blogs/eslint.config.mjs
  • apps/blogs/hooks/use-mobile.ts
  • apps/blogs/lib/utils.ts
  • apps/blogs/metadata.json
  • apps/blogs/next-env.d.ts
  • apps/blogs/next.config.ts
  • apps/blogs/package.json
  • apps/blogs/postcss.config.mjs
  • apps/blogs/tsconfig.json
  • apps/docs/.gitignore
  • apps/docs/README.md
  • apps/docs/content/docs/api/index.mdx
  • apps/docs/content/docs/api/meta.json
  • apps/docs/content/docs/concepts/citations.mdx
  • apps/docs/content/docs/concepts/index.mdx
  • apps/docs/content/docs/concepts/meta.json
  • apps/docs/content/docs/concepts/no-chunking.mdx
  • apps/docs/content/docs/concepts/tree-retrieval.mdx
  • apps/docs/content/docs/concepts/treewalk.mdx
  • apps/docs/content/docs/getting-started/index.mdx
  • apps/docs/content/docs/getting-started/meta.json
  • apps/docs/content/docs/getting-started/quickstart.mdx
  • apps/docs/content/docs/index.mdx
  • apps/docs/content/docs/meta.json
  • apps/docs/content/docs/sdks/go.mdx
  • apps/docs/content/docs/sdks/index.mdx
  • apps/docs/content/docs/sdks/meta.json
  • apps/docs/content/docs/sdks/python.mdx
  • apps/docs/content/docs/sdks/typescript.mdx
  • apps/docs/content/docs/self-hosting/index.mdx
  • apps/docs/content/docs/self-hosting/meta.json
  • apps/docs/eslint.config.mjs
  • apps/docs/next.config.mjs
  • apps/docs/package.json
  • apps/docs/postcss.config.mjs
  • apps/docs/proxy.ts
  • apps/docs/source.config.ts
  • apps/docs/src/app/(home)/layout.tsx
  • apps/docs/src/app/(home)/page.tsx
  • apps/docs/src/app/(home)/treewalk-motif.tsx
  • apps/docs/src/app/api/search/route.ts
  • apps/docs/src/app/docs/[[...slug]]/page.tsx
  • apps/docs/src/app/docs/layout.tsx
  • apps/docs/src/app/global.css
  • apps/docs/src/app/icon.tsx
  • apps/docs/src/app/layout.tsx
  • apps/docs/src/app/llms-full.txt/route.ts
  • apps/docs/src/app/llms.mdx/docs/[[...slug]]/route.ts
  • apps/docs/src/app/llms.txt/route.ts
  • apps/docs/src/app/og/docs/[...slug]/route.tsx
  • apps/docs/src/components/HeroShader.tsx
  • apps/docs/src/components/mdx.tsx
  • apps/docs/src/hooks/useGsap.ts
  • apps/docs/src/lib/cn.ts
  • apps/docs/src/lib/fonts.ts
  • apps/docs/src/lib/layout.shared.tsx
  • apps/docs/src/lib/shared.ts
  • apps/docs/src/lib/source.ts
  • apps/docs/tsconfig.json
  • apps/web/package.json
  • apps/web/tsconfig.tsbuildinfo
  • package.json
  • packages/mcp-tools/package.json
  • packages/mcp-tools/src/handlers.ts
  • packages/mcp-tools/src/index.ts
  • packages/mcp-tools/src/schemas.ts
  • packages/mcp-tools/src/tools.ts
  • packages/mcp-tools/src/types.ts
  • packages/mcp-tools/tsconfig.json
  • packages/mcp-tools/tsup.config.ts
  • packages/openapi/openapi.yaml
  • packages/openapi/package.json
  • packages/ts-sdk/LICENSE
  • packages/ts-sdk/README.md
  • packages/ts-sdk/__tests__/client.test.ts
  • packages/ts-sdk/__tests__/integration.test.ts
  • packages/ts-sdk/package.json
  • packages/ts-sdk/src/client.ts
  • packages/ts-sdk/src/config.ts
  • packages/ts-sdk/src/errors.ts
  • packages/ts-sdk/src/http.ts
  • packages/ts-sdk/src/index.ts
  • packages/ts-sdk/src/retry.ts
  • packages/ts-sdk/src/types.ts
  • packages/ts-sdk/src/upload.ts
  • packages/ts-sdk/tsconfig.json
  • packages/ts-sdk/tsup.config.ts
💤 Files with no reviewable changes (26)
  • packages/ts-sdk/tsconfig.json
  • packages/ts-sdk/tests/client.test.ts
  • packages/mcp-tools/package.json
  • packages/mcp-tools/src/types.ts
  • packages/ts-sdk/tests/integration.test.ts
  • packages/ts-sdk/tsup.config.ts
  • packages/ts-sdk/src/config.ts
  • packages/ts-sdk/src/http.ts
  • packages/ts-sdk/package.json
  • packages/ts-sdk/src/upload.ts
  • packages/mcp-tools/src/tools.ts
  • packages/ts-sdk/LICENSE
  • packages/mcp-tools/src/handlers.ts
  • packages/ts-sdk/README.md
  • packages/ts-sdk/src/retry.ts
  • packages/mcp-tools/src/schemas.ts
  • packages/ts-sdk/src/index.ts
  • packages/ts-sdk/src/errors.ts
  • packages/mcp-tools/tsup.config.ts
  • .github/workflows/publish-ts-sdk.yml
  • packages/ts-sdk/src/client.ts
  • packages/openapi/openapi.yaml
  • packages/openapi/package.json
  • packages/ts-sdk/src/types.ts
  • packages/mcp-tools/src/index.ts
  • packages/mcp-tools/tsconfig.json

Comment thread apps/blogs/.env.example
# GEMINI_API_KEY: Required for Gemini AI API calls.
# AI Studio automatically injects this at runtime from user secrets.
# Users configure this via the Secrets panel in the AI Studio UI.
GEMINI_API_KEY="MY_GEMINI_API_KEY"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the quotes from the example secrets.

These placeholders are meant to be copied into Secrets / .env as raw values. Keeping the quotes makes them easier to paste incorrectly, and dotenv-linter already flags both lines.

Suggested cleanup
-GEMINI_API_KEY="MY_GEMINI_API_KEY"
+GEMINI_API_KEY=MY_GEMINI_API_KEY

 # APP_URL: The URL where this applet is hosted.
@@
-APP_URL="MY_APP_URL"
+APP_URL=MY_APP_URL

Also applies to: 9-9

🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 4-4: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)

🤖 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 `@apps/blogs/.env.example` at line 4, Remove the double quotes from the example
secret values in the .env.example file. Update GEMINI_API_KEY and the other API
key placeholder mentioned (line 9) by removing the surrounding quotes so the raw
values are shown without quotes. This prevents users from accidentally copying
the quotes as part of their actual secrets when pasting values into their .env
configuration.

Source: Linters/SAST tools

Comment thread apps/blogs/metadata.json
"name": "Vectorless Blog",
"description": "Insights, specifications, and performance analyses of structure-preserving retrieval architectures.",
"requestFramePermissions": [],
"majorCapabilities": ["MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for actual `@google/genai` imports and usage in apps/blogs

rg -n --type=ts --type=tsx -C3 "from ['\"]`@google/genai`['\"]" apps/blogs/
rg -n --type=ts --type=tsx -C3 "GoogleGenerativeAI|GenerativeModel" apps/blogs/

Repository: hallelx2/vectorless

Length of output: 119


🏁 Script executed:

# Search for `@google/genai` imports and usage - corrected approach
rg -n "`@google/genai`" apps/blogs/ -C3
rg -n "GoogleGenerativeAI|GenerativeModel" apps/blogs/ -C3

Repository: hallelx2/vectorless

Length of output: 445


🏁 Script executed:

# Read metadata.json to confirm the capability claim
cat apps/blogs/metadata.json

Repository: hallelx2/vectorless

Length of output: 316


🏁 Script executed:

# Read app/page.tsx to check for actual Gemini API usage
wc -l apps/blogs/app/page.tsx && head -50 apps/blogs/app/page.tsx

Repository: hallelx2/vectorless

Length of output: 1123


🏁 Script executed:

# Search for GoogleGenerativeAI or GenerativeModel usage
rg -n "GoogleGenerativeAI|GenerativeModel" apps/blogs/app/page.tsx -C5

Repository: hallelx2/vectorless

Length of output: 45


🏁 Script executed:

# Search for setTimeout/mock implementations in page.tsx
rg -n "setTimeout|mock" apps/blogs/app/page.tsx -C3

Repository: hallelx2/vectorless

Length of output: 1264


🏁 Script executed:

# Check imports at the top of page.tsx
sed -n '1,100p' apps/blogs/app/page.tsx | grep -n "import"

Repository: hallelx2/vectorless

Length of output: 195


🏁 Script executed:

# Get complete imports section
sed -n '1,30p' apps/blogs/app/page.tsx

Repository: hallelx2/vectorless

Length of output: 599


🏁 Script executed:

# Check the mock retrieval logic more thoroughly
sed -n '280,330p' apps/blogs/app/page.tsx

Repository: hallelx2/vectorless

Length of output: 2457


Capability claim inconsistent with implementation.

metadata.json claims MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API, but the blog app's demo uses entirely mocked retrieval logic. The @google/genai dependency is listed in package.json but is never imported or used. The handleRetrieve function in app/page.tsx (lines 280–330) uses hardcoded responses triggered by setTimeout, with no actual Gemini API integration.

Remove the capability claim from metadata.json or implement actual server-side Gemini API usage.

🤖 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 `@apps/blogs/metadata.json` at line 5, The metadata.json file falsely claims
the MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API capability, but the actual
implementation in the blog app uses mocked responses in the handleRetrieve
function rather than any real Gemini API integration. Remove the
MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API entry from the majorCapabilities array
in metadata.json to accurately reflect that the app does not use server-side
Gemini API functionality.

Comment thread apps/blogs/next.config.ts
},
],
},
output: process.env.NEXT_STANDALONE === 'true' ? 'standalone' : undefined,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

rg -n "NEXT_STANDALONE|standalone" .

Repository: hallelx2/vectorless

Length of output: 280


🏁 Script executed:

find . -type f \( -name "*.yml" -o -name "*.yaml" -o -name "Dockerfile*" -o -name "docker-compose*" -o -name "*.json" \) | grep -E "(workflows|docker|deploy|build)" | head -20

Repository: hallelx2/vectorless

Length of output: 259


🏁 Script executed:

fd -t f -e yml -e yaml . .github/workflows/ 2>/dev/null || echo "No workflows found"

Repository: hallelx2/vectorless

Length of output: 125


🏁 Script executed:

fd -t f \( -name "Dockerfile" -o -name "docker-compose*" -o -name "*.yml" -o -name "*.yaml" \) . | head -30

Repository: hallelx2/vectorless

Length of output: 294


🏁 Script executed:

cat -n package.json | grep -A 5 -B 5 "build\|deploy" || echo "Check package.json manually"

Repository: hallelx2/vectorless

Length of output: 432


🏁 Script executed:

cat .github/workflows/ci.yml

Repository: hallelx2/vectorless

Length of output: 1404


🏁 Script executed:

cat ./docker-compose.yml

Repository: hallelx2/vectorless

Length of output: 463


🏁 Script executed:

cat ./deploy/local/docker-compose.yml

Repository: hallelx2/vectorless

Length of output: 5719


CI and deploy configurations must set NEXT_STANDALONE=true if standalone output is required.

The conditional logic in apps/blogs/next.config.ts expects NEXT_STANDALONE=true to generate .next/standalone, but neither the CI workflow (.github/workflows/ci.yml) nor the docker-compose files set this variable. When the flag is omitted, the build silently falls back to the default output layout. Any deployment expecting .next/standalone will fail without explicit environment variable configuration.

🤖 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 `@apps/blogs/next.config.ts` at line 22, The conditional output logic in
next.config.ts expects the NEXT_STANDALONE environment variable to be set to
'true' to generate .next/standalone, but this variable is not being configured
in the CI and deployment environments. Add NEXT_STANDALONE=true to the build
environment in .github/workflows/ci.yml and to the relevant service
configurations in docker-compose files to ensure the standalone output mode is
actually generated during builds and available for deployments that depend on
it.

Comment thread apps/blogs/README.md
Comment on lines +1 to +20
<div align="center">
<img width="1200" height="475" alt="GHBanner" src="https://ai.google.dev/static/site-assets/images/share-ais-513315318.png" />
</div>

# Run and deploy your AI Studio app

This contains everything you need to run your app locally.

View your app in AI Studio: https://ai.studio/apps/3b8c6a97-eb59-4fb0-aade-3976e82644b1

## Run Locally

**Prerequisites:** Node.js


1. Install dependencies:
`npm install`
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
3. Run the app:
`npm run dev`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

README contains AI Studio template boilerplate inconsistent with actual app.

The README references:

  1. Google AI Studio app URL (line 9) — external service unrelated to this monorepo blog app
  2. .env.local setup (line 18) — the repo uses .env.example, and the app doesn't actually call the Gemini API
  3. AI Studio banner image (line 2) — branding mismatch with Vectorless

This appears to be leftover template content from an AI Studio export. Replace with documentation relevant to the Vectorless blog app, or clarify that this is a demo/template.

🤖 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 `@apps/blogs/README.md` around lines 1 - 20, Replace the AI Studio template
boilerplate content in the README with documentation specific to the Vectorless
blog app. Remove the Google AI Studio app URL reference (line 9), update the
environment setup instructions to reference .env.example instead of .env.local
(line 18) and clarify that the app does not require a Gemini API key, and
replace the AI Studio banner image (line 2) with appropriate Vectorless branding
to match the actual application purpose and technology stack.

Comment on lines +48 to +50
title="API Reference"
href="/docs/api"
description="The HTTP API surface — generated from the engine's OpenAPI spec."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the API Reference copy.

This card still says the API reference is "generated from the engine's OpenAPI spec", but this PR removes packages/openapi. That wording is now stale and will mislead readers about the source of truth.

✏️ Suggested copy change
-    description="The HTTP API surface — generated from the engine's OpenAPI spec."
+    description="The HTTP API surface — documented in the API reference."
🤖 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 `@apps/docs/content/docs/index.mdx` around lines 48 - 50, The description
property in the API Reference card (title="API Reference" with href="/docs/api")
currently states the API reference is "generated from the engine's OpenAPI
spec", but since this PR removes the packages/openapi package, this description
is now outdated and misleading. Update the description text to accurately
reflect the current source and purpose of the API reference without referencing
the OpenAPI spec generation.

<div className="flex gap-8">
<Link href="/docs" className="text-sm text-vl-muted hover:text-vl-ink">Documentation</Link>
<Link href="https://github.com/hallelx2/vectorless-engine" className="text-sm text-vl-muted hover:text-vl-ink">GitHub</Link>
<Link href="#" className="text-sm text-vl-muted hover:text-vl-ink">Status</Link>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace the placeholder status link with a real destination or non-link text.

Line 292 uses href="#", which creates a dead navigation target in production docs.

Suggested fix
-            <Link href="#" className="text-sm text-vl-muted hover:text-vl-ink">Status</Link>
+            <Link href="https://status.vectorless.dev" className="text-sm text-vl-muted hover:text-vl-ink">Status</Link>
🤖 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 `@apps/docs/src/app/`(home)/page.tsx at line 292, The Link component with the
text "Status" currently uses href="#" as a placeholder, which creates a dead
navigation link in production. Either replace the href="#" with a real
destination URL pointing to a valid status page, or if this should not be a
navigation link at all, convert it from a Link component to regular HTML text
wrapped in a span or div element while preserving the existing className
styling.

@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';

@source '../**/*.{ts,tsx}';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Include docs content files in Tailwind source scanning.

Line 6 excludes content/**/*.mdx, so utility classes authored in documentation pages can be purged from output.

Suggested fix
 `@source` '../**/*.{ts,tsx}';
+@source '../../content/**/*.{md,mdx}';
📝 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.

Suggested change
@source '../**/*.{ts,tsx}';
`@source` '../**/*.{ts,tsx}';
`@source` '../../content/**/*.{md,mdx}';
🧰 Tools
🪛 Stylelint (17.13.0)

[error] 6-6: Unexpected unknown at-rule "@source" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

🤖 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 `@apps/docs/src/app/global.css` at line 6, The Tailwind source scanning
configuration in global.css only targets ts and tsx files, which excludes
content/**.mdx documentation files from being scanned for utility classes,
causing those classes to be purged from the output. Modify the `@source` directive
to include the content directory and mdx files by updating the pattern to also
scan documentation markdown files alongside the existing TypeScript sources.

Comment on lines +21 to +24
theme={{
enabled: false,
forcedTheme: 'light',
}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enable theme switching if dark mode is intended to remain optional.

Line 22-23 hard-disable theming (enabled: false, forcedTheme: 'light'), which prevents any dark-theme toggle behavior.

Suggested fix
         <RootProvider
           theme={{
-            enabled: false,
-            forcedTheme: 'light',
+            enabled: true,
+            defaultTheme: 'light',
           }}
         >
📝 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.

Suggested change
theme={{
enabled: false,
forcedTheme: 'light',
}}
theme={{
enabled: true,
defaultTheme: 'light',
}}
🤖 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 `@apps/docs/src/app/layout.tsx` around lines 21 - 24, The theme configuration
object in the layout component has theming disabled with enabled set to false
and forcedTheme set to light, which prevents users from switching between light
and dark themes. To enable theme switching functionality, change the enabled
property to true and adjust the forcedTheme setting appropriately to allow the
theme toggle to work. This will restore the ability for users to switch themes
if dark mode is intended as an optional choice.

Comment on lines +6 to +8
export function GET() {
return new Response(llms(source).index());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Set an explicit plain-text response header.

llms.txt is returned as a bare string, so the response currently has no Content-Type. That makes the endpoint less reliable for clients that fetch it as a plain-text artifact.

Suggested fix
 export function GET() {
-  return new Response(llms(source).index());
+  return new Response(llms(source).index(), {
+    headers: {
+      'Content-Type': 'text/plain; charset=utf-8',
+    },
+  });
 }
📝 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.

Suggested change
export function GET() {
return new Response(llms(source).index());
}
export function GET() {
return new Response(llms(source).index(), {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
},
});
}
🤖 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 `@apps/docs/src/app/llms.txt/route.ts` around lines 6 - 8, The GET function
returns a Response without an explicit Content-Type header, which causes the
endpoint to be unreliable for clients expecting plain-text. Modify the Response
constructor in the GET function to include a headers object with the
Content-Type set to "text/plain" so that clients can properly identify the
response format.

Comment on lines +9 to +27
export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
const { slug } = await params;
const page = source.getPage(slug.slice(0, -1));
if (!page) notFound();

return new ImageResponse(
<DefaultImage title={page.data.title} description={page.data.description} site={appName} />,
{
width: 1200,
height: 630,
},
);
}

export function generateStaticParams() {
return source.getPages().map((page) => ({
lang: page.locale,
slug: getPageImage(page).segments,
}));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,260p' apps/docs/src/lib/source.ts
sed -n '1,220p' apps/docs/src/app/og/docs/[...slug]/route.tsx
rg -n "getPageImage\(|source\.getPage\(|lang:" apps/docs/src -C 3

Repository: hallelx2/vectorless

Length of output: 6141


🏁 Script executed:

# Check the actual directory structure for the route
find apps/docs/src/app -type d -name "*og*" -o -name "*docs*" | sort

# Check for any parent route groups or configurations
rg -n "lang|locale" apps/docs/src/app/og -C 2

# Check the main docs route for comparison
cat -n apps/docs/src/app/docs/[[...slug]]/page.tsx | head -50

Repository: hallelx2/vectorless

Length of output: 2830


Remove lang from generateStaticParams() return object.

The route pattern /og/docs/[...slug] has no [lang] segment, yet generateStaticParams() returns lang: page.locale (line 25). This breaks the static params contract—Next.js cannot route to a segment that doesn't exist in the pattern. The lang property should be removed since it's unused by this route.

Additionally, slug.slice(0, -1) (line 11) compensates for getPageImage(page).segments appending 'image.png', indicating a deeper contract mismatch between the helper and route expectations that should be clarified or fixed.

🤖 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 `@apps/docs/src/app/og/docs/`[...slug]/route.tsx around lines 9 - 27, In the
generateStaticParams() function, remove the lang: page.locale property from the
returned object since the route pattern /og/docs/[...slug] does not have a
[lang] segment. The function should only return slug:
getPageImage(page).segments. Additionally, investigate why slug.slice(0, -1) is
needed in the GET function while getPageImage(page).segments appends
'image.png', and either clarify or fix this contract mismatch between the helper
function and route expectations.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant