replicas-engine 0.1.99 → 0.1.101

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 +56 -20
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -1091,7 +1091,7 @@ function parseReplicasConfigString(content, filename) {
1091
1091
  }
1092
1092
 
1093
1093
  // ../shared/src/engine/environment.ts
1094
- var DAYTONA_SNAPSHOT_ID = "13-04-2026-royal-york-v2";
1094
+ var DAYTONA_SNAPSHOT_ID = "13-04-2026-royal-york";
1095
1095
 
1096
1096
  // ../shared/src/engine/types.ts
1097
1097
  var DEFAULT_CHAT_TITLES = {
@@ -1643,6 +1643,7 @@ var PreviewService = class {
1643
1643
  var previewService = new PreviewService();
1644
1644
 
1645
1645
  // src/services/chat/chat-service.ts
1646
+ import { existsSync as existsSync7 } from "fs";
1646
1647
  import { mkdir as mkdir10, readFile as readFile8, rm, writeFile as writeFile8 } from "fs/promises";
1647
1648
  import { homedir as homedir9 } from "os";
1648
1649
  import { join as join11 } from "path";
@@ -3076,23 +3077,27 @@ async function getChatFinalResponse(chatId) {
3076
3077
  }
3077
3078
  return "[No response from subagent]";
3078
3079
  }
3079
- function buildSpawnAgentTool(parentChatId) {
3080
+ function buildSpawnAgentTool(parentChatId, codexAvailable = false) {
3081
+ const providerEnum = codexAvailable ? z.enum(["claude", "codex", "relay"]) : z.enum(["claude", "relay"]);
3082
+ const providerDesc = codexAvailable ? "Which agent to use. Prefer codex 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.";
3083
+ const useCases = codexAvailable ? `- Complex code writing tasks (use provider 'codex' with a capable model)
3084
+ - Codebase exploration that would consume many tokens (use provider 'claude')` : `- Complex code writing tasks (use provider 'claude')
3085
+ - Codebase exploration that would consume many tokens (use provider 'claude')`;
3080
3086
  return tool(
3081
3087
  "spawn_agent",
3082
3088
  `Spawn a new subagent to perform a task. The subagent runs in its own chat with a fresh context window.
3083
3089
 
3084
3090
  Use this for:
3085
- - Complex code writing tasks (use provider 'codex' with a capable model)
3086
- - Codebase exploration that would consume many tokens (use provider 'claude')
3091
+ ${useCases}
3087
3092
  - Browser testing, large test runs, or other token-heavy operations
3088
3093
  - Any task you want to delegate to preserve your own context
3089
3094
 
3090
3095
  The tool blocks until the subagent completes and returns its final response.
3091
3096
  You will also receive the chatId so you can send follow-up messages or clean up the chat.`,
3092
3097
  {
3093
- provider: z.enum(["claude", "codex", "relay"]).describe("Which agent to use. Prefer codex for code writing, claude for exploration/analysis, relay for complex multi-step orchestration."),
3098
+ provider: providerEnum.describe(providerDesc),
3094
3099
  prompt: z.string().describe("The full prompt/instructions for the subagent. Be detailed - it has no context from your conversation."),
3095
- model: z.string().optional().describe("Model override. Claude: opus, sonnet, haiku. Codex: gpt-5.4, gpt-5.3-codex, etc."),
3100
+ model: z.string().optional().describe(codexAvailable ? "Model override. Claude: opus, sonnet, haiku. Codex: gpt-5.4, gpt-5.3-codex, etc." : "Model override. Claude: opus, sonnet, haiku."),
3096
3101
  title: z.string().optional().describe("Optional title for the subagent chat (for identification)."),
3097
3102
  timeout_minutes: z.number().positive().optional().describe("Timeout in minutes for the subagent to complete (default: 10). Set higher for large tasks to avoid losing work.")
3098
3103
  },
@@ -3208,11 +3213,11 @@ var deleteAgentTool = tool(
3208
3213
  }
3209
3214
  }
3210
3215
  );
3211
- function createRelayMcpServer(parentChatId) {
3216
+ function createRelayMcpServer(parentChatId, codexAvailable = false) {
3212
3217
  return createSdkMcpServer({
3213
3218
  name: "relay-subagent-tools",
3214
3219
  version: "1.0.0",
3215
- tools: [buildSpawnAgentTool(parentChatId), messageAgentTool, deleteAgentTool]
3220
+ tools: [buildSpawnAgentTool(parentChatId, codexAvailable), messageAgentTool, deleteAgentTool]
3216
3221
  });
3217
3222
  }
3218
3223
 
@@ -3314,12 +3319,17 @@ function getUsingToolsSection() {
3314
3319
  ];
3315
3320
  return [`# Using your tools`, ...prependBullets(items)].join("\n");
3316
3321
  }
3317
- function getDelegationSection() {
3322
+ function getDelegationSection(codexAvailable) {
3323
+ const providerList = codexAvailable ? "claude, codex, or relay" : "claude or relay";
3324
+ const spawnDesc = `Create a new subagent with a specific provider (${providerList}), send it a prompt, and wait for its response. Returns the chatId and the agent's final response. You can set a custom timeout via the timeout_minutes parameter (default: 10 minutes).`;
3325
+ const agentSelectionLines = codexAvailable ? `Use provider 'codex' for heavy code writing, implementation, and large refactors. Suggested models: gpt-5.4 (default), gpt-5.3-codex.
3326
+
3327
+ Use provider 'claude' for codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: opus (default), sonnet (faster).` : `Use provider 'claude' for all tasks including code writing, codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: opus (default), sonnet (faster).`;
3318
3328
  return `# Delegation
3319
3329
 
3320
3330
  You have three subagent tools for spawning and managing agents that run in separate context windows:
3321
3331
 
3322
- - **spawn_agent**: Create a new subagent with a specific provider (claude or codex), send it a prompt, and wait for its response. Returns the chatId and the agent's final response. You can set a custom timeout via the timeout_minutes parameter (default: 10 minutes).
3332
+ - **spawn_agent**: ${spawnDesc}
3323
3333
  - **message_agent**: Send a follow-up message to an existing subagent by chatId. Use for iteration, corrections, or additional requests in the same context.
3324
3334
  - **delete_agent**: Delete a subagent chat when you no longer need it.
3325
3335
 
@@ -3339,7 +3349,15 @@ Your primary resource is your context window. Every tool call result, every code
3339
3349
 
3340
3350
  ## Parallel execution
3341
3351
 
3342
- You can spawn multiple subagents in parallel by making multiple spawn_agent tool calls in a single response. Do this whenever you have independent tasks \u2014 do NOT call them sequentially if they don't depend on each other. For example, if you need to test three endpoints, spawn three subagents in one response, not one after another.
3352
+ You can spawn multiple subagents in parallel by making multiple spawn_agent tool calls in a single response. Do this whenever you have truly independent tasks \u2014 do NOT call them sequentially if they don't depend on each other. For example, if you need to test three endpoints, spawn three subagents in one response, not one after another.
3353
+
3354
+ **IMPORTANT \u2014 recognize implicit dependencies:** Tasks are NOT independent when one task's output shapes what the other needs to know. The most common case: if you are building both a backend and a frontend, the frontend depends on the backend \u2014 it needs to know the API endpoints, request/response shapes, data models, etc. You MUST complete the backend subagent first, then use its output to write an informed prompt for the frontend subagent. Other examples of implicit dependencies:
3355
+ - Building a library/SDK and code that consumes it
3356
+ - Creating a database schema and code that queries it
3357
+ - Implementing an API and writing tests for that API
3358
+ - Any producer/consumer relationship where the consumer needs to match the producer's interface
3359
+
3360
+ When in doubt about whether tasks are independent, run them sequentially. The cost of unnecessary sequencing is just latency; the cost of incorrect parallelization is a subagent working blind and producing incompatible code.
3343
3361
 
3344
3362
  ## Testing your work
3345
3363
 
@@ -3357,9 +3375,20 @@ The default subagent timeout is 10 minutes. For tasks you expect to take longer
3357
3375
 
3358
3376
  ## Agent selection
3359
3377
 
3360
- Use provider 'codex' for heavy code writing, implementation, and large refactors. Suggested models: gpt-5.4 (default), gpt-5.3-codex.
3378
+ ${agentSelectionLines}
3379
+
3380
+ ## Incremental progress on complex tasks
3361
3381
 
3362
- Use provider 'claude' for codebase exploration, code review, planning, complex debugging, and tasks requiring nuanced architectural understanding. Suggested models: opus (default), sonnet (faster).
3382
+ For complex, multi-step tasks (building a full feature, large refactors, new systems), do NOT try to accomplish everything in one shot. Instead, take an incremental commits approach \u2014 work step by step, feature by feature, commit by commit.
3383
+
3384
+ **How to work incrementally:**
3385
+ - Break the task into discrete, meaningful steps (e.g., schema first, then API endpoints, then frontend, then tests).
3386
+ - After each step, commit the work in a clean state before moving on. By clean state, we mean the kind of code that is stable, does not introduce major bugs, the code is orderly and well-documented. A good rule of thumb is: could another agent or human pick up from this commit and continue building without having to clean up an unrelated mess?
3387
+ - Review the results of each step before starting the next. This lets you catch issues early, adjust course, and carry accurate context forward about what was already built.
3388
+
3389
+ **Why this matters:** Trying to build an entire system in one shot tends to produce lower-quality, harder-to-debug output. Incremental commits create natural checkpoints \u2014 if something goes wrong, you only lose one step's worth of work, not everything. This approach also preserves your context window since you track high-level progress without holding all the implementation details.
3390
+
3391
+ **When to use this:** Apply incremental progress for tasks that span multiple components, require many files to be changed, or would otherwise be a large, complex, time-consuming piece of work. For simple, self-contained tasks (a bug fix, a single endpoint, a small refactor), working in one pass is fine.
3363
3392
 
3364
3393
  ## Effective delegation
3365
3394
 
@@ -3412,14 +3441,15 @@ function getEnvironmentSection() {
3412
3441
  ...prependBullets(envItems.filter((x) => x !== null))
3413
3442
  ].join("\n");
3414
3443
  }
3415
- function buildRelaySystemPrompt(customInstructions) {
3444
+ function buildRelaySystemPrompt(options) {
3445
+ const { customInstructions, codexAvailable } = options ?? {};
3416
3446
  const sections = [
3417
3447
  getIntroSection(),
3418
3448
  getSystemSection(),
3419
3449
  getDoingTasksSection(),
3420
3450
  getActionsSection(),
3421
3451
  getUsingToolsSection(),
3422
- getDelegationSection(),
3452
+ getDelegationSection(codexAvailable ?? false),
3423
3453
  getToneAndStyleSection(),
3424
3454
  getOutputEfficiencySection(),
3425
3455
  getEnvironmentSection(),
@@ -3446,12 +3476,13 @@ var RELAY_TOOLS = [
3446
3476
  var RelayManager = class {
3447
3477
  inner;
3448
3478
  constructor(options) {
3479
+ const codexAvailable = options.codexAvailable ?? false;
3449
3480
  this.inner = new ClaudeManager({
3450
3481
  ...options,
3451
- systemPromptOverride: buildRelaySystemPrompt,
3482
+ systemPromptOverride: (customInstructions) => buildRelaySystemPrompt({ customInstructions, codexAvailable }),
3452
3483
  tools: RELAY_TOOLS,
3453
3484
  mcpServers: {
3454
- "relay-subagent-tools": createRelayMcpServer(options.chatId)
3485
+ "relay-subagent-tools": createRelayMcpServer(options.chatId, codexAvailable)
3455
3486
  },
3456
3487
  envOverrides: {
3457
3488
  CLAUDE_CODE_STREAM_CLOSE_TIMEOUT: "900000"
@@ -3550,6 +3581,10 @@ var ENGINE_DIR2 = join11(homedir9(), ".replicas", "engine");
3550
3581
  var CHATS_FILE = join11(ENGINE_DIR2, "chats.json");
3551
3582
  var CLAUDE_HISTORY_DIR = join11(ENGINE_DIR2, "claude-histories");
3552
3583
  var RELAY_HISTORY_DIR = join11(ENGINE_DIR2, "relay-histories");
3584
+ var CODEX_AUTH_PATH2 = join11(homedir9(), ".codex", "auth.json");
3585
+ function isCodexAvailable() {
3586
+ return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
3587
+ }
3553
3588
  function isPersistedChat(value) {
3554
3589
  if (!isRecord(value)) {
3555
3590
  return false;
@@ -3761,7 +3796,8 @@ var ChatService = class {
3761
3796
  onSaveSessionId: saveSession,
3762
3797
  onTurnComplete: onProviderTurnComplete,
3763
3798
  onEvent: onProviderEvent,
3764
- chatId: persisted.id
3799
+ chatId: persisted.id,
3800
+ codexAvailable: isCodexAvailable()
3765
3801
  });
3766
3802
  } else {
3767
3803
  provider = new CodexManager({
@@ -3972,7 +4008,7 @@ var planService = new PlanService();
3972
4008
  import { execFile as execFile2 } from "child_process";
3973
4009
  import { promisify as promisify3 } from "util";
3974
4010
  import { readFile as readFile11 } from "fs/promises";
3975
- import { existsSync as existsSync7 } from "fs";
4011
+ import { existsSync as existsSync8 } from "fs";
3976
4012
  import { join as join14 } from "path";
3977
4013
 
3978
4014
  // src/services/warm-hook-logs-service.ts
@@ -4074,7 +4110,7 @@ async function executeHookScript(params) {
4074
4110
  async function readRepoWarmHook(repoPath) {
4075
4111
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
4076
4112
  const configPath = join14(repoPath, filename);
4077
- if (!existsSync7(configPath)) {
4113
+ if (!existsSync8(configPath)) {
4078
4114
  continue;
4079
4115
  }
4080
4116
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.99",
3
+ "version": "0.1.101",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",