replicas-engine 0.1.15 → 0.1.16
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 +43 -28
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import "dotenv/config";
|
|
|
5
5
|
import { serve } from "@hono/node-server";
|
|
6
6
|
import { Hono as Hono3 } from "hono";
|
|
7
7
|
import { readFile as readFile2 } from "fs/promises";
|
|
8
|
+
import { execSync as execSync2 } from "child_process";
|
|
8
9
|
|
|
9
10
|
// src/middleware/auth.ts
|
|
10
11
|
var authMiddleware = async (c, next) => {
|
|
@@ -218,25 +219,25 @@ function convertCodexEvent(event, linearSessionId) {
|
|
|
218
219
|
const item = event.item;
|
|
219
220
|
if (!item) return null;
|
|
220
221
|
if (item.type === "agent_message") {
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
222
|
+
const text = "text" in item ? String(item.text || "") : "";
|
|
223
|
+
if (text) {
|
|
223
224
|
return {
|
|
224
225
|
linearSessionId,
|
|
225
226
|
content: {
|
|
226
227
|
type: "thought",
|
|
227
|
-
body:
|
|
228
|
+
body: text
|
|
228
229
|
}
|
|
229
230
|
};
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
233
|
if (item.type === "reasoning") {
|
|
233
|
-
const
|
|
234
|
-
if (
|
|
234
|
+
const text = "text" in item ? String(item.text || "") : "";
|
|
235
|
+
if (text) {
|
|
235
236
|
return {
|
|
236
237
|
linearSessionId,
|
|
237
238
|
content: {
|
|
238
239
|
type: "thought",
|
|
239
|
-
body:
|
|
240
|
+
body: text
|
|
240
241
|
}
|
|
241
242
|
};
|
|
242
243
|
}
|
|
@@ -253,23 +254,24 @@ function convertCodexEvent(event, linearSessionId) {
|
|
|
253
254
|
};
|
|
254
255
|
}
|
|
255
256
|
if (item.type === "file_change") {
|
|
256
|
-
const
|
|
257
|
+
const changes = "changes" in item && Array.isArray(item.changes) ? item.changes : [];
|
|
258
|
+
const paths = changes.map((c) => c.path || "").filter(Boolean);
|
|
257
259
|
return {
|
|
258
260
|
linearSessionId,
|
|
259
261
|
content: {
|
|
260
262
|
type: "action",
|
|
261
263
|
action: "File change",
|
|
262
|
-
parameter:
|
|
264
|
+
parameter: paths.join(", ") || ""
|
|
263
265
|
}
|
|
264
266
|
};
|
|
265
267
|
}
|
|
266
268
|
if (item.type === "mcp_tool_call") {
|
|
267
|
-
const
|
|
269
|
+
const tool = "tool" in item ? String(item.tool || "") : "";
|
|
268
270
|
return {
|
|
269
271
|
linearSessionId,
|
|
270
272
|
content: {
|
|
271
273
|
type: "action",
|
|
272
|
-
action:
|
|
274
|
+
action: tool || "MCP tool call",
|
|
273
275
|
parameter: ""
|
|
274
276
|
}
|
|
275
277
|
};
|
|
@@ -299,45 +301,45 @@ function convertCodexEvent(event, linearSessionId) {
|
|
|
299
301
|
if (event.type === "item.completed") {
|
|
300
302
|
const item = event.item;
|
|
301
303
|
if (!item) return null;
|
|
302
|
-
const getResult = () => {
|
|
303
|
-
if ("output" in item && item.output) return String(item.output);
|
|
304
|
-
if ("result" in item && item.result) return String(item.result);
|
|
305
|
-
if ("exit_code" in item) return `Exit code: ${item.exit_code}`;
|
|
306
|
-
return "Done";
|
|
307
|
-
};
|
|
308
304
|
if (item.type === "command_execution") {
|
|
309
305
|
const command = "command" in item ? String(item.command || "") : "";
|
|
306
|
+
const output = "aggregated_output" in item ? String(item.aggregated_output || "") : "";
|
|
307
|
+
const exitCode = "exit_code" in item ? item.exit_code : void 0;
|
|
308
|
+
const result = exitCode !== void 0 ? `Exit code: ${exitCode}` : output || "Done";
|
|
310
309
|
return {
|
|
311
310
|
linearSessionId,
|
|
312
311
|
content: {
|
|
313
312
|
type: "action",
|
|
314
313
|
action: "Running command",
|
|
315
314
|
parameter: command,
|
|
316
|
-
result
|
|
315
|
+
result
|
|
317
316
|
}
|
|
318
317
|
};
|
|
319
318
|
}
|
|
320
319
|
if (item.type === "file_change") {
|
|
321
|
-
const
|
|
320
|
+
const changes = "changes" in item && Array.isArray(item.changes) ? item.changes : [];
|
|
321
|
+
const paths = changes.map((c) => c.path || "").filter(Boolean);
|
|
322
|
+
const status = "status" in item ? String(item.status || "") : "";
|
|
322
323
|
return {
|
|
323
324
|
linearSessionId,
|
|
324
325
|
content: {
|
|
325
326
|
type: "action",
|
|
326
327
|
action: "File change",
|
|
327
|
-
parameter:
|
|
328
|
-
result:
|
|
328
|
+
parameter: paths.join(", ") || "",
|
|
329
|
+
result: status === "completed" ? "Done" : status || "Done"
|
|
329
330
|
}
|
|
330
331
|
};
|
|
331
332
|
}
|
|
332
333
|
if (item.type === "mcp_tool_call") {
|
|
333
|
-
const
|
|
334
|
+
const tool = "tool" in item ? String(item.tool || "") : "";
|
|
335
|
+
const status = "status" in item ? String(item.status || "") : "";
|
|
334
336
|
return {
|
|
335
337
|
linearSessionId,
|
|
336
338
|
content: {
|
|
337
339
|
type: "action",
|
|
338
|
-
action:
|
|
340
|
+
action: tool || "MCP tool call",
|
|
339
341
|
parameter: "",
|
|
340
|
-
result:
|
|
342
|
+
result: status === "completed" ? "Done" : status || "Done"
|
|
341
343
|
}
|
|
342
344
|
};
|
|
343
345
|
}
|
|
@@ -349,7 +351,7 @@ function convertCodexEvent(event, linearSessionId) {
|
|
|
349
351
|
type: "action",
|
|
350
352
|
action: "Web search",
|
|
351
353
|
parameter: query2,
|
|
352
|
-
result:
|
|
354
|
+
result: "Done"
|
|
353
355
|
}
|
|
354
356
|
};
|
|
355
357
|
}
|
|
@@ -360,18 +362,18 @@ function convertCodexEvent(event, linearSessionId) {
|
|
|
360
362
|
type: "action",
|
|
361
363
|
action: "Updating plan",
|
|
362
364
|
parameter: "",
|
|
363
|
-
result:
|
|
365
|
+
result: "Done"
|
|
364
366
|
}
|
|
365
367
|
};
|
|
366
368
|
}
|
|
367
369
|
if (item.type === "agent_message") {
|
|
368
|
-
const
|
|
369
|
-
if (
|
|
370
|
+
const text = "text" in item ? String(item.text || "") : "";
|
|
371
|
+
if (text) {
|
|
370
372
|
return {
|
|
371
373
|
linearSessionId,
|
|
372
374
|
content: {
|
|
373
375
|
type: "thought",
|
|
374
|
-
body:
|
|
376
|
+
body: text
|
|
375
377
|
}
|
|
376
378
|
};
|
|
377
379
|
}
|
|
@@ -1216,6 +1218,15 @@ async function initializeGitRepository() {
|
|
|
1216
1218
|
// src/index.ts
|
|
1217
1219
|
var READY_MESSAGE = "========= REPLICAS WORKSPACE READY ==========";
|
|
1218
1220
|
var COMPLETION_MESSAGE = "========= REPLICAS WORKSPACE INITIALIZATION COMPLETE ==========";
|
|
1221
|
+
function checkActiveSSHSessions() {
|
|
1222
|
+
try {
|
|
1223
|
+
const output = execSync2('who | grep -v "^$" | wc -l', { encoding: "utf-8" });
|
|
1224
|
+
const sessionCount = parseInt(output.trim(), 10);
|
|
1225
|
+
return sessionCount > 0;
|
|
1226
|
+
} catch {
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1219
1230
|
var app = new Hono3();
|
|
1220
1231
|
app.get("/health", async (c) => {
|
|
1221
1232
|
try {
|
|
@@ -1243,11 +1254,13 @@ app.get("/status", async (c) => {
|
|
|
1243
1254
|
const isClaudeUsed = claudeHistory.thread_id !== null;
|
|
1244
1255
|
const claudeStatus = await claudeManager.getStatus();
|
|
1245
1256
|
const workingDirectory = claudeStatus.working_directory;
|
|
1257
|
+
const hasActiveSSHSessions = checkActiveSSHSessions();
|
|
1246
1258
|
return c.json({
|
|
1247
1259
|
isCodexProcessing,
|
|
1248
1260
|
isClaudeProcessing,
|
|
1249
1261
|
isCodexUsed,
|
|
1250
1262
|
isClaudeUsed,
|
|
1263
|
+
hasActiveSSHSessions,
|
|
1251
1264
|
...getGitStatus(workingDirectory),
|
|
1252
1265
|
linearBetaEnabled: true
|
|
1253
1266
|
// TODO: delete
|
|
@@ -1283,5 +1296,7 @@ serve(
|
|
|
1283
1296
|
console.warn(`Git initialization warning: ${gitResult.error}`);
|
|
1284
1297
|
}
|
|
1285
1298
|
await githubTokenManager.start();
|
|
1299
|
+
const monolithService2 = new MonolithService();
|
|
1300
|
+
await monolithService2.sendEvent({ type: "workspace_ready", payload: {} });
|
|
1286
1301
|
}
|
|
1287
1302
|
);
|