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.
- package/dist/src/index.js +90 -21
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
731
|
+
return { status: "not_found" };
|
|
703
732
|
}
|
|
704
733
|
} catch {
|
|
705
|
-
return
|
|
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
|
|
755
|
+
return { status: "error" };
|
|
727
756
|
}
|
|
728
|
-
return
|
|
757
|
+
return { status: "not_found" };
|
|
729
758
|
} catch (error) {
|
|
730
759
|
console.error("Error checking for pull request:", error);
|
|
731
|
-
return
|
|
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
|
|
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 = "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
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 ==========";
|