replicas-engine 0.1.26 → 0.1.28

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 +103 -17
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  // src/index.ts
4
4
  import "dotenv/config";
5
5
  import { serve } from "@hono/node-server";
6
- import { Hono as Hono3 } from "hono";
7
- import { readFile as readFile4 } from "fs/promises";
6
+ import { Hono as Hono4 } from "hono";
7
+ import { readFile as readFile5 } from "fs/promises";
8
8
  import { execSync as execSync2 } from "child_process";
9
9
 
10
10
  // src/middleware/auth.ts
@@ -1178,11 +1178,10 @@ var CodexManager = class {
1178
1178
  });
1179
1179
  }
1180
1180
  } finally {
1181
- if (linearSessionId) {
1182
- const status = await getGitStatus(this.workingDirectory);
1183
- monolithService.sendEvent({ type: "agent_turn_complete", payload: { linearSessionId, status } }).catch(() => {
1184
- });
1185
- }
1181
+ const status = await getGitStatus(this.workingDirectory);
1182
+ const payload = linearSessionId ? { linearSessionId, status } : { status };
1183
+ monolithService.sendEvent({ type: "agent_turn_complete", payload }).catch(() => {
1184
+ });
1186
1185
  }
1187
1186
  }
1188
1187
  async getHistory() {
@@ -1651,11 +1650,10 @@ var ClaudeManager = class {
1651
1650
  });
1652
1651
  }
1653
1652
  } finally {
1654
- if (linearSessionId) {
1655
- const status = await getGitStatus(this.workingDirectory);
1656
- monolithService.sendEvent({ type: "agent_turn_complete", payload: { linearSessionId, status } }).catch(() => {
1657
- });
1658
- }
1653
+ const status = await getGitStatus(this.workingDirectory);
1654
+ const payload = linearSessionId ? { linearSessionId, status } : { status };
1655
+ monolithService.sendEvent({ type: "agent_turn_complete", payload }).catch(() => {
1656
+ });
1659
1657
  }
1660
1658
  }
