replicas-engine 0.1.32 → 0.1.33

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 +76 -58
  2. package/package.json +3 -2
package/dist/src/index.js CHANGED
@@ -5,7 +5,7 @@ import "./chunk-ZXMDA7VB.js";
5
5
  import "dotenv/config";
6
6
  import { serve } from "@hono/node-server";
7
7
  import { Hono as Hono4 } from "hono";
8
- import { readFile as readFile5 } from "fs/promises";
8
+ import { readFile as readFile6 } from "fs/promises";
9
9
  import { execSync as execSync2 } from "child_process";
10
10
 
11
11
  // src/middleware/auth.ts
@@ -86,7 +86,8 @@ async function readJSONLPaginated(filePath, limit, offset = 0) {
86
86
  }
87
87
 
88
88
  // src/services/codex-manager.ts
89
- import { readdir, stat, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
89
+ import { readdir, stat, writeFile as writeFile3, mkdir as mkdir3, readFile as readFile4 } from "fs/promises";
90
+ import { existsSync as existsSync3 } from "fs";
90
91
  import { join as join3 } from "path";
91
92
  import { homedir as homedir3 } from "os";
92
93
 
@@ -785,6 +786,14 @@ async function normalizeImages(images) {
785
786
  return normalized;
786
787
  }
787
788
 
789
+ // src/services/replicas-config.ts
790
+ import { readFile as readFile3, appendFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
791
+ import { existsSync as existsSync2 } from "fs";
792
+ import { join as join2 } from "path";
793
+ import { homedir as homedir2 } from "os";
794
+ import { exec } from "child_process";
795
+ import { promisify } from "util";
796
+
788
797
  // ../shared/src/sandbox.ts
789
798
  var SANDBOX_LIFECYCLE = {
790
799
  AUTO_STOP_MINUTES: 60,
@@ -795,7 +804,6 @@ var SANDBOX_LIFECYCLE = {
795
804
 
796
805
  // ../shared/src/prompts.ts
797
806
  var GENERAL_INSTRUCTIONS_TAG = "general_instructions";
798
- var CODEX_USER_INSTRUCTION_TAG = "user_instruction";
799
807
  function wrapInTag(content, tag) {
800
808
  return `<${tag}>
801
809
  ${content}
@@ -803,12 +811,6 @@ ${content}
803
811
  }
804
812
 
805
813
  // src/services/replicas-config.ts
806
- import { readFile as readFile3, appendFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
807
- import { existsSync as existsSync2 } from "fs";
808
- import { join as join2 } from "path";
809
- import { homedir as homedir2 } from "os";
810
- import { exec } from "child_process";
811
- import { promisify } from "util";
812
814
  var execAsync = promisify(exec);
813
815
  var START_HOOKS_LOG = join2(homedir2(), ".replicas", "startHooks.log");
814
816
  var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
@@ -1004,7 +1006,9 @@ Commands: ${hooks.length}
1004
1006
  var replicasConfigService = new ReplicasConfigService();
1005
1007
 
1006
1008
  // src/services/codex-manager.ts
1009
+ import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
1007
1010
  var DEFAULT_MODEL = "gpt-5.2-codex";
1011
+ var CODEX_CONFIG_PATH = join3(homedir3(), ".codex", "config.toml");
1008
1012
  var CodexManager = class {
1009
1013
  codex;
1010
1014
  currentThreadId = null;
@@ -1084,11 +1088,33 @@ var CodexManager = class {
1084
1088
  return START_HOOKS_RUNNING_PROMPT;
1085
1089
  }
1086
1090
  /**
1087
- * Legacy sendMessage method - now uses the queue internally
1088
- * @deprecated Use enqueueMessage for better control over queue status
1091
+ * Update the developer_instructions in ~/.codex/config.toml
1092
+ * This sets the system prompt that Codex will use for this turn
1089
1093
  */
1090
- async sendMessage(message, model, customInstructions, images, permissionMode) {
1091
- await this.enqueueMessage(message, model, customInstructions, images, permissionMode);
1094
+ async updateCodexConfig(developerInstructions) {
1095
+ try {
1096
+ const codexDir = join3(homedir3(), ".codex");
1097
+ await mkdir3(codexDir, { recursive: true });
1098
+ let config = {};
1099
+ if (existsSync3(CODEX_CONFIG_PATH)) {
1100
+ try {
1101
+ const existingContent = await readFile4(CODEX_CONFIG_PATH, "utf-8");
1102
+ config = parseToml(existingContent);
1103
+ } catch (parseError) {
1104
+ console.warn("[CodexManager] Failed to parse existing config.toml, starting fresh:", parseError);
1105
+ }
1106
+ }
1107
+ if (developerInstructions) {
1108
+ config.developer_instructions = developerInstructions;
1109
+ } else {
1110
+ delete config.developer_instructions;
1111
+ }
1112
+ const tomlContent = stringifyToml(config);
1113
+ await writeFile3(CODEX_CONFIG_PATH, tomlContent, "utf-8");
1114
+ console.log("[CodexManager] Updated config.toml with developer_instructions");
1115
+ } catch (error) {
1116
+ console.error("[CodexManager] Failed to update config.toml:", error);
1117
+ }
1092
1118
  }
1093
1119
  /**
1094
1120
  * Helper method to save normalized images to temp files for Codex SDK
@@ -1118,39 +1144,32 @@ var CodexManager = class {
1118
1144
  const normalizedImages = await normalizeImages(images);
1119
1145
  tempImagePaths = await this.saveImagesToTempFiles(normalizedImages);
1120
1146
  }
1147
+ const startHooksInstruction = this.getStartHooksInstruction();
1148
+ const parts = [];
1149
+ if (this.baseSystemPrompt) {
1150
+ parts.push(this.baseSystemPrompt);
1151
+ }
1152
+ if (startHooksInstruction) {
1153
+ parts.push(startHooksInstruction);
1154
+ }
1155
+ if (customInstructions) {
1156
+ parts.push(customInstructions);
1157
+ }
1158
+ const developerInstructions = parts.length > 0 ? parts.join("\n\n") : void 0;
1159
+ await this.updateCodexConfig(developerInstructions);
1121
1160
  const sandboxMode = "danger-full-access";
1161
+ const threadOptions = {
1162
+ workingDirectory: this.workingDirectory,
1163
+ skipGitRepoCheck: true,
1164
+ sandboxMode,
1165
+ model: model || DEFAULT_MODEL,
1166
+ webSearchMode: "live"
1167
+ };
1122
1168
  if (this.currentThreadId) {
1123
- this.currentThread = this.codex.resumeThread(this.currentThreadId, {
1124
- workingDirectory: this.workingDirectory,
1125
- skipGitRepoCheck: true,
1126
- sandboxMode,
1127
- model: model || DEFAULT_MODEL
1128
- });
1169
+ this.currentThread = this.codex.resumeThread(this.currentThreadId, threadOptions);
1129
1170
  } else {
1130
- this.currentThread = this.codex.startThread({
1131
- workingDirectory: this.workingDirectory,
1132
- skipGitRepoCheck: true,
1133
- sandboxMode,
1134
- model: model || DEFAULT_MODEL
1135
- });
1136
- const startHooksInstruction = this.getStartHooksInstruction();
1137
- const parts = [];
1138
- if (this.baseSystemPrompt) {
1139
- parts.push(this.baseSystemPrompt);
1140
- }
1141
- if (startHooksInstruction) {
1142
- parts.push(startHooksInstruction);
1143
- }
1144
- if (customInstructions) {
1145
- parts.push(customInstructions);
1146
- }
1147
- const combinedInstructions = parts.length > 0 ? parts.join("\n\n") : void 0;
1148
- if (combinedInstructions) {
1149
- message = combinedInstructions + "\n\n\n" + wrapInTag(message, CODEX_USER_INSTRUCTION_TAG);
1150
- } else {
1151
- message = wrapInTag(message, CODEX_USER_INSTRUCTION_TAG);
1152
- }
1153
- const { events: events2 } = await this.currentThread.runStreamed(wrapInTag("Hello", CODEX_USER_INSTRUCTION_TAG));
1171
+ this.currentThread = this.codex.startThread(threadOptions);
1172
+ const { events: events2 } = await this.currentThread.runStreamed("Hello");
1154
1173
  for await (const event of events2) {
1155
1174
  if (event.type === "thread.started") {
1156
1175
  this.currentThreadId = event.thread_id;
@@ -1164,16 +1183,15 @@ var CodexManager = class {
1164
1183
  console.log(`[CodexManager] Captured and persisted thread ID from thread.id: ${this.currentThreadId}`);
1165
1184
  }
1166
1185
  }
1167
- const wrappedMessage = this.currentThreadId && !message.includes(`<${CODEX_USER_INSTRUCTION_TAG}>`) ? wrapInTag(message, CODEX_USER_INSTRUCTION_TAG) : message;
1168
1186
  let input;
1169
1187
  if (tempImagePaths.length > 0) {
1170
1188
  const inputItems = [
1171
- { type: "text", text: wrappedMessage },
1189
+ { type: "text", text: message },
1172
1190
  ...tempImagePaths.map((path5) => ({ type: "local_image", path: path5 }))
1173
1191
  ];
1174
1192
  input = inputItems;
1175
1193
  } else {
1176
- input = wrappedMessage;
1194
+ input = message;
1177
1195
  }
1178
1196
  const { events } = await this.currentThread.runStreamed(input);
1179
1197
  let latestThoughtEvent = null;
@@ -1905,8 +1923,8 @@ var claude_default = claude;
1905
1923
  import { Hono as Hono3 } from "hono";
1906
1924
 
1907
1925
  // src/services/plans-service.ts
1908
- import { readFile as readFile4, readdir as readdir2, mkdir as mkdir5 } from "fs/promises";
1909
- import { existsSync as existsSync3 } from "fs";
1926
+ import { readFile as readFile5, readdir as readdir2, mkdir as mkdir5 } from "fs/promises";
1927
+ import { existsSync as existsSync4 } from "fs";
1910
1928
  import { join as join5, basename } from "path";
1911
1929
  import { homedir as homedir5 } from "os";
1912
1930
  var PLANS_DIR = join5(homedir5(), ".replicas", "plans");
@@ -1919,10 +1937,10 @@ function isValidFilename(filename) {
1919
1937
  return safePattern.test(filename);
1920
1938
  }
1921
1939
  async function ensurePlansDir() {
1922
- if (!existsSync3(PLANS_DIR)) {
1940
+ if (!existsSync4(PLANS_DIR)) {
1923
1941
  await mkdir5(PLANS_DIR, { recursive: true });
1924
1942
  }
1925
- if (!existsSync3(CLAUDE_PLANS_DIR)) {
1943
+ if (!existsSync4(CLAUDE_PLANS_DIR)) {
1926
1944
  await mkdir5(CLAUDE_PLANS_DIR, { recursive: true });
1927
1945
  }
1928
1946
  }
@@ -1943,11 +1961,11 @@ async function getPlanContent(filename) {
1943
1961
  const safeName = basename(filename);
1944
1962
  const replicasPath = join5(PLANS_DIR, safeName);
1945
1963
  const claudePath = join5(CLAUDE_PLANS_DIR, safeName);
1946
- if (existsSync3(replicasPath)) {
1947
- return await readFile4(replicasPath, "utf-8");
1964
+ if (existsSync4(replicasPath)) {
1965
+ return await readFile5(replicasPath, "utf-8");
1948
1966
  }
1949
- if (existsSync3(claudePath)) {
1950
- return await readFile4(claudePath, "utf-8");
1967
+ if (existsSync4(claudePath)) {
1968
+ return await readFile5(claudePath, "utf-8");
1951
1969
  }
1952
1970
  throw new Error("Plan not found");
1953
1971
  }
@@ -2254,7 +2272,7 @@ var CodexTokenManager = class {
2254
2272
  var codexTokenManager = new CodexTokenManager();
2255
2273
 
2256
2274
  // src/services/git-init.ts
2257
- import { existsSync as existsSync4 } from "fs";
2275
+ import { existsSync as existsSync5 } from "fs";
2258
2276
  import path4 from "path";
2259
2277
  var initializedBranch = null;
2260
2278
  function findAvailableBranchName(baseName, cwd) {
@@ -2290,7 +2308,7 @@ async function initializeGitRepository() {
2290
2308
  };
2291
2309
  }
2292
2310
  const repoPath = path4.join(workspaceHome, "workspaces", repoName);
2293
- if (!existsSync4(repoPath)) {
2311
+ if (!existsSync5(repoPath)) {
2294
2312
  console.log(`[GitInit] Repository directory does not exist: ${repoPath}`);
2295
2313
  console.log("[GitInit] Waiting for initializer to clone the repository...");
2296
2314
  return {
@@ -2298,7 +2316,7 @@ async function initializeGitRepository() {
2298
2316
  branch: null
2299
2317
  };
2300
2318
  }
2301
- if (!existsSync4(path4.join(repoPath, ".git"))) {
2319
+ if (!existsSync5(path4.join(repoPath, ".git"))) {
2302
2320
  return {
2303
2321
  success: false,
2304
2322
  branch: null,
@@ -2381,7 +2399,7 @@ function checkActiveSSHSessions() {
2381
2399
  var app = new Hono4();
2382
2400
  app.get("/health", async (c) => {
2383
2401
  try {
2384
- const logContent = await readFile5("/var/log/cloud-init-output.log", "utf-8");
2402
+ const logContent = await readFile6("/var/log/cloud-init-output.log", "utf-8");
2385
2403
  let status;
2386
2404
  if (logContent.includes(COMPLETION_MESSAGE)) {
2387
2405
  status = "active";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -28,9 +28,10 @@
28
28
  "dependencies": {
29
29
  "@anthropic-ai/claude-agent-sdk": "^0.1.30",
30
30
  "@hono/node-server": "^1.19.5",
31
- "@openai/codex-sdk": "^0.50.0",
31
+ "@openai/codex-sdk": "^0.88.0",
32
32
  "dotenv": "^17.2.3",
33
33
  "hono": "^4.10.3",
34
+ "smol-toml": "^1.6.0",
34
35
  "zod": "^3.25.0"
35
36
  },
36
37
  "devDependencies": {