Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,55 @@ Set `CODEFLOW_STORE_ROOT` to override the default location.

Browser-only preferences such as live completions, auto-implement, and theme stay in local storage. The raw NVIDIA API key is no longer persisted there; it is held in the current browser session only unless you provide it through `NVIDIA_API_KEY`.

## OpenCode Integration

CodeFlow supports OpenCode as an alternative AI backend for code generation and implementation:

### Setup

1. Install OpenCode globally (optional, for CLI usage):
```bash
npm install -g opencode-ai
```

2. Configure OpenCode from the CodeFlow settings panel:
- Open Settings (gear icon or press `S`)
- Click "Configure OpenCode"
- Select your AI provider (Anthropic, OpenAI, Google, etc.)
- Enter your API key
- Click "Start Server"

### Features

- **Multiple AI Providers**: Support for Anthropic (Claude), OpenAI (GPT), Google (Gemini), Azure OpenAI, Groq, Mistral, Cohere, Perplexity, OpenRouter, AWS Bedrock, and local models
- **MCP Servers**: Configure Model Context Protocol servers for enhanced agent capabilities
- **Skills & Hooks**: Enable OpenCode skills and configure pre/post hooks for automated workflows
- **Agent Types**: Choose between "build" (full file access) or "plan" (read-only analysis) agents

### OpenCode API Routes

- `GET /api/opencode/status` - Get server status
- `POST /api/opencode/start` - Start the OpenCode server
- `POST /api/opencode/stop` - Stop the OpenCode server
- `POST /api/opencode/restart` - Restart the OpenCode server
- `POST /api/opencode/agent` - Send a message to the agent
- `GET /api/opencode/sessions` - List OpenCode sessions
- `POST /api/opencode/sessions` - Create a new session
- `GET /api/opencode/sessions/:id` - Get session details
- `POST /api/opencode/sessions/:id` - Send message to session
- `DELETE /api/opencode/sessions/:id` - Delete session
- `GET /api/opencode/mcp` - List configured MCP servers
- `POST /api/opencode/mcp` - Configure MCP server
- `GET /api/opencode/permissions` - List pending permission requests
- `POST /api/opencode/permissions` - Reply to permission request

### Using OpenCode for Code Generation

When OpenCode is running, you can use it for:
- Node implementation (`POST /api/implement-node` with `useOpencode: true`)
- Code suggestions (`POST /api/code-suggestions` with `useOpencode: true`)
- Direct agent queries via the OpenCode panel in the workbench

## API routes

- `POST /api/blueprint`
Expand Down
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
import "./.next/dev/types/routes.d.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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if the dev-specific types path exists and verify Next.js type generation

# Check if the dev types path exists
if [ -f ".next/dev/types/routes.d.ts" ]; then
  echo "✓ Dev types path exists"
else
  echo "✗ Dev types path does NOT exist"
fi

# Check if production types path exists
if [ -f ".next/types/routes.d.ts" ]; then
  echo "✓ Production types path exists"
else
  echo "✗ Production types path does NOT exist"
fi

# Check Next.js configuration for TypeScript settings
if [ -f "next.config.js" ] || [ -f "next.config.mjs" ] || [ -f "next.config.ts" ]; then
  echo "Next.js config found:"
  fd -e js -e mjs -e ts '^next\.config\.' --max-depth 1 --exec cat {}
fi

# Check if this file was recently auto-generated or manually edited
echo -e "\nRecent commits touching next-env.d.ts:"
git log --oneline --follow -5 -- next-env.d.ts

Repository: nehraa/CodeFlow

Length of output: 499


🏁 Script executed:

# See the git diff for this file in the current commit
git diff HEAD -- next-env.d.ts

Repository: nehraa/CodeFlow

Length of output: 41


🏁 Script executed:

# Check the file content
cat -n next-env.d.ts

Repository: nehraa/CodeFlow

Length of output: 351


🏁 Script executed:

# Check if there are any TypeScript or build errors related to types
if [ -f "tsconfig.json" ]; then
  echo "=== tsconfig.json ===" 
  cat tsconfig.json
fi

Repository: nehraa/CodeFlow

Length of output: 975


🏁 Script executed:

# Search for references to .next/types or .next/dev/types in the codebase
rg '\.next/(dev/)?types' --type ts --type tsx --type js --type jsx

Repository: nehraa/CodeFlow

Length of output: 86


🏁 Script executed:

# Check git history to see what changed
git log --oneline -10 -- next-env.d.ts

Repository: nehraa/CodeFlow

Length of output: 124


🏁 Script executed:

# See the actual previous version of the file
git show HEAD~1:next-env.d.ts 2>/dev/null || echo "No previous version found"

Repository: nehraa/CodeFlow

Length of output: 84


🏁 Script executed:

