replicas-engine 0.1.155 → 0.1.156
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 +151 -52
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -277,7 +277,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
// ../shared/src/engine/environment.ts
|
|
280
|
-
var DAYTONA_SNAPSHOT_ID = "11-05-2026-royal-york-
|
|
280
|
+
var DAYTONA_SNAPSHOT_ID = "11-05-2026-royal-york-v2";
|
|
281
281
|
|
|
282
282
|
// ../shared/src/engine/types.ts
|
|
283
283
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -1993,12 +1993,12 @@ function convertClaudeEvent(event, linearSessionId) {
|
|
|
1993
1993
|
}
|
|
1994
1994
|
};
|
|
1995
1995
|
}
|
|
1996
|
-
if (block.type === "thinking" && block.
|
|
1996
|
+
if (block.type === "thinking" && block.thinking) {
|
|
1997
1997
|
return {
|
|
1998
1998
|
linearSessionId,
|
|
1999
1999
|
content: {
|
|
2000
2000
|
type: "thought",
|
|
2001
|
-
body: block.
|
|
2001
|
+
body: block.thinking
|
|
2002
2002
|
}
|
|
2003
2003
|
};
|
|
2004
2004
|
}
|
|
@@ -4451,8 +4451,7 @@ var PlanService = class {
|
|
|
4451
4451
|
var planService = new PlanService();
|
|
4452
4452
|
|
|
4453
4453
|
// src/services/warm-hooks-service.ts
|
|
4454
|
-
import {
|
|
4455
|
-
import { promisify as promisify3 } from "util";
|
|
4454
|
+
import { spawn } from "child_process";
|
|
4456
4455
|
import { readFile as readFile11 } from "fs/promises";
|
|
4457
4456
|
import { existsSync as existsSync8 } from "fs";
|
|
4458
4457
|
import { join as join15 } from "path";
|
|
@@ -4565,34 +4564,6 @@ var WarmHookLogsService = class {
|
|
|
4565
4564
|
var warmHookLogsService = new WarmHookLogsService();
|
|
4566
4565
|
|
|
4567
4566
|
// src/services/warm-hooks-service.ts
|
|
4568
|
-
var execFileAsync2 = promisify3(execFile2);
|
|
4569
|
-
async function executeHookScript(params) {
|
|
4570
|
-
const timeout = clampWarmHookTimeoutMs(params.timeoutMs);
|
|
4571
|
-
try {
|
|
4572
|
-
const { stdout, stderr } = await execFileAsync2("bash", ["-lc", params.content], {
|
|
4573
|
-
cwd: params.cwd,
|
|
4574
|
-
timeout,
|
|
4575
|
-
maxBuffer: HOOK_EXEC_MAX_BUFFER_BYTES,
|
|
4576
|
-
env: process.env
|
|
4577
|
-
});
|
|
4578
|
-
const combined = [`$ ${params.label}`, stdout ?? "", stderr ?? ""].filter(Boolean).join("\n");
|
|
4579
|
-
return {
|
|
4580
|
-
exitCode: 0,
|
|
4581
|
-
output: combined,
|
|
4582
|
-
timedOut: false
|
|
4583
|
-
};
|
|
4584
|
-
} catch (error) {
|
|
4585
|
-
const execError = error;
|
|
4586
|
-
const timedOut = execError.signal === "SIGTERM" || execError.killed === true;
|
|
4587
|
-
const exitCode = typeof execError.code === "number" ? execError.code : 1;
|
|
4588
|
-
const combined = [`$ ${params.label}`, execError.stdout ?? "", execError.stderr ?? "", execError.message].filter(Boolean).join("\n");
|
|
4589
|
-
return {
|
|
4590
|
-
exitCode,
|
|
4591
|
-
output: combined,
|
|
4592
|
-
timedOut
|
|
4593
|
-
};
|
|
4594
|
-
}
|
|
4595
|
-
}
|
|
4596
4567
|
async function readRepoWarmHook(repoPath) {
|
|
4597
4568
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
4598
4569
|
const configPath = join15(repoPath, filename);
|
|
@@ -4635,15 +4606,79 @@ async function collectRepoWarmHooks() {
|
|
|
4635
4606
|
return collected;
|
|
4636
4607
|
}
|
|
4637
4608
|
async function runWarmHooks(params) {
|
|
4609
|
+
return runWarmHooksStreaming({ ...params, onEvent: () => {
|
|
4610
|
+
} });
|
|
4611
|
+
}
|
|
4612
|
+
async function executeHookScriptStreaming(params) {
|
|
4613
|
+
const timeout = clampWarmHookTimeoutMs(params.timeoutMs);
|
|
4614
|
+
const outputParts = [];
|
|
4615
|
+
let outputBytes = 0;
|
|
4616
|
+
let bufferExceeded = false;
|
|
4617
|
+
params.onChunk(`$ ${params.label}
|
|
4618
|
+
`);
|
|
4619
|
+
return new Promise((resolve2) => {
|
|
4620
|
+
const proc = spawn("bash", ["-lc", params.content], {
|
|
4621
|
+
cwd: params.cwd,
|
|
4622
|
+
env: process.env,
|
|
4623
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
4624
|
+
});
|
|
4625
|
+
let killed = false;
|
|
4626
|
+
const timer = setTimeout(() => {
|
|
4627
|
+
killed = true;
|
|
4628
|
+
proc.kill("SIGTERM");
|
|
4629
|
+
}, timeout);
|
|
4630
|
+
const handleData = (data) => {
|
|
4631
|
+
outputBytes += data.length;
|
|
4632
|
+
if (bufferExceeded) return;
|
|
4633
|
+
if (outputBytes > HOOK_EXEC_MAX_BUFFER_BYTES) {
|
|
4634
|
+
bufferExceeded = true;
|
|
4635
|
+
const msg = `
|
|
4636
|
+
[output truncated \u2014 exceeded ${HOOK_EXEC_MAX_BUFFER_BYTES} bytes]
|
|
4637
|
+
`;
|
|
4638
|
+
outputParts.push(msg);
|
|
4639
|
+
params.onChunk(msg);
|
|
4640
|
+
proc.kill("SIGTERM");
|
|
4641
|
+
return;
|
|
4642
|
+
}
|
|
4643
|
+
const text = data.toString();
|
|
4644
|
+
outputParts.push(text);
|
|
4645
|
+
params.onChunk(text);
|
|
4646
|
+
};
|
|
4647
|
+
proc.stdout.on("data", handleData);
|
|
4648
|
+
proc.stderr.on("data", handleData);
|
|
4649
|
+
proc.on("close", (code) => {
|
|
4650
|
+
clearTimeout(timer);
|
|
4651
|
+
const output = [`$ ${params.label}`, ...outputParts].join("");
|
|
4652
|
+
resolve2({
|
|
4653
|
+
exitCode: bufferExceeded ? 1 : code ?? 1,
|
|
4654
|
+
output,
|
|
4655
|
+
timedOut: killed && !bufferExceeded
|
|
4656
|
+
});
|
|
4657
|
+
});
|
|
4658
|
+
proc.on("error", (err) => {
|
|
4659
|
+
clearTimeout(timer);
|
|
4660
|
+
const output = [`$ ${params.label}
|
|
4661
|
+
`, ...outputParts, err.message].join("");
|
|
4662
|
+
resolve2({
|
|
4663
|
+
exitCode: 1,
|
|
4664
|
+
output,
|
|
4665
|
+
timedOut: false
|
|
4666
|
+
});
|
|
4667
|
+
});
|
|
4668
|
+
proc.stdin.end();
|
|
4669
|
+
});
|
|
4670
|
+
}
|
|
4671
|
+
async function runWarmHooksStreaming(params) {
|
|
4638
4672
|
const outputBlocks = [];
|
|
4639
4673
|
const globalHook = (params.globalWarmHook ?? params.organizationWarmHook)?.trim();
|
|
4640
4674
|
const environmentHook = params.environmentWarmHook?.trim();
|
|
4641
4675
|
if (globalHook) {
|
|
4642
|
-
const globalResult = await
|
|
4676
|
+
const globalResult = await executeHookScriptStreaming({
|
|
4643
4677
|
label: "global-warm-hook",
|
|
4644
4678
|
cwd: gitService.getWorkspaceRoot(),
|
|
4645
4679
|
content: globalHook,
|
|
4646
|
-
timeoutMs: params.timeoutMs
|
|
4680
|
+
timeoutMs: params.timeoutMs,
|
|
4681
|
+
onChunk: (chunk) => params.onEvent({ type: "output", data: chunk, label: "global-warm-hook" })
|
|
4647
4682
|
});
|
|
4648
4683
|
outputBlocks.push(globalResult.output);
|
|
4649
4684
|
await environmentDetailsService.setGlobalWarmHook(globalResult.exitCode === 0 ? "yes" : "no", globalResult.output);
|
|
@@ -4656,19 +4691,22 @@ async function runWarmHooks(params) {
|
|
|
4656
4691
|
});
|
|
4657
4692
|
if (globalResult.exitCode !== 0) {
|
|
4658
4693
|
await environmentDetailsService.setEnvironmentWarmHook("n/a");
|
|
4659
|
-
|
|
4694
|
+
const result2 = {
|
|
4660
4695
|
exitCode: globalResult.exitCode,
|
|
4661
4696
|
output: outputBlocks.join("\n\n"),
|
|
4662
4697
|
timedOut: globalResult.timedOut
|
|
4663
4698
|
};
|
|
4699
|
+
params.onEvent({ type: "complete", exitCode: result2.exitCode, timedOut: result2.timedOut });
|
|
4700
|
+
return result2;
|
|
4664
4701
|
}
|
|
4665
4702
|
}
|
|
4666
4703
|
if (environmentHook) {
|
|
4667
|
-
const envResult = await
|
|
4704
|
+
const envResult = await executeHookScriptStreaming({
|
|
4668
4705
|
label: "environment-warm-hook",
|
|
4669
4706
|
cwd: gitService.getWorkspaceRoot(),
|
|
4670
4707
|
content: environmentHook,
|
|
4671
|
-
timeoutMs: params.timeoutMs
|
|
4708
|
+
timeoutMs: params.timeoutMs,
|
|
4709
|
+
onChunk: (chunk) => params.onEvent({ type: "output", data: chunk, label: "environment-warm-hook" })
|
|
4672
4710
|
});
|
|
4673
4711
|
outputBlocks.push(envResult.output);
|
|
4674
4712
|
await environmentDetailsService.setEnvironmentWarmHook(envResult.exitCode === 0 ? "yes" : "no", envResult.output);
|
|
@@ -4680,11 +4718,13 @@ async function runWarmHooks(params) {
|
|
|
4680
4718
|
executedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4681
4719
|
});
|
|
4682
4720
|
if (envResult.exitCode !== 0) {
|
|
4683
|
-
|
|
4721
|
+
const result2 = {
|
|
4684
4722
|
exitCode: envResult.exitCode,
|
|
4685
4723
|
output: outputBlocks.join("\n\n"),
|
|
4686
4724
|
timedOut: envResult.timedOut
|
|
4687
4725
|
};
|
|
4726
|
+
params.onEvent({ type: "complete", exitCode: result2.exitCode, timedOut: result2.timedOut });
|
|
4727
|
+
return result2;
|
|
4688
4728
|
}
|
|
4689
4729
|
} else {
|
|
4690
4730
|
await environmentDetailsService.setEnvironmentWarmHook("n/a");
|
|
@@ -4707,11 +4747,12 @@ async function runWarmHooks(params) {
|
|
|
4707
4747
|
let repoTimedOut = false;
|
|
4708
4748
|
let repoExitCode = 0;
|
|
4709
4749
|
for (const command of repoHook.commands) {
|
|
4710
|
-
const repoResult = await
|
|
4750
|
+
const repoResult = await executeHookScriptStreaming({
|
|
4711
4751
|
label: `repo-warm-hook:${repoHook.repoName}`,
|
|
4712
4752
|
cwd: repoHook.repoPath,
|
|
4713
4753
|
content: command,
|
|
4714
|
-
timeoutMs: repoHook.timeoutMs
|
|
4754
|
+
timeoutMs: repoHook.timeoutMs,
|
|
4755
|
+
onChunk: (chunk) => params.onEvent({ type: "output", data: chunk, label: `repo:${repoHook.repoName}` })
|
|
4715
4756
|
});
|
|
4716
4757
|
outputBlocks.push(repoResult.output);
|
|
4717
4758
|
repoOutputBlocks.push(repoResult.output);
|
|
@@ -4734,25 +4775,23 @@ async function runWarmHooks(params) {
|
|
|
4734
4775
|
executedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4735
4776
|
});
|
|
4736
4777
|
if (repoFailed) {
|
|
4737
|
-
|
|
4778
|
+
const result2 = {
|
|
4738
4779
|
exitCode: repoExitCode,
|
|
4739
4780
|
output: outputBlocks.join("\n\n"),
|
|
4740
4781
|
timedOut: repoTimedOut
|
|
4741
4782
|
};
|
|
4783
|
+
params.onEvent({ type: "complete", exitCode: result2.exitCode, timedOut: result2.timedOut });
|
|
4784
|
+
return result2;
|
|
4742
4785
|
}
|
|
4743
4786
|
}
|
|
4744
4787
|
if (outputBlocks.length === 0) {
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
timedOut: false
|
|
4749
|
-
};
|
|
4788
|
+
const result2 = { exitCode: 0, output: "No warm hooks configured.", timedOut: false };
|
|
4789
|
+
params.onEvent({ type: "complete", exitCode: 0, timedOut: false });
|
|
4790
|
+
return result2;
|
|
4750
4791
|
}
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
timedOut: false
|
|
4755
|
-
};
|
|
4792
|
+
const result = { exitCode: 0, output: outputBlocks.join("\n\n"), timedOut: false };
|
|
4793
|
+
params.onEvent({ type: "complete", exitCode: 0, timedOut: false });
|
|
4794
|
+
return result;
|
|
4756
4795
|
}
|
|
4757
4796
|
|
|
4758
4797
|
// src/v1-routes.ts
|
|
@@ -5046,6 +5085,66 @@ function createV1Routes(deps) {
|
|
|
5046
5085
|
);
|
|
5047
5086
|
}
|
|
5048
5087
|
});
|
|
5088
|
+
app2.post("/warm-hooks/run/stream", async (c) => {
|
|
5089
|
+
try {
|
|
5090
|
+
const body = await c.req.json();
|
|
5091
|
+
const encoder = new TextEncoder();
|
|
5092
|
+
const stream = new ReadableStream({
|
|
5093
|
+
start: (controller) => {
|
|
5094
|
+
let closed = false;
|
|
5095
|
+
const safeEnqueue = (chunk) => {
|
|
5096
|
+
if (closed) return false;
|
|
5097
|
+
try {
|
|
5098
|
+
controller.enqueue(encoder.encode(chunk));
|
|
5099
|
+
return true;
|
|
5100
|
+
} catch {
|
|
5101
|
+
closed = true;
|
|
5102
|
+
return false;
|
|
5103
|
+
}
|
|
5104
|
+
};
|
|
5105
|
+
const heartbeat = setInterval(() => {
|
|
5106
|
+
if (!safeEnqueue(": ping\n\n")) clearInterval(heartbeat);
|
|
5107
|
+
}, 15e3);
|
|
5108
|
+
safeEnqueue(": connected\n\n");
|
|
5109
|
+
runWarmHooksStreaming({
|
|
5110
|
+
globalWarmHook: body.globalWarmHook,
|
|
5111
|
+
environmentWarmHook: body.environmentWarmHook,
|
|
5112
|
+
organizationWarmHook: body.organizationWarmHook,
|
|
5113
|
+
timeoutMs: body.timeoutMs,
|
|
5114
|
+
onEvent: (event) => {
|
|
5115
|
+
safeEnqueue(`data: ${JSON.stringify(event)}
|
|
5116
|
+
|
|
5117
|
+
`);
|
|
5118
|
+
}
|
|
5119
|
+
}).then(() => {
|
|
5120
|
+
clearInterval(heartbeat);
|
|
5121
|
+
if (!closed) {
|
|
5122
|
+
closed = true;
|
|
5123
|
+
controller.close();
|
|
5124
|
+
}
|
|
5125
|
+
}).catch((err) => {
|
|
5126
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
5127
|
+
safeEnqueue(`data: ${JSON.stringify({ type: "error", data: message })}
|
|
5128
|
+
|
|
5129
|
+
`);
|
|
5130
|
+
clearInterval(heartbeat);
|
|
5131
|
+
if (!closed) {
|
|
5132
|
+
closed = true;
|
|
5133
|
+
controller.close();
|
|
5134
|
+
}
|
|
5135
|
+
});
|
|
5136
|
+
}
|
|
5137
|
+
});
|
|
5138
|
+
return new Response(stream, {
|
|
5139
|
+
headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" }
|
|
5140
|
+
});
|
|
5141
|
+
} catch (error) {
|
|
5142
|
+
return c.json(
|
|
5143
|
+
jsonError("Failed to run warm hooks", error instanceof Error ? error.message : "Unknown error"),
|
|
5144
|
+
500
|
|
5145
|
+
);
|
|
5146
|
+
}
|
|
5147
|
+
});
|
|
5049
5148
|
app2.get("/warm-hooks/logs", async (c) => {
|
|
5050
5149
|
try {
|
|
5051
5150
|
const logs = await warmHookLogsService.getAllLogs();
|