Skip to content

feat: implement API for AI interactions and authentication: - #244

Open
yashdev9274 wants to merge 1 commit into
mainfrom
supercode-cli
Open

feat: implement API for AI interactions and authentication:#244
yashdev9274 wants to merge 1 commit into
mainfrom
supercode-cli

Conversation

@yashdev9274

@yashdev9274 yashdev9274 commented Jul 27, 2026

Copy link
Copy Markdown
Owner
  • Added core API functionality for AI chat and object generation with streaming responses.
  • Introduced authentication middleware to secure routes and manage user sessions.
  • Created health check and user management endpoints for improved service monitoring.
  • Established a structured environment configuration for better deployment practices.
  • Integrated token budget management to track usage and enforce limits on AI interactions.

Description

Please include a summary of the change and which issue is fixed.

Fixes #(issue)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor (no functional changes)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

  • bun test passes
  • bun run typecheck passes
  • bun run lint passes (if applicable)

Checklist:

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works

Summary by CodeRabbit

  • New Features

    • Launched API backend with GitHub authentication and user session management
    • Added AI chat streaming and structured JSON generation endpoints
    • Implemented daily token usage tracking and budget enforcement
    • Integrated support for multiple AI model providers
  • Chores

    • Released SDK client library for streamlined API integration

- Added core API functionality for AI chat and object generation with streaming responses.
- Introduced authentication middleware to secure routes and manage user sessions.
- Created health check and user management endpoints for improved service monitoring.
- Established a structured environment configuration for better deployment practices.
- Integrated token budget management to track usage and enforce limits on AI interactions.
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
supercli Ready Ready Preview, Comment Jul 27, 2026 11:38am
supercli-client Ready Ready Preview, Comment Jul 27, 2026 11:38am
supercli-docs Ready Ready Preview, Comment Jul 27, 2026 11:38am

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR adds a Bun/Hono API with authentication, AI provider routing, token budgets, usage tracking, streaming endpoints, and structured generation. It also introduces a typed SDK with Zod schemas and HTTP/NDJSON client methods.

Changes

API runtime and authentication

Layer / File(s) Summary
API runtime and application wiring
apps/api/.env.example, apps/api/package.json, apps/api/src/app.ts, apps/api/src/index.ts, apps/api/src/types.ts, apps/api/src/routes/health.ts, apps/api/tsconfig.json
Configures the Bun project, starts the Hono server, mounts routes and middleware, defines app types, and adds the health endpoint.
Authentication and session routes
apps/api/src/lib/auth.ts, apps/api/src/lib/prisma.ts, apps/api/src/middleware/auth.ts, apps/api/src/routes/auth.ts
Adds Better-Auth with Prisma/PostgreSQL, bearer-session authentication, /auth/me, and sign-out handling.

AI provider flow

Layer / File(s) Summary
Provider routing and usage enforcement
apps/api/src/providers/index.ts, apps/api/src/lib/pricing.ts, apps/api/src/lib/token-budget.ts, apps/api/src/lib/track-usage.ts
Routes provider requests, computes token costs, enforces daily limits, streams model output, and records usage events.
AI API endpoints
apps/api/src/routes/ai.ts
Adds authenticated /ai/chat NDJSON streaming and /ai/generate-object JSON endpoints with request validation and error handling.

SDK

Layer / File(s) Summary
SDK contracts and public exports
packages/sdk/types.ts, packages/sdk/schemas.ts, packages/sdk/index.ts, packages/sdk/tsconfig.json, packages/sdk/package.json
Defines and exports SDK types and Zod schemas for requests, responses, providers, usage, and stream chunks.
SDK HTTP and streaming client
packages/sdk/client.ts
Adds authenticated health, user, chat, chat-stream, and object-generation methods with validation and NDJSON parsing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Poem

A rabbit hops through streams of text,
With tokens counted, limits checked best.
Auth guards stand by every door,
While SDK schemas validate more.
“Bun-powered carrots!” cheers the hare.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: new API endpoints for AI interactions and authentication.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch supercode-cli

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 19

🧹 Nitpick comments (2)
apps/api/src/providers/index.ts (1)

61-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate pricing table/logic — already diverged from lib/pricing.ts.

This local MODEL_PRICING/computeCost duplicates lib/pricing.ts and has already drifted: missing cacheWrite and the "nvidia/minimax-m3" zero-price entry. Import from lib/pricing.ts instead to avoid future price drift.

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

In `@apps/api/src/providers/index.ts` around lines 61 - 77, Remove the local
MODEL_PRICING table and computeCost implementation in the provider module, and
import and reuse the existing pricing helper from lib/pricing.ts. Update callers
to use that shared symbol so cache-write pricing and the "nvidia/minimax-m3"
entry remain consistent.
apps/api/src/routes/ai.ts (1)

10-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated messages schema between the two endpoints.

The same message-array shape is repeated verbatim in chatBodySchema and generateObjectBodySchema. Extract a shared messageSchema to avoid drift between the two.

+const messageSchema = z.object({
+  role: z.enum(["system", "user", "assistant"]),
+  content: z.string(),
+})
+
 const chatBodySchema = z.object({
-  messages: z.array(z.object({
-    role: z.enum(["system", "user", "assistant"]),
-    content: z.string(),
-  })),
+  messages: z.array(messageSchema),
   ...
 })
 
 const generateObjectBodySchema = z.object({
-  messages: z.array(z.object({
-    role: z.enum(["system", "user", "assistant"]),
-    content: z.string(),
-  })),
+  messages: z.array(messageSchema),
   ...
 })

