replicas-engine 0.1.286 → 0.1.287
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 +104 -44
- package/package.json +1 -1
- package/scripts/engine-watchdog.sh +2 -2
package/dist/src/index.js
CHANGED
|
@@ -286,7 +286,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
286
286
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
287
287
|
|
|
288
288
|
// ../shared/src/e2b.ts
|
|
289
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-
|
|
289
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-09-v1";
|
|
290
290
|
|
|
291
291
|
// ../shared/src/runtime-env.ts
|
|
292
292
|
function parsePosixEnvFile(content) {
|
|
@@ -3738,28 +3738,91 @@ var GitService = class {
|
|
|
3738
3738
|
var gitService = new GitService();
|
|
3739
3739
|
|
|
3740
3740
|
// src/utils/logger.ts
|
|
3741
|
-
import {
|
|
3741
|
+
import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
3742
3742
|
import { homedir as homedir4 } from "os";
|
|
3743
3743
|
import { join as join6 } from "path";
|
|
3744
3744
|
import { format } from "util";
|
|
3745
3745
|
import { randomBytes } from "crypto";
|
|
3746
|
+
|
|
3747
|
+
// src/utils/stream-writer.ts
|
|
3748
|
+
import { createWriteStream } from "fs";
|
|
3749
|
+
var DEFAULT_HIGH_WATER = 8 * 1024 * 1024;
|
|
3750
|
+
var StreamWriter = class {
|
|
3751
|
+
stream = null;
|
|
3752
|
+
backpressured = false;
|
|
3753
|
+
droppedCount = 0;
|
|
3754
|
+
flushTimer = null;
|
|
3755
|
+
open(path4, highWaterMark = DEFAULT_HIGH_WATER) {
|
|
3756
|
+
this.stream = createWriteStream(path4, { flags: "a", highWaterMark });
|
|
3757
|
+
this.stream.on("error", () => {
|
|
3758
|
+
this.stream = null;
|
|
3759
|
+
});
|
|
3760
|
+
this.stream.on("drain", () => {
|
|
3761
|
+
this.backpressured = false;
|
|
3762
|
+
});
|
|
3763
|
+
}
|
|
3764
|
+
write(line) {
|
|
3765
|
+
if (!this.stream) return false;
|
|
3766
|
+
if (this.backpressured) {
|
|
3767
|
+
this.droppedCount++;
|
|
3768
|
+
this.scheduleDropWarning();
|
|
3769
|
+
return false;
|
|
3770
|
+
}
|
|
3771
|
+
const written = this.stream.write(line);
|
|
3772
|
+
if (!written) {
|
|
3773
|
+
this.backpressured = true;
|
|
3774
|
+
}
|
|
3775
|
+
return true;
|
|
3776
|
+
}
|
|
3777
|
+
flush() {
|
|
3778
|
+
return new Promise((resolve3) => {
|
|
3779
|
+
if (!this.stream) {
|
|
3780
|
+
resolve3();
|
|
3781
|
+
return;
|
|
3782
|
+
}
|
|
3783
|
+
if (this.flushTimer) {
|
|
3784
|
+
clearTimeout(this.flushTimer);
|
|
3785
|
+
this.flushTimer = null;
|
|
3786
|
+
}
|
|
3787
|
+
const s = this.stream;
|
|
3788
|
+
this.stream = null;
|
|
3789
|
+
s.end(() => resolve3());
|
|
3790
|
+
});
|
|
3791
|
+
}
|
|
3792
|
+
scheduleDropWarning() {
|
|
3793
|
+
if (this.flushTimer) return;
|
|
3794
|
+
this.flushTimer = setTimeout(() => {
|
|
3795
|
+
this.flushTimer = null;
|
|
3796
|
+
if (this.droppedCount > 0 && this.stream) {
|
|
3797
|
+
this.stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [WARN] Dropped ${this.droppedCount} log lines due to IO backpressure
|
|
3798
|
+
`);
|
|
3799
|
+
this.droppedCount = 0;
|
|
3800
|
+
}
|
|
3801
|
+
}, 2e3);
|
|
3802
|
+
if (this.flushTimer && typeof this.flushTimer === "object" && "unref" in this.flushTimer) {
|
|
3803
|
+
this.flushTimer.unref();
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
};
|
|
3807
|
+
|
|
3808
|
+
// src/utils/logger.ts
|
|
3746
3809
|
var LOG_DIR = join6(homedir4(), ".replicas", "logs");
|
|
3747
3810
|
var EngineLogger = class {
|
|
3748
3811
|
_sessionId = null;
|
|
3749
|
-
filePath = null;
|
|
3750
|
-
writeChain = Promise.resolve();
|
|
3751
3812
|
patched = false;
|
|
3813
|
+
writer = new StreamWriter();
|
|
3752
3814
|
get sessionId() {
|
|
3753
3815
|
return this._sessionId;
|
|
3754
3816
|
}
|
|
3755
3817
|
async initialize() {
|
|
3756
3818
|
await mkdir3(LOG_DIR, { recursive: true });
|
|
3757
3819
|
this._sessionId = this.createSessionId();
|
|
3758
|
-
|
|
3759
|
-
await writeFile2(
|
|
3820
|
+
const logPath = join6(LOG_DIR, `${this._sessionId}.log`);
|
|
3821
|
+
await writeFile2(logPath, `=== Replicas Engine Session ${this._sessionId} ===
|
|
3760
3822
|
`, "utf-8");
|
|
3823
|
+
this.writer.open(logPath);
|
|
3761
3824
|
this.patchConsole();
|
|
3762
|
-
this.log("INFO", `Engine logging initialized at ${
|
|
3825
|
+
this.log("INFO", `Engine logging initialized at ${logPath}`);
|
|
3763
3826
|
}
|
|
3764
3827
|
patchConsole() {
|
|
3765
3828
|
if (this.patched) return;
|
|
@@ -3781,21 +3844,11 @@ var EngineLogger = class {
|
|
|
3781
3844
|
};
|
|
3782
3845
|
}
|
|
3783
3846
|
log(level, message) {
|
|
3784
|
-
|
|
3785
|
-
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${message}
|
|
3786
|
-
`;
|
|
3787
|
-
this.writeChain = this.writeChain.then(() => appendFile(this.filePath, line, "utf-8")).catch((error) => {
|
|
3788
|
-
try {
|
|
3789
|
-
const err = error instanceof Error ? error.message : "Unknown error";
|
|
3790
|
-
process.stderr.write(`[EngineLogger] Failed to append log line: ${err}
|
|
3847
|
+
this.writer.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${message}
|
|
3791
3848
|
`);
|
|
3792
|
-
} catch {
|
|
3793
|
-
}
|
|
3794
|
-
});
|
|
3795
3849
|
}
|
|
3796
|
-
/** Wait for all queued log writes to complete. */
|
|
3797
3850
|
flush() {
|
|
3798
|
-
return this.
|
|
3851
|
+
return this.writer.flush();
|
|
3799
3852
|
}
|
|
3800
3853
|
createSessionId() {
|
|
3801
3854
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-");
|
|
@@ -3806,7 +3859,7 @@ var EngineLogger = class {
|
|
|
3806
3859
|
var engineLogger = new EngineLogger();
|
|
3807
3860
|
|
|
3808
3861
|
// src/services/replicas-config-service.ts
|
|
3809
|
-
import { readFile as readFile5, appendFile
|
|
3862
|
+
import { readFile as readFile5, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
|
|
3810
3863
|
import { existsSync as existsSync4 } from "fs";
|
|
3811
3864
|
import { join as join9 } from "path";
|
|
3812
3865
|
import { homedir as homedir7 } from "os";
|
|
@@ -4180,7 +4233,7 @@ var ReplicasConfigService = class {
|
|
|
4180
4233
|
`;
|
|
4181
4234
|
try {
|
|
4182
4235
|
await mkdir6(join9(homedir7(), ".replicas"), { recursive: true });
|
|
4183
|
-
await
|
|
4236
|
+
await appendFile(START_HOOKS_LOG, logLine, "utf-8");
|
|
4184
4237
|
} catch (error) {
|
|
4185
4238
|
console.error("Failed to write to start hooks log:", error);
|
|
4186
4239
|
}
|
|
@@ -4508,7 +4561,7 @@ ${startHookConfig.commands.join("\n")}`;
|
|
|
4508
4561
|
var replicasConfigService = new ReplicasConfigService();
|
|
4509
4562
|
|
|
4510
4563
|
// src/services/event-service.ts
|
|
4511
|
-
import {
|
|
4564
|
+
import { mkdir as mkdir7 } from "fs/promises";
|
|
4512
4565
|
import { homedir as homedir8 } from "os";
|
|
4513
4566
|
import { join as join10 } from "path";
|
|
4514
4567
|
import { randomUUID } from "crypto";
|
|
@@ -4516,9 +4569,10 @@ var ENGINE_DIR = join10(homedir8(), ".replicas", "engine");
|
|
|
4516
4569
|
var EVENTS_FILE = join10(ENGINE_DIR, "events.jsonl");
|
|
4517
4570
|
var EventService = class {
|
|
4518
4571
|
subscribers = /* @__PURE__ */ new Map();
|
|
4519
|
-
|
|
4572
|
+
writer = new StreamWriter();
|
|
4520
4573
|
async initialize() {
|
|
4521
4574
|
await mkdir7(ENGINE_DIR, { recursive: true });
|
|
4575
|
+
this.writer.open(EVENTS_FILE);
|
|
4522
4576
|
}
|
|
4523
4577
|
subscribe(subscriber) {
|
|
4524
4578
|
const id = randomUUID();
|
|
@@ -4531,18 +4585,13 @@ var EventService = class {
|
|
|
4531
4585
|
return this.subscribers.size;
|
|
4532
4586
|
}
|
|
4533
4587
|
async publish(event) {
|
|
4534
|
-
this.
|
|
4535
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
4536
|
-
process.stderr.write(`[EventService] Previous write failed, continuing: ${message}
|
|
4537
|
-
`);
|
|
4538
|
-
}).then(() => appendFile3(EVENTS_FILE, JSON.stringify(event) + "\n", "utf-8"));
|
|
4588
|
+
this.writer.write(JSON.stringify(event) + "\n");
|
|
4539
4589
|
for (const subscriber of this.subscribers.values()) {
|
|
4540
4590
|
try {
|
|
4541
4591
|
subscriber(event);
|
|
4542
4592
|
} catch {
|
|
4543
4593
|
}
|
|
4544
4594
|
}
|
|
4545
|
-
await this.writeChain;
|
|
4546
4595
|
}
|
|
4547
4596
|
};
|
|
4548
4597
|
var eventService = new EventService();
|
|
@@ -4664,7 +4713,7 @@ async function registerDesktopPreview() {
|
|
|
4664
4713
|
|
|
4665
4714
|
// src/services/chat/chat-service.ts
|
|
4666
4715
|
import { existsSync as existsSync7 } from "fs";
|
|
4667
|
-
import { appendFile as
|
|
4716
|
+
import { appendFile as appendFile3, copyFile, mkdir as mkdir11, readFile as readFile8, rename as rename2, rm } from "fs/promises";
|
|
4668
4717
|
import { homedir as homedir12 } from "os";
|
|
4669
4718
|
import { join as join14 } from "path";
|
|
4670
4719
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -4675,7 +4724,7 @@ import {
|
|
|
4675
4724
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
4676
4725
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
4677
4726
|
import { join as join13 } from "path";
|
|
4678
|
-
import { mkdir as mkdir10, appendFile as
|
|
4727
|
+
import { mkdir as mkdir10, appendFile as appendFile2 } from "fs/promises";
|
|
4679
4728
|
import { homedir as homedir11 } from "os";
|
|
4680
4729
|
|
|
4681
4730
|
// src/utils/jsonl-reader.ts
|
|
@@ -5788,7 +5837,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
5788
5837
|
type,
|
|
5789
5838
|
payload: { ...payload, parent_tool_use_id: null }
|
|
5790
5839
|
};
|
|
5791
|
-
await
|
|
5840
|
+
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
5792
5841
|
this.onEvent(event);
|
|
5793
5842
|
}
|
|
5794
5843
|
buildCanUseTool() {
|
|
@@ -5924,7 +5973,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
5924
5973
|
}
|
|
5925
5974
|
};
|
|
5926
5975
|
try {
|
|
5927
|
-
await
|
|
5976
|
+
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
5928
5977
|
} catch (writeError) {
|
|
5929
5978
|
console.error("[ClaudeManager] Failed to record auth-retry-exhausted event:", writeError);
|
|
5930
5979
|
}
|
|
@@ -6254,7 +6303,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6254
6303
|
try {
|
|
6255
6304
|
const usage = await response.getContextUsage();
|
|
6256
6305
|
const event = this.emitContextUsage(this.buildContextUsagePayload(usage));
|
|
6257
|
-
await
|
|
6306
|
+
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
6258
6307
|
} catch (error) {
|
|
6259
6308
|
console.warn("[ClaudeManager] Failed to record context usage:", error instanceof Error ? error.message : error);
|
|
6260
6309
|
}
|
|
@@ -6330,7 +6379,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6330
6379
|
type: `claude-${event.type}`,
|
|
6331
6380
|
payload: event
|
|
6332
6381
|
};
|
|
6333
|
-
await
|
|
6382
|
+
await appendFile2(this.historyFile, JSON.stringify(jsonEvent) + "\n", "utf-8");
|
|
6334
6383
|
this.onEvent(jsonEvent);
|
|
6335
6384
|
}
|
|
6336
6385
|
};
|
|
@@ -6531,7 +6580,7 @@ var AspClient = class {
|
|
|
6531
6580
|
// src/managers/codex-asp/app-server-process.ts
|
|
6532
6581
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
6533
6582
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
6534
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
6583
|
+
var ENGINE_PACKAGE_VERSION = "0.1.287";
|
|
6535
6584
|
var INITIALIZE_METHOD = "initialize";
|
|
6536
6585
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
6537
6586
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -8911,7 +8960,8 @@ var ChatService = class {
|
|
|
8911
8960
|
}
|
|
8912
8961
|
workingDirectory;
|
|
8913
8962
|
chats = /* @__PURE__ */ new Map();
|
|
8914
|
-
|
|
8963
|
+
persistInFlight = false;
|
|
8964
|
+
persistQueued = false;
|
|
8915
8965
|
async initialize() {
|
|
8916
8966
|
await mkdir11(ENGINE_DIR2, { recursive: true });
|
|
8917
8967
|
await mkdir11(CLAUDE_HISTORY_DIR, { recursive: true });
|
|
@@ -9018,7 +9068,7 @@ var ChatService = class {
|
|
|
9018
9068
|
}
|
|
9019
9069
|
async appendSender(chatId, sender) {
|
|
9020
9070
|
try {
|
|
9021
|
-
await
|
|
9071
|
+
await appendFile3(this.senderFilePath(chatId), JSON.stringify(sender) + "\n", "utf-8");
|
|
9022
9072
|
} catch (error) {
|
|
9023
9073
|
console.error("[ChatService] Failed to append sender record:", error);
|
|
9024
9074
|
}
|
|
@@ -9408,8 +9458,12 @@ var ChatService = class {
|
|
|
9408
9458
|
}
|
|
9409
9459
|
}
|
|
9410
9460
|
async persistAllChats() {
|
|
9411
|
-
|
|
9412
|
-
|
|
9461
|
+
if (this.persistInFlight) {
|
|
9462
|
+
this.persistQueued = true;
|
|
9463
|
+
return;
|
|
9464
|
+
}
|
|
9465
|
+
this.persistInFlight = true;
|
|
9466
|
+
try {
|
|
9413
9467
|
const payload = Array.from(this.chats.values()).map((chat) => chat.persisted);
|
|
9414
9468
|
try {
|
|
9415
9469
|
await copyFile(CHATS_FILE, CHATS_BACKUP_FILE);
|
|
@@ -9420,8 +9474,14 @@ var ChatService = class {
|
|
|
9420
9474
|
}
|
|
9421
9475
|
await atomicWriteFile(CHATS_FILE, `${JSON.stringify(payload, null, 2)}
|
|
9422
9476
|
`);
|
|
9423
|
-
}
|
|
9424
|
-
|
|
9477
|
+
} catch {
|
|
9478
|
+
} finally {
|
|
9479
|
+
this.persistInFlight = false;
|
|
9480
|
+
if (this.persistQueued) {
|
|
9481
|
+
this.persistQueued = false;
|
|
9482
|
+
void this.persistAllChats();
|
|
9483
|
+
}
|
|
9484
|
+
}
|
|
9425
9485
|
}
|
|
9426
9486
|
async publish(input) {
|
|
9427
9487
|
const event = {
|
|
@@ -9829,7 +9889,7 @@ import { existsSync as existsSync8 } from "fs";
|
|
|
9829
9889
|
import { join as join18 } from "path";
|
|
9830
9890
|
|
|
9831
9891
|
// src/services/warm-hook-logs-service.ts
|
|
9832
|
-
import { mkdir as mkdir12, readFile as readFile11, writeFile as writeFile6, readdir as readdir4, appendFile as
|
|
9892
|
+
import { mkdir as mkdir12, readFile as readFile11, writeFile as writeFile6, readdir as readdir4, appendFile as appendFile4, unlink as unlink3 } from "fs/promises";
|
|
9833
9893
|
import { homedir as homedir14 } from "os";
|
|
9834
9894
|
import { join as join17 } from "path";
|
|
9835
9895
|
var LOGS_DIR2 = join17(homedir14(), ".replicas", "warm-hook-logs");
|
|
@@ -9914,7 +9974,7 @@ var WarmHookLogsService = class {
|
|
|
9914
9974
|
}
|
|
9915
9975
|
async appendCurrentRunLog(chunk) {
|
|
9916
9976
|
if (!chunk) return;
|
|
9917
|
-
await
|
|
9977
|
+
await appendFile4(CURRENT_RUN_LOG, chunk, "utf-8");
|
|
9918
9978
|
}
|
|
9919
9979
|
async getCurrentRunLog() {
|
|
9920
9980
|
try {
|
package/package.json
CHANGED
|
@@ -86,9 +86,9 @@ while true; do
|
|
|
86
86
|
|
|
87
87
|
START_TIME=$(date +%s)
|
|
88
88
|
if [ -n "$ENGINE_LD_PRELOAD" ]; then
|
|
89
|
-
LD_PRELOAD="$ENGINE_LD_PRELOAD" "${ENGINE_CMD[@]}" >> "$BOOTSTRAP_LOG" 2>&1 &
|
|
89
|
+
LD_PRELOAD="$ENGINE_LD_PRELOAD" "${ENGINE_CMD[@]}" > >(cat >> "$BOOTSTRAP_LOG") 2>&1 &
|
|
90
90
|
else
|
|
91
|
-
"${ENGINE_CMD[@]}" >> "$BOOTSTRAP_LOG" 2>&1 &
|
|
91
|
+
"${ENGINE_CMD[@]}" > >(cat >> "$BOOTSTRAP_LOG") 2>&1 &
|
|
92
92
|
fi
|
|
93
93
|
ENGINE_PID=$!
|
|
94
94
|
echo "$ENGINE_PID" > "$PIDFILE"
|