effect-cursor-sdk 0.2.1 → 0.3.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/README.md +15 -3
- package/dist/index.d.ts +201 -7
- package/dist/index.js +312 -14
- package/dist/index.js.map +1 -1
- package/docs/MIGRATION_NEXT_MAJOR.md +22 -0
- package/docs/RECIPES.md +256 -0
- package/docs/RELEASE_CHECKLIST.md +46 -0
- package/docs/SDK_COVERAGE.md +72 -0
- package/package.json +7 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config, ConfigProvider, Context, Data, Effect, Layer, ManagedRuntime, Match, Metric, Option, Redacted, Schema, Stream } from "effect";
|
|
1
|
+
import { Config, ConfigProvider, Context, Data, Effect, Layer, ManagedRuntime, Match, Metric, Option, Redacted, Schedule, Schema, Stream } from "effect";
|
|
2
2
|
import { Agent, AuthenticationError, AuthenticationError as AuthenticationError$1, ConfigurationError, ConfigurationError as ConfigurationError$1, Cursor, CursorAgentError, CursorAgentError as CursorAgentError$1, CursorAgentPlatform, IntegrationNotConnectedError, IntegrationNotConnectedError as IntegrationNotConnectedError$1, NetworkError, NetworkError as NetworkError$1, RateLimitError, RateLimitError as RateLimitError$1, UnknownAgentError, UnknownAgentError as UnknownAgentError$1, UnsupportedRunOperationError, UnsupportedRunOperationError as UnsupportedRunOperationError$1, createAgentPlatform, createInMemoryRunEventNotifier, createLocalRunEventNotifier, createSdkMessageRunStreamEvent, decodeLocalRunStreamEvent, decodeSdkMessageRunStreamEvent, getTurnType, isTerminalLocalRunStreamEvent, localRunStreamEventToSdkMessage, startLocalRunEventNotifierServer } from "@cursor/sdk";
|
|
3
3
|
//#region src/cursor-error.ts
|
|
4
4
|
/**
|
|
@@ -237,6 +237,14 @@ const agentOptionsFromConfig = (config, overrides = {}) => {
|
|
|
237
237
|
* It uses ConfigProvider to load the environment variables
|
|
238
238
|
* with their default names (`CURSOR_API_KEY`, `CURSOR_MODEL`, `CURSOR_LOCAL_CWD`)
|
|
239
239
|
* from {@link cursorConfig}.
|
|
240
|
+
* Omitting `CURSOR_API_KEY` only means no default API-key-based auth will be
|
|
241
|
+
* set; callers can still provide credentials via {@link agentOptionsFromConfig}
|
|
242
|
+
* overrides or the `*FromConfig` service helpers.
|
|
243
|
+
*
|
|
244
|
+
* If the API key is not set, it will log a warning message.
|
|
245
|
+
*
|
|
246
|
+
* **NOTE**: omitting the API key will cause an unauthenticated error
|
|
247
|
+
* in subsequent calls to the Cursor SDK API.
|
|
240
248
|
*
|
|
241
249
|
* @example
|
|
242
250
|
* ```ts
|
|
@@ -278,6 +286,7 @@ const loadCursorConfig = Effect.gen(function* () {
|
|
|
278
286
|
const provider = yield* ConfigProvider.ConfigProvider;
|
|
279
287
|
const raw = yield* cursorConfig.parse(provider);
|
|
280
288
|
const apiKey = Option.getOrUndefined(raw.apiKey);
|
|
289
|
+
if (apiKey === void 0 || apiKey === null) yield* Effect.logWarning("CURSOR_API_KEY is not set — this will cause an unauthenticated error in subsequent calls to the Cursor SDK API.");
|
|
281
290
|
const modelId = Option.getOrUndefined(raw.modelId);
|
|
282
291
|
const cwd = Option.getOrUndefined(raw.cwd);
|
|
283
292
|
return new CursorConfig({
|
|
@@ -493,7 +502,7 @@ const redact = (value) => {
|
|
|
493
502
|
return redactInner(value, /* @__PURE__ */ new Set(), 0);
|
|
494
503
|
};
|
|
495
504
|
/**
|
|
496
|
-
* Wraps an SDK-backed {@link Effect
|
|
505
|
+
* Wraps an SDK-backed {@link Effect} with consistent
|
|
497
506
|
* observability: increments {@link cursorOperationsStarted} at execution start,
|
|
498
507
|
* increments {@link cursorOperationsFailed} on the error channel, and attaches
|
|
499
508
|
* a span named `cursor.<operation>` (for example `cursor.agent.list`).
|
|
@@ -871,9 +880,10 @@ var MockCursorRun = class {
|
|
|
871
880
|
createdAt = Date.now();
|
|
872
881
|
#status;
|
|
873
882
|
#listeners = /* @__PURE__ */ new Set();
|
|
874
|
-
constructor(streamEvents, waitResult) {
|
|
883
|
+
constructor(streamEvents, waitResult, behavior) {
|
|
875
884
|
this.streamEvents = streamEvents;
|
|
876
885
|
this.waitResult = waitResult;
|
|
886
|
+
this.behavior = behavior;
|
|
877
887
|
this.id = waitResult.id;
|
|
878
888
|
this.agentId = streamEvents[0]?.agent_id ?? "mock-agent";
|
|
879
889
|
this.#status = waitResult.status;
|
|
@@ -893,10 +903,14 @@ var MockCursorRun = class {
|
|
|
893
903
|
get git() {
|
|
894
904
|
return this.waitResult.git;
|
|
895
905
|
}
|
|
896
|
-
supports(
|
|
897
|
-
|
|
906
|
+
supports(operation) {
|
|
907
|
+
const override = this.behavior?.supports?.[operation];
|
|
908
|
+
return override !== void 0 ? override : true;
|
|
909
|
+
}
|
|
910
|
+
unsupportedReason(operation) {
|
|
911
|
+
if (this.supports(operation)) return void 0;
|
|
912
|
+
return this.behavior?.unsupportedReason?.[operation] ?? "unsupported in mock";
|
|
898
913
|
}
|
|
899
|
-
unsupportedReason(_operation) {}
|
|
900
914
|
async *stream() {
|
|
901
915
|
yield* this.streamEvents;
|
|
902
916
|
}
|
|
@@ -936,6 +950,7 @@ var MockCursorAgent = class {
|
|
|
936
950
|
agentId;
|
|
937
951
|
runs = [];
|
|
938
952
|
closed = false;
|
|
953
|
+
#sendIndex = 0;
|
|
939
954
|
constructor(fixtures = {}) {
|
|
940
955
|
this.fixtures = fixtures;
|
|
941
956
|
this.agentId = fixtures.agentId ?? "mock-agent";
|
|
@@ -944,7 +959,14 @@ var MockCursorAgent = class {
|
|
|
944
959
|
return this.fixtures.result?.model;
|
|
945
960
|
}
|
|
946
961
|
async send(_message, _options) {
|
|
947
|
-
const
|
|
962
|
+
const seq = this.fixtures.sendSequence;
|
|
963
|
+
const piece = seq === void 0 ? void 0 : seq[Math.min(this.#sendIndex, Math.max(seq.length - 1, 0))];
|
|
964
|
+
const merged = piece !== void 0 ? {
|
|
965
|
+
...this.fixtures,
|
|
966
|
+
...piece
|
|
967
|
+
} : this.fixtures;
|
|
968
|
+
if (seq !== void 0) this.#sendIndex++;
|
|
969
|
+
const run = makeMockRun(merged);
|
|
948
970
|
this.runs.push(run);
|
|
949
971
|
return run;
|
|
950
972
|
}
|
|
@@ -976,6 +998,9 @@ const makeMockRun = (fixtures = {}) => {
|
|
|
976
998
|
id: runId,
|
|
977
999
|
status: "finished",
|
|
978
1000
|
result: ""
|
|
1001
|
+
}, {
|
|
1002
|
+
supports: fixtures.runSupports,
|
|
1003
|
+
unsupportedReason: fixtures.runUnsupportedReason
|
|
979
1004
|
});
|
|
980
1005
|
};
|
|
981
1006
|
/**
|
|
@@ -990,6 +1015,29 @@ const makeMockAgent = (fixtures = {}) => {
|
|
|
990
1015
|
return new MockCursorAgent(fixtures);
|
|
991
1016
|
};
|
|
992
1017
|
/**
|
|
1018
|
+
* Minimal assistant {@link SDKMessage} for streaming tests.
|
|
1019
|
+
*
|
|
1020
|
+
* @category testing
|
|
1021
|
+
*/
|
|
1022
|
+
const makeMockAssistantSdkMessage = (text, ids = {}) => {
|
|
1023
|
+
return {
|
|
1024
|
+
type: "assistant",
|
|
1025
|
+
agent_id: ids.agentId ?? "mock-agent",
|
|
1026
|
+
run_id: ids.runId ?? "mock-run",
|
|
1027
|
+
message: {
|
|
1028
|
+
role: "assistant",
|
|
1029
|
+
content: [{
|
|
1030
|
+
type: "text",
|
|
1031
|
+
text
|
|
1032
|
+
}]
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
};
|
|
1036
|
+
const rejectFactory = (fixtures, method) => {
|
|
1037
|
+
const err = fixtures.factoryErrors?.[method];
|
|
1038
|
+
if (err !== void 0) return Promise.reject(err);
|
|
1039
|
+
};
|
|
1040
|
+
/**
|
|
993
1041
|
* Layer replacing the SDK factory with deterministic mock behavior.
|
|
994
1042
|
*
|
|
995
1043
|
* This is the lowest-level mock entry point. Prefer {@link mockLayer} when you
|
|
@@ -1011,12 +1059,14 @@ const makeMockAgent = (fixtures = {}) => {
|
|
|
1011
1059
|
const makeMockSdkFactoryLayer = (fixtures = {}) => {
|
|
1012
1060
|
return Layer.succeed(CursorSdkFactory, CursorSdkFactory.of({
|
|
1013
1061
|
create: (_options) => {
|
|
1014
|
-
return Promise.resolve(makeMockAgent(fixtures));
|
|
1062
|
+
return rejectFactory(fixtures, "create") ?? Promise.resolve(makeMockAgent(fixtures));
|
|
1015
1063
|
},
|
|
1016
1064
|
resume: (_agentId, _options) => {
|
|
1017
|
-
return Promise.resolve(makeMockAgent(fixtures));
|
|
1065
|
+
return rejectFactory(fixtures, "resume") ?? Promise.resolve(makeMockAgent(fixtures));
|
|
1018
1066
|
},
|
|
1019
1067
|
prompt: async (_message, _options) => {
|
|
1068
|
+
const early = rejectFactory(fixtures, "prompt");
|
|
1069
|
+
if (early) return early;
|
|
1020
1070
|
return fixtures.result ?? {
|
|
1021
1071
|
id: fixtures.runId ?? "mock-run",
|
|
1022
1072
|
status: "finished",
|
|
@@ -1024,15 +1074,23 @@ const makeMockSdkFactoryLayer = (fixtures = {}) => {
|
|
|
1024
1074
|
};
|
|
1025
1075
|
},
|
|
1026
1076
|
listAgents: async (_options) => {
|
|
1077
|
+
const early = rejectFactory(fixtures, "listAgents");
|
|
1078
|
+
if (early) return early;
|
|
1027
1079
|
return { items: [...fixtures.agents ?? []] };
|
|
1028
1080
|
},
|
|
1029
1081
|
listRuns: async (_agentId, _options) => {
|
|
1082
|
+
const early = rejectFactory(fixtures, "listRuns");
|
|
1083
|
+
if (early) return early;
|
|
1030
1084
|
return { items: [makeMockRun(fixtures)] };
|
|
1031
1085
|
},
|
|
1032
1086
|
getRun: async (_runId, _options) => {
|
|
1087
|
+
const early = rejectFactory(fixtures, "getRun");
|
|
1088
|
+
if (early) return early;
|
|
1033
1089
|
return makeMockRun(fixtures);
|
|
1034
1090
|
},
|
|
1035
1091
|
getAgent: async (_agentId, _options) => {
|
|
1092
|
+
const early = rejectFactory(fixtures, "getAgent");
|
|
1093
|
+
if (early) return early;
|
|
1036
1094
|
return fixtures.agents?.[0] ?? {
|
|
1037
1095
|
agentId: fixtures.agentId ?? "mock-agent",
|
|
1038
1096
|
name: "Mock Agent",
|
|
@@ -1040,35 +1098,250 @@ const makeMockSdkFactoryLayer = (fixtures = {}) => {
|
|
|
1040
1098
|
lastModified: 0
|
|
1041
1099
|
};
|
|
1042
1100
|
},
|
|
1043
|
-
archiveAgent: async (_agentId, _options) => {
|
|
1044
|
-
|
|
1045
|
-
|
|
1101
|
+
archiveAgent: async (_agentId, _options) => {
|
|
1102
|
+
const early = rejectFactory(fixtures, "archiveAgent");
|
|
1103
|
+
if (early) return early;
|
|
1104
|
+
},
|
|
1105
|
+
unarchiveAgent: async (_agentId, _options) => {
|
|
1106
|
+
const early = rejectFactory(fixtures, "unarchiveAgent");
|
|
1107
|
+
if (early) return early;
|
|
1108
|
+
},
|
|
1109
|
+
deleteAgent: async (_agentId, _options) => {
|
|
1110
|
+
const early = rejectFactory(fixtures, "deleteAgent");
|
|
1111
|
+
if (early) return early;
|
|
1112
|
+
},
|
|
1046
1113
|
listMessages: async (_agentId, _options) => {
|
|
1114
|
+
const early = rejectFactory(fixtures, "listMessages");
|
|
1115
|
+
if (early) return early;
|
|
1047
1116
|
return [...fixtures.messages ?? []];
|
|
1048
1117
|
},
|
|
1049
1118
|
me: async (_options) => {
|
|
1119
|
+
const early = rejectFactory(fixtures, "me");
|
|
1120
|
+
if (early) return early;
|
|
1050
1121
|
return fixtures.user ?? {
|
|
1051
1122
|
apiKeyName: "mock",
|
|
1052
1123
|
createdAt: "1970-01-01T00:00:00.000Z"
|
|
1053
1124
|
};
|
|
1054
1125
|
},
|
|
1055
1126
|
listModels: async (_options) => {
|
|
1127
|
+
const early = rejectFactory(fixtures, "listModels");
|
|
1128
|
+
if (early) return early;
|
|
1056
1129
|
return [...fixtures.models ?? []];
|
|
1057
1130
|
},
|
|
1058
1131
|
listRepositories: async (_options) => {
|
|
1132
|
+
const early = rejectFactory(fixtures, "listRepositories");
|
|
1133
|
+
if (early) return early;
|
|
1059
1134
|
return [...fixtures.repositories ?? []];
|
|
1060
1135
|
}
|
|
1061
1136
|
}));
|
|
1062
1137
|
};
|
|
1063
1138
|
//#endregion
|
|
1139
|
+
//#region src/cursor-observability.ts
|
|
1140
|
+
/**
|
|
1141
|
+
* Reusable observability helpers: stream metrics, retry schedules, and safe summaries.
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* import {
|
|
1146
|
+
* cursorCatalogLoadTimeout,
|
|
1147
|
+
* cursorCatalogRetrySchedule,
|
|
1148
|
+
* CursorInspectionService,
|
|
1149
|
+
* liveLayer,
|
|
1150
|
+
* } from "effect-cursor-sdk";
|
|
1151
|
+
* import { Effect } from "effect";
|
|
1152
|
+
*
|
|
1153
|
+
* const catalog = Effect.gen(function* () {
|
|
1154
|
+
* const inspection = yield* CursorInspectionService;
|
|
1155
|
+
* return yield* Effect.all(
|
|
1156
|
+
* { agents: inspection.listAgents({ runtime: "cloud" }), models: inspection.listModels() },
|
|
1157
|
+
* { concurrency: "unbounded" },
|
|
1158
|
+
* ).pipe(Effect.retry(cursorCatalogRetrySchedule), Effect.timeout(cursorCatalogLoadTimeout));
|
|
1159
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1160
|
+
* ```
|
|
1161
|
+
*
|
|
1162
|
+
* @module
|
|
1163
|
+
*/
|
|
1164
|
+
/**
|
|
1165
|
+
* Default exponential retry for Cursor catalog-style calls (list agents, models, repos).
|
|
1166
|
+
*
|
|
1167
|
+
* Matches the pattern used in the advanced ops dashboard example: 150ms base, 3 attempts.
|
|
1168
|
+
*
|
|
1169
|
+
* @example
|
|
1170
|
+
* ```ts
|
|
1171
|
+
* import { CursorInspectionService, cursorCatalogRetrySchedule, liveLayer } from "effect-cursor-sdk";
|
|
1172
|
+
* import { Effect } from "effect";
|
|
1173
|
+
*
|
|
1174
|
+
* const program = Effect.gen(function* () {
|
|
1175
|
+
* const inspection = yield* CursorInspectionService;
|
|
1176
|
+
* return yield* inspection.listModels().pipe(Effect.retry(cursorCatalogRetrySchedule));
|
|
1177
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1178
|
+
* ```
|
|
1179
|
+
*
|
|
1180
|
+
* @category observability
|
|
1181
|
+
*/
|
|
1182
|
+
const cursorCatalogRetrySchedule = Schedule.exponential("150 millis").pipe(Schedule.both(Schedule.recurs(3)));
|
|
1183
|
+
/**
|
|
1184
|
+
* Default timeout for parallel catalog loads.
|
|
1185
|
+
*
|
|
1186
|
+
* @example
|
|
1187
|
+
* ```ts
|
|
1188
|
+
* import { CursorInspectionService, cursorCatalogLoadTimeout, liveLayer } from "effect-cursor-sdk";
|
|
1189
|
+
* import { Effect } from "effect";
|
|
1190
|
+
*
|
|
1191
|
+
* const program = Effect.gen(function* () {
|
|
1192
|
+
* const inspection = yield* CursorInspectionService;
|
|
1193
|
+
* return yield* Effect.all(
|
|
1194
|
+
* { user: inspection.me(), models: inspection.listModels() },
|
|
1195
|
+
* { concurrency: "unbounded" },
|
|
1196
|
+
* ).pipe(Effect.timeout(cursorCatalogLoadTimeout));
|
|
1197
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1198
|
+
* ```
|
|
1199
|
+
*
|
|
1200
|
+
* @category observability
|
|
1201
|
+
*/
|
|
1202
|
+
const cursorCatalogLoadTimeout = "45 seconds";
|
|
1203
|
+
/**
|
|
1204
|
+
* Append assistant-visible text from a streamed {@link SDKMessage} (same rules as {@link CursorRunService.collectText}).
|
|
1205
|
+
*
|
|
1206
|
+
* @example
|
|
1207
|
+
* ```ts
|
|
1208
|
+
* import { appendAssistantSdkMessageText } from "effect-cursor-sdk";
|
|
1209
|
+
* import type { SDKMessage } from "effect-cursor-sdk";
|
|
1210
|
+
*
|
|
1211
|
+
* const events: SDKMessage[] = []; // from run.stream()
|
|
1212
|
+
* const text = events.reduce(appendAssistantSdkMessageText, "");
|
|
1213
|
+
* ```
|
|
1214
|
+
*
|
|
1215
|
+
* @category observability
|
|
1216
|
+
*/
|
|
1217
|
+
const appendAssistantSdkMessageText = (text, event) => {
|
|
1218
|
+
if (event.type !== "assistant") return text;
|
|
1219
|
+
return text + event.message.content.filter((block) => {
|
|
1220
|
+
return block.type === "text";
|
|
1221
|
+
}).map((block) => {
|
|
1222
|
+
return block.text;
|
|
1223
|
+
}).join("");
|
|
1224
|
+
};
|
|
1225
|
+
/**
|
|
1226
|
+
* Wraps a run event stream and increments {@link cursorStreamEvents} per emitted event.
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* ```ts
|
|
1230
|
+
* import { CursorRunService, streamEventsTracked, liveLayer } from "effect-cursor-sdk";
|
|
1231
|
+
* import { Effect, Stream } from "effect";
|
|
1232
|
+
* import type { Run } from "effect-cursor-sdk";
|
|
1233
|
+
*
|
|
1234
|
+
* declare const run: Run;
|
|
1235
|
+
*
|
|
1236
|
+
* const program = Effect.gen(function* () {
|
|
1237
|
+
* const runs = yield* CursorRunService;
|
|
1238
|
+
* yield* streamEventsTracked(runs.streamEvents(run)).pipe(Stream.runDrain);
|
|
1239
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1240
|
+
* ```
|
|
1241
|
+
*
|
|
1242
|
+
* @category observability
|
|
1243
|
+
*/
|
|
1244
|
+
const streamEventsTracked = (stream) => {
|
|
1245
|
+
return stream.pipe(Stream.tap(() => Effect.void.pipe(Effect.trackSuccesses(cursorStreamEvents.pipe(Metric.withConstantInput(1))))));
|
|
1246
|
+
};
|
|
1247
|
+
/**
|
|
1248
|
+
* Like {@link CursorRunService.collectText}, but increments {@link cursorStreamEvents} per stream chunk.
|
|
1249
|
+
*
|
|
1250
|
+
* @param run - SDK run handle.
|
|
1251
|
+
* @param streamEvents - Typically `runs.streamEvents` from {@link CursorRunService}.
|
|
1252
|
+
*
|
|
1253
|
+
* @example
|
|
1254
|
+
* ```ts
|
|
1255
|
+
* import { collectTextTracked, CursorRunService, liveLayer } from "effect-cursor-sdk";
|
|
1256
|
+
* import { Effect } from "effect";
|
|
1257
|
+
* import type { Run } from "effect-cursor-sdk";
|
|
1258
|
+
*
|
|
1259
|
+
* declare const run: Run;
|
|
1260
|
+
*
|
|
1261
|
+
* const text = Effect.gen(function* () {
|
|
1262
|
+
* const runs = yield* CursorRunService;
|
|
1263
|
+
* return yield* collectTextTracked(run, (r) => runs.streamEvents(r));
|
|
1264
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1265
|
+
* ```
|
|
1266
|
+
*
|
|
1267
|
+
* @category observability
|
|
1268
|
+
*/
|
|
1269
|
+
const collectTextTracked = (run, streamEvents) => {
|
|
1270
|
+
return streamEventsTracked(streamEvents(run)).pipe(Stream.runFold(() => "", appendAssistantSdkMessageText));
|
|
1271
|
+
};
|
|
1272
|
+
/**
|
|
1273
|
+
* Build a redacted, log-safe summary of {@link AgentOptions} **without** an API key value.
|
|
1274
|
+
*
|
|
1275
|
+
* @remarks
|
|
1276
|
+
* Nested structures are passed through {@link redact}. Never log raw `apiKey`.
|
|
1277
|
+
*
|
|
1278
|
+
* @example
|
|
1279
|
+
* ```ts
|
|
1280
|
+
* import { summarizeAgentOptionsForLog } from "effect-cursor-sdk";
|
|
1281
|
+
* import { Effect } from "effect";
|
|
1282
|
+
*
|
|
1283
|
+
* const program = Effect.gen(function* () {
|
|
1284
|
+
* const options = { model: { id: "composer-2" }, apiKey: "secret" };
|
|
1285
|
+
* yield* Effect.logInfo("cursor run", summarizeAgentOptionsForLog(options));
|
|
1286
|
+
* });
|
|
1287
|
+
* ```
|
|
1288
|
+
*
|
|
1289
|
+
* @category observability
|
|
1290
|
+
*/
|
|
1291
|
+
const summarizeAgentOptionsForLog = (options) => {
|
|
1292
|
+
const mcpKeys = options.mcpServers ? Object.keys(options.mcpServers) : void 0;
|
|
1293
|
+
return redact({
|
|
1294
|
+
model: options.model,
|
|
1295
|
+
name: options.name,
|
|
1296
|
+
agentId: options.agentId,
|
|
1297
|
+
local: options.local,
|
|
1298
|
+
cloud: options.cloud ? {
|
|
1299
|
+
reposCount: options.cloud.repos?.length,
|
|
1300
|
+
autoCreatePR: options.cloud.autoCreatePR,
|
|
1301
|
+
workOnCurrentBranch: options.cloud.workOnCurrentBranch,
|
|
1302
|
+
envType: options.cloud.env?.type
|
|
1303
|
+
} : void 0,
|
|
1304
|
+
mcpServerNames: mcpKeys,
|
|
1305
|
+
agentsCount: options.agents ? Object.keys(options.agents).length : void 0
|
|
1306
|
+
});
|
|
1307
|
+
};
|
|
1308
|
+
/**
|
|
1309
|
+
* Attach minimal run identifiers for structured logs or span attributes.
|
|
1310
|
+
*
|
|
1311
|
+
* @example
|
|
1312
|
+
* ```ts
|
|
1313
|
+
* import { summarizeRunForLog } from "effect-cursor-sdk";
|
|
1314
|
+
* import { Effect } from "effect";
|
|
1315
|
+
*
|
|
1316
|
+
* const program = Effect.gen(function* () {
|
|
1317
|
+
* const run = { id: "run_1", agentId: "agt_1", status: "finished" as const };
|
|
1318
|
+
* yield* Effect.logDebug("run done", summarizeRunForLog(run));
|
|
1319
|
+
* });
|
|
1320
|
+
* ```
|
|
1321
|
+
*
|
|
1322
|
+
* @category observability
|
|
1323
|
+
*/
|
|
1324
|
+
const summarizeRunForLog = (run) => {
|
|
1325
|
+
return {
|
|
1326
|
+
runId: run.id,
|
|
1327
|
+
agentId: run.agentId,
|
|
1328
|
+
status: run.status
|
|
1329
|
+
};
|
|
1330
|
+
};
|
|
1331
|
+
//#endregion
|
|
1064
1332
|
//#region src/cursor-run.ts
|
|
1065
1333
|
/**
|
|
1066
1334
|
* Effect-native helpers for SDK run handles.
|
|
1067
1335
|
*
|
|
1068
1336
|
* @example
|
|
1069
1337
|
* ```ts
|
|
1338
|
+
* const runService = yield* CursorRunService;
|
|
1339
|
+
*
|
|
1340
|
+
* // Create a run with the agent service
|
|
1070
1341
|
* const run = yield* agents.send(agent, "Refactor auth")
|
|
1071
|
-
*
|
|
1342
|
+
*
|
|
1343
|
+
* // Use the run service with the created run
|
|
1344
|
+
* const conversation = yield* runService.conversation(run);
|
|
1072
1345
|
* ```
|
|
1073
1346
|
*
|
|
1074
1347
|
* @see {@link CursorAgentService} for creating and sending runs.
|
|
@@ -1132,6 +1405,31 @@ var CursorRunService = class CursorRunService extends Context.Service()("effect-
|
|
|
1132
1405
|
onDidChangeStatus: (run, listener) => {
|
|
1133
1406
|
return Effect.sync(() => run.onDidChangeStatus(listener));
|
|
1134
1407
|
},
|
|
1408
|
+
streamStatusChanges: (run) => {
|
|
1409
|
+
return Stream.fromAsyncIterable((async function* () {
|
|
1410
|
+
const pending = [];
|
|
1411
|
+
let notify;
|
|
1412
|
+
const unsub = run.onDidChangeStatus((status) => {
|
|
1413
|
+
pending.push(status);
|
|
1414
|
+
const resume = notify;
|
|
1415
|
+
notify = void 0;
|
|
1416
|
+
resume?.();
|
|
1417
|
+
});
|
|
1418
|
+
try {
|
|
1419
|
+
while (true) {
|
|
1420
|
+
if (pending.length > 0) {
|
|
1421
|
+
yield pending.shift();
|
|
1422
|
+
continue;
|
|
1423
|
+
}
|
|
1424
|
+
await new Promise((resolve) => {
|
|
1425
|
+
notify = resolve;
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
} finally {
|
|
1429
|
+
unsub();
|
|
1430
|
+
}
|
|
1431
|
+
})(), () => void 0);
|
|
1432
|
+
},
|
|
1135
1433
|
collectText: (run) => {
|
|
1136
1434
|
return Stream.fromAsyncIterable(run.stream(), (cause) => {
|
|
1137
1435
|
return mapCursorError(cause, {
|
|
@@ -1234,6 +1532,6 @@ const makeMockRuntime = (fixtures = {}) => {
|
|
|
1234
1532
|
*/
|
|
1235
1533
|
const packageName = "effect-cursor-sdk";
|
|
1236
1534
|
//#endregion
|
|
1237
|
-
export { AuthenticationError, ConfigurationError, CursorAgentError, CursorAgentPlatform, CursorAgentService, CursorApiKey, CursorArtifactService, CursorAuthenticationError, CursorConfig, CursorConfigurationError, CursorInspectionService, CursorIntegrationNotConnectedError, CursorLocalCwd, CursorModelId, CursorNetworkError, CursorRateLimitError, CursorRunFailedError, CursorRunService, CursorSdkFactory, CursorStreamError, CursorUnknownError, CursorUnsupportedOperationError, IntegrationNotConnectedError, MockCursorAgent, MockCursorRun, NetworkError, RateLimitError, UnknownAgentError, UnsupportedRunOperationError, agentOptionsFromConfig, createAgentPlatform, createInMemoryRunEventNotifier, createLocalRunEventNotifier, createSdkMessageRunStreamEvent, cursorConfig, cursorOperationsFailed, cursorOperationsStarted, cursorStreamEvents, decodeLocalRunStreamEvent, decodeSdkMessageRunStreamEvent, getTurnType, instrument, isTerminalLocalRunStreamEvent, liveLayer, liveRuntime, loadCursorConfig, localRunStreamEventToSdkMessage, makeMockAgent, makeMockRun, makeMockRuntime, makeMockSdkFactoryLayer, mapCursorError, mockLayer, packageName, redact, startLocalRunEventNotifierServer };
|
|
1535
|
+
export { AuthenticationError, ConfigurationError, CursorAgentError, CursorAgentPlatform, CursorAgentService, CursorApiKey, CursorArtifactService, CursorAuthenticationError, CursorConfig, CursorConfigurationError, CursorInspectionService, CursorIntegrationNotConnectedError, CursorLocalCwd, CursorModelId, CursorNetworkError, CursorRateLimitError, CursorRunFailedError, CursorRunService, CursorSdkFactory, CursorStreamError, CursorUnknownError, CursorUnsupportedOperationError, IntegrationNotConnectedError, MockCursorAgent, MockCursorRun, NetworkError, RateLimitError, UnknownAgentError, UnsupportedRunOperationError, agentOptionsFromConfig, appendAssistantSdkMessageText, collectTextTracked, createAgentPlatform, createInMemoryRunEventNotifier, createLocalRunEventNotifier, createSdkMessageRunStreamEvent, cursorCatalogLoadTimeout, cursorCatalogRetrySchedule, cursorConfig, cursorOperationsFailed, cursorOperationsStarted, cursorStreamEvents, decodeLocalRunStreamEvent, decodeSdkMessageRunStreamEvent, getTurnType, instrument, isTerminalLocalRunStreamEvent, liveLayer, liveRuntime, loadCursorConfig, localRunStreamEventToSdkMessage, makeMockAgent, makeMockAssistantSdkMessage, makeMockRun, makeMockRuntime, makeMockSdkFactoryLayer, mapCursorError, mockLayer, packageName, redact, startLocalRunEventNotifierServer, streamEventsTracked, summarizeAgentOptionsForLog, summarizeRunForLog };
|
|
1238
1536
|
|
|
1239
1537
|
//# sourceMappingURL=index.js.map
|