mirror of
https://github.com/coder/registry.git
synced 2026-06-04 21:48:16 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 443db3b7dc | |||
| 057d40554b | |||
| 0d73bb6588 | |||
| 2932fb482b | |||
| 6ce61c9acd | |||
| 6677432df7 | |||
| 142167f9c0 | |||
| 798cb1d79c |
@@ -0,0 +1,261 @@
|
|||||||
|
---
|
||||||
|
display_name: Cursor CLI
|
||||||
|
description: Run Cursor CLI agent in your workspace with MCP and force mode support
|
||||||
|
icon: ../../../../.icons/cursor.svg
|
||||||
|
verified: true
|
||||||
|
tags: [cli, cursor, ai, agent, mcp, automation]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Cursor CLI
|
||||||
|
|
||||||
|
Run the [Cursor CLI](https://docs.cursor.com/en/cli/overview) agent in your workspace for terminal-based AI coding assistance. Supports both interactive and non-interactive modes, MCP (Model Context Protocol), and automation features.
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "cursor-cli" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/cursor-cli/coder"
|
||||||
|
version = "1.0.0"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
folder = "/home/coder"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- You must add the [Coder Login](https://registry.coder.com/modules/coder-login) module to your template
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **CLI Agent**: Terminal-based AI coding assistant with interactive and non-interactive modes
|
||||||
|
- **AgentAPI Integration**: Web interface for CLI interactions
|
||||||
|
- **Interactive Mode**: Conversational sessions with text output
|
||||||
|
- **Non-Interactive Mode**: Automation-friendly for scripts and CI pipelines
|
||||||
|
- **Session Management**: List, resume, and manage coding sessions
|
||||||
|
- **Model Selection**: Support for multiple AI models (GPT-5, Claude, etc.)
|
||||||
|
- **MCP Support**: Model Context Protocol for extended functionality
|
||||||
|
- **Rules System**: Custom agent behavior configuration
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Basic setup
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "coder-login" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/coder-login/coder"
|
||||||
|
version = "1.0.15"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
}
|
||||||
|
|
||||||
|
module "cursor-cli" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/cursor-cli/coder"
|
||||||
|
version = "1.0.0"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
folder = "/home/coder/project"
|
||||||
|
install_cursor_cli = true
|
||||||
|
install_agentapi = true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI only (no web interface)
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "cursor-cli" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/cursor-cli/coder"
|
||||||
|
version = "1.0.0"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
folder = "/home/coder/project"
|
||||||
|
install_cursor_cli = true
|
||||||
|
install_agentapi = false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### With MCP and force mode for automation
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "cursor-cli" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/cursor-cli/coder"
|
||||||
|
version = "1.0.0"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
folder = "/home/coder/project"
|
||||||
|
|
||||||
|
# MCP Configuration
|
||||||
|
enable_mcp = true
|
||||||
|
mcp_config_path = "/home/coder/.cursor/custom-mcp.json"
|
||||||
|
|
||||||
|
# Automation Features
|
||||||
|
enable_force_mode = true
|
||||||
|
default_model = "gpt-5"
|
||||||
|
|
||||||
|
# Rules System
|
||||||
|
enable_rules = true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration with Coder Tasks
|
||||||
|
|
||||||
|
```tf
|
||||||
|
# Cursor CLI module with automation features
|
||||||
|
module "cursor-cli" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/cursor-cli/coder"
|
||||||
|
version = "1.0.0"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
enable_force_mode = true
|
||||||
|
default_model = "claude-4-sonnet"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Automated code review task
|
||||||
|
resource "coder_task" "ai_code_review" {
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
name = "AI Code Review"
|
||||||
|
command = "cursor-agent -p 'review the latest git changes for security issues and best practices' --force --output-format text"
|
||||||
|
cron = "0 9 * * 1-5" # Weekdays at 9 AM
|
||||||
|
}
|
||||||
|
|
||||||
|
# Automated test generation
|
||||||
|
resource "coder_task" "generate_tests" {
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
name = "Generate Missing Tests"
|
||||||
|
command = "cursor-agent -p 'analyze the src/ directory and generate unit tests for functions missing test coverage' --force"
|
||||||
|
cron = "0 18 * * *" # Daily at 6 PM
|
||||||
|
}
|
||||||
|
|
||||||
|
# Documentation updates
|
||||||
|
resource "coder_task" "update_docs" {
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
name = "Update Documentation"
|
||||||
|
command = "cursor-agent -p 'review and update README.md to reflect any new features or API changes' --force --model gpt-5"
|
||||||
|
cron = "0 12 * * 0" # Sundays at noon
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### With custom pre-install script
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "cursor-cli" {
|
||||||
|
count = data.coder_workspace.me.start_count
|
||||||
|
source = "registry.coder.com/coder/cursor-cli/coder"
|
||||||
|
version = "1.0.0"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
|
||||||
|
pre_install_script = <<-EOT
|
||||||
|
# Install additional dependencies
|
||||||
|
npm install -g typescript
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Web Interface
|
||||||
|
|
||||||
|
1. Click the "Cursor CLI" button to access the web interface
|
||||||
|
2. Start interactive sessions with text output
|
||||||
|
|
||||||
|
### Terminal Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Interactive mode (default)
|
||||||
|
cursor-agent
|
||||||
|
|
||||||
|
# Interactive mode with initial prompt
|
||||||
|
cursor-agent "refactor the auth module to use JWT tokens"
|
||||||
|
|
||||||
|
# Non-interactive mode with text output
|
||||||
|
cursor-agent -p "find and fix performance issues" --output-format text
|
||||||
|
|
||||||
|
# Force mode for automation (non-interactive)
|
||||||
|
cursor-agent -p "review code for security issues" --force
|
||||||
|
|
||||||
|
# Use specific model
|
||||||
|
cursor-agent -p "add error handling" --model "gpt-5"
|
||||||
|
|
||||||
|
# Combine force mode with model selection
|
||||||
|
cursor-agent -p "generate comprehensive tests" --force --model "claude-4-sonnet"
|
||||||
|
|
||||||
|
# Session management
|
||||||
|
cursor-agent ls # List all previous chats
|
||||||
|
cursor-agent resume # Resume latest conversation
|
||||||
|
cursor-agent --resume="chat-id" # Resume specific conversation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interactive Mode Features
|
||||||
|
|
||||||
|
- Conversational sessions with the agent
|
||||||
|
- Review proposed changes before applying
|
||||||
|
- Real-time guidance and steering
|
||||||
|
- Text-based output optimized for terminal use
|
||||||
|
- Session persistence and resumption
|
||||||
|
|
||||||
|
### Non-Interactive Mode Features
|
||||||
|
|
||||||
|
- Automation-friendly for scripts and CI pipelines
|
||||||
|
- Direct prompt execution with text output
|
||||||
|
- Model selection support
|
||||||
|
- Git integration for change reviews
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
### Cursor CLI with Coder Tasks Integration
|
||||||
|
|
||||||
|
*Screenshot showing the cursor-cli module working with automated Coder Tasks will be added here*
|
||||||
|
|
||||||
|
- Interactive web interface for cursor-agent
|
||||||
|
- Automated code review tasks running in background
|
||||||
|
- Terminal output showing force mode execution
|
||||||
|
- MCP integration with custom tools
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The module supports comprehensive configuration options:
|
||||||
|
|
||||||
|
### Core Features
|
||||||
|
- **MCP (Model Context Protocol)**: Automatically detects `mcp.json` configuration or uses custom path
|
||||||
|
- **Rules System**: Supports `.cursor/rules` directory for custom agent behavior
|
||||||
|
- **Force Mode**: Enable non-interactive automation for CI/CD pipelines
|
||||||
|
- **Model Selection**: Set default AI model (gpt-5, claude-4-sonnet, etc.)
|
||||||
|
- **Environment Variables**: Respects Cursor CLI environment settings
|
||||||
|
|
||||||
|
### Available Variables
|
||||||
|
|
||||||
|
| Variable | Type | Default | Description |
|
||||||
|
|----------|------|---------|-------------|
|
||||||
|
| `enable_mcp` | bool | `true` | Enable MCP (Model Context Protocol) support |
|
||||||
|
| `mcp_config_path` | string | `""` | Path to custom MCP configuration file |
|
||||||
|
| `enable_force_mode` | bool | `false` | Enable force mode for non-interactive automation |
|
||||||
|
| `default_model` | string | `""` | Default AI model (e.g., gpt-5, claude-4-sonnet) |
|
||||||
|
| `enable_rules` | bool | `true` | Enable the rules system (.cursor/rules directory) |
|
||||||
|
| `install_cursor_cli` | bool | `true` | Whether to install Cursor CLI |
|
||||||
|
| `install_agentapi` | bool | `true` | Whether to install AgentAPI web interface |
|
||||||
|
| `folder` | string | `"/home/coder"` | Working directory for cursor-agent |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
The module creates log files in the workspace's `~/.cursor-cli-module` directory. Check these files if you encounter issues:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check installation logs
|
||||||
|
cat ~/.cursor-cli-module/install.log
|
||||||
|
|
||||||
|
# Check runtime logs
|
||||||
|
cat ~/.cursor-cli-module/runtime.log
|
||||||
|
|
||||||
|
# Verify Cursor CLI installation
|
||||||
|
cursor-agent --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Cursor CLI not found**: Ensure `install_cursor_cli = true` or install manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://cursor.com/install -fsS | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Permission issues**: Check that the installation script has proper permissions
|
||||||
|
|
||||||
|
3. **Path issues**: The module automatically adds Cursor CLI to PATH, but you may need to restart your shell
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import { describe, expect, it } from "bun:test";
|
||||||
|
import {
|
||||||
|
runTerraformApply,
|
||||||
|
runTerraformInit,
|
||||||
|
testRequiredVariables,
|
||||||
|
} from "~test";
|
||||||
|
|
||||||
|
describe("cursor-cli", async () => {
|
||||||
|
await runTerraformInit(import.meta.dir);
|
||||||
|
|
||||||
|
testRequiredVariables(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
});
|
||||||
|
|
||||||
|
it("default output with CLI enabled", async () => {
|
||||||
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that AgentAPI module is created
|
||||||
|
const agentapi_module = state.resources.find(
|
||||||
|
(res) => res.type === "module" && res.name === "agentapi",
|
||||||
|
);
|
||||||
|
expect(agentapi_module).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("adds custom folder", async () => {
|
||||||
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
folder: "/foo/bar",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that AgentAPI module is created with custom folder
|
||||||
|
const agentapi_module = state.resources.find(
|
||||||
|
(res) => res.type === "module" && res.name === "agentapi",
|
||||||
|
);
|
||||||
|
expect(agentapi_module).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("expect order to be set", async () => {
|
||||||
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
order: "22",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that AgentAPI module is created
|
||||||
|
const agentapi_module = state.resources.find(
|
||||||
|
(res) => res.type === "module" && res.name === "agentapi",
|
||||||
|
);
|
||||||
|
expect(agentapi_module).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("disables CLI installation", async () => {
|
||||||
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
install_cursor_cli: "false",
|
||||||
|
install_agentapi: "false",
|
||||||
|
});
|
||||||
|
|
||||||
|
// AgentAPI module should still exist but with install_agentapi = false
|
||||||
|
const agentapi_module = state.resources.find(
|
||||||
|
(res) => res.type === "module" && res.name === "agentapi",
|
||||||
|
);
|
||||||
|
expect(agentapi_module).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("enables only CLI without web interface", async () => {
|
||||||
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
install_cursor_cli: "true",
|
||||||
|
install_agentapi: "false",
|
||||||
|
});
|
||||||
|
|
||||||
|
// AgentAPI module should exist but with install_agentapi = false
|
||||||
|
const agentapi_module = state.resources.find(
|
||||||
|
(res) => res.type === "module" && res.name === "agentapi",
|
||||||
|
);
|
||||||
|
expect(agentapi_module).not.toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
coder = {
|
||||||
|
source = "coder/coder"
|
||||||
|
version = ">= 2.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "agent_id" {
|
||||||
|
type = string
|
||||||
|
description = "The ID of a Coder agent."
|
||||||
|
}
|
||||||
|
|
||||||
|
data "coder_workspace" "me" {}
|
||||||
|
|
||||||
|
data "coder_workspace_owner" "me" {}
|
||||||
|
|
||||||
|
variable "order" {
|
||||||
|
type = number
|
||||||
|
description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)."
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "group" {
|
||||||
|
type = string
|
||||||
|
description = "The name of a group that this app belongs to."
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "icon" {
|
||||||
|
type = string
|
||||||
|
description = "The icon to use for the app."
|
||||||
|
default = "/icon/cursor.svg"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "folder" {
|
||||||
|
type = string
|
||||||
|
description = "The folder to run Cursor CLI in."
|
||||||
|
default = "/home/coder"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "install_cursor_cli" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to install Cursor CLI."
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "install_agentapi" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to install AgentAPI."
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "agentapi_version" {
|
||||||
|
type = string
|
||||||
|
description = "The version of AgentAPI to install."
|
||||||
|
default = "v0.3.3"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subdomain" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to use a subdomain for AgentAPI."
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pre_install_script" {
|
||||||
|
type = string
|
||||||
|
description = "Custom script to run before installing Cursor CLI."
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "post_install_script" {
|
||||||
|
type = string
|
||||||
|
description = "Custom script to run after installing Cursor CLI."
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "enable_mcp" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to enable MCP (Model Context Protocol) support."
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "mcp_config_path" {
|
||||||
|
type = string
|
||||||
|
description = "Path to the MCP configuration file (mcp.json)."
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "enable_force_mode" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to enable force mode for non-interactive automation."
|
||||||
|
default = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "default_model" {
|
||||||
|
type = string
|
||||||
|
description = "Default AI model to use (e.g., gpt-5, claude-4-sonnet)."
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "enable_rules" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to enable the rules system (.cursor/rules directory)."
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
app_slug = "cursor-cli"
|
||||||
|
install_script = file("${path.module}/scripts/install.sh")
|
||||||
|
start_script = file("${path.module}/scripts/start.sh")
|
||||||
|
module_dir_name = ".cursor-cli-module"
|
||||||
|
}
|
||||||
|
|
||||||
|
module "agentapi" {
|
||||||
|
source = "registry.coder.com/coder/agentapi/coder"
|
||||||
|
version = "1.1.0"
|
||||||
|
|
||||||
|
agent_id = var.agent_id
|
||||||
|
web_app_slug = local.app_slug
|
||||||
|
web_app_order = var.order
|
||||||
|
web_app_group = var.group
|
||||||
|
web_app_icon = var.icon
|
||||||
|
web_app_display_name = "Cursor CLI"
|
||||||
|
cli_app_slug = "${local.app_slug}-terminal"
|
||||||
|
cli_app_display_name = "Cursor CLI Terminal"
|
||||||
|
module_dir_name = local.module_dir_name
|
||||||
|
install_agentapi = var.install_agentapi
|
||||||
|
agentapi_version = var.agentapi_version
|
||||||
|
agentapi_subdomain = var.subdomain
|
||||||
|
pre_install_script = var.pre_install_script
|
||||||
|
post_install_script = var.post_install_script
|
||||||
|
start_script = local.start_script
|
||||||
|
install_script = <<-EOT
|
||||||
|
#!/bin/bash
|
||||||
|
set -o errexit
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
|
||||||
|
chmod +x /tmp/install.sh
|
||||||
|
|
||||||
|
ARG_FOLDER='${var.folder}' \
|
||||||
|
ARG_INSTALL='${var.install_cursor_cli}' \
|
||||||
|
ARG_ENABLE_MCP='${var.enable_mcp}' \
|
||||||
|
ARG_MCP_CONFIG_PATH='${var.mcp_config_path}' \
|
||||||
|
ARG_ENABLE_FORCE_MODE='${var.enable_force_mode}' \
|
||||||
|
ARG_DEFAULT_MODEL='${var.default_model}' \
|
||||||
|
ARG_ENABLE_RULES='${var.enable_rules}' \
|
||||||
|
/tmp/install.sh
|
||||||
|
EOT
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Function to check if a command exists
|
||||||
|
command_exists() {
|
||||||
|
command -v "$1" > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
echo "--------------------------------"
|
||||||
|
echo "folder: $ARG_FOLDER"
|
||||||
|
echo "install: $ARG_INSTALL"
|
||||||
|
echo "enable_mcp: $ARG_ENABLE_MCP"
|
||||||
|
echo "mcp_config_path: $ARG_MCP_CONFIG_PATH"
|
||||||
|
echo "enable_force_mode: $ARG_ENABLE_FORCE_MODE"
|
||||||
|
echo "default_model: $ARG_DEFAULT_MODEL"
|
||||||
|
echo "enable_rules: $ARG_ENABLE_RULES"
|
||||||
|
echo "--------------------------------"
|
||||||
|
|
||||||
|
set +o nounset
|
||||||
|
|
||||||
|
if [ "${ARG_INSTALL}" = "true" ]; then
|
||||||
|
echo "Installing Cursor CLI..."
|
||||||
|
|
||||||
|
# Install Cursor CLI using the official installer
|
||||||
|
curl https://cursor.com/install -fsS | bash
|
||||||
|
|
||||||
|
# Add cursor-agent to PATH if not already there
|
||||||
|
if ! command_exists cursor-agent; then
|
||||||
|
echo 'export PATH="$HOME/.cursor/bin:$PATH"' >> "$HOME/.bashrc"
|
||||||
|
echo 'export PATH="$HOME/.cursor/bin:$PATH"' >> "$HOME/.zshrc" 2> /dev/null || true
|
||||||
|
export PATH="$HOME/.cursor/bin:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cursor CLI installed"
|
||||||
|
|
||||||
|
# Configure MCP if enabled
|
||||||
|
if [ "${ARG_ENABLE_MCP}" = "true" ]; then
|
||||||
|
echo "Configuring MCP (Model Context Protocol)..."
|
||||||
|
|
||||||
|
# Create MCP config directory if it doesn't exist
|
||||||
|
mkdir -p "$HOME/.cursor"
|
||||||
|
|
||||||
|
# If custom MCP config path is provided, copy it
|
||||||
|
if [ -n "${ARG_MCP_CONFIG_PATH}" ] && [ -f "${ARG_MCP_CONFIG_PATH}" ]; then
|
||||||
|
cp "${ARG_MCP_CONFIG_PATH}" "$HOME/.cursor/mcp.json"
|
||||||
|
echo "MCP configuration copied from ${ARG_MCP_CONFIG_PATH}"
|
||||||
|
else
|
||||||
|
# Create a basic MCP config if none exists
|
||||||
|
if [ ! -f "$HOME/.cursor/mcp.json" ]; then
|
||||||
|
cat > "$HOME/.cursor/mcp.json" << 'EOF'
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"filesystem": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["@modelcontextprotocol/server-filesystem", "/tmp"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo "Basic MCP configuration created"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure rules system if enabled
|
||||||
|
if [ "${ARG_ENABLE_RULES}" = "true" ]; then
|
||||||
|
echo "Setting up Cursor rules system..."
|
||||||
|
mkdir -p "$HOME/.cursor/rules"
|
||||||
|
|
||||||
|
# Create a basic rules file if none exists
|
||||||
|
if [ ! -f "$HOME/.cursor/rules/general.md" ]; then
|
||||||
|
cat > "$HOME/.cursor/rules/general.md" << 'EOF'
|
||||||
|
# General Coding Rules
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
- Use consistent indentation (2 spaces for JS/TS, 4 for Python)
|
||||||
|
- Add meaningful comments for complex logic
|
||||||
|
- Follow language-specific naming conventions
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
- Write tests for new functionality
|
||||||
|
- Handle errors gracefully
|
||||||
|
- Use descriptive variable and function names
|
||||||
|
EOF
|
||||||
|
echo "Basic rules configuration created"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Skipping Cursor CLI installation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify installation
|
||||||
|
if command_exists cursor-agent; then
|
||||||
|
CURSOR_CMD=cursor-agent
|
||||||
|
elif [ -f "$HOME/.cursor/bin/cursor-agent" ]; then
|
||||||
|
CURSOR_CMD="$HOME/.cursor/bin/cursor-agent"
|
||||||
|
else
|
||||||
|
echo "Warning: Cursor CLI is not installed or not found in PATH. Please enable install_cursor_cli or install it manually."
|
||||||
|
echo "You can install it manually with: curl https://cursor.com/install -fsS | bash"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cursor CLI setup complete"
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Function to check if a command exists
|
||||||
|
command_exists() {
|
||||||
|
command -v "$1" > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
if [ -n "${ARG_FOLDER:-}" ] && [ -d "${ARG_FOLDER}" ]; then
|
||||||
|
cd "${ARG_FOLDER}" || {
|
||||||
|
echo "Warning: Could not change to directory ${ARG_FOLDER}, using current directory"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find cursor-agent command
|
||||||
|
if command_exists cursor-agent; then
|
||||||
|
CURSOR_CMD=cursor-agent
|
||||||
|
elif [ -f "$HOME/.cursor/bin/cursor-agent" ]; then
|
||||||
|
CURSOR_CMD="$HOME/.cursor/bin/cursor-agent"
|
||||||
|
else
|
||||||
|
echo "Error: Cursor CLI is not installed. Please enable install_cursor_cli or install it manually."
|
||||||
|
echo "You can install it manually with: curl https://cursor.com/install -fsS | bash"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting Cursor CLI in $(pwd)"
|
||||||
|
echo "Interactive mode with text output enabled"
|
||||||
|
echo "Available commands:"
|
||||||
|
echo " - Start interactive session: cursor-agent"
|
||||||
|
echo " - Non-interactive mode: cursor-agent -p 'your prompt here'"
|
||||||
|
echo " - With specific model: cursor-agent -p 'prompt' --model 'gpt-5'"
|
||||||
|
echo " - Text output format: cursor-agent -p 'prompt' --output-format text"
|
||||||
|
echo " - Force mode (non-interactive): cursor-agent -p 'prompt' --force"
|
||||||
|
echo " - List sessions: cursor-agent ls"
|
||||||
|
echo " - Resume session: cursor-agent resume"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Set up environment variables for configuration
|
||||||
|
if [ -n "${ARG_DEFAULT_MODEL:-}" ]; then
|
||||||
|
export CURSOR_DEFAULT_MODEL="${ARG_DEFAULT_MODEL}"
|
||||||
|
echo "Default model set to: ${ARG_DEFAULT_MODEL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ARG_ENABLE_FORCE_MODE:-false}" = "true" ]; then
|
||||||
|
export CURSOR_FORCE_MODE="true"
|
||||||
|
echo "Force mode enabled for non-interactive automation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ARG_ENABLE_MCP:-true}" = "true" ]; then
|
||||||
|
echo "MCP (Model Context Protocol) support enabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ARG_ENABLE_RULES:-true}" = "true" ]; then
|
||||||
|
echo "Rules system enabled (.cursor/rules directory)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Configure for interactive mode with text output
|
||||||
|
# If no arguments provided, start in interactive mode
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "Starting interactive session..."
|
||||||
|
exec "$CURSOR_CMD"
|
||||||
|
else
|
||||||
|
# Pass through all arguments for custom usage
|
||||||
|
exec "$CURSOR_CMD" "$@"
|
||||||
|
fi
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Find all directories that contain any .tftest.hcl files and run terraform test in each
|
||||||
|
|
||||||
|
run_dir() {
|
||||||
|
local dir="$1"
|
||||||
|
echo "==> Running terraform test in $dir"
|
||||||
|
(cd "$dir" && terraform init -upgrade -input=false -no-color > /dev/null && terraform test -no-color -verbose)
|
||||||
|
}
|
||||||
|
|
||||||
|
mapfile -t test_dirs < <(find . -type f -name "*.tftest.hcl" -print0 | xargs -0 -I{} dirname {} | sort -u)
|
||||||
|
|
||||||
|
if [[ ${#test_dirs[@]} -eq 0 ]]; then
|
||||||
|
echo "No .tftest.hcl tests found."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=0
|
||||||
|
for d in "${test_dirs[@]}"; do
|
||||||
|
if ! run_dir "$d"; then
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $status
|
||||||
Reference in New Issue
Block a user