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.
- package/dist/src/index.js +76 -58
- 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
|
|
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
|
-
*
|
|
1088
|
-
*
|
|
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
|
|
1091
|
-
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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
|
|
1909
|
-
import { existsSync as
|
|
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 (!
|
|
1940
|
+
if (!existsSync4(PLANS_DIR)) {
|
|
1923
1941
|
await mkdir5(PLANS_DIR, { recursive: true });
|
|
1924
1942
|
}
|
|
1925
|
-
if (!
|
|
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 (
|
|
1947
|
-
return await
|
|
1964
|
+
if (existsSync4(replicasPath)) {
|
|
1965
|
+
return await readFile5(replicasPath, "utf-8");
|
|
1948
1966
|
}
|
|
1949
|
-
if (
|
|
1950
|
-
return await
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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.
|
|
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.
|
|
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": {
|