replicas-engine 0.1.409 → 0.1.411

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 +203 -56
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -207,6 +207,7 @@ var AGENT_MODELS = {
207
207
  "gpt-5-mini",
208
208
  "gemini-3.1-pro",
209
209
  "gemini-3-flash",
210
+ "grok-4.5",
210
211
  "grok-4.3",
211
212
  CLAUDE_HAIKU_4_5_MODEL,
212
213
  "kimi-k2.5"
@@ -244,6 +245,7 @@ var MODEL_LABELS = {
244
245
  [CLAUDE_HAIKU_4_5_MODEL]: "Haiku 4.5",
245
246
  "gemini-3.1-pro": "Gemini 3.1 Pro",
246
247
  "gemini-3-flash": "Gemini 3 Flash",
248
+ "grok-4.5": "Grok 4.5",
247
249
  "grok-4.3": "Grok 4.3",
248
250
  "kimi-k2.5": "Kimi K2.5"
249
251
  };
@@ -479,7 +481,7 @@ var WORKSPACE_SIZES = ["small", "large"];
479
481
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
480
482
 
481
483
  // ../shared/src/e2b.ts
482
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-08-v4";
484
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-09-v1";
483
485
 
484
486
  // ../shared/src/runtime-env.ts
485
487
  function parsePosixEnvFile(content) {
@@ -5533,27 +5535,81 @@ function linearThoughtToResponse(thought) {
5533
5535
  function summarizeInput(input) {
5534
5536
  if (!input) return "";
5535
5537
  if (typeof input === "string") return input;
5536
- if (typeof input === "object") {
5537
- const obj = input;
5538
- if (obj.file_path) return String(obj.file_path);
5539
- if (obj.command) return String(obj.command);
5540
- if (obj.pattern) return `pattern: ${String(obj.pattern)}`;
5541
- if (obj.query) return String(obj.query);
5542
- if (obj.url) return String(obj.url);
5543
- if (typeof obj.activeForm === "string" && obj.activeForm) return String(obj.activeForm);
5544
- if (typeof obj.subject === "string" && obj.subject) return String(obj.subject);
5545
- const keys = Object.keys(obj);
5546
- if (keys.length > 0) {
5547
- const firstKey = keys[0];
5548
- return `${firstKey}: ${String(obj[firstKey])}`;
5538
+ if (isRecord(input)) {
5539
+ if (input.file_path) return String(input.file_path);
5540
+ if (input.command) return String(input.command);
5541
+ if (input.pattern) return `pattern: ${String(input.pattern)}`;
5542
+ if (input.query) return String(input.query);
5543
+ if (input.url) return String(input.url);
5544
+ if (typeof input.activeForm === "string" && input.activeForm) return String(input.activeForm);
5545
+ if (typeof input.subject === "string" && input.subject) return String(input.subject);
5546
+ for (const [key, value] of Object.entries(input)) {
5547
+ return `${key}: ${String(value)}`;
5549
5548
  }
5550
5549
  }
5551
5550
  return "";
5552
5551
  }
5552
+ function summarizeResult(result) {
5553
+ if (!result) return "";
5554
+ if (typeof result === "string") return result;
5555
+ if (isRecord(result)) {
5556
+ if (typeof result.message === "string") return result.message;
5557
+ if (typeof result.error === "string") return result.error;
5558
+ if (typeof result.stdout === "string") return result.stdout;
5559
+ if (typeof result.stderr === "string") return result.stderr;
5560
+ if (typeof result.path === "string") return result.path;
5561
+ }
5562
+ try {
5563
+ return JSON.stringify(result);
5564
+ } catch {
5565
+ return String(result);
5566
+ }
5567
+ }
5568
+ function toolAction(toolName) {
5569
+ switch (toolName) {
5570
+ case "Bash":
5571
+ case "bash":
5572
+ case "shell":
5573
+ return "Running command";
5574
+ case "Edit":
5575
+ case "edit":
5576
+ return "Editing file";
5577
+ case "Write":
5578
+ case "write":
5579
+ return "Writing file";
5580
+ case "Read":
5581
+ case "read":
5582
+ return "Reading file";
5583
+ case "Glob":
5584
+ case "glob":
5585
+ return "Searching files";
5586
+ case "Grep":
5587
+ case "grep":
5588
+ case "semsearch":
5589
+ return "Searching code";
5590
+ case "WebSearch":
5591
+ return "Web search";
5592
+ case "WebFetch":
5593
+ return "Fetching URL";
5594
+ case "delete":
5595
+ return "Deleting file";
5596
+ case "Task":
5597
+ case "task":
5598
+ return "Spawning subagent";
5599
+ case "TaskCreate":
5600
+ case "TaskUpdate":
5601
+ case "TaskList":
5602
+ case "TaskGet":
5603
+ case "update_todos":
5604
+ case "create_plan":
5605
+ return "Updating plan";
5606
+ default:
5607
+ return toolName;
5608
+ }
5609
+ }
5553
5610
  function convertClaudeEvent(event, linearSessionId) {
5554
5611
  if (event.type === "assistant") {
5555
- const message = event;
5556
- const contentBlocks = normalizeContentBlocks(message.message?.content);
5612
+ const contentBlocks = normalizeContentBlocks(event.message.content);
5557
5613
  for (const block of contentBlocks) {
5558
5614
  if (block.type === "text" && block.text) {
5559
5615
  return {
@@ -5576,47 +5632,11 @@ function convertClaudeEvent(event, linearSessionId) {
5576
5632
  if (block.type === "tool_use" && block.name) {
5577
5633
  const toolName = block.name;
5578
5634
  const parameter = summarizeInput(block.input);
5579
- let action = toolName;
5580
- switch (toolName) {
5581
- case "Bash":
5582
- action = "Running command";
5583
- break;
5584
- case "Edit":
5585
- action = "Editing file";
5586
- break;
5587
- case "Write":
5588
- action = "Writing file";
5589
- break;
5590
- case "Read":
5591
- action = "Reading file";
5592
- break;
5593
- case "Glob":
5594
- action = "Searching files";
5595
- break;
5596
- case "Grep":
5597
- action = "Searching code";
5598
- break;
5599
- case "WebSearch":
5600
- action = "Web search";
5601
- break;
5602
- case "WebFetch":
5603
- action = "Fetching URL";
5604
- break;
5605
- case "Task":
5606
- action = "Spawning subagent";
5607
- break;
5608
- case "TaskCreate":
5609
- case "TaskUpdate":
5610
- case "TaskList":
5611
- case "TaskGet":
5612
- action = "Updating plan";
5613
- break;
5614
- }
5615
5635
  return {
5616
5636
  linearSessionId,
5617
5637
  content: {
5618
5638
  type: "action",
5619
- action,
5639
+ action: toolAction(toolName),
5620
5640
  parameter
5621
5641
  }
5622
5642
  };
@@ -5624,8 +5644,7 @@ function convertClaudeEvent(event, linearSessionId) {
5624
5644
  }
5625
5645
  }
5626
5646
  if (event.type === "user") {
5627
- const message = event;
5628
- const contentBlocks = normalizeContentBlocks(message.message?.content);
5647
+ const contentBlocks = normalizeContentBlocks(event.message.content);
5629
5648
  for (const block of contentBlocks) {
5630
5649
  if (block.type === "tool_result") {
5631
5650
  const resultText = extractToolResultText(block.content);
@@ -5645,6 +5664,106 @@ function convertClaudeEvent(event, linearSessionId) {
5645
5664
  }
5646
5665
  return null;
5647
5666
  }
5667
+ function convertCursorEvent(event, linearSessionId) {
5668
+ if (event.type === "assistant") {
5669
+ for (const block of event.message.content) {
5670
+ if (block.type === "text" && block.text) {
5671
+ return {
5672
+ linearSessionId,
5673
+ content: {
5674
+ type: "thought",
5675
+ body: block.text
5676
+ }
5677
+ };
5678
+ }
5679
+ if (block.type === "tool_use" && block.name) {
5680
+ return {
5681
+ linearSessionId,
5682
+ content: {
5683
+ type: "action",
5684
+ action: toolAction(block.name),
5685
+ parameter: summarizeInput(block.input)
5686
+ }
5687
+ };
5688
+ }
5689
+ }
5690
+ }
5691
+ if (event.type === "thinking" && event.text) {
5692
+ return {
5693
+ linearSessionId,
5694
+ content: {
5695
+ type: "thought",
5696
+ body: event.text
5697
+ }
5698
+ };
5699
+ }
5700
+ if (event.type === "tool_call") {
5701
+ const result = event.status === "running" ? void 0 : event.status === "error" ? `Error: ${summarizeResult(event.result) || "Tool failed"}` : summarizeResult(event.result) || "Done";
5702
+ return {
5703
+ linearSessionId,
5704
+ content: {
5705
+ type: "action",
5706
+ action: toolAction(event.name),
5707
+ parameter: summarizeInput(event.args),
5708
+ ...result ? { result } : {}
5709
+ }
5710
+ };
5711
+ }
5712
+ if (event.type === "task" && event.text) {
5713
+ return {
5714
+ linearSessionId,
5715
+ content: {
5716
+ type: "thought",
5717
+ body: event.text
5718
+ }
5719
+ };
5720
+ }
5721
+ return null;
5722
+ }
5723
+ function isOpencodePartEnded(part) {
5724
+ return "time" in part && isRecord(part.time) && part.time.end !== void 0;
5725
+ }
5726
+ function convertOpencodePart(part, linearSessionId) {
5727
+ if ((part.type === "text" || part.type === "reasoning") && isOpencodePartEnded(part)) {
5728
+ const body = typeof part.text === "string" ? part.text.trim() : "";
5729
+ if (!body) return null;
5730
+ return {
5731
+ linearSessionId,
5732
+ content: {
5733
+ type: "thought",
5734
+ body
5735
+ }
5736
+ };
5737
+ }
5738
+ if (part.type === "tool" && isRecord(part.state)) {
5739
+ const state = part.state;
5740
+ const status = typeof state.status === "string" ? state.status : void 0;
5741
+ const result = status === "completed" ? summarizeResult(state.output) || "Done" : status === "error" ? `Error: ${summarizeResult(state.error) || "Tool failed"}` : void 0;
5742
+ return {
5743
+ linearSessionId,
5744
+ content: {
5745
+ type: "action",
5746
+ action: toolAction(typeof part.tool === "string" ? part.tool : "Tool"),
5747
+ parameter: summarizeInput(state.input),
5748
+ ...result ? { result } : {}
5749
+ }
5750
+ };
5751
+ }
5752
+ if (part.type === "patch") {
5753
+ const files = "files" in part && Array.isArray(part.files) ? part.files.filter((file) => typeof file === "string") : [];
5754
+ if (files.length === 0) return null;
5755
+ return {
5756
+ linearSessionId,
5757
+ content: {
5758
+ type: "action",
5759
+ action: "File change",
5760
+ parameter: files.join(", "),
5761
+ result: "Done"
5762
+ }
5763
+ };
5764
+ }
5765
+ return null;
5766
+ }
5648
5767
  function mapTodoStatus(status) {
5649
5768
  if (status === "in_progress") {
5650
5769
  return "inProgress";
@@ -8087,7 +8206,7 @@ var AspClient = class {
8087
8206
  // src/managers/codex-asp/app-server-process.ts
8088
8207
  var DEFAULT_CODEX_BINARY = "codex";
8089
8208
  var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
8090
- var ENGINE_PACKAGE_VERSION = "0.1.409";
8209
+ var ENGINE_PACKAGE_VERSION = "0.1.411";
8091
8210
  var INITIALIZE_METHOD = "initialize";
8092
8211
  var INITIALIZED_NOTIFICATION = "initialized";
8093
8212
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -10294,6 +10413,8 @@ var CursorManager = class extends CodingAgentManager {
10294
10413
  return this.agent;
10295
10414
  }
10296
10415
  async processMessageInternal(request) {
10416
+ const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
10417
+ const linearForwarder = new LinearEventForwarder(linearSessionId);
10297
10418
  try {
10298
10419
  const agent = await this.ensureAgent(request);
10299
10420
  const message = await this.toCursorMessage(request);
@@ -10310,6 +10431,9 @@ var CursorManager = class extends CodingAgentManager {
10310
10431
  this.activeModel = model;
10311
10432
  for await (const event of run.stream()) {
10312
10433
  this.recordCursorEvent(event);
10434
+ if (linearSessionId) {
10435
+ linearForwarder.sendEvent(convertCursorEvent(event, linearSessionId));
10436
+ }
10313
10437
  }
10314
10438
  const result = await run.wait();
10315
10439
  if (result.status === "error") {
@@ -10318,6 +10442,8 @@ var CursorManager = class extends CodingAgentManager {
10318
10442
  message: result.result || "Cursor run failed",
10319
10443
  runId: result.id
10320
10444
  }, this.historyFile);
10445
+ } else {
10446
+ linearForwarder.flushThoughtAsResponse();
10321
10447
  }
10322
10448
  } catch (error) {
10323
10449
  this.recordHistoryEvent("cursor-error", {
@@ -10572,6 +10698,8 @@ var OpencodeManager = class extends CodingAgentManager {
10572
10698
  textParts = /* @__PURE__ */ new Map();
10573
10699
  reasoningParts = /* @__PURE__ */ new Map();
10574
10700
  nonAssistantMessageIds = /* @__PURE__ */ new Set();
10701
+ activeLinearForwarder = null;
10702
+ forwardedLinearPartKeys = /* @__PURE__ */ new Set();
10575
10703
  modelVariants = /* @__PURE__ */ new Map();
10576
10704
  slashCommandsCache = null;
10577
10705
  slashCommandsRequest = null;
@@ -10738,7 +10866,11 @@ var OpencodeManager = class extends CodingAgentManager {
10738
10866
  async processMessageInternal(request) {
10739
10867
  const model = request.model ?? DEFAULT_OPENCODE_MODEL;
10740
10868
  const controller = new AbortController();
10869
+ const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
10870
+ const linearForwarder = new LinearEventForwarder(linearSessionId);
10741
10871
  this.activeAbortController = controller;
10872
+ this.activeLinearForwarder = linearForwarder;
10873
+ this.forwardedLinearPartKeys.clear();
10742
10874
  try {
10743
10875
  const client = await this.ensureClient(model);
10744
10876
  const agent = request.planMode ? "plan" : "build";
@@ -10760,6 +10892,7 @@ var OpencodeManager = class extends CodingAgentManager {
10760
10892
  }, { signal: controller.signal, throwOnError: true });
10761
10893
  this.recordHistoryEvent("opencode-message.updated", { info: result.data.info }, this.historyFile);
10762
10894
  for (const part of result.data.parts) this.recordOpencodePart(part);
10895
+ linearForwarder.flushThoughtAsResponse();
10763
10896
  this.recordHistoryEvent("opencode-session.idle", { sessionID: sessionId }, this.historyFile);
10764
10897
  } catch (error) {
10765
10898
  if (controller.signal.aborted) {
@@ -10770,6 +10903,8 @@ var OpencodeManager = class extends CodingAgentManager {
10770
10903
  }
10771
10904
  } finally {
10772
10905
  this.activeAbortController = null;
10906
+ this.activeLinearForwarder = null;
10907
+ this.forwardedLinearPartKeys.clear();
10773
10908
  await this.historyFile.flush();
10774
10909
  await this.onTurnComplete();
10775
10910
  }
@@ -10893,8 +11028,20 @@ var OpencodeManager = class extends CodingAgentManager {
10893
11028
  }
10894
11029
  return false;
10895
11030
  }
11031
+ forwardOpencodePartToLinear(part) {
11032
+ const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
11033
+ if (!linearSessionId || !this.activeLinearForwarder) return;
11034
+ const event = convertOpencodePart(part, linearSessionId);
11035
+ if (!event) return;
11036
+ if (typeof part.id !== "string") return;
11037
+ const key = `${part.type}:${part.id}:${JSON.stringify(event.content)}`;
11038
+ if (this.forwardedLinearPartKeys.has(key)) return;
11039
+ this.forwardedLinearPartKeys.add(key);
11040
+ this.activeLinearForwarder.sendEvent(event);
11041
+ }
10896
11042
  recordOpencodePart(part) {
10897
11043
  this.recordHistoryEvent(`opencode-part-${part.type}`, { part }, this.historyFile);
11044
+ this.forwardOpencodePartToLinear(part);
10898
11045
  }
10899
11046
  };
10900
11047
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.409",
3
+ "version": "0.1.411",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",