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
40 changes: 40 additions & 0 deletions .github/workflows/publish-cursor-extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish Cursor Extension

on:
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"
cache: "yarn"
cache-dependency-path: "agent-support/cursor/yarn.lock"

- name: Install Task
uses: arduino/setup-task@v1
with:
version: "3.x"

- name: Publish Cursor Extension
run: task cursor:publish
working-directory: ${{ github.workspace }}
env:
OVSX_TOKEN: ${{ secrets.OVSX_TOKEN }}

- name: Upload Extension Artifact
uses: actions/upload-artifact@v4
with:
name: cursor-git-ai-extension
path: agent-support/cursor/cursor-git-ai.vsix
retention-days: 30
37 changes: 16 additions & 21 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
version: "3"
tasks:
# CLI
build:
desc: Build the project in release mode (native Apple Silicon)
cmds:
Expand All @@ -13,30 +14,24 @@ tasks:
desc: Clean build artifacts
cmds:
- cargo clean

check:
desc: Check code without building
cmds:
- cargo check

clippy:
desc: Run clippy linter
cmds:
- cargo clippy -- -D warnings

fmt:
desc: Format code
cmds:
- cargo fmt

fmt:check:
desc: Check code formatting
cmds:
- cargo fmt -- --check

release:local:
desc: Build release and install to user bin directory
deps: [build]
cmds:
- cp target/release/git-ai ~/.local/bin/git-ai
- chmod +x ~/.local/bin/git-ai

# Extensions
cursor:build:
desc: Build the cursor extension
dir: agent-support/cursor
cmds:
- yarn install
- yarn run compile
cursor:publish:
desc: publish the cursor extension
deps: [cursor:build]
dir: agent-support/cursor
cmds:
- npx vsce package --out cursor-git-ai.vsix
- npx ovsx publish cursor-git-ai.vsix
5 changes: 5 additions & 0 deletions agent-support/cursor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
out
dist
node_modules
.vscode-test/
*.vsix
5 changes: 5 additions & 0 deletions agent-support/cursor/.vscode-test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { defineConfig } from '@vscode/test-cli';

export default defineConfig({
files: 'out/test/**/*.test.js',
});
8 changes: 8 additions & 0 deletions agent-support/cursor/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"dbaeumer.vscode-eslint",
"ms-vscode.extension-test-runner"
]
}
21 changes: 21 additions & 0 deletions agent-support/cursor/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
}
]
}
11 changes: 11 additions & 0 deletions agent-support/cursor/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}
20 changes: 20 additions & 0 deletions agent-support/cursor/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
11 changes: 11 additions & 0 deletions agent-support/cursor/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.vscode/**
.vscode-test/**
src/**
.gitignore
.yarnrc
vsc-extension-quickstart.md
**/tsconfig.json
**/eslint.config.mjs
**/*.map
**/*.ts
**/.vscode-test.*
1 change: 1 addition & 0 deletions agent-support/cursor/.yarnrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--ignore-engines true
9 changes: 9 additions & 0 deletions agent-support/cursor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Change Log

All notable changes to the "cursor-git-ai" extension will be documented in this file.

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## [Unreleased]

- Initial release
1 change: 1 addition & 0 deletions agent-support/cursor/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MIT
31 changes: 31 additions & 0 deletions agent-support/cursor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# VSCode / Cursor `git-ai` extension

A VS Code extension that tracks AI-generated code using [git-ai](https://github.com/acunniffe/git-ai).

## Workaround Alert

Cursor does not expose any of its composer events or any hooks for `PostEdit` ([upvote this Feature Request](https://forum.cursor.com/t/request-hooks-support-post-edit-pre-edit-etc/114716) to help).

In an ideal world this extension would be able to listen for events like `onAIChangesAccepted` or `onAIChangesApplied`, but instead we are forced to use hueristics.

1. All single charecter inserts AND code changes trigged by paste, undo or redo shortcuts will be debounced for 4 seconds then trigger a human edit checkpoint.
2. All multi-line edits, not triggered by paste, undo or redo will immediatly trigger an AI edit checkpoint.

Known limitations:

- Checking out new HEADs may trigger an AI checkpoint on ustaged changes. Stash first.

You can enable toast messages from the extension when it calls checkpoints to get a feel for the effectiveness of the hueritics add this option to your settings:

```json
"cursorGitAi.enableCheckpointLogging: true"
```

## Installation

1. **Install the extension** in Cursor
2. **Install [`git-ai`](https://github.com/acunniffe/git-ai)** `curl -sSL https://gitai.run/install.sh | bash`
3. **Ensure `git-ai` is on your PATH** so the extension can find it
4. **Restart Cursor**

## License
28 changes: 28 additions & 0 deletions agent-support/cursor/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";

export default [{
files: ["**/*.ts"],
}, {
plugins: {
"@typescript-eslint": typescriptEslint,
},

languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: "module",
},

rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],

curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}];
105 changes: 105 additions & 0 deletions agent-support/cursor/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"name": "cursor-git-ai",
"displayName": "git-ai for Cursor",
"description": "Keep track of code generated by AI.",
"version": "0.0.1",
"publisher": "acunniffe",
"repository": {
"type": "git",
"url": "https://github.com/acunniffe/git-ai"
},
"engines": {
"vscode": "1.99.3",
"node": ">=20.18.1"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./out/extension.js",
"contributes": {
"configuration": {
"title": "Cursor Git AI",
"properties": {
"cursorGitAi.enableCheckpointLogging": {
"type": "boolean",
"default": false,
"description": "Enable notifications for AI and human edit detection"
}
}
},
"commands": [
{
"command": "cursor-git-ai.pasteWithDetection",
"title": "Paste with AI Detection"
},
{
"command": "cursor-git-ai.undoWithDetection",
"title": "Undo with AI Detection"
},
{
"command": "cursor-git-ai.redoWithDetection",
"title": "Redo with AI Detection"
}
],
"keybindings": [
{
"command": "cursor-git-ai.pasteWithDetection",
"key": "ctrl+v",
"when": "editorTextFocus"
},
{
"command": "cursor-git-ai.pasteWithDetection",
"key": "cmd+v",
"when": "editorTextFocus"
},
{
"command": "cursor-git-ai.undoWithDetection",
"key": "ctrl+z",
"when": "editorTextFocus"
},
{
"command": "cursor-git-ai.undoWithDetection",
"key": "cmd+z",
"when": "editorTextFocus"
},
{
"command": "cursor-git-ai.redoWithDetection",
"key": "ctrl+shift+z",
"when": "editorTextFocus"
},
{
"command": "cursor-git-ai.redoWithDetection",
"key": "cmd+shift+z",
"when": "editorTextFocus"
}
]
},
"scripts": {
"vscode:prepublish": "yarn run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "yarn run compile && yarn run lint",
"lint": "eslint src",
"test": "vscode-test"
},
"dependencies": {
"lodash.debounce": "4.0.8"
},
"devDependencies": {
"ovsx": "0.10.4",
"@vscode/vsce": "3.6.0",
"@types/vscode": "1.99.1",
"@types/mocha": "^10.0.10",
"@types/node": "20.x",
"@types/lodash.debounce": "4.0.9",
"@typescript-eslint/eslint-plugin": "^8.31.1",
"@typescript-eslint/parser": "^8.31.1",
"eslint": "^9.25.1",
"typescript": "^5.8.3",
"@vscode/test-cli": "^0.0.11",
"@vscode/test-electron": "^2.5.2"
}
}
Loading
Loading