-
Notifications
You must be signed in to change notification settings - Fork 73
Add new cursor-cli module #306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
798cb1d
142167f
6677432
6ce61c9
2932fb4
0d73bb6
057d405
443db3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
--- | ||
display_name: Cursor CLI | ||
description: Run Cursor CLI agent in your workspace | ||
icon: ../../../../.icons/cursor.svg | ||
verified: true | ||
tags: [cli, cursor, ai, agent] | ||
--- | ||
|
||
# Cursor CLI | ||
|
||
Run the [Cursor CLI](https://docs.cursor.com/en/cli/overview) agent in your workspace for terminal-based AI coding assistance. | ||
|
||
```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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have an example of how to use with Coder Tasks? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely! I'll add a comprehensive example showing how to integrate cursor-cli with Coder Tasks for automated workflows. This will include both interactive and non-interactive usage patterns. |
||
|
||
### 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 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 | ||
|
||
# Use specific model | ||
cursor-agent -p "add error handling" --model "gpt-5" | ||
|
||
# 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 | ||
|
||
## Configuration | ||
|
||
The module supports the same configuration options as the Cursor CLI: | ||
|
||
- **MCP (Model Context Protocol)**: Automatically detects `mcp.json` configuration | ||
- **Rules System**: Supports `.cursor/rules` directory for custom agent behavior | ||
- **Environment Variables**: Respects Cursor CLI environment settings | ||
|
||
## 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
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 | ||
} | ||
|
||
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}' \ | ||
/tmp/install.sh | ||
EOT | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a screenshot with this and Coder Tasks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea! I'll add a screenshot showing the cursor-cli module working with Coder Tasks. Let me set that up and add it to the README.