replicas-engine 0.1.433 → 0.1.435
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/README.md +1 -0
- package/dist/src/index.js +96 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,6 +97,7 @@ Engine persistence locations:
|
|
|
97
97
|
- `~/.replicas/startHooks.log`
|
|
98
98
|
- Canvas read locations (for `/canvas` endpoints):
|
|
99
99
|
- `~/.claude/plans` (where Claude Code writes its plans)
|
|
100
|
+
- `~/.local/share/opencode/plans` and each repository's `.opencode/plans`
|
|
100
101
|
- `~/.replicas/canvas`
|
|
101
102
|
- Health endpoint readiness signal file:
|
|
102
103
|
- `/var/log/cloud-init-output.log` (if missing, `/health` reports `initializing`)
|
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-
|
|
509
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-14-v6";
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4230
|
-
|
|
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.
|
|
8481
|
+
var ENGINE_PACKAGE_VERSION = "0.1.435";
|
|
8468
8482
|
var INITIALIZE_METHOD = "initialize";
|
|
8469
8483
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
8470
8484
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -9210,7 +9224,7 @@ async function buildTurnInput(request) {
|
|
|
9210
9224
|
})));
|
|
9211
9225
|
return { input, tempImagePaths };
|
|
9212
9226
|
}
|
|
9213
|
-
async function buildTurnStartParams(threadId, request,
|
|
9227
|
+
async function buildTurnStartParams(threadId, request, serviceTier) {
|
|
9214
9228
|
const effort = toReasoningEffort(request.thinkingLevel);
|
|
9215
9229
|
const model = request.model ?? DEFAULT_MODEL;
|
|
9216
9230
|
const { input, tempImagePaths } = await buildTurnInput(request);
|
|
@@ -9222,16 +9236,14 @@ async function buildTurnStartParams(threadId, request, developerInstructions, se
|
|
|
9222
9236
|
...serviceTier !== void 0 ? { serviceTier } : {},
|
|
9223
9237
|
...codexApprovalPolicyOverrides(),
|
|
9224
9238
|
...effort ? { effort } : {},
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
developer_instructions: developerInstructions
|
|
9232
|
-
}
|
|
9239
|
+
collaborationMode: {
|
|
9240
|
+
mode: request.planMode ? "plan" : "default",
|
|
9241
|
+
settings: {
|
|
9242
|
+
model,
|
|
9243
|
+
reasoning_effort: effort ?? null,
|
|
9244
|
+
developer_instructions: null
|
|
9233
9245
|
}
|
|
9234
|
-
}
|
|
9246
|
+
}
|
|
9235
9247
|
},
|
|
9236
9248
|
tempImagePaths
|
|
9237
9249
|
};
|
|
@@ -9710,10 +9722,10 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
9710
9722
|
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
9711
9723
|
const serviceTier = await this.resolveRequestedServiceTier(host, request);
|
|
9712
9724
|
await this.applyThreadServiceTier(host, threadId, serviceTier);
|
|
9713
|
-
const runTurn = options.runTurn ?? ((aspHost, aspThreadId
|
|
9725
|
+
const runTurn = options.runTurn ?? ((aspHost, aspThreadId) => this.runTurn(aspHost, aspThreadId, request, serviceTier));
|
|
9714
9726
|
let completedTurn;
|
|
9715
9727
|
try {
|
|
9716
|
-
completedTurn = await runTurn(host, threadId
|
|
9728
|
+
completedTurn = await runTurn(host, threadId);
|
|
9717
9729
|
} catch (error) {
|
|
9718
9730
|
await this.refreshQuotaSnapshot(host);
|
|
9719
9731
|
if (this.quotaStatus.blocked) {
|
|
@@ -9808,8 +9820,8 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
9808
9820
|
console.warn("[CodexAspManager] Failed to apply skill registries:", error);
|
|
9809
9821
|
}
|
|
9810
9822
|
}
|
|
9811
|
-
async runTurn(host, threadId, request,
|
|
9812
|
-
const { params, tempImagePaths } = await buildTurnStartParams(threadId, request,
|
|
9823
|
+
async runTurn(host, threadId, request, serviceTier) {
|
|
9824
|
+
const { params, tempImagePaths } = await buildTurnStartParams(threadId, request, serviceTier);
|
|
9813
9825
|
return this.observeTurn(host, threadId, request, async () => {
|
|
9814
9826
|
const turnStartResponse = await host.client.request(
|
|
9815
9827
|
TURN_START_METHOD,
|
|
@@ -12276,14 +12288,22 @@ var keepAliveService = new KeepAliveService();
|
|
|
12276
12288
|
import { readdir as readdir6, readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
12277
12289
|
import { homedir as homedir13 } from "os";
|
|
12278
12290
|
import { join as join19 } from "path";
|
|
12279
|
-
var
|
|
12280
|
-
join19(homedir13(), ".
|
|
12281
|
-
join19(homedir13(), ".
|
|
12291
|
+
var GLOBAL_CANVAS_DIRECTORIES = [
|
|
12292
|
+
join19(homedir13(), ".claude", "plans"),
|
|
12293
|
+
join19(process.env.XDG_DATA_HOME ?? join19(homedir13(), ".local", "share"), "opencode", "plans"),
|
|
12294
|
+
join19(homedir13(), ".replicas", "canvas")
|
|
12282
12295
|
];
|
|
12296
|
+
async function canvasDirectories() {
|
|
12297
|
+
const repositories = await gitService.listRepositories().catch(() => []);
|
|
12298
|
+
return [
|
|
12299
|
+
...GLOBAL_CANVAS_DIRECTORIES,
|
|
12300
|
+
...repositories.map((repository) => join19(repository.path, ".opencode", "plans"))
|
|
12301
|
+
];
|
|
12302
|
+
}
|
|
12283
12303
|
var CanvasService = class {
|
|
12284
12304
|
async listItems() {
|
|
12285
12305
|
const items = /* @__PURE__ */ new Map();
|
|
12286
|
-
for (const directory of
|
|
12306
|
+
for (const directory of await canvasDirectories()) {
|
|
12287
12307
|
let entries;
|
|
12288
12308
|
try {
|
|
12289
12309
|
entries = await readdir6(directory, { withFileTypes: true });
|
|
@@ -12311,7 +12331,7 @@ var CanvasService = class {
|
|
|
12311
12331
|
const safe = sanitizeCanvasFilename(filename);
|
|
12312
12332
|
if (!safe) return null;
|
|
12313
12333
|
const { kind, mimeType } = classifyCanvasFilename(safe);
|
|
12314
|
-
for (const directory of
|
|
12334
|
+
for (const directory of await canvasDirectories()) {
|
|
12315
12335
|
const filePath = join19(directory, safe);
|
|
12316
12336
|
let sizeBytes = 0;
|
|
12317
12337
|
let updatedAt = "";
|
|
@@ -12515,6 +12535,39 @@ async function uploadChatTranscript(chatId, filePath, chat) {
|
|
|
12515
12535
|
}
|
|
12516
12536
|
}
|
|
12517
12537
|
|
|
12538
|
+
// src/services/upload-repo-state.ts
|
|
12539
|
+
var uploadQueue = Promise.resolve();
|
|
12540
|
+
async function sendRepoState(repos) {
|
|
12541
|
+
const form = new FormData();
|
|
12542
|
+
form.append(
|
|
12543
|
+
"file",
|
|
12544
|
+
new Blob([JSON.stringify({ repos })], { type: "application/json" }),
|
|
12545
|
+
"repo-state.json"
|
|
12546
|
+
);
|
|
12547
|
+
const response = await monolithRequest("/v1/engine/repo-state", { body: form });
|
|
12548
|
+
if (!response.ok) {
|
|
12549
|
+
const errorText = await response.text();
|
|
12550
|
+
throw new Error(`upload failed: ${response.status} ${errorText}`);
|
|
12551
|
+
}
|
|
12552
|
+
}
|
|
12553
|
+
function uploadRepoState(repos) {
|
|
12554
|
+
const upload = uploadQueue.then(() => sendRepoState(repos));
|
|
12555
|
+
uploadQueue = upload.catch(() => {
|
|
12556
|
+
});
|
|
12557
|
+
return upload;
|
|
12558
|
+
}
|
|
12559
|
+
async function flushRepoState() {
|
|
12560
|
+
try {
|
|
12561
|
+
const { repos, complete } = await gitService.listReposWithCompleteness({ includeDiffs: true });
|
|
12562
|
+
if (!complete) return { flushed: 0, skipped: 1, failed: 0 };
|
|
12563
|
+
await uploadRepoState(repos);
|
|
12564
|
+
return { flushed: 1, skipped: 0, failed: 0 };
|
|
12565
|
+
} catch (err) {
|
|
12566
|
+
console.error("[RepoStateUploader] upload failed:", err);
|
|
12567
|
+
return { flushed: 0, skipped: 0, failed: 1 };
|
|
12568
|
+
}
|
|
12569
|
+
}
|
|
12570
|
+
|
|
12518
12571
|
// src/services/chat/chat-service.ts
|
|
12519
12572
|
var CHAT_SENDERS_DIR = join21(ENGINE_DIR2, "chat-senders");
|
|
12520
12573
|
var CODEX_AUTH_PATH2 = join21(homedir15(), ".codex", "auth.json");
|
|
@@ -12986,11 +13039,12 @@ var ChatService = class {
|
|
|
12986
13039
|
const chatsById = new Map(
|
|
12987
13040
|
[...this.chats.entries()].map(([chatId, chat]) => [chatId, this.toSummary(chat)])
|
|
12988
13041
|
);
|
|
12989
|
-
const [chatTranscripts, canvas] = await Promise.all([
|
|
13042
|
+
const [chatTranscripts, canvas, repoState] = await Promise.all([
|
|
12990
13043
|
flushAllChatTranscripts(chatsById),
|
|
12991
|
-
flushAllCanvasItems()
|
|
13044
|
+
flushAllCanvasItems(),
|
|
13045
|
+
flushRepoState()
|
|
12992
13046
|
]);
|
|
12993
|
-
return { chatTranscripts, canvas };
|
|
13047
|
+
return { chatTranscripts, canvas, repoState };
|
|
12994
13048
|
}
|
|
12995
13049
|
createRuntimeChat(persisted) {
|
|
12996
13050
|
const saveSession = async (sessionId) => {
|
|
@@ -13293,15 +13347,23 @@ var ChatService = class {
|
|
|
13293
13347
|
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
13294
13348
|
const observedBranches = chat.observedBranchesByRepo;
|
|
13295
13349
|
chat.observedBranchesByRepo = /* @__PURE__ */ new Map();
|
|
13296
|
-
let repoStatuses;
|
|
13350
|
+
let repoStatuses = [];
|
|
13351
|
+
let repoStateComplete = false;
|
|
13297
13352
|
try {
|
|
13298
|
-
|
|
13353
|
+
const refreshed = await gitService.refreshReposWithCompleteness(observedBranches, { includeDiffs: true });
|
|
13354
|
+
repoStatuses = refreshed.repos;
|
|
13355
|
+
repoStateComplete = refreshed.complete;
|
|
13299
13356
|
console.log(`Repository Statuses Refreshed: `, repoStatuses);
|
|
13300
13357
|
} catch (error) {
|
|
13301
13358
|
console.error("[ChatService] Failed to refresh repo statuses:", error);
|
|
13302
13359
|
}
|
|
13360
|
+
if (repoStateComplete) {
|
|
13361
|
+
uploadRepoState(repoStatuses).catch((err) => {
|
|
13362
|
+
console.error("[ChatService] Failed to upload repository state:", err);
|
|
13363
|
+
});
|
|
13364
|
+
}
|
|
13303
13365
|
try {
|
|
13304
|
-
const payload = linearSessionId ? { linearSessionId, repoStatuses
|
|
13366
|
+
const payload = linearSessionId ? { linearSessionId, repoStatuses } : { repoStatuses };
|
|
13305
13367
|
await monolithService.sendEvent({ type: "agent_turn_complete", payload });
|
|
13306
13368
|
} catch (error) {
|
|
13307
13369
|
console.error("[ChatService] Failed to send agent_turn_complete event:", error);
|
|
@@ -14325,11 +14387,10 @@ function createV1Routes(deps) {
|
|
|
14325
14387
|
});
|
|
14326
14388
|
app2.get("/repos", async (c) => {
|
|
14327
14389
|
const includeDiffs = c.req.query("includeDiffs") === "true";
|
|
14328
|
-
const
|
|
14390
|
+
const repos = await gitService.listRepos({ includeDiffs });
|
|
14329
14391
|
const response = {
|
|
14330
14392
|
repos,
|
|
14331
|
-
workspaceRoot: gitService.getWorkspaceRoot()
|
|
14332
|
-
complete
|
|
14393
|
+
workspaceRoot: gitService.getWorkspaceRoot()
|
|
14333
14394
|
};
|
|
14334
14395
|
return c.json(response);
|
|
14335
14396
|
});
|