pi-cursor-sdk 0.1.37 → 0.1.38
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 +27 -0
- package/docs/cursor-native-tool-replay.md +3 -3
- package/package.json +1 -1
- package/scripts/platform-smoke/card-detect.mjs +1 -1
- package/src/context-window-cache.ts +10 -14
- package/src/context.ts +1 -1
- package/src/cursor-agent-message-web-tools.ts +2 -1
- package/src/cursor-agents-context-registration.ts +18 -0
- package/src/cursor-agents-context.ts +21 -30
- package/src/cursor-edit-diff.ts +4 -2
- package/src/cursor-fallback-warning.ts +22 -0
- package/src/cursor-incomplete-tool-visibility.ts +5 -10
- package/src/cursor-live-run-coordinator.ts +1 -1
- package/src/cursor-mcp-timeout-override.ts +0 -2
- package/src/cursor-model-lifecycle.ts +72 -0
- package/src/cursor-native-replay-routing.ts +1 -1
- package/src/cursor-native-replay-trace.ts +1 -1
- package/src/cursor-native-tool-display-registration.ts +16 -28
- package/src/cursor-native-tool-display-replay.ts +4 -21
- package/src/cursor-native-tool-display-state.ts +1 -1
- package/src/cursor-native-tool-display-tools.ts +10 -17
- package/src/cursor-native-tool-names.ts +16 -0
- package/src/cursor-pi-tool-bridge-env.ts +12 -0
- package/src/cursor-pi-tool-bridge-mcp.ts +16 -21
- package/src/cursor-pi-tool-bridge-run.ts +5 -5
- package/src/cursor-pi-tool-bridge-server.ts +8 -3
- package/src/cursor-pi-tool-bridge-snapshot.ts +7 -13
- package/src/cursor-pi-tool-bridge.ts +7 -7
- package/src/cursor-provider-lazy.ts +51 -0
- package/src/cursor-provider-live-run-drain.ts +1 -1
- package/src/cursor-provider-run-finalizer.ts +5 -5
- package/src/cursor-provider-run-outcome.ts +0 -1
- package/src/cursor-provider-turn-coordinator.ts +4 -5
- package/src/cursor-provider-turn-display-router.ts +5 -1
- package/src/cursor-provider-turn-emit.ts +1 -1
- package/src/cursor-provider-turn-lifecycle-emitter.ts +1 -5
- package/src/cursor-provider-turn-prepare.ts +13 -9
- package/src/cursor-provider-turn-runner.ts +3 -11
- package/src/cursor-provider-turn-sdk-normalizer.ts +28 -5
- package/src/cursor-provider-turn-send.ts +7 -2
- package/src/cursor-provider-turn-types.ts +1 -3
- package/src/cursor-provider.ts +3 -2
- package/src/cursor-question-tool.ts +5 -18
- package/src/cursor-record-utils.ts +42 -0
- package/src/cursor-replay-activity-builders.ts +16 -122
- package/src/cursor-replay-tool-details.ts +52 -80
- package/src/cursor-sdk-event-debug.ts +6 -6
- package/src/cursor-sensitive-text.ts +4 -4
- package/src/cursor-session-agent-lifecycle.ts +47 -0
- package/src/cursor-session-agent.ts +9 -47
- package/src/cursor-session-scope.ts +23 -4
- package/src/cursor-setting-sources.ts +8 -8
- package/src/cursor-skill-tool.ts +25 -32
- package/src/cursor-state.ts +66 -45
- package/src/cursor-tool-lifecycle.ts +16 -9
- package/src/cursor-tool-presentation-registry.ts +27 -18
- package/src/cursor-tool-result-display-readers.ts +185 -0
- package/src/cursor-tool-transcript.ts +17 -33
- package/src/cursor-tool-visibility.ts +9 -1
- package/src/cursor-transcript-tool-formatters.ts +23 -172
- package/src/cursor-transcript-tool-specs.ts +16 -41
- package/src/cursor-transcript-utils.ts +2 -34
- package/src/cursor-usage-accounting.ts +0 -6
- package/src/cursor-web-tool-activity.ts +4 -12
- package/src/cursor-web-tool-args.ts +1 -9
- package/src/index.ts +15 -16
- package/src/model-discovery.ts +5 -4
- package/src/model-list-cache.ts +37 -38
- package/src/cursor-native-tool-display.ts +0 -10
- package/src/cursor-provider-turn-api-key.ts +0 -1
- package/src/cursor-provider-turn-message-offset.ts +0 -15
- package/src/cursor-session-cwd.ts +0 -28
- package/src/cursor-tool-names.ts +0 -9
|
@@ -18,23 +18,15 @@ import {
|
|
|
18
18
|
withActivitySummaryFallback,
|
|
19
19
|
type CursorReplayActivitySummaryOverride,
|
|
20
20
|
type CursorReplayGenerateImageSummaryArgs,
|
|
21
|
-
type CursorReplayPathSummaryArgs,
|
|
22
|
-
type CursorReplayPlanSummaryArgs,
|
|
23
|
-
type CursorReplayReadLintsSummaryArgs,
|
|
24
|
-
type CursorReplayRecordScreenSummaryArgs,
|
|
25
|
-
type CursorReplaySemSearchSummaryArgs,
|
|
26
21
|
type CursorReplaySummaryArgs,
|
|
27
|
-
type CursorReplayTaskSummaryArgs,
|
|
28
|
-
type CursorReplayTodoSummaryArgs,
|
|
29
22
|
type CursorReplayWebFetchSummaryArgs,
|
|
30
23
|
type CursorReplayWebSearchSummaryArgs,
|
|
31
24
|
} from "./cursor-replay-summary-args.js";
|
|
25
|
+
import { truncateCursorDisplayLine } from "./cursor-display-text.js";
|
|
32
26
|
import {
|
|
33
|
-
buildCollapsedReplayDetailFields,
|
|
34
27
|
buildCreatePlanReplaySummaryArgs,
|
|
35
28
|
buildDeleteReplayDetailFields,
|
|
36
29
|
buildDeleteReplaySummaryArgs,
|
|
37
|
-
buildEmptyReplayDetailFields,
|
|
38
30
|
buildGenerateImageReplayDetailFields,
|
|
39
31
|
buildGenerateImageReplaySummaryArgs,
|
|
40
32
|
buildMcpReplaySummaryArgs,
|
|
@@ -55,6 +47,9 @@ import type {
|
|
|
55
47
|
|
|
56
48
|
export const CURSOR_REPLAY_ACTIVITY_TOOL_NAME = "cursor" as const;
|
|
57
49
|
|
|
50
|
+
const EMPTY_REPLAY_DETAIL_FIELDS = (): Record<string, never> => ({});
|
|
51
|
+
const COLLAPSED_REPLAY_DETAIL_FIELDS = (): { collapseDetailsByDefault: true } => ({ collapseDetailsByDefault: true });
|
|
52
|
+
|
|
58
53
|
export type CursorWebToolKind = "webSearch" | "webFetch";
|
|
59
54
|
|
|
60
55
|
export type CursorToolLifecycleLabelKind =
|
|
@@ -187,7 +182,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
187
182
|
replayCallSummary: withActivitySummaryFallback(summarizeReplayReadLints),
|
|
188
183
|
activityReplay: {
|
|
189
184
|
buildActivityArgs: buildReadLintsReplaySummaryArgs,
|
|
190
|
-
buildDetails:
|
|
185
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
191
186
|
},
|
|
192
187
|
},
|
|
193
188
|
{
|
|
@@ -198,7 +193,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
198
193
|
replayCallSummary: withActivitySummaryFallback(summarizeReplayTodoCount),
|
|
199
194
|
activityReplay: {
|
|
200
195
|
buildActivityArgs: ({ args, result }) => buildTodoReplaySummaryArgs(args, result),
|
|
201
|
-
buildDetails:
|
|
196
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
202
197
|
},
|
|
203
198
|
},
|
|
204
199
|
{
|
|
@@ -209,7 +204,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
209
204
|
replayCallSummary: withActivitySummaryFallback(summarizeReplayPlan),
|
|
210
205
|
activityReplay: {
|
|
211
206
|
buildActivityArgs: buildCreatePlanReplaySummaryArgs,
|
|
212
|
-
buildDetails:
|
|
207
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
213
208
|
},
|
|
214
209
|
},
|
|
215
210
|
{
|
|
@@ -220,7 +215,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
220
215
|
replayCallSummary: withActivitySummaryFallback(summarizeReplayTask),
|
|
221
216
|
activityReplay: {
|
|
222
217
|
buildActivityArgs: buildTaskReplaySummaryArgs,
|
|
223
|
-
buildDetails:
|
|
218
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
224
219
|
},
|
|
225
220
|
},
|
|
226
221
|
{
|
|
@@ -244,7 +239,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
244
239
|
replayCallSummary: withActivitySummaryFallback(summarizeReplayMcp),
|
|
245
240
|
activityReplay: {
|
|
246
241
|
buildActivityArgs: buildMcpReplaySummaryArgs,
|
|
247
|
-
buildDetails:
|
|
242
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
248
243
|
},
|
|
249
244
|
},
|
|
250
245
|
{
|
|
@@ -255,7 +250,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
255
250
|
replayCallSummary: withActivitySummaryFallback(formatReplaySemSearchQuery),
|
|
256
251
|
activityReplay: {
|
|
257
252
|
buildActivityArgs: buildSemSearchReplaySummaryArgs,
|
|
258
|
-
buildDetails:
|
|
253
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
259
254
|
},
|
|
260
255
|
},
|
|
261
256
|
{
|
|
@@ -266,7 +261,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
266
261
|
replayCallSummary: withActivitySummaryFallback(summarizeReplayRecordScreen),
|
|
267
262
|
activityReplay: {
|
|
268
263
|
buildActivityArgs: buildRecordScreenReplaySummaryArgs,
|
|
269
|
-
buildDetails:
|
|
264
|
+
buildDetails: EMPTY_REPLAY_DETAIL_FIELDS,
|
|
270
265
|
},
|
|
271
266
|
},
|
|
272
267
|
{
|
|
@@ -282,7 +277,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
282
277
|
),
|
|
283
278
|
activityReplay: {
|
|
284
279
|
buildActivityArgs: buildWebSearchReplaySummaryArgs,
|
|
285
|
-
buildDetails:
|
|
280
|
+
buildDetails: COLLAPSED_REPLAY_DETAIL_FIELDS,
|
|
286
281
|
},
|
|
287
282
|
},
|
|
288
283
|
{
|
|
@@ -298,7 +293,7 @@ export const CURSOR_TOOL_PRESENTATION_SPECS = [
|
|
|
298
293
|
),
|
|
299
294
|
activityReplay: {
|
|
300
295
|
buildActivityArgs: buildWebFetchReplaySummaryArgs,
|
|
301
|
-
buildDetails:
|
|
296
|
+
buildDetails: COLLAPSED_REPLAY_DETAIL_FIELDS,
|
|
302
297
|
},
|
|
303
298
|
},
|
|
304
299
|
] as const satisfies readonly CursorToolPresentationSpec[];
|
|
@@ -389,6 +384,20 @@ export function getCursorReplayActivityTitle(toolName: string): string | undefin
|
|
|
389
384
|
return spec.displayLabel;
|
|
390
385
|
}
|
|
391
386
|
|
|
387
|
+
function buildCursorGenericActivityTitle(displayName: string): string {
|
|
388
|
+
if (!displayName || displayName === "unknown") return "Cursor tool";
|
|
389
|
+
return `Cursor ${truncateCursorDisplayLine(displayName, 120)}`;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/** Canonical activity title: registry label when known, otherwise neutral fallback. */
|
|
393
|
+
export function getCursorToolActivityTitle(toolName: string): string {
|
|
394
|
+
const normalized = normalizeCursorToolName(toolName);
|
|
395
|
+
const known = getCursorReplayActivityTitle(normalized);
|
|
396
|
+
if (known) return known;
|
|
397
|
+
const label = toolName.trim() || normalized;
|
|
398
|
+
return buildCursorGenericActivityTitle(label);
|
|
399
|
+
}
|
|
400
|
+
|
|
392
401
|
function getCursorToolPresentationSpecByNormalizedKey(normalizedKey: string): CursorToolPresentationSpec | undefined {
|
|
393
402
|
return SPECS_BY_NORMALIZED_KEY.get(normalizedKey.toLowerCase());
|
|
394
403
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { asRecord, getArray, getNumber, getRecord, getString, stringifyUnknown } from "./cursor-record-utils.js";
|
|
2
|
+
import { scrubSensitiveText } from "./cursor-sensitive-text.js";
|
|
3
|
+
import { firstNonEmptyLine, formatDisplayPath, truncateArg } from "./cursor-transcript-utils.js";
|
|
4
|
+
|
|
5
|
+
export interface CursorToolResultLike {
|
|
6
|
+
status: string | undefined;
|
|
7
|
+
value: unknown;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface CursorToolResultReaderOptions {
|
|
11
|
+
cwd?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CursorTodoItem {
|
|
15
|
+
content: string;
|
|
16
|
+
status?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getReadLintPaths(
|
|
20
|
+
args: Record<string, unknown>,
|
|
21
|
+
result: CursorToolResultLike,
|
|
22
|
+
options: CursorToolResultReaderOptions,
|
|
23
|
+
): string[] {
|
|
24
|
+
const explicitPaths = Array.isArray(args.paths)
|
|
25
|
+
? args.paths.filter((entry): entry is string => typeof entry === "string")
|
|
26
|
+
: typeof args.path === "string"
|
|
27
|
+
? [args.path]
|
|
28
|
+
: [];
|
|
29
|
+
const resultPaths = (getArray(asRecord(result.value), "fileDiagnostics") ?? [])
|
|
30
|
+
.map((file) => getString(asRecord(file), "path"))
|
|
31
|
+
.filter((entry): entry is string => Boolean(entry));
|
|
32
|
+
return [...new Set([...explicitPaths, ...resultPaths].map((entry) => formatDisplayPath(entry, options.cwd)))];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getReadLintDiagnostics(result: CursorToolResultLike, options: CursorToolResultReaderOptions): string[] {
|
|
36
|
+
const value = asRecord(result.value);
|
|
37
|
+
const files = getArray(value, "fileDiagnostics") ?? [];
|
|
38
|
+
const lines: string[] = [];
|
|
39
|
+
for (const file of files) {
|
|
40
|
+
const fileRecord = asRecord(file);
|
|
41
|
+
const pathValue = getString(fileRecord, "path");
|
|
42
|
+
const path = pathValue ? formatDisplayPath(pathValue, options.cwd) : "unknown";
|
|
43
|
+
const diagnostics = getArray(fileRecord, "diagnostics") ?? [];
|
|
44
|
+
for (const diagnostic of diagnostics) {
|
|
45
|
+
const diagnosticRecord = asRecord(diagnostic);
|
|
46
|
+
const severity = getString(diagnosticRecord, "severity") ?? "diagnostic";
|
|
47
|
+
const message = getString(diagnosticRecord, "message") ?? "";
|
|
48
|
+
const source = getString(diagnosticRecord, "source");
|
|
49
|
+
lines.push(`${path}: ${severity}${source ? ` ${source}` : ""}: ${message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return lines;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getTodoItems(args: Record<string, unknown>, result: CursorToolResultLike): CursorTodoItem[] {
|
|
56
|
+
const value = asRecord(result.value);
|
|
57
|
+
const rawTodos = getArray(value, "todos") ?? getArray(args, "todos") ?? [];
|
|
58
|
+
const todos: CursorTodoItem[] = [];
|
|
59
|
+
for (const todo of rawTodos) {
|
|
60
|
+
const record = asRecord(todo);
|
|
61
|
+
const content = getString(record, "content");
|
|
62
|
+
if (!content) continue;
|
|
63
|
+
const status = getString(record, "status");
|
|
64
|
+
todos.push(status ? { content, status } : { content });
|
|
65
|
+
}
|
|
66
|
+
return todos;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function getTodoTotalCount(args: Record<string, unknown>, result: CursorToolResultLike, todos: CursorTodoItem[]): number {
|
|
70
|
+
return getNumber(asRecord(result.value), "totalCount") ?? getNumber(args, "totalCount") ?? todos.length;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getTaskDescription(args: Record<string, unknown>, result: CursorToolResultLike): string {
|
|
74
|
+
return getString(args, "description") ?? getString(asRecord(result.value), "description") ?? "task";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getNestedRecord(record: Record<string, unknown> | undefined, ...keys: string[]): Record<string, unknown> | undefined {
|
|
78
|
+
let current = record;
|
|
79
|
+
for (const key of keys) {
|
|
80
|
+
current = getRecord(current, key);
|
|
81
|
+
if (!current) return undefined;
|
|
82
|
+
}
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function collectTaskText(result: CursorToolResultLike): string {
|
|
87
|
+
const value = asRecord(result.value);
|
|
88
|
+
const success = getNestedRecord(value, "result", "success");
|
|
89
|
+
const command = getString(success, "command");
|
|
90
|
+
const stdout = getString(success, "stdout");
|
|
91
|
+
const interleavedOutput = getString(success, "interleavedOutput");
|
|
92
|
+
const assistantMessages = (getArray(value, "conversationSteps") ?? [])
|
|
93
|
+
.map((step) => getString(getRecord(asRecord(step), "assistantMessage"), "text"))
|
|
94
|
+
.filter((entry): entry is string => Boolean(entry));
|
|
95
|
+
const parts = [command ? `$ ${command}` : undefined, stdout || interleavedOutput, ...assistantMessages].filter((part): part is string => Boolean(part));
|
|
96
|
+
return parts.join("\n");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function getGenerateImagePath(args: Record<string, unknown>, result: CursorToolResultLike): string | undefined {
|
|
100
|
+
const value = asRecord(result.value);
|
|
101
|
+
return getString(value, "filePath") ?? getString(args, "filePath") ?? getString(args, "path");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function getGenerateImageDisplayPath(
|
|
105
|
+
args: Record<string, unknown>,
|
|
106
|
+
result: CursorToolResultLike,
|
|
107
|
+
options: CursorToolResultReaderOptions,
|
|
108
|
+
): string | undefined {
|
|
109
|
+
const path = getGenerateImagePath(args, result);
|
|
110
|
+
return path ? formatDisplayPath(path, options.cwd) : undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function inferImageMimeType(path: string | undefined): string | undefined {
|
|
114
|
+
const lower = path?.toLowerCase();
|
|
115
|
+
if (!lower) return undefined;
|
|
116
|
+
if (lower.endsWith(".png")) return "image/png";
|
|
117
|
+
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
118
|
+
if (lower.endsWith(".gif")) return "image/gif";
|
|
119
|
+
if (lower.endsWith(".webp")) return "image/webp";
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getMcpContentText(entry: unknown): string | undefined {
|
|
124
|
+
const record = asRecord(entry);
|
|
125
|
+
const directText = getString(record, "text");
|
|
126
|
+
if (directText) return directText;
|
|
127
|
+
const nestedText = getRecord(record, "text");
|
|
128
|
+
return getString(nestedText, "text");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function describeNonTextMcpContent(entry: unknown): string {
|
|
132
|
+
const record = asRecord(entry);
|
|
133
|
+
const type = getString(record, "type") ?? "content";
|
|
134
|
+
if (type === "image") {
|
|
135
|
+
const mimeType = getString(record, "mimeType") ?? getString(record, "mime") ?? getString(record, "mediaType");
|
|
136
|
+
return `[image${mimeType ? ` ${mimeType}` : ""} omitted]`;
|
|
137
|
+
}
|
|
138
|
+
if (type === "audio") return "[audio omitted]";
|
|
139
|
+
if (type === "resource") return "[resource omitted]";
|
|
140
|
+
return `[${type} omitted]`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface McpDisplayResult {
|
|
144
|
+
isToolError: boolean;
|
|
145
|
+
text: string;
|
|
146
|
+
nonTextSummary: string;
|
|
147
|
+
body: string;
|
|
148
|
+
preview?: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function readMcpDisplayResult(result: CursorToolResultLike): McpDisplayResult {
|
|
152
|
+
if (result.status === "error") {
|
|
153
|
+
return { isToolError: false, text: "", nonTextSummary: "", body: "" };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const value = asRecord(result.value);
|
|
157
|
+
const isToolError = value?.isError === true;
|
|
158
|
+
const content = getArray(value, "content") ?? [];
|
|
159
|
+
const textParts: string[] = [];
|
|
160
|
+
const nonTextParts: string[] = [];
|
|
161
|
+
let preview: string | undefined;
|
|
162
|
+
|
|
163
|
+
for (const entry of content) {
|
|
164
|
+
const text = getMcpContentText(entry);
|
|
165
|
+
if (text) {
|
|
166
|
+
textParts.push(text);
|
|
167
|
+
const line = firstNonEmptyLine(text);
|
|
168
|
+
if (!preview && line) preview = truncateArg(scrubSensitiveText(line), 120);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
nonTextParts.push(describeNonTextMcpContent(entry));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!preview) preview = nonTextParts[0];
|
|
175
|
+
const text = textParts.join("\n");
|
|
176
|
+
const nonTextSummary = nonTextParts.join("\n");
|
|
177
|
+
const body = text || nonTextSummary || scrubSensitiveText(stringifyUnknown(result.value), undefined);
|
|
178
|
+
return {
|
|
179
|
+
isToolError,
|
|
180
|
+
text,
|
|
181
|
+
nonTextSummary,
|
|
182
|
+
body: `${isToolError ? "[tool error]\n" : ""}${body}`.trim(),
|
|
183
|
+
...(preview ? { preview } : {}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { asRecord, getString } from "./cursor-record-utils.js";
|
|
2
|
+
import { normalizeCursorToolName } from "./cursor-tool-presentation-registry.js";
|
|
3
|
+
import {
|
|
4
|
+
buildCursorPiToolDisplayFromSpec,
|
|
5
|
+
formatCursorToolTranscriptFromSpec,
|
|
6
|
+
type ToolDisplayContext,
|
|
7
|
+
} from "./cursor-transcript-tool-specs.js";
|
|
1
8
|
import {
|
|
2
|
-
asRecord,
|
|
3
|
-
getString,
|
|
4
9
|
getToolArgs,
|
|
5
10
|
getToolName,
|
|
6
11
|
getToolResult,
|
|
@@ -8,27 +13,12 @@ import {
|
|
|
8
13
|
type CursorPiToolDisplay,
|
|
9
14
|
type TranscriptOptions,
|
|
10
15
|
} from "./cursor-transcript-utils.js";
|
|
11
|
-
import { normalizeCursorToolName as normalizeToolName } from "./cursor-tool-presentation-registry.js";
|
|
12
|
-
import {
|
|
13
|
-
buildCursorPiToolDisplayFromSpec,
|
|
14
|
-
formatCursorToolTranscriptFromSpec,
|
|
15
|
-
type ToolDisplayContext,
|
|
16
|
-
} from "./cursor-transcript-tool-specs.js";
|
|
17
16
|
import { resolveTranscriptToolName } from "./cursor-web-tool-activity.js";
|
|
18
17
|
|
|
19
18
|
export type { CursorPiToolDisplay } from "./cursor-transcript-utils.js";
|
|
19
|
+
export type { ToolDisplayContext } from "./cursor-transcript-tool-specs.js";
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
const name = normalizeToolName(getToolName(toolCall));
|
|
23
|
-
if (name !== "createPlan") return undefined;
|
|
24
|
-
const args = getToolArgs(toolCall);
|
|
25
|
-
const result = normalizeResult(getToolResult(toolCall));
|
|
26
|
-
const plan = getString(args, "plan") ?? getString(asRecord(result.value), "plan");
|
|
27
|
-
const trimmed = plan?.trim();
|
|
28
|
-
return trimmed || undefined;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function buildToolDisplayContext(toolCall: unknown, options: TranscriptOptions): ToolDisplayContext {
|
|
21
|
+
function buildToolDisplayContext(toolCall: unknown, options: TranscriptOptions = {}): ToolDisplayContext {
|
|
32
22
|
const rawName = getToolName(toolCall);
|
|
33
23
|
const args = getToolArgs(toolCall);
|
|
34
24
|
return {
|
|
@@ -48,18 +38,12 @@ export function buildCursorPiToolDisplay(toolCall: unknown, options: TranscriptO
|
|
|
48
38
|
return buildCursorPiToolDisplayFromSpec(buildToolDisplayContext(toolCall, options));
|
|
49
39
|
}
|
|
50
40
|
|
|
51
|
-
export function
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
name: completed.name ?? started.name,
|
|
60
|
-
type: completed.type ?? started.type,
|
|
61
|
-
args: completed.args ?? started.args,
|
|
62
|
-
input: completed.input ?? started.input,
|
|
63
|
-
result: completed.result ?? started.result,
|
|
64
|
-
};
|
|
41
|
+
export function getCursorCreatePlanText(toolCall: unknown): string | undefined {
|
|
42
|
+
const name = normalizeCursorToolName(getToolName(toolCall));
|
|
43
|
+
if (name !== "createPlan") return undefined;
|
|
44
|
+
const args = getToolArgs(toolCall);
|
|
45
|
+
const result = normalizeResult(getToolResult(toolCall));
|
|
46
|
+
const plan = getString(args, "plan") ?? getString(asRecord(result.value), "plan");
|
|
47
|
+
const trimmed = plan?.trim();
|
|
48
|
+
return trimmed || undefined;
|
|
65
49
|
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getCursorReplayActivityTitle,
|
|
3
|
+
getCursorToolVisibilityPolicy,
|
|
4
|
+
normalizeCursorToolName as normalizeToolName,
|
|
5
|
+
} from "./cursor-tool-presentation-registry.js";
|
|
2
6
|
import { getToolArgs, getToolName } from "./cursor-transcript-utils.js";
|
|
3
7
|
import { resolveTranscriptToolName } from "./cursor-web-tool-activity.js";
|
|
4
8
|
|
|
@@ -14,6 +18,10 @@ export interface CursorToolVisibility {
|
|
|
14
18
|
fastLocalDiscovery: boolean;
|
|
15
19
|
}
|
|
16
20
|
|
|
21
|
+
export function getNormalizedCursorToolName(toolCall: unknown): string {
|
|
22
|
+
return classifyCursorToolVisibility(toolCall).normalizedName;
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
export function classifyCursorToolVisibility(toolCall: unknown): CursorToolVisibility {
|
|
18
26
|
const args = getToolArgs(toolCall);
|
|
19
27
|
const displayName = resolveTranscriptToolName(getToolName(toolCall), args);
|