Also applies to: 27-38

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

In `@apps/api/src/routes/ai.ts` around lines 10 - 25, Extract the repeated message
object definition into a shared messageSchema near chatBodySchema, then reuse it
for the messages arrays in both chatBodySchema and generateObjectBodySchema.
Preserve the existing role enum and content validation unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/package.json`:
- Line 10: Replace the no-op "lint" script in package.json with a command that
runs the project's configured linter against the API source files, or make the
script exit nonzero until linting is configured. Ensure bun run lint cannot
succeed without performing real validation.
- Around line 8-9: Update the package.json start script to execute the
dist/index.js artifact generated by the build script, instead of launching
src/index.ts. Keep the existing build command unchanged so production starts
from the compiled output.

In `@apps/api/src/app.ts`:
- Around line 15-17: Update the bodyLimit configuration in apps/api/src/app.ts
lines 15-17 to read and parse SUPERCODE_JSON_BODY_LIMIT, using the parsed value
as maxSize instead of the hardcoded limit. Keep SUPERCODE_JSON_BODY_LIMIT in
apps/api/.env.example line 3 because the runtime configuration will consume it.
- Around line 24-26: Update the app route registration in the app initialization
flow to mount the Better Auth GET/POST wildcard handler from the auth
configuration before authRoute, using the configured /api/auth base path so
GitHub sign-in and callback requests are handled while preserving the existing
custom auth routes.

In `@apps/api/src/lib/auth.ts`:
- Line 18: Update the GitHub OAuth configuration in the auth setup so the
production redirectURI uses serverUrl, matching the Better-Auth baseURL, rather
than clientUrl; preserve the existing callback path and non-production behavior.
- Around line 16-17: Validate GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET before
registering the GitHub provider instead of relying on type assertions. When
GitHub is optional, omit the provider if either value is missing; when required,
fail fast with a clear configuration error, ensuring no provider is registered
with undefined credentials.

In `@apps/api/src/lib/pricing.ts`:
- Around line 1-37: The NVIDIA routed model key is “minimaxai/minimax-m3”, but
MODEL_PRICING only recognizes “minimax-m3”, causing zero-cost lookups. Update
the pricing lookup or shared pricing definitions used by routeToProvider so the
routed NVIDIA key resolves to the Minimax pricing values, while preserving
existing model pricing behavior.

In `@apps/api/src/lib/token-budget.ts`:
- Around line 6-28: Update the UsageEvent query in checkDailyTokenBudget to
filter by the provided userId in addition to the current-day createdAt range, so
all returned totals are scoped to that user. Preserve the existing date
boundaries and token field selection.

In `@apps/api/src/lib/track-usage.ts`:
- Around line 3-11: Add an explicit return type annotation to the exported
recordUsage function, using the actual value it returns (or Promise<void> if it
performs side effects without returning a value). Keep the existing parameter
contract and implementation behavior unchanged.

In `@apps/api/src/middleware/auth.ts`:
- Around line 12-26: Restrict the try/catch in the authentication middleware to
the prisma.session.findUnique call so only session lookup failures return 401.
Move await next() after the catch block while preserving the existing session
validation and c.set("user", ...) / c.set("session", ...) behavior, allowing
downstream handler exceptions to propagate.

In `@apps/api/src/providers/index.ts`:
- Around line 145-160: Prevent SSRF in the provider-selection branch for
“nvidia”, “mergedev”, “orcarouter”, and “concentrateai” by removing
client-controlled opts.baseUrl or validating it against a small
server-controlled allow-list of approved provider endpoints before passing it to
createOpenAICompatible. Preserve the existing environment/default URL fallback
and reject any unapproved scheme or host.
- Around line 10-11: Remove the local DAILY_TOKEN_LIMIT/DAILY_QUERY_LIMIT budget
logic and reuse lib/token-budget.ts’s checkDailyTokenBudget. Thread the
authenticated userId through createStreamText and its callers, passing it to
both the budget check and the onFinish usage-event persistence so accounting is
per user. Use the consolidated helper’s atomic/concurrency-safe path rather than
retaining the local check-then-act implementation.
- Around line 166-168: Update the option defaults in the provider configuration
to use nullish fallback semantics instead of || for opts.maxTokens,
opts.temperature, and opts.topP, preserving explicitly supplied 0 values while
still applying defaults when values are null or undefined.
- Around line 133-160: Update the provider switch so the google case passes
opts.apiKey to the Google provider factory, and the minimax case uses the
createMinimax factory with opts.apiKey before creating aiModel. Ensure
opts.apiKey is no longer silently ignored for these providers, while preserving
the existing model-selection behavior.
- Around line 170-187: Replace the inline Prisma usage-event creation in the
onFinish callback with the existing recordUsage helper from lib/track-usage.ts.
Pass the completed usage data and measured request duration so durationMs
reflects actual latency, while preserving the current provider, model, token,
and cost values.

In `@apps/api/src/routes/ai.ts`:
- Around line 27-38: Update the /ai/generate-object handler and its provider
flow to use the AI SDK structured generation path (generateObject or
streamObject) with an explicit output schema, rather than plain streamText. Pass
the schema through the provider invocation, honor
generateObjectBodySchema.responseFormat, and return the validated structured
object so the response cannot contain raw, unvalidated model text.
- Around line 56-101: Add the third onError callback to the Hono stream call in
the streaming response around result.textStream. Handle exceptions from
iteration or s.write by writing a JSON NDJSON error chunk to the client before
the stream closes, while preserving the existing text and finish chunk behavior;
keep the outer catch for errors occurring before streaming begins.

In `@packages/sdk/client.ts`:
- Around line 84-98: Replace the swallowed parse/validation errors in the
stream-decoding loop with a contextual error that is thrown to the caller,
covering malformed JSON, schema mismatches, and invalid finish chunks. Apply
this to both packages/sdk/client.ts lines 84-98 and lines 132-140 so the
corresponding streaming paths, including chatStream(), never return partial
results while silently omitting invalid chunks.
- Around line 158-159: Define and export a generateObjectResponseSchema for
validating the object-generation response, then update the response handling
around res.json() to return generateObjectResponseSchema.parse(data) instead of
constructing an unvalidated object. Preserve the existing GenerateObjectResponse
shape while rejecting empty or non-string object values.

---

Nitpick comments:
In `@apps/api/src/providers/index.ts`:
- Around line 61-77: Remove the local MODEL_PRICING table and computeCost
implementation in the provider module, and import and reuse the existing pricing
helper from lib/pricing.ts. Update callers to use that shared symbol so
cache-write pricing and the "nvidia/minimax-m3" entry remain consistent.

In `@apps/api/src/routes/ai.ts`:
- Around line 10-25: Extract the repeated message object definition into a
shared messageSchema near chatBodySchema, then reuse it for the messages arrays
in both chatBodySchema and generateObjectBodySchema. Preserve the existing role
enum and content validation unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: edbba77e-2d93-4aa8-abd4-30106e11ea78

📥 Commits

Reviewing files that changed from the base of the PR and between 92469ae and 5b248e3.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • apps/api/.env.example
  • apps/api/package.json
  • apps/api/src/app.ts
  • apps/api/src/index.ts
  • apps/api/src/lib/auth.ts
  • apps/api/src/lib/pricing.ts
  • apps/api/src/lib/prisma.ts
  • apps/api/src/lib/token-budget.ts
  • apps/api/src/lib/track-usage.ts
  • apps/api/src/middleware/auth.ts
  • apps/api/src/providers/index.ts
  • apps/api/src/routes/ai.ts
  • apps/api/src/routes/auth.ts
  • apps/api/src/routes/health.ts
  • apps/api/src/types.ts
  • apps/api/tsconfig.json
  • packages/sdk/client.ts
  • packages/sdk/index.ts
  • packages/sdk/package.json
  • packages/sdk/schemas.ts
  • packages/sdk/tsconfig.json
  • packages/sdk/types.ts

Comment thread apps/api/package.json
Comment on lines +8 to +9
"build": "bun build --target bun --outdir dist src/index.ts",
"start": "bun src/index.ts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Run the artifact produced by build.

build emits dist/index.js, but start runs src/index.ts. This means production does not use the built artifact and deployments containing only dist cannot start.

Suggested fix
-    "start": "bun src/index.ts",
+    "start": "bun dist/index.js",
📝 Committable suggestion

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

Suggested change
"build": "bun build --target bun --outdir dist src/index.ts",
"start": "bun src/index.ts",
"build": "bun build --target bun --outdir dist src/index.ts",
"start": "bun dist/index.js",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/package.json` around lines 8 - 9, Update the package.json start
script to execute the dist/index.js artifact generated by the build script,
instead of launching src/index.ts. Keep the existing build command unchanged so
production starts from the compiled output.

