POC: Cookbook style listing in the docs#397
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughRegisters a Cookbooks blog plugin, updates Astro/Starlight configuration and dependencies, adds many new documentation pages and governance/templates/scripts for speckit/specify workflows, extends the content schema to include blogSchema, updates sidebar navigation to exclude /cookbooks, modifies HubSpot loader behavior, adds environment samples, and expands the public OpenAPI JSON with connected_accounts and permission/schema changes. Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@astro.config.mjs`:
- Around line 94-99: Remove the invalid metrics option from the starlightBlog()
call: open the configuration where starlightBlog(...) is invoked and delete the
entire metrics: { readingTime: true, words: 'total' } object so the plugin
options only use supported keys (prefix, title, postCount, recentPostCount,
authors, navigation, frontmatter); ensure no other code relies on that removed
option since reading time and word count are provided automatically via post
metadata/frontmatter.
In `@src/configs/sidebar.config.ts`:
- Around line 511-515: The exclude array (export const exclude) currently lists
'/blog' which may not match nested blog pages; update the pattern in the exclude
array to use a recursive glob (e.g., replace '/blog' with '/blog/**') so the
entire blog subtree is excluded by the glob matcher, and keep the existing
'/apis/**/*' style consistent with other entries.
In `@src/content/docs/blog/building-custom-org-switcher.mdx`:
- Around line 107-116: The "Add domain context" block currently contains only a
JavaScript example; replace it with a Tabs block containing Node.js, Python, Go,
and Java examples that each call the Domains API to list domains for an
organization and show how to display a domain (e.g., "@acme.com") next to the
org name. Specifically, update the block that references scalekit.domains.list
and organizationId: 'org_123' so it includes a Node.js/JavaScript snippet (same
call pattern), a Python snippet calling scalekit.domains.list or equivalent
client method with organization_id='org_123', a Go snippet using the
Domains.List method with OrganizationID: "org_123", and a Java snippet using the
domains().list(...) call with organizationId "org_123"; keep the examples
minimal and consistent (fetch domains, iterate or access first domain, and show
"@acme.com" display note).
- Around line 47-103: Add the required syncKey attribute to the Tabs components
so language selection remains consistent: locate the Tabs elements (the
top-level Tabs component wrapping the TabItem blocks in this file) and add
syncKey="tech-stack" to each Tabs instance (the TabItem components remain
unchanged); ensure both Tabs blocks on the page use the identical syncKey value
"tech-stack" so multi-language examples stay synchronized across pages.
- Around line 1-16: Update the MDX frontmatter: change the Title field to
sentence case (update 'title'), confirm and update the publish `date` to the
intended current date if needed, and add the required navigation metadata by
adding `sidebar_label` (a short label) and `sidebar_position` or `order` to
place it in the docs navigation; also add `tableOfContents: true` to enable TOC
for multi-section pages and ensure the existing `authors`, `tags`, `excerpt`,
`featured`, and `cover` fields remain intact (look for the frontmatter block
beginning with `---` and the keys `title`, `date`, `authors` to locate where to
add these fields).
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
assets/blog/covers/custom-org-switcher.jpgis excluded by!**/*.jpgpnpm-lock.yamlis excluded by!**/pnpm-lock.yamlpublic/images/blog/authors/hashirr-lukmahn.jpgis excluded by!**/*.jpg
📒 Files selected for processing (5)
astro.config.mjspackage.jsonsrc/configs/sidebar.config.tssrc/content.config.tssrc/content/docs/blog/building-custom-org-switcher.mdx
🧰 Additional context used
📓 Path-based instructions (8)
astro.config.mjs
📄 CodeRabbit inference engine (.cursorrules)
astro.config.mjs: Expressive Code is configured inastro.config.mjswith themes 'tokyo-night' (dark) and 'light-plus' (light), JetBrains Mono font, and border radius 0.375rem
Expressive Code collapsible sections plugin must be enabled inastro.config.mjs
Files:
astro.config.mjs
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy,gradle,xml,json}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Comments should not duplicate the code - avoid comments that simply restate what the code does; comments should add value beyond what's obvious from reading the code
Files:
package.jsonsrc/configs/sidebar.config.tssrc/content.config.ts
**/*.{js,ts,py,go,java,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
SDK variable names must follow language-specific conventions: Node.js uses
scalekit, Python usesscalekit_client, Go usesscalekitClient, Java usesscalekitClient
Files:
src/configs/sidebar.config.tssrc/content.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}: Good comments do not excuse unclear code - refactor the code to be self-explanatory instead of using comments to explain poorly written code; use better variable names, function names, and code structure
Comments should dispel confusion, not cause it - ensure comments clarify rather than obscure the code's purpose; avoid cryptic or joke comments
Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Provide links to the original source of copied code - always attribute code copied from external sources with URLs to Stack Overflow answers, GitHub repositories, or documentation
Include links to external references where helpful - reference standards, RFCs, and official documentation; link to relevant specifications when implementing protocols
Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Include file headers with copyright information, license, and authorship - provide a brief description of the file's purpose and document dependencies and requirements
Files:
src/configs/sidebar.config.tssrc/content.config.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Use JSDoc standards for all function, class, and complex logic comments in JavaScript/TypeScript - include parameter descriptions (
@param), return values (@returns), types (@type), and descriptions; document exceptions and edge cases
Files:
src/configs/sidebar.config.tssrc/content.config.ts
**/*.mdx
📄 CodeRabbit inference engine (.cursorrules)
**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component:1. ## Titlewith all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...
Files:
src/content/docs/blog/building-custom-org-switcher.mdx
**/*.{md,mdx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{md,mdx}: All code examples must include implementations in all 4 languages: Node.js, Python, Go, and Java
Include security comments in code examples explaining security threats and implications
Code examples must demonstrate both success and error paths
Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array
Use second person ('you', 'your application') for writing voice in documentation
Use present tense for descriptions and imperative mood for instructions in documentation
**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and...
Files:
src/content/docs/blog/building-custom-org-switcher.mdx
**/*.{yml,yaml,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)
**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Files:
src/content/docs/blog/building-custom-org-switcher.mdx
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to astro.config.mjs : Expressive Code collapsible sections plugin must be enabled in `astro.config.mjs`
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to astro.config.mjs : Expressive Code is configured in `astro.config.mjs` with themes 'tokyo-night' (dark) and 'light-plus' (light), JetBrains Mono font, and border radius 0.375rem
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to astro.config.mjs : Expressive Code collapsible sections plugin must be enabled in `astro.config.mjs`
Applied to files:
astro.config.mjs
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to astro.config.mjs : Expressive Code is configured in `astro.config.mjs` with themes 'tokyo-night' (dark) and 'light-plus' (light), JetBrains Mono font, and border radius 0.375rem
Applied to files:
astro.config.mjs
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Import `{ Code }` from `astrojs/starlight/components` once per `.mdx` file, placing the import below frontmatter
Applied to files:
astro.config.mjs
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Set concise sidebar labels that match user vocabulary in navigation metadata
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Set appropriate sidebar labels for navigation in frontmatter
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Keep documentation synchronized with product changes
Applied to files:
src/content/docs/blog/building-custom-org-switcher.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use `<Tabs syncKey="tech-stack">` to synchronize multi-language code selection across documentation pages
Applied to files:
src/content/docs/blog/building-custom-org-switcher.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.mdx : Use Tabs/TabItem components for multi-language or multi-framework examples in MDX documentation
Applied to files:
src/content/docs/blog/building-custom-org-switcher.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Structure documentation content with clear headings for better search understanding
Applied to files:
src/content/docs/blog/building-custom-org-switcher.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Update code examples when APIs or behaviors change
Applied to files:
src/content/docs/blog/building-custom-org-switcher.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Applied to files:
src/content/docs/blog/building-custom-org-switcher.mdx
🔇 Additional comments (2)
package.json (1)
51-51: No issues found. The dependencystarlight-blogat version^0.25.2is the current release on npm and is designed as a Starlight plugin for Astro. Compatibility is appropriate for standard Astro/Starlight setups.src/content.config.ts (1)
12-42: No validation concern: blogSchema fields are optional by design.
blogSchema(context)returns a.partial()schema from starlight-blog, making all blog-specific fields (date, authors, excerpt, cover, tags, featured) optional by default. Regular docs will validate correctly without providing blog metadata.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| export const exclude = [ | ||
| '/', // Home page | ||
| '/blog', | ||
| '/404', // Error page | ||
| '/apis/**/*', // REST API reference has Scalar-powered navigation |
There was a problem hiding this comment.
Exclude the entire blog subtree, not just /blog.
/blog alone may not match /blog/... pages in glob-based matching. Consider using /blog/** to ensure all blog posts are excluded from topic navigation.
🔧 Suggested fix
export const exclude = [
'/', // Home page
- '/blog',
+ '/blog/**',
'/404', // Error page
'/apis/**/*', // REST API reference has Scalar-powered navigation
]📝 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.
| export const exclude = [ | |
| '/', // Home page | |
| '/blog', | |
| '/404', // Error page | |
| '/apis/**/*', // REST API reference has Scalar-powered navigation | |
| export const exclude = [ | |
| '/', // Home page | |
| '/blog/**', | |
| '/404', // Error page | |
| '/apis/**/*', // REST API reference has Scalar-powered navigation | |
| ] |
🤖 Prompt for AI Agents
In `@src/configs/sidebar.config.ts` around lines 511 - 515, The exclude array
(export const exclude) currently lists '/blog' which may not match nested blog
pages; update the pattern in the exclude array to use a recursive glob (e.g.,
replace '/blog' with '/blog/**') so the entire blog subtree is excluded by the
glob matcher, and keep the existing '/apis/**/*' style consistent with other
entries.
There was a problem hiding this comment.
@HashirrLukmahn - this could be or should be /cookbooks I suppose
There was a problem hiding this comment.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
| <Tabs> | ||
| <TabItem value="node" label="Node.js"> | ||
| ```javascript title="Express.js" | ||
| // Use case: Get user's organizations for your switcher UI | ||
| // Security: Always validate session ownership before returning org data | ||
| const session = await scalekit.session.getSession(sessionId); | ||
|
|
||
| // Extract organizations from the session response | ||
| const organizations = session.authenticated_organizations || []; | ||
|
|
||
| // Render your organization switcher with this data | ||
| res.json({ organizations }); | ||
| ``` | ||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
| ```python title="Flask" | ||
| # Use case: Get user's organizations for your switcher UI | ||
| # Security: Always validate session ownership before returning org data | ||
| session = scalekit_client.session.get_session(session_id) | ||
|
|
||
| # Extract organizations from the session response | ||
| organizations = session.get('authenticated_organizations', []) | ||
|
|
||
| # Render your organization switcher with this data | ||
| return jsonify({'organizations': organizations}) | ||
| ``` | ||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
| ```go title="Gin" | ||
| // Use case: Get user's organizations for your switcher UI | ||
| // Security: Always validate session ownership before returning org data | ||
| session, err := scalekitClient.Session().GetSession(ctx, sessionId) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Extract organizations from the session response | ||
| organizations := session.AuthenticatedOrganizations | ||
|
|
||
| // Render your organization switcher with this data | ||
| c.JSON(http.StatusOK, gin.H{"organizations": organizations}) | ||
| ``` | ||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
| ```java title="Spring" | ||
| // Use case: Get user's organizations for your switcher UI | ||
| // Security: Always validate session ownership before returning org data | ||
| Session session = scalekitClient.sessions().getSession(sessionId); | ||
|
|
||
| // Extract organizations from the session response | ||
| List<Organization> organizations = session.getAuthenticatedOrganizations(); | ||
|
|
||
| // Render your organization switcher with this data | ||
| return ResponseEntity.ok(Map.of("organizations", organizations)); | ||
| ``` | ||
| </TabItem> | ||
| </Tabs> |
There was a problem hiding this comment.
Use <Tabs syncKey="tech-stack"> for multi-language examples.
Both Tabs blocks should include syncKey="tech-stack" so language selection stays consistent across pages. This is required for MDX multi-language examples. Based on learnings, ...
🔧 Suggested update
-<Tabs>
+<Tabs syncKey="tech-stack">Also applies to: 124-243
🤖 Prompt for AI Agents
In `@src/content/docs/blog/building-custom-org-switcher.mdx` around lines 47 -
103, Add the required syncKey attribute to the Tabs components so language
selection remains consistent: locate the Tabs elements (the top-level Tabs
component wrapping the TabItem blocks in this file) and add syncKey="tech-stack"
to each Tabs instance (the TabItem components remain unchanged); ensure both
Tabs blocks on the page use the identical syncKey value "tech-stack" so
multi-language examples stay synchronized across pages.
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (1)
src/configs/sidebar.config.ts (1)
522-527:⚠️ Potential issue | 🟡 Minor
/cookbookswon't match sub-pages — same glob issue as the prior/blogcomment.The entry
/cookbookswill only exclude the exact path/cookbooks; any article page like/cookbooks/building-custom-org-switcherwill still be picked up by the topic sidebar. The fix is the same as suggested for/blog:🔧 Proposed fix
export const exclude = [ '/', // Home page - '/cookbooks', + '/cookbooks/**', '/404', // Error page '/apis/**/*', // REST API reference has Scalar-powered navigation ]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/configs/sidebar.config.ts` around lines 522 - 527, The exclude array entry for cookbooks currently only matches the exact path '/cookbooks' so nested pages (e.g., '/cookbooks/building-custom-org-switcher') still appear; update the exclude entry in the exclude constant (in src/configs/sidebar.config.ts) to use a glob that matches subpaths (for example change '/cookbooks' to a recursive glob like '/cookbooks/**/*') so all cookbook sub-pages are excluded from the topic sidebar.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/content/docs/cookbooks/implement-nextjs-auth.mdx`:
- Line 2: Update the title frontmatter string "Implementing Passwordless Auth in
Next.js 15" to sentence case by lowercasing non-proper nouns—e.g., change it to
"Implementing passwordless auth in Next.js 15" (or "Implementing passwordless
authentication in Next.js 15" if you prefer the full word) so the title follows
the sentence-case guideline; modify the title value where it's defined in the
document header.
- Around line 280-295: The middleware currently only checks for the presence of
a 'session' cookie in middleware(req) which allows expired or tampered JWTs;
update middleware to validate the JWT before allowing access by calling the
existing readSessionEmail utility (or invoking jwt.verify) with the cookie value
and rejecting if verification fails or token is expired; keep the same redirect
behavior (create URL('/login', req.url) and set next param) when verification
fails, and return NextResponse.next() only when readSessionEmail/jwt.verify
confirms a valid session; reference middleware, readSessionEmail, jwt.verify,
NextRequest, and NextResponse in your changes.
- Around line 88-121: The three session helper functions (createSession,
readSessionEmail, clearSession) must be converted to async functions and call
await cookies() (since cookies() returns a Promise in Next.js 15); update
createSession to await cookies() before .set, update readSessionEmail to await
cookies() before .get and keep the jwt.verify try/catch, and update clearSession
to await cookies() before .delete. Also update any route handlers or callers to
await createSession and clearSession (and await readSessionEmail where used) so
callers handle the async nature.
In `@src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdx`:
- Line 52: The sentence uses "timeout" as a verb; update the phrase "If these
initial requests timeout, authentication fails completely." to use the phrasal
verb "time out" by replacing "timeout" with "time out" so it reads "If these
initial requests time out, authentication fails completely."; locate this text
in the Java Spring Boot JWT timeout cookbook (the line containing that sentence)
and make the single-word replacement.
- Line 2: The document title uses Title Case; change it to sentence case so
non-proper nouns are lowercase—update the title string "Configuring JWT
Validation Timeouts in Spring Boot 4.0+" to "Configuring JWT validation timeouts
in Spring Boot 4.0+" (modify the frontmatter/title line that currently contains
the title).
- Around line 73-97: Remove the misleading YAML/properties timeout entries under
spring.security.oauth2.resourceserver.jwt (the application.yml and
application.properties TabItems) and add a clear caveat noting these properties
are ignored in Spring Boot 4 / Spring Security 7; instead, reference and
recommend the programmatic approach shown in the doc (the NimbusJwtDecoder +
custom RestOperations example around the existing "NimbusJwtDecoder" /
"RestOperations" code in lines ~112–138) and instruct readers to configure
timeouts via a custom RestTemplate/HttpClient or WebClient passed into
NimbusJwtDecoder rather than via declarative properties.
---
Duplicate comments:
In `@src/configs/sidebar.config.ts`:
- Around line 522-527: The exclude array entry for cookbooks currently only
matches the exact path '/cookbooks' so nested pages (e.g.,
'/cookbooks/building-custom-org-switcher') still appear; update the exclude
entry in the exclude constant (in src/configs/sidebar.config.ts) to use a glob
that matches subpaths (for example change '/cookbooks' to a recursive glob like
'/cookbooks/**/*') so all cookbook sub-pages are excluded from the topic
sidebar.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/configs/sidebar.config.tssrc/content/docs/cookbooks/building-custom-org-switcher.mdxsrc/content/docs/cookbooks/implement-nextjs-auth.mdxsrc/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/content/docs/cookbooks/building-custom-org-switcher.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.mdx
📄 CodeRabbit inference engine (.cursorrules)
**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component:1. ## Titlewith all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...
Files:
src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdxsrc/content/docs/cookbooks/implement-nextjs-auth.mdx
**/*.{yml,yaml,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)
**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Files:
src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdxsrc/content/docs/cookbooks/implement-nextjs-auth.mdx
**/*.{md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/deno-docs-style.mdc)
**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and purposeful - annotate only what matters
Use consistent variable and file names across a documentation page
Use descriptive link text in documentation (e.g., 'See permission flags' not 'click here')
Prefer relative links for internal documentation pages and include anchors for section references
Reference APIs consistently using backticks for code, file names, CLI flags, and endpoints
Use backticks for code, file names, CLI flags, and endpoints in documentation
Use lists for options and features in documentation; tables only when comparisons are cleare...
Files:
src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdxsrc/content/docs/cookbooks/implement-nextjs-auth.mdx
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy,gradle,xml,json}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Comments should not duplicate the code - avoid comments that simply restate what the code does; comments should add value beyond what's obvious from reading the code
Files:
src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}: Good comments do not excuse unclear code - refactor the code to be self-explanatory instead of using comments to explain poorly written code; use better variable names, function names, and code structure
Comments should dispel confusion, not cause it - ensure comments clarify rather than obscure the code's purpose; avoid cryptic or joke comments
Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Provide links to the original source of copied code - always attribute code copied from external sources with URLs to Stack Overflow answers, GitHub repositories, or documentation
Include links to external references where helpful - reference standards, RFCs, and official documentation; link to relevant specifications when implementing protocols
Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Include file headers with copyright information, license, and authorship - provide a brief description of the file's purpose and document dependencies and requirements
Files:
src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Use JSDoc standards for all function, class, and complex logic comments in JavaScript/TypeScript - include parameter descriptions (
@param), return values (@returns), types (@type), and descriptions; document exceptions and edge cases
Files:
src/configs/sidebar.config.ts
🧠 Learnings (17)
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.
Applied to files:
src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdxsrc/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.
Applied to files:
src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdxsrc/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Applied to files:
src/content/docs/cookbooks/implement-nextjs-auth.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Avoid trailing punctuation in navigation labels and avoid emojis and exclamation marks
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Set concise sidebar labels that match user vocabulary in navigation metadata
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Don't skip important context or prerequisites in documentation
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.mdx : Use consistent import paths with the `@/` prefix in MDX files
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Applied to files:
src/configs/sidebar.config.ts
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Don't use inconsistent terminology across documentation pages
Applied to files:
src/configs/sidebar.config.ts
🪛 LanguageTool
src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdx
[grammar] ~52-~52: Ensure spelling is correct
Context: ... validations If these initial requests timeout, authentication fails completely. ## W...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
| @@ -0,0 +1,431 @@ | |||
| --- | |||
| title: 'Implementing Passwordless Auth in Next.js 15' | |||
There was a problem hiding this comment.
Title violates sentence-case guideline.
"Passwordless" and "Auth" are not proper nouns and should be lowercase.
🔧 Proposed fix
-title: 'Implementing Passwordless Auth in Next.js 15'
+title: 'Implementing passwordless auth in Next.js 15'📝 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.
| title: 'Implementing Passwordless Auth in Next.js 15' | |
| title: 'Implementing passwordless auth in Next.js 15' |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/cookbooks/implement-nextjs-auth.mdx` at line 2, Update the
title frontmatter string "Implementing Passwordless Auth in Next.js 15" to
sentence case by lowercasing non-proper nouns—e.g., change it to "Implementing
passwordless auth in Next.js 15" (or "Implementing passwordless authentication
in Next.js 15" if you prefer the full word) so the title follows the
sentence-case guideline; modify the title value where it's defined in the
document header.
| ```typescript | ||
| import jwt from 'jsonwebtoken'; | ||
| import { cookies } from 'next/headers'; | ||
|
|
||
| const COOKIE = 'session'; | ||
| const SECRET = process.env.JWT_SECRET!; | ||
|
|
||
| export function createSession(email: string) { | ||
| const token = jwt.sign({ email }, SECRET, { expiresIn: '7d' }); | ||
| cookies().set(COOKIE, token, { | ||
| httpOnly: true, | ||
| secure: process.env.NODE_ENV === 'production', | ||
| sameSite: 'lax', | ||
| path: '/', | ||
| maxAge: 60 * 60 * 24 * 7, | ||
| }); | ||
| } | ||
|
|
||
| export function readSessionEmail(): string | null { | ||
| const token = cookies().get(COOKIE)?.value; | ||
| if (!token) return null; | ||
|
|
||
| try { | ||
| const decoded = jwt.verify(token, SECRET) as { email: string }; | ||
| return decoded.email; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| export function clearSession() { | ||
| cookies().delete(COOKIE); | ||
| } | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Next.js 15 cookies() async API breaking changes
💡 Result:
Next.js 15 cookies() async API — breaking changes
-
cookies()is now async and returns aPromise(it used to be synchronous in Next.js ≤14). You mustawait cookies()(or use React’suse()in Server Components). [1][3][2]// Before (<=14) const cookieStore = cookies() const token = cookieStore.get('token') // After (15) const cookieStore = await cookies() const token = cookieStore.get('token')
-
Transitional compatibility exists in Next.js 15, but it’s temporary: you can still access cookies synchronously by casting to
UnsafeUnwrappedCookies, but it warns in dev and is meant only to ease migration. [1][3]import { cookies, type UnsafeUnwrappedCookies } from 'next/headers' const cookieStore = cookies() as unknown as UnsafeUnwrappedCookies // warns in dev
-
Synchronous access can become an error in some modes: Next.js 15 may throw when request APIs are used synchronously (notably when
cacheComponentsis enabled), even though the promise-proxy exists for migration. [4] -
Migration support: the upgrade codemod can auto-convert many call sites (and leaves
@next-codemod-errormarkers where it can’t). [1][4] -
Heads-up: Next.js 16 fully removes synchronous compatibility—
cookies()(and similar request APIs) are async-only. [5]
Sources: Next.js v15 upgrade guide [1], Next.js 15 announcement [2], cookies() API docs [3], Next.js error reference [4], Next.js v16 upgrade guide [5].
🏁 Script executed:
cat -n src/content/docs/cookbooks/implement-nextjs-auth.mdx | sed -n '85,125p'Repository: scalekit-inc/developer-docs
Length of output: 1296
cookies() is async in Next.js 15—update all three session utilities to use await.
cookies() returns a Promise in Next.js 15 (it was synchronous in v14 and earlier). The current code will warn in development and fail in production, especially when cacheComponents is enabled. Since this cookbook targets Next.js 15, update createSession, readSessionEmail, and clearSession to be async functions with await cookies(). Call sites in route handlers must also await these functions.
Proposed fix for `lib/session-store.ts`
-export function createSession(email: string) {
- const token = jwt.sign({ email }, SECRET, { expiresIn: '7d' });
- cookies().set(COOKIE, token, {
+export async function createSession(email: string) {
+ const token = jwt.sign({ email }, SECRET, { expiresIn: '7d' });
+ const cookieStore = await cookies();
+ cookieStore.set(COOKIE, token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
path: '/',
maxAge: 60 * 60 * 24 * 7,
});
}
-export function readSessionEmail(): string | null {
- const token = cookies().get(COOKIE)?.value;
+export async function readSessionEmail(): Promise<string | null> {
+ const cookieStore = await cookies();
+ const token = cookieStore.get(COOKIE)?.value;
if (!token) return null;
try {
const decoded = jwt.verify(token, SECRET) as { email: string };
return decoded.email;
} catch {
return null;
}
}
-export function clearSession() {
- cookies().delete(COOKIE);
+export async function clearSession() {
+ const cookieStore = await cookies();
+ cookieStore.delete(COOKIE);
}Update the route handlers that call createSession and clearSession to await them.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/cookbooks/implement-nextjs-auth.mdx` around lines 88 - 121,
The three session helper functions (createSession, readSessionEmail,
clearSession) must be converted to async functions and call await cookies()
(since cookies() returns a Promise in Next.js 15); update createSession to await
cookies() before .set, update readSessionEmail to await cookies() before .get
and keep the jwt.verify try/catch, and update clearSession to await cookies()
before .delete. Also update any route handlers or callers to await createSession
and clearSession (and await readSessionEmail where used) so callers handle the
async nature.
| export function middleware(req: NextRequest) { | ||
| const protectedPath = req.nextUrl.pathname.startsWith('/dashboard'); | ||
| const hasSession = Boolean(req.cookies.get('session')?.value); | ||
|
|
||
| if (protectedPath && !hasSession) { | ||
| const url = new URL('/login', req.url); | ||
| url.searchParams.set('next', req.nextUrl.pathname); | ||
| return NextResponse.redirect(url); | ||
| } | ||
|
|
||
| return NextResponse.next(); | ||
| } | ||
|
|
||
| export const config = { | ||
| matcher: ['/dashboard/:path*'], | ||
| }; |
There was a problem hiding this comment.
Middleware validates cookie presence only — not JWT signature or expiry.
The check Boolean(req.cookies.get('session')?.value) passes for any non-empty cookie value, including expired or maliciously crafted tokens. A user whose session JWT has expired can still access protected routes indefinitely.
The middleware should verify the JWT before granting access. The simplest approach is to reuse the readSessionEmail utility (which calls jwt.verify), or inline the decode inline:
🔧 Proposed fix
-import { NextRequest, NextResponse } from 'next/server';
+import { NextRequest, NextResponse } from 'next/server';
+import jwt from 'jsonwebtoken';
export function middleware(req: NextRequest) {
const protectedPath = req.nextUrl.pathname.startsWith('/dashboard');
- const hasSession = Boolean(req.cookies.get('session')?.value);
+ const token = req.cookies.get('session')?.value;
+ let hasValidSession = false;
+ if (token) {
+ try {
+ jwt.verify(token, process.env.JWT_SECRET!);
+ hasValidSession = true;
+ } catch {
+ hasValidSession = false;
+ }
+ }
- if (protectedPath && !hasSession) {
+ if (protectedPath && !hasValidSession) {
const url = new URL('/login', req.url);
url.searchParams.set('next', req.nextUrl.pathname);
return NextResponse.redirect(url);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/cookbooks/implement-nextjs-auth.mdx` around lines 280 - 295,
The middleware currently only checks for the presence of a 'session' cookie in
middleware(req) which allows expired or tampered JWTs; update middleware to
validate the JWT before allowing access by calling the existing readSessionEmail
utility (or invoking jwt.verify) with the cookie value and rejecting if
verification fails or token is expired; keep the same redirect behavior (create
URL('/login', req.url) and set next param) when verification fails, and return
NextResponse.next() only when readSessionEmail/jwt.verify confirms a valid
session; reference middleware, readSessionEmail, jwt.verify, NextRequest, and
NextResponse in your changes.
| @@ -0,0 +1,175 @@ | |||
| --- | |||
| title: 'Configuring JWT Validation Timeouts in Spring Boot 4.0+' | |||
There was a problem hiding this comment.
Title violates sentence-case guideline.
"Validation" and "Timeouts" are not proper nouns and should be lowercase.
🔧 Proposed fix
-title: 'Configuring JWT Validation Timeouts in Spring Boot 4.0+'
+title: 'Configuring JWT validation timeouts in Spring Boot 4.0+'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdx` at line 2, The
document title uses Title Case; change it to sentence case so non-proper nouns
are lowercase—update the title string "Configuring JWT Validation Timeouts in
Spring Boot 4.0+" to "Configuring JWT validation timeouts in Spring Boot 4.0+"
(modify the frontmatter/title line that currently contains the title).
| 2. Retrieves the JWKS (JSON Web Key Set) to verify token signatures | ||
| 3. Caches these for future validations | ||
|
|
||
| If these initial requests timeout, authentication fails completely. |
There was a problem hiding this comment.
Grammar: "timeout" here is a verb — should be written "time out".
The static analysis tool's flag is valid. "Timeout" (noun/adjective) vs. "time out" (phrasal verb).
🔧 Proposed fix
-If these initial requests timeout, authentication fails completely.
+If these initial requests time out, authentication fails completely.📝 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.
| If these initial requests timeout, authentication fails completely. | |
| If these initial requests time out, authentication fails completely. |
🧰 Tools
🪛 LanguageTool
[grammar] ~52-~52: Ensure spelling is correct
Context: ... validations If these initial requests timeout, authentication fails completely. ## W...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdx` at line 52, The
sentence uses "timeout" as a verb; update the phrase "If these initial requests
timeout, authentication fails completely." to use the phrasal verb "time out" by
replacing "timeout" with "time out" so it reads "If these initial requests time
out, authentication fails completely."; locate this text in the Java Spring Boot
JWT timeout cookbook (the line containing that sentence) and make the
single-word replacement.
| <Tabs> | ||
| <TabItem value="yaml" label="application.yml"> | ||
| ```yaml | ||
| spring: | ||
| security: | ||
| oauth2: | ||
| resourceserver: | ||
| jwt: | ||
| issuer-uri: https://auth.scalekit.com | ||
| # Configure timeouts for JWKS and discovery endpoints | ||
| client: | ||
| registration: | ||
| connect-timeout: 10000 # 10 seconds for connection | ||
| read-timeout: 10000 # 10 seconds for reading response | ||
| ``` | ||
| </TabItem> | ||
| <TabItem value="properties" label="application.properties"> | ||
| ```properties | ||
| spring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.scalekit.com | ||
| # Configure timeouts for JWKS and discovery endpoints | ||
| spring.security.oauth2.resourceserver.jwt.client.registration.connect-timeout=10000 | ||
| spring.security.oauth2.resourceserver.jwt.client.registration.read-timeout=10000 | ||
| ``` | ||
| </TabItem> | ||
| </Tabs> |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Spring Boot 4.0 spring.security.oauth2.resourceserver.jwt timeout configuration properties
💡 Result:
Spring Boot 4.0 (Spring Security 7.x) does not expose any spring.security.oauth2.resourceserver.jwt.* configuration properties for HTTP timeouts (connect/read) when the resource server fetches OIDC metadata / JWK set keys. Boot’s JWT resource-server properties cover things like issuer-uri, jwk-set-uri, audiences, etc., but not timeouts. [1]
Servlet (Spring MVC): configure via a JwtDecoder bean
Spring Security documents that the resource server uses 30s connect + 30s socket/read timeouts by default, and shows customizing them by supplying a RestOperations (e.g., RestTemplate) to NimbusJwtDecoder: [2]
`@Bean`
JwtDecoder jwtDecoder(RestTemplateBuilder builder) {
RestOperations rest = builder
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(5))
.build();
return NimbusJwtDecoder.withIssuerLocation(issuerUri)
.restOperations(rest)
.build();
}Reactive (WebFlux): configure via a ReactiveJwtDecoder bean
For reactive apps, NimbusReactiveJwtDecoder lets you supply a custom WebClient (where you set Reactor Netty timeouts, proxy, etc.) via the builder’s webClient(WebClient) method. [3]
Sources:
[1] Spring Boot reference (resource server JWT properties) (docs.enterprise.spring.io)
[2] Spring Security reference (JWT “Configuring Timeouts” with RestOperations) (docs.spring.io)
[3] Spring Security Javadoc (NimbusReactiveJwtDecoder...Builder.webClient(WebClient)) (docs.spring.io)
Citations:
- 1: https://docs.enterprise.spring.io/spring-boot/docs/3.1.15.2/reference/htmlsingle?utm_source=openai
- 2: https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html?utm_source=openai
- 3: https://docs.spring.io/spring-security/reference/api/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.JwkSetUriReactiveJwtDecoderBuilder.html?utm_source=openai
🌐 Web query:
Spring Security ResourceServer JWT decoder client timeout configuration
💡 Result:
Spring Security’s OAuth2 Resource Server JWT support uses 30s connect + 30s read/socket timeouts by default when fetching the JWK Set. You change this by providing your own HTTP client to the decoder builder. [1]
Servlet (Spring MVC) — NimbusJwtDecoder (uses RestOperations)
Expose a custom JwtDecoder bean and pass a RestOperations (typically a RestTemplate) with your desired timeouts:
`@Bean`
JwtDecoder jwtDecoder(RestTemplateBuilder builder) {
RestOperations rest = builder
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(5))
.build();
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
.restOperations(rest)
.build();
}Spring Security supports injecting RestOperations via NimbusJwtDecoder.withJwkSetUri(...).restOperations(...). [1][2]
Reactive (WebFlux) — NimbusReactiveJwtDecoder (uses WebClient)
Provide a WebClient configured with timeouts, then:
`@Bean`
ReactiveJwtDecoder jwtDecoder(WebClient webClient) {
return NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)
.webClient(webClient)
.build();
}The reactive builder explicitly supports supplying a WebClient via .webClient(...). [3]
🌐 Web query:
Spring Security NimbusJwtDecoder RestOperations timeout configuration 2024 2025
💡 Result:
To configure connect/read timeouts for the HTTP calls Spring Security makes to fetch OIDC metadata and/or the JWK Set, supply a RestOperations (typically a RestTemplate) to the NimbusJwtDecoder builder via .restOperations(...) (works with both withIssuerLocation(...) and withJwkSetUri(...)). Spring Security’s reference docs show this as the supported approach and note a default of 30s connect + 30s socket/read unless you override it. [1]
`@Bean`
JwtDecoder jwtDecoder(RestTemplateBuilder builder) {
RestOperations rest = builder
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(5))
.build();
return NimbusJwtDecoder.withIssuerLocation("https://idp.example.com/issuer")
.restOperations(rest)
.build();
// or: .withJwkSetUri(jwkSetUri).restOperations(rest).build();
}The NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder#restOperations(RestOperations) hook is part of the public API. [2]
Note: there was an enhancement request (Dec 11, 2023) indicating that some internal paths used a default RestTemplate “with no timeout configured” (risking hung threads), so explicitly wiring timeouts as above is the safest option across versions. [3]
Sources: [1] Spring Security Reference – “Configuring Timeouts” (Resource Server JWT) • [2] Spring Security Javadoc – NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder#restOperations • [3] spring-projects/spring-security issue #14269
Remove or caveat the YAML/properties timeout configuration—it will silently have no effect.
Spring Boot 4.0 (Spring Security 7.x) does not expose spring.security.oauth2.resourceserver.jwt.client.registration.connect-timeout or similar timeout properties for the resource server's JWT decoder. The documented properties under spring.security.oauth2.resourceserver.jwt.* are limited to issuer-uri, jwk-set-uri, and validation options only.
The programmatic approach shown in lines 112–138 (using NimbusJwtDecoder with a custom RestOperations) is the documented and correct way to configure timeouts. Developers who apply the declarative YAML/properties config will believe timeouts are set to 10 seconds when they actually remain at Spring Security's default of 30 seconds, creating a false sense of control.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/cookbooks/java-spring-boot-jwt-timeout.mdx` around lines 73
- 97, Remove the misleading YAML/properties timeout entries under
spring.security.oauth2.resourceserver.jwt (the application.yml and
application.properties TabItems) and add a clear caveat noting these properties
are ignored in Spring Boot 4 / Spring Security 7; instead, reference and
recommend the programmatic approach shown in the doc (the NimbusJwtDecoder +
custom RestOperations example around the existing "NimbusJwtDecoder" /
"RestOperations" code in lines ~112–138) and instruct readers to configure
timeouts via a custom RestTemplate/HttpClient or WebClient passed into
NimbusJwtDecoder rather than via declarative properties.
✅ Deploy Preview for scalekit-starlight ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Actionable comments posted: 40
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.gitignore (1)
16-35: 🧹 Nitpick | 🔵 TrivialRemove duplicate
debug.logignore entry.
debug.logis listed twice (Line 16 and Line 34). Keep a single entry to reduce config noise.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gitignore around lines 16 - 35, The .gitignore contains duplicate entries for debug.log; edit the .gitignore and remove the redundant debug.log line so only a single debug.log entry remains (ensure the remaining debug.log entry is kept and there are no other duplicate ignore entries).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/commands/speckit.checklist.md:
- Line 240: The checklist item string currently reads "Are rate limiting
requirements quantified with specific thresholds? [Clarity]"; update that
literal checklist text (the quoted string) to use the hyphenated compound
adjective "rate-limiting requirements" so it becomes "Are rate-limiting
requirements quantified with specific thresholds? [Clarity]".
- Around line 34-71: Add explicit verification-check criteria to each step in
the "Execution Steps" sequence in .claude/commands/speckit.checklist.md: for
Step 1 (Setup) update the instructions that parse
`.specify/scripts/bash/check-prerequisites.sh --json` so the step includes
concrete expected artifacts (e.g., FEATURE_DIR absolute path present,
AVAILABLE_DOCS array non-empty, JSON schema keys) and a pass/fail condition
before proceeding; for Step 2 (Clarify intent (dynamic)) add per-question
generation verification (e.g., signals extracted list not empty, cluster count
≤4, audience inferred or flagged) plus expected outputs (Q1–Q3 produced or
explicit skip reason) and a short checkpoint that halts further generation if
verification fails; apply the same pattern to any subsequent numbered steps:
state the exact artifact/field to validate, the validation rule, and the
required next-state (continue/abort) so each procedural step has an unambiguous
verification checklist and pass/fail criteria.
- Around line 91-97: Resolve the contradictory creation rules by making
/speckit.checklist always create a NEW file (never append); change the filename
rule from plain "[domain].md" to a unique name that preserves the domain prefix
(e.g., "[domain]-YYYYMMDD-HHMMSS.md" or "[domain]-<uuid>.md"), remove the "If
file exists, append to existing file" statement, and keep "Number items
sequentially starting from CHK001" (per checklist file); update all occurrences
of the old append rule (including the other instance noted) and any code or docs
that build filenames for the /speckit.checklist command to use the
timestamp/UUID scheme.
- Around line 36-38: Add explicit fail-fast handling after running
`.specify/scripts/bash/check-prerequisites.sh --json`: validate the JSON output
and ensure the required keys FEATURE_DIR and AVAILABLE_DOCS are present and
non-empty; if the script fails, returns invalid JSON, or those keys are missing,
immediately exit with a non-zero status and emit a clear error message
indicating which check failed so downstream checklist generation cannot proceed
with undefined context.
In @.claude/commands/speckit.clarify.md:
- Around line 88-90: Unify the conflicting clarification-question limits by
introducing a single constant (e.g., MAX_CLARIFICATION_QUESTIONS) and using it
everywhere the doc enforces a cap: the "Generate (internally) a prioritized
queue of candidate clarification questions" constraint that currently says
"Maximum of 10 total questions" and the later places that cap at 5; pick the
intended value (5 or 10), replace the hard-coded numbers with the constant, and
update the descriptive text so all occurrences consistently reference
MAX_CLARIFICATION_QUESTIONS.
In @.claude/commands/speckit.constitution.md:
- Line 47: The propagation checklist incorrectly scopes command-file
verification to ".specify/templates/commands/*.md (including this one)" while
this file lives in ".claude/commands/", so update the checklist text to include
both command locations or use a broader glob describing both directories;
specifically edit the sentence containing the quoted glob to either list both
patterns (".specify/templates/commands/*.md" and ".claude/commands/*.md") or to
say "command files in the repository's command directories (e.g.,
templates/commands and .claude/commands)" so sync validation will catch this
file and other command docs.
In @.claude/commands/speckit.implement.md:
- Line 88: Edit the C ignore defaults line that starts with "**C**:" to remove
the "Makefile" entry so Makefiles are not ignored; locate the markdown entry
containing the list (`build/, bin/, obj/, out/, *.o, *.a, *.so, *.exe, Makefile,
config.log, .idea/, *.log, .env*`) and delete the "Makefile" token (and any
stray comma/space) so the list preserves proper punctuation; leave all other
ignore patterns unchanged and update any nearby explanatory text if it mentions
Makefile being ignored.
In @.claude/commands/speckit.plan.md:
- Line 36: The "Stop and report" step references "Phase 2 planning" which
doesn't exist in this document (only Phase 0 and Phase 1 are defined); update
the text under the "4. **Stop and report**" section to either (a) change "Phase
2 planning" to "Phase 1 planning" if the intent is to stop after the last
defined phase, or (b) add a clear definition for "Phase 2" elsewhere consistent
with Phase 0/1 and then keep the reference — make sure the line mentions
IMPL_PLAN and generated artifacts remain accurate.
- Around line 78-80: The command list currently hardcodes the 'claude' agent
when running .specify/scripts/bash/update-agent-context.sh; change the
invocation to use the agent-detection mechanism instead of a literal 'claude'
(e.g., derive the agent name from the same detection logic referenced in the
comments and pass that variable to update-agent-context.sh). Update the step
that mentions running ".specify/scripts/bash/update-agent-context.sh claude" to
call the script with the detectedAgent variable or helper (the same detection
used by the surrounding steps) so the correct agent-specific context file is
updated rather than always updating Claude's context.
In @.claude/commands/speckit.specify.md:
- Around line 57-61: Update the example invocations for the
create-new-feature.sh script so they match the script's supported flags and
invocation method: remove the duplicate `--json` and conflicting `"$ARGUMENTS"`
placeholder in the bash example and call the script via bash (e.g., `bash
.specify/scripts/bash/create-new-feature.sh --json --number 5 --short-name
"user-auth" "Add user authentication"`), and replace the PowerShell example with
an explicit bash invocation using the same supported flags (`--json`,
`--number`, `--short-name`) rather than `-Json`, `-Number`, or `-ShortName`;
reference the script name create-new-feature.sh and the ARGUMENTS placeholder
when editing the lines.
In @.claude/commands/speckit.tasks.md:
- Around line 96-103: The checklist contains inconsistent "✅ CORRECT" examples:
the entry `- [ ] T001 Create project structure per implementation plan` lacks a
file path while other correct examples (e.g., `- [ ] T012 [P] [US1] Create User
model in src/models/user.py`) include a file path, causing malformed tasks;
update the incorrect "✅ CORRECT" example to follow the canonical format by
adding the missing file path and any missing labels (Task ID, Story label, and
optional priority) so it matches the pattern used by `T005`, `T012`, and `T014`.
In @.coderabbit.yaml:
- Around line 42-43: The rule in .coderabbit.yaml that globally requires
`sidebar.order` should be narrowed: change the check so `sidebar.order` is only
mandatory when a page lives in a directory referenced by a sidebar entry (i.e.,
when the sidebar entry points to a directory, not when the sidebar explicitly
maps individual files as in src/configs/sidebar.config.ts); update the validator
logic to detect whether a sidebar item is a directory reference versus an
explicit file mapping and skip the `sidebar.order` assertion for pages under
directories that are explicitly mapped (e.g., pages under
src/content/docs/authenticate/fsa/multiapp/), or add an allowlist/exception for
those paths so the rule no longer produces false positives.
In @.env.example:
- Line 80: The example env contains a concrete SCALEKIT_CLIENT_ID value which
should be replaced with a neutral placeholder to avoid accidental reuse; update
the SCALEKIT_CLIENT_ID entry in .env.example to a clearly identifiable
placeholder string (e.g., YOUR_SCALEKIT_CLIENT_ID or <SCALEKIT_CLIENT_ID>) and
ensure any surrounding formatting stays consistent with other example variables
so consumers know to replace it with their own secret.
In @.gitignore:
- Around line 38-45: The negation rules (e.g., "!.specify/memory/",
"!.specify/memory/constitution.md", "!.claude/commands/speckit.constitution.md")
are currently overridden by later broad ignores (".specify/", ".claude/")
because .gitignore uses last-match-wins; move the broad ignore entries earlier
and place the negation lines after them (or remove the conflicting broad lines)
so the specific exceptions are evaluated last and remain effective for .specify/
and .claude/.
In @.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/2-PLAN.md:
- Around line 34-35: The plan contains machine-local absolute paths (the lines
listing "/Users/saif/.config/opencode/get-shit-done/workflows/execute-plan.md"
and "/Users/saif/.config/opencode/get-shit-done/templates/summary.md") which
break portability; update the references in
.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/2-PLAN.md to use
repo-relative paths (e.g., ./config/... or docs/... as appropriate) or load them
from environment variables (e.g., OPENCODE_WORKFLOW_PATH,
OPENCODE_TEMPLATE_PATH) and fallback to sensible defaults, ensuring the strings
you change are the exact entries shown so CI and other contributors can resolve
them without user-specific directories.
In @.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/2-SUMMARY.md:
- Around line 34-45: The frontmatter date "completed: 2026-02-25" conflicts with
the runtime metrics timestamps showing 2025-02-25; pick the correct date (e.g.,
2026-02-25) and make them consistent by updating the frontmatter "completed"
value and all runtime metric fields ("Started:" and "Completed:" entries in the
footer/body) to the chosen date string so every occurrence in the document
matches; search for the literal dates in this file (the frontmatter "completed"
key and the "Started:"/"Completed:" timestamps) and change them consistently.
- Around line 69-70: The "### Created" subheading and other subheadings in
.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/2-SUMMARY.md are
followed immediately by list items, violating markdownlint MD022; insert a
single blank line after each subheading (e.g., after "### Created" and the other
subheadings referenced) so there is one empty line between the heading and the
subsequent list content throughout the file.
In
@.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/verification-report.md:
- Line 3: Add a single blank line immediately after each Markdown heading to
satisfy MD022: for example insert one empty line after the "## Branch
Information" heading and do the same for the other headings mentioned ("24-24",
"33-33", "41-41", "48-48", "51-51", "60-60", "76-76", "83-83" correspond to the
other heading lines) so every heading is followed by one blank line for proper
markdownlint formatting and improved readability.
In @.planning/STATE.md:
- Around line 8-10: Update the chronology in STATE.md so the “Last activity”
matches the most recent recorded activity: change the trailing “Last activity:
2025-02-25 - Completed quick task 2: Switch to go_v210 branch and verify Go SDK
v2.10 documentation updates” to use the later date from the subsequent entry
(2026-02-18) or otherwise recalc to the actual newest activity date; ensure the
table row for "Switch to go_v210 branch and verify Go SDK v2.10 documentation
updates" remains accurate and that the overall "Last activity" label reflects
the true most-recent timestamp.
In @.specify/memory/constitution.md:
- Line 248: Update the constitution's LAST_AMENDED_DATE value shown on line with
"Last Amended" from "2026-02-09" to "2026-02-26" so the header metadata
(`**Version**: 1.2.0 | **Ratified**: 2026-02-06 | **Last Amended**: 2026-02-26`)
reflects today's date; locate the `Last Amended` string in
.specify/memory/constitution.md and change only the date to 2026-02-26.
In @.specify/scripts/bash/check-prerequisites.sh:
- Around line 83-100: The script currently calls
check_feature_branch("$CURRENT_BRANCH","$HAS_GIT") before honoring the
--paths-only fast path, causing branch validation to run even when PATHS_ONLY is
true; update the flow so branch validation is skipped in paths-only mode by
relocating the check_feature_branch invocation to after the PATHS_ONLY
conditional or wrapping it in an if ! $PATHS_ONLY ... fi guard (referencing
check_feature_branch, PATHS_ONLY and CURRENT_BRANCH) so --paths-only exits
immediately without performing branch validation.
In @.specify/scripts/bash/common.sh:
- Around line 139-151: get_feature_paths() currently emits single-quoted
variable assignments directly, which breaks eval when values contain single
quotes; fix by escaping single quotes in each value before printing (e.g., for
repo_root, current_branch, feature_dir, etc. do
escaped=${repo_root//\'/\'\"\'\"\'} and use that escaped variable in the
here-doc output). Update the output in get_feature_paths() so every emitted
assignment uses the escaped value, ensuring callers (setup-plan.sh,
update-agent-context.sh, check-prerequisites.sh) that do eval
$(get_feature_paths) safely parse even if branch names or paths contain single
quotes.
In @.specify/scripts/bash/create-new-feature.sh:
- Around line 249-250: The script currently does arithmetic conversion using
FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))") which will crash if
BRANCH_NUMBER (the parsed --number) is non-numeric; add a validation step before
that line to verify BRANCH_NUMBER contains only digits (e.g. use a regex like
^[0-9]+$ or an integer check) and if it fails, print a clear error (including
the invalid value) and exit with a non-zero status; once validated, proceed to
compute FEATURE_NUM as before.
In @.specify/scripts/bash/setup-plan.sh:
- Line 31: Replace the unquoted command substitution passed to eval so the
entire output of get_feature_paths is treated as a single argument; locate the
line using eval and the get_feature_paths function and change it to call eval
with the command substitution wrapped in double quotes (i.e., pass the output of
get_feature_paths as a quoted string to eval).
In @.specify/scripts/bash/update-agent-context.sh:
- Line 747: The usage string passed to log_info is missing the supported agent
types "roo" and "amp"; update the string in the script (the log_info call shown)
to include "roo" and "amp" so it matches the valid branches in
update_specific_agent(), ensuring the usage list covers all accepted agent
names.
- Around line 458-461: The post-increment expression
((existing_changes_count++)) can return a non-zero exit status under set -e and
abort the script; replace it with a safe increment that never returns non-zero
(e.g., use existing_changes_count=$((existing_changes_count+1)) or
((existing_changes_count+=1))) in the block that writes to temp_file
(referencing existing_changes_count). Also update the usage/help text that lists
supported agents to match the case handling (add roo and amp and remove
codebuddy) so the supported-agents string aligns with the case statement
handling (see the case branches for roo and amp and the incorrect codebuddy
entry).
In `@astro.config.mjs`:
- Around line 98-104: Add a short inline comment above the starlightBlog({ ...
}) plugin entry explaining why this plugin is enabled and what it does (for
example: that it surfaces cookbook/blog content under the /cookbooks route and
enables readingTime/word metrics). Update the starlightBlog invocation (symbol:
starlightBlog, including the prefix 'cookbooks' and metrics keys) to be preceded
by a one-line descriptive comment that documents its purpose and any important
config choices.
In `@CLAUDE.md`:
- Around line 11-241: The document uses title case for multiple top-level
headings (e.g., "Core Principles", "Writing Standards", "Technical
Requirements", "Frontmatter and Content Structure", "Document Types and
Templates", "Development Workflow", "Active Technologies"); change each
Markdown/MDX heading to sentence case (e.g., "Core principles", "Writing
standards", "Technical requirements", "Frontmatter and content structure",
"Document types and templates", "Development workflow", "Active technologies")
to conform to the repo guideline; update every heading string in CLAUDE.md
accordingly, keeping the same structure and frontmatter values but normalizing
heading capitalization throughout.
- Around line 202-248: Append a "Quality Checklist" section to the end of
CLAUDE.md that includes the required footer marker; specifically add a "Quality
Checklist" heading (or ensure an existing one) and finish the document with the
exact token `STYLE-CHECK: [PASSED | TODO]` so automated checks can detect
pass/todo status, ensuring the literal marker is present as the final line of
the file.
In `@CONTRIBUTING.md`:
- Around line 238-247: Add a clear exception below the <Tabs
syncKey="tech-stack"> example in CONTRIBUTING.md stating that the four-language
SDK tab requirement does not apply to the multi-app authentication docs, which
intentionally use shell/curl conceptual examples until SDK support is available;
explicitly reference the multi-app auth docs (authenticate/fsa/multiapp) and
instruct contributors to follow the existing shell/curl pattern there until SDK
examples are added, so the Tabs guideline and the multi-app docs do not
contradict each other.
- Around line 14-22: The TOC contains broken anchor targets—update the entries
for "Run git hooks", "Describe project architecture" (and its subitems "Describe
Starlight plugins", "Describe overridden components", "Describe custom
components"), "Raise a pull request" and any other mismatched items so they
match the actual heading IDs in CONTRIBUTING.md (either by changing the TOC
anchors to the exact kebab-case generated from the real headings or by
renaming/adding the corresponding headings to match the anchors); check headings
like Run git hooks, Describe project architecture, and Raise a pull request in
the file and make the TOC links and heading text consistent.
- Around line 216-226: Update the frontmatter requirements to match repo policy:
change the mandatory fields list so every page MUST include at least title,
description, and sidebar.label (refer to the frontmatter keys `title`,
`description`, and `sidebar.label`), and mark `sidebar.order` and `tags` as
optional (use `sidebar.order` only when navigation ordering matters and `tags`
only when applicable); adjust the example and wording accordingly so
contributors are not instructed to always include `sidebar.order` or `tags`.
In `@netlify/functions/slack-bot.ts`:
- Around line 30-54: The current in-memory dedupe map (processedEventIds) used
by isDuplicateEvent with EVENT_ID_TTL_MS won't persist across Lambda instances;
replace it with a shared TTL-backed store (e.g., Redis or Netlify Blob/DB) and
perform an atomic check-and-set with expiry when verifying event IDs: in
isDuplicateEvent, instead of checking processedEventIds.has/set, call the shared
store to SET the event_id with NX and TTL (or equivalent upsert-with-expiry) and
return true if the key already existed, ensuring all Lambda instances consult
the same store and preventing duplicate Slack replies.
- Around line 97-102: Remove the early-return that acknowledges all Slack
retries: do not return 200 when getHeader(headers, 'x-slack-retry-num') is
present; instead log the retry headers (retryNum and retryReason) with
console.info and allow execution to continue so the existing event-id
deduplication (isDuplicateEvent(eventId) / event_id handling) can run and handle
idempotent retry processing; keep using getHeader to read 'x-slack-retry-num'
and 'x-slack-retry-reason' but do not short-circuit the handler.
In `@project-docs/.env.template`:
- Around line 11-27: Replace all real-looking token values in the .env template
with neutral placeholders or empty values so no secrets are committed;
specifically update STARLIGHT_CHANGELOG_90DAY_ACCESS, GITHUB_TOKEN,
PUBLIC_SAMPLEAPP_API_KEY, PUBLIC_PYLON_APP_ID, SLACK_BOT_TOKEN,
SLACK_SIGNING_SECRET, ALGOLIA_APP_ID, ALGOLIA_API_KEY,
ALGOLIA_ASKAI_ASSISTANT_ID, ALGOLIA_INDEX_NAME, ALGOLIA_ASKAI_ORIGIN, and
ALGOLIA_ASKAI_BASE_URL to use descriptive placeholders (e.g. <YOUR_GITHUB_TOKEN>
or empty) and remove any masked or token-like strings present in the file.
- Around line 33-35: Update the root .env.example to use the same
auth.scalekit.com domain as the application and docs to avoid mismatch;
specifically ensure the SCALEKIT_AUTHORIZE_URL and SCALEKIT_TOKEN_URL entries
(and any SCALEKIT_REDIRECT_URI that references the auth domain) in .env.example
use auth.scalekit.com instead of auth.scalekit.cloud so they match the values
referenced in project-docs/.env.template and the app defaults.
In `@public/api/scalekit.scalar.json`:
- Around line 3451-3457: The OpenAPI parameter "type" (query parameter named
"type" with schema enum ["SCALEKIT","ENVIRONMENT"]) has a mismatch with its
description (which mentions "ALL"); update the OpenAPI generator/template that
emits the "type" query param so the contract is consistent—either add "ALL" to
the enum or change the description to instruct clients to omit the parameter for
"all" (and ensure the generator sets the same default behavior in codegen
metadata); locate the template or source that builds the parameter named "type"
in the Scalekit permission endpoint and apply the fix so regenerated
public/api/scalekit.scalar.json is consistent.
- Around line 11751-12047: The OpenAPI spec adds webhook paths like
"connected_account.created"/"connected_account.updated" that reference the
ScalekitEvent schema, but the ScalekitEvent.type and ScalekitEvent.object enums
do not include "connected_account.*" or "ConnectedAccount", causing schema
mismatch; fix by either adding the connected_account event types and
"ConnectedAccount" object value to the ScalekitEvent.enums (ScalekitEvent.type,
ScalekitEvent.object) or update the webhook paths to reference a new, permissive
ConnectedAccountEvent schema (or a generic ScalekitEventBase without restrictive
enums) and adjust the OpenAPI generator/template to emit the correct schema ref
for connected account webhooks (update references to ScalekitEvent in the
connected_account.* post entries).
In `@README.md`:
- Line 126: Update the README line that currently states "Every page needs
`title`, `description`, `sidebar.label`, and `tags`" to correctly reflect that
only `title`, `description`, and `sidebar.label` are required frontmatter fields
while `tags` is optional; edit the sentence to list the required fields
(`title`, `description`, `sidebar.label`) and note that `tags` may be included
but is not mandatory so contributors are not misled.
- Around line 88-94: The README contains contradictory statements about hot
module replacement: the sentence "Changes to MDX files hot-reload instantly"
conflicts with the table entry for the `pnpm dev` command that says "(no HMR)";
update the documentation so they match by either (A) changing the sentence to
specify which command provides HMR (e.g., "When running `pnpm dev:hmr` or `pnpm
dev` with HMR enabled, changes to MDX files hot-reload instantly") or (B)
updating the `pnpm dev` description to reflect that it does provide HMR if that
is true; locate and edit the README lines referencing "MDX", "hot-reload",
"HMR", and the `pnpm dev` table entry to ensure a single consistent statement
about which command enables hot-reload.
---
Outside diff comments:
In @.gitignore:
- Around line 16-35: The .gitignore contains duplicate entries for debug.log;
edit the .gitignore and remove the redundant debug.log line so only a single
debug.log entry remains (ensure the remaining debug.log entry is kept and there
are no other duplicate ignore entries).
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (39)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlpublic/d2/docs/authenticate/auth-methods/authentication-flow-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/fsa/multiapp/native-app-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/fsa/multiapp/overview-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/fsa/multiapp/single-page-app-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/fsa/multiapp/web-app-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/manage-users-orgs/hosted-widgets-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/manage-users-orgs/jit-provisioning-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/manage-users-orgs/scim-provisioning-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/mcp/overview-0.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/mcp/overview-1.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/mcp/overview-2.svgis excluded by!**/*.svgpublic/d2/docs/authenticate/mcp/overview-3.svgis excluded by!**/*.svgpublic/d2/docs/dev-kit/tools/use-scalekit-credentials-0.svgis excluded by!**/*.svgpublic/d2/docs/directory/guides/group-based-role-assignment-0.svgis excluded by!**/*.svgpublic/d2/docs/mcp/auth-methods/custom-auth-0.svgis excluded by!**/*.svgpublic/d2/docs/mcp/auth-methods/enterprise-0.svgis excluded by!**/*.svgsrc/assets/docs/_onboard-enterprise-customers-sso/org_domain.pngis excluded by!**/*.pngsrc/assets/docs/ai-assisted-mcp-quickstart/1.pngis excluded by!**/*.pngsrc/assets/docs/ai-assisted-mcp-quickstart/2.gifis excluded by!**/*.gifsrc/assets/docs/ai-assisted-mcp-quickstart/skill-activation.pngis excluded by!**/*.pngsrc/assets/docs/group-based-role-assignment/2026-02-06-16-15-49.pngis excluded by!**/*.pngsrc/assets/docs/group-based-role-assignment/add-role-page.pngis excluded by!**/*.pngsrc/assets/docs/group-based-role-assignment/default-roles.pngis excluded by!**/*.pngsrc/assets/docs/group-based-role-assignment/roles-and-permissions.pngis excluded by!**/*.pngsrc/assets/docs/guides/multi-app/delete-app.pngis excluded by!**/*.pngsrc/assets/docs/guides/multi-app/spa-client-id.pngis excluded by!**/*.pngsrc/assets/docs/guides/multi-app/web-app-details.pngis excluded by!**/*.pngsrc/assets/docs/guides/multi-app/web-app-redirects.pngis excluded by!**/*.pngsrc/assets/docs/guides/multi-app/web-client-creds.pngis excluded by!**/*.pngsrc/assets/docs/guides/multi-app/web-modal.pngis excluded by!**/*.pngsrc/assets/docs/hosted-widgets/org_member.pngis excluded by!**/*.pngsrc/assets/docs/hosted-widgets/org_scim.pngis excluded by!**/*.pngsrc/assets/docs/hosted-widgets/org_settings.pngis excluded by!**/*.pngsrc/assets/docs/hosted-widgets/org_sso.pngis excluded by!**/*.pngsrc/assets/docs/hosted-widgets/user_profile.pngis excluded by!**/*.pngsrc/assets/docs/hosted-widgets/user_security.pngis excluded by!**/*.pngsrc/assets/docs/scalekit-dryrun/user-profile-details.pngis excluded by!**/*.pngsrc/assets/docs/use-scalekit-credentials/01.pngis excluded by!**/*.png
📒 Files selected for processing (185)
.claude/commands/speckit.analyze.md.claude/commands/speckit.checklist.md.claude/commands/speckit.clarify.md.claude/commands/speckit.constitution.md.claude/commands/speckit.implement.md.claude/commands/speckit.plan.md.claude/commands/speckit.specify.md.claude/commands/speckit.tasks.md.claude/commands/speckit.taskstoissues.md.coderabbit.yaml.env.example.gitignore.planning/STATE.md.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/2-PLAN.md.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/2-SUMMARY.md.planning/quick/2-switch-to-go-v210-branch-and-verify-if-t/verification-report.md.specify/memory/constitution.md.specify/scripts/bash/check-prerequisites.sh.specify/scripts/bash/common.sh.specify/scripts/bash/create-new-feature.sh.specify/scripts/bash/setup-plan.sh.specify/scripts/bash/update-agent-context.sh.specify/templates/agent-file-template.md.specify/templates/checklist-template.md.specify/templates/plan-template.md.specify/templates/spec-template.md.specify/templates/tasks-template.mdCLAUDE.mdCONTRIBUTING.mdREADME.mdastro.config.mjsnetlify/functions/slack-bot.tspackage.jsonproject-docs/.env.templatepublic/api/scalekit.scalar.jsonpublic/api/scalekit.scalar.yamlpublic/js/posthog.jspublic/js/pylon-widget.jsscripts/install-d2.shscripts/setup-git-hooks.jsscripts/sync-agent-connectors.jsspecs/001-mcp-auth-quickstart/checklists/requirements.mdspecs/001-mcp-auth-quickstart/contracts/content-template-contract.yamlspecs/001-mcp-auth-quickstart/contracts/frontmatter-contract.yamlspecs/001-mcp-auth-quickstart/contracts/sidebar-contract.yamlspecs/001-mcp-auth-quickstart/data-model.mdspecs/001-mcp-auth-quickstart/plan.mdspecs/001-mcp-auth-quickstart/quickstart.mdspecs/001-mcp-auth-quickstart/research.mdspecs/001-mcp-auth-quickstart/spec.mdspecs/001-mcp-auth-quickstart/tasks.mdsrc/components/SecondaryNav.astrosrc/components/auth/AuthCTA.astrosrc/components/auth/AuthGate.astrosrc/components/auth/AuthValue.astrosrc/components/overrides/Footer.astrosrc/components/overrides/Header.astrosrc/components/templates/_installsdk.mdxsrc/components/templates/_onboard-enterprise-customers-scim.mdxsrc/components/templates/_onboard-enterprise-customers-sso.mdxsrc/components/templates/_retrieve-user-details.mdxsrc/components/templates/_scim-integrations.mdxsrc/components/templates/_user-authpage.mdxsrc/components/templates/index.tssrc/components/ui/landing/Fold4.astrosrc/configs/llms.config.tssrc/configs/redirects.config.tssrc/configs/sidebar.config.tssrc/content/docs/agent-auth/authentication/multi-provider.mdxsrc/content/docs/agent-auth/authentication/scopes-permissions.mdxsrc/content/docs/agent-auth/authentication/testing-auth-flows.mdxsrc/content/docs/agent-auth/authentication/token-management.mdxsrc/content/docs/agent-auth/authentication/troubleshooting.mdxsrc/content/docs/agent-auth/overview.mdxsrc/content/docs/agent-auth/quickstart.mdxsrc/content/docs/agent-auth/start-agent-auth-coding-agents.mdxsrc/content/docs/authenticate/auth-methods/authentication-flow.mdxsrc/content/docs/authenticate/authz/implement-access-control.mdxsrc/content/docs/authenticate/fsa/complete-login.mdxsrc/content/docs/authenticate/fsa/implement-login.mdxsrc/content/docs/authenticate/fsa/logout.mdxsrc/content/docs/authenticate/fsa/manage-session.mdxsrc/content/docs/authenticate/fsa/multiapp/manage-apps.mdxsrc/content/docs/authenticate/fsa/multiapp/native-app.mdxsrc/content/docs/authenticate/fsa/multiapp/overview.mdxsrc/content/docs/authenticate/fsa/multiapp/single-page-app.mdxsrc/content/docs/authenticate/fsa/multiapp/web-app.mdxsrc/content/docs/authenticate/fsa/quickstart.mdxsrc/content/docs/authenticate/manage-organizations/add-users-to-organization.mdxsrc/content/docs/authenticate/manage-users-orgs/hosted-widgets.mdxsrc/content/docs/authenticate/manage-users-orgs/jit-provisioning.mdxsrc/content/docs/authenticate/manage-users-orgs/organization-switching.mdxsrc/content/docs/authenticate/manage-users-orgs/scim-provisioning.mdxsrc/content/docs/authenticate/mcp/overview.mdxsrc/content/docs/authenticate/mcp/quickstart.mdxsrc/content/docs/authenticate/mcp/start-mcp-auth-coding-agents.mdxsrc/content/docs/authenticate/sso/add-modular-sso.mdxsrc/content/docs/dev-kit/guides/testing/sso-simulator.mdxsrc/content/docs/dev-kit/tools/scalekit-dryrun.mdxsrc/content/docs/dev-kit/tools/sso-simulator.mdxsrc/content/docs/dev-kit/tools/use-scalekit-credentials.mdxsrc/content/docs/directory/guides/group-based-role-assignment.mdxsrc/content/docs/directory/guides/onboard-enterprise-customers.mdxsrc/content/docs/guides/integrations/scim-integrations/generic-scim.mdxsrc/content/docs/guides/integrations/social-connections/google.mdxsrc/content/docs/guides/m2m/api-auth-m2m-clients.mdxsrc/content/docs/guides/m2m/overview.mdxsrc/content/docs/guides/security/authentication-best-practices.mdxsrc/content/docs/guides/user-auth/modular-social-logins.mdxsrc/content/docs/guides/user-management/scim-provisioning.mdxsrc/content/docs/mcp/auth-methods/custom-auth.mdxsrc/content/docs/mcp/auth-methods/enterprise.mdxsrc/content/docs/passwordless/oidc.mdxsrc/content/docs/reference/agent-connectors/airtable.mdxsrc/content/docs/reference/agent-connectors/asana.mdxsrc/content/docs/reference/agent-connectors/attention.mdxsrc/content/docs/reference/agent-connectors/bigquery.mdxsrc/content/docs/reference/agent-connectors/chorus.mdxsrc/content/docs/reference/agent-connectors/clari_copilot.mdxsrc/content/docs/reference/agent-connectors/clickup.mdxsrc/content/docs/reference/agent-connectors/confluence.mdxsrc/content/docs/reference/agent-connectors/dropbox.mdxsrc/content/docs/reference/agent-connectors/fathom.mdxsrc/content/docs/reference/agent-connectors/freshdesk.mdxsrc/content/docs/reference/agent-connectors/github.mdxsrc/content/docs/reference/agent-connectors/gmail.mdxsrc/content/docs/reference/agent-connectors/gong.mdxsrc/content/docs/reference/agent-connectors/google_ads.mdxsrc/content/docs/reference/agent-connectors/googlecalendar.mdxsrc/content/docs/reference/agent-connectors/googledocs.mdxsrc/content/docs/reference/agent-connectors/googledrive.mdxsrc/content/docs/reference/agent-connectors/googleforms.mdxsrc/content/docs/reference/agent-connectors/googlemeet.mdxsrc/content/docs/reference/agent-connectors/googlesheets.mdxsrc/content/docs/reference/agent-connectors/googleslides.mdxsrc/content/docs/reference/agent-connectors/hubspot.mdxsrc/content/docs/reference/agent-connectors/intercom.mdxsrc/content/docs/reference/agent-connectors/jira.mdxsrc/content/docs/reference/agent-connectors/linear.mdxsrc/content/docs/reference/agent-connectors/microsoftexcel.mdxsrc/content/docs/reference/agent-connectors/microsoftteams.mdxsrc/content/docs/reference/agent-connectors/microsoftword.mdxsrc/content/docs/reference/agent-connectors/monday.mdxsrc/content/docs/reference/agent-connectors/notion.mdxsrc/content/docs/reference/agent-connectors/onedrive.mdxsrc/content/docs/reference/agent-connectors/onenote.mdxsrc/content/docs/reference/agent-connectors/outlook.mdxsrc/content/docs/reference/agent-connectors/salesforce.mdxsrc/content/docs/reference/agent-connectors/servicenow.mdxsrc/content/docs/reference/agent-connectors/sharepoint.mdxsrc/content/docs/reference/agent-connectors/slack.mdxsrc/content/docs/reference/agent-connectors/snowflake.mdxsrc/content/docs/reference/agent-connectors/trello.mdxsrc/content/docs/reference/agent-connectors/zendesk.mdxsrc/content/docs/reference/agent-connectors/zoom.mdxsrc/content/docs/reference/contact-us.mdxsrc/content/docs/sso/guides/idp-init-sso.mdxsrc/content/docs/sso/guides/onboard-enterprise-customers.mdxsrc/content/docs/sso/guides/test-sso.mdxsrc/content/docs/sso/quickstart.mdxsrc/loaders/github-files-loader.tssrc/middleware.tssrc/pages/api/v1/users/support-hash.tssrc/pages/apis.astrosrc/pages/auth/callback.tssrc/pages/auth/login.tssrc/pages/auth/logout.tssrc/pages/auth/refresh.tssrc/pages/auth/session.tssrc/pages/sdks/java.astrosrc/styles/custom.csssrc/utils/auth/auth-config.tssrc/utils/auth/auth-cookies.tssrc/utils/auth/auth-redirects.tssrc/utils/auth/auth-tokens.tssrc/utils/auth/jwt.tssrc/utils/auth/pkce.tssrc/utils/auth/session-client.tssrc/utils/icon-map.tssrc/writing-standards/content-standards.mdsrc/writing-standards/document-templates.mdsrc/writing-standards/style-guide.mdsrc/writing-standards/technical-guidelines.mdsrc/writing-standards/workflows.mdtsconfig.json
| 1. **Setup**: Run `.specify/scripts/bash/check-prerequisites.sh --json` from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS list. | ||
| - All file paths must be absolute. | ||
| - For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot"). |
There was a problem hiding this comment.
Add explicit fail-fast handling for prerequisite parsing.
Line 36 requires JSON parsing but never defines what to do if the script fails or returns malformed/missing keys (FEATURE_DIR, AVAILABLE_DOCS). Add a hard-stop branch to avoid generating checklists with undefined context.
Proposed clarification patch
-1. **Setup**: Run `.specify/scripts/bash/check-prerequisites.sh --json` from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS list.
+1. **Setup**: Run `.specify/scripts/bash/check-prerequisites.sh --json` from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS list.
+ - If the command exits non-zero, JSON is invalid, or required keys are missing, STOP and report the error.
+ - Do not continue with checklist generation until prerequisites are valid.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/commands/speckit.checklist.md around lines 36 - 38, Add explicit
fail-fast handling after running `.specify/scripts/bash/check-prerequisites.sh
--json`: validate the JSON output and ensure the required keys FEATURE_DIR and
AVAILABLE_DOCS are present and non-empty; if the script fails, returns invalid
JSON, or those keys are missing, immediately exit with a non-zero status and
emit a clear error message indicating which check failed so downstream checklist
generation cannot proceed with undefined context.
| - Generate unique checklist filename: | ||
| - Use short, descriptive name based on domain (e.g., `ux.md`, `api.md`, `security.md`) | ||
| - Format: `[domain].md` | ||
| - If file exists, append to existing file | ||
| - Number items sequentially starting from CHK001 | ||
| - Each `/speckit.checklist` run creates a NEW file (never overwrites existing checklists) | ||
|
|
There was a problem hiding this comment.
Resolve conflicting file-creation rules (append vs new file).
Line 94 says to append if [domain].md exists, but Line 96 says each run must create a NEW file and never overwrite. These rules conflict and will produce inconsistent implementations.
Proposed clarification patch
- - Generate unique checklist filename:
- - Use short, descriptive name based on domain (e.g., `ux.md`, `api.md`, `security.md`)
- - Format: `[domain].md`
- - If file exists, append to existing file
+ - Generate unique checklist filename:
+ - Use short, descriptive name based on domain (e.g., `ux`, `api`, `security`)
+ - Format: `[domain]-[YYYYMMDD-HHMMSS].md`
+ - Never append to an existing file
...
-**Important**: Each `/speckit.checklist` command invocation creates a checklist file using short, descriptive names unless file already exists.
+**Important**: Each `/speckit.checklist` command invocation creates a new checklist file with a short, descriptive + unique name.Also applies to: 214-215
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/commands/speckit.checklist.md around lines 91 - 97, Resolve the
contradictory creation rules by making /speckit.checklist always create a NEW
file (never append); change the filename rule from plain "[domain].md" to a
unique name that preserves the domain prefix (e.g.,
"[domain]-YYYYMMDD-HHMMSS.md" or "[domain]-<uuid>.md"), remove the "If file
exists, append to existing file" statement, and keep "Number items sequentially
starting from CHK001" (per checklist file); update all occurrences of the old
append rule (including the other instance noted) and any code or docs that build
filenames for the /speckit.checklist command to use the timestamp/UUID scheme.
| SCALEKIT_AUTHORIZE_URL=https://auth.scalekit.com/oauth/authorize # Authorization endpoint used in /auth/login | ||
| SCALEKIT_TOKEN_URL=https://auth.scalekit.com/oauth/token # Token endpoint used in /auth/callback | ||
| SCALEKIT_REDIRECT_URI=http://localhost:4321/auth/callback # Must exactly match the redirect URI in Scalekit |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find env template files
echo "=== Finding env template files ==="
find . -name ".env*" -type f | head -20
# Show content of the mentioned files
echo -e "\n=== Content of project-docs/.env.template (lines 30-40) ==="
if [ -f "project-docs/.env.template" ]; then
sed -n '30,40p' "project-docs/.env.template"
else
echo "File not found"
fi
echo -e "\n=== Content of project-docs/.env.example (if exists) ==="
if [ -f "project-docs/.env.example" ]; then
cat "project-docs/.env.example" | head -40
else
echo "File not found"
fi
# Search for all auth endpoint references
echo -e "\n=== Auth domain references across repo ==="
rg -i 'auth\.scalekit\.(com|cloud)' --no-heading -nRepository: scalekit-inc/developer-docs
Length of output: 2398
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# More thorough search for env.example
echo "=== Searching for any .env.example files ==="
find . -name "*env.example*" -o -name "*env*.example*" 2>/dev/null || echo "No matches found"
# Search for auth.scalekit.cloud anywhere in repo
echo -e "\n=== Searching for auth.scalekit.cloud ==="
rg 'auth\.scalekit\.cloud' --no-heading -n || echo "No matches found"
# Check git status/diff for recent changes
echo -e "\n=== Recent env-related changes (git diff) ==="
git diff --name-only | grep -i env || echo "No env files changed"
# Show all occurrences of SCALEKIT_AUTHORIZE_URL and SCALEKIT_TOKEN_URL
echo -e "\n=== All SCALEKIT_AUTHORIZE_URL and SCALEKIT_TOKEN_URL references ==="
rg 'SCALEKIT_(AUTHORIZE|TOKEN)_URL' --no-heading -A1 -B1 | head -30Repository: scalekit-inc/developer-docs
Length of output: 2697
🏁 Script executed:
cat ./.env.exampleRepository: scalekit-inc/developer-docs
Length of output: 4383
Resolve the auth endpoint domain inconsistency between environment templates.
.env.example (root) uses auth.scalekit.cloud while project-docs/.env.template uses auth.scalekit.com. Since application code defaults to .com and documentation examples consistently reference .com, standardize both templates to use the same domain to prevent login failures for contributors using different configuration files.
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 33-33: [UnorderedKey] The SCALEKIT_AUTHORIZE_URL key should go before the SCALEKIT_CLIENT_ID key
(UnorderedKey)
[warning] 33-33: [ValueWithoutQuotes] This value needs to be surrounded in quotes
(ValueWithoutQuotes)
[warning] 34-34: [ValueWithoutQuotes] This value needs to be surrounded in quotes
(ValueWithoutQuotes)
[warning] 35-35: [UnorderedKey] The SCALEKIT_REDIRECT_URI key should go before the SCALEKIT_TOKEN_URL key
(UnorderedKey)
[warning] 35-35: [ValueWithoutQuotes] This value needs to be surrounded in quotes
(ValueWithoutQuotes)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@project-docs/.env.template` around lines 33 - 35, Update the root
.env.example to use the same auth.scalekit.com domain as the application and
docs to avoid mismatch; specifically ensure the SCALEKIT_AUTHORIZE_URL and
SCALEKIT_TOKEN_URL entries (and any SCALEKIT_REDIRECT_URI that references the
auth domain) in .env.example use auth.scalekit.com instead of
auth.scalekit.cloud so they match the values referenced in
project-docs/.env.template and the app defaults.
| "schema": { | ||
| "type": "string", | ||
| "enum": ["SCALEKIT", "ENVIRONMENT"] | ||
| }, | ||
| "description": "Filter permissions by type: ALL, SCALEKIT, or ENVIRONMENT, where SCALEKIT are predefined Scalekit permissions and ENVIRONMENT are custom permissions created in the environment, default is ALL", | ||
| "name": "type", | ||
| "in": "query" |
There was a problem hiding this comment.
type filter contract is inconsistent between enum and description.
Line 3453 allows only SCALEKIT and ENVIRONMENT, but Line 3455 describes ALL as a valid filter value. This can cause clients to send type=ALL and fail validation/codegen expectations. Please align the source spec generation so either ALL is in the enum, or the description says “omit type for all”.
Based on learnings: public/api/scalekit.scalar.json is a generated OpenAPI artifact, so this should be fixed in the generator/source templates rather than by directly editing this JSON.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@public/api/scalekit.scalar.json` around lines 3451 - 3457, The OpenAPI
parameter "type" (query parameter named "type" with schema enum
["SCALEKIT","ENVIRONMENT"]) has a mismatch with its description (which mentions
"ALL"); update the OpenAPI generator/template that emits the "type" query param
so the contract is consistent—either add "ALL" to the enum or change the
description to instruct clients to omit the parameter for "all" (and ensure the
generator sets the same default behavior in codegen metadata); locate the
template or source that builds the parameter named "type" in the Scalekit
permission endpoint and apply the fix so regenerated
public/api/scalekit.scalar.json is consistent.
…on switcher - Integrated the starlight-blog package into the project, enabling blog functionality with metrics for reading time and total words. - Updated the Astro configuration to include the starlight-blog plugin. - Added a new blog post titled "Building a Custom Organization Switcher," detailing how to create a custom organization switcher UI for enhanced user experiences in multi-tenant applications. - Updated sidebar configuration to exclude the blog from navigation and ensure a cleaner user experience. - Included a new author image for the blog post to enhance visual appeal.
- Updated the Astro configuration to include a prefix for the starlight-blog integration, enhancing the organization of blog content under the 'cookbooks' category. This change aims to improve navigation and content discoverability for users.
…the Developer Resources
14ea0d7 to
deb8a62
Compare
State: Proof of Concept
Adds a blog-style content surface to docs.scalekit.com dedicated to P.A.T.-driven technical stories (Problem → Angle → Teach). This space is for problem‑first, opinionated, and educational articles that sit alongside reference docs, helping developers discover real-world use cases, understand Scalekit’s unique point of view, and learn concrete implementation patterns without wading through product‑only documentation.
Example we current have
Summary by CodeRabbit
New Features
Documentation
Chores