pi-cursor-sdk 0.4.0 → 0.5.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/CHANGELOG.md +30 -0
- package/README.md +65 -13
- package/dist/context-window-cache.js +0 -6
- package/dist/context.js +8 -0
- package/dist/cursor-cloud-lifecycle.js +122 -98
- package/dist/cursor-durable-fs.js +97 -3
- package/dist/cursor-fallback-models.generated.js +288 -1
- package/dist/cursor-fallback-warning.js +2 -2
- package/dist/cursor-http1.js +8 -8
- package/dist/cursor-live-run-coordinator.js +9 -13
- package/dist/cursor-native-replay-routing.js +1 -1
- package/dist/cursor-native-tool-display-registration.js +46 -22
- package/dist/cursor-native-tool-display-state.js +57 -22
- package/dist/cursor-native-tool-display-tools.js +5 -6
- package/dist/cursor-pi-tool-bridge-constants.js +23 -2
- package/dist/cursor-pi-tool-bridge-run.js +7 -3
- package/dist/cursor-pi-tool-bridge-snapshot.js +1 -1
- package/dist/cursor-pi-tool-bridge.js +31 -9
- package/dist/cursor-provider-binding.js +58 -0
- package/dist/cursor-provider-errors.js +28 -7
- package/dist/cursor-provider-lazy.js +23 -11
- package/dist/cursor-provider-live-run-drain.js +15 -12
- package/dist/cursor-provider-run-finalizer.js +19 -8
- package/dist/cursor-provider-turn-coordinator.js +1 -0
- package/dist/cursor-provider-turn-display-router.js +4 -0
- package/dist/cursor-provider-turn-emit.js +1 -0
- package/dist/cursor-provider-turn-finalize.js +29 -20
- package/dist/cursor-provider-turn-prepare.js +24 -11
- package/dist/cursor-provider-turn-runner.js +37 -11
- package/dist/cursor-provider-turn-send.js +22 -9
- package/dist/cursor-provider-turn-summary.js +89 -0
- package/dist/cursor-provider.js +9 -3
- package/dist/cursor-request-provenance.js +42 -0
- package/dist/cursor-ripgrep-path.js +14 -3
- package/dist/cursor-runtime-state.js +50 -43
- package/dist/cursor-sdk-billed-usage.js +54 -75
- package/dist/cursor-sdk-event-debug-session.js +5 -6
- package/dist/cursor-sdk-event-debug.js +9 -6
- package/dist/cursor-sdk-process-error-guard.js +8 -7
- package/dist/cursor-sdk-runtime.js +13 -0
- package/dist/cursor-session-agent-cleanup.js +2 -2
- package/dist/cursor-session-agent-lifecycle.js +18 -9
- package/dist/cursor-session-agent-lineage.js +28 -12
- package/dist/cursor-session-agent-resume.js +51 -35
- package/dist/cursor-session-agent.js +9 -9
- package/dist/cursor-session-compaction-prep.js +2 -7
- package/dist/cursor-session-scope.js +71 -39
- package/dist/cursor-session-settings.js +61 -0
- package/dist/cursor-skill-tool.js +32 -49
- package/dist/cursor-state.js +72 -62
- package/dist/cursor-usage-accounting.js +13 -70
- package/dist/cursor-usage-command.js +89 -0
- package/dist/cursor-usage-ledger.js +512 -0
- package/dist/index.js +11 -19
- package/dist/model-discovery.js +11 -19
- package/docs/cursor-dogfood-checklist.md +3 -3
- package/docs/cursor-live-smoke-checklist.md +15 -15
- package/docs/cursor-model-ux-spec.md +59 -18
- package/docs/cursor-native-tool-replay.md +5 -3
- package/docs/cursor-native-tool-visual-audit.md +8 -8
- package/docs/cursor-testing-lessons.md +47 -23
- package/docs/cursor-tool-surfaces.md +1 -1
- package/docs/platform-smoke-implementation.md +10 -6
- package/docs/platform-smoke.md +35 -46
- package/package.json +6 -6
- package/scripts/cloud-runtime-smoke.mjs +4 -2
- package/scripts/local-resume-smoke.mjs +1 -1
- package/scripts/platform-smoke/card-detect.mjs +2 -8
- package/scripts/platform-smoke/targets.mjs +8 -15
- package/scripts/platform-smoke/visual-evidence.mjs +7 -2
- package/scripts/tmux-live-smoke.sh +57 -90
- package/src/context-window-cache.ts +0 -6
- package/src/context.ts +8 -0
- package/src/cursor-cloud-lifecycle.ts +124 -98
- package/src/cursor-durable-fs.ts +65 -3
- package/src/cursor-fallback-models.generated.ts +288 -1
- package/src/cursor-fallback-warning.ts +2 -2
- package/src/cursor-http1.ts +8 -8
- package/src/cursor-live-run-coordinator.ts +12 -13
- package/src/cursor-native-replay-routing.ts +2 -1
- package/src/cursor-native-tool-display-registration.ts +48 -24
- package/src/cursor-native-tool-display-state.ts +65 -21
- package/src/cursor-native-tool-display-tools.ts +7 -4
- package/src/cursor-pi-tool-bridge-constants.ts +27 -2
- package/src/cursor-pi-tool-bridge-run.ts +11 -3
- package/src/cursor-pi-tool-bridge-snapshot.ts +1 -1
- package/src/cursor-pi-tool-bridge.ts +26 -9
- package/src/cursor-provider-binding.ts +62 -0
- package/src/cursor-provider-errors.ts +27 -7
- package/src/cursor-provider-lazy.ts +21 -15
- package/src/cursor-provider-live-run-drain.ts +20 -13
- package/src/cursor-provider-run-finalizer.ts +24 -15
- package/src/cursor-provider-turn-coordinator.ts +2 -0
- package/src/cursor-provider-turn-display-router.ts +5 -0
- package/src/cursor-provider-turn-emit.ts +3 -1
- package/src/cursor-provider-turn-finalize.ts +38 -23
- package/src/cursor-provider-turn-prepare.ts +23 -14
- package/src/cursor-provider-turn-runner.ts +40 -13
- package/src/cursor-provider-turn-send.ts +23 -15
- package/src/cursor-provider-turn-summary.ts +94 -0
- package/src/cursor-provider-turn-types.ts +37 -4
- package/src/cursor-provider.ts +25 -3
- package/src/cursor-request-provenance.ts +64 -0
- package/src/cursor-ripgrep-path.ts +15 -5
- package/src/cursor-runtime-state.ts +53 -48
- package/src/cursor-sdk-billed-usage.ts +54 -102
- package/src/cursor-sdk-event-debug-session.ts +5 -5
- package/src/cursor-sdk-event-debug.ts +10 -6
- package/src/cursor-sdk-process-error-guard.ts +7 -7
- package/src/cursor-sdk-runtime.ts +14 -0
- package/src/cursor-session-agent-cleanup.ts +2 -2
- package/src/cursor-session-agent-lifecycle.ts +14 -9
- package/src/cursor-session-agent-lineage.ts +26 -12
- package/src/cursor-session-agent-resume.ts +49 -36
- package/src/cursor-session-agent.ts +13 -10
- package/src/cursor-session-compaction-prep.ts +2 -7
- package/src/cursor-session-scope.ts +87 -39
- package/src/cursor-session-settings.ts +72 -0
- package/src/cursor-skill-tool.ts +37 -61
- package/src/cursor-state.ts +74 -67
- package/src/cursor-usage-accounting.ts +17 -82
- package/src/cursor-usage-command.ts +76 -0
- package/src/cursor-usage-ledger.ts +500 -0
- package/src/index.ts +14 -23
- package/src/model-discovery.ts +14 -22
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated with @cursor/sdk@1.0.32 from
|
|
1
|
+
// Generated with @cursor/sdk@1.0.32 from 45 Cursor models.
|
|
2
2
|
// Refresh with: npm run refresh:cursor-snapshots -- --write
|
|
3
3
|
// Do not add secrets; this file stores public model metadata only.
|
|
4
4
|
export const FALLBACK_MODEL_ITEMS = [
|
|
@@ -5597,6 +5597,185 @@ export const FALLBACK_MODEL_ITEMS = [
|
|
|
5597
5597
|
}
|
|
5598
5598
|
]
|
|
5599
5599
|
},
|
|
5600
|
+
{
|
|
5601
|
+
id: "claude-sonnet-5-5",
|
|
5602
|
+
displayName: "Claude Sonnet 5.5",
|
|
5603
|
+
parameters: [
|
|
5604
|
+
{
|
|
5605
|
+
id: "context",
|
|
5606
|
+
displayName: "Context",
|
|
5607
|
+
values: [
|
|
5608
|
+
{
|
|
5609
|
+
value: "300k",
|
|
5610
|
+
displayName: "300K"
|
|
5611
|
+
},
|
|
5612
|
+
{
|
|
5613
|
+
value: "1m",
|
|
5614
|
+
displayName: "1M"
|
|
5615
|
+
}
|
|
5616
|
+
]
|
|
5617
|
+
},
|
|
5618
|
+
{
|
|
5619
|
+
id: "reasoning_effort",
|
|
5620
|
+
displayName: "Effort",
|
|
5621
|
+
values: [
|
|
5622
|
+
{
|
|
5623
|
+
value: "low",
|
|
5624
|
+
displayName: "Low"
|
|
5625
|
+
},
|
|
5626
|
+
{
|
|
5627
|
+
value: "medium",
|
|
5628
|
+
displayName: "Medium"
|
|
5629
|
+
},
|
|
5630
|
+
{
|
|
5631
|
+
value: "high",
|
|
5632
|
+
displayName: "High"
|
|
5633
|
+
},
|
|
5634
|
+
{
|
|
5635
|
+
value: "xhigh",
|
|
5636
|
+
displayName: "Extra High"
|
|
5637
|
+
},
|
|
5638
|
+
{
|
|
5639
|
+
value: "max",
|
|
5640
|
+
displayName: "Max"
|
|
5641
|
+
}
|
|
5642
|
+
]
|
|
5643
|
+
}
|
|
5644
|
+
],
|
|
5645
|
+
variants: [
|
|
5646
|
+
{
|
|
5647
|
+
params: [
|
|
5648
|
+
{
|
|
5649
|
+
id: "context",
|
|
5650
|
+
value: "300k"
|
|
5651
|
+
},
|
|
5652
|
+
{
|
|
5653
|
+
id: "reasoning_effort",
|
|
5654
|
+
value: "low"
|
|
5655
|
+
}
|
|
5656
|
+
],
|
|
5657
|
+
displayName: "Claude Sonnet 5.5 Low"
|
|
5658
|
+
},
|
|
5659
|
+
{
|
|
5660
|
+
params: [
|
|
5661
|
+
{
|
|
5662
|
+
id: "context",
|
|
5663
|
+
value: "300k"
|
|
5664
|
+
},
|
|
5665
|
+
{
|
|
5666
|
+
id: "reasoning_effort",
|
|
5667
|
+
value: "medium"
|
|
5668
|
+
}
|
|
5669
|
+
],
|
|
5670
|
+
displayName: "Claude Sonnet 5.5 Medium"
|
|
5671
|
+
},
|
|
5672
|
+
{
|
|
5673
|
+
params: [
|
|
5674
|
+
{
|
|
5675
|
+
id: "context",
|
|
5676
|
+
value: "300k"
|
|
5677
|
+
},
|
|
5678
|
+
{
|
|
5679
|
+
id: "reasoning_effort",
|
|
5680
|
+
value: "high"
|
|
5681
|
+
}
|
|
5682
|
+
],
|
|
5683
|
+
displayName: "Claude Sonnet 5.5 High"
|
|
5684
|
+
},
|
|
5685
|
+
{
|
|
5686
|
+
params: [
|
|
5687
|
+
{
|
|
5688
|
+
id: "context",
|
|
5689
|
+
value: "300k"
|
|
5690
|
+
},
|
|
5691
|
+
{
|
|
5692
|
+
id: "reasoning_effort",
|
|
5693
|
+
value: "xhigh"
|
|
5694
|
+
}
|
|
5695
|
+
],
|
|
5696
|
+
displayName: "Claude Sonnet 5.5 Extra High"
|
|
5697
|
+
},
|
|
5698
|
+
{
|
|
5699
|
+
params: [
|
|
5700
|
+
{
|
|
5701
|
+
id: "context",
|
|
5702
|
+
value: "300k"
|
|
5703
|
+
},
|
|
5704
|
+
{
|
|
5705
|
+
id: "reasoning_effort",
|
|
5706
|
+
value: "max"
|
|
5707
|
+
}
|
|
5708
|
+
],
|
|
5709
|
+
displayName: "Claude Sonnet 5.5 Max"
|
|
5710
|
+
},
|
|
5711
|
+
{
|
|
5712
|
+
params: [
|
|
5713
|
+
{
|
|
5714
|
+
id: "context",
|
|
5715
|
+
value: "1m"
|
|
5716
|
+
},
|
|
5717
|
+
{
|
|
5718
|
+
id: "reasoning_effort",
|
|
5719
|
+
value: "low"
|
|
5720
|
+
}
|
|
5721
|
+
],
|
|
5722
|
+
displayName: "Claude Sonnet 5.5 1M Low"
|
|
5723
|
+
},
|
|
5724
|
+
{
|
|
5725
|
+
params: [
|
|
5726
|
+
{
|
|
5727
|
+
id: "context",
|
|
5728
|
+
value: "1m"
|
|
5729
|
+
},
|
|
5730
|
+
{
|
|
5731
|
+
id: "reasoning_effort",
|
|
5732
|
+
value: "medium"
|
|
5733
|
+
}
|
|
5734
|
+
],
|
|
5735
|
+
displayName: "Claude Sonnet 5.5 1M Medium"
|
|
5736
|
+
},
|
|
5737
|
+
{
|
|
5738
|
+
params: [
|
|
5739
|
+
{
|
|
5740
|
+
id: "context",
|
|
5741
|
+
value: "1m"
|
|
5742
|
+
},
|
|
5743
|
+
{
|
|
5744
|
+
id: "reasoning_effort",
|
|
5745
|
+
value: "high"
|
|
5746
|
+
}
|
|
5747
|
+
],
|
|
5748
|
+
displayName: "Claude Sonnet 5.5 1M High",
|
|
5749
|
+
isDefault: true
|
|
5750
|
+
},
|
|
5751
|
+
{
|
|
5752
|
+
params: [
|
|
5753
|
+
{
|
|
5754
|
+
id: "context",
|
|
5755
|
+
value: "1m"
|
|
5756
|
+
},
|
|
5757
|
+
{
|
|
5758
|
+
id: "reasoning_effort",
|
|
5759
|
+
value: "xhigh"
|
|
5760
|
+
}
|
|
5761
|
+
],
|
|
5762
|
+
displayName: "Claude Sonnet 5.5 1M Extra High"
|
|
5763
|
+
},
|
|
5764
|
+
{
|
|
5765
|
+
params: [
|
|
5766
|
+
{
|
|
5767
|
+
id: "context",
|
|
5768
|
+
value: "1m"
|
|
5769
|
+
},
|
|
5770
|
+
{
|
|
5771
|
+
id: "reasoning_effort",
|
|
5772
|
+
value: "max"
|
|
5773
|
+
}
|
|
5774
|
+
],
|
|
5775
|
+
displayName: "Claude Sonnet 5.5 1M Max"
|
|
5776
|
+
}
|
|
5777
|
+
]
|
|
5778
|
+
},
|
|
5600
5779
|
{
|
|
5601
5780
|
id: "composer-2",
|
|
5602
5781
|
displayName: "Composer 2",
|
|
@@ -5977,6 +6156,114 @@ export const FALLBACK_MODEL_ITEMS = [
|
|
|
5977
6156
|
}
|
|
5978
6157
|
]
|
|
5979
6158
|
},
|
|
6159
|
+
{
|
|
6160
|
+
id: "glm-5p3",
|
|
6161
|
+
displayName: "GLM 5.3",
|
|
6162
|
+
parameters: [
|
|
6163
|
+
{
|
|
6164
|
+
id: "reasoning",
|
|
6165
|
+
displayName: "Reasoning",
|
|
6166
|
+
values: [
|
|
6167
|
+
{
|
|
6168
|
+
value: "low",
|
|
6169
|
+
displayName: "Low"
|
|
6170
|
+
},
|
|
6171
|
+
{
|
|
6172
|
+
value: "high",
|
|
6173
|
+
displayName: "High"
|
|
6174
|
+
},
|
|
6175
|
+
{
|
|
6176
|
+
value: "max",
|
|
6177
|
+
displayName: "Max"
|
|
6178
|
+
}
|
|
6179
|
+
]
|
|
6180
|
+
}
|
|
6181
|
+
],
|
|
6182
|
+
variants: [
|
|
6183
|
+
{
|
|
6184
|
+
params: [
|
|
6185
|
+
{
|
|
6186
|
+
id: "reasoning",
|
|
6187
|
+
value: "low"
|
|
6188
|
+
}
|
|
6189
|
+
],
|
|
6190
|
+
displayName: "GLM 5.3 Low"
|
|
6191
|
+
},
|
|
6192
|
+
{
|
|
6193
|
+
params: [
|
|
6194
|
+
{
|
|
6195
|
+
id: "reasoning",
|
|
6196
|
+
value: "high"
|
|
6197
|
+
}
|
|
6198
|
+
],
|
|
6199
|
+
displayName: "GLM 5.3 High"
|
|
6200
|
+
},
|
|
6201
|
+
{
|
|
6202
|
+
params: [
|
|
6203
|
+
{
|
|
6204
|
+
id: "reasoning",
|
|
6205
|
+
value: "max"
|
|
6206
|
+
}
|
|
6207
|
+
],
|
|
6208
|
+
displayName: "GLM 5.3 Max",
|
|
6209
|
+
isDefault: true
|
|
6210
|
+
}
|
|
6211
|
+
]
|
|
6212
|
+
},
|
|
6213
|
+
{
|
|
6214
|
+
id: "glm-5p3-flash",
|
|
6215
|
+
displayName: "GLM 5.3 Flash",
|
|
6216
|
+
parameters: [
|
|
6217
|
+
{
|
|
6218
|
+
id: "reasoning",
|
|
6219
|
+
displayName: "Reasoning",
|
|
6220
|
+
values: [
|
|
6221
|
+
{
|
|
6222
|
+
value: "low",
|
|
6223
|
+
displayName: "Low"
|
|
6224
|
+
},
|
|
6225
|
+
{
|
|
6226
|
+
value: "high",
|
|
6227
|
+
displayName: "High"
|
|
6228
|
+
},
|
|
6229
|
+
{
|
|
6230
|
+
value: "max",
|
|
6231
|
+
displayName: "Max"
|
|
6232
|
+
}
|
|
6233
|
+
]
|
|
6234
|
+
}
|
|
6235
|
+
],
|
|
6236
|
+
variants: [
|
|
6237
|
+
{
|
|
6238
|
+
params: [
|
|
6239
|
+
{
|
|
6240
|
+
id: "reasoning",
|
|
6241
|
+
value: "low"
|
|
6242
|
+
}
|
|
6243
|
+
],
|
|
6244
|
+
displayName: "GLM 5.3 Flash Low"
|
|
6245
|
+
},
|
|
6246
|
+
{
|
|
6247
|
+
params: [
|
|
6248
|
+
{
|
|
6249
|
+
id: "reasoning",
|
|
6250
|
+
value: "high"
|
|
6251
|
+
}
|
|
6252
|
+
],
|
|
6253
|
+
displayName: "GLM 5.3 Flash High"
|
|
6254
|
+
},
|
|
6255
|
+
{
|
|
6256
|
+
params: [
|
|
6257
|
+
{
|
|
6258
|
+
id: "reasoning",
|
|
6259
|
+
value: "max"
|
|
6260
|
+
}
|
|
6261
|
+
],
|
|
6262
|
+
displayName: "GLM 5.3 Flash Max",
|
|
6263
|
+
isDefault: true
|
|
6264
|
+
}
|
|
6265
|
+
]
|
|
6266
|
+
},
|
|
5980
6267
|
{
|
|
5981
6268
|
id: "gpt-5-mini",
|
|
5982
6269
|
displayName: "GPT-5 Mini",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { isCursorModel } from "./cursor-model.js";
|
|
2
2
|
import { registerCursorModelLifecycle } from "./cursor-model-lifecycle.js";
|
|
3
|
-
import {
|
|
3
|
+
import { cursorSessionScopeKeyForManager } from "./cursor-session-scope.js";
|
|
4
4
|
export function registerCursorFallbackIssueWarning(pi, issue) {
|
|
5
5
|
const warnedSessionScopeKeys = new Set();
|
|
6
6
|
registerCursorModelLifecycle(pi, (ctx) => {
|
|
7
7
|
if (!isCursorModel(ctx.model) || !ctx.hasUI)
|
|
8
8
|
return;
|
|
9
|
-
const scopeKey =
|
|
9
|
+
const scopeKey = cursorSessionScopeKeyForManager(ctx.sessionManager);
|
|
10
10
|
if (warnedSessionScopeKeys.has(scopeKey))
|
|
11
11
|
return;
|
|
12
12
|
warnedSessionScopeKeys.add(scopeKey);
|
package/dist/cursor-http1.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { asRecord } from "./cursor-record-utils.js";
|
|
2
|
+
import { getCursorSessionSettings } from "./cursor-session-settings.js";
|
|
2
3
|
export const CURSOR_HTTP1_ENTRY_TYPE = "cursor-http1-state";
|
|
3
|
-
let sessionCursorHttp1Enabled;
|
|
4
4
|
let globalPreferenceAuthoritative = false;
|
|
5
5
|
let configuredCursor;
|
|
6
6
|
export function isCursorHttp1EntryData(value) {
|
|
7
7
|
return typeof asRecord(value)?.enabled === "boolean";
|
|
8
8
|
}
|
|
9
|
-
export function getStoredCursorHttp1Enabled() {
|
|
10
|
-
return
|
|
9
|
+
export function getStoredCursorHttp1Enabled(scopeKey) {
|
|
10
|
+
return getCursorSessionSettings(scopeKey).http1;
|
|
11
11
|
}
|
|
12
|
-
export function setStoredCursorHttp1Enabled(enabled) {
|
|
13
|
-
|
|
12
|
+
export function setStoredCursorHttp1Enabled(enabled, scopeKey) {
|
|
13
|
+
getCursorSessionSettings(scopeKey).http1 = enabled;
|
|
14
14
|
}
|
|
15
|
-
export function getResolvedSessionCursorHttp1Enabled() {
|
|
16
|
-
return globalPreferenceAuthoritative ? undefined :
|
|
15
|
+
export function getResolvedSessionCursorHttp1Enabled(scopeKey) {
|
|
16
|
+
return globalPreferenceAuthoritative ? undefined : getStoredCursorHttp1Enabled(scopeKey);
|
|
17
17
|
}
|
|
18
18
|
export function setCursorHttp1GlobalPreferenceAuthoritative(authoritative) {
|
|
19
19
|
globalPreferenceAuthoritative = authoritative;
|
|
@@ -38,7 +38,7 @@ export function configureCursorSdkHttp1(sdk, setting) {
|
|
|
38
38
|
}
|
|
39
39
|
export const __testUtils = {
|
|
40
40
|
reset() {
|
|
41
|
-
|
|
41
|
+
setStoredCursorHttp1Enabled(undefined);
|
|
42
42
|
globalPreferenceAuthoritative = false;
|
|
43
43
|
configuredCursor = undefined;
|
|
44
44
|
},
|
|
@@ -153,6 +153,7 @@ export function createCursorLiveRunCoordinator(deps) {
|
|
|
153
153
|
bridgeRun: params.bridgeRun,
|
|
154
154
|
sessionBridgeRun: params.sessionBridgeRun,
|
|
155
155
|
sessionAgentScopeKey,
|
|
156
|
+
nativeDisplay: params.nativeDisplay,
|
|
156
157
|
accounting: createCursorLiveRunAccountingState(params.promptInputTokens),
|
|
157
158
|
pendingEvents: [],
|
|
158
159
|
textDeltas: params.textDeltas ?? [],
|
|
@@ -270,7 +271,10 @@ export function createCursorLiveRunCoordinator(deps) {
|
|
|
270
271
|
run.accounting = taken.state;
|
|
271
272
|
return taken.sdkTurnUsage;
|
|
272
273
|
},
|
|
273
|
-
getPendingFromContext(context, getReplayId) {
|
|
274
|
+
getPendingFromContext(context, getReplayId, scopeKey) {
|
|
275
|
+
const run = getUndisposed(pendingRunIdsByScopeKey.get(scopeKey));
|
|
276
|
+
if (!run)
|
|
277
|
+
return undefined;
|
|
274
278
|
const messages = getCursorConversationMessages(context);
|
|
275
279
|
let index = messages.length - 1;
|
|
276
280
|
while (index >= 0 && messages[index]?.role === "user") {
|
|
@@ -280,18 +284,8 @@ export function createCursorLiveRunCoordinator(deps) {
|
|
|
280
284
|
const message = messages[index];
|
|
281
285
|
if (message.role !== "toolResult")
|
|
282
286
|
break;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const replayRun = getUndisposed(replayId);
|
|
286
|
-
if (replayRun)
|
|
287
|
-
return replayRun;
|
|
288
|
-
}
|
|
289
|
-
for (const run of pendingRuns.values()) {
|
|
290
|
-
if (run.disposed)
|
|
291
|
-
continue;
|
|
292
|
-
if (run.bridgeRun?.hasPendingPiToolCallId(message.toolCallId))
|
|
293
|
-
return run;
|
|
294
|
-
}
|
|
287
|
+
if (matchesCursorLiveRunToolResult(run, message, getReplayId))
|
|
288
|
+
return run;
|
|
295
289
|
}
|
|
296
290
|
return undefined;
|
|
297
291
|
},
|
|
@@ -389,12 +383,14 @@ export function createCursorLiveRunCoordinator(deps) {
|
|
|
389
383
|
}
|
|
390
384
|
if (abandoned) {
|
|
391
385
|
if (!run.done) {
|
|
386
|
+
const usageCompletion = run.onAbandon?.();
|
|
392
387
|
try {
|
|
393
388
|
await cancelCursorLiveSdkRun(run);
|
|
394
389
|
}
|
|
395
390
|
catch {
|
|
396
391
|
// cancellation failure should not block session-agent abandonment
|
|
397
392
|
}
|
|
393
|
+
await usageCompletion;
|
|
398
394
|
}
|
|
399
395
|
await deps.abandonSessionAgent(run.sessionAgentScopeKey);
|
|
400
396
|
}
|
|
@@ -8,7 +8,7 @@ export function isNativeToolActiveInContext(toolName, activeToolNames) {
|
|
|
8
8
|
* Extension resync (pi active tools) is separate; this uses context.tools snapshot only.
|
|
9
9
|
*/
|
|
10
10
|
export function resolveNativeReplayDisposition(input) {
|
|
11
|
-
if (!input.useNativeToolReplay || !canRenderCursorToolNatively(input.toolName)) {
|
|
11
|
+
if (!input.useNativeToolReplay || !(input.registeredToolNames?.has(input.toolName) ?? canRenderCursorToolNatively(input.toolName))) {
|
|
12
12
|
return "transcript_trace";
|
|
13
13
|
}
|
|
14
14
|
if (isNativeToolActiveInContext(input.toolName, input.activeToolNames) && input.hasLiveRun) {
|
|
@@ -2,7 +2,7 @@ import { arePiToolsDisabled } from "./cursor-active-tools.js";
|
|
|
2
2
|
import { CURSOR_MODEL_ACTIVE_REPLAY_TOOL_NAMES, isNativeCursorToolName, NATIVE_CURSOR_TOOL_NAMES, } from "./cursor-native-tool-names.js";
|
|
3
3
|
import { isCursorModel } from "./cursor-model.js";
|
|
4
4
|
import { registerCursorModelLifecycle } from "./cursor-model-lifecycle.js";
|
|
5
|
-
import { isCursorNativeToolDisplayRequested, isCursorNativeToolRegistrationRequested, NATIVE_CURSOR_TOOL_DISPLAY_ENV, readBooleanEnv,
|
|
5
|
+
import { isCursorNativeToolDisplayRequested, isCursorNativeToolRegistrationRequested, NATIVE_CURSOR_TOOL_DISPLAY_ENV, readBooleanEnv, getCursorNativeToolDisplayState, registerCursorNativeToolDisplayState, setCursorNativeToolDisplayRuntimeRequested, } from "./cursor-native-tool-display-state.js";
|
|
6
6
|
import { isCursorReplayToolName } from "./cursor-tool-presentation-registry.js";
|
|
7
7
|
import { registerNativeCursorTool } from "./cursor-native-tool-display-tools.js";
|
|
8
8
|
export const CURSOR_CORE_PI_REPLAY_TOOL_NAMES = ["read", "bash", "edit", "write"];
|
|
@@ -10,22 +10,37 @@ const CORE_PI_TOOL_NAMES = new Set(CURSOR_CORE_PI_REPLAY_TOOL_NAMES);
|
|
|
10
10
|
function isCursorCorePiReplayToolName(toolName) {
|
|
11
11
|
return CORE_PI_TOOL_NAMES.has(toolName);
|
|
12
12
|
}
|
|
13
|
+
// Pi filters getAllTools even after registration; new/reloaded extensions receive a new API.
|
|
14
|
+
const filteredRegistrations = new WeakMap();
|
|
13
15
|
function hasNonBuiltinTool(pi, toolName) {
|
|
14
16
|
const existingTool = pi.getAllTools().find((tool) => tool.name === toolName);
|
|
15
17
|
return existingTool !== undefined && existingTool.sourceInfo.source !== "builtin";
|
|
16
18
|
}
|
|
17
|
-
function registerNativeCursorToolsFromSet(pi, toolNames) {
|
|
19
|
+
function registerNativeCursorToolsFromSet(pi, toolNames, getCwd) {
|
|
20
|
+
const state = getCursorNativeToolDisplayState(pi);
|
|
21
|
+
const { registeredNativeToolSources, skippedNativeToolNames } = state;
|
|
22
|
+
let filteredToolNames = filteredRegistrations.get(pi);
|
|
23
|
+
if (!filteredToolNames) {
|
|
24
|
+
filteredToolNames = new Set();
|
|
25
|
+
filteredRegistrations.set(pi, filteredToolNames);
|
|
26
|
+
}
|
|
18
27
|
const newlySkippedToolNames = [];
|
|
19
28
|
for (const toolName of toolNames) {
|
|
20
|
-
if (
|
|
29
|
+
if (registeredNativeToolSources.has(toolName) || filteredToolNames.has(toolName))
|
|
21
30
|
continue;
|
|
22
31
|
if (hasNonBuiltinTool(pi, toolName)) {
|
|
23
|
-
skippedNativeToolNames.
|
|
24
|
-
|
|
32
|
+
if (!skippedNativeToolNames.has(toolName)) {
|
|
33
|
+
skippedNativeToolNames.add(toolName);
|
|
34
|
+
newlySkippedToolNames.push(toolName);
|
|
35
|
+
}
|
|
25
36
|
continue;
|
|
26
37
|
}
|
|
27
|
-
registerNativeCursorTool(pi, toolName);
|
|
28
|
-
|
|
38
|
+
registerNativeCursorTool(pi, toolName, getCwd, state);
|
|
39
|
+
const registeredTool = pi.getAllTools().find((tool) => tool.name === toolName);
|
|
40
|
+
if (registeredTool)
|
|
41
|
+
registeredNativeToolSources.set(toolName, registeredTool.sourceInfo);
|
|
42
|
+
else
|
|
43
|
+
filteredToolNames.add(toolName);
|
|
29
44
|
}
|
|
30
45
|
return newlySkippedToolNames;
|
|
31
46
|
}
|
|
@@ -34,15 +49,13 @@ function notifySkippedNativeCursorToolsIfNeeded(ctx, skippedToolNames) {
|
|
|
34
49
|
return;
|
|
35
50
|
ctx.ui.notify(`Cursor native tool replay skipped for ${skippedToolNames.join(", ")} because another extension already provides ${skippedToolNames.length === 1 ? "that tool" : "those tools"}. Cursor will use scrubbed activity transcripts for skipped tools.`, "warning");
|
|
36
51
|
}
|
|
37
|
-
function hasAttemptedNativeCursorToolRegistration() {
|
|
38
|
-
return registeredNativeToolNames.size > 0 || skippedNativeToolNames.size > 0;
|
|
39
|
-
}
|
|
40
52
|
function removeRegisteredNonCoreNativeCursorTools(pi) {
|
|
41
|
-
|
|
53
|
+
const { registeredNativeToolSources } = getCursorNativeToolDisplayState(pi);
|
|
54
|
+
if (registeredNativeToolSources.size === 0)
|
|
42
55
|
return;
|
|
43
56
|
const activeToolNames = new Set(pi.getActiveTools());
|
|
44
57
|
let changed = false;
|
|
45
|
-
for (const toolName of
|
|
58
|
+
for (const toolName of registeredNativeToolSources.keys()) {
|
|
46
59
|
if (isCursorCorePiReplayToolName(toolName))
|
|
47
60
|
continue;
|
|
48
61
|
if (!activeToolNames.delete(toolName))
|
|
@@ -53,7 +66,8 @@ function removeRegisteredNonCoreNativeCursorTools(pi) {
|
|
|
53
66
|
pi.setActiveTools([...activeToolNames]);
|
|
54
67
|
}
|
|
55
68
|
export function syncRegisteredNativeCursorToolsForModel(pi, model) {
|
|
56
|
-
|
|
69
|
+
const { registeredNativeToolSources } = getCursorNativeToolDisplayState(pi);
|
|
70
|
+
if (registeredNativeToolSources.size === 0)
|
|
57
71
|
return;
|
|
58
72
|
if (!isCursorModel(model)) {
|
|
59
73
|
removeRegisteredNonCoreNativeCursorTools(pi);
|
|
@@ -63,7 +77,7 @@ export function syncRegisteredNativeCursorToolsForModel(pi, model) {
|
|
|
63
77
|
return;
|
|
64
78
|
const activeToolNames = new Set(pi.getActiveTools());
|
|
65
79
|
let changed = false;
|
|
66
|
-
for (const toolName of
|
|
80
|
+
for (const toolName of registeredNativeToolSources.keys()) {
|
|
67
81
|
if (isCursorReplayToolName(toolName) && !CURSOR_MODEL_ACTIVE_REPLAY_TOOL_NAMES.some((activeReplayToolName) => activeReplayToolName === toolName))
|
|
68
82
|
continue;
|
|
69
83
|
if (activeToolNames.has(toolName))
|
|
@@ -74,29 +88,39 @@ export function syncRegisteredNativeCursorToolsForModel(pi, model) {
|
|
|
74
88
|
if (changed)
|
|
75
89
|
pi.setActiveTools([...activeToolNames]);
|
|
76
90
|
}
|
|
77
|
-
function ensureNativeCursorToolsRegisteredForModel(pi, ctx) {
|
|
78
|
-
if (!isCursorModel(ctx.model)
|
|
91
|
+
function ensureNativeCursorToolsRegisteredForModel(pi, ctx, getCwd) {
|
|
92
|
+
if (!isCursorModel(ctx.model))
|
|
79
93
|
return;
|
|
80
94
|
const nonCoreToolNames = NATIVE_CURSOR_TOOL_NAMES.filter((toolName) => !isCursorCorePiReplayToolName(toolName));
|
|
81
95
|
const skippedToolNames = [
|
|
82
|
-
...registerNativeCursorToolsFromSet(pi, nonCoreToolNames),
|
|
83
|
-
...registerNativeCursorToolsFromSet(pi, CURSOR_CORE_PI_REPLAY_TOOL_NAMES),
|
|
96
|
+
...registerNativeCursorToolsFromSet(pi, nonCoreToolNames, getCwd),
|
|
97
|
+
...registerNativeCursorToolsFromSet(pi, CURSOR_CORE_PI_REPLAY_TOOL_NAMES, getCwd),
|
|
84
98
|
];
|
|
85
99
|
notifySkippedNativeCursorToolsIfNeeded(ctx, skippedToolNames);
|
|
86
100
|
}
|
|
87
|
-
function ensureThenSyncNativeCursorToolsForModel(pi, ctx) {
|
|
101
|
+
function ensureThenSyncNativeCursorToolsForModel(pi, ctx, getCwd) {
|
|
102
|
+
const { registeredNativeToolSources } = getCursorNativeToolDisplayState(pi);
|
|
103
|
+
const currentTools = pi.getAllTools();
|
|
104
|
+
for (const [toolName, sourceInfo] of registeredNativeToolSources) {
|
|
105
|
+
if (!currentTools.some((tool) => tool.name === toolName && tool.sourceInfo === sourceInfo)) {
|
|
106
|
+
registeredNativeToolSources.delete(toolName);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
88
109
|
const requested = isCursorNativeToolRegistrationRequested(ctx.mode);
|
|
89
|
-
setCursorNativeToolDisplayRuntimeRequested(requested);
|
|
110
|
+
setCursorNativeToolDisplayRuntimeRequested(requested, pi);
|
|
90
111
|
if (!requested) {
|
|
91
112
|
removeRegisteredNonCoreNativeCursorTools(pi);
|
|
92
113
|
return;
|
|
93
114
|
}
|
|
94
|
-
ensureNativeCursorToolsRegisteredForModel(pi, ctx);
|
|
115
|
+
ensureNativeCursorToolsRegisteredForModel(pi, ctx, getCwd);
|
|
95
116
|
syncRegisteredNativeCursorToolsForModel(pi, ctx.model);
|
|
96
117
|
}
|
|
97
118
|
export function registerCursorNativeToolDisplay(pi) {
|
|
119
|
+
registerCursorNativeToolDisplayState(pi);
|
|
120
|
+
let cwd = process.cwd();
|
|
98
121
|
registerCursorModelLifecycle(pi, (ctx) => {
|
|
99
|
-
|
|
122
|
+
cwd = ctx.cwd;
|
|
123
|
+
ensureThenSyncNativeCursorToolsForModel(pi, ctx, () => cwd);
|
|
100
124
|
});
|
|
101
125
|
}
|
|
102
126
|
export { isNativeCursorToolName, isCursorNativeToolDisplayRequested };
|
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import { parseOptionalEnvBoolean } from "./cursor-env-boolean.js";
|
|
2
|
+
import { normalizeCursorToolName } from "./cursor-tool-presentation-registry.js";
|
|
2
3
|
export const NATIVE_CURSOR_TOOL_DISPLAY_ENV = "PI_CURSOR_NATIVE_TOOL_DISPLAY";
|
|
3
4
|
export const NATIVE_CURSOR_TOOL_REGISTRATION_ENV = "PI_CURSOR_REGISTER_NATIVE_TOOLS";
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
function createDisplayState() {
|
|
6
|
+
return { registeredNativeToolSources: new Map(), skippedNativeToolNames: new Set(), runtimeRequested: false, resultIds: new Set() };
|
|
7
|
+
}
|
|
8
|
+
let lastDisplayState = createDisplayState();
|
|
9
|
+
const displayStates = new Map();
|
|
10
|
+
// IDs index results; the owning display state and tool authorize consumption.
|
|
6
11
|
export const nativeToolResults = new Map();
|
|
7
|
-
|
|
12
|
+
const resultStates = new Map();
|
|
13
|
+
export function getCursorNativeToolDisplayState(pi) {
|
|
14
|
+
if (!pi)
|
|
15
|
+
return lastDisplayState;
|
|
16
|
+
const state = displayStates.get(pi);
|
|
17
|
+
if (!state)
|
|
18
|
+
throw new Error("Cursor native display binding is no longer active.");
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
export function registerCursorNativeToolDisplayState(pi) {
|
|
22
|
+
const state = createDisplayState();
|
|
23
|
+
displayStates.set(pi, state);
|
|
24
|
+
lastDisplayState = state;
|
|
25
|
+
pi.on("session_shutdown", () => {
|
|
26
|
+
displayStates.delete(pi);
|
|
27
|
+
for (const id of state.resultIds) {
|
|
28
|
+
nativeToolResults.delete(id);
|
|
29
|
+
resultStates.delete(id);
|
|
30
|
+
}
|
|
31
|
+
state.resultIds.clear();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
8
34
|
export function readBooleanEnv(name, env = process.env) {
|
|
9
35
|
return parseOptionalEnvBoolean(env[name]);
|
|
10
36
|
}
|
|
@@ -19,34 +45,42 @@ export function isCursorNativeToolDisplayRequested(mode) {
|
|
|
19
45
|
export function isCursorNativeToolRegistrationRequested(mode) {
|
|
20
46
|
return mode !== "print" && readBooleanEnv(NATIVE_CURSOR_TOOL_REGISTRATION_ENV) !== false && isCursorNativeToolDisplayRequested(mode);
|
|
21
47
|
}
|
|
22
|
-
export function setCursorNativeToolDisplayRuntimeRequested(requested) {
|
|
23
|
-
|
|
48
|
+
export function setCursorNativeToolDisplayRuntimeRequested(requested, pi) {
|
|
49
|
+
getCursorNativeToolDisplayState(pi).runtimeRequested = requested;
|
|
24
50
|
}
|
|
25
51
|
export function isCursorNativeToolDisplayEnabled() {
|
|
26
|
-
return
|
|
52
|
+
return getCursorNativeToolDisplayState().registeredNativeToolSources.size > 0;
|
|
27
53
|
}
|
|
28
|
-
export function isCursorNativeToolDisplayRuntimeEnabled() {
|
|
29
|
-
return
|
|
54
|
+
export function isCursorNativeToolDisplayRuntimeEnabled(state = getCursorNativeToolDisplayState()) {
|
|
55
|
+
return state.runtimeRequested && readBooleanEnv(NATIVE_CURSOR_TOOL_DISPLAY_ENV) !== false && state.registeredNativeToolSources.size > 0;
|
|
30
56
|
}
|
|
31
57
|
export function canRenderCursorToolNatively(toolName) {
|
|
32
|
-
return
|
|
58
|
+
return getCursorNativeToolDisplayState().registeredNativeToolSources.has(toolName);
|
|
33
59
|
}
|
|
34
|
-
export function isRegisteredCursorNativeToolName(toolName) {
|
|
35
|
-
return
|
|
60
|
+
export function isRegisteredCursorNativeToolName(toolName, pi) {
|
|
61
|
+
return (pi ? displayStates.get(pi) : lastDisplayState)?.registeredNativeToolSources.has(toolName) === true;
|
|
36
62
|
}
|
|
37
|
-
export function recordCursorNativeToolDisplay(item) {
|
|
38
|
-
if (!
|
|
63
|
+
export function recordCursorNativeToolDisplay(item, state = getCursorNativeToolDisplayState()) {
|
|
64
|
+
if (!state.registeredNativeToolSources.has(item.toolName))
|
|
39
65
|
return false;
|
|
40
66
|
nativeToolResults.set(item.id, item);
|
|
67
|
+
resultStates.set(item.id, state);
|
|
68
|
+
state.resultIds.add(item.id);
|
|
41
69
|
return true;
|
|
42
70
|
}
|
|
43
71
|
export function deleteCursorNativeToolDisplay(id) {
|
|
44
72
|
nativeToolResults.delete(id);
|
|
73
|
+
resultStates.get(id)?.resultIds.delete(id);
|
|
74
|
+
resultStates.delete(id);
|
|
45
75
|
}
|
|
46
|
-
export function consumeCursorNativeToolDisplay(id) {
|
|
76
|
+
export function consumeCursorNativeToolDisplay(id, state, toolName) {
|
|
47
77
|
const item = nativeToolResults.get(id);
|
|
48
|
-
if (item)
|
|
49
|
-
|
|
78
|
+
if (item) {
|
|
79
|
+
if (resultStates.get(id) !== state || normalizeCursorToolName(item.toolName) !== normalizeCursorToolName(toolName)) {
|
|
80
|
+
throw new Error(`No owned Cursor ${toolName} result was available. This replay-only call does not execute work.`);
|
|
81
|
+
}
|
|
82
|
+
deleteCursorNativeToolDisplay(id);
|
|
83
|
+
}
|
|
50
84
|
return item;
|
|
51
85
|
}
|
|
52
86
|
export function isCursorReplayToolCallId(toolCallId) {
|
|
@@ -57,14 +91,15 @@ export function isCursorFileMutationToolName(toolName) {
|
|
|
57
91
|
}
|
|
58
92
|
export const __testUtils = {
|
|
59
93
|
nativeToolResultCount: () => nativeToolResults.size,
|
|
60
|
-
registerNativeToolNameForTests(toolName) {
|
|
61
|
-
|
|
62
|
-
|
|
94
|
+
registerNativeToolNameForTests(toolName, pi) {
|
|
95
|
+
const state = getCursorNativeToolDisplayState(pi);
|
|
96
|
+
state.runtimeRequested = true;
|
|
97
|
+
state.registeredNativeToolSources.set(toolName, { path: "test", source: "inline", scope: "temporary", origin: "top-level" });
|
|
63
98
|
},
|
|
64
99
|
reset() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
skippedNativeToolNames.clear();
|
|
100
|
+
lastDisplayState = createDisplayState();
|
|
101
|
+
displayStates.clear();
|
|
68
102
|
nativeToolResults.clear();
|
|
103
|
+
resultStates.clear();
|
|
69
104
|
},
|
|
70
105
|
};
|