Comment thread apps/api/package.json
"dev": "bun --watch src/index.ts",
"build": "bun build --target bun --outdir dist src/index.ts",
"start": "bun src/index.ts",
"lint": "echo 'api lint scaffold pending'",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Replace the no-op lint script.

bun run lint currently succeeds without checking any source files, so the PR’s lint validation provides no protection against lint regressions. Wire an actual linter or fail until one is configured.

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

In `@apps/api/package.json` at line 10, Replace the no-op "lint" script in
package.json with a command that runs the project's configured linter against
the API source files, or make the script exit nonzero until linting is
configured. Ensure bun run lint cannot succeed without performing real
validation.

Comment thread apps/api/src/app.ts
Comment on lines +15 to +17
app.use("*", bodyLimit({
maxSize: 10 * 1024 * 1024,
}))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Connect the documented body-limit configuration to runtime behavior.

The environment variable is declared but ignored by the application’s hardcoded limit.

  • apps/api/src/app.ts#L15-L17: parse and apply SUPERCODE_JSON_BODY_LIMIT.
  • apps/api/.env.example#L3-L3: keep the variable only if the application actually consumes it.
📍 Affects 2 files
  • apps/api/src/app.ts#L15-L17 (this comment)
  • apps/api/.env.example#L3-L3
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/app.ts` around lines 15 - 17, Update the bodyLimit configuration
in apps/api/src/app.ts lines 15-17 to read and parse SUPERCODE_JSON_BODY_LIMIT,
using the parsed value as maxSize instead of the hardcoded limit. Keep
SUPERCODE_JSON_BODY_LIMIT in apps/api/.env.example line 3 because the runtime
configuration will consume it.

Comment thread apps/api/src/app.ts
Comment on lines +24 to +26
app.route("/", healthRoute)
app.route("/", authRoute)
app.route("/", aiRoute)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- files ---\n'
git ls-files | rg '(^|/)(app|auth).*\.(ts|tsx|js)$|auth' || true

printf '\n--- app.ts outline ---\n'
ast-grep outline apps/api/src/app.ts --view expanded || true

printf '\n--- app.ts ---\n'
cat -n apps/api/src/app.ts

printf '\n--- auth.ts outline ---\n'
ast-grep outline apps/api/src/lib/auth.ts --view expanded || true

printf '\n--- auth.ts ---\n'
cat -n apps/api/src/lib/auth.ts

printf '\n--- route files matching auth/health/ai ---\n'
git ls-files apps/api/src | rg '(^|/)(routes|lib|index|auth|health|ai)\.(ts|js)$' || true

printf '\n--- route usages ---\n'
rg -n "healthRoute|authRoute|aiRoute|basePath|betterAuth|auth/me|sign-out|callback/github|`@auth`|/api/auth|toAuth" apps/api/src -S || true

Repository: yashdev9274/supercli

Length of output: 249


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- files ---'
git ls-files | rg '(^|/)(app|auth).*\.(ts|tsx|js)$|auth' || true

printf '%s\n' '\n--- app.ts outline ---'
ast-grep outline apps/api/src/app.ts --view expanded || true

printf '%s\n' '\n--- app.ts ---'
cat -n apps/api/src/app.ts

printf '%s\n' '\n--- auth.ts outline ---'
ast-grep outline apps/api/src/lib/auth.ts --view expanded || true

printf '%s\n' '\n--- auth.ts ---'
cat -n apps/api/src/lib/auth.ts

printf '%s\n' '\n--- route files matching auth/health/ai ---'
git ls-files apps/api/src | rg '(^|/)(routes|lib|index|auth|health|ai)\.(ts|js)$' || true

printf '%s\n' '\n--- route usages ---'
rg -n "healthRoute|authRoute|aiRoute|basePath|betterAuth|auth/me|sign-out|callback/github|`@auth`|/api/auth|toAuth" apps/api/src -S || true

Repository: yashdev9274/supercli

Length of output: 22917


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- apps/api/src/routes/auth.ts ---'
cat -n apps/api/src/routes/auth.ts

printf '%s\n' '\n--- apps/api/src/middleware/auth.ts ---'
cat -n apps/api/src/middleware/auth.ts

printf '%s\n' '\n--- apps/api package.json/auth deps ---'
if [ -f apps/api/package.json ]; then cat -n apps/api/package.json | sed -n '1,220p'; fi

printf '%s\n' '\n--- root/package lock snippets for hono/better-auth ---'
if [ -f package.json ]; then rg -n '"hono"|"better-auth"' package.json apps packages -S || true; fi

Repository: yashdev9274/supercli

Length of output: 10194


🌐 Web query:

better-auth Node.js Hono getHandler postHandler basePath toAuth

💡 Result:

In Better Auth, the handler function acts as the unified endpoint for all authentication-related requests (GET and POST) [1][2]. When integrating with Hono, you mount this handler to a specific path using Hono's.on method [3][4]. Mounting the Handler The standard approach is to use a wildcard path to ensure all authentication sub-routes are captured [2][4]. It is recommended to use the single asterisk () wildcard rather than double, as the latter can cause routing conflicts in some Hono configurations [5]. Example implementation: const app = new Hono; app.on(["POST", "GET"], "/api/auth/", (c) => { return auth.handler(c.req.raw); }); Configuration and basePath The path you provide in app.on must align with the basePath defined in your Better Auth configuration [6]. By default, Better Auth uses /api/auth as its base path [6]. If you change the basePath in your auth options, you must update the mounting path in your Hono application to match [6]. Key Considerations 1. CORS Middleware: If your frontend is on a different domain, register the Hono CORS middleware before the auth route to ensure preflight requests (OPTIONS) are handled correctly [2][4]. 2. Session Middleware: You can define a global Hono middleware that calls auth.api.getSession to populate the Hono context (c.set) with user and session data, making it available to other routes [2][4]. 3. Client Configuration: When using the Hono RPC client (@hono/client) from a different domain, you must set credentials: "include" in the client's configuration to ensure cookies are sent with requests [2][4]. Note: The terms getHandler, postHandler, and toAuth are not standard, primary methods for Better Auth/Hono integration; the unified auth.handler method is the designated, authoritative way to process requests [1][2]. For frameworks like Next.js or generic Node.js pages, different utilities such as toNextJsHandler or toNodeHandler are used instead [7].

Citations:


Mount the Better Auth handler.

apps/api/src/lib/auth.ts configures Better Auth with basePath: "/api/auth", but apps/api/src/app.ts only mounts the custom /auth/me and /auth/sign-out routes. GitHub sign-in and /api/auth/callback/github need the Better Auth GET/POST handler mounted as a wildcard under the same base paths before the custom auth handlers.

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

In `@apps/api/src/app.ts` around lines 24 - 26, Update the app route registration
in the app initialization flow to mount the Better Auth GET/POST wildcard
handler from the auth configuration before authRoute, using the configured
/api/auth base path so GitHub sign-in and callback requests are handled while
preserving the existing custom auth routes.

Comment thread apps/api/src/lib/auth.ts
Comment on lines +16 to +17
clientId: process.env.GITHUB_CLIENT_ID as string,
clientSecret: process.env.GITHUB_CLIENT_SECRET as string,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(auth\.ts|\.env\.example|package\.json|pnpm-lock\.yaml)$' || true

echo "== auth outline =="
if [ -f apps/api/src/lib/auth.ts ]; then
  ast-grep outline apps/api/src/lib/auth.ts || true
  wc -l apps/api/src/lib/auth.ts
  sed -n '1,220p' apps/api/src/lib/auth.ts | cat -n
fi

echo "== env references =="
rg -n "GITHUB_CLIENT_ID|GITHUB_CLIENT_SECRET|github|GITHUB|CLIENT_URL|SERVER_URL|better-auth" apps/api .env.example .env* -S 2>/dev/null || true

Repository: yashdev9274/supercli

Length of output: 2899


🌐 Web query:

Better Auth OAuth github redirectURI baseURL SERVER_URL CLIENT_URL environment

💡 Result:

In Better Auth, managing OAuth redirect URIs involves correctly configuring your environment and authentication settings to bridge the gap between your server (where the auth logic runs) and your client (where the user interacts with your application) [1]. Key Configuration Concepts baseURL: This is the root URL of your authentication server [2]. You should always set this explicitly in your Better Auth configuration or via the environment variable BETTER_AUTH_URL [3]. Relying on automatic request inference is not recommended for production environments [3]. redirectURI: By default, Better Auth constructs the redirect URI using the baseURL and a standard callback path (e.g., /api/auth/callback/github) [4][5]. You can override this by providing a specific redirectURI in the provider configuration [2][3], but it must match exactly what you have registered in your GitHub OAuth App settings. Handling Client vs. Server URLs A common issue occurs when your server runs on one port (e.g., 8787) and your client on another (e.g., 3000) [1]. Better Auth might default to the server's URL, leading to redirect mismatches [1]. To resolve this: 1. Trusted Origins: Add your client's URL to the trustedOrigins array in your auth configuration to allow cross-origin communication [1]. export const auth = betterAuth({ baseURL: "http://your-server-url", trustedOrigins: ["http://localhost:3000"], }); 2. Callback URL Parameter: When initiating the sign-in process on the client, pass the callbackURL parameter to specify where the user should be sent after the OAuth flow completes [1]. await authClient.signIn.social({ provider: "github", callbackURL: "http://localhost:3000/dashboard", }); 3. OAuth Proxy Plugin: For complex deployments (e.g., preview environments or multi-host setups), use the OAuth Proxy plugin [6]. This allows you to register only your production callback URL with GitHub while the plugin handles routing requests from other environments through your production server [6]. Always ensure that the redirect URL registered in your GitHub Developer Settings matches the callback endpoint constructed by Better Auth [7][6]. If you are using the Generic OAuth plugin, remember that the redirectURI must include the:providerId placeholder [5][8].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== root env example =="
if [ -f .env.example ]; then
  cat -n .env.example | sed -n '1,180p'
fi

echo "== apps/api env example =="
if [ -f apps/api/.env.example ]; then
  cat -n apps/api/.env.example | sed -n '1,180p'
fi

echo "== runtime probe process.env assertion behavior =="
node - <<'JS'
const env = { GITHUB_CLIENT_ID: undefined, GITHUB_CLIENT_SECRET: undefined }

function register(input) {
  return {
    clientId: input.GITHUB_CLIENT_ID,
    clientSecret: input.GITHUB_CLIENT_SECRET,
    authEnvIsNull: input.GITHUB_CLIENT_ID === null,
    authEnvIsUndefined: input.GITHUB_CLIENT_ID === undefined,
    authEnvEmptyString: input.GITHUB_CLIENT_ID === "",
  }
}
console.log(JSON.stringify(register(env), null, 2))
JS

echo "== better-auth package metadata/source availability =="
python3 - <<'PY'
import json
from pathlib import Path
root = Path("apps/api")
for p in ["package.json", "pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lockb"]:
    path = root / p
    print(f"{path}: exists={path.exists()}")
PY

Repository: yashdev9274/supercli

Length of output: 1958


Validate GitHub credentials before registering the provider.

as string only suppresses TypeScript errors; it does not convert missing environment variables into strings. With apps/api/.env.example, GitHub is configured with undefined credentials, so the provider can register with no clientId/clientSecret. Omit the provider when GitHub is optional, or fail fast with a clear configuration error when it is required.

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

In `@apps/api/src/lib/auth.ts` around lines 16 - 17, Validate GITHUB_CLIENT_ID and
GITHUB_CLIENT_SECRET before registering the GitHub provider instead of relying
on type assertions. When GitHub is optional, omit the provider if either value
is missing; when required, fail fast with a clear configuration error, ensuring
no provider is registered with undefined credentials.

Comment on lines +170 to +187
onFinish: async ({ usage }) => {
const cost = computeCost(aiModel, usage.inputTokens ?? 0, usage.outputTokens ?? 0, 0)
try {
await prisma.usageEvent.create({
data: {
provider: aiProvider,
model: aiModel,
inputTokens: usage.inputTokens ?? 0,
outputTokens: usage.outputTokens ?? 0,
cachedInputTokens: 0,
costUsd: cost,
durationMs: 0,
},
})
} catch (e) {
console.error("[track-usage] Failed to record usage:", e)
}
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Usage recording duplicates lib/track-usage.ts and hardcodes durationMs: 0.

This onFinish block reimplements recordUsage inline instead of calling it, and durationMs is always 0 rather than measured — usage records will never carry real latency data.

+  const startedAt = Date.now()
   const result = streamText({
     ...
     onFinish: async ({ usage }) => {
       const cost = computeCost(aiModel, usage.inputTokens ?? 0, usage.outputTokens ?? 0, 0)
-      try {
-        await prisma.usageEvent.create({
-          data: {
-            provider: aiProvider,
-            model: aiModel,
-            inputTokens: usage.inputTokens ?? 0,
-            outputTokens: usage.outputTokens ?? 0,
-            cachedInputTokens: 0,
-            costUsd: cost,
-            durationMs: 0,
-          },
-        })
-      } catch (e) {
-        console.error("[track-usage] Failed to record usage:", e)
-      }
+      await recordUsage({
+        provider: aiProvider,
+        model: aiModel,
+        inputTokens: usage.inputTokens ?? 0,
+        outputTokens: usage.outputTokens ?? 0,
+        costUsd: cost,
+        durationMs: Date.now() - startedAt,
+      })
     },
   })
📝 Committable suggestion

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

Suggested change
onFinish: async ({ usage }) => {
const cost = computeCost(aiModel, usage.inputTokens ?? 0, usage.outputTokens ?? 0, 0)
try {
await prisma.usageEvent.create({
data: {
provider: aiProvider,
model: aiModel,
inputTokens: usage.inputTokens ?? 0,
outputTokens: usage.outputTokens ?? 0,
cachedInputTokens: 0,
costUsd: cost,
durationMs: 0,
},
})
} catch (e) {
console.error("[track-usage] Failed to record usage:", e)
}
},
onFinish: async ({ usage }) => {
const cost = computeCost(aiModel, usage.inputTokens ?? 0, usage.outputTokens ?? 0, 0)
await recordUsage({
provider: aiProvider,
model: aiModel,
inputTokens: usage.inputTokens ?? 0,
outputTokens: usage.outputTokens ?? 0,
costUsd: cost,
durationMs: Date.now() - startedAt,
})
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/providers/index.ts` around lines 170 - 187, Replace the inline
Prisma usage-event creation in the onFinish callback with the existing
recordUsage helper from lib/track-usage.ts. Pass the completed usage data and
measured request duration so durationMs reflects actual latency, while
preserving the current provider, model, token, and cost values.

