replicas-engine 0.1.32 → 0.1.34
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
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;
|
|
@@ -1637,6 +1655,8 @@ var ClaudeManager = class {
|
|
|
1637
1655
|
cwd: this.workingDirectory,
|
|
1638
1656
|
permissionMode: permissionMode === "read" ? "plan" : "bypassPermissions",
|
|
1639
1657
|
allowDangerouslySkipPermissions: permissionMode !== "read",
|
|
1658
|
+
// Disable tools that require user input - this is a background agent
|
|
1659
|
+
disallowedTools: ["ExitPlanMode", "AskUserQuestion"],
|
|
1640
1660
|
settingSources: ["user", "project", "local"],
|
|
1641
1661
|
systemPrompt: {
|
|
1642
1662
|
type: "preset",
|
|
@@ -1905,8 +1925,8 @@ var claude_default = claude;
|
|
|
1905
1925
|
import { Hono as Hono3 } from "hono";
|
|
1906
1926
|
|
|
1907
1927
|
// src/services/plans-service.ts
|
|
1908
|
-
import { readFile as
|
|
1909
|
-
import { existsSync as
|
|
1928
|
+
import { readFile as readFile5, readdir as readdir2, mkdir as mkdir5 } from "fs/promises";
|
|
1929
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1910
1930
|
import { join as join5, basename } from "path";
|
|
1911
1931
|
import { homedir as homedir5 } from "os";
|
|
1912
1932
|
var PLANS_DIR = join5(homedir5(), ".replicas", "plans");
|
|
@@ -1919,10 +1939,10 @@ function isValidFilename(filename) {
|
|
|
1919
1939
|
return safePattern.test(filename);
|
|
1920
1940
|
}
|
|
1921
1941
|
async function ensurePlansDir() {
|
|
1922
|
-
if (!
|
|
1942
|
+
if (!existsSync4(PLANS_DIR)) {
|
|
1923
1943
|
await mkdir5(PLANS_DIR, { recursive: true });
|
|
1924
1944
|
}
|
|
1925
|
-
if (!
|
|
1945
|
+
if (!existsSync4(CLAUDE_PLANS_DIR)) {
|
|
1926
1946
|
await mkdir5(CLAUDE_PLANS_DIR, { recursive: true });
|
|
1927
1947
|
}
|
|
1928
1948
|
}
|
|
@@ -1930,7 +1950,7 @@ async function listPlans() {
|
|
|
1930
1950
|
await ensurePlansDir();
|
|
1931
1951
|
try {
|
|
1932
1952
|
const files = [...await readdir2(PLANS_DIR), ...await readdir2(CLAUDE_PLANS_DIR)];
|
|
1933
|
-
return files.filter((file) => file
|
|
1953
|
+
return files.filter((file) => isValidFilename(file)).sort((a, b) => a.localeCompare(b));
|
|
1934
1954
|
} catch {
|
|
1935
1955
|
return [];
|
|
1936
1956
|
}
|
|
@@ -1943,11 +1963,11 @@ async function getPlanContent(filename) {
|
|
|
1943
1963
|
const safeName = basename(filename);
|
|
1944
1964
|
const replicasPath = join5(PLANS_DIR, safeName);
|
|
1945
1965
|
const claudePath = join5(CLAUDE_PLANS_DIR, safeName);
|
|
1946
|
-
if (
|
|
1947
|
-
return await
|
|
1966
|
+
if (existsSync4(replicasPath)) {
|
|
1967
|
+
return await readFile5(replicasPath, "utf-8");
|
|
1948
1968
|
}
|
|
1949
|
-
if (
|
|
1950
|
-
return await
|
|
1969
|
+
if (existsSync4(claudePath)) {
|
|
1970
|
+
return await readFile5(claudePath, "utf-8");
|
|
1951
1971
|
}
|
|
1952
1972
|
throw new Error("Plan not found");
|
|
1953
1973
|
}
|
|
@@ -2254,7 +2274,7 @@ var CodexTokenManager = class {
|
|
|
2254
2274
|
var codexTokenManager = new CodexTokenManager();
|
|
2255
2275
|
|
|
2256
2276
|
// src/services/git-init.ts
|
|
2257
|
-
import { existsSync as
|
|
2277
|
+
import { existsSync as existsSync5 } from "fs";
|
|
2258
2278
|
import path4 from "path";
|
|
2259
2279
|
var initializedBranch = null;
|
|
2260
2280
|
function findAvailableBranchName(baseName, cwd) {
|
|
@@ -2290,7 +2310,7 @@ async function initializeGitRepository() {
|
|
|
2290
2310
|
};
|
|
2291
2311
|
}
|
|
2292
2312
|
const repoPath = path4.join(workspaceHome, "workspaces", repoName);
|
|
2293
|
-
if (!
|
|
2313
|
+
if (!existsSync5(repoPath)) {
|
|
2294
2314
|
console.log(`[GitInit] Repository directory does not exist: ${repoPath}`);
|
|
2295
2315
|
console.log("[GitInit] Waiting for initializer to clone the repository...");
|
|
2296
2316
|
return {
|
|
@@ -2298,7 +2318,7 @@ async function initializeGitRepository() {
|
|
|
2298
2318
|
branch: null
|
|
2299
2319
|
};
|
|
2300
2320
|
}
|
|
2301
|
-
if (!
|
|
2321
|
+
if (!existsSync5(path4.join(repoPath, ".git"))) {
|
|
2302
2322
|
return {
|
|
2303
2323
|
success: false,
|
|
2304
2324
|
branch: null,
|
|
@@ -2381,7 +2401,7 @@ function checkActiveSSHSessions() {
|
|
|
2381
2401
|
var app = new Hono4();
|
|
2382
2402
|
app.get("/health", async (c) => {
|
|
2383
2403
|
try {
|
|
2384
|
-
const logContent = await
|
|
2404
|
+
const logContent = await readFile6("/var/log/cloud-init-output.log", "utf-8");
|
|
2385
2405
|
let status;
|
|
2386
2406
|
if (logContent.includes(COMPLETION_MESSAGE)) {
|
|
2387
2407
|
status = "active";
|
|
@@ -167,8 +167,8 @@ var require_utils = __commonJS({
|
|
|
167
167
|
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));
|
|
168
168
|
}
|
|
169
169
|
};
|
|
170
|
-
module.exports.wrapperSymbol = Symbol("wrapper");
|
|
171
|
-
module.exports.implSymbol = Symbol("impl");
|
|
170
|
+
module.exports.wrapperSymbol = /* @__PURE__ */ Symbol("wrapper");
|
|
171
|
+
module.exports.implSymbol = /* @__PURE__ */ Symbol("impl");
|
|
172
172
|
module.exports.wrapperForImpl = function(impl) {
|
|
173
173
|
return impl[module.exports.wrapperSymbol];
|
|
174
174
|
};
|
|
@@ -361,7 +361,7 @@ var require_url_state_machine = __commonJS({
|
|
|
361
361
|
ws: 80,
|
|
362
362
|
wss: 443
|
|
363
363
|
};
|
|
364
|
-
var failure = Symbol("failure");
|
|
364
|
+
var failure = /* @__PURE__ */ Symbol("failure");
|
|
365
365
|
function countSymbols(str) {
|
|
366
366
|
return punycode.ucs2.decode(str).length;
|
|
367
367
|
}
|
|
@@ -1787,8 +1787,8 @@ var require_lib2 = __commonJS({
|
|
|
1787
1787
|
var https = _interopDefault(__require("https"));
|
|
1788
1788
|
var zlib = _interopDefault(__require("zlib"));
|
|
1789
1789
|
var Readable = Stream.Readable;
|
|
1790
|
-
var BUFFER = Symbol("buffer");
|
|
1791
|
-
var TYPE = Symbol("type");
|
|
1790
|
+
var BUFFER = /* @__PURE__ */ Symbol("buffer");
|
|
1791
|
+
var TYPE = /* @__PURE__ */ Symbol("type");
|
|
1792
1792
|
var Blob = class _Blob {
|
|
1793
1793
|
constructor() {
|
|
1794
1794
|
this[TYPE] = "";
|
|
@@ -1899,7 +1899,7 @@ var require_lib2 = __commonJS({
|
|
|
1899
1899
|
FetchError.prototype.constructor = FetchError;
|
|
1900
1900
|
FetchError.prototype.name = "FetchError";
|
|
1901
1901
|
var convert;
|
|
1902
|
-
var INTERNALS = Symbol("Body internals");
|
|
1902
|
+
var INTERNALS = /* @__PURE__ */ Symbol("Body internals");
|
|
1903
1903
|
var PassThrough = Stream.PassThrough;
|
|
1904
1904
|
function Body(body) {
|
|
1905
1905
|
var _this = this;
|
|
@@ -2239,7 +2239,7 @@ var require_lib2 = __commonJS({
|
|
|
2239
2239
|
}
|
|
2240
2240
|
return void 0;
|
|
2241
2241
|
}
|
|
2242
|
-
var MAP = Symbol("map");
|
|
2242
|
+
var MAP = /* @__PURE__ */ Symbol("map");
|
|
2243
2243
|
var Headers = class _Headers {
|
|
2244
2244
|
/**
|
|
2245
2245
|
* Headers class
|
|
@@ -2447,7 +2447,7 @@ var require_lib2 = __commonJS({
|
|
|
2447
2447
|
return [k.toLowerCase(), headers[MAP][k].join(", ")];
|
|
2448
2448
|
});
|
|
2449
2449
|
}
|
|
2450
|
-
var INTERNAL = Symbol("internal");
|
|
2450
|
+
var INTERNAL = /* @__PURE__ */ Symbol("internal");
|
|
2451
2451
|
function createHeadersIterator(target, kind) {
|
|
2452
2452
|
const iterator = Object.create(HeadersIteratorPrototype);
|
|
2453
2453
|
iterator[INTERNAL] = {
|
|
@@ -2516,7 +2516,7 @@ var require_lib2 = __commonJS({
|
|
|
2516
2516
|
}
|
|
2517
2517
|
return headers;
|
|
2518
2518
|
}
|
|
2519
|
-
var INTERNALS$1 = Symbol("Response internals");
|
|
2519
|
+
var INTERNALS$1 = /* @__PURE__ */ Symbol("Response internals");
|
|
2520
2520
|
var STATUS_CODES = http.STATUS_CODES;
|
|
2521
2521
|
var Response = class _Response {
|
|
2522
2522
|
constructor() {
|
|
@@ -2592,7 +2592,7 @@ var require_lib2 = __commonJS({
|
|
|
2592
2592
|
enumerable: false,
|
|
2593
2593
|
configurable: true
|
|
2594
2594
|
});
|
|
2595
|
-
var INTERNALS$2 = Symbol("Request internals");
|
|
2595
|
+
var INTERNALS$2 = /* @__PURE__ */ Symbol("Request internals");
|
|
2596
2596
|
var URL = Url.URL || whatwgUrl.URL;
|
|
2597
2597
|
var parse_url = Url.parse;
|
|
2598
2598
|
var format_url = Url.format;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "replicas-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
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": {
|