# Check if there are any build or test failures
if [ -f "package.json" ]; then
  echo "=== Build scripts in package.json ===" 
  rg '"(build|test)"' package.json -A 1
fi

Repository: nehraa/CodeFlow

Length of output: 207


🏁 Script executed:

# Search for references to the routes types path
rg 'routes\.d\.ts|\.next.*types' -A 2 -B 2 --max-count=10

Repository: nehraa/CodeFlow

Length of output: 497


🏁 Script executed:

# Check if the change is a new file or a modification
git log --format="%H %s" -1 -- next-env.d.ts | head -1
git show --name-status c44e827 | grep next-env

Repository: nehraa/CodeFlow

Length of output: 173


🏁 Script executed:

# Verify that Next.js with typedRoutes:true generates types in the .next/dev/types path
# Look at Next.js documentation and check what's the standard behavior
web_search
Next.js typedRoutes typed routes .next dev types path location

Repository: nehraa/CodeFlow

Length of output: 155


🏁 Script executed:

# Check if there's any documented reason for including next-env.d.ts in version control
rg 'next-env' .gitignore README.md --max-count=5 -A 2

Repository: nehraa/CodeFlow

Length of output: 41


🌐 Web query:

Next.js typedRoutes routes.d.ts .next/dev/types path generation

💡 Result:

Next.js generates the routes.d.ts file for typedRoutes as part of its type generation process when the typedRoutes option is enabled in next.config.js. This provides type-safe routes, including a Route type and global helpers like PageProps and LayoutProps. To enable: In next.config.js: const nextConfig = { typedRoutes: true, } module.exports = nextConfig The routes.d.ts file is automatically generated: - In development: .next/dev/types/routes.d.ts - In production/build: .next/types/routes.d.ts Generation occurs during: - next dev - next build - Or manually via next typegen (generates types without full build, useful for CI/type-checking) The next-env.d.ts file (in project root) imports the appropriate routes.d.ts path and should be gitignored as it toggles between dev/prod paths. Ensure tsconfig.json includes: "include": [ "next-env.d.ts", ".next/types//.ts", "/.ts", "/*.tsx" ] Usage example for typed routes: const route: Route<'/blog/[slug]'> = '/blog/my-post'; // Provides autocomplete, validation for Link href, navigation methods (push, redirect, etc.), supports dynamic segments. This feature requires TypeScript and works with App Router (and some Pages Router support). For full route tree scanning from app/ directory, parallel routes (@slot), redirects/rewrites.

Citations:


🏁 Script executed:

# Check .gitignore to see if .next is ignored
cat .gitignore | grep -E '^\/?\.next'

Repository: nehraa/CodeFlow

Length of output: 64


🏁 Script executed:

# Check if next-env.d.ts should be in version control by looking at Next.js best practices
# and checking what the official Next.js template does
rg 'next-env' --type md README.md docs/ -A 2 -B 2 2>/dev/null || echo "No markdown docs found"

Repository: nehraa/CodeFlow

Length of output: 81


🏁 Script executed:

# Check if next-env.d.ts is already in .gitignore
cat .gitignore | head -20

Repository: nehraa/CodeFlow

Length of output: 313


🏁 Script executed:

# Check the actual commit to see if next-env.d.ts was added or modified
git show --stat c44e827

Repository: nehraa/CodeFlow

Length of output: 21096


🏁 Script executed:

# Verify Next.js best practices - check if next-env.d.ts should be gitignored
# by looking at Next.js starter templates
rg 'next-env\.d\.ts' --type md --type txt 2>/dev/null || echo "No references found"

Repository: nehraa/CodeFlow

Length of output: 78


🏁 Script executed:

# Verify the original state - check git history before this commit
git show c44e827^:next-env.d.ts 2>/dev/null || echo "File did not exist in previous commit (expected - this is the first)"

Repository: nehraa/CodeFlow

Length of output: 127


🏁 Script executed:

# Check if there's any documentation or comments about why next-env.d.ts was committed
rg 'next-env' --max-count=10 -B 3 -A 3

Repository: nehraa/CodeFlow

Length of output: 263


🏁 Script executed:

# Verify tsconfig includes both paths
grep -A 5 '"include"' tsconfig.json | head -20

Repository: nehraa/CodeFlow

Length of output: 177


Remove next-env.d.ts from version control; it should be auto-generated per environment.

This file should not be committed to git. Per Next.js conventions, next-env.d.ts is auto-generated during next dev and next build with environment-specific paths:

  • Development: .next/dev/types/routes.d.ts
  • Production/Build: .next/types/routes.d.ts

