This document contains critical rules and guidelines for AI agents working on this codebase.
By default, all log statements MUST use static strings only. Dynamic values are only allowed through the task-flow logging utility in lib/utils/task-flow-logs.ts.
// BAD - Contains dynamic values
await logger.info(`Task created: ${taskId}`)
await logger.error(`Failed to process ${filename}`)
console.log(`User ${userId} logged in`)
console.error(`Error for ${provider}:`, error)// GOOD - Static strings only
await logger.info('Task created')
await logger.error('Failed to process file')
console.log('User logged in')
console.error('Error occurred:', error)Key task flow logs may include selected dynamic values, but only when all of the following are true:
- The message is produced via
formatKeyTaskLogMessage()fromlib/utils/task-flow-logs.ts - The metadata keys are from the allowlist in that file
- The values are operational identifiers only, not secrets or user content
Examples of allowed dynamic values:
sessionIdthreadIdruntimeNameruntimeStateselectedModelpromptCharstranscriptCursorturnStatusmodesourceinstalledSkill
Examples that remain forbidden:
- tokens, secrets, API keys, passwords
- repository URLs and file paths
- raw user prompts or assistant content
- branch names, commit messages, personal identifiers
- Prevents data leakage: Dynamic values in logs can expose sensitive information (user IDs, file paths, credentials, etc.) to end users
- Security by default: Logs are displayed directly in the UI and returned in API responses
- Outside the approved task-flow utility path, this applies to ALL log levels (info, error, success, command, console.log, console.error, console.warn, etc.)
- Devbox runtime credentials (DEVBOX_TOKEN, DEVBOX_JWT_SIGNING_KEY)
- User IDs and personal information
- File paths and repository URLs
- Branch names and commit messages
- Error details that may contain sensitive context
- Any dynamic values that could reveal system internals
The redactSensitiveInfo() function in lib/utils/logging.ts automatically redacts known sensitive patterns, but this is a backup measure only. The primary defense is to never log dynamic values in the first place.
- API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)
- GitHub tokens (ghp*, gho*, ghu*, ghs*, ghr_)
- Devbox runtime credentials (DEVBOX_TOKEN, DEVBOX_JWT_SIGNING_KEY)
- Bearer tokens
- JSON fields (teamId, projectId)
- Environment variables containing KEY, TOKEN, SECRET, PASSWORD, TEAM_ID, PROJECT_ID
Always run pnpm format, pnpm type-check, and pnpm lint after making changes to TypeScript/TSX files.
The project uses Prettier for code formatting, TypeScript for type checking, and ESLint for linting. After editing any .ts or .tsx files, run:
pnpm format
pnpm type-check
pnpm lintIf any errors are found:
- Type errors: Fix TypeScript type errors by correcting type annotations, adding missing imports, or fixing type mismatches
- Lint errors: Fix ESLint errors by following the suggested fixes or adjusting the code to meet the linting rules
- Do not skip or ignore errors - all errors must be resolved before considering the task complete
This ensures all code follows the project's formatting standards, type safety requirements, and linting rules, preventing issues in pull requests.
When adding UI components, check if a shadcn/ui component exists and install it via CLI instead of writing it manually.
pnpm dlx shadcn@latest add <component-name>Existing components are in components/ui/. See shadcn/ui docs for available components.
-
Use descriptive static messages
// Instead of logging the value, log the action await logger.info('Sandbox created successfully') await logger.info('Dependencies installed') await logger.error('Build failed')
-
Server-side logging for debugging
// Use console.error for server-side debugging (not shown to users) // But still avoid sensitive data console.error('Sandbox creation error:', error)
-
Progress updates
// Use static progress messages await logger.updateProgress(50, 'Installing dependencies') await logger.updateProgress(75, 'Running build')
-
Generic error messages to users
await logger.error('Operation failed') // NOT: await logger.error(`Operation failed: ${error.message}`)
-
Detailed server-side logging
console.error('Detailed error for debugging:', error) // This appears in server logs, not user-facing logs
When making changes that involve logging:
-
Search for dynamic values
# Check for logger statements with template literals grep -r "logger\.(info|error|success|command)\(\`.*\$\{" . # Check for console statements with template literals grep -r "console\.(log|error|warn|info)\(\`.*\$\{" .
-
Verify no sensitive data exposure
- Test the feature in the UI
- Check the logs displayed to users
- Ensure no sensitive information is visible
Never expose these in logs or to the client:
-
POSTGRES_URL- Database connection string that may contain credentials -
SEALOS_HOST- Sealos cluster host configuration -
DEVBOX_TOKEN- Devbox runtime API token -
DEVBOX_JWT_SIGNING_KEY- Devbox JWT signing secret -
AI_GATEWAY_API_KEY- AI Gateway API key -
ANTHROPIC_API_KEY- Anthropic/Claude API key -
OPENAI_API_KEY- OpenAI API key -
GEMINI_API_KEY- Google Gemini API key -
CURSOR_API_KEY- Cursor API key -
GH_TOKEN/GITHUB_TOKEN- GitHub personal access token -
JWE_SECRET- Encryption secret -
ENCRYPTION_KEY- Encryption key -
Any user-provided API keys
The current app does not require any client-safe auth provider variables. Do not add NEXT_PUBLIC_ variables unless the app code explicitly needs them.
The current codebase expects these environment variables:
- Required core runtime:
POSTGRES_URL,SEALOS_HOST,DEVBOX_TOKEN,JWE_SECRET,ENCRYPTION_KEY,GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET - Required for Devbox JWT auth when
DEVBOX_TOKENis not set:DEVBOX_JWT_SIGNING_KEY - Required for AI-generated branch names, titles, and commit messages:
AI_GATEWAY_API_KEY - Optional callback override for self-hosted deployments:
APP_BASE_URL
Do not rename these without updating the corresponding code paths. In particular, GitHub OAuth currently uses GITHUB_CLIENT_ID on the server, not NEXT_PUBLIC_GITHUB_CLIENT_ID.
The repository page uses a nested routing structure with separate pages for each tab:
app/repos/[owner]/[repo]/
├── layout.tsx # Shared layout with navigation tabs
├── page.tsx # Redirects to /commits by default
├── commits/
│ └── page.tsx # Commits page
├── issues/
│ └── page.tsx # Issues page
└── pull-requests/
└── page.tsx # Pull Requests page
components/repo-layout.tsx- Shared layout component with tab navigationcomponents/repo-commits.tsx- Commits list componentcomponents/repo-issues.tsx- Issues list componentcomponents/repo-pull-requests.tsx- Pull requests list component
app/api/repos/[owner]/[repo]/
├── commits/route.ts # GET - Fetch commits
├── issues/route.ts # GET - Fetch issues
└── pull-requests/route.ts # GET - Fetch pull requests
- Tab Navigation: Uses Next.js Link components for client-side navigation between tabs
- Separate Pages: Each tab renders on its own route (commits, issues, pull-requests)
- Default Route: Visiting
/repos/[owner]/[repo]redirects to/repos/[owner]/[repo]/commits - Active State: The active tab is determined by matching the current pathname
- GitHub Integration: All data is fetched from GitHub API using Octokit client
To add a new tab to the repository page:
- Create a new directory under
app/repos/[owner]/[repo]/[tab-name]/ - Add a
page.tsxfile that renders your component - Create the component in
components/repo-[tab-name].tsx - Add an API route in
app/api/repos/[owner]/[repo]/[tab-name]/route.ts - Update the
tabsarray incomponents/repo-layout.tsxto include the new tab - Follow the existing patterns for data fetching and error handling
Before submitting changes, verify:
- No template literals with
${}in any log statements - All logger calls use static strings
- All console calls use static strings (for user-facing logs)
- No sensitive data in error messages
- Tested in UI to confirm no data leakage
- Server-side debugging logs don't expose credentials
- Ran
pnpm formatand code is properly formatted - Ran
pnpm format:checkto verify formatting - Ran
pnpm type-checkand all type errors are fixed - Ran
pnpm lintand all linting errors are fixed - Ran
pnpm buildonly when the user requested it or the task required production build verification
If you need to log information for debugging purposes:
- Use server-side console logs (not shown to users)
- Still avoid logging sensitive credentials
- Consider adding better error handling instead of logging details
- Use generic user-facing messages
Remember: When in doubt, use a static string. No exceptions.
Source code for dependencies is available in opensrc/ for deeper understanding of implementation details.
See opensrc/sources.json for the list of available packages and their versions.
Use this source code when you need to understand how a package works internally, not just its types/interface.
To fetch source code for a package or repository you need to understand, run:
npx opensrc <package> # npm package (e.g., npx opensrc zod)
npx opensrc pypi:<package> # Python package (e.g., npx opensrc pypi:requests)
npx opensrc crates:<package> # Rust crate (e.g., npx opensrc crates:serde)
npx opensrc <owner>/<repo> # GitHub repo (e.g., npx opensrc vercel/ai)-
Use task-flow logs for approved runtime identifiers
import { formatKeyTaskLogMessage, TASK_FLOW_LOGS } from '@/lib/utils/task-flow-logs' const message = formatKeyTaskLogMessage(TASK_FLOW_LOGS.GATEWAY_SESSION_READY, { sessionId, mode: 'created', }) await logger.success(message) console.info(message)