@band-ai/sdk 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CopilotACPAdapter-Bj6NRdqd.d.ts → CursorACPAdapter-7-Jtl1LV.d.ts} +90 -1
- package/dist/{CopilotACPAdapter-HRvat7CP.d.cts → CursorACPAdapter-_YhrXRWq.d.cts} +90 -1
- package/dist/adapters.cjs +476 -128
- package/dist/adapters.d.cts +1 -1
- package/dist/adapters.d.ts +1 -1
- package/dist/adapters.js +5 -1
- package/dist/{chunk-KXLV645N.js → chunk-STUSNTHF.js} +463 -117
- package/dist/index.cjs +413 -65
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1070,7 +1070,9 @@ __export(src_exports, {
|
|
|
1070
1070
|
ClaudeSDKAdapter: () => ClaudeSDKAdapter,
|
|
1071
1071
|
CodexAdapter: () => CodexAdapter,
|
|
1072
1072
|
CopilotACPAdapter: () => CopilotACPAdapter,
|
|
1073
|
+
CursorACPAdapter: () => CursorACPAdapter,
|
|
1073
1074
|
DEFAULT_COPILOT_ACP_COMMAND: () => DEFAULT_COPILOT_ACP_COMMAND,
|
|
1075
|
+
DEFAULT_CURSOR_ACP_COMMAND: () => DEFAULT_CURSOR_ACP_COMMAND,
|
|
1074
1076
|
DEFAULT_OMP_ACP_COMMAND: () => DEFAULT_OMP_ACP_COMMAND,
|
|
1075
1077
|
DefaultPreprocessor: () => DefaultPreprocessor,
|
|
1076
1078
|
DeliveryFailedError: () => DeliveryFailedError,
|
|
@@ -8342,15 +8344,20 @@ function systemUpdateParts(participantsMessage, contactsMessage) {
|
|
|
8342
8344
|
}
|
|
8343
8345
|
function buildConversationPrompt(options) {
|
|
8344
8346
|
const parts = [];
|
|
8345
|
-
if (options.isSessionBootstrap
|
|
8346
|
-
const historyText = options.history.raw.slice(-(options.maxHistoryMessages ?? 50)).map(formatHistoryLine).join("\n");
|
|
8347
|
-
|
|
8347
|
+
if (options.isSessionBootstrap) {
|
|
8348
|
+
const historyText = options.history.raw.slice(-(options.maxHistoryMessages ?? 50)).filter(isTextHistoryEntry).map(formatHistoryLine).join("\n");
|
|
8349
|
+
if (historyText) {
|
|
8350
|
+
parts.push(`${options.historyHeader}
|
|
8348
8351
|
${historyText}`);
|
|
8352
|
+
}
|
|
8349
8353
|
}
|
|
8350
8354
|
parts.push(...systemUpdateParts(options.participantsMessage, options.contactsMessage));
|
|
8351
8355
|
parts.push(options.currentMessage);
|
|
8352
8356
|
return parts.join("\n\n");
|
|
8353
8357
|
}
|
|
8358
|
+
function isTextHistoryEntry(entry) {
|
|
8359
|
+
return entry.message_type === void 0 || entry.message_type === "text";
|
|
8360
|
+
}
|
|
8354
8361
|
function formatHistoryLine(entry) {
|
|
8355
8362
|
const sender = String(entry.sender_name ?? entry.sender_type ?? "Unknown");
|
|
8356
8363
|
const content = String(entry.content ?? "");
|
|
@@ -17255,23 +17262,17 @@ function asAcpJsonRpcError(error) {
|
|
|
17255
17262
|
init_chatEvents();
|
|
17256
17263
|
init_schemas();
|
|
17257
17264
|
|
|
17258
|
-
// src/adapters/acp/types.ts
|
|
17259
|
-
function choosePermissionOption(options) {
|
|
17260
|
-
if (options.length === 0) {
|
|
17261
|
-
return null;
|
|
17262
|
-
}
|
|
17263
|
-
return options.find((option) => option.kind === "allow_once") ?? options.find((option) => option.kind === "allow_always") ?? options[0];
|
|
17264
|
-
}
|
|
17265
|
-
|
|
17266
17265
|
// src/adapters/acp/client.ts
|
|
17267
17266
|
var BandACPClient = class {
|
|
17268
17267
|
sessionChunks = /* @__PURE__ */ new Map();
|
|
17269
17268
|
permissionHandler;
|
|
17269
|
+
extensionHandler;
|
|
17270
17270
|
// The handler is connection-scoped and required at construction, so it is
|
|
17271
17271
|
// already in place before the agent process is spawned: there is no window
|
|
17272
17272
|
// in which a `session/request_permission` has nowhere to go.
|
|
17273
|
-
constructor(permissionHandler) {
|
|
17273
|
+
constructor(permissionHandler, extensionHandler) {
|
|
17274
17274
|
this.permissionHandler = permissionHandler;
|
|
17275
|
+
this.extensionHandler = extensionHandler;
|
|
17275
17276
|
}
|
|
17276
17277
|
beginSession(sessionId) {
|
|
17277
17278
|
this.sessionChunks.set(sessionId, []);
|
|
@@ -17316,62 +17317,26 @@ var BandACPClient = class {
|
|
|
17316
17317
|
return chunks;
|
|
17317
17318
|
}
|
|
17318
17319
|
async extMethod(method, params) {
|
|
17319
|
-
|
|
17320
|
-
|
|
17321
|
-
|
|
17322
|
-
|
|
17323
|
-
|
|
17324
|
-
|
|
17325
|
-
return {
|
|
17326
|
-
outcome: {
|
|
17327
|
-
type: "cancelled"
|
|
17328
|
-
}
|
|
17329
|
-
};
|
|
17330
|
-
}
|
|
17331
|
-
return {
|
|
17332
|
-
outcome: {
|
|
17333
|
-
type: "selected",
|
|
17334
|
-
optionId: selected.optionId
|
|
17335
|
-
}
|
|
17336
|
-
};
|
|
17337
|
-
}
|
|
17338
|
-
if (method === "cursor/create_plan") {
|
|
17339
|
-
return {
|
|
17340
|
-
outcome: {
|
|
17341
|
-
type: "approved"
|
|
17342
|
-
}
|
|
17343
|
-
};
|
|
17344
|
-
}
|
|
17345
|
-
return {};
|
|
17320
|
+
const result = await this.extensionHandler?.extMethod?.(
|
|
17321
|
+
method,
|
|
17322
|
+
params,
|
|
17323
|
+
{ sessionId: sessionIdFrom(params) }
|
|
17324
|
+
);
|
|
17325
|
+
return result ?? {};
|
|
17346
17326
|
}
|
|
17347
17327
|
async extNotification(method, params) {
|
|
17348
|
-
const sessionId =
|
|
17349
|
-
|
|
17350
|
-
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17354
|
-
|
|
17355
|
-
|
|
17356
|
-
this.appendChunk(sessionId, {
|
|
17357
|
-
chunkType: "plan",
|
|
17358
|
-
content: lines.join("\n"),
|
|
17359
|
-
metadata: {},
|
|
17360
|
-
streamed: false
|
|
17361
|
-
});
|
|
17362
|
-
}
|
|
17328
|
+
const sessionId = sessionIdFrom(params);
|
|
17329
|
+
const chunks = await this.extensionHandler?.extNotification?.(
|
|
17330
|
+
method,
|
|
17331
|
+
params,
|
|
17332
|
+
{ sessionId }
|
|
17333
|
+
);
|
|
17334
|
+
const targetSessionId = sessionId ?? this.extensionHandler?.extensionSessionId?.() ?? null;
|
|
17335
|
+
if (!targetSessionId || !chunks) {
|
|
17363
17336
|
return;
|
|
17364
17337
|
}
|
|
17365
|
-
|
|
17366
|
-
|
|
17367
|
-
if (result) {
|
|
17368
|
-
this.appendChunk(sessionId, {
|
|
17369
|
-
chunkType: "text",
|
|
17370
|
-
content: `[Task completed] ${result}`,
|
|
17371
|
-
metadata: {},
|
|
17372
|
-
streamed: false
|
|
17373
|
-
});
|
|
17374
|
-
}
|
|
17338
|
+
for (const chunk of chunks) {
|
|
17339
|
+
this.appendChunk(targetSessionId, chunk);
|
|
17375
17340
|
}
|
|
17376
17341
|
}
|
|
17377
17342
|
appendChunk(sessionId, chunk) {
|
|
@@ -17496,6 +17461,17 @@ function extractTextFromContent(content) {
|
|
|
17496
17461
|
function toOptionalString(value) {
|
|
17497
17462
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
17498
17463
|
}
|
|
17464
|
+
function sessionIdFrom(params) {
|
|
17465
|
+
return toOptionalString(params.sessionId) ?? toOptionalString(params.session_id);
|
|
17466
|
+
}
|
|
17467
|
+
|
|
17468
|
+
// src/adapters/acp/types.ts
|
|
17469
|
+
function choosePermissionOption(options) {
|
|
17470
|
+
if (options.length === 0) {
|
|
17471
|
+
return null;
|
|
17472
|
+
}
|
|
17473
|
+
return options.find((option) => option.kind === "allow_once") ?? options.find((option) => option.kind === "allow_always") ?? options[0];
|
|
17474
|
+
}
|
|
17499
17475
|
|
|
17500
17476
|
// src/adapters/acp/loader.ts
|
|
17501
17477
|
init_errors();
|
|
@@ -17542,6 +17518,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
17542
17518
|
additionalMcpTools;
|
|
17543
17519
|
clientCapabilities;
|
|
17544
17520
|
connectionFactory;
|
|
17521
|
+
extensionHandler;
|
|
17545
17522
|
tcpEndpoint;
|
|
17546
17523
|
// The value's `generation` is the connection generation the session was
|
|
17547
17524
|
// last established/restored against. `client` is the exact BandACPClient
|
|
@@ -17606,6 +17583,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
17606
17583
|
this.additionalMcpTools = [...options.additionalMcpTools ?? []];
|
|
17607
17584
|
this.clientCapabilities = options.clientCapabilities;
|
|
17608
17585
|
this.connectionFactory = options.connectionFactory;
|
|
17586
|
+
this.extensionHandler = options.extensionHandler;
|
|
17609
17587
|
this.tcpEndpoint = tcpEndpoint;
|
|
17610
17588
|
this.resolvePermission = options.resolvePermission;
|
|
17611
17589
|
this.resolveSessionMode = options.resolveSessionMode;
|
|
@@ -17661,6 +17639,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
17661
17639
|
let client = null;
|
|
17662
17640
|
let sessionId;
|
|
17663
17641
|
let generation = 0;
|
|
17642
|
+
await this.onAcpTurnStarted(message, tools, context);
|
|
17664
17643
|
try {
|
|
17665
17644
|
const ensured = await this.ensureConnection();
|
|
17666
17645
|
connection = ensured.connection;
|
|
@@ -17671,6 +17650,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
17671
17650
|
}
|
|
17672
17651
|
sessionId = await this.getOrCreateSession(context.roomId, connection, generation, client);
|
|
17673
17652
|
const sessionKey = this.sessionKey(generation, sessionId);
|
|
17653
|
+
await this.onAcpSessionReady(message, tools, context, sessionId);
|
|
17674
17654
|
client.beginSession(sessionId);
|
|
17675
17655
|
const content = replaceUuidMentions(message.content, mentionSubjectsFromMetadata(message.metadata));
|
|
17676
17656
|
const messageWithContext = [...systemUpdateParts(participantsMessage, contactsMessage), content].join("\n\n");
|
|
@@ -17741,8 +17721,16 @@ ${messageWithContext}`;
|
|
|
17741
17721
|
...configError ? { optionId: configError.optionId, selectedValue: configError.selectedValue } : {}
|
|
17742
17722
|
}
|
|
17743
17723
|
);
|
|
17724
|
+
} finally {
|
|
17725
|
+
await this.onAcpTurnFinished(message, tools, context);
|
|
17744
17726
|
}
|
|
17745
17727
|
}
|
|
17728
|
+
async onAcpTurnStarted(_message, _tools, _context) {
|
|
17729
|
+
}
|
|
17730
|
+
async onAcpTurnFinished(_message, _tools, _context) {
|
|
17731
|
+
}
|
|
17732
|
+
async onAcpSessionReady(_message, _tools, _context, _sessionId) {
|
|
17733
|
+
}
|
|
17746
17734
|
// Best-effort: tells the agent to stop working on a turn Band has already
|
|
17747
17735
|
// given up waiting for (the ACP client has no way to force it), evicts the
|
|
17748
17736
|
// session so the room's next turn re-establishes rather than reuses it
|
|
@@ -17912,6 +17900,9 @@ ${messageWithContext}`;
|
|
|
17912
17900
|
sessionKey(generation, sessionId) {
|
|
17913
17901
|
return `${generation}:${sessionId}`;
|
|
17914
17902
|
}
|
|
17903
|
+
roomIdForSession(sessionId) {
|
|
17904
|
+
return [...this.roomToSession.entries()].find(([, owner]) => owner.sessionId === sessionId)?.[0];
|
|
17905
|
+
}
|
|
17915
17906
|
async ensureConnection() {
|
|
17916
17907
|
if (this.connection && !this.connection.signal.aborted) {
|
|
17917
17908
|
return { connection: this.connection, generation: this.connectionGeneration };
|
|
@@ -17948,7 +17939,10 @@ ${messageWithContext}`;
|
|
|
17948
17939
|
throw new Error(CONNECTION_ATTEMPT_SUPERSEDED_ERROR);
|
|
17949
17940
|
}
|
|
17950
17941
|
const owner = { generation: -1 };
|
|
17951
|
-
const client = new BandACPClient(
|
|
17942
|
+
const client = new BandACPClient(
|
|
17943
|
+
(params) => this.routePermissionRequest(params, owner.generation),
|
|
17944
|
+
this.extensionHandler
|
|
17945
|
+
);
|
|
17952
17946
|
handle = await (this.connectionFactory ? this.connectionFactory(client, {
|
|
17953
17947
|
command: this.command,
|
|
17954
17948
|
cwd: this.cwd,
|
|
@@ -18804,6 +18798,358 @@ var CopilotACPAdapter = class extends ACPClientAdapter {
|
|
|
18804
18798
|
}
|
|
18805
18799
|
};
|
|
18806
18800
|
|
|
18801
|
+
// src/adapters/cursor-acp/CursorACPAdapter.ts
|
|
18802
|
+
var DEFAULT_CURSOR_ACP_COMMAND = ["agent", "acp"];
|
|
18803
|
+
var DEFAULT_CURSOR_DECISION_TIMEOUT_MS = 3e5;
|
|
18804
|
+
var DEFAULT_CURSOR_MAX_PENDING_DECISIONS = 10;
|
|
18805
|
+
var CursorExtensions = class {
|
|
18806
|
+
adapter = null;
|
|
18807
|
+
todosBySession = /* @__PURE__ */ new Map();
|
|
18808
|
+
bind(adapter) {
|
|
18809
|
+
this.adapter = adapter;
|
|
18810
|
+
}
|
|
18811
|
+
async resolvePermission(request, signal) {
|
|
18812
|
+
return this.adapter?.resolveCursorPermission(request, signal);
|
|
18813
|
+
}
|
|
18814
|
+
extensionSessionId() {
|
|
18815
|
+
return this.adapter?.extensionSessionId() ?? null;
|
|
18816
|
+
}
|
|
18817
|
+
async extMethod(method, params, context) {
|
|
18818
|
+
return this.adapter?.resolveExtension(method, params, context.sessionId) ?? null;
|
|
18819
|
+
}
|
|
18820
|
+
async extNotification(method, params, context) {
|
|
18821
|
+
const sessionId = context.sessionId ?? this.extensionSessionId();
|
|
18822
|
+
if (!sessionId) {
|
|
18823
|
+
return;
|
|
18824
|
+
}
|
|
18825
|
+
if (method === "cursor/update_todos") {
|
|
18826
|
+
const content = this.updateTodos(sessionId, params);
|
|
18827
|
+
if (!content) {
|
|
18828
|
+
return;
|
|
18829
|
+
}
|
|
18830
|
+
return [{ chunkType: "plan", content, metadata: { cursor_todos: true }, streamed: false }];
|
|
18831
|
+
}
|
|
18832
|
+
if (method === "cursor/task") {
|
|
18833
|
+
const description = stringValue(params.description);
|
|
18834
|
+
if (!description) {
|
|
18835
|
+
return [];
|
|
18836
|
+
}
|
|
18837
|
+
const subagentType = stringValue(params.subagentType) ?? "unspecified";
|
|
18838
|
+
const model = stringValue(params.model);
|
|
18839
|
+
const suffix = model ? ` (${model})` : "";
|
|
18840
|
+
return [{ chunkType: "plan", content: `[Cursor ${subagentType} task] ${description}${suffix}`, metadata: {}, streamed: false }];
|
|
18841
|
+
}
|
|
18842
|
+
if (method === "cursor/generate_image") {
|
|
18843
|
+
const description = stringValue(params.description);
|
|
18844
|
+
if (!description) {
|
|
18845
|
+
return [];
|
|
18846
|
+
}
|
|
18847
|
+
const filePath = stringValue(params.filePath);
|
|
18848
|
+
return [{ chunkType: "plan", content: `[Cursor generated image] ${description}${filePath ? ` \u2192 ${filePath}` : ""}`, metadata: {}, streamed: false }];
|
|
18849
|
+
}
|
|
18850
|
+
}
|
|
18851
|
+
forgetSession(sessionId) {
|
|
18852
|
+
this.todosBySession.delete(sessionId);
|
|
18853
|
+
}
|
|
18854
|
+
clearSessions() {
|
|
18855
|
+
this.todosBySession.clear();
|
|
18856
|
+
}
|
|
18857
|
+
updateTodos(sessionId, params) {
|
|
18858
|
+
const todos = parseTodos(params.todos);
|
|
18859
|
+
if (params.merge === true) {
|
|
18860
|
+
const current2 = this.todosBySession.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
18861
|
+
for (const todo of todos) {
|
|
18862
|
+
current2.set(todo.id, todo);
|
|
18863
|
+
}
|
|
18864
|
+
this.todosBySession.set(sessionId, current2);
|
|
18865
|
+
} else {
|
|
18866
|
+
this.todosBySession.set(sessionId, new Map(todos.map((todo) => [todo.id, todo])));
|
|
18867
|
+
}
|
|
18868
|
+
const current = this.todosBySession.get(sessionId);
|
|
18869
|
+
return current && current.size > 0 ? [...current.values()].map((todo) => `- [${todoMark(todo.status)}] ${todo.content}`).join("\n") : void 0;
|
|
18870
|
+
}
|
|
18871
|
+
};
|
|
18872
|
+
var CursorACPAdapter = class extends ACPClientAdapter {
|
|
18873
|
+
provider = "cursor-acp";
|
|
18874
|
+
approvalMode;
|
|
18875
|
+
questionMode;
|
|
18876
|
+
planMode;
|
|
18877
|
+
decisionTimeoutMs;
|
|
18878
|
+
maxPendingDecisions;
|
|
18879
|
+
authorizedSenders;
|
|
18880
|
+
decisionLogger;
|
|
18881
|
+
extensions;
|
|
18882
|
+
turns = /* @__PURE__ */ new Map();
|
|
18883
|
+
pending = /* @__PURE__ */ new Map();
|
|
18884
|
+
activeTurn = null;
|
|
18885
|
+
turnTail = Promise.resolve();
|
|
18886
|
+
constructor(options = {}) {
|
|
18887
|
+
const extensions = new CursorExtensions();
|
|
18888
|
+
validateOptions(options);
|
|
18889
|
+
const env = cursorEnv(options);
|
|
18890
|
+
super({
|
|
18891
|
+
...options,
|
|
18892
|
+
env,
|
|
18893
|
+
command: options.command ?? [...DEFAULT_CURSOR_ACP_COMMAND],
|
|
18894
|
+
authMethod: "cursor_login",
|
|
18895
|
+
extensionHandler: extensions,
|
|
18896
|
+
resolvePermission: (request, signal) => extensions.resolvePermission(request, signal)
|
|
18897
|
+
});
|
|
18898
|
+
extensions.bind(this);
|
|
18899
|
+
this.extensions = extensions;
|
|
18900
|
+
this.approvalMode = options.approvalMode ?? "manual";
|
|
18901
|
+
this.questionMode = options.questionMode ?? "manual";
|
|
18902
|
+
this.planMode = options.planMode ?? "manual";
|
|
18903
|
+
this.decisionTimeoutMs = options.decisionTimeoutMs ?? DEFAULT_CURSOR_DECISION_TIMEOUT_MS;
|
|
18904
|
+
this.maxPendingDecisions = options.maxPendingDecisions ?? DEFAULT_CURSOR_MAX_PENDING_DECISIONS;
|
|
18905
|
+
this.authorizedSenders = options.decisionAuthorizedSenders ? new Set(options.decisionAuthorizedSenders) : null;
|
|
18906
|
+
this.decisionLogger = resolveLogger(options.logger);
|
|
18907
|
+
}
|
|
18908
|
+
async onMessage(message, tools, history, participantsMessage, contactsMessage, context) {
|
|
18909
|
+
if (await this.handleControl(message, tools, context.roomId)) {
|
|
18910
|
+
return;
|
|
18911
|
+
}
|
|
18912
|
+
await this.withCursorTurnLock(() => super.onMessage(message, tools, history, participantsMessage, contactsMessage, context));
|
|
18913
|
+
}
|
|
18914
|
+
async onAcpTurnStarted(message, tools, context) {
|
|
18915
|
+
const turn = { messageId: message.id, roomId: context.roomId, tools, requesterId: message.senderId };
|
|
18916
|
+
this.turns.set(context.roomId, turn);
|
|
18917
|
+
this.activeTurn = turn;
|
|
18918
|
+
}
|
|
18919
|
+
async onAcpSessionReady(message, _tools, context, sessionId) {
|
|
18920
|
+
const turn = this.turns.get(context.roomId);
|
|
18921
|
+
if (turn?.messageId === message.id) {
|
|
18922
|
+
turn.sessionId = sessionId;
|
|
18923
|
+
}
|
|
18924
|
+
}
|
|
18925
|
+
async onAcpTurnFinished(message, _tools, context) {
|
|
18926
|
+
const turn = this.turns.get(context.roomId);
|
|
18927
|
+
if (turn?.messageId === message.id) {
|
|
18928
|
+
this.turns.delete(context.roomId);
|
|
18929
|
+
this.cancelRoom(context.roomId);
|
|
18930
|
+
}
|
|
18931
|
+
if (this.activeTurn?.messageId === message.id) {
|
|
18932
|
+
this.activeTurn = null;
|
|
18933
|
+
}
|
|
18934
|
+
}
|
|
18935
|
+
async onCleanup(roomId) {
|
|
18936
|
+
const sessionId = this.turns.get(roomId)?.sessionId;
|
|
18937
|
+
this.cancelRoom(roomId);
|
|
18938
|
+
this.turns.delete(roomId);
|
|
18939
|
+
if (this.activeTurn?.roomId === roomId) {
|
|
18940
|
+
this.activeTurn = null;
|
|
18941
|
+
}
|
|
18942
|
+
await super.onCleanup(roomId);
|
|
18943
|
+
if (sessionId) {
|
|
18944
|
+
this.extensions.forgetSession(sessionId);
|
|
18945
|
+
}
|
|
18946
|
+
}
|
|
18947
|
+
async stop() {
|
|
18948
|
+
for (const decision of this.pending.values()) {
|
|
18949
|
+
decision.resolve(void 0);
|
|
18950
|
+
}
|
|
18951
|
+
this.pending.clear();
|
|
18952
|
+
this.turns.clear();
|
|
18953
|
+
this.activeTurn = null;
|
|
18954
|
+
this.extensions.clearSessions();
|
|
18955
|
+
await super.stop();
|
|
18956
|
+
}
|
|
18957
|
+
async resolveExtension(method, params, sessionId) {
|
|
18958
|
+
const roomId = sessionId ? this.roomIdForSession(sessionId) : this.activeTurn?.roomId;
|
|
18959
|
+
const turn = roomId ? this.turns.get(roomId) : void 0;
|
|
18960
|
+
if (!turn || sessionId && turn.sessionId !== sessionId) {
|
|
18961
|
+
return { outcome: { outcome: "cancelled" } };
|
|
18962
|
+
}
|
|
18963
|
+
if (method === "cursor/ask_question") {
|
|
18964
|
+
return this.resolveQuestion(turn.roomId, turn, params);
|
|
18965
|
+
}
|
|
18966
|
+
if (method === "cursor/create_plan") {
|
|
18967
|
+
return this.resolvePlan(turn.roomId, turn, params);
|
|
18968
|
+
}
|
|
18969
|
+
return {};
|
|
18970
|
+
}
|
|
18971
|
+
async resolveCursorPermission(request, signal) {
|
|
18972
|
+
if (this.approvalMode === "autoAccept") {
|
|
18973
|
+
return allowOption(request.options)?.optionId;
|
|
18974
|
+
}
|
|
18975
|
+
if (this.approvalMode === "autoDecline") {
|
|
18976
|
+
return void 0;
|
|
18977
|
+
}
|
|
18978
|
+
const turn = this.turns.get(request.roomId);
|
|
18979
|
+
if (!turn) {
|
|
18980
|
+
return void 0;
|
|
18981
|
+
}
|
|
18982
|
+
const options = request.options.map((option) => option.optionId);
|
|
18983
|
+
const token = await this.waitForDecision("permission", request.roomId, turn, /* @__PURE__ */ new Map([["permission", options]]), /* @__PURE__ */ new Set(), `Cursor needs permission. Reply \`/cursor select {token} option-id\` or \`/cursor deny {token}\`.`, signal);
|
|
18984
|
+
return typeof token === "string" && options.includes(token) ? token : void 0;
|
|
18985
|
+
}
|
|
18986
|
+
extensionSessionId() {
|
|
18987
|
+
return this.activeTurn?.sessionId ?? null;
|
|
18988
|
+
}
|
|
18989
|
+
async resolveQuestion(roomId, turn, params) {
|
|
18990
|
+
const questions = questionChoices(params.questions);
|
|
18991
|
+
if (questions.choices.size === 0) {
|
|
18992
|
+
return { outcome: { outcome: "cancelled" } };
|
|
18993
|
+
}
|
|
18994
|
+
if (this.questionMode === "autoCancel") {
|
|
18995
|
+
return { outcome: { outcome: "cancelled" } };
|
|
18996
|
+
}
|
|
18997
|
+
if (this.questionMode === "autoFirst") {
|
|
18998
|
+
return answered(Object.fromEntries([...questions.choices].map(([id, options]) => [id, [options[0]]])));
|
|
18999
|
+
}
|
|
19000
|
+
const result = await this.waitForDecision("question", roomId, turn, questions.choices, questions.multiSelect, "Cursor needs input. Reply `/cursor answer {token} question-id=option-id[,option-id] ...`.");
|
|
19001
|
+
return isRecord3(result) ? result : { outcome: { outcome: "cancelled" } };
|
|
19002
|
+
}
|
|
19003
|
+
async resolvePlan(roomId, turn, params) {
|
|
19004
|
+
if (this.planMode === "autoAccept") {
|
|
19005
|
+
return { outcome: { outcome: "accepted" } };
|
|
19006
|
+
}
|
|
19007
|
+
if (this.planMode === "autoDecline") {
|
|
19008
|
+
return { outcome: { outcome: "rejected" } };
|
|
19009
|
+
}
|
|
19010
|
+
const title = stringValue(params.title) ?? "Cursor plan";
|
|
19011
|
+
const result = await this.waitForDecision("plan", roomId, turn, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set(), `${title} needs approval. Reply \`/cursor accept {token}\` or \`/cursor reject {token}\`.`);
|
|
19012
|
+
return isRecord3(result) ? result : { outcome: { outcome: "cancelled" } };
|
|
19013
|
+
}
|
|
19014
|
+
async waitForDecision(kind, roomId, turn, choices, multiSelect, prompt, signal) {
|
|
19015
|
+
if (this.pending.size >= this.maxPendingDecisions) {
|
|
19016
|
+
this.pending.values().next().value?.resolve(void 0);
|
|
19017
|
+
}
|
|
19018
|
+
const token = crypto.randomUUID().slice(0, 8);
|
|
19019
|
+
return new Promise((resolve) => {
|
|
19020
|
+
const timer = setTimeout(() => settle(void 0), this.decisionTimeoutMs);
|
|
19021
|
+
const abort = () => settle(void 0);
|
|
19022
|
+
const settle = (value) => {
|
|
19023
|
+
clearTimeout(timer);
|
|
19024
|
+
signal?.removeEventListener("abort", abort);
|
|
19025
|
+
this.pending.delete(token);
|
|
19026
|
+
resolve(value);
|
|
19027
|
+
};
|
|
19028
|
+
this.pending.set(token, { kind, roomId, choices, multiSelect, resolve: settle });
|
|
19029
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
19030
|
+
void turn.tools.sendMessage(prompt.replaceAll("{token}", token), [turn.requesterId]).catch((error) => {
|
|
19031
|
+
this.decisionLogger.warn("cursor_acp.decision_prompt_delivery_failed", { roomId, kind, error: String(error) });
|
|
19032
|
+
settle(void 0);
|
|
19033
|
+
});
|
|
19034
|
+
});
|
|
19035
|
+
}
|
|
19036
|
+
async handleControl(message, tools, roomId) {
|
|
19037
|
+
const words = message.content.trim().split(/\s+/);
|
|
19038
|
+
if (words[0]?.toLowerCase() !== "/cursor") {
|
|
19039
|
+
return false;
|
|
19040
|
+
}
|
|
19041
|
+
if (words.length === 1 || words[1]?.toLowerCase() === "decisions") {
|
|
19042
|
+
const entries = [...this.pending.entries()].filter(([, decision2]) => decision2.roomId === roomId).map(([token2, decision2]) => `\`${token2}\` (${decision2.kind})`);
|
|
19043
|
+
await tools.sendMessage(`Pending Cursor decisions: ${entries.join(", ") || "none"}`);
|
|
19044
|
+
return true;
|
|
19045
|
+
}
|
|
19046
|
+
const [_, action, token, ...args] = words;
|
|
19047
|
+
const decision = token ? this.pending.get(token) : void 0;
|
|
19048
|
+
if (!decision || decision.roomId !== roomId) {
|
|
19049
|
+
await tools.sendMessage(`Cursor decision \`${token ?? ""}\` is not pending.`);
|
|
19050
|
+
return true;
|
|
19051
|
+
}
|
|
19052
|
+
if (this.authorizedSenders && !this.authorizedSenders.has(message.senderId)) {
|
|
19053
|
+
await tools.sendMessage("You are not authorized to resolve Cursor decisions.");
|
|
19054
|
+
return true;
|
|
19055
|
+
}
|
|
19056
|
+
const result = commandResult(action ?? "", args, decision);
|
|
19057
|
+
if (result === null) {
|
|
19058
|
+
await tools.sendMessage(`That command is not valid for Cursor ${decision.kind} decision \`${token}\`.`);
|
|
19059
|
+
return true;
|
|
19060
|
+
}
|
|
19061
|
+
decision.resolve(result);
|
|
19062
|
+
await tools.sendMessage(`Cursor ${decision.kind} decision \`${token}\` resolved.`);
|
|
19063
|
+
return true;
|
|
19064
|
+
}
|
|
19065
|
+
cancelRoom(roomId) {
|
|
19066
|
+
for (const [token, decision] of this.pending) {
|
|
19067
|
+
if (decision.roomId === roomId) {
|
|
19068
|
+
decision.resolve(void 0);
|
|
19069
|
+
this.pending.delete(token);
|
|
19070
|
+
}
|
|
19071
|
+
}
|
|
19072
|
+
}
|
|
19073
|
+
async withCursorTurnLock(run) {
|
|
19074
|
+
const queued = this.turnTail.then(run, run);
|
|
19075
|
+
this.turnTail = queued.then(() => void 0, () => void 0);
|
|
19076
|
+
return queued;
|
|
19077
|
+
}
|
|
19078
|
+
};
|
|
19079
|
+
function cursorEnv(options) {
|
|
19080
|
+
const env = { ...options.env };
|
|
19081
|
+
if (options.apiKey) env.CURSOR_API_KEY ??= options.apiKey;
|
|
19082
|
+
if (options.authToken) env.CURSOR_AUTH_TOKEN ??= options.authToken;
|
|
19083
|
+
return Object.keys(env).length > 0 ? env : void 0;
|
|
19084
|
+
}
|
|
19085
|
+
function validateOptions(options) {
|
|
19086
|
+
if (options.apiKey && options.authToken) throw new Error("set either apiKey or authToken, not both");
|
|
19087
|
+
if (Array.isArray(options.command) && options.command.length === 0) throw new Error("Cursor ACP command must not be empty");
|
|
19088
|
+
if (options.decisionTimeoutMs !== void 0 && (!Number.isFinite(options.decisionTimeoutMs) || options.decisionTimeoutMs <= 0)) throw new Error("decisionTimeoutMs must be a positive finite number");
|
|
19089
|
+
if (options.maxPendingDecisions !== void 0 && (!Number.isInteger(options.maxPendingDecisions) || options.maxPendingDecisions <= 0)) throw new Error("maxPendingDecisions must be a positive integer");
|
|
19090
|
+
}
|
|
19091
|
+
function allowOption(options) {
|
|
19092
|
+
return options.find((option) => option.kind === "allow_once") ?? options.find((option) => option.kind === "allow_always");
|
|
19093
|
+
}
|
|
19094
|
+
function questionChoices(value) {
|
|
19095
|
+
const choices = /* @__PURE__ */ new Map();
|
|
19096
|
+
const multiSelect = /* @__PURE__ */ new Set();
|
|
19097
|
+
if (!Array.isArray(value)) return { choices, multiSelect };
|
|
19098
|
+
for (const question of value) {
|
|
19099
|
+
if (!isRecord3(question) || typeof question.id !== "string" || !Array.isArray(question.options)) continue;
|
|
19100
|
+
const options = question.options.filter(isRecord3).map((option) => stringValue(option.id)).filter((id) => !!id);
|
|
19101
|
+
if (options.length === 0) continue;
|
|
19102
|
+
choices.set(question.id, options);
|
|
19103
|
+
if (question.allowMultiple === true) multiSelect.add(question.id);
|
|
19104
|
+
}
|
|
19105
|
+
return { choices, multiSelect };
|
|
19106
|
+
}
|
|
19107
|
+
function commandResult(action, args, decision) {
|
|
19108
|
+
if (decision.kind === "permission") return action === "deny" ? void 0 : action === "select" && args.length === 1 && decision.choices.get("permission")?.includes(args[0] ?? "") ? args[0] : null;
|
|
19109
|
+
if (decision.kind === "plan") return action === "accept" ? { outcome: { outcome: "accepted" } } : action === "reject" ? { outcome: { outcome: "rejected" } } : null;
|
|
19110
|
+
if (action !== "answer") return null;
|
|
19111
|
+
const selected = {};
|
|
19112
|
+
for (const argument of args) {
|
|
19113
|
+
const [id, raw] = argument.split("=", 2);
|
|
19114
|
+
const values = raw?.split(",") ?? [];
|
|
19115
|
+
const offered = id ? decision.choices.get(id) : void 0;
|
|
19116
|
+
if (!id || !offered || selected[id] || values.length === 0 || values.length > 1 && !decision.multiSelect.has(id) || values.some((value) => !offered.includes(value))) return null;
|
|
19117
|
+
selected[id] = values;
|
|
19118
|
+
}
|
|
19119
|
+
return Object.keys(selected).length === decision.choices.size ? answered(selected) : null;
|
|
19120
|
+
}
|
|
19121
|
+
function answered(selected) {
|
|
19122
|
+
return { outcome: { outcome: "answered", answers: Object.entries(selected).map(([questionId, selectedOptionIds]) => ({ questionId, selectedOptionIds })) } };
|
|
19123
|
+
}
|
|
19124
|
+
function parseTodos(value) {
|
|
19125
|
+
if (!Array.isArray(value)) return [];
|
|
19126
|
+
return value.flatMap((todo) => {
|
|
19127
|
+
if (!isRecord3(todo)) return [];
|
|
19128
|
+
const id = stringValue(todo.id);
|
|
19129
|
+
const content = stringValue(todo.content);
|
|
19130
|
+
const status = stringValue(todo.status);
|
|
19131
|
+
return id && content && status ? [{ id, content, status }] : [];
|
|
19132
|
+
});
|
|
19133
|
+
}
|
|
19134
|
+
function todoMark(status) {
|
|
19135
|
+
switch (status) {
|
|
19136
|
+
case "completed":
|
|
19137
|
+
return "x";
|
|
19138
|
+
case "in_progress":
|
|
19139
|
+
return "~";
|
|
19140
|
+
case "cancelled":
|
|
19141
|
+
return "-";
|
|
19142
|
+
default:
|
|
19143
|
+
return " ";
|
|
19144
|
+
}
|
|
19145
|
+
}
|
|
19146
|
+
function isRecord3(value) {
|
|
19147
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
19148
|
+
}
|
|
19149
|
+
function stringValue(value) {
|
|
19150
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
19151
|
+
}
|
|
19152
|
+
|
|
18807
19153
|
// src/core/index.ts
|
|
18808
19154
|
var import_band_sdk_core13 = require("@band-ai/band-sdk-core");
|
|
18809
19155
|
init_protocols();
|
|
@@ -18828,7 +19174,9 @@ init_schemas();
|
|
|
18828
19174
|
ClaudeSDKAdapter,
|
|
18829
19175
|
CodexAdapter,
|
|
18830
19176
|
CopilotACPAdapter,
|
|
19177
|
+
CursorACPAdapter,
|
|
18831
19178
|
DEFAULT_COPILOT_ACP_COMMAND,
|
|
19179
|
+
DEFAULT_CURSOR_ACP_COMMAND,
|
|
18832
19180
|
DEFAULT_OMP_ACP_COMMAND,
|
|
18833
19181
|
DefaultPreprocessor,
|
|
18834
19182
|
DeliveryFailedError,
|
package/dist/index.d.cts
CHANGED
|
@@ -9,7 +9,7 @@ import { P as PlatformMessage } from './types-DtcOLALn.cjs';
|
|
|
9
9
|
export { A as AgentConfig, a as AgentInput, C as ContactEvent, b as ContactEventCallback, c as ContactEventConfig, d as ContactEventStrategy, e as ConversationContext, H as HistoryProvider, M as MessageHandler, f as PlatformEvent, R as ReconnectedEvent, S as SessionConfig } from './types-DtcOLALn.cjs';
|
|
10
10
|
export { W as WebSocketConflictPolicy, a as WebSocketDisconnectError, b as WebSocketDisconnectReason } from './disconnectReason-Cctmg1SN.cjs';
|
|
11
11
|
export { C as CustomToolDef } from './customTools-Bfecd0mJ.cjs';
|
|
12
|
-
export { A as A2AAdapter, a as A2AAdapterOptions, b as A2AGatewayAdapter, c as ACPClientAdapter, d as ACPClientAdapterBaseOptions, e as ACPClientAdapterOptions, f as ACPClientStdioOptions, g as ACPClientTcpOptions, h as ACPConfigRequest, i as ACPConfigSelections, j as AcpSessionConfigError, k as AnthropicAdapter, l as AnthropicAdapterOptions, C as CODEX_REASONING_EFFORTS, m as CODEX_REASONING_SUMMARIES, n as CODEX_WEB_SEARCH_MODES, o as ClaudePermissionMode, p as ClaudeSDKAdapter, q as ClaudeSDKAdapterOptions, r as CodexAdapter, s as CodexAdapterConfig, t as CodexApprovalPolicy, u as CodexReasoningEffort, v as CodexReasoningSummary, w as CodexSandboxMode, x as CodexWebSearchMode, y as CopilotACPAdapter, z as CopilotACPAdapterOptions, B as CopilotACPStdioOptions, D as CopilotACPTcpOptions, E as
|
|
12
|
+
export { A as A2AAdapter, a as A2AAdapterOptions, b as A2AGatewayAdapter, c as ACPClientAdapter, d as ACPClientAdapterBaseOptions, e as ACPClientAdapterOptions, f as ACPClientStdioOptions, g as ACPClientTcpOptions, h as ACPConfigRequest, i as ACPConfigSelections, j as AcpSessionConfigError, k as AnthropicAdapter, l as AnthropicAdapterOptions, C as CODEX_REASONING_EFFORTS, m as CODEX_REASONING_SUMMARIES, n as CODEX_WEB_SEARCH_MODES, o as ClaudePermissionMode, p as ClaudeSDKAdapter, q as ClaudeSDKAdapterOptions, r as CodexAdapter, s as CodexAdapterConfig, t as CodexApprovalPolicy, u as CodexReasoningEffort, v as CodexReasoningSummary, w as CodexSandboxMode, x as CodexWebSearchMode, y as CopilotACPAdapter, z as CopilotACPAdapterOptions, B as CopilotACPStdioOptions, D as CopilotACPTcpOptions, E as CursorACPAdapter, F as CursorACPAdapterOptions, G as CursorApprovalMode, H as CursorPlanMode, I as CursorQuestionMode, J as DEFAULT_COPILOT_ACP_COMMAND, K as DEFAULT_CURSOR_ACP_COMMAND, L as DEFAULT_OMP_ACP_COMMAND, M as FAILURE_CODE_SESSION_CONFIG, N as GeminiAdapter, O as GeminiAdapterOptions, P as GenericAdapter, Q as GenericAdapterHandler, R as GoogleADKAdapter, S as GoogleADKAdapterOptions, T as LangGraphAdapter, U as LangGraphAdapterOptions, V as LangGraphGraph, W as LettaAdapter, X as LettaAdapterOptions, Y as MISSING_CONFIG_OPTIONS_REASON, Z as OmpACPAdapter, _ as OmpACPAdapterOptions, $ as OpenAIAdapter, a0 as OpenAIAdapterOptions, a1 as OpencodeAdapter, a2 as OpencodeAdapterConfig, a3 as OpencodeApprovalMode, a4 as OpencodeApprovalReply, a5 as OpencodeQuestionMode, a6 as ParlantAdapter, a7 as ParlantAdapterOptions, a8 as ToolCallingModel, a9 as VercelAISDKAdapter, aa as VercelAISDKAdapterOptions, ab as applySessionConfigSelections } from './CursorACPAdapter-_YhrXRWq.cjs';
|
|
13
13
|
export { S as SimpleAdapter } from './simpleAdapter-D75rcz9n.cjs';
|
|
14
14
|
export { A as A2AAuth, a as A2AGatewayAdapterOptions } from './acp-client-D-I_5lK-.cjs';
|
|
15
15
|
export { AgentFailure } from '@band-ai/band-sdk-core';
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { P as PlatformMessage } from './types-CKU1N0SK.js';
|
|
|
9
9
|
export { A as AgentConfig, a as AgentInput, C as ContactEvent, b as ContactEventCallback, c as ContactEventConfig, d as ContactEventStrategy, e as ConversationContext, H as HistoryProvider, M as MessageHandler, f as PlatformEvent, R as ReconnectedEvent, S as SessionConfig } from './types-CKU1N0SK.js';
|
|
10
10
|
export { W as WebSocketConflictPolicy, a as WebSocketDisconnectError, b as WebSocketDisconnectReason } from './disconnectReason-Cctmg1SN.js';
|
|
11
11
|
export { C as CustomToolDef } from './customTools-Bfecd0mJ.js';
|
|
12
|
-
export { A as A2AAdapter, a as A2AAdapterOptions, b as A2AGatewayAdapter, c as ACPClientAdapter, d as ACPClientAdapterBaseOptions, e as ACPClientAdapterOptions, f as ACPClientStdioOptions, g as ACPClientTcpOptions, h as ACPConfigRequest, i as ACPConfigSelections, j as AcpSessionConfigError, k as AnthropicAdapter, l as AnthropicAdapterOptions, C as CODEX_REASONING_EFFORTS, m as CODEX_REASONING_SUMMARIES, n as CODEX_WEB_SEARCH_MODES, o as ClaudePermissionMode, p as ClaudeSDKAdapter, q as ClaudeSDKAdapterOptions, r as CodexAdapter, s as CodexAdapterConfig, t as CodexApprovalPolicy, u as CodexReasoningEffort, v as CodexReasoningSummary, w as CodexSandboxMode, x as CodexWebSearchMode, y as CopilotACPAdapter, z as CopilotACPAdapterOptions, B as CopilotACPStdioOptions, D as CopilotACPTcpOptions, E as
|
|
12
|
+
export { A as A2AAdapter, a as A2AAdapterOptions, b as A2AGatewayAdapter, c as ACPClientAdapter, d as ACPClientAdapterBaseOptions, e as ACPClientAdapterOptions, f as ACPClientStdioOptions, g as ACPClientTcpOptions, h as ACPConfigRequest, i as ACPConfigSelections, j as AcpSessionConfigError, k as AnthropicAdapter, l as AnthropicAdapterOptions, C as CODEX_REASONING_EFFORTS, m as CODEX_REASONING_SUMMARIES, n as CODEX_WEB_SEARCH_MODES, o as ClaudePermissionMode, p as ClaudeSDKAdapter, q as ClaudeSDKAdapterOptions, r as CodexAdapter, s as CodexAdapterConfig, t as CodexApprovalPolicy, u as CodexReasoningEffort, v as CodexReasoningSummary, w as CodexSandboxMode, x as CodexWebSearchMode, y as CopilotACPAdapter, z as CopilotACPAdapterOptions, B as CopilotACPStdioOptions, D as CopilotACPTcpOptions, E as CursorACPAdapter, F as CursorACPAdapterOptions, G as CursorApprovalMode, H as CursorPlanMode, I as CursorQuestionMode, J as DEFAULT_COPILOT_ACP_COMMAND, K as DEFAULT_CURSOR_ACP_COMMAND, L as DEFAULT_OMP_ACP_COMMAND, M as FAILURE_CODE_SESSION_CONFIG, N as GeminiAdapter, O as GeminiAdapterOptions, P as GenericAdapter, Q as GenericAdapterHandler, R as GoogleADKAdapter, S as GoogleADKAdapterOptions, T as LangGraphAdapter, U as LangGraphAdapterOptions, V as LangGraphGraph, W as LettaAdapter, X as LettaAdapterOptions, Y as MISSING_CONFIG_OPTIONS_REASON, Z as OmpACPAdapter, _ as OmpACPAdapterOptions, $ as OpenAIAdapter, a0 as OpenAIAdapterOptions, a1 as OpencodeAdapter, a2 as OpencodeAdapterConfig, a3 as OpencodeApprovalMode, a4 as OpencodeApprovalReply, a5 as OpencodeQuestionMode, a6 as ParlantAdapter, a7 as ParlantAdapterOptions, a8 as ToolCallingModel, a9 as VercelAISDKAdapter, aa as VercelAISDKAdapterOptions, ab as applySessionConfigSelections } from './CursorACPAdapter-7-Jtl1LV.js';
|
|
13
13
|
export { S as SimpleAdapter } from './simpleAdapter-eLvsAQNo.js';
|
|
14
14
|
export { A as A2AAuth, a as A2AGatewayAdapterOptions } from './acp-client-DUXyczlF.js';
|
|
15
15
|
export { AgentFailure } from '@band-ai/band-sdk-core';
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,9 @@ import {
|
|
|
8
8
|
ClaudeSDKAdapter,
|
|
9
9
|
CodexAdapter,
|
|
10
10
|
CopilotACPAdapter,
|
|
11
|
+
CursorACPAdapter,
|
|
11
12
|
DEFAULT_COPILOT_ACP_COMMAND,
|
|
13
|
+
DEFAULT_CURSOR_ACP_COMMAND,
|
|
12
14
|
DEFAULT_OMP_ACP_COMMAND,
|
|
13
15
|
FAILURE_CODE_SESSION_CONFIG,
|
|
14
16
|
GeminiAdapter,
|
|
@@ -22,7 +24,7 @@ import {
|
|
|
22
24
|
OpencodeAdapter,
|
|
23
25
|
VercelAISDKAdapter,
|
|
24
26
|
applySessionConfigSelections
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-STUSNTHF.js";
|
|
26
28
|
import "./chunk-UL3Y5C4J.js";
|
|
27
29
|
import "./chunk-JDW5WSGF.js";
|
|
28
30
|
import {
|
|
@@ -283,7 +285,9 @@ export {
|
|
|
283
285
|
ClaudeSDKAdapter,
|
|
284
286
|
CodexAdapter,
|
|
285
287
|
CopilotACPAdapter,
|
|
288
|
+
CursorACPAdapter,
|
|
286
289
|
DEFAULT_COPILOT_ACP_COMMAND,
|
|
290
|
+
DEFAULT_CURSOR_ACP_COMMAND,
|
|
287
291
|
DEFAULT_OMP_ACP_COMMAND,
|
|
288
292
|
DefaultPreprocessor,
|
|
289
293
|
DeliveryFailedError,
|