replicas-engine 0.1.468 → 0.1.470

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 +182 -130
  2. package/package.json +3 -3
package/dist/src/index.js CHANGED
@@ -582,7 +582,7 @@ var WORKSPACE_SIZES = ["small", "large"];
582
582
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
583
583
 
584
584
  // ../shared/src/e2b.ts
585
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-19-v20";
585
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-20-v2";
586
586
 
587
587
  // ../shared/src/runtime-env.ts
588
588
  function shellQuotePosix(value) {
@@ -2796,10 +2796,19 @@ function hasChatStarted(chat) {
2796
2796
  var DESKTOP_NOVNC_PORT = 6080;
2797
2797
 
2798
2798
  // ../shared/src/engine/v1.ts
2799
+ import { z as z2 } from "zod";
2799
2800
  var MERGED_MESSAGE_SEPARATOR = "\n\n<!-- replicas:merged -->\n\n";
2800
2801
  var ENGINE_HEALTH_WAIT_HEADER = "X-Replicas-Health-Wait";
2801
2802
  var ENGINE_HEALTH_WAIT_QUERY_PARAM = "wait_ms";
2802
2803
  var ENGINE_HEALTH_MAX_WAIT_MS = 2e3;
2804
+ var createChatRequestSchema = z2.object({
2805
+ id: z2.string().uuid().optional(),
2806
+ createdAt: z2.string().datetime().optional(),
2807
+ provider: z2.enum(VALID_AGENT_PROVIDERS),
2808
+ title: z2.string().min(1).optional(),
2809
+ parentChatId: z2.string().uuid().optional(),
2810
+ clientRequestId: z2.string().min(1).max(128).optional()
2811
+ });
2803
2812
  function normalizeCodexAspTranscriptStatus(status, failed = false) {
2804
2813
  if (failed || status === "failed" || status === "declined") return "failed";
2805
2814
  if (status === "completed") return "completed";
@@ -2817,6 +2826,20 @@ function imageContentToUserMessageImages(images) {
2817
2826
  }
2818
2827
  return userImages.length > 0 ? userImages : void 0;
2819
2828
  }
2829
+ function createAcceptedUserMessageEvent(message, messageId, timestamp, images) {
2830
+ const eventImages = imageContentToUserMessageImages(images);
2831
+ return {
2832
+ timestamp,
2833
+ type: "event_msg",
2834
+ payload: {
2835
+ type: "user_message",
2836
+ message,
2837
+ source: ACCEPTED_USER_MESSAGE_SOURCE,
2838
+ [USER_MESSAGE_ID_PAYLOAD_KEY]: messageId,
2839
+ ...eventImages ? { images: eventImages } : {}
2840
+ }
2841
+ };
2842
+ }
2820
2843
  function isCodexAspTranscript(value) {
2821
2844
  if (!isRecord(value)) return false;
2822
2845
  return typeof value.threadId === "string" && typeof value.updatedAt === "string" && Array.isArray(value.turns);
@@ -3207,6 +3230,22 @@ function safeJsonParse(str, fallback) {
3207
3230
  }
3208
3231
  }
3209
3232
 
3233
+ // ../shared/src/display-message/parsers/utils.ts
3234
+ function userMessageImages(value) {
3235
+ if (!Array.isArray(value)) return void 0;
3236
+ const images = value.filter((item) => isRecord(item) && item.type === "image" && typeof item.mediaType === "string" && typeof item.data === "string");
3237
+ return images.length > 0 ? images : void 0;
3238
+ }
3239
+ function stringifyDisplayValue(value) {
3240
+ if (value === void 0 || value === null) return void 0;
3241
+ if (typeof value === "string") return value;
3242
+ try {
3243
+ return JSON.stringify(value, null, 2);
3244
+ } catch {
3245
+ return String(value);
3246
+ }
3247
+ }
3248
+
3210
3249
  // ../shared/src/display-message/parsers/codex-parser.ts
3211
3250
  function getStatusFromExitCode(exitCode) {
3212
3251
  return exitCode === 0 ? "completed" : "failed";
@@ -3219,14 +3258,6 @@ function displayId(event, eventIndex, prefix) {
3219
3258
  const stableId = getPayloadString(event, USER_MESSAGE_ID_PAYLOAD_KEY) ?? getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY);
3220
3259
  return stableId ? `${prefix}-${stableId}` : `${prefix}-${event.timestamp}-${eventIndex}`;
3221
3260
  }
3222
- function userMessageImages(value) {
3223
- if (!Array.isArray(value)) return void 0;
3224
- const images = value.filter((item) => {
3225
- if (!isRecord(item)) return false;
3226
- return item.type === "image" && typeof item.mediaType === "string" && typeof item.data === "string";
3227
- });
3228
- return images.length > 0 ? images : void 0;
3229
- }
3230
3261
  function parseShellOutput(raw) {
3231
3262
  const exitCodeMatch = raw.match(/^Exit code: (\d+)/m) || raw.match(/Process exited with code (\d+)/);
3232
3263
  const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
@@ -3450,17 +3481,6 @@ function parseCodexEvents(events) {
3450
3481
  return messages;
3451
3482
  }
3452
3483
 
3453
- // ../shared/src/display-message/parsers/utils.ts
3454
- function stringifyDisplayValue(value) {
3455
- if (value === void 0 || value === null) return void 0;
3456
- if (typeof value === "string") return value;
3457
- try {
3458
- return JSON.stringify(value, null, 2);
3459
- } catch {
3460
- return String(value);
3461
- }
3462
- }
3463
-
3464
3484
  // ../shared/src/display-message/parsers/cursor-parser.ts
3465
3485
  function getTextContent(value) {
3466
3486
  if (!Array.isArray(value)) return "";
@@ -4021,6 +4041,7 @@ function parseClaudeEvents(events, parentToolUseId) {
4021
4041
  let liveStreamId = null;
4022
4042
  const assistantThinking = /* @__PURE__ */ new Map();
4023
4043
  const assistantTextCounts = /* @__PURE__ */ new Map();
4044
+ const acceptedUserMessageIndexes = /* @__PURE__ */ new Set();
4024
4045
  const taskAccumulator = new TaskAccumulator();
4025
4046
  const taskSnapshot = () => taskAccumulator.getTasks().map((task) => ({
4026
4047
  text: task.subject,
@@ -4028,6 +4049,21 @@ function parseClaudeEvents(events, parentToolUseId) {
4028
4049
  itemStatus: task.status
4029
4050
  }));
4030
4051
  filteredEvents.forEach((event) => {
4052
+ if (event.type === "event_msg" && event.payload.type === "user_message") {
4053
+ const content = typeof event.payload.message === "string" ? event.payload.message : "";
4054
+ const images = userMessageImages(event.payload.images);
4055
+ if (content || images) {
4056
+ const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
4057
+ acceptedUserMessageIndexes.add(messages.push({
4058
+ id: typeof messageId === "string" ? messageId : `user-${event.timestamp}`,
4059
+ type: "user",
4060
+ content,
4061
+ images,
4062
+ timestamp: event.timestamp
4063
+ }) - 1);
4064
+ }
4065
+ return;
4066
+ }
4031
4067
  if (event.type === CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE) {
4032
4068
  const payload = coerceClaudePartialMessagePayload(event.payload);
4033
4069
  if (!payload) return;
@@ -4085,13 +4121,24 @@ function parseClaudeEvents(events, parentToolUseId) {
4085
4121
  };
4086
4122
  }).filter((img) => img.data);
4087
4123
  if (textContent || images.length > 0) {
4088
- messages.push({
4089
- id: `user-${event.timestamp}`,
4124
+ const acceptedIndex = [...acceptedUserMessageIndexes].find((index) => {
4125
+ const accepted2 = messages[index];
4126
+ return accepted2?.type === "user" && accepted2.content === textContent;
4127
+ });
4128
+ const accepted = acceptedIndex === void 0 ? void 0 : messages[acceptedIndex];
4129
+ const message = {
4130
+ id: accepted?.id ?? `user-${event.timestamp}`,
4090
4131
  type: "user",
4091
4132
  content: textContent || (images.length > 0 ? `[${images.length} image${images.length > 1 ? "s" : ""} attached]` : ""),
4092
- images: images.length > 0 ? images : void 0,
4133
+ images: images.length > 0 ? images : accepted?.type === "user" ? accepted.images : void 0,
4093
4134
  timestamp: event.timestamp
4094
- });
4135
+ };
4136
+ if (acceptedIndex === void 0) {
4137
+ messages.push(message);
4138
+ } else {
4139
+ messages[acceptedIndex] = message;
4140
+ acceptedUserMessageIndexes.delete(acceptedIndex);
4141
+ }
4095
4142
  }
4096
4143
  }
4097
4144
  if (event.type === "claude-assistant") {
@@ -7610,11 +7657,11 @@ var MessageQueueService = class {
7610
7657
  position: this.queue.length
7611
7658
  };
7612
7659
  }
7613
- const messageId = this.generateMessageId();
7660
+ const messageId = request.messageId ?? this.generateMessageId();
7614
7661
  const queuedMessage = {
7615
7662
  id: messageId,
7616
7663
  ...request,
7617
- queuedAt: (/* @__PURE__ */ new Date()).toISOString()
7664
+ queuedAt: request.submittedAt ?? (/* @__PURE__ */ new Date()).toISOString()
7618
7665
  };
7619
7666
  if (this.processing) {
7620
7667
  this.queue.push(queuedMessage);
@@ -9785,7 +9832,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
9785
9832
  var MIN_CODEX_CLI_VERSION = "0.144.6";
9786
9833
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
9787
9834
  var codexCliVersionEnsured = null;
9788
- var ENGINE_PACKAGE_VERSION = "0.1.468";
9835
+ var ENGINE_PACKAGE_VERSION = "0.1.470";
9789
9836
  var INITIALIZE_METHOD = "initialize";
9790
9837
  var INITIALIZED_NOTIFICATION = "initialized";
9791
9838
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -12310,7 +12357,7 @@ import { delimiter, dirname as dirname6, join as join18 } from "path";
12310
12357
  import { randomBytes as randomBytes2 } from "crypto";
12311
12358
  import { fileURLToPath } from "url";
12312
12359
  import { Agent } from "undici";
12313
- import { z as z2 } from "zod";
12360
+ import { z as z3 } from "zod";
12314
12361
  import {
12315
12362
  createOpencodeClient,
12316
12363
  createOpencodeServer
@@ -12347,9 +12394,9 @@ var OPENCODE_VARIANT_CANDIDATES_BY_THINKING_LEVEL = {
12347
12394
  ultra: ["max", "xhigh", "high"],
12348
12395
  ultracode: ["max", "xhigh", "high"]
12349
12396
  };
12350
- var opencodeAuthSchema = z2.record(z2.string(), z2.object({
12351
- type: z2.string().optional(),
12352
- key: z2.string().optional()
12397
+ var opencodeAuthSchema = z3.record(z3.string(), z3.object({
12398
+ type: z3.string().optional(),
12399
+ key: z3.string().optional()
12353
12400
  }));
12354
12401
  async function hasOpenCodeGoCredentials() {
12355
12402
  if (!existsSync7(OPENCODE_AUTH_PATH2)) return false;
@@ -13041,7 +13088,7 @@ import {
13041
13088
  ModelRegistry,
13042
13089
  SessionManager,
13043
13090
  DefaultResourceLoader
13044
- } from "@mariozechner/pi-coding-agent";
13091
+ } from "@earendil-works/pi-coding-agent";
13045
13092
  function eventPayload(event) {
13046
13093
  return isRecord4(event) ? { ...event } : { value: event };
13047
13094
  }
@@ -13194,7 +13241,7 @@ var PiManager = class extends CodingAgentManager {
13194
13241
 
13195
13242
  // src/managers/relay-tools.ts
13196
13243
  import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
13197
- import { z as z3 } from "zod";
13244
+ import { z as z4 } from "zod";
13198
13245
 
13199
13246
  // src/managers/relay-providers.ts
13200
13247
  function isRelaySubagentProviderAllowed(provider, allowedProviders) {
@@ -13309,7 +13356,7 @@ function buildSpawnAgentTool(parentChatId, availability = {}, getAllowedProvider
13309
13356
  const cursorAvailable = availability.cursorAvailable ?? false;
13310
13357
  const opencodeAvailable = availability.opencodeAvailable ?? false;
13311
13358
  const availableProviders = getAvailableRelayProviders(availability);
13312
- const providerEnum = z3.enum(availableProviders);
13359
+ const providerEnum = z4.enum(availableProviders);
13313
13360
  const codeProviders = getAvailableCodeProviders(availability);
13314
13361
  const providerDesc = codeProviders.length > 0 ? `Which agent to use. Prefer ${codeProviders.join(" or ")} for code writing, claude for exploration/analysis, relay for complex multi-step orchestration.` : "Which agent to use. Use claude for code writing, exploration, and analysis. Use relay for complex multi-step orchestration.";
13315
13362
  const useCases = codeProviders.length > 0 ? `- Complex code writing tasks (use provider '${codeProviders.join("' or '")}' with a capable model)
@@ -13328,18 +13375,18 @@ The tool blocks until the subagent completes and returns its final response.
13328
13375
  You will also receive the chatId so you can send follow-up messages or clean up the chat.`,
13329
13376
  {
13330
13377
  provider: providerEnum.describe(providerDesc),
13331
- prompt: z3.string().describe("The full prompt/instructions for the subagent. Be detailed - it has no context from your conversation."),
13332
- model: z3.string().optional().describe([
13378
+ prompt: z4.string().describe("The full prompt/instructions for the subagent. Be detailed - it has no context from your conversation."),
13379
+ model: z4.string().optional().describe([
13333
13380
  `Model override. Claude: ${AGENT_MODELS.claude.join(", ")} (opus is the default; sonnet is faster).`,
13334
13381
  codexAvailable ? `Codex: ${AGENT_MODELS.codex.join(", ")}.` : null,
13335
13382
  cursorAvailable ? `Cursor: ${AGENT_MODELS.cursor.join(", ")}.` : null,
13336
13383
  opencodeAvailable ? `Opencode: ${AGENT_MODELS.opencode.join(", ")}.` : null
13337
13384
  ].filter(Boolean).join(" ")),
13338
- thinking_level: z3.enum(VALID_THINKING_LEVELS).optional().describe(
13385
+ thinking_level: z4.enum(VALID_THINKING_LEVELS).optional().describe(
13339
13386
  "Controls how much thinking/reasoning the subagent applies. low = light thinking, medium = moderate, high = deep reasoning, xhigh = extended effort, max = maximum effort, ultra = Codex ultra, ultracode = Claude Code dynamic workflows. Defaults: Claude = high, Codex = medium, Cursor = medium, Opencode = medium."
13340
13387
  ),
13341
- title: z3.string().optional().describe("Optional title for the subagent chat (for identification)."),
13342
- timeout_minutes: z3.number().positive().optional().describe("Timeout in minutes for the subagent to complete (default: 10). Set higher for large tasks to avoid losing work.")
13388
+ title: z4.string().optional().describe("Optional title for the subagent chat (for identification)."),
13389
+ timeout_minutes: z4.number().positive().optional().describe("Timeout in minutes for the subagent to complete (default: 10). Set higher for large tasks to avoid losing work.")
13343
13390
  },
13344
13391
  async (args) => {
13345
13392
  try {
@@ -13414,13 +13461,13 @@ var messageAgentTool = tool(
13414
13461
 
13415
13462
  The tool blocks until the subagent completes and returns its response.`,
13416
13463
  {
13417
- chatId: z3.string().describe("The chat ID of the subagent (returned by spawn_agent)."),
13418
- message: z3.string().describe("The follow-up message to send."),
13419
- model: z3.string().optional().describe("Optional model override for this message."),
13420
- thinking_level: z3.enum(VALID_THINKING_LEVELS).optional().describe(
13464
+ chatId: z4.string().describe("The chat ID of the subagent (returned by spawn_agent)."),
13465
+ message: z4.string().describe("The follow-up message to send."),
13466
+ model: z4.string().optional().describe("Optional model override for this message."),
13467
+ thinking_level: z4.enum(VALID_THINKING_LEVELS).optional().describe(
13421
13468
  "Controls how much thinking/reasoning the subagent applies. low = light thinking, medium = moderate, high = deep reasoning, xhigh = extended effort, max = maximum effort, ultra = Codex ultra, ultracode = Claude Code dynamic workflows. Defaults: Claude = high, Codex = medium, Cursor = medium, Opencode = medium."
13422
13469
  ),
13423
- timeout_minutes: z3.number().positive().optional().describe("Timeout in minutes for the subagent to complete (default: 10). Set higher for large tasks to avoid losing work.")
13470
+ timeout_minutes: z4.number().positive().optional().describe("Timeout in minutes for the subagent to complete (default: 10). Set higher for large tasks to avoid losing work.")
13424
13471
  },
13425
13472
  async (args) => {
13426
13473
  try {
@@ -13458,7 +13505,7 @@ var deleteAgentTool = tool(
13458
13505
  "delete_agent",
13459
13506
  `Delete a subagent chat to free resources. Use this after a subagent has completed its work and you no longer need to send it follow-up messages.`,
13460
13507
  {
13461
- chatId: z3.string().describe("The chat ID of the subagent to delete.")
13508
+ chatId: z4.string().describe("The chat ID of the subagent to delete.")
13462
13509
  },
13463
13510
  async (args) => {
13464
13511
  try {
@@ -14234,7 +14281,11 @@ function normalizePersistedChat(chat) {
14234
14281
  providerSessionId: isLegacyCodexSdkChat ? null : chat.providerSessionId,
14235
14282
  parentChatId: chat.parentChatId ?? null,
14236
14283
  lastMessageText: chat.lastMessageText ?? null,
14237
- deletedAt: chat.deletedAt ?? null
14284
+ deletedAt: chat.deletedAt ?? null,
14285
+ acceptedSendResponses: isRecord4(chat.acceptedSendResponses) ? Object.fromEntries(Object.entries(chat.acceptedSendResponses).filter((entry) => {
14286
+ const response = entry[1];
14287
+ return isRecord4(response) && typeof response.messageId === "string" && typeof response.queued === "boolean" && typeof response.position === "number";
14288
+ })) : {}
14238
14289
  };
14239
14290
  }
14240
14291
  function parsePersistedChatsContent(content) {
@@ -14247,20 +14298,6 @@ function parsePersistedChatsContent(content) {
14247
14298
  function corruptChatsFilePath() {
14248
14299
  return `${CHATS_FILE}.corrupt-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
14249
14300
  }
14250
- function createUserMessageEvent(message, messageId, images) {
14251
- const eventImages = imageContentToUserMessageImages(images);
14252
- return {
14253
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
14254
- type: "event_msg",
14255
- payload: {
14256
- type: "user_message",
14257
- message,
14258
- source: ACCEPTED_USER_MESSAGE_SOURCE,
14259
- [USER_MESSAGE_ID_PAYLOAD_KEY]: messageId,
14260
- ...eventImages ? { images: eventImages } : {}
14261
- }
14262
- };
14263
- }
14264
14301
  var ChatService = class {
14265
14302
  constructor(workingDirectory) {
14266
14303
  this.workingDirectory = workingDirectory;
@@ -14323,17 +14360,30 @@ var ChatService = class {
14323
14360
  };
14324
14361
  }
14325
14362
  async createChat(request) {
14326
- const now = (/* @__PURE__ */ new Date()).toISOString();
14363
+ const now = request.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
14327
14364
  const title = request.title?.trim() || `${request.provider} chat`;
14328
- if (isDefaultChat({ provider: request.provider, title }) && Array.from(this.chats.values()).some((chat) => !chat.persisted.deletedAt && chat.persisted.provider === request.provider && isDefaultChat(chat.persisted))) {
14329
- throw new DuplicateDefaultChatError(request.provider);
14365
+ if (request.id) {
14366
+ const existing = this.chats.get(request.id);
14367
+ if (existing && !existing.persisted.deletedAt) {
14368
+ if (existing.persisted.provider !== request.provider) {
14369
+ throw new Error(`Chat ${request.id} already exists with a different provider`);
14370
+ }
14371
+ return this.toSummary(existing);
14372
+ }
14373
+ }
14374
+ const existingDefault = isDefaultChat({ provider: request.provider, title }) ? Array.from(this.chats.values()).find((chat) => !chat.persisted.deletedAt && chat.persisted.provider === request.provider && isDefaultChat(chat.persisted)) : void 0;
14375
+ if (existingDefault) {
14376
+ if (!request.id || hasChatStarted(this.toSummary(existingDefault))) {
14377
+ throw new DuplicateDefaultChatError(request.provider);
14378
+ }
14379
+ this.chats.delete(existingDefault.persisted.id);
14330
14380
  }
14331
14381
  const parentChatId = request.parentChatId ?? null;
14332
14382
  if (parentChatId && !this.chats.has(parentChatId)) {
14333
14383
  throw new ChatNotFoundError(parentChatId);
14334
14384
  }
14335
14385
  const persisted = {
14336
- id: randomUUID5(),
14386
+ id: request.id ?? randomUUID5(),
14337
14387
  provider: request.provider,
14338
14388
  title,
14339
14389
  createdAt: now,
@@ -14368,8 +14418,14 @@ var ChatService = class {
14368
14418
  if (chat.acceptedSendResponses.size <= MAX_ACCEPTED_SEND_RESPONSES) break;
14369
14419
  chat.acceptedSendResponses.delete(key);
14370
14420
  }
14421
+ chat.persisted.acceptedSendResponses = Object.fromEntries(chat.acceptedSendResponses);
14371
14422
  }
14372
- const acceptedEvent = createUserMessageEvent(request.message, result.messageId, request.images);
14423
+ const acceptedEvent = createAcceptedUserMessageEvent(
14424
+ request.message,
14425
+ result.messageId,
14426
+ request.submittedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
14427
+ request.images
14428
+ );
14373
14429
  chat.pendingMessageIds.push(result.messageId);
14374
14430
  if (request.errorNotificationTarget) {
14375
14431
  chat.errorNotificationTargets.set(result.messageId, request.errorNotificationTarget);
@@ -14384,7 +14440,7 @@ var ChatService = class {
14384
14440
  senderEmail: request.senderEmail,
14385
14441
  ...request.senderDisplayName ? { senderDisplayName: request.senderDisplayName } : {},
14386
14442
  ...request.senderAvatarUrl ? { senderAvatarUrl: request.senderAvatarUrl } : {},
14387
- recordedAt: (/* @__PURE__ */ new Date()).toISOString()
14443
+ recordedAt: request.submittedAt ?? (/* @__PURE__ */ new Date()).toISOString()
14388
14444
  };
14389
14445
  await this.appendSender(chatId, recordedSender);
14390
14446
  }
@@ -14736,7 +14792,7 @@ var ChatService = class {
14736
14792
  provider,
14737
14793
  pendingMessageIds: [],
14738
14794
  acceptedUserEvents: /* @__PURE__ */ new Map(),
14739
- acceptedSendResponses: /* @__PURE__ */ new Map(),
14795
+ acceptedSendResponses: new Map(Object.entries(persisted.acceptedSendResponses ?? {})),
14740
14796
  activeMessageId: null,
14741
14797
  hasActiveTurn: false,
14742
14798
  observedBranchesByRepo: /* @__PURE__ */ new Map(),
@@ -15275,7 +15331,7 @@ var RepoFileService = class {
15275
15331
 
15276
15332
  // src/v1-routes.ts
15277
15333
  import { Hono } from "hono";
15278
- import { z as z4 } from "zod";
15334
+ import { z as z5 } from "zod";
15279
15335
  import { readdir as readdir9, stat as stat5, readFile as readFile18 } from "fs/promises";
15280
15336
  import { join as join26, resolve as resolve3 } from "path";
15281
15337
 
@@ -15783,79 +15839,75 @@ var TerminalService = class {
15783
15839
  var terminalService = new TerminalService();
15784
15840
 
15785
15841
  // src/v1-routes.ts
15786
- var setWorkspaceNameSchema = z4.object({
15787
- name: z4.string().min(1).max(48)
15788
- });
15789
- var createChatSchema = z4.object({
15790
- provider: z4.enum(["claude", "codex", "cursor", "opencode", "pi", "relay"]),
15791
- title: z4.string().min(1).optional(),
15792
- parentChatId: z4.string().uuid().optional(),
15793
- clientRequestId: z4.string().min(1).max(128).optional()
15842
+ var setWorkspaceNameSchema = z5.object({
15843
+ name: z5.string().min(1).max(48)
15794
15844
  });
15795
- var imageMediaTypeSchema = z4.enum(IMAGE_MEDIA_TYPES);
15796
- var createPreviewSchema = z4.object({
15797
- port: z4.number().int().min(1).max(65535),
15798
- publicUrl: z4.string().min(1)
15845
+ var imageMediaTypeSchema = z5.enum(IMAGE_MEDIA_TYPES);
15846
+ var createPreviewSchema = z5.object({
15847
+ port: z5.number().int().min(1).max(65535),
15848
+ publicUrl: z5.string().min(1)
15799
15849
  });
15800
- var terminalSizeSchema = z4.object({
15801
- cols: z4.number().int().min(2).max(500),
15802
- rows: z4.number().int().min(1).max(200)
15850
+ var terminalSizeSchema = z5.object({
15851
+ cols: z5.number().int().min(2).max(500),
15852
+ rows: z5.number().int().min(1).max(200)
15803
15853
  });
15804
- var writeTerminalSessionSchema = z4.object({
15805
- data: z4.string().max(64 * 1024),
15806
- generation: z4.number().int().nonnegative(),
15807
- sequence: z4.number().int().nonnegative()
15854
+ var writeTerminalSessionSchema = z5.object({
15855
+ data: z5.string().max(64 * 1024),
15856
+ generation: z5.number().int().nonnegative(),
15857
+ sequence: z5.number().int().nonnegative()
15808
15858
  });
15809
- var sendMessageSchema = z4.object({
15810
- message: z4.string().min(1),
15811
- model: z4.string().optional(),
15812
- customInstructions: z4.string().optional(),
15813
- planMode: z4.boolean().optional(),
15814
- images: z4.array(z4.object({
15815
- type: z4.literal("image"),
15816
- source: z4.union([
15817
- z4.object({
15818
- type: z4.literal("base64"),
15859
+ var sendMessageSchema = z5.object({
15860
+ messageId: z5.string().min(1).optional(),
15861
+ submittedAt: z5.string().datetime().optional(),
15862
+ message: z5.string().min(1),
15863
+ model: z5.string().optional(),
15864
+ customInstructions: z5.string().optional(),
15865
+ planMode: z5.boolean().optional(),
15866
+ images: z5.array(z5.object({
15867
+ type: z5.literal("image"),
15868
+ source: z5.union([
15869
+ z5.object({
15870
+ type: z5.literal("base64"),
15819
15871
  media_type: imageMediaTypeSchema,
15820
- data: z4.string().min(1)
15872
+ data: z5.string().min(1)
15821
15873
  }),
15822
- z4.object({
15823
- type: z4.literal("url"),
15824
- url: z4.string().url()
15874
+ z5.object({
15875
+ type: z5.literal("url"),
15876
+ url: z5.string().url()
15825
15877
  })
15826
15878
  ])
15827
15879
  })).optional(),
15828
- thinkingLevel: z4.enum(VALID_THINKING_LEVELS).optional(),
15829
- goalMode: z4.boolean().optional(),
15830
- fastMode: z4.boolean().optional(),
15831
- enableInteractiveTools: z4.boolean().optional(),
15832
- type: z4.string().min(1).optional(),
15833
- merge: z4.boolean().optional(),
15834
- idempotencyKey: z4.string().min(1).max(128).optional(),
15835
- senderUserId: z4.string().optional(),
15836
- senderEmail: z4.string().optional(),
15837
- senderDisplayName: z4.string().optional(),
15838
- senderAvatarUrl: z4.string().optional(),
15839
- errorNotificationTarget: z4.discriminatedUnion("type", [
15840
- z4.object({ type: z4.literal("slack") }),
15841
- z4.object({ type: z4.literal("linear"), sessionId: z4.string().min(1) }),
15842
- z4.object({
15843
- type: z4.literal("code_host"),
15844
- provider: z4.enum(["github", "gitlab"]),
15845
- resource: z4.enum(["issue", "pull_request"]),
15846
- repositoryId: z4.string().min(1),
15847
- resourceNumber: z4.number().int().positive()
15880
+ thinkingLevel: z5.enum(VALID_THINKING_LEVELS).optional(),
15881
+ goalMode: z5.boolean().optional(),
15882
+ fastMode: z5.boolean().optional(),
15883
+ enableInteractiveTools: z5.boolean().optional(),
15884
+ type: z5.string().min(1).optional(),
15885
+ merge: z5.boolean().optional(),
15886
+ idempotencyKey: z5.string().min(1).max(128).optional(),
15887
+ senderUserId: z5.string().optional(),
15888
+ senderEmail: z5.string().optional(),
15889
+ senderDisplayName: z5.string().optional(),
15890
+ senderAvatarUrl: z5.string().optional(),
15891
+ errorNotificationTarget: z5.discriminatedUnion("type", [
15892
+ z5.object({ type: z5.literal("slack") }),
15893
+ z5.object({ type: z5.literal("linear"), sessionId: z5.string().min(1) }),
15894
+ z5.object({
15895
+ type: z5.literal("code_host"),
15896
+ provider: z5.enum(["github", "gitlab"]),
15897
+ resource: z5.enum(["issue", "pull_request"]),
15898
+ repositoryId: z5.string().min(1),
15899
+ resourceNumber: z5.number().int().positive()
15848
15900
  }),
15849
- z4.object({ type: z4.literal("automation"), executionId: z4.string().min(1) })
15901
+ z5.object({ type: z5.literal("automation"), executionId: z5.string().min(1) })
15850
15902
  ]).optional()
15851
15903
  });
15852
- var respondToolInputSchema = z4.object({
15853
- requestId: z4.string().min(1),
15854
- selectionId: z4.string().min(1)
15904
+ var respondToolInputSchema = z5.object({
15905
+ requestId: z5.string().min(1),
15906
+ selectionId: z5.string().min(1)
15855
15907
  });
15856
- var updateGoalSchema = z4.object({
15857
- objective: z4.string().trim().min(1).max(MAX_CODEX_GOAL_OBJECTIVE_CHARS).optional(),
15858
- status: z4.enum(["active", "paused"]).optional()
15908
+ var updateGoalSchema = z5.object({
15909
+ objective: z5.string().trim().min(1).max(MAX_CODEX_GOAL_OBJECTIVE_CHARS).optional(),
15910
+ status: z5.enum(["active", "paused"]).optional()
15859
15911
  }).refine((body) => body.objective !== void 0 || body.status !== void 0, {
15860
15912
  message: "Goal objective or status required"
15861
15913
  });
@@ -15937,7 +15989,7 @@ function createV1Routes(deps) {
15937
15989
  });
15938
15990
  app2.post("/chats", async (c) => {
15939
15991
  try {
15940
- const body = createChatSchema.parse(await c.req.json());
15992
+ const body = createChatRequestSchema.parse(await c.req.json());
15941
15993
  const chat = await deps.chatService.createChat(body);
15942
15994
  const response = { chat };
15943
15995
  return c.json(response, 201);
@@ -16046,7 +16098,7 @@ function createV1Routes(deps) {
16046
16098
  const result = await deps.chatService.updateGoal(c.req.param("chatId"), body);
16047
16099
  return c.json(result);
16048
16100
  } catch (error) {
16049
- if (error instanceof z4.ZodError) {
16101
+ if (error instanceof z5.ZodError) {
16050
16102
  return c.json(jsonError(error.issues[0]?.message || "Invalid goal update"), 400);
16051
16103
  }
16052
16104
  if (error instanceof ChatNotFoundError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.468",
3
+ "version": "0.1.470",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -35,8 +35,8 @@
35
35
  "@connectrpc/connect-node": "1.7.0",
36
36
  "@cursor/sdk": "1.0.19",
37
37
  "@hono/node-server": "^1.19.5",
38
- "@mariozechner/pi-ai": "0.73.1",
39
- "@mariozechner/pi-coding-agent": "0.73.1",
38
+ "@earendil-works/pi-ai": "0.79.10",
39
+ "@earendil-works/pi-coding-agent": "0.79.0",
40
40
  "@opencode-ai/sdk": "1.17.9",
41
41
  "hono": "^4.10.3",
42
42
  "opencode-ai": "1.17.9",