Skip to content

feat: integrate Nova web and enhance authentication flow: - #322

Merged
yashdev9274 merged 2 commits into
mainfrom
supercode-cli
Oct 8, 2026
Merged

yashdev9274 merged 2 commits into
mainfrom
supercode-cli

Conversation

@yashdev9274

@yashdev9274 yashdev9274 commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Description

  • Updated the dashboard and Nova web to run on port 3003, improving accessibility.
  • Implemented a safe redirect mechanism for Nova login sessions, ensuring only allowed origins are accepted.
  • Enhanced the authentication client to support one-time tokens for secure session management.
  • Added new API routes for Composio interactions, including session management and tool execution.
  • Updated environment configurations to support Nova web integration and CLI authentication.
  • Improved error handling and response structures for Composio-related requests.

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 Supercode Review

New Features

  • Add Nova Web app routing/layout and a Nova-specific login redirect flow (including safe origin handling).
  • Implement one-time token generation and a CLI callback endpoint for Nova login sessions.
  • Add CLI server Composio service + routes for connecting, disconnecting, listing apps, creating MCP sessions, and executing tools.
  • Add Nova Web API routes for sessions/turn streaming, approvals, connectors, settings, and Composio integration endpoints.

Infrastructure

  • Update local/dev and environment docs to reflect the new port and NOVA host.

Tests

  • Add Composio route tests on the CLI server and Nova references route tests.

- Updated the dashboard and Nova web to run on port 3003, improving accessibility.
- Implemented a safe redirect mechanism for Nova login sessions, ensuring only allowed origins are accepted.
- Enhanced the authentication client to support one-time tokens for secure session management.
- Added new API routes for Composio interactions, including session management and tool execution.
- Updated environment configurations to support Nova web integration and CLI authentication.
- Improved error handling and response structures for Composio-related requests.
@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
supercli Ready Ready Preview Oct 8, 2026 3:12pm UTC
supercli-client Ready Ready Preview Oct 8, 2026 3:12pm UTC
supercli-docs Ready Ready Preview Oct 8, 2026 3:12pm UTC
vercel-supercodeai-integration Ready Ready Preview Oct 8, 2026 3:12pm UTC

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 119 files, which is 19 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9d8769cc-9069-4da7-b6fd-edb9458906dc
📥 Commits

