replicas-engine 0.1.433 → 0.1.434

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.
Files changed (2) hide show
  1. package/dist/src/index.js +71 -16
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -506,7 +506,7 @@ var WORKSPACE_SIZES = ["small", "large"];
506
506
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
507
507
 
508
508
  // ../shared/src/e2b.ts
509
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-14-v4";
509
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-14-v5";
510
510
 
511
511
  // ../shared/src/runtime-env.ts
512
512
  function shellQuotePosix(value) {
@@ -4218,21 +4218,35 @@ var GitService = class {
4218
4218
  return { repos: states, complete };
4219
4219
  }
4220
4220
  async refreshRepos(observedBranchesByRepo, options) {
4221
- const repos = await this.listRepositories();
4221
+ return (await this.refreshReposWithCompleteness(observedBranchesByRepo, options)).repos;
4222
+ }
4223
+ async refreshReposWithCompleteness(observedBranchesByRepo, options) {
4224
+ const discovered = await this.listRepositoriesWithCompleteness();
4222
4225
  const states = [];
4223
- for (const repo of repos) {
4226
+ let complete = discovered.complete;
4227
+ for (const repo of discovered.repos) {
4224
4228
  try {
4225
4229
  const persistedState = await loadRepoState(repo.name);
4226
4230
  const currentBranch = await getCurrentBranch(repo.path) ?? repo.defaultBranch;
4227
4231
  const startHooksCompleted = persistedState?.startHooksCompleted ?? false;
4228
4232
  const observed = observedBranchesByRepo?.get(repo.name);
4229
- states.push(
4230
- await this.refreshRepoMetadata(repo, currentBranch, startHooksCompleted, persistedState, observed, options?.includeDiffs === true)
4233
+ const state = await this.refreshRepoMetadata(
4234
+ repo,
4235
+ currentBranch,
4236
+ startHooksCompleted,
4237
+ persistedState,
4238
+ observed,
4239
+ options?.includeDiffs === true
4231
4240
  );
4241
+ if (state.gitDiff === null || options?.includeDiffs === true && state.gitDiff.fullDiff === void 0) {
4242
+ complete = false;
4243
+ }
4244
+ states.push(state);
4232
4245
  } catch {
4246
+ complete = false;
4233
4247
  }
4234
4248
  }
4235
- return states;
4249
+ return { repos: states, complete };
4236
4250
  }
4237
4251
  // Fast branch snapshot for per-event observation during a turn. Reads
4238
4252
  // .git/HEAD directly for each repo (no subprocess) so callers can safely
@@ -8464,7 +8478,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
8464
8478
  var MIN_CODEX_CLI_VERSION = "0.144.0";
8465
8479
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
8466
8480
  var codexCliVersionEnsured = null;
8467
- var ENGINE_PACKAGE_VERSION = "0.1.433";
8481
+ var ENGINE_PACKAGE_VERSION = "0.1.434";
8468
8482
  var INITIALIZE_METHOD = "initialize";
8469
8483
  var INITIALIZED_NOTIFICATION = "initialized";
8470
8484
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -12515,6 +12529,39 @@ async function uploadChatTranscript(chatId, filePath, chat) {
12515
12529
  }
12516
12530
  }
12517
12531
 
12532
+ // src/services/upload-repo-state.ts
12533
+ var uploadQueue = Promise.resolve();
12534
+ async function sendRepoState(repos) {
12535
+ const form = new FormData();
12536
+ form.append(
12537
+ "file",
12538
+ new Blob([JSON.stringify({ repos })], { type: "application/json" }),
12539
+ "repo-state.json"
12540
+ );
12541
+ const response = await monolithRequest("/v1/engine/repo-state", { body: form });
12542
+ if (!response.ok) {
12543
+ const errorText = await response.text();
12544
+ throw new Error(`upload failed: ${response.status} ${errorText}`);
12545
+ }
12546
+ }
12547
+ function uploadRepoState(repos) {
12548
+ const upload = uploadQueue.then(() => sendRepoState(repos));
12549
+ uploadQueue = upload.catch(() => {
12550
+ });
12551
+ return upload;
12552
+ }
12553
+ async function flushRepoState() {
12554
+ try {
12555
+ const { repos, complete } = await gitService.listReposWithCompleteness({ includeDiffs: true });
12556
+ if (!complete) return { flushed: 0, skipped: 1, failed: 0 };
12557
+ await uploadRepoState(repos);
12558
+ return { flushed: 1, skipped: 0, failed: 0 };
12559
+ } catch (err) {
12560
+ console.error("[RepoStateUploader] upload failed:", err);
12561
+ return { flushed: 0, skipped: 0, failed: 1 };
12562
+ }
12563
+ }
12564
+
12518
12565
  // src/services/chat/chat-service.ts
12519
12566
  var CHAT_SENDERS_DIR = join21(ENGINE_DIR2, "chat-senders");
12520
12567
  var CODEX_AUTH_PATH2 = join21(homedir15(), ".codex", "auth.json");
@@ -12986,11 +13033,12 @@ var ChatService = class {
12986
13033
  const chatsById = new Map(
12987
13034
  [...this.chats.entries()].map(([chatId, chat]) => [chatId, this.toSummary(chat)])
12988
13035
  );
12989
- const [chatTranscripts, canvas] = await Promise.all([
13036
+ const [chatTranscripts, canvas, repoState] = await Promise.all([
12990
13037
  flushAllChatTranscripts(chatsById),
12991
- flushAllCanvasItems()
13038
+ flushAllCanvasItems(),
13039
+ flushRepoState()
12992
13040
  ]);
12993
- return { chatTranscripts, canvas };
13041
+ return { chatTranscripts, canvas, repoState };
12994
13042
  }
12995
13043
  createRuntimeChat(persisted) {
12996
13044
  const saveSession = async (sessionId) => {
@@ -13293,15 +13341,23 @@ var ChatService = class {
13293
13341
  const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
13294
13342
  const observedBranches = chat.observedBranchesByRepo;
13295
13343
  chat.observedBranchesByRepo = /* @__PURE__ */ new Map();
13296
- let repoStatuses;
13344
+ let repoStatuses = [];
13345
+ let repoStateComplete = false;
13297
13346
  try {
13298
- repoStatuses = await gitService.refreshRepos(observedBranches, { includeDiffs: true });
13347
+ const refreshed = await gitService.refreshReposWithCompleteness(observedBranches, { includeDiffs: true });
13348
+ repoStatuses = refreshed.repos;
13349
+ repoStateComplete = refreshed.complete;
13299
13350
  console.log(`Repository Statuses Refreshed: `, repoStatuses);
13300
13351
  } catch (error) {
13301
13352
  console.error("[ChatService] Failed to refresh repo statuses:", error);
13302
13353
  }
13354
+ if (repoStateComplete) {
13355
+ uploadRepoState(repoStatuses).catch((err) => {
13356
+ console.error("[ChatService] Failed to upload repository state:", err);
13357
+ });
13358
+ }
13303
13359
  try {
13304
- const payload = linearSessionId ? { linearSessionId, repoStatuses: repoStatuses ?? [] } : { repoStatuses: repoStatuses ?? [] };
13360
+ const payload = linearSessionId ? { linearSessionId, repoStatuses } : { repoStatuses };
13305
13361
  await monolithService.sendEvent({ type: "agent_turn_complete", payload });
13306
13362
  } catch (error) {
13307
13363
  console.error("[ChatService] Failed to send agent_turn_complete event:", error);
@@ -14325,11 +14381,10 @@ function createV1Routes(deps) {
14325
14381
  });
14326
14382
  app2.get("/repos", async (c) => {
14327
14383
  const includeDiffs = c.req.query("includeDiffs") === "true";
14328
- const { repos, complete } = await gitService.listReposWithCompleteness({ includeDiffs });
14384
+ const repos = await gitService.listRepos({ includeDiffs });
14329
14385
  const response = {
14330
14386
  repos,
14331
- workspaceRoot: gitService.getWorkspaceRoot(),
14332
- complete
14387
+ workspaceRoot: gitService.getWorkspaceRoot()
14333
14388
  };
14334
14389
  return c.json(response);
14335
14390
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.433",
3
+ "version": "0.1.434",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",