feat(agents): add technology stack subagents for modern web development#152
feat(agents): add technology stack subagents for modern web development#152marcusquinn merged 4 commits intomainfrom
Conversation
Add subagents documenting best practices and common hazards for: UI/Frontend: - tailwind-css.md: Positioning, layouts, responsive design, glow effects - react-context.md: State management, providers, hooks patterns - i18next.md: Internationalization, multi-locale translations - nextjs-layouts.md: App Router layouts, providers, route groups API/Backend: - hono.md: Lightweight web framework, middleware, validation - vercel-ai-sdk.md: AI streaming, useChat hook, providers - drizzle.md: Type-safe ORM, migrations, relations - better-auth.md: Authentication, OAuth, sessions Monorepo: - turborepo.md: Build system, workspaces, caching, pipelines Each subagent includes: - Common hazards from real development sessions - Code patterns and examples - Integration with Context7 MCP for current docs - Related agent references
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands the knowledge base by introducing a suite of new subagents focused on modern web development technologies. The primary goal is to provide developers with structured documentation, best practices, and insights into common pitfalls for various frontend, backend, and monorepo tools, thereby enhancing development efficiency and reducing errors. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughTen new comprehensive documentation files were added under Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Jan 22 06:37:58 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
🤖 Augment PR SummarySummary: This PR adds a set of new technology-focused “subagent” guides under Changes:
Technical Notes: These are documentation/agent-content additions only (no runtime code changes), intended to capture “lessons learned” and provide copy/paste starting points with Context7 MCP references for up-to-date docs. 🤖 Was this summary useful? React with 👍 or 👎 |
| return message.role === "assistant" ? ( | ||
| <div | ||
| key={i} | ||
| dangerouslySetInnerHTML={{ |
There was a problem hiding this comment.
This example renders marked.parse(part.text) via dangerouslySetInnerHTML without any sanitization, which can lead to XSS if assistant/user content includes HTML. Consider adding an explicit warning here (or showing a safe markdown renderer / sanitizer) so readers don’t copy an insecure pattern.
🤖 Was this useful? React with 👍 or 👎
| # Check for missing keys across locales | ||
| for locale in de es fr; do | ||
| echo "=== Missing in $locale ===" | ||
| diff <(jq -r 'paths | join(".")' en/common.json | sort) \ |
There was a problem hiding this comment.
.agent/tools/api/drizzle.md
Outdated
| email: text("email").notNull().unique(), | ||
| name: text("name"), | ||
| createdAt: timestamp("created_at").defaultNow().notNull(), | ||
| updatedAt: timestamp("updated_at").defaultNow().notNull(), |
There was a problem hiding this comment.
There was a problem hiding this comment.
Code Review
This pull request introduces an extensive set of documentation files, or "subagents," covering a wide range of modern web development technologies. The content is well-organized, providing quick references, detailed patterns, and common pitfalls for each topic. My review focuses on enhancing the accuracy and clarity of the code examples within these new markdown files. I've identified several incomplete or potentially confusing code snippets, a significant security concern regarding un-sanitized HTML rendering, and a few instances of incorrect API usage. Addressing these suggestions will improve the reliability and developer experience of this valuable documentation.
| dangerouslySetInnerHTML={{ | ||
| __html: marked.parse(part.text), | ||
| }} |
There was a problem hiding this comment.
Using dangerouslySetInnerHTML with the output of marked.parse without sanitization poses a significant Cross-Site Scripting (XSS) risk. An AI model's output could potentially be manipulated to include malicious HTML or script tags. It is crucial to sanitize the HTML before rendering it.
I recommend using a library like DOMPurify to clean the HTML string.
.agent/tools/ui/i18next.md
Outdated
| import { getTranslation } from "@workspace/i18n/server"; | ||
|
|
||
| export default async function Page({ params }) { | ||
| const { locale } = await params; |
There was a problem hiding this comment.
.agent/tools/api/hono.md
Outdated
| // Server: Define routes with types | ||
| const routes = app | ||
| .get("/api/users", (c) => c.json({ users: [] })) | ||
| .post("/api/users", zValidator("json", schema), (c) => { |
There was a problem hiding this comment.
The schema variable used in zValidator("json", schema) is not defined in this snippet. Based on the preceding "Zod Validation" example, it seems you intended to use createUserSchema. Using an undefined variable makes the example incorrect.
| .post("/api/users", zValidator("json", schema), (c) => { | |
| .post("/api/users", zValidator("json", createUserSchema), (c) => { |
|
|
||
| ```bash | ||
| # Use dotenv-cli for env loading | ||
| pnpm with-env turbo build |
There was a problem hiding this comment.
The command pnpm with-env is not a standard pnpm or dotenv-cli command. This is likely a custom script specific to this project, which could be confusing for readers. It would be clearer to either explain what the with-env script does or use a standard dotenv-cli command, such as pnpm dotenv -- turbo build.
.agent/tools/api/drizzle.md
Outdated
| console.log("Seeding complete!"); | ||
| } | ||
|
|
||
| seed().catch(console.error); |
There was a problem hiding this comment.
The error handling for the seed script is minimal. In a real-world scenario, especially if this script is part of a CI/CD pipeline, it's important for the script to exit with a non-zero status code on failure. This signals to the calling process that something went wrong.
Consider a more robust error handling approach.
| seed().catch(console.error); | |
| seed().catch((err) => { | |
| console.error(err); | |
| process.exit(1); | |
| }); |
| export function useSidebar() { | ||
| const context = useContext(SidebarContext); | ||
| if (!context) { | ||
| // Return safe defaults when used outside provider | ||
| return { | ||
| open: false, | ||
| setOpen: () => {}, | ||
| toggleSidebar: () => {}, | ||
| width: 384, | ||
| setWidth: () => {}, | ||
| }; | ||
| } | ||
| return context; | ||
| } |
There was a problem hiding this comment.
The useSidebar hook returns safe default values when used outside its provider. While this prevents crashes, it can silently hide bugs where a provider is missing but expected. A more robust pattern for required contexts is to throw an error. The existing useSidebarOptional hook already serves the use case for optional consumption. I recommend modifying useSidebar to enforce the presence of its provider.
| export function useSidebar() { | |
| const context = useContext(SidebarContext); | |
| if (!context) { | |
| // Return safe defaults when used outside provider | |
| return { | |
| open: false, | |
| setOpen: () => {}, | |
| toggleSidebar: () => {}, | |
| width: 384, | |
| setWidth: () => {}, | |
| }; | |
| } | |
| return context; | |
| } | |
| export function useSidebar() { | |
| const context = useContext(SidebarContext); | |
| if (!context) { | |
| throw new Error("useSidebar must be used within a SidebarProvider"); | |
| } | |
| return context; | |
| } |
| interface SidebarProviderProps { | ||
| readonly children: ReactNode; | ||
| readonly defaultOpen?: boolean; | ||
| } |
There was a problem hiding this comment.
The SidebarProvider accepts a defaultOpen prop, but the initial width is hardcoded from DEFAULT_WIDTH. For consistency and flexibility, consider also accepting a defaultWidth prop. This would allow the initial width to be set dynamically, for example, from a cookie read in a server component, similar to how defaultOpen is handled.
| interface SidebarProviderProps { | |
| readonly children: ReactNode; | |
| readonly defaultOpen?: boolean; | |
| } | |
| interface SidebarProviderProps { | |
| readonly children: ReactNode; | |
| readonly defaultOpen?: boolean; | |
| readonly defaultWidth?: number; | |
| } |
| <aside className={cn( | ||
| "w-80 shrink-0 transition-all", | ||
| open ? "w-80" : "w-0 overflow-hidden" | ||
| )}>Right</aside> |
There was a problem hiding this comment.
The cn utility function is used here but is not defined or imported. This is a common utility in Tailwind CSS projects (often a combination of clsx and tailwind-merge), but its presence should be noted for developers unfamiliar with it. Please add a comment or a note explaining what cn is and where it comes from.
| ```tsx | ||
| const [width, setWidth] = useState(384); | ||
| const [isResizing, setIsResizing] = useState(false); | ||
|
|
||
| // Disable transition while dragging for smooth resize | ||
| <aside className={cn( | ||
| "w-[var(--sidebar-width)]", | ||
| !isResizing && "transition-all duration-300" | ||
| )}> | ||
| {/* Resize handle */} | ||
| <div | ||
| onMouseDown={() => setIsResizing(true)} | ||
| className={cn( | ||
| "absolute left-0 top-0 h-full w-1 cursor-col-resize", | ||
| "hover:bg-primary/20 active:bg-primary/30", | ||
| // Wider hit area for easier grabbing | ||
| "before:absolute before:inset-y-0 before:-left-1 before:w-3" | ||
| )} | ||
| /> | ||
| </aside> | ||
| ``` |
There was a problem hiding this comment.
The example for a resizable element is incomplete. It shows how to initiate resizing with onMouseDown but omits the crucial logic for handling mousemove and mouseup events (usually on the window object) to actually perform the resize and stop it. This could be misleading. Please add a comment to clarify that this is a partial example and mention the missing event handlers.
| </div> | ||
|
|
||
| // Or with min-height for scroll behavior | ||
| <ScrollArea className="flex-1"> |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In @.agent/tools/api/better-auth.md:
- Around line 40-53: Replace the non-null assertions for environment variables
in the betterAuth config by first reading and validating them (e.g., const
GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID) and throwing or returning a
clear error if missing; update the socialProviders.google block in the auth
configuration to use those validated constants instead of
process.env.GOOGLE_CLIENT_ID! and process.env.GOOGLE_CLIENT_SECRET! so runtime
failures are prevented and errors show which variable is absent.
In @.agent/tools/api/drizzle.md:
- Around line 222-249: The seed.ts script's seed() currently calls
db.delete(posts) and db.delete(users) unconditionally which will wipe production
data; modify seed() (and its invocation) to require an explicit,
environment-gated opt-in before performing destructive deletes: check NODE_ENV
(or a new env var like ALLOW_DB_WIPE) and refuse to run deletes when NODE_ENV
=== "production" unless ALLOW_DB_WIPE === "true" (or a CLI flag) is set; add a
clear, logged confirmation prompt or fail-fast error if the safety gate isn't
satisfied, and ensure the script exits without deleting when the guard blocks
the operation.
In @.agent/tools/api/hono.md:
- Around line 127-133: The middleware registered via app.use("/api/admin/*",
...) only checks for existence of the Authorization header
(c.req.header("Authorization")) but never validates the token; update this
middleware to parse the header (e.g., check "Bearer " scheme), validate/verify
the token using your auth utility or JWT verifier, return 401 on missing or
invalid token, and attach the decoded user/claims to the context (e.g.,
c.req.user or c.set("user", ...)) before calling await next() so downstream
handlers can trust the authenticated identity.
- Around line 209-221: The upload handler at app.post("/api/upload") currently
trusts the parsed File and reads its arrayBuffer without checks; add security
guards by enforcing a MAX_FILE_SIZE constant and rejecting requests when
file.size exceeds it before calling file.arrayBuffer(), validate file.type
against an explicit whitelist of allowed MIME types and return a 400 when
mismatched, and sanitize file.name (remove/normalize path segments and
disallowed chars or generate a safe server-side filename) before using it;
ensure you perform these checks on the parsed "file" variable in the same
handler and return clear JSON error responses for size/type/name failures.
In @.agent/tools/api/vercel-ai-sdk.md:
- Around line 124-217: The assistant HTML is rendered with
dangerouslySetInnerHTML using marked.parse in AIChatSidebar (inside the
displayMessages.map), which allows XSS; fix by sanitizing the parsed HTML before
insertion (e.g., import DOMPurify and replace __html: marked.parse(part.text)
with __html: DOMPurify.sanitize(marked.parse(part.text))). Add DOMPurify (and
types) to deps and ensure only assistant message parts use the sanitized HTML
path in the mapping where dangerouslySetInnerHTML is used.
In @.agent/tools/ui/i18next.md:
- Line 8: Frontmatter currently sets the boolean key "bash: false" while the
document contains a shell validation script; update the frontmatter to "bash:
true" so the subagent can run the validation script programmatically (or
explicitly state in the frontmatter that the included script is for manual
execution) — locate and edit the "bash" frontmatter key in this file to enable
bash execution for the validation script.
🧹 Nitpick comments (6)
.agent/tools/ui/tailwind-css.md (1)
70-78: Validate numeric values before injecting into CSS.The pattern directly interpolates
${width}into inline styles. If this pattern is used with user-controlled input, ensure the value is validated as a number to prevent CSS injection.🔒 Safer pattern with validation
// Define in context/provider +const sanitizedWidth = typeof width === 'number' && width > 0 ? width : 384; -<style>{`:root { --sidebar-width: ${width}px; }`}</style> +<style>{`:root { --sidebar-width: ${sanitizedWidth}px; }`}</style> // Use in className <aside className="w-[var(--sidebar-width)]">.agent/tools/api/hono.md (1)
141-147: Consider production-safe error logging.The error handler logs errors with
console.error(err), which could expose stack traces in production logs. Consider using a structured logger with appropriate log levels and sanitization..agent/tools/ui/i18next.md (1)
248-256: Validation script lacks error handling and documentation.The script assumes
jqis installed and that locale directories exist in the current path. For DevOps automation excellence, add prerequisite checks and proper error handling.🔧 Hardened validation script
+#!/usr/bin/env bash +set -euo pipefail + +# Check prerequisites +command -v jq >/dev/null 2>&1 || { echo "Error: jq is required" >&2; exit 1; } + +# Configuration +BASE_LOCALE="en" +TARGET_LOCALES=("de" "es" "fr") +NAMESPACE="common" + # Check for missing keys across locales -for locale in de es fr; do +for locale in "${TARGET_LOCALES[@]}"; do + if [[ ! -f "$locale/$NAMESPACE.json" ]]; then + echo "Warning: $locale/$NAMESPACE.json not found, skipping" >&2 + continue + fi echo "=== Missing in $locale ===" - diff <(jq -r 'paths | join(".")' en/common.json | sort) \ - <(jq -r 'paths | join(".")' $locale/common.json | sort) \ + diff <(jq -r 'paths | join(".")' "$BASE_LOCALE/$NAMESPACE.json" | sort) \ + <(jq -r 'paths | join(".")' "$locale/$NAMESPACE.json" | sort) \ | grep "^<" | sed 's/^< //' || true done.agent/tools/api/better-auth.md (1)
134-148: Consider documenting password requirements.The email/password sign-up example doesn't mention password validation or strength requirements. For security best practices, document recommended password policies.
Example addition:
// Add password strength validation const passwordSchema = z.string() .min(8, "Password must be at least 8 characters") .regex(/[A-Z]/, "Password must contain uppercase letter") .regex(/[a-z]/, "Password must contain lowercase letter") .regex(/[0-9]/, "Password must contain number"); const handleSignUp = async (data: { email: string; password: string; name: string; }) => { // Validate password strength const validation = passwordSchema.safeParse(data.password); if (!validation.success) { console.error(validation.error); return; } // ... rest of sign-up };.agent/tools/ui/react-context.md (2)
82-91: Cookie persistence pattern works correctly.The
document.cookiepattern is appropriate for client-side UI state persistence. For production use with sensitive data, consider adding security attributes (Secure; SameSite=Lax) to the cookie string, though for sidebar state this is not critical.🔒 Optional: Add security attributes to cookies
For enhanced security posture (especially if pattern is copied for sensitive data):
-document.cookie = `${COOKIE_NAME}=${value}; path=/; max-age=${COOKIE_MAX_AGE}`; +document.cookie = `${COOKIE_NAME}=${value}; path=/; max-age=${COOKIE_MAX_AGE}; SameSite=Lax`;Note:
Secureattribute requires HTTPS and would be added in production environments.Also applies to: 170-181
93-104: Clever CSS variable injection pattern!The inline
<style>tag approach for injecting dynamic CSS variables is innovative and works well for most applications. For projects with strict Content Security Policy (CSP), you might need to use CSS-in-JS libraries or CSS modules as alternatives, but this is not a concern for typical setups.Also applies to: 189-196
| app.use("/api/admin/*", async (c, next) => { | ||
| const token = c.req.header("Authorization"); | ||
| if (!token) { | ||
| return c.json({ error: "Unauthorized" }, 401); | ||
| } | ||
| await next(); | ||
| }); |
There was a problem hiding this comment.
Authentication middleware example is incomplete.
The middleware checks for the presence of an Authorization header but doesn't validate the token. This could mislead developers into deploying insufficient authentication.
🔐 Enhanced example with validation note
// Route-specific middleware
app.use("/api/admin/*", async (c, next) => {
const token = c.req.header("Authorization");
if (!token) {
return c.json({ error: "Unauthorized" }, 401);
}
+ // TODO: Validate token (e.g., JWT verification, session lookup)
+ // const valid = await verifyToken(token);
+ // if (!valid) return c.json({ error: "Invalid token" }, 401);
await next();
});🤖 Prompt for AI Agents
In @.agent/tools/api/hono.md around lines 127 - 133, The middleware registered
via app.use("/api/admin/*", ...) only checks for existence of the Authorization
header (c.req.header("Authorization")) but never validates the token; update
this middleware to parse the header (e.g., check "Bearer " scheme),
validate/verify the token using your auth utility or JWT verifier, return 401 on
missing or invalid token, and attach the decoded user/claims to the context
(e.g., c.req.user or c.set("user", ...)) before calling await next() so
downstream handlers can trust the authenticated identity.
| app.post("/api/upload", async (c) => { | ||
| const body = await c.req.parseBody(); | ||
| const file = body["file"] as File; | ||
|
|
||
| if (!file) { | ||
| return c.json({ error: "No file" }, 400); | ||
| } | ||
|
|
||
| const buffer = await file.arrayBuffer(); | ||
| // Process file... | ||
|
|
||
| return c.json({ filename: file.name, size: file.size }); | ||
| }); |
There was a problem hiding this comment.
File upload example lacks essential security validations.
The pattern is missing critical file upload security measures: file size limits, MIME type validation, and filename sanitization.
🛡️ Secure file upload pattern
app.post("/api/upload", async (c) => {
const body = await c.req.parseBody();
const file = body["file"] as File;
if (!file) {
return c.json({ error: "No file" }, 400);
}
+
+ // Validate file size (e.g., 10MB limit)
+ const MAX_SIZE = 10 * 1024 * 1024;
+ if (file.size > MAX_SIZE) {
+ return c.json({ error: "File too large" }, 413);
+ }
+
+ // Validate MIME type
+ const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp"];
+ if (!ALLOWED_TYPES.includes(file.type)) {
+ return c.json({ error: "Invalid file type" }, 400);
+ }
const buffer = await file.arrayBuffer();
// Process file...
return c.json({ filename: file.name, size: file.size });
});📝 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.
| app.post("/api/upload", async (c) => { | |
| const body = await c.req.parseBody(); | |
| const file = body["file"] as File; | |
| if (!file) { | |
| return c.json({ error: "No file" }, 400); | |
| } | |
| const buffer = await file.arrayBuffer(); | |
| // Process file... | |
| return c.json({ filename: file.name, size: file.size }); | |
| }); | |
| app.post("/api/upload", async (c) => { | |
| const body = await c.req.parseBody(); | |
| const file = body["file"] as File; | |
| if (!file) { | |
| return c.json({ error: "No file" }, 400); | |
| } | |
| // Validate file size (e.g., 10MB limit) | |
| const MAX_SIZE = 10 * 1024 * 1024; | |
| if (file.size > MAX_SIZE) { | |
| return c.json({ error: "File too large" }, 413); | |
| } | |
| // Validate MIME type | |
| const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp"]; | |
| if (!ALLOWED_TYPES.includes(file.type)) { | |
| return c.json({ error: "Invalid file type" }, 400); | |
| } | |
| const buffer = await file.arrayBuffer(); | |
| // Process file... | |
| return c.json({ filename: file.name, size: file.size }); | |
| }); |
🤖 Prompt for AI Agents
In @.agent/tools/api/hono.md around lines 209 - 221, The upload handler at
app.post("/api/upload") currently trusts the parsed File and reads its
arrayBuffer without checks; add security guards by enforcing a MAX_FILE_SIZE
constant and rejecting requests when file.size exceeds it before calling
file.arrayBuffer(), validate file.type against an explicit whitelist of allowed
MIME types and return a 400 when mismatched, and sanitize file.name
(remove/normalize path segments and disallowed chars or generate a safe
server-side filename) before using it; ensure you perform these checks on the
parsed "file" variable in the same handler and return clear JSON error responses
for size/type/name failures.
- Add XSS warning for dangerouslySetInnerHTML with marked.parse - Add DOMPurify sanitization recommendation - Fix Next.js 15 params typing (params is now a Promise) - Add version compatibility note for Next.js 14 vs 15 - Fix validation script to specify working directory - Use message.parts instead of deprecated message.content
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Thu Jan 22 06:43:40 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.agent/tools/ui/i18next.md:
- Around line 36-61: Update the documentation example to reflect the actual
repository structure or add the missing package: either change the referenced
path "packages/i18n/src/translations/" and the "Adding New Translation Key"
grep/file examples to the real locale folder locations used by this repo (and
remove any reference to "@workspace/i18n" import alias), or create a new i18n
workspace package with the exact directory layout and configure the
workspace/import alias so the shown grep and file paths work; ensure the "Adding
New Translation Key" section points to valid paths and commands that run in this
repository.
🧹 Nitpick comments (2)
.agent/tools/ui/i18next.md (2)
257-270: Enhance validation script to cover all namespaces.The validation script currently only checks
common.json, but the file structure (lines 38-42) documents multiple namespaces (marketing.json,dashboard.json). Consider extending the script to validate all namespace files or adding a note that it's a common.json-specific example.♻️ Enhanced validation covering all namespaces
# Check for missing keys across locales # Run from packages/i18n/src/translations/ directory cd packages/i18n/src/translations +# Check if required tools are available +command -v jq >/dev/null 2>&1 || { echo "Error: jq is required but not installed"; exit 1; } + +# Find all JSON files in en/ to use as baseline +for namespace in en/*.json; do + namespace_file=$(basename "$namespace") + echo "=== Checking namespace: $namespace_file ===" + -for locale in de es fr; do - echo "=== Missing in $locale ===" - diff <(jq -r 'paths | join(".")' en/common.json | sort) \ - <(jq -r 'paths | join(".")' $locale/common.json | sort) \ - | grep "^<" | sed 's/^< //' -done + for locale in de es fr; do + if [ -f "$locale/$namespace_file" ]; then + echo " Missing in $locale/$namespace_file:" + diff <(jq -r 'paths | join(".")' "en/$namespace_file" | sort) \ + <(jq -r 'paths | join(".")' "$locale/$namespace_file" | sort) \ + | grep "^<" | sed 's/^< / /' + else + echo " ✗ $locale/$namespace_file does not exist" + fi + done + echo "" +done
24-24: Consider adding a Context7 usage example.While the documentation mentions using Context7 MCP for current documentation, providing a concrete example of the command would improve developer experience. For instance, showing how to fetch the latest i18next API docs or specific feature documentation.
Example addition:
**Docs**: Use Context7 MCP for current documentation ```bash # Example: Fetch latest i18next useTranslation hook documentation context7_read "i18next useTranslation hook API"</blockquote></details> </blockquote></details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
|
|
||
| ```text | ||
| packages/i18n/src/translations/ | ||
| ├── en/ | ||
| │ ├── common.json # Shared UI strings | ||
| │ ├── marketing.json # Marketing pages | ||
| │ └── dashboard.json # Dashboard-specific | ||
| ├── de/ | ||
| │ └── common.json | ||
| ├── es/ | ||
| │ └── common.json | ||
| └── fr/ | ||
| └── common.json | ||
| ``` | ||
|
|
||
| **Adding New Translation Key**: | ||
|
|
||
| ```bash | ||
| # 1. Add to English first | ||
| # packages/i18n/src/translations/en/common.json | ||
|
|
||
| # 2. Find same location in other locales | ||
| grep -n '"feedback":' packages/i18n/src/translations/*/common.json | ||
|
|
||
| # 3. Add to ALL locales at same position | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify the i18n package structure and import aliases match documentation
echo "=== Checking i18n package structure ==="
if [ -d "packages/i18n/src/translations" ]; then
echo "✓ packages/i18n/src/translations/ exists"
fd -t f -e json . packages/i18n/src/translations 2>/dev/null | head -10
else
echo "✗ packages/i18n/src/translations/ not found"
echo "Searching for alternative i18n locations..."
fd -t d -g '*i18n*' packages 2>/dev/null || echo "No i18n directories found in packages/"
find . -maxdepth 3 -type d -name "*i18n*" 2>/dev/null | grep -v node_modules
fi
echo -e "\n=== Checking workspace import alias ==="
if [ -f "package.json" ]; then
echo "Checking root package.json for workspace configuration..."
cat package.json | jq '.workspaces // .name' 2>/dev/null | head -20
fi
if [ -f "packages/i18n/package.json" ]; then
echo "✓ packages/i18n/package.json found"
cat packages/i18n/package.json | jq '.name' 2>/dev/null
else
echo "✗ packages/i18n/package.json not found"
find packages -maxdepth 2 -name "package.json" -type f 2>/dev/null | head -10
fi
echo -e "\n=== Checking for i18n imports in codebase ==="
rg '@workspace/i18n|@i18n|from.*i18n' --type=tsx --type=ts --type=jsx --type=js -g '!node_modules' -c 2>/dev/null | head -10 || echo "No matches found"
echo -e "\n=== Checking file structure ==="
ls -la packages/i18n/src/translations/ 2>/dev/null || echo "Directory not found"Repository: marcusquinn/aidevops
Length of output: 479
Documentation examples reference non-existent i18n package structure and import aliases that will fail.
The file structure example (lines 36-49) references packages/i18n/src/translations/ and the bash commands reference @workspace/i18n imports, but verification shows:
packages/i18n/directory does not exist in the repository- No i18n package is configured in the workspace
- The grep command and file paths in the "Adding New Translation Key" section (lines 51-61) will not work
Either update the documentation to match the actual project structure, or ensure the i18n package and directory structure described are created before this documentation is merged.
🤖 Prompt for AI Agents
In @.agent/tools/ui/i18next.md around lines 36 - 61, Update the documentation
example to reflect the actual repository structure or add the missing package:
either change the referenced path "packages/i18n/src/translations/" and the
"Adding New Translation Key" grep/file examples to the real locale folder
locations used by this repo (and remove any reference to "@workspace/i18n"
import alias), or create a new i18n workspace package with the exact directory
layout and configure the workspace/import alias so the shown grep and file paths
work; ensure the "Adding New Translation Key" section points to valid paths and
commands that run in this repository.
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Fri Jan 23 00:29:26 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Fri Jan 23 00:45:57 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|



Summary
Add subagents documenting best practices and common hazards for modern web development technologies. These agents capture learnings from real development sessions to help avoid common pitfalls.
Changes
UI/Frontend (
tools/ui/)API/Backend (
tools/api/)Monorepo (
tools/monorepo/)Design
Each subagent follows aidevops patterns:
Testing
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.