replicas-engine 0.1.62 → 0.1.63

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 +83 -9
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/index.ts
4
4
  import { serve } from "@hono/node-server";
5
5
  import { Hono as Hono2 } from "hono";
6
- import { readFile as readFile12 } from "fs/promises";
6
+ import { readFile as readFile13 } from "fs/promises";
7
7
  import { execSync } from "child_process";
8
8
  import { randomUUID as randomUUID5 } from "crypto";
9
9
 
@@ -799,15 +799,18 @@ import { format } from "util";
799
799
  import { randomBytes } from "crypto";
800
800
  var LOG_DIR = join4(homedir3(), ".replicas", "logs");
801
801
  var EngineLogger = class {
802
- sessionId = null;
802
+ _sessionId = null;
803
803
  filePath = null;
804
804
  writeChain = Promise.resolve();
805
805
  patched = false;
806
+ get sessionId() {
807
+ return this._sessionId;
808
+ }
806
809
  async initialize() {
807
810
  await mkdir2(LOG_DIR, { recursive: true });
808
- this.sessionId = this.createSessionId();
809
- this.filePath = join4(LOG_DIR, `${this.sessionId}.log`);
810
- await writeFile2(this.filePath, `=== Replicas Engine Session ${this.sessionId} ===
811
+ this._sessionId = this.createSessionId();
812
+ this.filePath = join4(LOG_DIR, `${this._sessionId}.log`);
813
+ await writeFile2(this.filePath, `=== Replicas Engine Session ${this._sessionId} ===
811
814
  `, "utf-8");
812
815
  this.patchConsole();
813
816
  this.log("INFO", `Engine logging initialized at ${this.filePath}`);
@@ -2341,8 +2344,8 @@ var PromptStream = class {
2341
2344
  if (this.closed) {
2342
2345
  return Promise.resolve({ value: void 0, done: true });
2343
2346
  }
2344
- return new Promise((resolve) => {
2345
- this.waiters.push(resolve);
2347
+ return new Promise((resolve2) => {
2348
+ this.waiters.push(resolve2);
2346
2349
  });
2347
2350
  }
2348
2351
  };
@@ -2597,7 +2600,7 @@ function isJsonlEvent2(value) {
2597
2600
  return typeof value.timestamp === "string" && typeof value.type === "string" && isRecord(value.payload);
2598
2601
  }
2599
2602
  function sleep(ms) {
2600
- return new Promise((resolve) => setTimeout(resolve, ms));
2603
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
2601
2604
  }
2602
2605
  var CodexManager = class extends CodingAgentManager {
2603
2606
  codex;
@@ -3239,6 +3242,8 @@ var ChatService = class {
3239
3242
  // src/v1-routes.ts
3240
3243
  import { Hono } from "hono";
3241
3244
  import { z } from "zod";
3245
+ import { readdir as readdir6, stat as stat3, readFile as readFile12 } from "fs/promises";
3246
+ import { join as join15, resolve } from "path";
3242
3247
 
3243
3248
  // src/services/plan-service.ts
3244
3249
  import { readdir as readdir4, readFile as readFile9 } from "fs/promises";
@@ -3870,6 +3875,75 @@ function createV1Routes(deps) {
3870
3875
  return c.json(jsonError("Failed to create preview", details), 400);
3871
3876
  }
3872
3877
  });
3878
+ app2.get("/logs", async (c) => {
3879
+ try {
3880
+ const files = await readdir6(LOG_DIR).catch(() => []);
3881
+ const logFiles = files.filter((f) => f.endsWith(".log"));
3882
+ const sessions = await Promise.all(
3883
+ logFiles.map(async (filename) => {
3884
+ const filePath = join15(LOG_DIR, filename);
3885
+ const fileStat = await stat3(filePath);
3886
+ const sessionId = filename.replace(/\.log$/, "");
3887
+ return {
3888
+ sessionId,
3889
+ filename,
3890
+ sizeBytes: fileStat.size,
3891
+ updatedAt: fileStat.mtime.toISOString()
3892
+ };
3893
+ })
3894
+ );
3895
+ sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
3896
+ return c.json({
3897
+ currentSessionId: engineLogger.sessionId,
3898
+ sessions
3899
+ });
3900
+ } catch (error) {
3901
+ return c.json(
3902
+ jsonError("Failed to list logs", error instanceof Error ? error.message : "Unknown error"),
3903
+ 500
3904
+ );
3905
+ }
3906
+ });
3907
+ app2.get("/logs/:sessionId", async (c) => {
3908
+ try {
3909
+ const sessionId = c.req.param("sessionId");
3910
+ if (!sessionId || /[/\\]/.test(sessionId) || sessionId.includes("..")) {
3911
+ return c.json(jsonError("Invalid session ID"), 400);
3912
+ }
3913
+ const filePath = resolve(LOG_DIR, `${sessionId}.log`);
3914
+ if (!filePath.startsWith(resolve(LOG_DIR))) {
3915
+ return c.json(jsonError("Invalid session ID"), 400);
3916
+ }
3917
+ const offset = parseInt(c.req.query("offset") || "0", 10);
3918
+ const limit = Math.min(parseInt(c.req.query("limit") || "500", 10), 5e3);
3919
+ let content;
3920
+ try {
3921
+ content = await readFile12(filePath, "utf-8");
3922
+ } catch {
3923
+ return c.json(jsonError("Log session not found"), 404);
3924
+ }
3925
+ const allLines = content.split("\n");
3926
+ if (allLines.length > 0 && allLines[allLines.length - 1] === "") {
3927
+ allLines.pop();
3928
+ }
3929
+ const totalLines = allLines.length;
3930
+ const slicedLines = allLines.slice(offset, offset + limit);
3931
+ const hasMore = offset + limit < totalLines;
3932
+ return c.json({
3933
+ sessionId,
3934
+ totalLines,
3935
+ offset,
3936
+ limit,
3937
+ hasMore,
3938
+ lines: slicedLines
3939
+ });
3940
+ } catch (error) {
3941
+ return c.json(
3942
+ jsonError("Failed to read log", error instanceof Error ? error.message : "Unknown error"),
3943
+ 500
3944
+ );
3945
+ }
3946
+ });
3873
3947
  return app2;
3874
3948
  }
3875
3949
 
@@ -3910,7 +3984,7 @@ app.get("/health", async (c) => {
3910
3984
  return c.json({ status: "initializing", timestamp: (/* @__PURE__ */ new Date()).toISOString() }, 503);
3911
3985
  }
3912
3986
  try {
3913
- const logContent = await readFile12("/var/log/cloud-init-output.log", "utf-8");
3987
+ const logContent = await readFile13("/var/log/cloud-init-output.log", "utf-8");
3914
3988
  let status;
3915
3989
  if (logContent.includes(COMPLETION_MESSAGE)) {
3916
3990
  status = "active";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.62",
3
+ "version": "0.1.63",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",