@tduyng/pi-cursor 0.0.3 → 0.0.4
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/README.md +47 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,33 +1,18 @@
|
|
|
1
|
-
# pi-cursor
|
|
1
|
+
# @tduyng/pi-cursor
|
|
2
2
|
|
|
3
|
-
Cursor models
|
|
3
|
+
Cursor models inside pi, through the official Cursor SDK. The SDK runs the agent loop, and everything above the transport stays pi's: system prompt, tools, approvals, compaction and session tree.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Tools are callbacks, not a server
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`LocalAgentOptions.customTools` registers one in-process callback per tool, and a tool call does not end the Cursor run. The callback waits, pi executes the named tool through its normal pipeline, and the next `streamSimple` call resolves the callback with the result. The same run continues, so the model sees the result in the same conversation.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The extension switches Cursor's own harness off: `AgentOptions.tools: ['mcp']` leaves only pi's custom tools, and `local.settingSources: []` drops Cursor's rules, skills and MCP servers. No HTTP MCP server, no Hono server, no tool-name rewriting.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## A restart resumes the agent
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
- Node 24 or newer.
|
|
15
|
-
- A Cursor account.
|
|
16
|
-
- `@cursor/sdk` 1.0.40, installed by the workspace.
|
|
17
|
-
|
|
18
|
-
No Cursor CLI is installed or called. Login is the SDK browser flow, which mints a stored Cursor key under `~/.cursor/sdk/auth.json`.
|
|
19
|
-
|
|
20
|
-
## Login
|
|
21
|
-
|
|
22
|
-
```text
|
|
23
|
-
/cursor login
|
|
24
|
-
```
|
|
13
|
+
At the end of every clean turn the extension records the agent id with the working folder, prompt and tool hashes, the pi message count and its own hash of that prefix, in `~/.pi/agent/pi-cursor-agents.json`. The next process calls `Agent.resume` when all of those still match and the pending turn is a single new user message. A stale id, a diverged fork, or a turn killed mid tool round falls back to the replay. The ledger keeps the last 20 sessions.
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
`CURSOR_API_KEY` overrides the stored login. The key is read by the SDK and not copied into pi's `auth.json`.
|
|
29
|
-
|
|
30
|
-
Cursor bills SDK traffic under its own terms, and this extension cannot tell you whether a run is plan-included. Check the Cursor dashboard for the account's SDK usage.
|
|
15
|
+
A message typed while a tool runs goes out with `Run.steer`, so the model reads it before its next step. Images attached to such a message become a one-line note, because steering carries only text.
|
|
31
16
|
|
|
32
17
|
## Use
|
|
33
18
|
|
|
@@ -37,33 +22,24 @@ Cursor bills SDK traffic under its own terms, and this extension cannot tell you
|
|
|
37
22
|
|
|
38
23
|
The provider id is `cursor` and model ids are Cursor's own. The list comes from `Cursor.models.list()`, cached after the last successful read in `~/.pi/agent/pi-cursor-models.json` at mode 0600 and keyed by the credential. Startup registers the cache with no network call, session start refreshes it, and a small built-in list is the fallback.
|
|
39
24
|
|
|
40
|
-
A model that offers several context windows is registered once per window: the plain id uses the smallest
|
|
41
|
-
|
|
42
|
-
`/cursor fast on` adds Cursor's `fast` parameter to every model that exposes it. It is a billing choice, so it stays off until you ask. `/cursor status` shows the current setting.
|
|
25
|
+
A model that offers several context windows is registered once per window: the plain id uses the smallest, and `cursor/gpt-5.5@1m` asks for 1M. Cursor bills the larger windows as Max Mode, so the small default is the cheap one.
|
|
43
26
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
| Pi | Cursor SDK |
|
|
27
|
+
| Command | Effect |
|
|
47
28
|
| --- | --- |
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
54
|
-
A tool call does not end the Cursor run. The callback waits, pi executes the named tool through its normal pipeline, and the next `streamSimple` call resolves the callback with the result. The same run continues, so the model sees the result in the same conversation.
|
|
55
|
-
|
|
56
|
-
A message you steer in while a tool runs is delivered with `Run.steer`, so the model reads it before its next step. Images attached to such a message become a one-line note, because steering carries text only.
|
|
29
|
+
| `/cursor status` | Account, fast mode, prompt path, models |
|
|
30
|
+
| `/cursor login` | The SDK browser flow |
|
|
31
|
+
| `/cursor logout` | Removes the stored key and the resume ledger |
|
|
32
|
+
| `/cursor models` | Every registered id, per context window |
|
|
33
|
+
| `/cursor fast on\|off` | Cursor's `fast` parameter on every model that exposes it |
|
|
34
|
+
| `/cursor clear` | Drops the resume ledger |
|
|
57
35
|
|
|
58
|
-
|
|
36
|
+
`/cursor fast` is a billing choice, so it stays off until asked.
|
|
59
37
|
|
|
60
|
-
|
|
38
|
+
Thinking levels map to Cursor model parameters from the live catalog: `thinking` and `effort` for Claude models, `reasoning` for GPT, `effort` for Grok.
|
|
61
39
|
|
|
62
|
-
|
|
40
|
+
## Wire cost
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
Measured on the account this extension was built on, with gpt-5.5 and auto-smart, thinking off:
|
|
42
|
+
Measured on the account this extension was built on, gpt-5.5 with auto-smart and thinking off:
|
|
67
43
|
|
|
68
44
|
| Call | Input tokens | Wall time |
|
|
69
45
|
| --- | --- | --- |
|
|
@@ -71,48 +47,49 @@ Measured on the account this extension was built on, with gpt-5.5 and auto-smart
|
|
|
71
47
|
| Plain follow-up turn | 12.9k fresh plus 12.7k cached | 2.2s |
|
|
72
48
|
| Call after a tool round | 36.9k fresh plus 36.0k cached | 4.4 to 13s |
|
|
73
49
|
|
|
74
|
-
The tool-round number is Cursor's, not the tool result. The SDK re-prefills its own context around the custom tool callback, so one tool call costs about three plain calls.
|
|
50
|
+
The tool-round number is Cursor's, not the tool result. The SDK re-prefills its own context around the custom tool callback, so one tool call costs about three plain calls. The same 32k fresh appears with an empty working directory, so it is not workspace scanning. Fewer, wider tool calls per turn is the lever that exists.
|
|
75
51
|
|
|
76
|
-
|
|
52
|
+
The extension adds no tool, no prompt block and no schema. What it saves on the wire is the replay: a normal turn sends only the new user message, a tool round sends nothing, and a restarted pi process resumes the same agent.
|
|
77
53
|
|
|
78
|
-
##
|
|
54
|
+
## Install
|
|
79
55
|
|
|
80
|
-
-
|
|
56
|
+
- Pi 1.4 or newer.
|
|
57
|
+
- Node 24 or newer.
|
|
58
|
+
- A Cursor account.
|
|
59
|
+
- `@cursor/sdk` 1.0.40, installed by the workspace as a 25 MB dependency with optional platform packages.
|
|
81
60
|
|
|
82
|
-
|
|
61
|
+
```sh
|
|
62
|
+
pi install npm:@tduyng/pi-cursor
|
|
63
|
+
```
|
|
83
64
|
|
|
84
|
-
|
|
65
|
+
Local checkout: `pi install /path/to/dotfiles/pi/agent/extensions/pi-cursor`
|
|
85
66
|
|
|
86
|
-
|
|
67
|
+
No Cursor CLI is installed or called. Login is the SDK browser flow, which mints a stored Cursor key under `~/.cursor/sdk/auth.json`:
|
|
87
68
|
|
|
88
|
-
|
|
69
|
+
```text
|
|
70
|
+
/cursor login
|
|
71
|
+
```
|
|
89
72
|
|
|
90
|
-
|
|
73
|
+
If the browser does not open, the command prints the URL. `CURSOR_API_KEY` overrides the stored login, and the key is read by the SDK rather than copied into pi's `auth.json`.
|
|
91
74
|
|
|
92
|
-
|
|
75
|
+
Cursor bills SDK traffic under its own terms, and this extension cannot tell whether a run is plan-included. Check the Cursor dashboard for the account's SDK usage.
|
|
93
76
|
|
|
94
|
-
-
|
|
77
|
+
`~/.pi/agent/pi-cursor.json` holds the two preferences: `fast`, from `/cursor fast`, and `noSystemPrompt`, once Cursor has refused pi's prompt for this account.
|
|
95
78
|
|
|
96
|
-
|
|
79
|
+
## Limits
|
|
97
80
|
|
|
98
|
-
|
|
81
|
+
- Cursor owns the agent loop and its context management, so pi's compaction does not reach inside a live agent.
|
|
99
82
|
|
|
100
|
-
`
|
|
83
|
+
- `AgentOptions.systemPrompt` is server-gated. A rejected prompt comes back as a failed run about 20 seconds in, not from `Agent.create`, so that turn is retried with the prompt prepended to the first message.
|
|
101
84
|
|
|
102
|
-
|
|
85
|
+
- The rejection is recorded as `noSystemPrompt`, and every later agent skips the doomed attempt. The fallback works but spends more tokens, because the Cursor harness prompt remains.
|
|
103
86
|
|
|
104
|
-
|
|
87
|
+
- A failed run reaches pi as an error message, so an empty answer means a broken transport rather than a silent backend rejection.
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
pi install npm:@tduyng/pi-cursor
|
|
108
|
-
```
|
|
89
|
+
- Usage tokens come from Cursor's `turn-ended` events plus the run's own total. A message that ends in a tool call shows zero, because that step has not ended server side, and the next message carries both. Pi shows zero money cost because Cursor bills outside pi.
|
|
109
90
|
|
|
110
|
-
|
|
91
|
+
- A replay replaces earlier images with an `[image: mime]` placeholder and keeps only the pending message's images, so reattach one to ask about it again after a restart.
|
|
111
92
|
|
|
112
|
-
|
|
93
|
+
- A model id Cursor no longer serves fails at `send`, not at selection.
|
|
113
94
|
|
|
114
|
-
|
|
115
|
-
bun test extensions/pi-cursor
|
|
116
|
-
bun run typecheck
|
|
117
|
-
bun run lint:anti-slop
|
|
118
|
-
```
|
|
95
|
+
- A long pi tool run is held open by the Cursor local runtime, and the SDK documents no timeout for custom tools.
|
package/package.json
CHANGED