Reviewing files that changed from the base of the PR and between fb7b0c9 and ed2f1ce.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (119)
  • CONTRIBUTING.md
  • README.md
  • apps/supercode-cli/client/components/auth/login-form.tsx
  • apps/supercode-cli/client/lib/auth-client.ts
  • apps/supercode-cli/server/.env.example
  • apps/supercode-cli/server/src/index.ts
  • apps/supercode-cli/server/src/lib/auth.ts
  • apps/supercode-cli/server/src/lib/composio.ts
  • apps/supercode-cli/server/src/routes/composio-execute.test.ts
  • apps/supercode-cli/server/src/routes/composio.test.ts
  • apps/supercode-cli/server/src/routes/composio.ts
  • apps/supercode-cli/server/src/runtime/stream/openai-compatible-stream.ts
  • apps/web/.env.example
  • apps/web/app/(auth)/login/page.tsx
  • apps/web/app/(nova-app)/layout.tsx
  • apps/web/app/(nova-app)/nova-app-internal/approvals/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/connections/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/more/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/pulls/[id]/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/pulls/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/s/[sessionId]/page.tsx
  • apps/web/app/(nova-app)/nova-app-internal/settings/page.tsx
  • apps/web/app/(pages)/nova/page.tsx
  • apps/web/app/api/auth/cli/callback/route.ts
  • apps/web/app/api/desktop/nova/sessions/[sessionId]/messages/route.ts
  • apps/web/app/api/desktop/nova/sessions/route.ts
  • apps/web/app/api/integrations/github/callback/route.ts
  • apps/web/app/api/integrations/linear/callback/route.ts
  • apps/web/app/api/integrations/slack/callback/route.ts
  • apps/web/app/api/nova/approvals/[approvalId]/route.ts
  • apps/web/app/api/nova/approvals/route.ts
  • apps/web/app/api/nova/composio/apps/route.ts
  • apps/web/app/api/nova/composio/connect/route.ts
  • apps/web/app/api/nova/composio/disconnect/route.ts
  • apps/web/app/api/nova/composio/tools/route.ts
  • apps/web/app/api/nova/connectors/github/callback/route.ts
  • apps/web/app/api/nova/connectors/route.ts
  • apps/web/app/api/nova/local-projects/[projectId]/route.ts
  • apps/web/app/api/nova/local-projects/route.ts
  • apps/web/app/api/nova/references/route.test.ts
  • apps/web/app/api/nova/references/route.ts
  • apps/web/app/api/nova/sessions/[sessionId]/local-project/route.ts
  • apps/web/app/api/nova/sessions/[sessionId]/messages/route.ts
  • apps/web/app/api/nova/sessions/[sessionId]/route.ts
  • apps/web/app/api/nova/sessions/[sessionId]/sync/route.ts
  • apps/web/app/api/nova/sessions/[sessionId]/turn/route.ts
  • apps/web/app/api/nova/sessions/route.ts
  • apps/web/app/api/nova/settings/activity/route.ts
  • apps/web/app/api/nova/settings/usage/route.ts
  • apps/web/modules/components/login-ui.tsx
  • apps/web/modules/components/utils/auth-utils.ts
  • apps/web/modules/integrations/lib/app-url.ts
  • apps/web/modules/integrations/lib/callback-flow.ts
  • apps/web/modules/integrations/lib/composio.ts
  • apps/web/modules/integrations/lib/connect-flow.ts
  • apps/web/modules/integrations/lib/desktop-composio.ts
  • apps/web/modules/integrations/lib/oauth-state.test.ts
  • apps/web/modules/integrations/lib/oauth-state.ts
  • apps/web/modules/nova-web/api.ts
  • apps/web/modules/nova-web/components/account-menu.tsx
  • apps/web/modules/nova-web/components/approvals.tsx
  • apps/web/modules/nova-web/components/composer.tsx
  • apps/web/modules/nova-web/components/connections.tsx
  • apps/web/modules/nova-web/components/home.tsx
  • apps/web/modules/nova-web/components/mention-picker.tsx
  • apps/web/modules/nova-web/components/more.tsx
  • apps/web/modules/nova-web/components/pull-detail.tsx
  • apps/web/modules/nova-web/components/pulls.tsx
  • apps/web/modules/nova-web/components/settings.tsx
  • apps/web/modules/nova-web/components/sidebar.tsx
  • apps/web/modules/nova-web/components/thread.tsx
  • apps/web/modules/nova-web/components/timeline.tsx
  • apps/web/modules/nova-web/components/working-process.tsx
  • apps/web/modules/nova-web/local-files.ts
  • apps/web/modules/nova-web/local-workspace.test.ts
  • apps/web/modules/nova-web/local-workspace.ts
  • apps/web/modules/nova-web/mention-helpers.test.ts
  • apps/web/modules/nova-web/mention-helpers.ts
  • apps/web/modules/nova-web/models.ts
  • apps/web/modules/nova-web/nova-app.tsx
  • apps/web/modules/nova-web/nova-login.tsx
  • apps/web/modules/nova-web/settings-sections.ts
  • apps/web/modules/nova-web/theme.ts
  • apps/web/modules/nova-web/types.ts
  • apps/web/modules/nova-web/working-steps.test.ts
  • apps/web/modules/nova-web/working-steps.ts
  • apps/web/modules/nova/attachments/contracts.test.ts
  • apps/web/modules/nova/attachments/contracts.ts
  • apps/web/modules/nova/connectors/callback.ts
  • apps/web/modules/nova/connectors/config.ts
  • apps/web/modules/nova/harness/agent.test.ts
  • apps/web/modules/nova/harness/agent.ts
  • apps/web/modules/nova/harness/auth.ts
  • apps/web/modules/nova/harness/client.ts
  • apps/web/modules/nova/harness/composio-client.ts
  • apps/web/modules/nova/harness/composio.test.ts
  • apps/web/modules/nova/harness/composio.ts
  • apps/web/modules/nova/harness/cookies.ts
  • apps/web/modules/nova/local-projects/contracts.ts
  • apps/web/modules/nova/local-projects/service.ts
  • apps/web/modules/nova/references/contracts.ts
  • apps/web/modules/nova/references/service.test.ts
  • apps/web/modules/nova/references/service.ts
  • apps/web/modules/nova/sessions/local-attachments-turn.test.ts
  • apps/web/modules/nova/sessions/reference-persistence.test.ts
  • apps/web/modules/nova/sessions/references-turn.test.ts
  • apps/web/modules/nova/sessions/service.ts
  • apps/web/modules/nova/sessions/turn.test.ts
  • apps/web/modules/nova/sessions/turn.ts
  • apps/web/modules/nova/settings/service.ts
  • apps/web/next.config.ts
  • apps/web/package.json
  • apps/web/proxy.ts
  • packages/auth/package.json
  • packages/auth/src/server.ts
  • packages/db-terminal/src/client.ts
  • packages/db/prisma/migrations/20261008150000_web_local_project/migration.sql
  • packages/db/prisma/schema.prisma

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

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@vercel vercel 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.