Comment thread apps/api/src/routes/ai.ts
Comment on lines +27 to +38
const generateObjectBodySchema = z.object({
messages: z.array(z.object({
role: z.enum(["system", "user", "assistant"]),
content: z.string(),
})),
provider: z.string().optional().default("google"),
model: z.string().optional().default("gemini-3-flash-preview"),
apiKey: z.string().optional(),
baseUrl: z.string().optional(),
temperature: z.number().optional(),
responseFormat: z.enum(["json", "text"]).optional().default("json"),
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## Locate file and package context"
git ls-files | rg '(^|/)apps/api/src/routes/ai\.ts$|(^|/)package\.json$|(^|/)pnpm-lock\.yaml$|(^|/)yarn\.lock$|(^|/)package-lock\.json$' || true

echo
echo "## Inspect apps/api/src/routes/ai.ts"
if [ -f apps/api/src/routes/ai.ts ]; then
  wc -l apps/api/src/routes/ai.ts
  sed -n '1,170p' apps/api/src/routes/ai.ts | cat -n
fi

echo
echo "## Search for ai route usage and createStreamText generate object usages"
rg -n "generate-object|generateObject|streamObject|createStreamText|responseFormat|/ai" apps/api/src -S || true

Repository: yashdev9274/supercli

Length of output: 7192


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## apps/api/src/providers/index.ts relevant implementation"
sed -n '1,150p' apps/api/src/providers/index.ts | cat -n

echo
echo "## package versions for ai sdk and zod in relevant package manifests"
python3 - <<'PY'
import json, pathlib
for p in [pathlib.Path("package.json"), pathlib.Path("apps/api/package.json")]:
    if p.exists():
        print(f"--- {p} ---")
        data=json.loads(p.read_text())
        deps={}
        for section in ("dependencies","devDependencies","peerDependencies"):
            if section in data:
                deps.update(data[section])
        for name in ("ai","`@ai-sdk/google`","`@ai-sdk/provider`","dai-sdk","zod"):
            if name in deps:
                print(f"{name}: {deps[name]}")
PY

echo
echo "## References to responseFormat, generate-object JSON parsing downstream"
rg -n "responseFormat|generate-object|\"object\"|ai/generate-object|createStreamText" . -S --glob '!node_modules' --glob '!dist' --glob '!build' || true

echo
echo "## Behavioral probe: request body and implementation fields"
python3 - <<'PY'
from pathlib import Path
import re

src = Path("apps/api/src/routes/ai.ts")
text = src.read_text()

m = re.search(r'const generateObjectBodySchema = z\.object\((.*?)\n\)\n', text, re.S)
schema = m.group(0) if m else ""
print("has responseFormat field:", "responseFormat" in schema)
print("responseFormat is consumed by createStreamText call:", bool(re.search(r'generateObjectBodySchema[\s\S]*?createStreamText\(\{[\s\S]*?responseFormat', text)))

call = re.search(r'createStreamText\(\{(?P<body>.*?)(?=\}\),\s*async|\}\s*\)\.post)', text, re.S)
prompt = re.search(r'systemPrompt:\s*"(.*?)"', text)
for i in range(105,135):
    line = text.splitlines()[i-1]
    if any(s in line for s in ["let responseFormat", "const responseFormat", "responseFormat:"]):
        print(f"line {i}: responseFormat reference: {line.strip()}")
if prompt:
    print("explicit system prompt for generate-object:", prompt.group(1))
PY

Repository: yashdev9274/supercli

Length of output: 13539


Use a schema-backed object generation path for /ai/generate-object.

responseFormat is validated but ignored, and the endpoint returns c.json({ object: result.text }) using the plain streamText flow, so the object payload is the raw model response and can be non-JSON or drift from the expected output shape. Use AI SDK generateObject/streamObject with a schema and pass that schema through the provider path so structured requests actually validate the model output.

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

In `@apps/api/src/routes/ai.ts` around lines 27 - 38, Update the
/ai/generate-object handler and its provider flow to use the AI SDK structured
generation path (generateObject or streamObject) with an explicit output schema,
rather than plain streamText. Pass the schema through the provider invocation,
honor generateObjectBodySchema.responseFormat, and return the validated
structured object so the response cannot contain raw, unvalidated model text.

Comment thread apps/api/src/routes/ai.ts
Comment on lines +56 to +101
try {
const result = await createStreamText({
provider: body.provider,
model: body.model,
apiKey: body.apiKey,
baseUrl: body.baseUrl,
maxTokens: body.maxTokens,
temperature: body.temperature,
topP: body.topP,
messages: coreMessages,
systemPrompt,
conversationId: body.conversationId,
})

c.header("Content-Type", "application/x-ndjson")
c.header("Cache-Control", "no-cache")
c.header("Connection", "keep-alive")

return stream(c, async (s) => {
for await (const delta of result.textStream) {
const chunk = JSON.stringify({ type: "text-delta", textDelta: delta }) + "\n"
await s.write(chunk)
}

const finishReason = await result.finishReason
const usage = await result.usage

const finishChunk = JSON.stringify({
type: "finish",
finishReason,
usage: {
promptTokens: usage.inputTokens ?? 0,
completionTokens: usage.outputTokens ?? 0,
totalTokens: (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0),
},
}) + "\n"
await s.write(finishChunk)
})
} catch (error: any) {
const errorMessage = error?.message || "Unknown error"
if (errorMessage.includes("Daily token limit")) {
return c.json({ error: errorMessage }, 429)
}
console.error("[AI Chat Error]", error)
return c.json({ error: errorMessage }, 500)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does hono/streaming's stream() helper suppress errors thrown inside the callback when no onError handler is passed, in hono 4.7?

💡 Result:

In Hono 4.7, the stream helper does not suppress errors thrown inside the callback function, regardless of whether an onError handler is provided [1][2]. When an error is thrown within the callback: 1. If an onError handler is provided as the third argument, Hono executes it to allow for custom error logic (such as writing an error message to the stream) [1][2][3]. 2. If an onError handler is not provided, Hono catches the error and outputs it using console.error [1][2]. It is important to note that when an error occurs inside the streaming callback, the Hono app-level onError handler will not be triggered [1][4]. This is because the response has already been sent once the streaming begins, making it impossible to overwrite the response with an error page or custom response at that stage [1][5]. The stream will be automatically closed after the callback (or the error handler) finishes execution [1][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package hono versions =="
if [ -f package.json ]; then jq -r '.dependencies.hono?, .devDependencies.hono?' package.json; else true; fi
fd -a 'package.json$|pnpm-lock.yaml$|yarn.lock$|package-lock.json$' . | sed 's#^\./##' | head -40

echo "== locate ai.ts =="
fd 'ai\.ts$' apps src 2>/dev/null || fd 'ai\.ts$' .

echo "== inspect apps/api/src/routes/ai.ts relevant section =="
cat -n apps/api/src/routes/ai.ts | sed -n '1,150p'

echo "== read-only verifier: stream helper behavior from source if available =="
python3 - <<'PY'
from pathlib import Path
roots = [Path('node_modules/hono'), Path('/usr/local/lib/node_modules/hono'), Path('apps/api/node_modules/hono')]
for root in roots:
    p = root / 'dist' / 'cjs' / 'helper' / 'streaming' / 'stream.cjs'
    if not p.exists():
        p = root / 'dist' / 'cjs' / 'helper' / 'streaming' / 'stream.js'
    if not p.exists():
        continue
    print(f"FOUND {p}")
    text = p.read_text(errors='ignore')
    for needle in ['onError', 'c.res.body.close', 'console.error', 'callback']:
        print(f'--- {needle} ---')
        idx = text.find(needle)
        print(text[max(0, idx-800): idx+1200] if idx != -1 else '<not found>')
PY

Repository: yashdev9274/supercli

Length of output: 6757


🌐 Web query:

"hono" "stream" "onError" "callback" "console.error" "close"

💡 Result:

In Hono, the stream and streamSSE helpers automatically close the response stream after their callback function completes [1][2][3]. ### Error Handling The streaming helpers accept an optional third argument, which is an onError callback function [1][2][4]. * If an error occurs within the streaming callback and an onError handler is provided, that handler will execute [1][2]. * If no onError handler is specified, the error is caught and output to console.error by default [1][4]. * Important: The onError handler for the streaming helper is specific to the stream itself. It is distinct from the global app.onError hook [1][5]. Because the stream has already begun when the streaming callback executes, errors occurring during streaming cannot be caught by app.onError to overwrite the initial response [1]. ### Stream Closure * Automatic Closure: The underlying stream is automatically closed by the helper after the streaming callback (and the onError callback, if provided) finishes execution [1][2][3]. * Manual Closure: You can manually close the stream at any time by calling stream.close() within your code [2][6]. * Behavior with Exceptions: If the streaming callback throws an error, the streaming helper ensures the stream is closed (typically via a finally block in its internal implementation) [7][3]. Example usage with error handling: typescript app.get('/stream', (c) => { return stream( c, async (stream) => { await stream.write('Writing data...') // If this throws, execution moves to the onError callback throw new Error('Stream failed') }, (err, stream) => { console.error('Caught error:', err) stream.writeln('An error occurred!') // stream.close() is called automatically after this } ) }) [1] https://hono.dev/docs/helpers/streaming [2] https://mintlify.wiki/honojs/hono/api/helpers/streaming [7] honojs/hono#2164 [3] honojs/hono#2993 [5] https://hono.dev/docs/api/hono [4] https://github.com/MagicAPI/ai-gateway-ts/blob/main/HONO.md [6] honojs/hono#2050

Citations:


Handle mid-stream exceptions inside the Hono streaming callback.

stream(c, cb) is called without the third onError argument, so errors thrown after headers have been sent during result.textStream iteration or s.write() are not returned to the client, are not reachable by the surrounding try/catch, and only close with the default console.error. Add an onError handler that writes an error chunk before the stream closes.

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

In `@apps/api/src/routes/ai.ts` around lines 56 - 101, Add the third onError
callback to the Hono stream call in the streaming response around
result.textStream. Handle exceptions from iteration or s.write by writing a JSON
NDJSON error chunk to the client before the stream closes, while preserving the
existing text and finish chunk behavior; keep the outer catch for errors
occurring before streaming begins.

Comment thread packages/sdk/client.ts
Comment on lines +84 to +98
for (const line of lines) {
if (!line.trim()) continue
try {
const chunk = JSON.parse(line)
const parsed = streamChunkSchema.parse(chunk)

if (parsed.type === "text-delta") {
text += parsed.textDelta
} else if (parsed.type === "finish") {
finishReason = parsed.finishReason
usage = parsed.usage
}
} catch {
// Skip invalid JSON lines
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not silently discard malformed stream chunks.

A malformed JSON line, schema mismatch, or invalid finish chunk is ignored, so callers receive partial text or an empty finishReason as a successful result. Surface these failures instead of swallowing them.

  • packages/sdk/client.ts#L84-L98: throw a contextual stream-decoding error rather than continuing.
  • packages/sdk/client.ts#L132-L140: apply the same behavior so chatStream() does not silently omit chunks.
📍 Affects 1 file
  • packages/sdk/client.ts#L84-L98 (this comment)
  • packages/sdk/client.ts#L132-L140
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk/client.ts` around lines 84 - 98, Replace the swallowed
parse/validation errors in the stream-decoding loop with a contextual error that
is thrown to the caller, covering malformed JSON, schema mismatches, and invalid
finish chunks. Apply this to both packages/sdk/client.ts lines 84-98 and lines
132-140 so the corresponding streaming paths, including chatStream(), never
return partial results while silently omitting invalid chunks.

Comment thread packages/sdk/client.ts
Comment on lines +158 to +159
const data = await res.json()
return { object: data.object }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep outline apps/api/src/routes/ai.ts --items all
rg -n -C 4 'generate-object|object' apps/api/src/routes/ai.ts packages/sdk

Repository: yashdev9274/supercli

Length of output: 7556


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- packages/sdk/types.ts relevant section ---\n'
sed -n '1,90p' packages/sdk/types.ts

printf '\n--- packages/sdk/schemas.ts relevant section ---\n'
sed -n '1,110p' packages/sdk/schemas.ts

printf '\n--- packages/sdk/client.ts relevant method ---\n'
sed -n '130,165p' packages/sdk/client.ts

printf '\n--- apps/api/src/routes/ai.ts route section ---\n'
sed -n '96,135p' apps/api/src/routes/ai.ts

Repository: yashdev9274/supercli

Length of output: 249


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- packages/sdk/types.ts relevant section ---'
sed -n '1,90p' packages/sdk/types.ts

printf '%s\n' ''
printf '%s\n' '--- packages/sdk/schemas.ts relevant section ---'
sed -n '1,110p' packages/sdk/schemas.ts

printf '%s\n' ''
printf '%s\n' '--- packages/sdk/client.ts relevant method ---'
sed -n '130,165p' packages/sdk/client.ts

printf '%s\n' ''
printf '%s\n' '--- apps/api/src/routes/ai.ts route section ---'
sed -n '96,135p' apps/api/src/routes/ai.ts

Repository: yashdev9274/supercli

Length of output: 5805


Validate the object-generation response before returning it.

res.json() is untyped, so an empty or non-string object can resolve with a value that doesn’t satisfy GenerateObjectResponse. Add and export a generateObjectResponseSchema, then return generateObjectResponseSchema.parse(data).

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

In `@packages/sdk/client.ts` around lines 158 - 159, Define and export a
generateObjectResponseSchema for validating the object-generation response, then
update the response handling around res.json() to return
generateObjectResponseSchema.parse(data) instead of constructing an unvalidated
object. Preserve the existing GenerateObjectResponse shape while rejecting empty
or non-string object values.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant