@twelvehart/cursor-agents 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TwelveHart
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,306 @@
1
+ # cursor-agents
2
+
3
+ TypeScript SDK and CLI for the [Cursor Cloud Agents API](https://api.cursor.com).
4
+
5
+ Create, manage, and monitor AI coding agents that work autonomously on your GitHub repositories.
6
+
7
+ ## Installation
8
+
9
+ Until the first npm release is published, install from a local tarball:
10
+
11
+ ```bash
12
+ npm pack
13
+ npm install -g ./twelvehart-cursor-agents-0.1.0.tgz
14
+ cursor-agents --help
15
+ ```
16
+
17
+ After the package is published, install it from npm:
18
+
19
+ ```bash
20
+ npm install -g @twelvehart/cursor-agents
21
+ bun add @twelvehart/cursor-agents
22
+ ```
23
+
24
+ The package installs the `cursor-agents` CLI binary:
25
+
26
+ ```bash
27
+ npx @twelvehart/cursor-agents --help
28
+ cursor-agents --help
29
+ ```
30
+
31
+ ### CLI Packaging
32
+
33
+ The published package ships a Node entrypoint at `bin/cursor-agents.js` that loads the built CLI bundle from `dist/cli/index.js`. That keeps `cursor-agents` self-contained for global installs, `npx`, and `bunx` without requiring users to execute the TypeScript source directly.
34
+
35
+ Or clone and use directly:
36
+
37
+ ```bash
38
+ git clone https://github.com/ASRagab/cursor-agents-sdk-ts.git
39
+ cd cursor-agents-sdk-ts
40
+ bun install
41
+ node bin/cursor-agents.js --help
42
+ ```
43
+
44
+ ## Authentication
45
+
46
+ Get an API key from the [Cursor Dashboard](https://cursor.com/dashboard).
47
+
48
+ ```bash
49
+ export CURSOR_API_KEY="your-key-here"
50
+ ```
51
+
52
+ The SDK and CLI also read `CURSOR_API_KEY` and `CURSOR_BASE_URL` from a local `.env` file in the current working directory:
53
+
54
+ ```dotenv
55
+ CURSOR_API_KEY=your-key-here
56
+ CURSOR_BASE_URL=https://api.cursor.com
57
+ ```
58
+
59
+ ## SDK Usage
60
+
61
+ ```typescript
62
+ import { CursorAgents } from "@twelvehart/cursor-agents";
63
+
64
+ const client = new CursorAgents();
65
+ // Or: new CursorAgents({ apiKey: "cur_..." })
66
+
67
+ // Create an agent
68
+ const agent = await client.agents.create({
69
+ prompt: { text: "Fix the failing tests in src/utils.ts" },
70
+ source: { repository: "https://github.com/owner/repo", ref: "main" },
71
+ model: "claude-4-sonnet-thinking",
72
+ target: { autoCreatePr: true },
73
+ });
74
+
75
+ // Wait for completion
76
+ const result = await client.agents.waitFor(agent.id, {
77
+ onStatus: (a) => console.log(`Status: ${a.status}`),
78
+ });
79
+
80
+ // Watch conversation in real-time
81
+ const final = await client.agents.watch(agent.id, {
82
+ onMessage: (msg) => console.log(`[${msg.type}] ${msg.text}`),
83
+ });
84
+
85
+ // Get conversation history
86
+ const convo = await client.agents.conversation(agent.id);
87
+
88
+ // List and download artifacts
89
+ const artifacts = await client.agents.artifacts.list(agent.id);
90
+ const download = await client.agents.artifacts.downloadUrl(
91
+ agent.id,
92
+ artifacts.artifacts[0].absolutePath,
93
+ );
94
+
95
+ // Metadata
96
+ const me = await client.me();
97
+ const models = await client.models();
98
+ const repos = await client.repositories();
99
+ ```
100
+
101
+ ## Publishing
102
+
103
+ This repository is set up to publish `@twelvehart/cursor-agents` from GitHub Actions when a `v*` tag is pushed. The publish workflow runs lint, typecheck, unit tests, a build, a CLI smoke test, and `npm pack --dry-run` before publishing.
104
+
105
+ To make the workflow actually publish on npm, configure npm trusted publishing for the `@twelvehart/cursor-agents` package and point it at `.github/workflows/publish.yml`. npm’s current docs recommend trusted publishing with GitHub-hosted runners and `id-token: write` instead of long-lived `NPM_TOKEN` secrets.
106
+
107
+ ## CLI Usage
108
+
109
+ ### Global Flags
110
+
111
+ | Flag | Env Var | Description |
112
+ |------|---------|-------------|
113
+ | `--json` | — | Output structured JSON |
114
+ | `--api-key <key>` | `CURSOR_API_KEY` | API key |
115
+ | `--base-url <url>` | `CURSOR_BASE_URL` | Override API base URL |
116
+ | `--quiet` | — | Suppress non-essential output |
117
+
118
+ ### Commands
119
+
120
+ ```bash
121
+ # Authentication
122
+ cursor-agents auth whoami
123
+
124
+ # List available models and repos
125
+ cursor-agents models
126
+ cursor-agents repos
127
+
128
+ # Create an agent
129
+ cursor-agents create \
130
+ --repo owner/repo \
131
+ --ref main \
132
+ --prompt "Fix the failing tests" \
133
+ --model claude-4-sonnet-thinking \
134
+ --auto-pr
135
+
136
+ # Full GitHub URLs also work
137
+ cursor-agents create \
138
+ --repo https://github.com/owner/repo \
139
+ --ref main \
140
+ --prompt "Fix the failing tests"
141
+
142
+ # Create from a PR
143
+ cursor-agents create \
144
+ --pr https://github.com/owner/repo/pull/42 \
145
+ --prompt "Review and fix the issues"
146
+
147
+ # --auto-branch is only valid with --pr
148
+ cursor-agents create \
149
+ --pr https://github.com/owner/repo/pull/42 \
150
+ --prompt "Address review feedback" \
151
+ --auto-branch
152
+
153
+ # Use a prompt file for long prompts
154
+ cursor-agents create \
155
+ --repo https://github.com/owner/repo \
156
+ --prompt-file ./task.md
157
+
158
+ # Include images
159
+ cursor-agents create \
160
+ --repo https://github.com/owner/repo \
161
+ --prompt "Fix the layout shown in this screenshot" \
162
+ --image ./screenshot.png
163
+
164
+ # Create and wait for completion
165
+ cursor-agents create \
166
+ --repo https://github.com/owner/repo \
167
+ --prompt "Add error handling" \
168
+ --wait
169
+
170
+ # Create and watch conversation
171
+ cursor-agents create \
172
+ --repo https://github.com/owner/repo \
173
+ --prompt "Refactor the auth module" \
174
+ --watch
175
+
176
+ # List agents
177
+ cursor-agents list
178
+ cursor-agents list --limit 50 --pr https://github.com/owner/repo/pull/1
179
+
180
+ # Get agent status
181
+ cursor-agents status <agent-id>
182
+
183
+ # Wait for an agent
184
+ cursor-agents wait <agent-id> --timeout 300000
185
+
186
+ # Watch conversation messages
187
+ cursor-agents watch <agent-id>
188
+
189
+ # Send followup instruction
190
+ cursor-agents followup <agent-id> --prompt "Also update the README"
191
+ cursor-agents followup <agent-id> --prompt-file ./followup.md
192
+
193
+ # Stop / delete
194
+ cursor-agents stop <agent-id>
195
+ cursor-agents delete <agent-id>
196
+
197
+ # View conversation
198
+ cursor-agents conversation <agent-id>
199
+
200
+ # List and download artifacts
201
+ cursor-agents artifacts <agent-id>
202
+ cursor-agents download <agent-id> /workspace/src/index.ts --output ./index.ts
203
+ ```
204
+
205
+ ### JSON Output
206
+
207
+ When `--json` is passed, all output is structured:
208
+
209
+ ```json
210
+ { "ok": true, "data": { "id": "agent_123", "status": "FINISHED" } }
211
+ ```
212
+
213
+ On error:
214
+
215
+ ```json
216
+ { "ok": false, "error": { "code": "not_found", "message": "Agent not found", "status": 404 } }
217
+ ```
218
+
219
+ ### Exit Codes
220
+
221
+ | Code | Meaning |
222
+ |------|---------|
223
+ | 0 | Success |
224
+ | 1 | General error |
225
+ | 2 | Auth error |
226
+ | 3 | Not found |
227
+ | 4 | Rate limited |
228
+ | 5 | Timeout |
229
+
230
+ ### Coding Agent Skill
231
+
232
+ The repository includes an agent skill at [`skills/cursor-agents-cli/SKILL.md`](skills/cursor-agents-cli/SKILL.md).
233
+ This file teaches agents like Claude Code, Codex, Cursor, and others how to operate the CLI:
234
+ flag rules, workflow recipes, error recovery, and the JSON output contract.
235
+
236
+ Install via the [`npx skills`](https://github.com/vercel-labs/skills) ecosystem:
237
+
238
+ ```bash
239
+ # Install to all detected agents
240
+ npx skills add ASRagab/cursor-agents-sdk-ts
241
+
242
+ # Install to a specific agent
243
+ npx skills add ASRagab/cursor-agents-sdk-ts -a claude-code
244
+
245
+ # Install to a specific agent globally
246
+ npx skills add ASRagab/cursor-agents-sdk-ts -a claude-code -g
247
+
248
+ # List available skills first
249
+ npx skills add ASRagab/cursor-agents-sdk-ts --list
250
+ ```
251
+
252
+ Or copy the file manually into your agent's skills directory (e.g., `.claude/skills/` for Claude Code).
253
+
254
+ ## SDK API Reference
255
+
256
+ ### `CursorAgents(opts?)`
257
+
258
+ | Option | Type | Default | Description |
259
+ |--------|------|---------|-------------|
260
+ | `apiKey` | `string` | `CURSOR_API_KEY` env | API key |
261
+ | `baseUrl` | `string` | `https://api.cursor.com` | API base URL |
262
+
263
+ ### Agent Methods
264
+
265
+ | Method | Description |
266
+ |--------|-------------|
267
+ | `agents.create(opts)` | Launch an agent |
268
+ | `agents.list(opts?)` | List agents (paginated) |
269
+ | `agents.get(id)` | Get agent status |
270
+ | `agents.delete(id)` | Delete agent |
271
+ | `agents.stop(id)` | Stop running agent |
272
+ | `agents.followup(id, opts)` | Send followup instruction |
273
+ | `agents.conversation(id)` | Get conversation history |
274
+ | `agents.waitFor(id, opts?)` | Poll until terminal state |
275
+ | `agents.watch(id, opts?)` | Tail conversation messages |
276
+
277
+ ### Artifact Methods
278
+
279
+ | Method | Description |
280
+ |--------|-------------|
281
+ | `agents.artifacts.list(agentId)` | List artifacts |
282
+ | `agents.artifacts.downloadUrl(agentId, path)` | Get presigned download URL |
283
+
284
+ ### Metadata Methods
285
+
286
+ | Method | Description |
287
+ |--------|-------------|
288
+ | `me()` | API key info |
289
+ | `models()` | Available models |
290
+ | `repositories()` | Accessible GitHub repos |
291
+
292
+ ## Development
293
+
294
+ ```bash
295
+ bun install
296
+ bun run typecheck # TypeScript type checking
297
+ bun run lint # Biome linter
298
+ bun test # Unit tests
299
+ bun test tests/integration # Integration tests (needs CURSOR_API_KEY)
300
+ bun run build # Build the SDK, CLI bundle, and type declarations
301
+ npm pack --dry-run # Verify published package contents
302
+ ```
303
+
304
+ ## License
305
+
306
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "../dist/cli/index.js";
@@ -0,0 +1,43 @@
1
+ import type { BaseClient } from "./client";
2
+ import { type Agent, type Conversation, type ConversationMessage, type CreateAgentResponse, type IdResponse, type ListAgentsResponse, type Prompt, type Target } from "./schemas";
3
+ export interface CreateAgentOpts {
4
+ prompt: Prompt;
5
+ source: {
6
+ repository: string;
7
+ ref?: string;
8
+ } | {
9
+ prUrl: string;
10
+ };
11
+ model?: string;
12
+ target?: Target;
13
+ }
14
+ export interface ListAgentsOpts {
15
+ limit?: number;
16
+ cursor?: string;
17
+ prUrl?: string;
18
+ }
19
+ export interface WaitForOpts {
20
+ intervalMs?: number;
21
+ timeoutMs?: number;
22
+ onStatus?: (agent: Agent) => void;
23
+ }
24
+ export interface WatchOpts {
25
+ intervalMs?: number;
26
+ onMessage?: (msg: ConversationMessage) => void;
27
+ onStatus?: (agent: Agent) => void;
28
+ }
29
+ export declare class AgentsAPI {
30
+ private readonly client;
31
+ constructor(client: BaseClient);
32
+ create(opts: CreateAgentOpts): Promise<CreateAgentResponse>;
33
+ list(opts?: ListAgentsOpts): Promise<ListAgentsResponse>;
34
+ get(id: string): Promise<Agent>;
35
+ delete(id: string): Promise<IdResponse>;
36
+ stop(id: string): Promise<IdResponse>;
37
+ followup(id: string, opts: {
38
+ prompt: Prompt;
39
+ }): Promise<IdResponse>;
40
+ conversation(id: string): Promise<Conversation>;
41
+ waitFor(id: string, opts?: WaitForOpts): Promise<Agent>;
42
+ watch(id: string, opts?: WatchOpts): Promise<Agent>;
43
+ }
@@ -0,0 +1,8 @@
1
+ import type { BaseClient } from "./client";
2
+ import { type DownloadArtifactResponse, type ListArtifactsResponse } from "./schemas";
3
+ export declare class ArtifactsAPI {
4
+ private readonly client;
5
+ constructor(client: BaseClient);
6
+ list(agentId: string): Promise<ListArtifactsResponse>;
7
+ downloadUrl(agentId: string, absolutePath: string): Promise<DownloadArtifactResponse>;
8
+ }
@@ -0,0 +1,23 @@
1
+ import type { Command } from "commander";
2
+ import type { CursorAgents } from "../../index";
3
+ export declare function normalizeRepositoryInput(input: string): string;
4
+ export declare function validateCreateOptions(opts: {
5
+ pr?: string;
6
+ repo?: string;
7
+ ref?: string;
8
+ prompt?: string;
9
+ promptFile?: string;
10
+ autoPr?: boolean;
11
+ autoBranch?: boolean;
12
+ branchName?: string;
13
+ wait?: boolean;
14
+ watch?: boolean;
15
+ }): void;
16
+ export declare function suggestModels(requested: string, available: string[]): string[];
17
+ export declare function getModelHint(requested: string, available: string[]): {
18
+ hint: string;
19
+ suggestions: string[];
20
+ suggestionsConfidence: "high" | "low";
21
+ nextStep: string;
22
+ };
23
+ export declare function registerAgentsCommands(program: Command, getClient: () => CursorAgents): void;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ import type { CursorAgents } from "../../index";
3
+ export declare function registerArtifactsCommands(program: Command, getClient: () => CursorAgents): void;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ import type { CursorAgents } from "../../index";
3
+ export declare function registerAuthCommands(program: Command, getClient: () => CursorAgents): void;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ import type { CursorAgents } from "../../index";
3
+ export declare function registerModelsCommands(program: Command, getClient: () => CursorAgents): void;
@@ -0,0 +1 @@
1
+ export {};