Additional Suggestion:

Eager instantiation of the terminal Prisma client at module-evaluation time throws DATABASE_URL_TERMINAL is required during next build, crashing any route that imports @super/db-terminal.

Fix on Vercel

@greptile-apps

greptile-apps Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 0/5 Tier: plus

[Critical risk] Adds authentication flow and API routes for Nova web application.

The PR is not safe to merge until the login, Composio, database configuration, and session-lifecycle failures are addressed.

Findings

  1. P1 Login token expires too quickly ▶
  2. P1 Composio session ID mismatch ▶
  3. P1 Terminal database fallback removed ▶
  4. P1 Desktop messages never execute ▶
  5. P1 Long threads lose visible history ▶
  6. P1 Duplicate turns lose run IDs ▶
  7. P1 Stop button cannot stop turns ▶
  8. P2 Saved preferences have no effect ▶
Summary

The PR adds host-routed Nova web pages, transfers CLI authentication into a dashboard session, moves CLI Composio requests to a local service, and adds web session, reference, and harness-turn flows.

  • The login transfer window, Composio response contract, terminal database configuration, and message execution lifecycle need correction before merge.
  • Nova’s initial timeline load can omit history, and its Stop and General Settings controls do not perform their advertised actions.
  • The Composio SDK response field and affected typechecks and tests still need verification.

