feat: add Cursor project rules for Grok CLI (#143)

Add .cursor/rules/ with MDC rule files covering:
- project-overview.mdc: architecture, tech stack, key patterns
- typescript-conventions.mdc: ESM imports, naming, type practices
- react-ink-components.mdc: Ink terminal UI component guidelines
- tools-and-agent.mdc: agent loop, tool interface, adding new tools
- development-workflow.mdc: scripts, env vars, CI checklist

Update .gitignore to clarify .cursor/ is tracked.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ismail Pelaseyed <homanp@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-03-17 22:26:56 +01:00
1 parent ad177ec77a
commit e763e2f472
6 files changed
+285 -1

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
---
description: Development workflow, scripts, and common tasks
globs:
alwaysApply: true
---
# Development Workflow
## Prerequisites
- Node.js 18+ (required)
- Bun 1.0+ (preferred, npm as fallback)
## Common Commands
```bash
# Install dependencies
bun install # preferred
npm install # fallback
# Development (runs from source)
bun run dev # uses Bun runtime
bun run dev:node # uses tsx (Node.js + TypeScript)
# Build (compile TypeScript to dist/)
bun run build
# Type checking (no emit)
bun run typecheck
# Linting
bun run lint
# Run the built CLI
bun run start # Node.js
bun run start:bun # Bun runtime
```
## Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `GROK_API_KEY` | Yes | API key for Grok / OpenAI-compatible provider |
| `GROK_BASE_URL` | No | Custom API endpoint (default: `https://api.x.ai/v1`) |
| `GROK_MODEL` | No | Model override (default: `grok-code-fast-1`) |
| `GROK_MAX_TOKENS` | No | Max tokens per response (default: 1536) |
| `MORPH_API_KEY` | No | Enables Morph Fast Apply editing |
Copy `.env.example` to `.env` and fill in your values.
## Before Submitting Changes
1. Run `bun run typecheck` — CI enforces this on every PR.
2. Run `bun run lint` — fix any ESLint errors.
3. Ensure no secrets or `.env` files are committed.
4. Follow the PR template in `.github/pull_request_template.md`.
## Project Structure Conventions
- Source code lives in `src/`, compiled output in `dist/` (gitignored).
- No test framework is configured yet — if adding tests, prefer Vitest for ESM compatibility.
- The CLI entry point is `src/index.ts` which uses Commander.js for argument parsing.
+51
View File
@@ -0,0 +1,51 @@
---
description: Project overview and architecture for Grok CLI
globs:
alwaysApply: true
---
# Grok CLI — Project Overview
Grok CLI (`@vibe-kit/grok-cli`) is an open-source conversational AI CLI tool powered by Grok that brings AI assistance directly into the terminal.
## Tech Stack
- **Language**: TypeScript (ES2022, ESNext modules)
- **Runtime**: Node.js 18+ (Bun preferred)
- **UI Framework**: React with [Ink](https://github.com/vadimdemedes/ink) for terminal rendering
- **Build**: `tsc` (TypeScript compiler)
- **Package Manager**: Bun (primary), npm (fallback)
- **Linting**: ESLint with `@typescript-eslint`
- **API Client**: OpenAI SDK (used for OpenAI-compatible APIs including Grok)
## Architecture
```
src/
├── index.ts # CLI entry point (Commander.js)
├── agent/ # GrokAgent — orchestrates client, tools, MCP
├── grok/ # Grok API client and tool definitions
├── mcp/ # Model Context Protocol integration
├── commands/ # CLI subcommands (e.g. mcp)
├── tools/ # Built-in tools (bash, text-editor, search, etc.)
├── ui/ # Ink-based terminal UI
│ ├── app.tsx
│ ├── components/ # Chat interface, diff renderer, inputs, etc.
│ └── utils/ # Colors, markdown rendering, code colorizer
├── hooks/ # React hooks for input handling
├── utils/ # Settings, token counting, custom instructions
└── types/ # Shared TypeScript type definitions
```
## Key Patterns
- **Agent loop**: `GrokAgent` runs an iterative tool-call loop — the LLM responds, tools execute, results feed back until no more tool calls remain or the round limit is hit.
- **Streaming**: `processUserMessageStream` is an async generator that yields chunks for real-time UI updates.
- **Settings hierarchy**: User-level (`~/.grok/user-settings.json`) → Project-level (`.grok/settings.json`) → System defaults.
- **MCP**: External tools are integrated via Model Context Protocol servers (stdio, HTTP, SSE transports).
- **ESM only**: The project uses `"type": "module"` — all imports use `.js` extensions for compiled output.
## CI/CD
- **typecheck.yml**: Runs `tsc --noEmit` on push/PR to `main`/`develop`.
- **security.yml**: Runs `npm audit` and TruffleHog secret scanning.
+45
View File
@@ -0,0 +1,45 @@
---
description: Guidelines for React components using Ink for terminal UI
globs: "src/ui/**/*.tsx,src/hooks/**/*.ts"
alwaysApply: false
---
# React + Ink Terminal UI
## Framework
This project uses [Ink](https://github.com/vadimdemedes/ink) v4 to render React components in the terminal. Ink provides `<Box>`, `<Text>`, and other primitives instead of HTML elements.
## Component Patterns
- Use **functional components** with hooks — no class components.
- JSX is compiled with `"jsx": "react"` (classic transform), so `import React from "react"` is required in every `.tsx` file.
- Components are in `src/ui/components/` and follow kebab-case naming (`chat-interface.tsx`, `diff-renderer.tsx`).
## Key Components
| Component | Purpose |
|-----------|---------|
| `ChatInterface` | Main chat loop, orchestrates agent interaction |
| `ChatHistory` | Renders conversation entries |
| `ChatInput` | User text input with key bindings |
| `DiffRenderer` | Displays file diffs |
| `ModelSelection` | Model picker UI |
| `LoadingSpinner` | Animated loading indicator |
| `ConfirmationDialog` | User confirmation prompts for tool operations |
| `McpStatus` | MCP server connection status |
| `CommandSuggestions` | Autocomplete suggestions |
| `ApiKeyInput` | API key entry prompt |
## Ink-Specific Guidelines
- Use `<Box>` for layout (flexbox model) and `<Text>` for styled text.
- Use Ink's `useInput` hook for keyboard handling.
- Use `chalk` for color utilities in `src/ui/utils/colors.ts`.
- Markdown rendering for chat output uses `marked` + `marked-terminal`.
- The app is rendered via `render(React.createElement(ChatInterface, { agent, initialMessage }))` in the entry point.
## Hooks
- Custom hooks live in `src/hooks/`.
- Follow the `use` prefix convention (`useInput`, `useChat`, etc.).
+69
View File
@@ -0,0 +1,69 @@
---
description: Guidelines for the agent system and tool implementations
globs: "src/agent/**/*.ts,src/tools/**/*.ts,src/grok/**/*.ts"
alwaysApply: false
---
# Agent & Tools System
## GrokAgent
`GrokAgent` (in `src/agent/grok-agent.ts`) is the core orchestrator. It extends `EventEmitter` and manages:
- The Grok API client (`GrokClient`)
- Built-in tools (text editor, bash, search, todo, confirmation)
- Optional Morph Fast Apply editor
- MCP server integration
- Chat history and message accumulation
- Abort/cancellation support
### Agent Loop
The agent uses an iterative tool-call pattern:
1. Send messages to the LLM.
2. If the response contains `tool_calls`, execute each tool.
3. Append tool results to the message history.
4. Repeat until no tool calls remain or `maxToolRounds` is reached.
Both `processUserMessage` (non-streaming) and `processUserMessageStream` (async generator) implement this loop.
## Tool Interface
All tools return a `ToolResult`:
```typescript
interface ToolResult {
success: boolean;
output?: string;
error?: string;
data?: any;
}
```
Tools should never throw — wrap errors in `{ success: false, error: "..." }`.
## Built-in Tools
| Tool | File | Purpose |
|------|------|---------|
| `TextEditorTool` | `src/tools/text-editor.ts` | View, create, and str_replace files |
| `MorphEditorTool` | `src/tools/morph-editor.ts` | Fast Apply editing (requires MORPH_API_KEY) |
| `BashTool` | `src/tools/bash.ts` | Execute shell commands |
| `SearchTool` | `src/tools/search.ts` | Unified text/file search (uses ripgrep) |
| `TodoTool` | `src/tools/todo-tool.ts` | Create/update visual todo lists |
| `ConfirmationTool` | `src/tools/confirmation-tool.ts` | User confirmation for operations |
## Adding a New Tool
1. Create a new file in `src/tools/` implementing the tool class.
2. Export it from `src/tools/index.ts`.
3. Register the tool schema in `src/grok/tools.ts` (add to `GROK_TOOLS` array).
4. Add the execution case in `GrokAgent.executeTool()`.
5. Update the system prompt in the `GrokAgent` constructor to document the tool.
## MCP Integration
- MCP tools are prefixed with `mcp__` and dispatched through `executeMCPTool`.
- MCP config is loaded from `.grok/settings.json` under `mcpServers`.
- Supported transports: stdio, HTTP, SSE (defined in `src/mcp/transports.ts`).
+54
View File
@@ -0,0 +1,54 @@
---
description: TypeScript coding conventions and style guidelines
globs: "**/*.ts,**/*.tsx"
alwaysApply: false
---
# TypeScript Conventions
## Module System
- This is an ESM project (`"type": "module"` in package.json).
- Always use ES module `import`/`export` syntax — never `require()`.
- When importing local modules, include the `.js` extension (TypeScript compiles `.ts` → `.js`):
```typescript
import { GrokAgent } from "./agent/grok-agent.js";
```
## TypeScript Configuration
- Target: ES2022, Module: ESNext, JSX: react
- `strict: false` and `noImplicitAny: false` — the codebase does not enforce strict mode.
- `moduleResolution: "Bundler"` is used.
- Source files live in `src/`, compiled output goes to `dist/`.
## Type Practices
- Prefer explicit interfaces for public API boundaries (e.g. `ChatEntry`, `ToolResult`, `GrokToolCall`).
- Use `type` imports when importing only types:
```typescript
import type { ChatCompletionMessageParam } from "openai/resources/chat";
```
- `any` is acceptable where strict typing would add friction, but prefer narrower types when practical.
- Shared types belong in `src/types/index.ts`.
## Naming Conventions
- **Files**: kebab-case (`grok-agent.ts`, `chat-interface.tsx`, `settings-manager.ts`).
- **Classes**: PascalCase (`GrokAgent`, `TextEditorTool`, `BashTool`).
- **Interfaces/Types**: PascalCase (`ChatEntry`, `ToolResult`, `StreamingChunk`).
- **Functions/variables**: camelCase (`processUserMessage`, `loadApiKey`).
- **Constants**: camelCase or UPPER_SNAKE_CASE for true constants (`GROK_TOOLS`).
## Error Handling
- Catch errors as `error: any` and access `.message` for display.
- Tool execution methods return `ToolResult` objects (`{ success, output?, error? }`) rather than throwing.
- Use `process.exit(1)` for fatal CLI errors.
## ESLint Rules
- `@typescript-eslint/no-unused-vars`: error
- `@typescript-eslint/no-explicit-any`: warn
Run `bun run lint` to check and `bun run typecheck` to verify types.
+4 -1
View File
@@ -99,4 +99,7 @@ temp/
# Coding agents
.claude/
.grok/
.grok/
# Cursor config (tracked — do not ignore)
# .cursor/