replicas-engine 0.1.63 → 0.1.65

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 +90 -21
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -102,7 +102,29 @@ var BaseRefreshManager = class {
102
102
  }
103
103
  console.log(`[${this.managerName}] Starting token refresh service`);
104
104
  this.health.isRunning = true;
105
- await this.refreshOnce();
105
+ const config = this.getRuntimeConfig();
106
+ if (config) {
107
+ this.health.lastAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
108
+ for (let attempt = 1; attempt <= 3; attempt++) {
109
+ try {
110
+ await this.doRefresh(config);
111
+ this.health.lastSuccessAt = (/* @__PURE__ */ new Date()).toISOString();
112
+ this.health.lastErrorAt = null;
113
+ this.health.lastErrorMessage = null;
114
+ break;
115
+ } catch (error) {
116
+ const message = error instanceof Error ? error.message : "Unknown error";
117
+ this.health.lastErrorAt = (/* @__PURE__ */ new Date()).toISOString();
118
+ this.health.lastErrorMessage = message;
119
+ if (attempt < 3) {
120
+ console.warn(`[${this.managerName}] Initial refresh attempt ${attempt} failed, retrying in 2s...`);
121
+ await new Promise((resolve2) => setTimeout(resolve2, 2e3));
122
+ } else {
123
+ console.error(`[${this.managerName}] Initial refresh failed after 3 attempts:`, error);
124
+ }
125
+ }
126
+ }
127
+ }
106
128
  this.intervalHandle = setInterval(() => {
107
129
  this.refreshOnce().catch((error) => {
108
130
  console.error(`[${this.managerName}] Scheduled refresh failed:`, error);
@@ -330,7 +352,7 @@ import { execFileSync as execFileSync2 } from "child_process";
330
352
  import { join as join3 } from "path";
331
353
 
332
354
  // src/utils/state.ts
333
- import { readFile, writeFile, mkdir } from "fs/promises";
355
+ import { readFile, writeFile, mkdir, rename, unlink } from "fs/promises";
334
356
  import { existsSync } from "fs";
335
357
  import { join as join2 } from "path";
336
358
  import { homedir as homedir2 } from "os";
@@ -357,7 +379,14 @@ async function updateEngineState(updater) {
357
379
  await mkdir(STATE_DIR, { recursive: true });
358
380
  const currentState = await loadEngineState();
359
381
  const nextState = updater(currentState);
360
- await writeFile(STATE_FILE, JSON.stringify(nextState, null, 2), "utf-8");
382
+ const tmpFile = `${STATE_FILE}.${process.pid}.tmp`;
383
+ try {
384
+ await writeFile(tmpFile, JSON.stringify(nextState, null, 2), "utf-8");
385
+ await rename(tmpFile, STATE_FILE);
386
+ } catch (err) {
387
+ await unlink(tmpFile).catch(() => void 0);
388
+ throw err;
389
+ }
361
390
  });
362
391
  }
363
392
  function isEngineRepoDiff(value) {
@@ -674,11 +703,11 @@ var GitService = class {
674
703
  try {
675
704
  const currentBranch = currentBranchArg ?? getCurrentBranch(repoPath);
676
705
  if (!currentBranch) {
677
- return null;
706
+ return { status: "not_found" };
678
707
  }
679
708
  const cachedPr = this.cachedPrByRepo.get(repoName);
680
709
  if (cachedPr && cachedPr.currentBranch === currentBranch) {
681
- return cachedPr.prUrl;
710
+ return { status: "found", url: cachedPr.prUrl };
682
711
  }
683
712
  const persistedRepoState = persistedRepoStateArg ?? await loadRepoState(repoName);
684
713
  if (persistedRepoState?.prUrl && persistedRepoState.currentBranch === currentBranch) {
@@ -686,7 +715,7 @@ var GitService = class {
686
715
  prUrl: persistedRepoState.prUrl,
687
716
  currentBranch
688
717
  });
689
- return persistedRepoState.prUrl;
718
+ return { status: "found", url: persistedRepoState.prUrl };
690
719
  }
691
720
  this.cachedPrByRepo.delete(repoName);
692
721
  if (persistedRepoState?.prUrl && persistedRepoState.currentBranch !== currentBranch) {
@@ -699,10 +728,10 @@ var GitService = class {
699
728
  stdio: ["pipe", "pipe", "pipe"]
700
729
  }).trim();
701
730
  if (!remoteRef) {
702
- return null;
731
+ return { status: "not_found" };
703
732
  }
704
733
  } catch {
705
- return null;
734
+ return { status: "error" };
706
735
  }
707
736
  try {
708
737
  const prInfo = execFileSync2("gh", ["pr", "view", "--json", "url", "--jq", ".url"], {
@@ -718,17 +747,17 @@ var GitService = class {
718
747
  if (persistedRepoState) {
719
748
  await saveRepoState(repoName, { prUrl: prInfo }, persistedRepoState);
720
749
  }
721
- return prInfo;
750
+ return { status: "found", url: prInfo };
722
751
  }
723
752
  } catch (error) {
724
753
  const message = error instanceof Error ? error.message : String(error);
725
754
  console.warn(`[GitService] gh pr view failed for ${repoName}: ${message}`);
726
- return null;
755
+ return { status: "error" };
727
756
  }
728
- return null;
757
+ return { status: "not_found" };
729
758
  } catch (error) {
730
759
  console.error("Error checking for pull request:", error);
731
- return null;
760
+ return { status: "error" };
732
761
  }
733
762
  }
734
763
  resolveDefaultBranch(repoPath) {
@@ -766,12 +795,21 @@ var GitService = class {
766
795
  return normalized || "replicas";
767
796
  }
768
797
  async refreshRepoMetadata(repo, currentBranch, startHooksCompleted, persistedState) {
798
+ const prResult = await this.getPullRequestUrl(repo.name, repo.path, currentBranch, persistedState);
799
+ let prUrl;
800
+ if (prResult.status === "found") {
801
+ prUrl = prResult.url;
802
+ } else if (prResult.status === "not_found") {
803
+ prUrl = null;
804
+ } else {
805
+ prUrl = persistedState?.prUrl ?? null;
806
+ }
769
807
  const state = {
770
808
  name: repo.name,
771
809
  path: repo.path,
772
810
  defaultBranch: repo.defaultBranch,
773
811
  currentBranch,
774
- prUrl: await this.getPullRequestUrl(repo.name, repo.path, currentBranch, persistedState),
812
+ prUrl,
775
813
  gitDiff: this.getGitDiffStats(repo.path, repo.defaultBranch),
776
814
  startHooksCompleted
777
815
  };
@@ -847,6 +885,10 @@ var EngineLogger = class {
847
885
  }
848
886
  });
849
887
  }
888
+ /** Wait for all queued log writes to complete. */
889
+ flush() {
890
+ return this.writeChain;
891
+ }
850
892
  createSessionId() {
851
893
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-");
852
894
  const suffix = randomBytes(3).toString("hex");
@@ -1038,7 +1080,7 @@ function parseReplicasConfigString(content, filename) {
1038
1080
  }
1039
1081
 
1040
1082
  // ../shared/src/engine/environment.ts
1041
- var REPLICAS_ENGINE_VERSION = "20-03-2026-kipling";
1083
+ var REPLICAS_ENGINE_VERSION = "30-03-2026-kipling-v3";
1042
1084
 
1043
1085
  // ../shared/src/engine/types.ts
1044
1086
  var DEFAULT_CHAT_TITLES = {
@@ -2150,7 +2192,9 @@ var MessageQueueService = class {
2150
2192
  position: this.queue.length
2151
2193
  };
2152
2194
  }
2153
- this.startProcessing(queuedMessage);
2195
+ this.startProcessing(queuedMessage).catch((error) => {
2196
+ console.error("[MessageQueue] Unhandled error in startProcessing:", error);
2197
+ });
2154
2198
  return {
2155
2199
  queued: false,
2156
2200
  messageId,
@@ -2507,7 +2551,11 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
2507
2551
  this.activePromptStream?.close();
2508
2552
  this.activePromptStream = null;
2509
2553
  this.pendingInterrupt = false;
2510
- await this.onTurnComplete();
2554
+ try {
2555
+ await this.onTurnComplete();
2556
+ } catch (error) {
2557
+ console.error("[ClaudeManager] onTurnComplete failed:", error);
2558
+ }
2511
2559
  }
2512
2560
  }
2513
2561
  /**
@@ -2773,7 +2821,11 @@ var CodexManager = class extends CodingAgentManager {
2773
2821
  if (stopTail) {
2774
2822
  await stopTail();
2775
2823
  }
2776
- await this.onTurnComplete();
2824
+ try {
2825
+ await this.onTurnComplete();
2826
+ } catch (error) {
2827
+ console.error("[CodexManager] onTurnComplete failed:", error);
2828
+ }
2777
2829
  this.activeAbortController = null;
2778
2830
  }
2779
2831
  }
@@ -3232,10 +3284,19 @@ var ChatService = class {
3232
3284
  } catch {
3233
3285
  }
3234
3286
  const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
3235
- const repoStatuses = await gitService.refreshRepos();
3236
- console.log(`Repository Statuses Refreshed: `, repoStatuses);
3237
- const payload = linearSessionId ? { linearSessionId, repoStatuses } : { repoStatuses };
3238
- await monolithService.sendEvent({ type: "agent_turn_complete", payload });
3287
+ let repoStatuses;
3288
+ try {
3289
+ repoStatuses = await gitService.refreshRepos();
3290
+ console.log(`Repository Statuses Refreshed: `, repoStatuses);
3291
+ } catch (error) {
3292
+ console.error("[ChatService] Failed to refresh repo statuses:", error);
3293
+ }
3294
+ try {
3295
+ const payload = linearSessionId ? { linearSessionId, repoStatuses: repoStatuses ?? [] } : { repoStatuses: repoStatuses ?? [] };
3296
+ await monolithService.sendEvent({ type: "agent_turn_complete", payload });
3297
+ } catch (error) {
3298
+ console.error("[ChatService] Failed to send agent_turn_complete event:", error);
3299
+ }
3239
3300
  }
3240
3301
  };
3241
3302
 
@@ -3949,6 +4010,14 @@ function createV1Routes(deps) {
3949
4010
 
3950
4011
  // src/index.ts
3951
4012
  await engineLogger.initialize();
4013
+ process.on("uncaughtException", (error) => {
4014
+ console.error("[FATAL] Uncaught exception:", error);
4015
+ engineLogger.flush().finally(() => process.exit(1));
4016
+ });
4017
+ process.on("unhandledRejection", (reason) => {
4018
+ console.error("[FATAL] Unhandled rejection:", reason);
4019
+ engineLogger.flush().finally(() => process.exit(1));
4020
+ });
3952
4021
  await eventService.initialize();
3953
4022
  var READY_MESSAGE = "========= REPLICAS WORKSPACE READY ==========";
3954
4023
  var COMPLETION_MESSAGE = "========= REPLICAS WORKSPACE INITIALIZATION COMPLETE ==========";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.63",
3
+ "version": "0.1.65",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",