Reviews (1) · Last reviewed commit: "feat: integrate Nova web and enhance aut..." · Reviewed by Greptile

},
plugins: [
oneTimeToken({
expiresIn: 3,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Login token expires too quickly The CLI generates this token before sending the browser to Nova, where the callback makes another request to verify it. If navigation or a cold start takes more than three seconds, an otherwise successful GitHub sign-in ends in a 401, and the callback cannot recover the login.

return {
url: session.mcp.url,
headers: session.mcp.headers,
sessionId: session.sessionId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Composio session ID mismatch Both existing callers of this SDK response read session_id, but this code reads sessionId. If the SDK returns session_id, the CLI response omits the session ID and Nova passes an undefined ID to the Connections UI. The new tests mock sessionId, so they do not catch that mismatch.

Comment on lines +4 to +11
function terminalDatabaseUrl(): string {
const url = process.env.DATABASE_URL_TERMINAL?.trim()
if (!url) {
throw new Error(
"DATABASE_URL_TERMINAL is required for the terminal/harness database. "
+ "It must not fall back to the dashboard DATABASE_URL.",
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Terminal database fallback removed If a web deployment sets only DATABASE_URL, as the web environment example still permits, importing this client now throws instead of using the previous fallback. The waitlist and several Nova routes import it statically, so their handlers cannot run in that configuration.

Comment on lines +26 to +35
const posted = await postSessionMessage({
userId: user.id,
sessionId,
content: parsed.data.content,
clientMessageId: parsed.data.clientMessageId,
surface: "desktop",
})
if (!posted) return NextResponse.json({ error: "Session not found" }, { status: 404 })
return NextResponse.json(posted, { status: 201 })
} catch (error) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Desktop messages never execute When a desktop client posts a message, postSessionMessage creates a queued run and marks it active, but this route returns without starting the turn or dispatching the run. The client receives an acknowledgement while Nova never answers and the session remains marked as working. The new web message endpoint follows the same pattern.

Comment on lines +251 to +265
const loadSession = useCallback(async (sessionId: string, reset = false) => {
const [detailResponse, sync] = await Promise.all([
getSession(sessionId),
syncSession(sessionId, reset ? 0 : cursorRef.current, 500),
])
setSession(detailResponse.session)
if (reset) {
setTimeline(
mergeTimeline(
[],
sync.messages.map((entry) => ({ ...entry, kind: "message" as const })),
sync.activities.map((entry) => ({ ...entry, kind: "activity" as const })),
),
)
setSyncCursor(sync.nextSequence)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Long threads lose visible history When a thread has more than 500 timeline entries, this initial load takes one capped page and advances the cursor without checking hasMore. Later polling starts after that page, so the remaining history is omitted from the view until it is reloaded.

createdAt: existing.createdAt.toISOString(),
references: referencesFromMetadata(existing.metadata),
},
runId: existing.agentSession.activeRunId ?? "",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Duplicate turns lose run IDs A repeated clientMessageId returns the session’s current active run rather than the run for that message. After the original run completes, activeRunId is cleared, so a retry receives runId: "". The turn then tries to save an activity against a nonexistent run and fails instead of returning or resuming the original result.

Comment on lines +291 to +298
<Composer
value={draft}
onChange={onDraftChange}
references={references}
onReferencesChange={onReferencesChange}
onSubmit={onSubmit}
streaming={streaming}
disabled={loading}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Stop button cannot stop turns While a turn streams, the composer displays Stop, but this caller supplies no onStop handler and the streaming request has no abort signal. Clicking Stop does nothing; the harness can keep running and executing connected tools.

Comment on lines +38 to +49
type GeneralPrefs = {
openLinksInDesktop: boolean
enterBehavior: "interrupt" | "queue" | "newline"
cmdEnterBehavior: "queue" | "interrupt" | "steer"
altEnterBehavior: "steer" | "queue" | "interrupt"
}

const DEFAULT_PREFS: GeneralPrefs = {
openLinksInDesktop: false,
enterBehavior: "interrupt",
cmdEnterBehavior: "queue",
altEnterBehavior: "steer",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Saved preferences have no effect General Settings saves Enter-key behavior and “Open links in desktop app,” but the composer and link navigation never read those values. The controls appear to work while leaving behavior unchanged, which can mislead users about their selected settings.

@yashdev9274

Copy link
Copy Markdown
Owner Author

🤖 Supercode AI Review

Summary

Summary

This PR shifts the dashboard to serve “Dashboard / Nova Web” on port 3003, and adds a Nova-specific auth + redirect flow using one-time tokens and HMAC-signed OAuth state. It also introduces a new CLI-server Composio integration layer (including tool listing/execution) and a set of Nova Web API routes for sessions, approvals, connectors, and Composio connection management.

Walkthrough

  • CLI login UX + redirect safety

    • apps/supercode-cli/client/components/auth/login-form.tsx: introduces ALLOWED_REDIRECT_ORIGINS, getSafeRedirect(), one-time token generation, and a redirect to /api/auth/cli/callback on the Nova origin.
    • apps/supercode-cli/client/lib/auth-client.ts: enables oneTimeTokenClient() plugin.
  • CLI auth server (better-auth)

    • apps/supercode-cli/server/src/lib/auth.ts: adds Nova origins to trustedOrigins and configures oneTimeToken() (hashed storage).
  • CLI server Composio integration

    • apps/supercode-cli/server/src/lib/composio.ts: new ServerComposioService wrapping Composio APIs (sessions, connected accounts, tool listing, and tool execution).
    • apps/supercode-cli/server/src/routes/composio.ts: rewrites Composio routes to call ServerComposioService directly; adds OAuth callback handling via HMAC-signed state and returns Nova or desktop completion URLs.
    • apps/supercode-cli/server/src/lib/composio.ts + apps/supercode-cli/server/src/routes/composio*.test.ts: adds tests for execute + connection flows.
  • Nova Web

    • apps/web/app/(auth)/login/page.tsx: detects Nova host and redirects to the CLI sign-in with redirect pointing to Nova /app.
    • apps/web/app/(pages)/nova/page.tsx: replaced with a redirect to https://nova.supercodeai.tech/.
    • Adds Nova Web APIs under apps/web/app/api/nova/* including sessions, approvals, references, connectors, settings, and Composio endpoints.
    • apps/web/app/api/auth/cli/callback/route.ts: validates the CLI one-time token, creates/updates the user, sets session cookie, and (optionally) forwards the harness token cookie.

Changes table

File Summary
CONTRIBUTING.md Update local dashboard URL to port 3003
README.md Update dashboard/Nova Web URLs and port mapping
apps/supercode-cli/client/components/auth/login-form.tsx Add safe redirect origin allowlist + one-time token Nova session transfer
apps/supercode-cli/client/lib/auth-client.ts Enable better-auth one-time token client plugin
apps/supercode-cli/server/.env.example Add NOVA_WEB_URL and COMPOSIO_API_KEY placeholder
apps/supercode-cli/server/src/index.ts Add missing proxy routes for desktop nova messages/turn
apps/supercode-cli/server/src/lib/auth.ts Trust Nova origins + enable one-time token plugin
apps/supercode-cli/server/src/lib/composio.ts New Composio service wrapper
apps/supercode-cli/server/src/routes/composio-execute.test.ts New execute route contract tests
apps/supercode-cli/server/src/routes/composio.test.ts New full Composio connection/tool tests
apps/supercode-cli/server/src/routes/composio.ts Rewrite Composio routes with HMAC state + Nova completion redirects
apps/web/.env.example Document new Nova Web/client config
apps/web/app/(auth)/login/page.tsx Redirect Nova-hosted login to CLI sign-in with safe redirect
apps/web/app/(nova-app)/* Add Nova app layout + internal pages
apps/web/app/(pages)/nova/page.tsx Replace landing with redirect to nova.supercodeai.tech
apps/web/app/api/auth/cli/callback/route.ts New CLI callback endpoint validating one-time token and setting cookies
apps/web/app/api/nova/* New Nova APIs (sessions, turn streaming, approvals, references, settings, connectors, composio)
apps/web/modules/components/utils/auth-utils.ts Allow configurable redirect path for auth helpers
apps/web/modules/integrations/lib/app-url.ts Add Nova web base/connection URL helpers
apps/web/modules/integrations/lib/callback-flow.ts Add returnTo handling for Nova completion redirects
apps/web/modules/integrations/lib/oauth-state.ts Extend OAuth state to include returnTo: nova
apps/web/modules/integrations/lib/oauth-state.test.ts Test nova return target preservation
apps/web/modules/nova-web/api.ts New API client helpers + NDJSON turn streaming parser

Risk assessment

High — Auth and redirect flows across multiple apps (CLI, dashboard, Nova web) plus state signing/callback handling affect login/session and OAuth completion. Bugs here can break onboarding or cause confusing redirect behavior.

Test plan

  • Run bun test (repo) and ensure newly added composio + nova references tests pass.
  • Manually verify CLI login from Nova host:
    • Open http://nova.localhost:3003/login
    • Complete GitHub sign-in
    • Confirm redirect returns to Nova /app and sessions are established.
  • Manually verify Composio connection flow:
    • From Nova web “Connections”, connect a toolkit (e.g., linear) and confirm landing page matches connections?connected=....
    • Attempt a denied callback to confirm Nova receives integration_error=....
  • Verify CLI Composio tool execution:
    • Connect an account and execute a tool requiring approval (ensure approval gating still works as expected).

Suggested PR description

What

  • Move Dashboard + Nova Web to port 3003 and add Nova-specific login redirects.
  • Implement safe Nova redirect/origin handling and secure one-time token transfer from CLI login to Nova sessions.
  • Add CLI server Composio service + routes (sessions/apps/connect/disconnect/tools/execute) and Nova Web APIs to manage Nova sessions, approvals, connectors, settings, and Composio integrations.

Why

  • Provide a unified Nova Web experience with stronger auth/session security and robust OAuth completion handling.
  • Enable Composio connections and tool execution for both CLI and Nova surfaces.

How tested

  • Added and ran Bun tests for:
    • CLI Composio execute contract and connection/OAuth completion flows.
    • Nova references API (auth required, kind/q validation, error mapping).
  • Manual verification planned for login redirect and Composio connect flows between Nova web and CLI callback.

Findings

  • [critical] composio.ts OAuth state parsing uses unchecked base64 JSON decode — apps/supercode-cli/server/src/routes/composio.ts
    Explanation and why it matters.
    verifyState() does:

    • const [payload, signature, extra] = state.split(".")
    • const expected = createHmac(...).update(payload)...
    • JSON.parse(Buffer.from(payload, "base64url").toString("utf8"))

    If payload is malformed, the code catches parsing errors and returns null, which is fine; however, the stateSecret() relies on BETTER_AUTH_SECRET existing, and that error is thrown (503) inside the request handler catch, which then becomes sendError(). That means an OAuth callback with missing env can cause unexpected 502/503 behavior instead of a clean “invalid state” response. Also, base64url decoding failure will throw and is caught, but the mismatch between “invalid state” vs “server misconfigured” is not distinguished.

    Suggested fix.

    • Ensure stateSecret() failure is treated as an invalid state for callback requests (or return 503 explicitly before HMAC work). For example:
    function verifyState(state: unknown): z.infer<typeof stateSchema> | null {
      try {
        const secret = process.env.BETTER_AUTH_SECRET?.trim()
        if (!secret) return null
        ...
        const expected = createHmac("sha256", secret).update(payload)...
        ...
      } catch {
        return null
      }
    }
  • [high] Possible undefined input.name passed to executeTool when both toolName and name are absent/empty — apps/supercode-cli/server/src/routes/composio.ts
    Explanation and why it matters.
    executeSchema allows:

    toolName?: string
    name?: string
    arguments: z.record(z.unknown()).default({})
    }).refine((input) => Boolean(input.toolName || input.name) && (...))
      .transform((input) => ({ name: input.toolName ?? input.name ?? "", arguments: input.arguments }))

    While the refine enforces at least one is truthy, TypeScript still allows runtime cases where both are provided as "" (empty string). toolNameSchema/toolNameSchema.optional() + .min(1) should reject empty strings, but since both are optional and safeParse is used, this should be covered—however the transform emits name: "" and the code calls:

    • await service.executeTool(user.id, input.name, input.arguments)

    If the schema ever changes or Zod behavior differs, executeTool() would attempt Composio tool lookup with an empty name, returning 404. This is low-effort to harden now.

    Suggested fix.

    • After parsing, assert input.name.length > 0 before execution (defensive):
    if (!input.name) return res.status(400).json({ error: "Tool name is required" })
  • [high] apps/web/app/api/auth/cli/callback/route.ts uses crypto.randomUUID() without importing/using Web crypto API — apps/web/app/api/auth/cli/callback/route.ts
    Explanation and why it matters.
    The file calls crypto.randomUUID() but the diff shows no crypto import. In Next.js/edge/node runtimes, crypto may be global, but this is not guaranteed depending on runtime configuration. A production deployment could fail at runtime on the “create user” path.

    Suggested fix.

    • Import Node crypto or use globalThis.crypto explicitly.
    import { randomUUID } from "node:crypto"
    ...
    id: randomUUID()

    (Or ensure crypto is imported if the repo uses Node runtime here.)

  • [medium] Nova callback redirect allowlist is duplicated and incomplete across apps — apps/supercode-cli/client/components/auth/login-form.tsx and apps/web/app/(auth)/login/page.tsx
    Explanation and why it matters.
    The CLI client uses:

    const ALLOWED_REDIRECT_ORIGINS = new Set([
      "https://nova.supercodeai.tech",
      "http://nova.localhost:3003",
    ])

    The web login page uses:

    const NOVA_HOSTS = new Set(["nova.supercodeai.tech", "nova.localhost"])

    These are similar but not derived from shared configuration. This can easily drift (e.g., if port changes, staging hostnames are added, or a new Nova subdomain is introduced).

    Suggested fix.

    • Centralize allowed hosts/origins into config/env (or a shared module) and ensure both sides use the same source of truth.
  • [medium] apps/supercode-cli/server/src/routes/composio.ts returns mixed completion URL schemes depending on returnTo but callback expects specific query param names — apps/supercode-cli/server/src/routes/composio.ts + apps/web/modules/integrations/lib/callback-flow.ts
    Explanation and why it matters.
    The completion URL logic in CLI server for Nova uses:

    • completionUrl("nova", slug) → .../connections?connected=<slug> and on errors integration_error=<...>.

    Web integration callback-flow also implements Nova completion behavior via getNovaConnectionsUrl().

    The contract between the CLI callback redirect and Nova web pages/components should be consistent. In the diff, tests in apps/supercode-cli/server/src/routes/composio.test.ts assert:

    • http://nova.localhost:3003/connections?connected=linear
      which is good, but I’d still flag that there are two implementations (CLI server and web modules). If one side changes query params, the other side won’t enforce correctness.

    Suggested fix.

    • Deduplicate: have CLI server import/shared logic (or at least mirror via tests that assert the same query keys).
  • [nit] Minor string formatting consistency — apps/supercode-cli/client/components/auth/login-form.tsx
    Explanation and why it matters.
    Uses inconsistent quote styles in the added allowlist ("https://..." with double quotes) while the file surrounding code uses single quotes in imports and other strings.

    Suggested fix.

    • Align to the repo’s prevailing style (likely single quotes) for readability/lint cleanliness.
Sequence diagram

Sequence Diagram

sequenceDiagram
  participant U as User
  participant NovaLogin as Nova Web (/login)
  participant CLI as CLI Login Form
  participant AuthServer as CLI Auth (better-auth)
  participant CLIPlugin as oneTimeToken plugin
  participant CliCallback as Nova Web /api/auth/cli/callback
  participant Prisma as DB (prisma.user)
  participant NovaApp as Nova Web (/app /connections)

  U->>NovaLogin: Open Nova host login (nova.localhost:3003)
  NovaLogin->>CLI: Redirect to CLI /sign-in?redirect=<nova /app>
  U->>CLI: Complete GitHub sign-in
  CLI->>AuthServer: Create/obtain CLI session
  AuthServer-->>CLI: CLI session exists (better-auth)
  CLI->>CLIPlugin: authClient.oneTimeToken.generate()
  CLIPlugin-->>CLI: one-time token
  CLI->>CliCallback: GET/redirect to /api/auth/cli/callback?token=...&redirect=/app
  CliCallback->>AuthServer: POST /api/auth/one-time-token/verify { token }
  AuthServer-->>CliCallback: Session + token validity payload
  CliCallback->>Prisma: find/update/create user
  CliCallback-->>NovaApp: 302 redirect to redirect URL + set session cookie (and harness token cookie if present)
Loading

Automated review by Supercode · leave a 👍/👎 reaction to rate this review

@yashdev9274 yashdev9274 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Supercode found actionable issues during its complete PR analysis.

const value = error as { message?: string; statusCode?: number }
res.status(value.statusCode ?? 500).json({ error: value.message || fallback })
function stateSecret(): string {
const secret = process.env.BETTER_AUTH_SECRET

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

P1 · CRITICAL · verifyState secret failure treated as server error instead of invalid state

verifyState() calls stateSecret() which throws when BETTER_AUTH_SECRET is missing, causing the OAuth callback to hit the general error handler instead of returning a consistent 'invalid/expired state' response. This can turn a client-originated invalid state into a server misconfig failure. Evidence: stateSecret() throws 503; verifyState() does not catch it, so request handler falls into catch and sendError(). Suggested fix: have verifyState() return null if the secret is missing (or explicitly handle missing secret in the callback route) so callbacks fail closed as invalid state rather than noisy 5xx.

return errorResponse("The authentication service is unavailable", 502)
}

if (!cliResponse.ok) {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

P1 · HIGH · crypto.randomUUID used without import/guaranteed global

apps/web/app/api/auth/cli/callback/route.ts calls crypto.randomUUID() but the diff shows no import for crypto (no import { randomUUID } from 'node:crypto'). Depending on runtime (node vs edge) this can break at runtime when creating a new user. Suggested fix: import randomUUID from node:crypto or use globalThis.crypto with explicit handling.

@@ -9,6 +9,23 @@ import { Github, Code2, Sparkles, ArrowRight } from 'lucide-react'
import { ParticleBackground } from './particle-background'

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

P2 · MEDIUM · Duplicated Nova origin/host allowlists across apps can drift

Nova redirect/origin logic is implemented separately in CLI (ALLOWED_REDIRECT_ORIGINS) and web (NOVA_HOSTS). If ports/hosts/staging domains change, one side can drift and break redirects or weaken validation. Suggested fix: centralize these values via shared config/env and reuse the same source of truth in both places.

- Introduced new API routes for managing local projects, including creation, listing, updating, and binding to sessions.
- Implemented local attachments handling in session messages, allowing users to attach files directly from their local environment.
- Enhanced session management to include local project details and ensure proper authorization checks.
- Updated schemas and validation for local project inputs and attachments, improving data integrity.
- Added tests for local attachments and project management functionalities to ensure reliability.
onLocalFilesChange={onLocalFilesChange}
onLocalProjectChange={onLocalProjectChange}
onSubmit={onSubmit}
streaming={streaming}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The "Stop" button shown while a Nova turn is streaming is a no-op because onStop is never wired through ThreadView → Composer, leaving users unable to cancel a running turn.

Fix on Vercel

@yashdev9274
yashdev9274 merged commit ac3e3f4 into main Oct 8, 2026
7 of 10 checks passed

This branch was successfully deployed

4 active deployments
Preview – supercli — ed2f1cea Deployed Oct 8, 2026 by vercel[bot]
Preview – vercel-supercodeai-integration — ed2f1cea Deployed Oct 8, 2026 by vercel[bot]
Preview – supercli-docs — ed2f1cea Deployed Oct 8, 2026 by vercel[bot]
Preview – supercli-client — ed2f1cea Deployed Oct 8, 2026 by vercel[bot]
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