refactor: rename coding-agent executor to cursor-agent (closes #33)
- Rename coding-agent.ts → cursor-agent.ts - Rename coding-agent.test.ts → cursor-agent.test.ts - Rename CodingEffect → CursorEffect - Rename createCodingExecutor → createCursorExecutor - Update all imports, re-exports, and CONTRIBUTING.md references Made-with: Cursor Co-authored-by: 小橘 <xiaoju@shazhou.work>
This commit is contained in:
+18
-18
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Tests for coding-agent executor.
|
||||
* Tests for cursor-agent executor.
|
||||
*
|
||||
* Uses stub binaries to avoid actually spawning Cursor Agent.
|
||||
* Verifies prompt file content, error handling, and result structure.
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { type CodingEffect, createCodingExecutor } from './coding-agent.js';
|
||||
import { type CursorEffect, createCursorExecutor } from './cursor-agent.js';
|
||||
|
||||
const TEST_TMP = join(tmpdir(), `pulse-coding-test-${process.pid}`);
|
||||
const STUB_DIR = join(TEST_TMP, 'stubs');
|
||||
@@ -38,7 +38,7 @@ function makeStub(name: string, script: string): string {
|
||||
return path;
|
||||
}
|
||||
|
||||
function makeEffect(overrides?: Partial<CodingEffect>): CodingEffect {
|
||||
function makeEffect(overrides?: Partial<CursorEffect>): CursorEffect {
|
||||
return {
|
||||
type: 'coding-task',
|
||||
prompt: 'Fix the broken test in store.test.ts',
|
||||
@@ -48,9 +48,9 @@ function makeEffect(overrides?: Partial<CodingEffect>): CodingEffect {
|
||||
};
|
||||
}
|
||||
|
||||
describe('createCodingExecutor', () => {
|
||||
describe('createCursorExecutor', () => {
|
||||
test('returns a function', () => {
|
||||
const exec = createCodingExecutor({ tmpDir: TEST_TMP });
|
||||
const exec = createCursorExecutor({ tmpDir: TEST_TMP });
|
||||
expect(typeof exec).toBe('function');
|
||||
});
|
||||
|
||||
@@ -76,20 +76,20 @@ describe('createCodingExecutor', () => {
|
||||
|
||||
test('rejects unexpected effect type', async () => {
|
||||
const agentStub = makeStub('agent-type-check', 'exit 0');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'test-key',
|
||||
agentBin: agentStub,
|
||||
});
|
||||
|
||||
const badEffect = { ...makeEffect(), type: 'other-task' } as CodingEffect;
|
||||
const badEffect = { ...makeEffect(), type: 'other-task' } as CursorEffect;
|
||||
expect(exec(badEffect)).rejects.toThrow('Unexpected effect type');
|
||||
});
|
||||
});
|
||||
|
||||
describe('CodingEffect structure', () => {
|
||||
describe('CursorEffect structure', () => {
|
||||
test('required fields', () => {
|
||||
const effect: CodingEffect = {
|
||||
const effect: CursorEffect = {
|
||||
type: 'coding-task',
|
||||
prompt: 'do something',
|
||||
scenario: 'debug',
|
||||
@@ -103,7 +103,7 @@ describe('CodingEffect structure', () => {
|
||||
});
|
||||
|
||||
test('optional timeoutMs', () => {
|
||||
const effect: CodingEffect = {
|
||||
const effect: CursorEffect = {
|
||||
type: 'coding-task',
|
||||
prompt: 'do something',
|
||||
scenario: 'ci-fix',
|
||||
@@ -145,7 +145,7 @@ describe('prompt assembly', () => {
|
||||
// Stub reads the prompt file path (last positional arg) and cats it
|
||||
const catLastArg = 'cat "$' + '{@: -1}"';
|
||||
const agentStub = makeStub(`agent-${scenario}`, catLastArg);
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'test-api-key',
|
||||
agentBin: agentStub,
|
||||
@@ -162,7 +162,7 @@ describe('prompt assembly', () => {
|
||||
describe('temp file cleanup', () => {
|
||||
test('prompt file is deleted after execution', async () => {
|
||||
const agentStub = makeStub('agent-cleanup', 'exit 0');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'test-key',
|
||||
agentBin: agentStub,
|
||||
@@ -179,7 +179,7 @@ describe('temp file cleanup', () => {
|
||||
|
||||
test('prompt file is deleted even on failure', async () => {
|
||||
const agentStub = makeStub('agent-cleanup-fail', 'exit 1');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'test-key',
|
||||
agentBin: agentStub,
|
||||
@@ -197,7 +197,7 @@ describe('temp file cleanup', () => {
|
||||
|
||||
describe('error handling', () => {
|
||||
test('missing apiKey and failed apiKeyCommand throws', async () => {
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKeyCommand: '/nonexistent/path/to/binary',
|
||||
agentBin: '/bin/echo',
|
||||
@@ -211,7 +211,7 @@ describe('error handling', () => {
|
||||
|
||||
test('agent exit code 1 returns success=false', async () => {
|
||||
const failStub = makeStub('agent-fail', 'exit 1');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'test-key',
|
||||
agentBin: failStub,
|
||||
@@ -225,7 +225,7 @@ describe('error handling', () => {
|
||||
|
||||
test('agent exit code 0 returns success=true', async () => {
|
||||
const okStub = makeStub('agent-ok', 'echo "task done"; exit 0');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'test-key',
|
||||
agentBin: okStub,
|
||||
@@ -244,7 +244,7 @@ describe('API key caching', () => {
|
||||
test('apiKey is resolved once and cached', async () => {
|
||||
const keyStub = makeStub('key-counter', `echo "cached-key-$(date +%s%N)"`);
|
||||
const agentStub = makeStub('agent-cache', 'exit 0');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKeyCommand: keyStub,
|
||||
agentBin: agentStub,
|
||||
@@ -259,7 +259,7 @@ describe('API key caching', () => {
|
||||
|
||||
test('direct apiKey skips command resolution', async () => {
|
||||
const agentStub = makeStub('agent-direct', 'exit 0');
|
||||
const exec = createCodingExecutor({
|
||||
const exec = createCursorExecutor({
|
||||
tmpDir: TEST_TMP,
|
||||
apiKey: 'direct-key',
|
||||
apiKeyCommand: '/nonexistent/should-not-be-called',
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* executors/coding-agent.ts — Coding Agent Executor
|
||||
* executors/cursor-agent.ts — Cursor Agent Executor
|
||||
*
|
||||
* Spawns a Cursor Agent CLI process to execute coding tasks.
|
||||
* The executor is intentionally thin: it only translates a CodingEffect
|
||||
* The executor is intentionally thin: it only translates a CursorEffect
|
||||
* into a CLI invocation. All intelligence (clone, branch, test, PR)
|
||||
* lives in the coding agent driven by repo conventions and scenario prompts.
|
||||
*
|
||||
@@ -22,7 +22,7 @@ export type CodingScenario =
|
||||
| 'ci-fix'
|
||||
| 'refactor';
|
||||
|
||||
export interface CodingEffect {
|
||||
export interface CursorEffect {
|
||||
type: 'coding-task';
|
||||
/** Task description assembled by the triggering Rule. */
|
||||
prompt: string;
|
||||
@@ -96,10 +96,10 @@ const SCENARIO_PREAMBLES: Record<CodingScenario, string> = {
|
||||
/**
|
||||
* Create a coding agent executor with the given options.
|
||||
*
|
||||
* Returns an async function that accepts a CodingEffect and spawns
|
||||
* Returns an async function that accepts a CursorEffect and spawns
|
||||
* the Cursor Agent CLI to execute the task.
|
||||
*/
|
||||
export function createCodingExecutor(opts: CodingExecutorOptions = {}) {
|
||||
export function createCursorExecutor(opts: CodingExecutorOptions = {}) {
|
||||
const {
|
||||
agentBin = `${process.env.HOME}/.local/bin/agent`,
|
||||
apiKey: directApiKey,
|
||||
@@ -111,7 +111,7 @@ export function createCodingExecutor(opts: CodingExecutorOptions = {}) {
|
||||
let cachedApiKey: string | undefined = directApiKey;
|
||||
|
||||
return async function executeCodingTask(
|
||||
effect: CodingEffect,
|
||||
effect: CursorEffect,
|
||||
): Promise<CodingResult> {
|
||||
if (effect.type !== 'coding-task') {
|
||||
throw new Error(`Unexpected effect type: ${effect.type}`);
|
||||
@@ -1,7 +1,7 @@
|
||||
export {
|
||||
type CodingEffect,
|
||||
type CodingExecutorOptions,
|
||||
type CodingResult,
|
||||
type CodingScenario,
|
||||
createCodingExecutor,
|
||||
} from './coding-agent.js';
|
||||
type CursorEffect,
|
||||
createCursorExecutor,
|
||||
} from './cursor-agent.js';
|
||||
|
||||
Reference in New Issue
Block a user