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 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-08-v7";
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 { appendFile, mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
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
- this.filePath = join6(LOG_DIR, `${this._sessionId}.log`);
3760
- await writeFile2(this.filePath, `=== Replicas Engine Session ${this._sessionId} ===
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 ${this.filePath}`);
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
- if (!this.filePath) return;
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.writeChain;
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 as appendFile2, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
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 appendFile2(START_HOOKS_LOG, logLine, "utf-8");
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 { appendFile as appendFile3, mkdir as mkdir7 } from "fs/promises";
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
- writeChain = Promise.resolve();
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.writeChain = this.writeChain.catch((error) => {
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 appendFile5, copyFile, mkdir as mkdir11, readFile as readFile8, rename as rename2, rm } from "fs/promises";
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 appendFile4 } from "fs/promises";
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 appendFile4(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
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 appendFile4(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
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 appendFile4(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
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 appendFile4(this.historyFile, JSON.stringify(jsonEvent) + "\n", "utf-8");
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.285";
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
- writeChain = Promise.resolve();
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 appendFile5(this.senderFilePath(chatId), JSON.stringify(sender) + "\n", "utf-8");
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
- this.writeChain = this.writeChain.catch(() => {
9413
- }).then(async () => {
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
- await this.writeChain;
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 appendFile6, unlink as unlink3 } from "fs/promises";
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 appendFile6(CURRENT_RUN_LOG, chunk, "utf-8");
9977
+ await appendFile4(CURRENT_RUN_LOG, chunk, "utf-8");
9919
9978
  }
9920
9979
  async getCurrentRunLog() {
9921
9980
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.285",
3
+ "version": "0.1.287",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -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"