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,6 +1,6 @@
|
|
|
1
1
|
import type { ModelListItem } from "@cursor/sdk";
|
|
2
2
|
|
|
3
|
-
// Generated with @cursor/sdk@1.0.32 from
|
|
3
|
+
// Generated with @cursor/sdk@1.0.32 from 45 Cursor models.
|
|
4
4
|
// Refresh with: npm run refresh:cursor-snapshots -- --write
|
|
5
5
|
// Do not add secrets; this file stores public model metadata only.
|
|
6
6
|
export const FALLBACK_MODEL_ITEMS = [
|
|
@@ -5599,6 +5599,185 @@ export const FALLBACK_MODEL_ITEMS = [
|
|
|
5599
5599
|
}
|
|
5600
5600
|
]
|
|
5601
5601
|
},
|
|
5602
|
+
{
|
|
5603
|
+
id: "claude-sonnet-5-5",
|
|
5604
|
+
displayName: "Claude Sonnet 5.5",
|
|
5605
|
+
parameters: [
|
|
5606
|
+
{
|
|
5607
|
+
id: "context",
|
|
5608
|
+
displayName: "Context",
|
|
5609
|
+
values: [
|
|
5610
|
+
{
|
|
5611
|
+
value: "300k",
|
|
5612
|
+
displayName: "300K"
|
|
5613
|
+
},
|
|
5614
|
+
{
|
|
5615
|
+
value: "1m",
|
|
5616
|
+
displayName: "1M"
|
|
5617
|
+
}
|
|
5618
|
+
]
|
|
5619
|
+
},
|
|
5620
|
+
{
|
|
5621
|
+
id: "reasoning_effort",
|
|
5622
|
+
displayName: "Effort",
|
|
5623
|
+
values: [
|
|
5624
|
+
{
|
|
5625
|
+
value: "low",
|
|
5626
|
+
displayName: "Low"
|
|
5627
|
+
},
|
|
5628
|
+
{
|
|
5629
|
+
value: "medium",
|
|
5630
|
+
displayName: "Medium"
|
|
5631
|
+
},
|
|
5632
|
+
{
|
|
5633
|
+
value: "high",
|
|
5634
|
+
displayName: "High"
|
|
5635
|
+
},
|
|
5636
|
+
{
|
|
5637
|
+
value: "xhigh",
|
|
5638
|
+
displayName: "Extra High"
|
|
5639
|
+
},
|
|
5640
|
+
{
|
|
5641
|
+
value: "max",
|
|
5642
|
+
displayName: "Max"
|
|
5643
|
+
}
|
|
5644
|
+
]
|
|
5645
|
+
}
|
|
5646
|
+
],
|
|
5647
|
+
variants: [
|
|
5648
|
+
{
|
|
5649
|
+
params: [
|
|
5650
|
+
{
|
|
5651
|
+
id: "context",
|
|
5652
|
+
value: "300k"
|
|
5653
|
+
},
|
|
5654
|
+
{
|
|
5655
|
+
id: "reasoning_effort",
|
|
5656
|
+
value: "low"
|
|
5657
|
+
}
|
|
5658
|
+
],
|
|
5659
|
+
displayName: "Claude Sonnet 5.5 Low"
|
|
5660
|
+
},
|
|
5661
|
+
{
|
|
5662
|
+
params: [
|
|
5663
|
+
{
|
|
5664
|
+
id: "context",
|
|
5665
|
+
value: "300k"
|
|
5666
|
+
},
|
|
5667
|
+
{
|
|
5668
|
+
id: "reasoning_effort",
|
|
5669
|
+
value: "medium"
|
|
5670
|
+
}
|
|
5671
|
+
],
|
|
5672
|
+
displayName: "Claude Sonnet 5.5 Medium"
|
|
5673
|
+
},
|
|
5674
|
+
{
|
|
5675
|
+
params: [
|
|
5676
|
+
{
|
|
5677
|
+
id: "context",
|
|
5678
|
+
value: "300k"
|
|
5679
|
+
},
|
|
5680
|
+
{
|
|
5681
|
+
id: "reasoning_effort",
|
|
5682
|
+
value: "high"
|
|
5683
|
+
}
|
|
5684
|
+
],
|
|
5685
|
+
displayName: "Claude Sonnet 5.5 High"
|
|
5686
|
+
},
|
|
5687
|
+
{
|
|
5688
|
+
params: [
|
|
5689
|
+
{
|
|
5690
|
+
id: "context",
|
|
5691
|
+
value: "300k"
|
|
5692
|
+
},
|
|
5693
|
+
{
|
|
5694
|
+
id: "reasoning_effort",
|
|
5695
|
+
value: "xhigh"
|
|
5696
|
+
}
|
|
5697
|
+
],
|
|
5698
|
+
displayName: "Claude Sonnet 5.5 Extra High"
|
|
5699
|
+
},
|
|
5700
|
+
{
|
|
5701
|
+
params: [
|
|
5702
|
+
{
|
|
5703
|
+
id: "context",
|
|
5704
|
+
value: "300k"
|
|
5705
|
+
},
|
|
5706
|
+
{
|
|
5707
|
+
id: "reasoning_effort",
|
|
5708
|
+
value: "max"
|
|
5709
|
+
}
|
|
5710
|
+
],
|
|
5711
|
+
displayName: "Claude Sonnet 5.5 Max"
|
|
5712
|
+
},
|
|
5713
|
+
{
|
|
5714
|
+
params: [
|
|
5715
|
+
{
|
|
5716
|
+
id: "context",
|
|
5717
|
+
value: "1m"
|
|
5718
|
+
},
|
|
5719
|
+
{
|
|
5720
|
+
id: "reasoning_effort",
|
|
5721
|
+
value: "low"
|
|
5722
|
+
}
|
|
5723
|
+
],
|
|
5724
|
+
displayName: "Claude Sonnet 5.5 1M Low"
|
|
5725
|
+
},
|
|
5726
|
+
{
|
|
5727
|
+
params: [
|
|
5728
|
+
{
|
|
5729
|
+
id: "context",
|
|
5730
|
+
value: "1m"
|
|
5731
|
+
},
|
|
5732
|
+
{
|
|
5733
|
+
id: "reasoning_effort",
|
|
5734
|
+
value: "medium"
|
|
5735
|
+
}
|
|
5736
|
+
],
|
|
5737
|
+
displayName: "Claude Sonnet 5.5 1M Medium"
|
|
5738
|
+
},
|
|
5739
|
+
{
|
|
5740
|
+
params: [
|
|
5741
|
+
{
|
|
5742
|
+
id: "context",
|
|
5743
|
+
value: "1m"
|
|
5744
|
+
},
|
|
5745
|
+
{
|
|
5746
|
+
id: "reasoning_effort",
|
|
5747
|
+
value: "high"
|
|
5748
|
+
}
|
|
5749
|
+
],
|
|
5750
|
+
displayName: "Claude Sonnet 5.5 1M High",
|
|
5751
|
+
isDefault: true
|
|
5752
|
+
},
|
|
5753
|
+
{
|
|
5754
|
+
params: [
|
|
5755
|
+
{
|
|
5756
|
+
id: "context",
|
|
5757
|
+
value: "1m"
|
|
5758
|
+
},
|
|
5759
|
+
{
|
|
5760
|
+
id: "reasoning_effort",
|
|
5761
|
+
value: "xhigh"
|
|
5762
|
+
}
|
|
5763
|
+
],
|
|
5764
|
+
displayName: "Claude Sonnet 5.5 1M Extra High"
|
|
5765
|
+
},
|
|
5766
|
+
{
|
|
5767
|
+
params: [
|
|
5768
|
+
{
|
|
5769
|
+
id: "context",
|
|
5770
|
+
value: "1m"
|
|
5771
|
+
},
|
|
5772
|
+
{
|
|
5773
|
+
id: "reasoning_effort",
|
|
5774
|
+
value: "max"
|
|
5775
|
+
}
|
|
5776
|
+
],
|
|
5777
|
+
displayName: "Claude Sonnet 5.5 1M Max"
|
|
5778
|
+
}
|
|
5779
|
+
]
|
|
5780
|
+
},
|
|
5602
5781
|
{
|
|
5603
5782
|
id: "composer-2",
|
|
5604
5783
|
displayName: "Composer 2",
|
|
@@ -5979,6 +6158,114 @@ export const FALLBACK_MODEL_ITEMS = [
|
|
|
5979
6158
|
}
|
|
5980
6159
|
]
|
|
5981
6160
|
},
|
|
6161
|
+
{
|
|
6162
|
+
id: "glm-5p3",
|
|
6163
|
+
displayName: "GLM 5.3",
|
|
6164
|
+
parameters: [
|
|
6165
|
+
{
|
|
6166
|
+
id: "reasoning",
|
|
6167
|
+
displayName: "Reasoning",
|
|
6168
|
+
values: [
|
|
6169
|
+
{
|
|
6170
|
+
value: "low",
|
|
6171
|
+
displayName: "Low"
|
|
6172
|
+
},
|
|
6173
|
+
{
|
|
6174
|
+
value: "high",
|
|
6175
|
+
displayName: "High"
|
|
6176
|
+
},
|
|
6177
|
+
{
|
|
6178
|
+
value: "max",
|
|
6179
|
+
displayName: "Max"
|
|
6180
|
+
}
|
|
6181
|
+
]
|
|
6182
|
+
}
|
|
6183
|
+
],
|
|
6184
|
+
variants: [
|
|
6185
|
+
{
|
|
6186
|
+
params: [
|
|
6187
|
+
{
|
|
6188
|
+
id: "reasoning",
|
|
6189
|
+
value: "low"
|
|
6190
|
+
}
|
|
6191
|
+
],
|
|
6192
|
+
displayName: "GLM 5.3 Low"
|
|
6193
|
+
},
|
|
6194
|
+
{
|
|
6195
|
+
params: [
|
|
6196
|
+
{
|
|
6197
|
+
id: "reasoning",
|
|
6198
|
+
value: "high"
|
|
6199
|
+
}
|
|
6200
|
+
],
|
|
6201
|
+
displayName: "GLM 5.3 High"
|
|
6202
|
+
},
|
|
6203
|
+
{
|
|
6204
|
+
params: [
|
|
6205
|
+
{
|
|
6206
|
+
id: "reasoning",
|
|
6207
|
+
value: "max"
|
|
6208
|
+
}
|
|
6209
|
+
],
|
|
6210
|
+
displayName: "GLM 5.3 Max",
|
|
6211
|
+
isDefault: true
|
|
6212
|
+
}
|
|
6213
|
+
]
|
|
6214
|
+
},
|
|
6215
|
+
{
|
|
6216
|
+
id: "glm-5p3-flash",
|
|
6217
|
+
displayName: "GLM 5.3 Flash",
|
|
6218
|
+
parameters: [
|
|
6219
|
+
{
|
|
6220
|
+
id: "reasoning",
|
|
6221
|
+
displayName: "Reasoning",
|
|
6222
|
+
values: [
|
|
6223
|
+
{
|
|
6224
|
+
value: "low",
|
|
6225
|
+
displayName: "Low"
|
|
6226
|
+
},
|
|
6227
|
+
{
|
|
6228
|
+
value: "high",
|
|
6229
|
+
displayName: "High"
|
|
6230
|
+
},
|
|
6231
|
+
{
|
|
6232
|
+
value: "max",
|
|
6233
|
+
displayName: "Max"
|
|
6234
|
+
}
|
|
6235
|
+
]
|
|
6236
|
+
}
|
|
6237
|
+
],
|
|
6238
|
+
variants: [
|
|
6239
|
+
{
|
|
6240
|
+
params: [
|
|
6241
|
+
{
|
|
6242
|
+
id: "reasoning",
|
|
6243
|
+
value: "low"
|
|
6244
|
+
}
|
|
6245
|
+
],
|
|
6246
|
+
displayName: "GLM 5.3 Flash Low"
|
|
6247
|
+
},
|
|
6248
|
+
{
|
|
6249
|
+
params: [
|
|
6250
|
+
{
|
|
6251
|
+
id: "reasoning",
|
|
6252
|
+
value: "high"
|
|
6253
|
+
}
|
|
6254
|
+
],
|
|
6255
|
+
displayName: "GLM 5.3 Flash High"
|
|
6256
|
+
},
|
|
6257
|
+
{
|
|
6258
|
+
params: [
|
|
6259
|
+
{
|
|
6260
|
+
id: "reasoning",
|
|
6261
|
+
value: "max"
|
|
6262
|
+
}
|
|
6263
|
+
],
|
|
6264
|
+
displayName: "GLM 5.3 Flash Max",
|
|
6265
|
+
isDefault: true
|
|
6266
|
+
}
|
|
6267
|
+
]
|
|
6268
|
+
},
|
|
5982
6269
|
{
|
|
5983
6270
|
id: "gpt-5-mini",
|
|
5984
6271
|
displayName: "GPT-5 Mini",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { isCursorModel } from "./cursor-model.js";
|
|
3
3
|
import { registerCursorModelLifecycle, type CursorModelLifecycleExtensionApi } from "./cursor-model-lifecycle.js";
|
|
4
|
-
import {
|
|
4
|
+
import { cursorSessionScopeKeyForManager } from "./cursor-session-scope.js";
|
|
5
5
|
import type { CursorModelFallbackIssue } from "./model-discovery.js";
|
|
6
6
|
|
|
7
7
|
export type CursorFallbackWarningExtensionApi = CursorModelLifecycleExtensionApi;
|
|
@@ -14,7 +14,7 @@ export function registerCursorFallbackIssueWarning(
|
|
|
14
14
|
|
|
15
15
|
registerCursorModelLifecycle(pi, (ctx: ExtensionContext) => {
|
|
16
16
|
if (!isCursorModel(ctx.model) || !ctx.hasUI) return;
|
|
17
|
-
const scopeKey =
|
|
17
|
+
const scopeKey = cursorSessionScopeKeyForManager(ctx.sessionManager);
|
|
18
18
|
if (warnedSessionScopeKeys.has(scopeKey)) return;
|
|
19
19
|
warnedSessionScopeKeys.add(scopeKey);
|
|
20
20
|
ctx.ui.notify(issue.message, "warning");
|
package/src/cursor-http1.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CursorSdkModule } from "./cursor-sdk-runtime.js";
|
|
2
2
|
import type { CursorResolvedSetting } from "./cursor-config.js";
|
|
3
3
|
import { asRecord } from "./cursor-record-utils.js";
|
|
4
|
+
import { getCursorSessionSettings } from "./cursor-session-settings.js";
|
|
4
5
|
|
|
5
6
|
export const CURSOR_HTTP1_ENTRY_TYPE = "cursor-http1-state";
|
|
6
7
|
|
|
@@ -12,7 +13,6 @@ type CursorHttp1Sdk = {
|
|
|
12
13
|
Cursor: Pick<CursorSdkModule["Cursor"], "configure">;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
let sessionCursorHttp1Enabled: boolean | undefined;
|
|
16
16
|
let globalPreferenceAuthoritative = false;
|
|
17
17
|
let configuredCursor: CursorHttp1Sdk["Cursor"] | undefined;
|
|
18
18
|
|
|
@@ -20,16 +20,16 @@ export function isCursorHttp1EntryData(value: unknown): value is CursorHttp1Entr
|
|
|
20
20
|
return typeof asRecord(value)?.enabled === "boolean";
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export function getStoredCursorHttp1Enabled(): boolean | undefined {
|
|
24
|
-
return
|
|
23
|
+
export function getStoredCursorHttp1Enabled(scopeKey?: string): boolean | undefined {
|
|
24
|
+
return getCursorSessionSettings(scopeKey).http1;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function setStoredCursorHttp1Enabled(enabled: boolean | undefined): void {
|
|
28
|
-
|
|
27
|
+
export function setStoredCursorHttp1Enabled(enabled: boolean | undefined, scopeKey?: string): void {
|
|
28
|
+
getCursorSessionSettings(scopeKey).http1 = enabled;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export function getResolvedSessionCursorHttp1Enabled(): boolean | undefined {
|
|
32
|
-
return globalPreferenceAuthoritative ? undefined :
|
|
31
|
+
export function getResolvedSessionCursorHttp1Enabled(scopeKey?: string): boolean | undefined {
|
|
32
|
+
return globalPreferenceAuthoritative ? undefined : getStoredCursorHttp1Enabled(scopeKey);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export function setCursorHttp1GlobalPreferenceAuthoritative(authoritative: boolean): void {
|
|
@@ -58,7 +58,7 @@ export function configureCursorSdkHttp1(
|
|
|
58
58
|
|
|
59
59
|
export const __testUtils = {
|
|
60
60
|
reset(): void {
|
|
61
|
-
|
|
61
|
+
setStoredCursorHttp1Enabled(undefined);
|
|
62
62
|
globalPreferenceAuthoritative = false;
|
|
63
63
|
configuredCursor = undefined;
|
|
64
64
|
},
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
type CursorLiveToolResultConsumption,
|
|
12
12
|
} from "./cursor-live-run-accounting.js";
|
|
13
13
|
import type { CursorSdkTurnUsage } from "./cursor-usage-accounting.js";
|
|
14
|
-
import type { CursorNativeToolDisplayItem } from "./cursor-native-tool-display-state.js";
|
|
14
|
+
import type { CursorNativeToolDisplayItem, CursorNativeToolDisplayState } from "./cursor-native-tool-display-state.js";
|
|
15
15
|
import type { CursorPiBridgeToolRequest, CursorPiToolBridgeRun } from "./cursor-pi-tool-bridge.js";
|
|
16
16
|
import { getCursorSessionScopeKey } from "./cursor-session-scope.js";
|
|
17
17
|
import type { CursorSdkEventDebugRecorder } from "./cursor-sdk-event-debug.js";
|
|
@@ -45,7 +45,7 @@ export interface CursorLiveRun {
|
|
|
45
45
|
sdkRun?: CursorLiveSdkRun;
|
|
46
46
|
ignoreFutureSdkTurnUsage?: boolean;
|
|
47
47
|
accounting: CursorLiveRunAccountingState;
|
|
48
|
-
|
|
48
|
+
onAbandon?: () => Promise<void>;
|
|
49
49
|
pendingEvents: CursorLiveQueuedEvent[];
|
|
50
50
|
textDeltas: string[];
|
|
51
51
|
emittedText: string;
|
|
@@ -59,6 +59,7 @@ export interface CursorLiveRun {
|
|
|
59
59
|
abortMessage?: string;
|
|
60
60
|
chainUserInputAfterCompletion: boolean;
|
|
61
61
|
debugRecorder?: CursorSdkEventDebugRecorder;
|
|
62
|
+
nativeDisplay?: CursorNativeToolDisplayState;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export interface CursorLiveRunCreateParams {
|
|
@@ -70,6 +71,7 @@ export interface CursorLiveRunCreateParams {
|
|
|
70
71
|
promptInputTokens: number;
|
|
71
72
|
textDeltas?: string[];
|
|
72
73
|
debugRecorder?: CursorSdkEventDebugRecorder;
|
|
74
|
+
nativeDisplay?: CursorNativeToolDisplayState;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export interface CursorLiveRunCoordinatorDeps {
|
|
@@ -96,7 +98,7 @@ export interface CursorLiveRunCoordinator {
|
|
|
96
98
|
consumeToolResults(run: CursorLiveRun, context: Context, getReplayId: CursorReplayIdResolver): CursorLiveToolResultConsumption;
|
|
97
99
|
takeTurnInputTokens(run: CursorLiveRun, toolResultInputTokens: number): number;
|
|
98
100
|
takeSdkTurnUsage(run: CursorLiveRun): CursorSdkTurnUsage | undefined;
|
|
99
|
-
getPendingFromContext(context: Context, getReplayId: CursorReplayIdResolver): CursorLiveRun | undefined;
|
|
101
|
+
getPendingFromContext(context: Context, getReplayId: CursorReplayIdResolver, scopeKey: string): CursorLiveRun | undefined;
|
|
100
102
|
getActiveForScope(scopeKey?: string): CursorLiveRun | undefined;
|
|
101
103
|
isReady(run: CursorLiveRun): boolean;
|
|
102
104
|
waitForProgress(run: CursorLiveRun, signal?: AbortSignal): Promise<void>;
|
|
@@ -293,6 +295,7 @@ export function createCursorLiveRunCoordinator(deps: CursorLiveRunCoordinatorDep
|
|
|
293
295
|
bridgeRun: params.bridgeRun,
|
|
294
296
|
sessionBridgeRun: params.sessionBridgeRun,
|
|
295
297
|
sessionAgentScopeKey,
|
|
298
|
+
nativeDisplay: params.nativeDisplay,
|
|
296
299
|
accounting: createCursorLiveRunAccountingState(params.promptInputTokens),
|
|
297
300
|
pendingEvents: [],
|
|
298
301
|
textDeltas: params.textDeltas ?? [],
|
|
@@ -420,7 +423,9 @@ export function createCursorLiveRunCoordinator(deps: CursorLiveRunCoordinatorDep
|
|
|
420
423
|
return taken.sdkTurnUsage;
|
|
421
424
|
},
|
|
422
425
|
|
|
423
|
-
getPendingFromContext(context, getReplayId): CursorLiveRun | undefined {
|
|
426
|
+
getPendingFromContext(context, getReplayId, scopeKey): CursorLiveRun | undefined {
|
|
427
|
+
const run = getUndisposed(pendingRunIdsByScopeKey.get(scopeKey));
|
|
428
|
+
if (!run) return undefined;
|
|
424
429
|
const messages = getCursorConversationMessages(context);
|
|
425
430
|
let index = messages.length - 1;
|
|
426
431
|
while (index >= 0 && messages[index]?.role === "user") {
|
|
@@ -430,15 +435,7 @@ export function createCursorLiveRunCoordinator(deps: CursorLiveRunCoordinatorDep
|
|
|
430
435
|
for (; index >= 0; index -= 1) {
|
|
431
436
|
const message = messages[index];
|
|
432
437
|
if (message.role !== "toolResult") break;
|
|
433
|
-
|
|
434
|
-
if (replayId) {
|
|
435
|
-
const replayRun = getUndisposed(replayId);
|
|
436
|
-
if (replayRun) return replayRun;
|
|
437
|
-
}
|
|
438
|
-
for (const run of pendingRuns.values()) {
|
|
439
|
-
if (run.disposed) continue;
|
|
440
|
-
if (run.bridgeRun?.hasPendingPiToolCallId(message.toolCallId)) return run;
|
|
441
|
-
}
|
|
438
|
+
if (matchesCursorLiveRunToolResult(run, message, getReplayId)) return run;
|
|
442
439
|
}
|
|
443
440
|
return undefined;
|
|
444
441
|
},
|
|
@@ -531,11 +528,13 @@ export function createCursorLiveRunCoordinator(deps: CursorLiveRunCoordinatorDep
|
|
|
531
528
|
}
|
|
532
529
|
if (abandoned) {
|
|
533
530
|
if (!run.done) {
|
|
531
|
+
const usageCompletion = run.onAbandon?.();
|
|
534
532
|
try {
|
|
535
533
|
await cancelCursorLiveSdkRun(run);
|
|
536
534
|
} catch {
|
|
537
535
|
// cancellation failure should not block session-agent abandonment
|
|
538
536
|
}
|
|
537
|
+
await usageCompletion;
|
|
539
538
|
}
|
|
540
539
|
await deps.abandonSessionAgent(run.sessionAgentScopeKey);
|
|
541
540
|
}
|
|
@@ -8,6 +8,7 @@ export interface NativeReplayRoutingInput {
|
|
|
8
8
|
toolName: string;
|
|
9
9
|
useNativeToolReplay: boolean;
|
|
10
10
|
activeToolNames?: ReadonlySet<string>;
|
|
11
|
+
registeredToolNames?: ReadonlySet<string>;
|
|
11
12
|
hasLiveRun: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -20,7 +21,7 @@ export function isNativeToolActiveInContext(toolName: string, activeToolNames?:
|
|
|
20
21
|
* Extension resync (pi active tools) is separate; this uses context.tools snapshot only.
|
|
21
22
|
*/
|
|
22
23
|
export function resolveNativeReplayDisposition(input: NativeReplayRoutingInput): NativeReplayDisposition {
|
|
23
|
-
if (!input.useNativeToolReplay || !canRenderCursorToolNatively(input.toolName)) {
|
|
24
|
+
if (!input.useNativeToolReplay || !(input.registeredToolNames?.has(input.toolName) ?? canRenderCursorToolNatively(input.toolName))) {
|
|
24
25
|
return "transcript_trace";
|
|
25
26
|
}
|
|
26
27
|
if (isNativeToolActiveInContext(input.toolName, input.activeToolNames) && input.hasLiveRun) {
|
|
@@ -13,9 +13,9 @@ import {
|
|
|
13
13
|
isCursorNativeToolRegistrationRequested,
|
|
14
14
|
NATIVE_CURSOR_TOOL_DISPLAY_ENV,
|
|
15
15
|
readBooleanEnv,
|
|
16
|
-
|
|
16
|
+
getCursorNativeToolDisplayState,
|
|
17
|
+
registerCursorNativeToolDisplayState,
|
|
17
18
|
setCursorNativeToolDisplayRuntimeRequested,
|
|
18
|
-
skippedNativeToolNames,
|
|
19
19
|
} from "./cursor-native-tool-display-state.js";
|
|
20
20
|
import { isCursorReplayToolName } from "./cursor-tool-presentation-registry.js";
|
|
21
21
|
import { registerNativeCursorTool } from "./cursor-native-tool-display-tools.js";
|
|
@@ -30,7 +30,11 @@ function isCursorCorePiReplayToolName(toolName: string): toolName is (typeof CUR
|
|
|
30
30
|
type CursorNativeToolActivationApi = Pick<ExtensionAPI, "getActiveTools" | "setActiveTools">;
|
|
31
31
|
type CursorNativeToolRegistryApi = CursorNativeToolActivationApi & Pick<ExtensionAPI, "getAllTools" | "registerTool">;
|
|
32
32
|
|
|
33
|
-
export
|
|
33
|
+
export type CursorNativeToolDisplayExtensionApi = CursorNativeToolRegistryApi
|
|
34
|
+
& CursorModelLifecycleExtensionApi & Parameters<typeof registerCursorNativeToolDisplayState>[0];
|
|
35
|
+
|
|
36
|
+
// Pi filters getAllTools even after registration; new/reloaded extensions receive a new API.
|
|
37
|
+
const filteredRegistrations = new WeakMap<CursorNativeToolRegistryApi, Set<NativeCursorToolName>>();
|
|
34
38
|
|
|
35
39
|
function hasNonBuiltinTool(pi: Pick<ExtensionAPI, "getAllTools">, toolName: NativeCursorToolName): boolean {
|
|
36
40
|
const existingTool = pi.getAllTools().find((tool) => tool.name === toolName);
|
|
@@ -44,17 +48,29 @@ type NativeRegistrationContext = Pick<ExtensionContext, "mode" | "model"> & {
|
|
|
44
48
|
function registerNativeCursorToolsFromSet(
|
|
45
49
|
pi: CursorNativeToolRegistryApi,
|
|
46
50
|
toolNames: readonly NativeCursorToolName[],
|
|
51
|
+
getCwd: () => string,
|
|
47
52
|
): NativeCursorToolName[] {
|
|
53
|
+
const state = getCursorNativeToolDisplayState(pi);
|
|
54
|
+
const { registeredNativeToolSources, skippedNativeToolNames } = state;
|
|
55
|
+
let filteredToolNames = filteredRegistrations.get(pi);
|
|
56
|
+
if (!filteredToolNames) {
|
|
57
|
+
filteredToolNames = new Set();
|
|
58
|
+
filteredRegistrations.set(pi, filteredToolNames);
|
|
59
|
+
}
|
|
48
60
|
const newlySkippedToolNames: NativeCursorToolName[] = [];
|
|
49
61
|
for (const toolName of toolNames) {
|
|
50
|
-
if (
|
|
62
|
+
if (registeredNativeToolSources.has(toolName) || filteredToolNames.has(toolName)) continue;
|
|
51
63
|
if (hasNonBuiltinTool(pi, toolName)) {
|
|
52
|
-
skippedNativeToolNames.
|
|
53
|
-
|
|
64
|
+
if (!skippedNativeToolNames.has(toolName)) {
|
|
65
|
+
skippedNativeToolNames.add(toolName);
|
|
66
|
+
newlySkippedToolNames.push(toolName);
|
|
67
|
+
}
|
|
54
68
|
continue;
|
|
55
69
|
}
|
|
56
|
-
registerNativeCursorTool(pi, toolName);
|
|
57
|
-
|
|
70
|
+
registerNativeCursorTool(pi, toolName, getCwd, state);
|
|
71
|
+
const registeredTool = pi.getAllTools().find((tool) => tool.name === toolName);
|
|
72
|
+
if (registeredTool) registeredNativeToolSources.set(toolName, registeredTool.sourceInfo);
|
|
73
|
+
else filteredToolNames.add(toolName);
|
|
58
74
|
}
|
|
59
75
|
return newlySkippedToolNames;
|
|
60
76
|
}
|
|
@@ -67,15 +83,12 @@ function notifySkippedNativeCursorToolsIfNeeded(ctx: NativeRegistrationContext,
|
|
|
67
83
|
);
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
function hasAttemptedNativeCursorToolRegistration(): boolean {
|
|
71
|
-
return registeredNativeToolNames.size > 0 || skippedNativeToolNames.size > 0;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
86
|
function removeRegisteredNonCoreNativeCursorTools(pi: CursorNativeToolActivationApi): void {
|
|
75
|
-
|
|
87
|
+
const { registeredNativeToolSources } = getCursorNativeToolDisplayState(pi);
|
|
88
|
+
if (registeredNativeToolSources.size === 0) return;
|
|
76
89
|
const activeToolNames = new Set(pi.getActiveTools());
|
|
77
90
|
let changed = false;
|
|
78
|
-
for (const toolName of
|
|
91
|
+
for (const toolName of registeredNativeToolSources.keys()) {
|
|
79
92
|
if (isCursorCorePiReplayToolName(toolName)) continue;
|
|
80
93
|
if (!activeToolNames.delete(toolName)) continue;
|
|
81
94
|
changed = true;
|
|
@@ -87,7 +100,8 @@ export function syncRegisteredNativeCursorToolsForModel(
|
|
|
87
100
|
pi: CursorNativeToolActivationApi,
|
|
88
101
|
model: ExtensionContext["model"],
|
|
89
102
|
): void {
|
|
90
|
-
|
|
103
|
+
const { registeredNativeToolSources } = getCursorNativeToolDisplayState(pi);
|
|
104
|
+
if (registeredNativeToolSources.size === 0) return;
|
|
91
105
|
if (!isCursorModel(model)) {
|
|
92
106
|
removeRegisteredNonCoreNativeCursorTools(pi);
|
|
93
107
|
return;
|
|
@@ -95,7 +109,7 @@ export function syncRegisteredNativeCursorToolsForModel(
|
|
|
95
109
|
if (arePiToolsDisabled(pi)) return;
|
|
96
110
|
const activeToolNames = new Set(pi.getActiveTools());
|
|
97
111
|
let changed = false;
|
|
98
|
-
for (const toolName of
|
|
112
|
+
for (const toolName of registeredNativeToolSources.keys()) {
|
|
99
113
|
if (isCursorReplayToolName(toolName) && !CURSOR_MODEL_ACTIVE_REPLAY_TOOL_NAMES.some((activeReplayToolName) => activeReplayToolName === toolName)) continue;
|
|
100
114
|
if (activeToolNames.has(toolName)) continue;
|
|
101
115
|
activeToolNames.add(toolName);
|
|
@@ -104,31 +118,41 @@ export function syncRegisteredNativeCursorToolsForModel(
|
|
|
104
118
|
if (changed) pi.setActiveTools([...activeToolNames]);
|
|
105
119
|
}
|
|
106
120
|
|
|
107
|
-
function ensureNativeCursorToolsRegisteredForModel(pi: CursorNativeToolRegistryApi, ctx: NativeRegistrationContext): void {
|
|
108
|
-
if (!isCursorModel(ctx.model)
|
|
121
|
+
function ensureNativeCursorToolsRegisteredForModel(pi: CursorNativeToolRegistryApi, ctx: NativeRegistrationContext, getCwd: () => string): void {
|
|
122
|
+
if (!isCursorModel(ctx.model)) return;
|
|
109
123
|
|
|
110
124
|
const nonCoreToolNames = NATIVE_CURSOR_TOOL_NAMES.filter((toolName) => !isCursorCorePiReplayToolName(toolName));
|
|
111
125
|
const skippedToolNames = [
|
|
112
|
-
...registerNativeCursorToolsFromSet(pi, nonCoreToolNames),
|
|
113
|
-
...registerNativeCursorToolsFromSet(pi, CURSOR_CORE_PI_REPLAY_TOOL_NAMES),
|
|
126
|
+
...registerNativeCursorToolsFromSet(pi, nonCoreToolNames, getCwd),
|
|
127
|
+
...registerNativeCursorToolsFromSet(pi, CURSOR_CORE_PI_REPLAY_TOOL_NAMES, getCwd),
|
|
114
128
|
];
|
|
115
129
|
notifySkippedNativeCursorToolsIfNeeded(ctx, skippedToolNames);
|
|
116
130
|
}
|
|
117
131
|
|
|
118
|
-
function ensureThenSyncNativeCursorToolsForModel(pi: CursorNativeToolRegistryApi, ctx: NativeRegistrationContext): void {
|
|
132
|
+
function ensureThenSyncNativeCursorToolsForModel(pi: CursorNativeToolRegistryApi, ctx: NativeRegistrationContext, getCwd: () => string): void {
|
|
133
|
+
const { registeredNativeToolSources } = getCursorNativeToolDisplayState(pi);
|
|
134
|
+
const currentTools = pi.getAllTools();
|
|
135
|
+
for (const [toolName, sourceInfo] of registeredNativeToolSources) {
|
|
136
|
+
if (!currentTools.some((tool) => tool.name === toolName && tool.sourceInfo === sourceInfo)) {
|
|
137
|
+
registeredNativeToolSources.delete(toolName);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
119
140
|
const requested = isCursorNativeToolRegistrationRequested(ctx.mode);
|
|
120
|
-
setCursorNativeToolDisplayRuntimeRequested(requested);
|
|
141
|
+
setCursorNativeToolDisplayRuntimeRequested(requested, pi);
|
|
121
142
|
if (!requested) {
|
|
122
143
|
removeRegisteredNonCoreNativeCursorTools(pi);
|
|
123
144
|
return;
|
|
124
145
|
}
|
|
125
|
-
ensureNativeCursorToolsRegisteredForModel(pi, ctx);
|
|
146
|
+
ensureNativeCursorToolsRegisteredForModel(pi, ctx, getCwd);
|
|
126
147
|
syncRegisteredNativeCursorToolsForModel(pi, ctx.model);
|
|
127
148
|
}
|
|
128
149
|
|
|
129
150
|
export function registerCursorNativeToolDisplay(pi: CursorNativeToolDisplayExtensionApi): void {
|
|
151
|
+
registerCursorNativeToolDisplayState(pi);
|
|
152
|
+
let cwd = process.cwd();
|
|
130
153
|
registerCursorModelLifecycle(pi, (ctx) => {
|
|
131
|
-
|
|
154
|
+
cwd = ctx.cwd;
|
|
155
|
+
ensureThenSyncNativeCursorToolsForModel(pi, ctx, () => cwd);
|
|
132
156
|
});
|
|
133
157
|
}
|
|
134
158
|
|