By committing it with a hardcoded dev path, production builds will fail when Next.js generates .next/types/routes.d.ts but the committed file tries to import from .next/dev/types/routes.d.ts (which doesn't exist in that build).

Fix: Remove next-env.d.ts from git history and add it to .gitignore. Let Next.js auto-generate it with the correct paths for each environment. The tsconfig.json already correctly includes both possible paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@next-env.d.ts` at line 3, Remove the checked-in next-env.d.ts file and stop
committing it: delete the file from the repository (or remove it from git
history if already merged) and add an entry for next-env.d.ts to .gitignore so
Next.js can auto-generate it per environment; verify tsconfig.json remains
configured to include both ".next/dev/types/routes.d.ts" and
".next/types/routes.d.ts" so the correct path is used for dev vs build.


// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
181 changes: 181 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@xyflow/react": "^12.10.1",
"cross-spawn": "^7.0.6",
"framer-motion": "^12.38.0",
"monaco-editor": "^0.55.1",
"next": "^16.1.6",
"opencode-ai": "^1.3.13",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-rnd": "^10.4.13",
Expand All @@ -39,6 +41,7 @@
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/cross-spawn": "^6.0.6",
"@types/node": "^25.5.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
Expand Down
59 changes: 41 additions & 18 deletions src/app/api/code-suggestions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { withCodeflowGovernance } from "@/lib/blueprint/prompt-governance";
import { blueprintGraphSchema } from "@/lib/blueprint/schema";
import { getNvidiaKeySource, requestNvidiaChatCompletion, resolveNvidiaApiKey } from "@/lib/blueprint/nvidia";
import { isOpencodeAvailable, sendToOpencode } from "@/lib/opencode/agent";

const requestSchema = z.object({
graph: blueprintGraphSchema,
Expand All @@ -18,7 +19,8 @@ const requestSchema = z.object({
instruction: z.string().trim().optional(),
retrievalQuery: z.string().trim().min(1).optional(),
retrievalDepth: z.number().int().min(1).max(6).optional(),
nvidiaApiKey: z.string().optional()
nvidiaApiKey: z.string().optional(),
useOpencode: z.boolean().optional().default(false)
});

const responseSchema = z.object({
Expand Down Expand Up @@ -50,8 +52,9 @@ export async function POST(request: Request) {

try {
const body = requestSchema.parse(await request.json());
const apiKey = resolveNvidiaApiKey(body.nvidiaApiKey);
const keySource = getNvidiaKeySource(body.nvidiaApiKey);
const useOpencode = body.useOpencode && isOpencodeAvailable();
const apiKey = useOpencode ? null : resolveNvidiaApiKey(body.nvidiaApiKey);
const keySource = useOpencode ? "opencode" : getNvidiaKeySource(body.nvidiaApiKey);
const context = getNodeAssistanceContext(body.graph, body.nodeId);

if (!context) {
Expand All @@ -67,11 +70,16 @@ export async function POST(request: Request) {
keySource
});

if (!apiKey) {
return NextResponse.json(
{ error: "NVIDIA API key is required. Provide it in the UI or set NVIDIA_API_KEY environment variable." },
{ status: 400 }
);
if (!useOpencode && !apiKey) {
// Check if OpenCode is available as fallback
if (isOpencodeAvailable()) {
body.useOpencode = true;
} else {
return NextResponse.json(
{ error: "No AI backend available. Either start OpenCode server or provide NVIDIA API key." },
{ status: 400 }
);
}
}
Comment on lines +73 to 83

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Mutating the parsed body object to handle the fallback to OpenCode can be confusing. The original useOpencode constant remains false, and the logic later needs to check useOpencode || body.useOpencode. Consider using a mutable let useOpencode variable initialized earlier to make the control flow more straightforward and avoid side effects on the parsed request body.


const retrievalContext = await resolveAgentRetrievalContext({
Expand Down Expand Up @@ -132,16 +140,31 @@ Return the JSON suggestion now.`;
"implementation"
);

const content = await requestNvidiaChatCompletion({
apiKey,
messages: [
{ role: "system", content: governedSystemPrompt },
{ role: "user", content: userPrompt }
],
temperature: 0.2,
topP: 0.7,
maxTokens: 4096
});
let content: string;

if (useOpencode || body.useOpencode) {
const result = await sendToOpencode({
systemPrompt: governedSystemPrompt,
prompt: userPrompt,
});

if (!result.success) {
throw new Error(result.error ?? "OpenCode request failed");
}

content = result.content ?? "";
} else {
content = await requestNvidiaChatCompletion({
apiKey: apiKey!,
messages: [
{ role: "system", content: governedSystemPrompt },
{ role: "user", content: userPrompt }
],
temperature: 0.2,
topP: 0.7,
maxTokens: 4096
});
}

const jsonMatch = content.match(/\{[\s\S]*\}/);
const jsonString = jsonMatch ? jsonMatch[0] : content;
Expand Down
Loading
Loading