replicas-engine 0.1.285 → 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 -45
- 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) {
|
|
@@ -2265,7 +2265,6 @@ var WORKSPACE_STATUS_FILTERS = ["active", "sleeping", "preparing", "failed"];
|
|
|
2265
2265
|
var DEFAULT_STATUS_FILTERS = [...WORKSPACE_STATUS_FILTERS];
|
|
2266
2266
|
var DEFAULT_WORKSPACE_FILTERS = {
|
|
2267
2267
|
statuses: [...DEFAULT_STATUS_FILTERS],
|
|
2268
|
-
sources: [],
|
|
2269
2268
|
ownerIds: [],
|
|
2270
2269
|
activity: "any"
|
|
2271
2270
|
};
|
|
@@ -3739,28 +3738,91 @@ var GitService = class {
|
|
|
3739
3738
|
var gitService = new GitService();
|
|
3740
3739
|
|
|
3741
3740
|
// src/utils/logger.ts
|
|
3742
|
-
import {
|
|
3741
|
+
import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
3743
3742
|
import { homedir as homedir4 } from "os";
|
|
3744
3743
|
import { join as join6 } from "path";
|
|
3745
3744
|
import { format } from "util";
|
|
3746
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
|
|
3747
3809
|
var LOG_DIR = join6(homedir4(), ".replicas", "logs");
|
|
3748
3810
|
var EngineLogger = class {
|
|
3749
3811
|
_sessionId = null;
|
|
3750
|
-
filePath = null;
|
|
3751
|
-
writeChain = Promise.resolve();
|
|
3752
3812
|
patched = false;
|
|
3813
|
+
writer = new StreamWriter();
|
|
3753
3814
|
get sessionId() {
|
|
3754
3815
|
return this._sessionId;
|
|
3755
3816
|
}
|
|
3756
3817
|
async initialize() {
|
|
3757
3818
|
await mkdir3(LOG_DIR, { recursive: true });
|
|
3758
3819
|
this._sessionId = this.createSessionId();
|
|
3759
|
-
|
|
3760
|
-
await writeFile2(
|
|
3820
|
+
const logPath = join6(LOG_DIR, `${this._sessionId}.log`);
|
|
3821
|
+
await writeFile2(logPath, `=== Replicas Engine Session ${this._sessionId} ===
|
|
3761
3822
|
`, "utf-8");
|
|
3823
|
+
this.writer.open(logPath);
|
|
3762
3824
|
this.patchConsole();
|
|
3763
|
-
this.log("INFO", `Engine logging initialized at ${
|
|
3825
|
+
this.log("INFO", `Engine logging initialized at ${logPath}`);
|
|
3764
3826
|
}
|
|
3765
3827
|
patchConsole() {
|
|
3766
3828
|
if (this.patched) return;
|
|
@@ -3782,21 +3844,11 @@ var EngineLogger = class {
|
|
|
3782
3844
|
};
|
|
3783
3845
|
}
|
|
3784
3846
|
log(level, message) {
|
|
3785
|
-
|
|
3786
|
-
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${message}
|
|
3787
|
-
`;
|
|
3788
|
-
this.writeChain = this.writeChain.then(() => appendFile(this.filePath, line, "utf-8")).catch((error) => {
|
|
3789
|
-
try {
|
|
3790
|
-
const err = error instanceof Error ? error.message : "Unknown error";
|
|
3791
|
-
process.stderr.write(`[EngineLogger] Failed to append log line: ${err}
|
|
3847
|
+
this.writer.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${message}
|
|
3792
3848
|
`);
|
|
3793
|
-
} catch {
|
|
3794
|
-
}
|
|
3795
|
-
});
|
|
3796
3849
|
}
|
|
3797
|
-
/** Wait for all queued log writes to complete. */
|
|
3798
3850
|
flush() {
|
|
3799
|
-
return this.
|
|
3851
|
+
return this.writer.flush();
|
|
3800
3852
|
}
|
|
3801
3853
|
createSessionId() {
|
|
3802
3854
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-");
|
|
@@ -3807,7 +3859,7 @@ var EngineLogger = class {
|
|
|
3807
3859
|
var engineLogger = new EngineLogger();
|
|
3808
3860
|
|
|
3809
3861
|
// src/services/replicas-config-service.ts
|
|
3810
|
-
import { readFile as readFile5, appendFile
|
|
3862
|
+
import { readFile as readFile5, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
|
|
3811
3863
|
import { existsSync as existsSync4 } from "fs";
|
|
3812
3864
|
import { join as join9 } from "path";
|
|
3813
3865
|
import { homedir as homedir7 } from "os";
|
|
@@ -4181,7 +4233,7 @@ var ReplicasConfigService = class {
|
|
|
4181
4233
|
`;
|
|
4182
4234
|
try {
|
|
4183
4235
|
await mkdir6(join9(homedir7(), ".replicas"), { recursive: true });
|
|
4184
|
-
await
|
|
4236
|
+
await appendFile(START_HOOKS_LOG, logLine, "utf-8");
|
|
4185
4237
|
} catch (error) {
|
|
4186
4238
|
console.error("Failed to write to start hooks log:", error);
|
|
4187
4239
|
}
|
|
@@ -4509,7 +4561,7 @@ ${startHookConfig.commands.join("\n")}`;
|
|
|
4509
4561
|
var replicasConfigService = new ReplicasConfigService();
|
|
4510
4562
|
|
|
4511
4563
|
// src/services/event-service.ts
|
|
4512
|
-
import {
|
|
4564
|
+
import { mkdir as mkdir7 } from "fs/promises";
|
|
4513
4565
|
import { homedir as homedir8 } from "os";
|
|
4514
4566
|
import { join as join10 } from "path";
|
|
4515
4567
|
import { randomUUID } from "crypto";
|
|
@@ -4517,9 +4569,10 @@ var ENGINE_DIR = join10(homedir8(), ".replicas", "engine");
|
|
|
4517
4569
|
var EVENTS_FILE = join10(ENGINE_DIR, "events.jsonl");
|
|
4518
4570
|
var EventService = class {
|
|
4519
4571
|
subscribers = /* @__PURE__ */ new Map();
|
|
4520
|
-
|
|
4572
|
+
writer = new StreamWriter();
|
|
4521
4573
|
async initialize() {
|
|
4522
4574
|
await mkdir7(ENGINE_DIR, { recursive: true });
|
|
4575
|
+
this.writer.open(EVENTS_FILE);
|
|
4523
4576
|
}
|
|
4524
4577
|
subscribe(subscriber) {
|
|
4525
4578
|
const id = randomUUID();
|
|
@@ -4532,18 +4585,13 @@ var EventService = class {
|
|
|
4532
4585
|
return this.subscribers.size;
|
|
4533
4586
|
}
|
|
4534
4587
|
async publish(event) {
|
|
4535
|
-
this.
|
|
4536
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
4537
|
-
process.stderr.write(`[EventService] Previous write failed, continuing: ${message}
|
|
4538
|
-
`);
|
|
4539
|
-
}).then(() => appendFile3(EVENTS_FILE, JSON.stringify(event) + "\n", "utf-8"));
|
|
4588
|
+
this.writer.write(JSON.stringify(event) + "\n");
|
|
4540
4589
|
for (const subscriber of this.subscribers.values()) {
|
|
4541
4590
|
try {
|
|
4542
4591
|
subscriber(event);
|
|
4543
4592
|
} catch {
|
|
4544
4593
|
}
|
|
4545
4594
|
}
|
|
4546
|
-
await this.writeChain;
|
|
4547
4595
|
}
|
|
4548
4596
|
};
|
|
4549
4597
|
var eventService = new EventService();
|
|
@@ -4665,7 +4713,7 @@ async function registerDesktopPreview() {
|
|
|
4665
4713
|
|
|
4666
4714
|
// src/services/chat/chat-service.ts
|
|
4667
4715
|
import { existsSync as existsSync7 } from "fs";
|
|
4668
|
-
import { appendFile as
|
|
4716
|
+
import { appendFile as appendFile3, copyFile, mkdir as mkdir11, readFile as readFile8, rename as rename2, rm } from "fs/promises";
|
|
4669
4717
|
import { homedir as homedir12 } from "os";
|
|
4670
4718
|
import { join as join14 } from "path";
|
|
4671
4719
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -4676,7 +4724,7 @@ import {
|
|
|
4676
4724
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
4677
4725
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
4678
4726
|
import { join as join13 } from "path";
|
|
4679
|
-
import { mkdir as mkdir10, appendFile as
|
|
4727
|
+
import { mkdir as mkdir10, appendFile as appendFile2 } from "fs/promises";
|
|
4680
4728
|
import { homedir as homedir11 } from "os";
|
|
4681
4729
|
|
|
4682
4730
|
// src/utils/jsonl-reader.ts
|
|
@@ -5789,7 +5837,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
5789
5837
|
type,
|
|
5790
5838
|
payload: { ...payload, parent_tool_use_id: null }
|
|
5791
5839
|
};
|
|
5792
|
-
await
|
|
5840
|
+
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
5793
5841
|
this.onEvent(event);
|
|
5794
5842
|
}
|
|
5795
5843
|
buildCanUseTool() {
|
|
@@ -5925,7 +5973,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
5925
5973
|
}
|
|
5926
5974
|
};
|
|
5927
5975
|
try {
|
|
5928
|
-
await
|
|
5976
|
+
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
5929
5977
|
} catch (writeError) {
|
|
5930
5978
|
console.error("[ClaudeManager] Failed to record auth-retry-exhausted event:", writeError);
|
|
5931
5979
|
}
|
|
@@ -6255,7 +6303,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6255
6303
|
try {
|
|
6256
6304
|
const usage = await response.getContextUsage();
|
|
6257
6305
|
const event = this.emitContextUsage(this.buildContextUsagePayload(usage));
|
|
6258
|
-
await
|
|
6306
|
+
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
6259
6307
|
} catch (error) {
|
|
6260
6308
|
console.warn("[ClaudeManager] Failed to record context usage:", error instanceof Error ? error.message : error);
|
|
6261
6309
|
}
|
|
@@ -6331,7 +6379,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6331
6379
|
type: `claude-${event.type}`,
|
|
6332
6380
|
payload: event
|
|
6333
6381
|
};
|
|
6334
|
-
await
|
|
6382
|
+
await appendFile2(this.historyFile, JSON.stringify(jsonEvent) + "\n", "utf-8");
|
|
6335
6383
|
this.onEvent(jsonEvent);
|
|
6336
6384
|
}
|
|
6337
6385
|
};
|
|
@@ -6532,7 +6580,7 @@ var AspClient = class {
|
|
|
6532
6580
|
// src/managers/codex-asp/app-server-process.ts
|
|
6533
6581
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
6534
6582
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
6535
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
6583
|
+
var ENGINE_PACKAGE_VERSION = "0.1.287";
|
|
6536
6584
|
var INITIALIZE_METHOD = "initialize";
|
|
6537
6585
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
6538
6586
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -8912,7 +8960,8 @@ var ChatService = class {
|
|
|
8912
8960
|
}
|
|
8913
8961
|
workingDirectory;
|
|
8914
8962
|
chats = /* @__PURE__ */ new Map();
|
|
8915
|
-
|
|
8963
|
+
persistInFlight = false;
|
|
8964
|
+
persistQueued = false;
|
|
8916
8965
|
async initialize() {
|
|
8917
8966
|
await mkdir11(ENGINE_DIR2, { recursive: true });
|
|
8918
8967
|
await mkdir11(CLAUDE_HISTORY_DIR, { recursive: true });
|
|
@@ -9019,7 +9068,7 @@ var ChatService = class {
|
|
|
9019
9068
|
}
|
|
9020
9069
|
async appendSender(chatId, sender) {
|
|
9021
9070
|
try {
|
|
9022
|
-
await
|
|
9071
|
+
await appendFile3(this.senderFilePath(chatId), JSON.stringify(sender) + "\n", "utf-8");
|
|
9023
9072
|
} catch (error) {
|
|
9024
9073
|
console.error("[ChatService] Failed to append sender record:", error);
|
|
9025
9074
|
}
|
|
@@ -9409,8 +9458,12 @@ var ChatService = class {
|
|
|
9409
9458
|
}
|
|
9410
9459
|
}
|
|
9411
9460
|
async persistAllChats() {
|
|
9412
|
-
|
|
9413
|
-
|
|
9461
|
+
if (this.persistInFlight) {
|
|
9462
|
+
this.persistQueued = true;
|
|
9463
|
+
return;
|
|
9464
|
+
}
|
|
9465
|
+
this.persistInFlight = true;
|
|
9466
|
+
try {
|
|
9414
9467
|
const payload = Array.from(this.chats.values()).map((chat) => chat.persisted);
|
|
9415
9468
|
try {
|
|
9416
9469
|
await copyFile(CHATS_FILE, CHATS_BACKUP_FILE);
|
|
@@ -9421,8 +9474,14 @@ var ChatService = class {
|
|
|
9421
9474
|
}
|
|
9422
9475
|
await atomicWriteFile(CHATS_FILE, `${JSON.stringify(payload, null, 2)}
|
|
9423
9476
|
`);
|
|
9424
|
-
}
|
|
9425
|
-
|
|
9477
|
+
} catch {
|
|
9478
|
+
} finally {
|
|
9479
|
+
this.persistInFlight = false;
|
|
9480
|
+
if (this.persistQueued) {
|
|
9481
|
+
this.persistQueued = false;
|
|
9482
|
+
void this.persistAllChats();
|
|
9483
|
+
}
|
|
9484
|
+
}
|
|
9426
9485
|
}
|
|
9427
9486
|
async publish(input) {
|
|
9428
9487
|
const event = {
|
|
@@ -9830,7 +9889,7 @@ import { existsSync as existsSync8 } from "fs";
|
|
|
9830
9889
|
import { join as join18 } from "path";
|
|
9831
9890
|
|
|
9832
9891
|
// src/services/warm-hook-logs-service.ts
|
|
9833
|
-
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";
|
|
9834
9893
|
import { homedir as homedir14 } from "os";
|
|
9835
9894
|
import { join as join17 } from "path";
|
|
9836
9895
|
var LOGS_DIR2 = join17(homedir14(), ".replicas", "warm-hook-logs");
|
|
@@ -9915,7 +9974,7 @@ var WarmHookLogsService = class {
|
|
|
9915
9974
|
}
|
|
9916
9975
|
async appendCurrentRunLog(chunk) {
|
|
9917
9976
|
if (!chunk) return;
|
|
9918
|
-
await
|
|
9977
|
+
await appendFile4(CURRENT_RUN_LOG, chunk, "utf-8");
|
|
9919
9978
|
}
|
|
9920
9979
|
async getCurrentRunLog() {
|
|
9921
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"
|