1661
1659
  async getHistory() {
@@ -1880,6 +1878,93 @@ claude.post("/reset", async (c) => {
1880
1878
  });
1881
1879
  var claude_default = claude;
1882
1880
 
1881
+ // src/routes/plans.ts
1882
+ import { Hono as Hono3 } from "hono";
1883
+
1884
+ // src/services/plans-service.ts
1885
+ import { readFile as readFile4, readdir as readdir2, mkdir as mkdir5 } from "fs/promises";
1886
+ import { existsSync as existsSync3 } from "fs";
1887
+ import { join as join5, basename } from "path";
1888
+ import { homedir as homedir5 } from "os";
1889
+ var PLANS_DIR = join5(homedir5(), ".replicas", "plans");
1890
+ function isValidFilename(filename) {
1891
+ if (!filename.endsWith(".md")) {
1892
+ return false;
1893
+ }
1894
+ const safePattern = /^[a-zA-Z0-9_-]+\.md$/;
1895
+ return safePattern.test(filename);
1896
+ }
1897
+ async function ensurePlansDir() {
1898
+ if (!existsSync3(PLANS_DIR)) {
1899
+ await mkdir5(PLANS_DIR, { recursive: true });
1900
+ }
1901
+ }
1902
+ async function listPlans() {
1903
+ await ensurePlansDir();
1904
+ try {
1905
+ const files = await readdir2(PLANS_DIR);
1906
+ return files.filter((file) => file.endsWith(".md")).sort((a, b) => a.localeCompare(b));
1907
+ } catch {
1908
+ return [];
1909
+ }
1910
+ }
1911
+ async function getPlanContent(filename) {
1912
+ if (!isValidFilename(filename)) {
1913
+ throw new Error("Invalid filename");
1914
+ }
1915
+ await ensurePlansDir();
1916
+ const filePath = join5(PLANS_DIR, basename(filename));
1917
+ if (!existsSync3(filePath)) {
1918
+ throw new Error("Plan not found");
1919
+ }
1920
+ const content = await readFile4(filePath, "utf-8");
1921
+ return content;
1922
+ }
1923
+
1924
+ // src/routes/plans.ts
1925
+ var plans = new Hono3();
1926
+ plans.get("/", async (c) => {
1927
+ try {
1928
+ const planFiles = await listPlans();
1929
+ return c.json({ plans: planFiles });
1930
+ } catch (error) {
1931
+ return c.json(
1932
+ {
1933
+ error: "Failed to list plans",
1934
+ details: error instanceof Error ? error.message : "Unknown error"
1935
+ },
1936
+ 500
1937
+ );
1938
+ }
1939
+ });
1940
+ plans.get("/:filename", async (c) => {
1941
+ const filename = c.req.param("filename");
1942
+ if (!filename) {
1943
+ return c.json({ error: "Filename is required" }, 400);
1944
+ }
1945
+ try {
1946
+ const content = await getPlanContent(filename);
1947
+ return c.json({ content, filename });
1948
+ } catch (error) {
1949
+ if (error instanceof Error) {
1950
+ if (error.message === "Invalid filename") {
1951
+ return c.json({ error: "Invalid filename" }, 400);
1952
+ }
1953
+ if (error.message === "Plan not found") {
1954
+ return c.json({ error: "Plan not found" }, 404);
1955
+ }
1956
+ }
1957
+ return c.json(
1958
+ {
1959
+ error: "Failed to read plan",
1960
+ details: error instanceof Error ? error.message : "Unknown error"
1961
+ },
1962
+ 500
1963
+ );
1964
+ }
1965
+ });
1966
+ var plans_default = plans;
1967
+
1883
1968
  // src/services/github-token-manager.ts
1884
1969
  import { promises as fs } from "fs";
1885
1970
  import path from "path";
@@ -2138,7 +2223,7 @@ var CodexTokenManager = class {
2138
2223
  var codexTokenManager = new CodexTokenManager();
2139
2224
 
2140
2225
  // src/services/git-init.ts
2141
- import { existsSync as existsSync3 } from "fs";
2226
+ import { existsSync as existsSync4 } from "fs";
2142
2227
  import path4 from "path";
2143
2228
  var initializedBranch = null;
2144
2229
  function findAvailableBranchName(baseName, cwd) {
@@ -2174,7 +2259,7 @@ async function initializeGitRepository() {
2174
2259
  };
2175
2260
  }
2176
2261
  const repoPath = path4.join(workspaceHome, "workspaces", repoName);
2177
- if (!existsSync3(repoPath)) {
2262
+ if (!existsSync4(repoPath)) {
2178
2263
  console.log(`[GitInit] Repository directory does not exist: ${repoPath}`);
2179
2264
  console.log("[GitInit] Waiting for initializer to clone the repository...");
2180
2265
  return {
@@ -2182,7 +2267,7 @@ async function initializeGitRepository() {
2182
2267
  branch: null
2183
2268
  };
2184
2269
  }
2185
- if (!existsSync3(path4.join(repoPath, ".git"))) {
2270
+ if (!existsSync4(path4.join(repoPath, ".git"))) {
2186
2271
  return {
2187
2272
  success: false,
2188
2273
  branch: null,
@@ -2262,10 +2347,10 @@ function checkActiveSSHSessions() {
2262
2347
  return false;
2263
2348
  }
2264
2349
  }
2265
- var app = new Hono3();
2350
+ var app = new Hono4();
2266
2351
  app.get("/health", async (c) => {
2267
2352
  try {
2268
- const logContent = await readFile4("/var/log/cloud-init-output.log", "utf-8");
2353
+ const logContent = await readFile5("/var/log/cloud-init-output.log", "utf-8");
2269
2354
  let status;
2270
2355
  if (logContent.includes(COMPLETION_MESSAGE)) {
2271
2356
  status = "active";
@@ -2313,6 +2398,7 @@ app.get("/status", async (c) => {
2313
2398
  app.use("*", authMiddleware);
2314
2399
  app.route("/codex", codex_default);
2315
2400
  app.route("/claude", claude_default);
2401
+ app.route("/plans", plans_default);
2316
2402
  var port = Number(process.env.PORT) || 3737;
2317
2403
  serve(
2318
2404
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",