replicas-engine 0.1.237 → 0.1.238

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 +163 -52
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -1783,7 +1783,7 @@ function isClaudeAuthErrorText(text) {
1783
1783
  }
1784
1784
 
1785
1785
  // ../shared/src/engine/environment.ts
1786
- var DAYTONA_SNAPSHOT_ID = "29-05-2026-royal-york-v8";
1786
+ var DAYTONA_SNAPSHOT_ID = "29-05-2026-royal-york-v9";
1787
1787
  var DESKTOP_NOVNC_PORT = 6080;
1788
1788
 
1789
1789
  // ../shared/src/engine/types.ts
@@ -1802,9 +1802,9 @@ function normalizeClaudeModel(model) {
1802
1802
  }
1803
1803
  var MODEL_LABELS = {
1804
1804
  sonnet: "Sonnet 4.5",
1805
- opus: "Opus 4.7",
1806
- [CLAUDE_OPUS_1M_MODEL]: "Opus 4.7 (1M)",
1807
- [LEGACY_CLAUDE_OPUS_1M_MODEL]: "Opus 4.7 (1M)",
1805
+ opus: "Opus 4.8",
1806
+ [CLAUDE_OPUS_1M_MODEL]: "Opus 4.8 (1M)",
1807
+ [LEGACY_CLAUDE_OPUS_1M_MODEL]: "Opus 4.8 (1M)",
1808
1808
  haiku: "Haiku 4.5",
1809
1809
  "gpt-5.5": "GPT-5.5",
1810
1810
  "gpt-5.4": "GPT-5.4",
@@ -1952,6 +1952,127 @@ function isTerminalBackgroundTaskStatus(status) {
1952
1952
  return normalizeBackgroundTaskStatus(status) !== "in_progress";
1953
1953
  }
1954
1954
 
1955
+ // ../shared/src/display-message/task-accumulator.ts
1956
+ function mapTaskStatus(status) {
1957
+ if (status === "in_progress" || status === "completed") return status;
1958
+ return "pending";
1959
+ }
1960
+ function toAccumulatorInput(input) {
1961
+ if (typeof input === "string") {
1962
+ try {
1963
+ const parsed = JSON.parse(input);
1964
+ return isRecord(parsed) ? parsed : {};
1965
+ } catch {
1966
+ return {};
1967
+ }
1968
+ }
1969
+ return isRecord(input) ? input : {};
1970
+ }
1971
+ function extractToolResultText(content, separator = "\n") {
1972
+ if (typeof content === "string") return content;
1973
+ if (!Array.isArray(content)) return "";
1974
+ const texts = [];
1975
+ for (const part of content) {
1976
+ if (isRecord(part) && part.type === "text" && typeof part.text === "string") {
1977
+ texts.push(part.text);
1978
+ }
1979
+ }
1980
+ return texts.join(separator);
1981
+ }
1982
+ function parseStringField(value) {
1983
+ if (typeof value !== "string") return null;
1984
+ const trimmed = value.trim();
1985
+ return trimmed ? trimmed : null;
1986
+ }
1987
+ function parseCreateResultTaskId(resultText) {
1988
+ try {
1989
+ const parsed = JSON.parse(resultText);
1990
+ if (isRecord(parsed) && isRecord(parsed.task)) {
1991
+ return parseStringField(parsed.task.id);
1992
+ }
1993
+ } catch {
1994
+ }
1995
+ return resultText.match(/\bTask\s+#?([A-Za-z0-9_-]+)\s+created\b/i)?.[1] ?? null;
1996
+ }
1997
+ var TaskAccumulator = class {
1998
+ tasksByTaskId = /* @__PURE__ */ new Map();
1999
+ tasksByCreateToolUseId = /* @__PURE__ */ new Map();
2000
+ orderedKeys = [];
2001
+ processToolUse(toolName, toolUseId, input) {
2002
+ if (toolName === "TaskCreate") {
2003
+ const subject = parseStringField(input.subject);
2004
+ if (!subject) return false;
2005
+ this.tasksByCreateToolUseId.set(toolUseId, { subject, status: "pending" });
2006
+ this.orderedKeys.push(toolUseId);
2007
+ return true;
2008
+ }
2009
+ if (toolName === "TaskUpdate") {
2010
+ const taskId = parseStringField(input.taskId);
2011
+ if (!taskId) return false;
2012
+ if (input.status === "deleted") {
2013
+ if (!this.tasksByTaskId.delete(taskId)) return false;
2014
+ const idx = this.orderedKeys.indexOf(taskId);
2015
+ if (idx !== -1) this.orderedKeys.splice(idx, 1);
2016
+ return true;
2017
+ }
2018
+ const existing = this.tasksByTaskId.get(taskId);
2019
+ const subject = parseStringField(input.subject) ?? existing?.subject;
2020
+ if (!subject) return false;
2021
+ const status = input.status !== void 0 ? mapTaskStatus(input.status) : existing?.status ?? "pending";
2022
+ this.tasksByTaskId.set(taskId, { subject, status });
2023
+ if (!existing) this.orderedKeys.push(taskId);
2024
+ return true;
2025
+ }
2026
+ if (toolName === "TaskList") {
2027
+ if (!Array.isArray(input.tasks)) return false;
2028
+ let changed = false;
2029
+ for (const raw of input.tasks) {
2030
+ if (!isRecord(raw)) continue;
2031
+ const id = parseStringField(raw.id);
2032
+ const subject = parseStringField(raw.subject);
2033
+ if (!id || !subject) continue;
2034
+ const existing = this.tasksByTaskId.get(id);
2035
+ const next = { subject, status: mapTaskStatus(raw.status) };
2036
+ if (existing && existing.subject === next.subject && existing.status === next.status) continue;
2037
+ this.tasksByTaskId.set(id, next);
2038
+ if (!existing) this.orderedKeys.push(id);
2039
+ changed = true;
2040
+ }
2041
+ return changed;
2042
+ }
2043
+ return false;
2044
+ }
2045
+ processCreateResult(toolUseId, resultText) {
2046
+ const pending = this.tasksByCreateToolUseId.get(toolUseId);
2047
+ if (!pending) return false;
2048
+ const taskId = parseCreateResultTaskId(resultText);
2049
+ if (!taskId) return false;
2050
+ this.tasksByTaskId.set(taskId, pending);
2051
+ this.tasksByCreateToolUseId.delete(toolUseId);
2052
+ const idx = this.orderedKeys.indexOf(toolUseId);
2053
+ if (idx !== -1) this.orderedKeys.splice(idx, 1, taskId);
2054
+ return true;
2055
+ }
2056
+ getTasks() {
2057
+ const out = [];
2058
+ for (const key of this.orderedKeys) {
2059
+ const task = this.tasksByTaskId.get(key) ?? this.tasksByCreateToolUseId.get(key);
2060
+ if (task && task.subject) out.push(task);
2061
+ }
2062
+ return out;
2063
+ }
2064
+ processContentBlock(block) {
2065
+ if (!isRecord(block)) return false;
2066
+ if (block.type === "tool_use" && typeof block.name === "string" && typeof block.id === "string") {
2067
+ return this.processToolUse(block.name, block.id, toAccumulatorInput(block.input));
2068
+ }
2069
+ if (block.type === "tool_result" && typeof block.tool_use_id === "string") {
2070
+ return this.processCreateResult(block.tool_use_id, extractToolResultText(block.content, ""));
2071
+ }
2072
+ return false;
2073
+ }
2074
+ };
2075
+
1955
2076
  // ../shared/src/agent-event-utils.ts
1956
2077
  function getUserMessage(event) {
1957
2078
  return event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string" ? event.payload.message : null;
@@ -4051,14 +4172,8 @@ function summarizeInput(input) {
4051
4172
  if (obj.pattern) return `pattern: ${String(obj.pattern)}`;
4052
4173
  if (obj.query) return String(obj.query);
4053
4174
  if (obj.url) return String(obj.url);
4054
- if (obj.todos && Array.isArray(obj.todos)) {
4055
- const todos = obj.todos;
4056
- const completed = todos.filter((t) => t.status === "completed").length;
4057
- const total = todos.length;
4058
- const currentTask = todos.find((t) => t.status === "in_progress");
4059
- const summary = `${completed}/${total}`;
4060
- return currentTask?.content ? `${summary}: ${currentTask.content}` : summary;
4061
- }
4175
+ if (typeof obj.activeForm === "string" && obj.activeForm) return String(obj.activeForm);
4176
+ if (typeof obj.subject === "string" && obj.subject) return String(obj.subject);
4062
4177
  const keys = Object.keys(obj);
4063
4178
  if (keys.length > 0) {
4064
4179
  const firstKey = keys[0];
@@ -4122,7 +4237,10 @@ function convertClaudeEvent(event, linearSessionId) {
4122
4237
  case "Task":
4123
4238
  action = "Spawning subagent";
4124
4239
  break;
4125
- case "TodoWrite":
4240
+ case "TaskCreate":
4241
+ case "TaskUpdate":
4242
+ case "TaskList":
4243
+ case "TaskGet":
4126
4244
  action = "Updating plan";
4127
4245
  break;
4128
4246
  }
@@ -4142,12 +4260,7 @@ function convertClaudeEvent(event, linearSessionId) {
4142
4260
  const contentBlocks = message.message?.content || [];
4143
4261
  for (const block of contentBlocks) {
4144
4262
  if (block.type === "tool_result") {
4145
- let resultText = "";
4146
- if (typeof block.content === "string") {
4147
- resultText = block.content;
4148
- } else if (Array.isArray(block.content)) {
4149
- resultText = block.content.filter((c) => c.type === "text").map((c) => c.text || "").join("\n");
4150
- }
4263
+ const resultText = extractToolResultText(block.content);
4151
4264
  const isError = block.is_error || false;
4152
4265
  const result = isError ? `Error: ${resultText}` : resultText || "Done";
4153
4266
  return {
@@ -4176,34 +4289,6 @@ function mapTodoStatus(status) {
4176
4289
  }
4177
4290
  return "pending";
4178
4291
  }
4179
- function extractPlanFromClaudeEvent(event) {
4180
- if (event.type !== "assistant") {
4181
- return null;
4182
- }
4183
- const message = event;
4184
- const contentBlocks = message.message?.content || [];
4185
- for (const block of contentBlocks) {
4186
- if (block.type !== "tool_use" || block.name !== "TodoWrite") {
4187
- continue;
4188
- }
4189
- const input = typeof block.input === "string" ? (() => {
4190
- try {
4191
- return JSON.parse(block.input);
4192
- } catch {
4193
- return null;
4194
- }
4195
- })() : typeof block.input === "object" && block.input !== null ? block.input : null;
4196
- const todos = input?.todos;
4197
- if (!todos || todos.length === 0) {
4198
- return null;
4199
- }
4200
- return todos.filter((todo) => Boolean(todo.content && todo.content.trim().length > 0)).map((todo) => ({
4201
- content: todo.content.trim(),
4202
- status: mapTodoStatus(todo.status)
4203
- }));
4204
- }
4205
- return null;
4206
- }
4207
4292
  function convertCodexEvent(event, linearSessionId) {
4208
4293
  if (event.type === "turn.started") {
4209
4294
  return {
@@ -4997,6 +5082,7 @@ function isLinearThoughtEvent(event) {
4997
5082
  }
4998
5083
  var LinearEventForwarder = class {
4999
5084
  linearSessionId;
5085
+ taskAccumulator = new TaskAccumulator();
5000
5086
  latestThoughtEvent = null;
5001
5087
  constructor(linearSessionId) {
5002
5088
  this.linearSessionId = linearSessionId;
@@ -5009,6 +5095,25 @@ var LinearEventForwarder = class {
5009
5095
  }).catch(() => {
5010
5096
  });
5011
5097
  }
5098
+ processClaudeEventForPlan(event) {
5099
+ if (!this.linearSessionId) return;
5100
+ if (!this.routeEventToAccumulator(event)) return;
5101
+ const plan = this.taskAccumulator.getTasks().map((task) => ({
5102
+ content: task.subject,
5103
+ status: mapTodoStatus(task.status)
5104
+ }));
5105
+ this.sendPlan(plan);
5106
+ }
5107
+ routeEventToAccumulator(event) {
5108
+ if (event.type !== "assistant" && event.type !== "user") return false;
5109
+ const content = event.message.content;
5110
+ if (!Array.isArray(content)) return false;
5111
+ let changed = false;
5112
+ for (const block of content) {
5113
+ if (this.taskAccumulator.processContentBlock(block)) changed = true;
5114
+ }
5115
+ return changed;
5116
+ }
5012
5117
  sendEvent(linearEvent) {
5013
5118
  if (!this.linearSessionId || !linearEvent) return;
5014
5119
  if (this.latestThoughtEvent) {
@@ -5079,7 +5184,10 @@ var ALWAYS_ALLOWED_TOOLS = [
5079
5184
  "Grep",
5080
5185
  "WebSearch",
5081
5186
  "WebFetch",
5082
- "TodoWrite",
5187
+ "TaskCreate",
5188
+ "TaskUpdate",
5189
+ "TaskGet",
5190
+ "TaskList",
5083
5191
  "Agent",
5084
5192
  "ListMcpResourcesTool",
5085
5193
  "ReadMcpResourceTool",
@@ -5594,7 +5702,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
5594
5702
  await this.handleMessage(msg);
5595
5703
  _ClaudeManager.updateBackgroundTaskState(msg, this.activeBackgroundTasks);
5596
5704
  if (linearSessionId && this.sessionLinearForwarder) {
5597
- this.sessionLinearForwarder.sendPlan(extractPlanFromClaudeEvent(msg));
5705
+ this.sessionLinearForwarder.processClaudeEventForPlan(msg);
5598
5706
  this.sessionLinearForwarder.sendEvent(convertClaudeEvent(msg, linearSessionId));
5599
5707
  }
5600
5708
  if (msg.type === "result") {
@@ -5982,7 +6090,7 @@ var AspClient = class {
5982
6090
  // src/managers/codex-asp/app-server-process.ts
5983
6091
  var DEFAULT_CODEX_BINARY = "codex";
5984
6092
  var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
5985
- var ENGINE_PACKAGE_VERSION = "0.1.237";
6093
+ var ENGINE_PACKAGE_VERSION = "0.1.238";
5986
6094
  var INITIALIZE_METHOD = "initialize";
5987
6095
  var INITIALIZED_NOTIFICATION = "initialized";
5988
6096
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -8347,7 +8455,7 @@ function getEnvironmentSection() {
8347
8455
  `Platform: ${process.platform}`,
8348
8456
  getShellInfoLine(),
8349
8457
  `OS Version: ${unameSR}`,
8350
- `The most recent Claude model family is Claude 4.5/4.6/4.7. Model IDs \u2014 Opus 4.7: 'claude-opus-4-7', Sonnet 4.6: 'claude-sonnet-4-6', Haiku 4.5: 'claude-haiku-4-5-20251001'. When building AI applications, default to the latest and most capable Claude models.`
8458
+ `The most recent Claude model family is Claude 4.5/4.6/4.8. Model IDs \u2014 Opus 4.8: 'claude-opus-4-8', Sonnet 4.6: 'claude-sonnet-4-6', Haiku 4.5: 'claude-haiku-4-5-20251001'. When building AI applications, default to the latest and most capable Claude models.`
8351
8459
  ];
8352
8460
  return [
8353
8461
  `# Environment`,
@@ -8383,7 +8491,10 @@ var RELAY_TOOLS = [
8383
8491
  "WebSearch",
8384
8492
  "WebFetch",
8385
8493
  "Skill",
8386
- "TodoWrite",
8494
+ "TaskCreate",
8495
+ "TaskUpdate",
8496
+ "TaskGet",
8497
+ "TaskList",
8387
8498
  "TaskOutput",
8388
8499
  "TaskStop"
8389
8500
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.237",
3
+ "version": "0.1.238",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",