@ycodium-ai/agent-acp 0.2.2634 → 0.2.2664

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.
Files changed (2) hide show
  1. package/dist/index.js +295 -44
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -23440,11 +23440,21 @@ var AcpExecutorRequestError = class extends AcpExecutorError {
23440
23440
  }
23441
23441
  };
23442
23442
  var AcpConnectionClosedError = class extends Error {
23443
- constructor(message = "ACP connection closed") {
23444
- super(message);
23443
+ constructor(message = "ACP connection closed", options) {
23444
+ super(message, options);
23445
23445
  this.name = "AcpConnectionClosedError";
23446
23446
  }
23447
23447
  };
23448
+ async function withStartupStderr(error62, stderrTail) {
23449
+ if (!(error62 instanceof AcpConnectionClosedError) || stderrTail === void 0) return error62;
23450
+ const tail = await stderrTail();
23451
+ if (tail.length === 0) return error62;
23452
+ return new AcpConnectionClosedError(`${error62.message}
23453
+ Agent stderr (last lines):
23454
+ ${tail}`, {
23455
+ cause: error62
23456
+ });
23457
+ }
23448
23458
 
23449
23459
  // ../../packages/ycodium-acp-executor/src/jsonrpc.ts
23450
23460
  function isRecord2(value) {
@@ -24360,7 +24370,9 @@ function findAcpEffortConfig(configOptions) {
24360
24370
  function acpModelChoicesFromConfigOptions(configOptions) {
24361
24371
  if (!Array.isArray(configOptions)) return void 0;
24362
24372
  const records = configOptions.filter(isRecord3);
24363
- const modelOption = records.find((option) => normalizedField(option, "category") === "model");
24373
+ const modelOption = records.find((option) => normalizedField(option, "category") === "model") ?? records.find(
24374
+ (option) => normalizedField(option, "id") === "model" && normalizedField(option, "type") === "select"
24375
+ );
24364
24376
  if (modelOption === void 0) return void 0;
24365
24377
  if (!asString(modelOption["id"])?.trim()) return void 0;
24366
24378
  return flattenChoices(modelOption["options"], asString(modelOption["currentValue"])?.trim());
@@ -24784,7 +24796,7 @@ function extractModelConfigId(sessionResponse) {
24784
24796
  return opt.id.trim();
24785
24797
  }
24786
24798
  }
24787
- return void 0;
24799
+ return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
24788
24800
  }
24789
24801
  function findSessionConfigOption(configOptions, configId) {
24790
24802
  if (!configOptions) {
@@ -25181,6 +25193,13 @@ function readAcpText(source, key) {
25181
25193
  const trimmed = value.trim();
25182
25194
  return trimmed.length > 0 ? trimmed : void 0;
25183
25195
  }
25196
+ function textFromContentBlocks(blocks) {
25197
+ const parts = blocks.flatMap(
25198
+ (block) => isRecord5(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
25199
+ );
25200
+ const joined = parts.join("");
25201
+ return joined.trim().length > 0 ? joined : void 0;
25202
+ }
25184
25203
  function parseSessionUpdateEvent(params) {
25185
25204
  const upd = params.update;
25186
25205
  const events = [];
@@ -25264,6 +25283,28 @@ function parseSessionUpdateEvent(params) {
25264
25283
  }
25265
25284
  break;
25266
25285
  }
25286
+ case "compaction_update": {
25287
+ const compactionId = readAcpText(upd, "compactionId");
25288
+ const status = readAcpText(upd, "status");
25289
+ if (compactionId === void 0 || status === void 0) break;
25290
+ const rawSummary = upd["summary"];
25291
+ events.push({
25292
+ _tag: "CompactionUpdated",
25293
+ compactionId,
25294
+ status,
25295
+ summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
25296
+ error: readAcpText(upd, "error")
25297
+ });
25298
+ break;
25299
+ }
25300
+ case "compaction_summary_chunk": {
25301
+ const compactionId = readAcpText(upd, "compactionId");
25302
+ const content = isRecord5(upd["content"]) ? upd["content"] : void 0;
25303
+ const text = content?.["type"] === "text" ? content["text"] : void 0;
25304
+ if (compactionId === void 0 || typeof text !== "string" || text.length === 0) break;
25305
+ events.push({ _tag: "CompactionSummaryChunk", compactionId, text });
25306
+ break;
25307
+ }
25267
25308
  default:
25268
25309
  break;
25269
25310
  }
@@ -25360,6 +25401,97 @@ function createAcpExecutor(options) {
25360
25401
  if (settledPromptKeys.length > SETTLED_PROMPT_KEY_LIMIT) settledPromptKeys.shift();
25361
25402
  };
25362
25403
  const toolCalls = /* @__PURE__ */ new Map();
25404
+ const compactions = /* @__PURE__ */ new Map();
25405
+ let manualCompaction;
25406
+ const COMPACTION_SUMMARY_MAX_CHARS = 8e3;
25407
+ const nowMs = () => options.nowMs?.() ?? Date.now();
25408
+ const emitCompactionState = (record2, state) => {
25409
+ const summary = record2.summary?.trim() ?? "";
25410
+ const truncated = summary.length > COMPACTION_SUMMARY_MAX_CHARS;
25411
+ emit({
25412
+ type: "thread.state.changed",
25413
+ ...stamp(),
25414
+ provider: options.provider,
25415
+ threadId: options.threadId,
25416
+ ...activeTurnId !== void 0 ? { turnId: activeTurnId } : {},
25417
+ payload: {
25418
+ state,
25419
+ compaction: {
25420
+ compactionId: record2.snapshotId,
25421
+ trigger: record2.trigger,
25422
+ ...state === "compacted" ? { durationMs: Math.max(0, nowMs() - record2.startedAtMs) } : {},
25423
+ ...summary.length > 0 ? {
25424
+ summary: truncated ? summary.slice(0, COMPACTION_SUMMARY_MAX_CHARS) : summary,
25425
+ ...truncated ? { summaryTruncated: true } : {}
25426
+ } : {}
25427
+ }
25428
+ }
25429
+ });
25430
+ };
25431
+ const applyCompactionUpdate = (event) => {
25432
+ let record2 = compactions.get(event.compactionId);
25433
+ if (record2 === void 0) {
25434
+ if (manualCompaction !== void 0 && !manualCompaction.adopted) {
25435
+ manualCompaction.adopted = true;
25436
+ record2 = manualCompaction;
25437
+ } else {
25438
+ record2 = {
25439
+ snapshotId: randomId(),
25440
+ trigger: "automatic",
25441
+ startedAtMs: nowMs(),
25442
+ summary: void 0,
25443
+ announced: false,
25444
+ finished: false,
25445
+ adopted: false
25446
+ };
25447
+ }
25448
+ compactions.set(event.compactionId, record2);
25449
+ }
25450
+ if (event.summary !== void 0) record2.summary = event.summary ?? void 0;
25451
+ switch (event.status) {
25452
+ case "in_progress":
25453
+ if (!record2.announced) {
25454
+ record2.announced = true;
25455
+ emitCompactionState(record2, "compacting");
25456
+ }
25457
+ return;
25458
+ case "completed":
25459
+ record2.announced = true;
25460
+ record2.finished = true;
25461
+ compactions.delete(event.compactionId);
25462
+ emitCompactionState(record2, "compacted");
25463
+ return;
25464
+ case "failed":
25465
+ case "cancelled":
25466
+ record2.finished = true;
25467
+ compactions.delete(event.compactionId);
25468
+ emit({
25469
+ type: "runtime.warning",
25470
+ ...stamp(),
25471
+ provider: options.provider,
25472
+ threadId: options.threadId,
25473
+ ...activeTurnId !== void 0 ? { turnId: activeTurnId } : {},
25474
+ payload: {
25475
+ message: event.error ?? `Context compaction ${event.status}`,
25476
+ detail: { code: `context-compaction-${event.status}` }
25477
+ }
25478
+ });
25479
+ return;
25480
+ default:
25481
+ return;
25482
+ }
25483
+ };
25484
+ const shownToolCallIds = /* @__PURE__ */ new Set();
25485
+ const SHOWN_TOOL_CALL_LIMIT = 256;
25486
+ const rememberShownToolCall = (toolCallId) => {
25487
+ shownToolCallIds.add(toolCallId);
25488
+ if (shownToolCallIds.size <= SHOWN_TOOL_CALL_LIMIT) return;
25489
+ for (const id of shownToolCallIds) {
25490
+ if (toolCalls.has(id)) continue;
25491
+ shownToolCallIds.delete(id);
25492
+ return;
25493
+ }
25494
+ };
25363
25495
  let assistantSegment = { nextSegmentIndex: 0 };
25364
25496
  let modeState;
25365
25497
  let availableCommands = [];
@@ -25446,7 +25578,6 @@ function createAcpExecutor(options) {
25446
25578
  }
25447
25579
  for (const event of parsed.events) {
25448
25580
  if (event._tag === "ToolCallUpdated") {
25449
- closeActiveAssistantSegment(activeTurnId);
25450
25581
  const tracked = toolCalls.get(event.toolCall.toolCallId);
25451
25582
  const previous = tracked?.state;
25452
25583
  const nextToolCall = mergeToolCallState(previous, event.toolCall);
@@ -25465,9 +25596,35 @@ function createAcpExecutor(options) {
25465
25596
  skippedSinceEmit: decision.skippedSinceEmit
25466
25597
  });
25467
25598
  }
25468
- if (!decision.emit) {
25599
+ const hookResult = hooks.onToolCallUpdated?.({
25600
+ toolCallId: nextToolCall.toolCallId,
25601
+ status: nextToolCall.status,
25602
+ title: nextToolCall.title,
25603
+ kind: nextToolCall.kind,
25604
+ rawInput: nextToolCall.data["rawInput"],
25605
+ rawOutput: nextToolCall.data["rawOutput"],
25606
+ meta: params.update._meta,
25607
+ turnId: activeTurnId
25608
+ });
25609
+ const taskEvents = hookResult === void 0 ? [] : "events" in hookResult ? hookResult.events : hookResult;
25610
+ const handledByHook = hookResult !== void 0 && "events" in hookResult && hookResult.handled === true;
25611
+ for (const taskEvent of taskEvents) {
25612
+ emit({
25613
+ type: taskEvent.type,
25614
+ ...stamp(),
25615
+ provider: options.provider,
25616
+ threadId: options.threadId,
25617
+ ...taskEvent.turnId !== void 0 ? { turnId: taskEvent.turnId } : {},
25618
+ payload: taskEvent.payload
25619
+ });
25620
+ }
25621
+ if (handledByHook || !decision.emit) {
25469
25622
  continue;
25470
25623
  }
25624
+ if (!shownToolCallIds.has(nextToolCall.toolCallId)) {
25625
+ rememberShownToolCall(nextToolCall.toolCallId);
25626
+ closeActiveAssistantSegment(activeTurnId);
25627
+ }
25471
25628
  emit(
25472
25629
  makeAcpToolCallEvent({
25473
25630
  stamp: stamp(),
@@ -25480,7 +25637,21 @@ function createAcpExecutor(options) {
25480
25637
  );
25481
25638
  continue;
25482
25639
  }
25640
+ if (event._tag === "CompactionUpdated") {
25641
+ applyCompactionUpdate(event);
25642
+ continue;
25643
+ }
25644
+ if (event._tag === "CompactionSummaryChunk") {
25645
+ const record2 = compactions.get(event.compactionId);
25646
+ if (record2 !== void 0 && !record2.finished) {
25647
+ record2.summary = (record2.summary ?? "") + event.text;
25648
+ }
25649
+ continue;
25650
+ }
25483
25651
  if (event._tag === "ContentDelta") {
25652
+ if (manualCompaction !== void 0) {
25653
+ continue;
25654
+ }
25484
25655
  if (event.streamKind === "reasoning_text") {
25485
25656
  if (event.text.trim().length === 0) {
25486
25657
  continue;
@@ -25723,7 +25894,9 @@ function createAcpExecutor(options) {
25723
25894
  },
25724
25895
  onNotification: (notification) => {
25725
25896
  if (notification.method === "session/update") {
25726
- handleSessionUpdate(notification.params);
25897
+ const params = notification.params;
25898
+ const transformed = hooks.transformSessionUpdate ? hooks.transformSessionUpdate(params) : params;
25899
+ if (transformed !== void 0) handleSessionUpdate(transformed);
25727
25900
  return;
25728
25901
  }
25729
25902
  if (settleFromNotification(notification.method, notification.params)) return;
@@ -25857,13 +26030,15 @@ function createAcpExecutor(options) {
25857
26030
  options.mcpServers ?? [],
25858
26031
  initialized.agentCapabilities
25859
26032
  );
26033
+ const additionalDirectories = options.additionalDirectories !== void 0 && options.additionalDirectories.length > 0 ? { additionalDirectories: options.additionalDirectories } : {};
25860
26034
  let setup;
25861
26035
  let nextSessionId;
25862
26036
  if (options.resumeSessionId && options.resumeMethod === "session/resume") {
25863
26037
  setup = await connection.request("session/resume", {
25864
26038
  sessionId: options.resumeSessionId,
25865
26039
  cwd: options.cwd,
25866
- mcpServers
26040
+ mcpServers,
26041
+ ...additionalDirectories
25867
26042
  });
25868
26043
  nextSessionId = options.resumeSessionId;
25869
26044
  } else if (options.resumeSessionId) {
@@ -25872,7 +26047,8 @@ function createAcpExecutor(options) {
25872
26047
  setup = await connection.request("session/load", {
25873
26048
  sessionId: options.resumeSessionId,
25874
26049
  cwd: options.cwd,
25875
- mcpServers
26050
+ mcpServers,
26051
+ ...additionalDirectories
25876
26052
  });
25877
26053
  } finally {
25878
26054
  sessionLoadInFlight = false;
@@ -25885,7 +26061,8 @@ function createAcpExecutor(options) {
25885
26061
  } else {
25886
26062
  const created = await connection.request("session/new", {
25887
26063
  cwd: options.cwd,
25888
- mcpServers
26064
+ mcpServers,
26065
+ ...additionalDirectories
25889
26066
  });
25890
26067
  nextSessionId = created.sessionId;
25891
26068
  setup = created;
@@ -25959,13 +26136,13 @@ function createAcpExecutor(options) {
25959
26136
  startInFlight = void 0;
25960
26137
  return result;
25961
26138
  },
25962
- (error62) => {
26139
+ async (error62) => {
25963
26140
  startInFlight = void 0;
25964
26141
  if (isLive(expectedGeneration) && !startResult) {
25965
26142
  status = "idle";
25966
26143
  generation = expectedGeneration;
25967
26144
  }
25968
- throw error62;
26145
+ throw await withStartupStderr(error62, options.stderrTail);
25969
26146
  }
25970
26147
  );
25971
26148
  return startInFlight;
@@ -26033,6 +26210,36 @@ function createAcpExecutor(options) {
26033
26210
  interruptedTurnIds.delete(input2.turnId);
26034
26211
  }
26035
26212
  };
26213
+ const sendPromptRpc = async (sessionId2, promptParts) => {
26214
+ const settlementHooks = hooks.promptSettlement;
26215
+ const promptKey = settlementHooks === void 0 ? void 0 : randomId();
26216
+ const promptRpc = connection.request("session/prompt", {
26217
+ sessionId: sessionId2,
26218
+ prompt: promptParts,
26219
+ ...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
26220
+ });
26221
+ if (settlementHooks === void 0 || promptKey === void 0) {
26222
+ return await promptRpc;
26223
+ } else {
26224
+ const { promise: early, resolve: settleEarly } = Promise.withResolvers();
26225
+ pendingSettlement = { promptKey, sessionId: sessionId2, settle: settleEarly };
26226
+ try {
26227
+ const outcome = await Promise.race([
26228
+ promptRpc.then((value) => {
26229
+ const key = settlementHooks.responseKey?.(value);
26230
+ if (key !== void 0) rememberSettledPromptKey(key);
26231
+ return { response: value };
26232
+ }),
26233
+ early
26234
+ ]);
26235
+ if (outcome.error !== void 0) throw outcome.error;
26236
+ return outcome.response;
26237
+ } finally {
26238
+ pendingSettlement = void 0;
26239
+ void promptRpc.catch(() => void 0);
26240
+ }
26241
+ }
26242
+ };
26036
26243
  const prompt = async (input2) => {
26037
26244
  failIfDisposed();
26038
26245
  const started = requireStarted();
@@ -26083,35 +26290,8 @@ function createAcpExecutor(options) {
26083
26290
  expectedGeneration: started.generation
26084
26291
  });
26085
26292
  closeActiveAssistantSegment(turnId);
26086
- const settlementHooks = hooks.promptSettlement;
26087
- const promptKey = settlementHooks === void 0 ? void 0 : randomId();
26088
- const promptRpc = connection.request("session/prompt", {
26089
- sessionId: started.sessionId,
26090
- prompt: promptParts,
26091
- ...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
26092
- });
26093
26293
  try {
26094
- if (settlementHooks === void 0 || promptKey === void 0) {
26095
- response = await promptRpc;
26096
- } else {
26097
- const { promise: early, resolve: settleEarly } = Promise.withResolvers();
26098
- pendingSettlement = { promptKey, sessionId: started.sessionId, settle: settleEarly };
26099
- try {
26100
- const outcome = await Promise.race([
26101
- promptRpc.then((value) => {
26102
- const key = settlementHooks.responseKey?.(value);
26103
- if (key !== void 0) rememberSettledPromptKey(key);
26104
- return { response: value };
26105
- }),
26106
- early
26107
- ]);
26108
- if (outcome.error !== void 0) throw outcome.error;
26109
- response = outcome.response;
26110
- } finally {
26111
- pendingSettlement = void 0;
26112
- void promptRpc.catch(() => void 0);
26113
- }
26114
- }
26294
+ response = await sendPromptRpc(started.sessionId, promptParts);
26115
26295
  } catch (error62) {
26116
26296
  if (disposed) {
26117
26297
  throw new AcpExecutorDisposedError();
@@ -26275,6 +26455,74 @@ function createAcpExecutor(options) {
26275
26455
  };
26276
26456
  apply();
26277
26457
  };
26458
+ const compact = async (input2) => {
26459
+ failIfDisposed();
26460
+ const started = requireStarted();
26461
+ const trimmedName = input2.commandName.trim();
26462
+ const commandName = trimmedName.startsWith("/") ? trimmedName.slice(1) : trimmedName;
26463
+ if (!availableCommands.some((command) => command.name === commandName)) {
26464
+ throw new AcpExecutorError(
26465
+ "command-unavailable",
26466
+ `The agent has not advertised the /${commandName} command`
26467
+ );
26468
+ }
26469
+ if (promptsInFlight > 0 || promptMutex.isLocked || manualCompaction !== void 0) {
26470
+ throw new AcpExecutorError(
26471
+ "busy",
26472
+ "Cannot compact while a turn or another compaction is running"
26473
+ );
26474
+ }
26475
+ const record2 = {
26476
+ snapshotId: randomId(),
26477
+ trigger: "manual",
26478
+ startedAtMs: nowMs(),
26479
+ summary: void 0,
26480
+ announced: true,
26481
+ finished: false,
26482
+ adopted: false
26483
+ };
26484
+ await promptMutex.acquire();
26485
+ manualCompaction = record2;
26486
+ const emitSessionState = (state) => {
26487
+ emit({
26488
+ type: "session.state.changed",
26489
+ ...stamp(),
26490
+ provider: options.provider,
26491
+ threadId: options.threadId,
26492
+ payload: { state, reason: "compaction" }
26493
+ });
26494
+ };
26495
+ try {
26496
+ failIfDisposed();
26497
+ emitSessionState("compacting");
26498
+ emitCompactionState(record2, "compacting");
26499
+ let response;
26500
+ try {
26501
+ response = await sendPromptRpc(started.sessionId, [
26502
+ { type: "text", text: `/${commandName}` }
26503
+ ]);
26504
+ } catch (error62) {
26505
+ if (disposed) throw new AcpExecutorDisposedError();
26506
+ throw error62;
26507
+ }
26508
+ await connection.awaitInboundIdle();
26509
+ if (response.stopReason === "cancelled") {
26510
+ return;
26511
+ }
26512
+ if (!record2.finished) {
26513
+ record2.finished = true;
26514
+ emitCompactionState(record2, "compacted");
26515
+ }
26516
+ } finally {
26517
+ for (const [agentId, tracked] of compactions) {
26518
+ if (tracked === record2) compactions.delete(agentId);
26519
+ }
26520
+ manualCompaction = void 0;
26521
+ promptMutex.release();
26522
+ notifyPromptSettled();
26523
+ if (!disposed) emitSessionState("ready");
26524
+ }
26525
+ };
26278
26526
  const setNativeMode = async (modeId) => {
26279
26527
  failIfDisposed();
26280
26528
  const started = startResult;
@@ -26362,6 +26610,7 @@ function createAcpExecutor(options) {
26362
26610
  respondToRequest,
26363
26611
  respondToUserInput,
26364
26612
  setNativeMode,
26613
+ compact,
26365
26614
  dispose
26366
26615
  };
26367
26616
  }
@@ -26633,6 +26882,7 @@ import * as NodeFS from "node:fs";
26633
26882
  import * as NodeOS from "node:os";
26634
26883
  import * as NodePath from "node:path";
26635
26884
  import {
26885
+ describeExecutorSpawnFailure,
26636
26886
  ExecutorSpawnRefusedError
26637
26887
  } from "@ycodium-ai/plugin-api/executor";
26638
26888
  import { nodeStreamsFromHandle } from "@ycodium-ai/plugin-api/process-stdin";
@@ -26719,7 +26969,7 @@ async function probeAcpModelsViaSession(input2) {
26719
26969
  });
26720
26970
  } catch (error62) {
26721
26971
  if (error62 instanceof ExecutorSpawnRefusedError) throw error62;
26722
- return { kind: "not-started", detail: probeFailureDetail(error62) };
26972
+ return { kind: "not-started", ...describeExecutorSpawnFailure(error62) };
26723
26973
  }
26724
26974
  let handshake;
26725
26975
  try {
@@ -26862,7 +27112,7 @@ var createAcpInstance = (config2, host) => {
26862
27112
  return {
26863
27113
  installed: false,
26864
27114
  version: null,
26865
- readiness: "error",
27115
+ readiness: "not-installed",
26866
27116
  auth: { status: "unknown" },
26867
27117
  detail: "ACP program path is not configured"
26868
27118
  };
@@ -26874,7 +27124,7 @@ var createAcpInstance = (config2, host) => {
26874
27124
  return {
26875
27125
  installed: false,
26876
27126
  version: null,
26877
- readiness: "error",
27127
+ readiness: outcome.readiness,
26878
27128
  auth: { status: "unknown" },
26879
27129
  ...outcome.detail === void 0 ? {} : { detail: outcome.detail }
26880
27130
  };
@@ -26931,7 +27181,7 @@ var createAcpInstance = (config2, host) => {
26931
27181
  owner: { bindingId: host.bindingId },
26932
27182
  ...Object.keys(env).length > 0 ? { env } : {}
26933
27183
  });
26934
- const { readable, writable } = nodeStreamsFromHandle2(handle);
27184
+ const { readable, writable, stderrTail } = nodeStreamsFromHandle2(handle);
26935
27185
  const resume = input2.discardResumeCursor === true ? void 0 : parseAcpResumeCursor(input2.resumeCursor, RESUME_SCHEMA_VERSION);
26936
27186
  const requestedModelId = modelIdFromSelection(input2.modelSelection);
26937
27187
  const requestedEffort = modelSelectionStringOption(
@@ -26945,6 +27195,7 @@ var createAcpInstance = (config2, host) => {
26945
27195
  const executor = createAcpExecutor({
26946
27196
  readable,
26947
27197
  writable,
27198
+ stderrTail,
26948
27199
  ...requestedEffort === void 0 ? {} : { requestedEffort },
26949
27200
  cwd,
26950
27201
  threadId: input2.threadId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-acp",
3
- "version": "0.2.2634",
3
+ "version": "0.2.2664",
4
4
  "description": "Generic ACP executor: user-supplied CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -21,8 +21,8 @@
21
21
  "@types/node": "24.12.4",
22
22
  "esbuild": "0.28.1",
23
23
  "vite-plus": "0.2.2",
24
- "@ycodium-ai/plugin-api": "0.2.2634",
25
- "ycodium-acp-executor": "0.2.2634",
24
+ "@ycodium-ai/plugin-api": "0.2.2664",
25
+ "ycodium-acp-executor": "0.2.2664",
26
26
  "ycodium-executor-testing": "0.0.0"
27
27
  },
28
28
  "ycodium": {