replicas-engine 0.1.154 → 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.
Files changed (2) hide show
  1. package/dist/src/index.js +151 -52
  2. 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 = "10-05-2026-royal-york-v5";
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.text) {
1996
+ if (block.type === "thinking" && block.thinking) {
1997
1997
  return {
1998
1998
  linearSessionId,
1999
1999
  content: {
2000
2000
  type: "thought",
2001
- body: block.text
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 { execFile as execFile2 } from "child_process";
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 executeHookScript({
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
- return {
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 executeHookScript({
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
- return {
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 executeHookScript({
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
- return {
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
- return {
4746
- exitCode: 0,
4747
- output: "No warm hooks configured.",
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
- return {
4752
- exitCode: 0,
4753
- output: outputBlocks.join("\n\n"),
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.154",
3
+ "version": "0.1.156",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",