replicas-engine 0.1.412 → 0.1.414

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/src/index.js +270 -45
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -481,7 +481,7 @@ var WORKSPACE_SIZES = ["small", "large"];
481
481
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
482
482
 
483
483
  // ../shared/src/e2b.ts
484
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-09-v2";
484
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-09-v3";
485
485
 
486
486
  // ../shared/src/runtime-env.ts
487
487
  function parsePosixEnvFile(content) {
@@ -1418,59 +1418,26 @@ var GOOGLE_ABILITY = {
1418
1418
 
1419
1419
  // ../shared/src/default-skills/replicas-agent/abilities/learnings.ts
1420
1420
  var SECTION6 = `### Learnings
1421
- Curated, human-approved organization knowledge that helps you execute correctly \u2014 conventions, gotchas, environment facts, and past user corrections that the codebase alone can't tell you.
1421
+ Propose additions, updates, or deletions to curated organization knowledge.
1422
1422
 
1423
- **Reference:** \`references/LEARNINGS.md\`
1424
-
1425
- Use this when:
1426
- - You are starting a substantive task and have gathered enough context to write a meaningful query
1427
- - A user corrects you about a durable fact, preference, or process worth keeping
1428
- - You find an existing learning contradicted by the current code or docs`;
1423
+ **Reference:** \`references/LEARNINGS.md\``;
1429
1424
  var REFERENCE6 = `# Learnings
1430
1425
 
1431
- Learnings are curated, human-approved knowledge entries your organization maintains: conventions, gotchas, environment facts, and process rules. Some entries always apply; contextual entries are retrieved by matching your query against their trigger descriptions.
1432
-
1433
- ## Reading Learnings
1434
-
1435
- \`\`\`bash
1436
- replicas learnings read --query "<enriched query>"
1437
- \`\`\`
1438
-
1439
- **When to read:** once you've collected enough context to write a meaningful query \u2014 typically after your first look at the relevant code. Don't wait until you're deep into execution; learnings are most valuable before you commit to an approach.
1440
-
1441
- **Enrich the query.** Use codebase specifics (feature area, module/component names), not the raw user request. Triggers describe *situations*, so a query grounded in what the task actually touches matches far better.
1442
-
1443
- Example: the user asks "remove the PRs chart projections". After locating the chart you know it lives in the platform admin dashboard, so query:
1444
-
1445
- \`\`\`bash
1446
- replicas learnings read --query "Remove the PRs chart in the platform admin dashboard"
1447
- \`\`\`
1448
-
1449
- This matches a learning triggered on "UI/UX work on the admin panel" that the raw request would have missed.
1450
-
1451
- Output is a list of blocks \u2014 id, name, and content. Use the ids to propose updates or deletions.
1452
-
1453
- ## Proposing changes
1426
+ Learnings are curated, human-approved knowledge entries your organization maintains: conventions, gotchas, environment facts, and process rules.
1454
1427
 
1455
1428
  All writes are proposals: a human reviews them in the dashboard, and nothing takes effect until approved.
1456
1429
 
1457
- \`\`\`bash
1458
- replicas learnings add --name "<short name>" --content "<the knowledge>" [--trigger "<when to surface it>"] [--always] [--global]
1459
- replicas learnings update <id> [--name "..."] [--content "..."] [--trigger "..."] [--always true|false]
1460
- replicas learnings delete <id>
1461
- \`\`\`
1462
-
1463
- \`--always\` marks an entry as always-returned (no trigger needed); \`--global\` proposes org-wide scope instead of this workspace's environment.
1430
+ Use \`replicas learnings --help\` and subcommand help such as \`replicas learnings add --help\`, \`replicas learnings update --help\`, or \`replicas learnings delete --help\` for current command syntax.
1464
1431
 
1465
1432
  **Be very conservative:**
1466
- - Propose \`add\` only for durable, org-useful facts: explicit user corrections, hard-won environment or process knowledge.
1433
+ - Propose \`add\` only for repeatable, org-useful facts likely to matter again: explicit user corrections, hard-won environment or process knowledge.
1467
1434
  - Never store task-specific details, anything derivable by reading the repo, or secrets/credentials.
1468
- - Propose \`update\` or \`delete\` when a learning is contradicted by the current code or docs \u2014 flag outdated knowledge instead of silently ignoring it.
1435
+ - Propose \`update\` or \`delete\` when a learning is contradicted by the current code or docs, especially if the outdated guidance would affect future repeated work.
1469
1436
  - Write narrow triggers describing when the entry should surface (e.g. "UI/UX work on the admin panel"), not vague topics.`;
1470
1437
  var LEARNINGS_ABILITY = {
1471
1438
  label: "Learnings",
1472
- description: "Fetch curated org knowledge and propose new learnings for human review.",
1473
- bullet: "- Fetching organization Learnings (curated, human-approved knowledge) before executing, or proposing new ones",
1439
+ description: "Propose changes to curated org knowledge for human review.",
1440
+ bullet: "- Proposing changes to organization Learnings (curated, human-approved knowledge)",
1474
1441
  section: SECTION6,
1475
1442
  referenceFile: { name: "LEARNINGS.md", content: REFERENCE6 }
1476
1443
  };
@@ -2736,6 +2703,11 @@ function extractCommandProtectionCommandText(request, options = {}) {
2736
2703
  for (const key of COMMAND_PROTECTION_COMMAND_KEYS) {
2737
2704
  const value = input[key];
2738
2705
  if (typeof value === "string" && value.trim()) return value;
2706
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) return value.join(" ");
2707
+ }
2708
+ if (isRecord(input.args)) {
2709
+ const nested = extractCommandProtectionCommandText({ toolInput: input.args }, options);
2710
+ if (nested) return nested;
2739
2711
  }
2740
2712
  }
2741
2713
  if (typeof input === "string") return input;
@@ -6541,6 +6513,7 @@ var LinearEventForwarder = class {
6541
6513
  };
6542
6514
 
6543
6515
  // src/services/command-protection-service.ts
6516
+ var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by organization policy: agents may not merge pull requests.";
6544
6517
  function asCommandProtectionResponse(value) {
6545
6518
  if (typeof value !== "object" || value === null) return null;
6546
6519
  const candidate = value;
@@ -6585,6 +6558,17 @@ async function evaluateCommandProtection(request, signal) {
6585
6558
  function extractToolCommand(input) {
6586
6559
  return extractCommandProtectionCommandText({ toolInput: input }, { stringifyFallback: false });
6587
6560
  }
6561
+ function reportCommandProtectionBlock(options) {
6562
+ const message = options.result.reason || DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE;
6563
+ console.warn(`[${options.managerName}] blocked ${options.action} by PR merge policy: ${message}`);
6564
+ options.recordHistoryEvent(options.eventType, {
6565
+ type: "error",
6566
+ message,
6567
+ ...options.context,
6568
+ command: options.command
6569
+ }, options.historyFile);
6570
+ return message;
6571
+ }
6588
6572
 
6589
6573
  // src/services/skill-registry-service.ts
6590
6574
  import { readFile as readFile8, readdir as readdir3, stat as stat2 } from "fs/promises";
@@ -8232,7 +8216,7 @@ var AspClient = class {
8232
8216
  // src/managers/codex-asp/app-server-process.ts
8233
8217
  var DEFAULT_CODEX_BINARY = "codex";
8234
8218
  var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
8235
- var ENGINE_PACKAGE_VERSION = "0.1.412";
8219
+ var ENGINE_PACKAGE_VERSION = "0.1.414";
8236
8220
  var INITIALIZE_METHOD = "initialize";
8237
8221
  var INITIALIZED_NOTIFICATION = "initialized";
8238
8222
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -10348,6 +10332,24 @@ function extractCursorCommandDescription(content) {
10348
10332
  }
10349
10333
  return void 0;
10350
10334
  }
10335
+ function cursorToolInputFromDelta(update) {
10336
+ if (update.type !== "tool-call-started") return null;
10337
+ const toolCall = update.toolCall;
10338
+ return {
10339
+ toolName: toolCall.type,
10340
+ toolInput: toolCall,
10341
+ command: extractToolCommand(toolCall),
10342
+ toolUseId: update.callId
10343
+ };
10344
+ }
10345
+ function cursorToolInputFromMessage(event) {
10346
+ return {
10347
+ toolName: event.name,
10348
+ toolInput: event.args ?? {},
10349
+ command: extractToolCommand(event.args),
10350
+ toolUseId: event.call_id
10351
+ };
10352
+ }
10351
10353
  async function listCursorCommandsInDirectory(directory) {
10352
10354
  let entries;
10353
10355
  try {
@@ -10373,6 +10375,8 @@ var CursorManager = class extends CodingAgentManager {
10373
10375
  agent = null;
10374
10376
  activeRun = null;
10375
10377
  activeModel = null;
10378
+ blockedToolCallIds = /* @__PURE__ */ new Set();
10379
+ pendingCursorBlockReason = null;
10376
10380
  historyFilePath;
10377
10381
  historyFile;
10378
10382
  slashCommandsCache = null;
@@ -10451,12 +10455,22 @@ var CursorManager = class extends CodingAgentManager {
10451
10455
  }, this.historyFile);
10452
10456
  const run = await agent.send(message, {
10453
10457
  model: { id: model },
10454
- mode: request.planMode ? "plan" : "agent"
10458
+ mode: request.planMode ? "plan" : "agent",
10459
+ onDelta: async (args) => {
10460
+ await this.handleCursorToolCall(cursorToolInputFromDelta(args.update));
10461
+ }
10455
10462
  });
10456
10463
  this.activeRun = run;
10457
10464
  this.activeModel = model;
10465
+ if (this.pendingCursorBlockReason) {
10466
+ await run.cancel();
10467
+ throw new Error(this.pendingCursorBlockReason);
10468
+ }
10458
10469
  for await (const event of run.stream()) {
10459
10470
  this.recordCursorEvent(event);
10471
+ if (event.type === "tool_call" && event.status === "running") {
10472
+ await this.handleCursorToolCall(cursorToolInputFromMessage(event));
10473
+ }
10460
10474
  if (linearSessionId) {
10461
10475
  linearForwarder.sendEvent(convertCursorEvent(event, linearSessionId));
10462
10476
  }
@@ -10479,10 +10493,45 @@ var CursorManager = class extends CodingAgentManager {
10479
10493
  } finally {
10480
10494
  this.activeRun = null;
10481
10495
  this.activeModel = null;
10496
+ this.blockedToolCallIds.clear();
10497
+ this.pendingCursorBlockReason = null;
10482
10498
  await this.historyFile.flush();
10483
10499
  await this.onTurnComplete();
10484
10500
  }
10485
10501
  }
10502
+ async handleCursorToolCall(toolCall) {
10503
+ if (!ENGINE_ENV.REPLICAS_DISABLE_GH_PR_MERGE || !toolCall) return;
10504
+ if (this.blockedToolCallIds.has(toolCall.toolUseId)) return;
10505
+ const result = await evaluateCommandProtection({
10506
+ provider: "cursor",
10507
+ source: "cursor_tool_call",
10508
+ toolName: toolCall.toolName,
10509
+ toolInput: toolCall.toolInput,
10510
+ command: toolCall.command,
10511
+ cwd: this.workingDirectory,
10512
+ toolUseId: toolCall.toolUseId
10513
+ });
10514
+ if (result.allowed) return;
10515
+ this.blockedToolCallIds.add(toolCall.toolUseId);
10516
+ const message = reportCommandProtectionBlock({
10517
+ managerName: "CursorManager",
10518
+ action: "tool call",
10519
+ eventType: "cursor-command-protection.blocked",
10520
+ result,
10521
+ command: toolCall.command,
10522
+ context: {
10523
+ toolName: toolCall.toolName,
10524
+ toolUseId: toolCall.toolUseId
10525
+ },
10526
+ historyFile: this.historyFile,
10527
+ recordHistoryEvent: this.recordHistoryEvent.bind(this)
10528
+ });
10529
+ if (this.activeRun) {
10530
+ await this.activeRun.cancel();
10531
+ throw new Error(message);
10532
+ }
10533
+ this.pendingCursorBlockReason = message;
10534
+ }
10486
10535
  async toCursorMessage(request) {
10487
10536
  if (!request.images || request.images.length === 0) {
10488
10537
  return request.message;
@@ -10578,7 +10627,23 @@ var OPENCODE_SHIM_DIR = dirname6(fileURLToPath(new URL("../../scripts/opencode",
10578
10627
  var OPENCODE_CONFIG_PATH = join18(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
10579
10628
  var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
10580
10629
  var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
10581
- var OPENCODE_WORKSPACE_PERMISSION = "allow";
10630
+ var OPENCODE_WORKSPACE_PERMISSION = {
10631
+ read: "allow",
10632
+ edit: "allow",
10633
+ glob: "allow",
10634
+ grep: "allow",
10635
+ list: "allow",
10636
+ bash: "ask",
10637
+ task: "allow",
10638
+ external_directory: "allow",
10639
+ todowrite: "allow",
10640
+ question: "allow",
10641
+ webfetch: "allow",
10642
+ websearch: "allow",
10643
+ lsp: "allow",
10644
+ doom_loop: "allow",
10645
+ skill: "allow"
10646
+ };
10582
10647
  var OPENCODE_SLASH_COMMANDS_CACHE_MS = 3e4;
10583
10648
  var OPENCODE_VARIANT_CANDIDATES_BY_THINKING_LEVEL = {
10584
10649
  low: ["low"],
@@ -10710,6 +10775,27 @@ function opencodeErrorPayload(error) {
10710
10775
  function opencodeFetch(input, init) {
10711
10776
  return fetch(input, { ...init, dispatcher: OPENCODE_FETCH_DISPATCHER });
10712
10777
  }
10778
+ function parseOpencodeToolInputText(text) {
10779
+ try {
10780
+ return JSON.parse(text);
10781
+ } catch {
10782
+ return { command: text };
10783
+ }
10784
+ }
10785
+ function opencodePermissionCommand(payload, toolInput) {
10786
+ const toolCommand = extractToolCommand(toolInput);
10787
+ if (toolCommand) return toolCommand;
10788
+ const payloadCommand = extractToolCommand(payload);
10789
+ if (payloadCommand) return payloadCommand;
10790
+ const resources = Array.isArray(payload.resources) ? payload.resources.filter((item) => typeof item === "string") : [];
10791
+ if (resources.length > 0) return resources.join(" ");
10792
+ const metadata = isRecord4(payload.metadata) ? payload.metadata : null;
10793
+ for (const key of ["command", "cmd", "pattern", "resource"]) {
10794
+ const value = metadata?.[key];
10795
+ if (typeof value === "string" && value.trim()) return value;
10796
+ }
10797
+ return null;
10798
+ }
10713
10799
  var OpencodeManager = class extends CodingAgentManager {
10714
10800
  client = null;
10715
10801
  server = null;
@@ -10727,6 +10813,11 @@ var OpencodeManager = class extends CodingAgentManager {
10727
10813
  activeLinearForwarder = null;
10728
10814
  forwardedLinearPartKeys = /* @__PURE__ */ new Set();
10729
10815
  modelVariants = /* @__PURE__ */ new Map();
10816
+ handledPermissionRequestIds = /* @__PURE__ */ new Set();
10817
+ pendingPermissionRequestIds = /* @__PURE__ */ new Set();
10818
+ handledToolCallIds = /* @__PURE__ */ new Set();
10819
+ pendingToolCallIds = /* @__PURE__ */ new Set();
10820
+ opencodeToolInputs = /* @__PURE__ */ new Map();
10730
10821
  slashCommandsCache = null;
10731
10822
  slashCommandsRequest = null;
10732
10823
  constructor(options) {
@@ -10931,6 +11022,11 @@ var OpencodeManager = class extends CodingAgentManager {
10931
11022
  this.activeAbortController = null;
10932
11023
  this.activeLinearForwarder = null;
10933
11024
  this.forwardedLinearPartKeys.clear();
11025
+ this.handledPermissionRequestIds.clear();
11026
+ this.pendingPermissionRequestIds.clear();
11027
+ this.handledToolCallIds.clear();
11028
+ this.pendingToolCallIds.clear();
11029
+ this.opencodeToolInputs.clear();
10934
11030
  await this.historyFile.flush();
10935
11031
  await this.onTurnComplete();
10936
11032
  }
@@ -10968,12 +11064,141 @@ var OpencodeManager = class extends CodingAgentManager {
10968
11064
  if (typeof partSessionID === "string" && this.sessionId && partSessionID !== this.sessionId) return;
10969
11065
  if (event.type === "message.part.updated" && isOpencodePart(part)) {
10970
11066
  if (this.shouldRecordOpencodePart(part)) this.recordOpencodePart(part);
11067
+ this.handleOpencodePartProtection(part).catch((error) => {
11068
+ console.error("[OpencodeManager] Failed to evaluate Opencode tool part:", error);
11069
+ });
10971
11070
  return;
10972
11071
  }
10973
11072
  if (event.type === "message.updated") this.recordOpencodeMessageRole(payload);
11073
+ if (event.type === "session.next.tool.input.ended") {
11074
+ const callId = typeof payload.callID === "string" ? payload.callID : void 0;
11075
+ if (callId && typeof payload.text === "string") {
11076
+ this.opencodeToolInputs.set(callId, parseOpencodeToolInputText(payload.text));
11077
+ }
11078
+ }
11079
+ if (event.type === "permission.v2.asked" || event.type === "permission.asked") {
11080
+ this.respondToOpencodePermission(event.type, payload).catch((error) => {
11081
+ console.error("[OpencodeManager] Failed to respond to Opencode permission:", error);
11082
+ });
11083
+ }
11084
+ if (event.type === "session.next.tool.called") {
11085
+ this.handleOpencodeToolCallProtection(payload).catch((error) => {
11086
+ console.error("[OpencodeManager] Failed to evaluate Opencode tool call:", error);
11087
+ });
11088
+ }
10974
11089
  if (this.recordOpencodeNextPart(event.type, payload)) return;
10975
11090
  this.recordHistoryEvent(`opencode-${event.type}`, payload, this.historyFile);
10976
11091
  }
11092
+ async respondToOpencodePermission(type, payload) {
11093
+ if (!this.client) return;
11094
+ const requestId = typeof payload.id === "string" ? payload.id : void 0;
11095
+ const sessionId = typeof payload.sessionID === "string" ? payload.sessionID : this.sessionId ?? void 0;
11096
+ if (!requestId || !sessionId || this.handledPermissionRequestIds.has(requestId) || this.pendingPermissionRequestIds.has(requestId)) return;
11097
+ this.pendingPermissionRequestIds.add(requestId);
11098
+ try {
11099
+ const source = isRecord4(payload.source) ? payload.source : null;
11100
+ const callId = typeof source?.callID === "string" ? source.callID : isRecord4(payload.tool) && typeof payload.tool.callID === "string" ? payload.tool.callID : void 0;
11101
+ const toolInput = callId ? this.opencodeToolInputs.get(callId) ?? payload : payload;
11102
+ const command = opencodePermissionCommand(payload, toolInput);
11103
+ const result = ENGINE_ENV.REPLICAS_DISABLE_GH_PR_MERGE ? await evaluateCommandProtection({
11104
+ provider: "opencode",
11105
+ source: "opencode_permission_request",
11106
+ toolName: typeof payload.action === "string" ? payload.action : typeof payload.permission === "string" ? payload.permission : "permission",
11107
+ toolInput,
11108
+ command,
11109
+ cwd: this.workingDirectory,
11110
+ toolUseId: requestId
11111
+ }) : { allowed: true, enabled: false };
11112
+ const reply = result.allowed ? "once" : "reject";
11113
+ const message = result.allowed ? void 0 : reportCommandProtectionBlock({
11114
+ managerName: "OpencodeManager",
11115
+ action: "permission",
11116
+ eventType: "opencode-command-protection.blocked",
11117
+ result,
11118
+ command,
11119
+ context: {
11120
+ requestId
11121
+ },
11122
+ historyFile: this.historyFile,
11123
+ recordHistoryEvent: this.recordHistoryEvent.bind(this)
11124
+ });
11125
+ if (type === "permission.v2.asked") {
11126
+ await this.client.v2.session.permission.reply({
11127
+ sessionID: sessionId,
11128
+ requestID: requestId,
11129
+ reply,
11130
+ ...message ? { message } : {}
11131
+ }, { throwOnError: true });
11132
+ } else {
11133
+ await this.client.permission.reply({
11134
+ requestID: requestId,
11135
+ directory: this.workingDirectory,
11136
+ reply,
11137
+ ...message ? { message } : {}
11138
+ }, { throwOnError: true });
11139
+ }
11140
+ this.handledPermissionRequestIds.add(requestId);
11141
+ } finally {
11142
+ this.pendingPermissionRequestIds.delete(requestId);
11143
+ }
11144
+ }
11145
+ async handleOpencodeToolCallProtection(payload) {
11146
+ const callId = typeof payload.callID === "string" ? payload.callID : void 0;
11147
+ if (!callId || this.handledToolCallIds.has(callId)) return;
11148
+ const toolName = typeof payload.tool === "string" ? payload.tool : "tool";
11149
+ const input = isRecord4(payload.input) ? payload.input : {};
11150
+ this.opencodeToolInputs.set(callId, input);
11151
+ const command = extractToolCommand(input);
11152
+ await this.evaluateOpencodeToolProtection(toolName, input, command, callId);
11153
+ }
11154
+ async handleOpencodePartProtection(part) {
11155
+ if (part.type !== "tool") return;
11156
+ const state = part.state;
11157
+ if (state.status !== "running" && state.status !== "pending") return;
11158
+ await this.evaluateOpencodeToolProtection(part.tool, state.input, extractToolCommand(state.input), part.id);
11159
+ }
11160
+ async evaluateOpencodeToolProtection(toolName, toolInput, command, toolUseId) {
11161
+ if (!ENGINE_ENV.REPLICAS_DISABLE_GH_PR_MERGE || this.handledToolCallIds.has(toolUseId) || this.pendingToolCallIds.has(toolUseId)) return;
11162
+ this.pendingToolCallIds.add(toolUseId);
11163
+ try {
11164
+ const result = await evaluateCommandProtection({
11165
+ provider: "opencode",
11166
+ source: "opencode_tool_call",
11167
+ toolName,
11168
+ toolInput,
11169
+ command,
11170
+ cwd: this.workingDirectory,
11171
+ toolUseId
11172
+ });
11173
+ if (result.allowed) {
11174
+ this.handledToolCallIds.add(toolUseId);
11175
+ return;
11176
+ }
11177
+ const message = reportCommandProtectionBlock({
11178
+ managerName: "OpencodeManager",
11179
+ action: "tool call",
11180
+ eventType: "opencode-command-protection.blocked",
11181
+ result,
11182
+ command,
11183
+ context: {
11184
+ toolName,
11185
+ toolUseId
11186
+ },
11187
+ historyFile: this.historyFile,
11188
+ recordHistoryEvent: this.recordHistoryEvent.bind(this)
11189
+ });
11190
+ this.activeAbortController?.abort();
11191
+ if (this.client && this.sessionId) {
11192
+ await this.client.session.abort(
11193
+ { sessionID: this.sessionId, directory: this.workingDirectory },
11194
+ { throwOnError: true }
11195
+ );
11196
+ }
11197
+ this.handledToolCallIds.add(toolUseId);
11198
+ } finally {
11199
+ this.pendingToolCallIds.delete(toolUseId);
11200
+ }
11201
+ }
10977
11202
  recordOpencodeMessageRole(payload) {
10978
11203
  const info = isRecord4(payload.info) ? payload.info : null;
10979
11204
  const id = typeof info?.id === "string" ? info.id : void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.412",
3
+ "version": "0.1.414",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",