replicas-engine 0.1.28 → 0.1.30
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 +38 -27
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -630,7 +630,7 @@ var MessageQueue = class {
|
|
|
630
630
|
* Add a message to the queue or start processing immediately if not busy
|
|
631
631
|
* @returns Object indicating whether the message was queued or started processing
|
|
632
632
|
*/
|
|
633
|
-
async enqueue(message, model, customInstructions, images) {
|
|
633
|
+
async enqueue(message, model, customInstructions, images, permissionMode) {
|
|
634
634
|
const messageId = this.generateMessageId();
|
|
635
635
|
const queuedMessage = {
|
|
636
636
|
id: messageId,
|
|
@@ -638,6 +638,7 @@ var MessageQueue = class {
|
|
|
638
638
|
model,
|
|
639
639
|
customInstructions,
|
|
640
640
|
images,
|
|
641
|
+
permissionMode,
|
|
641
642
|
queuedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
642
643
|
};
|
|
643
644
|
if (this.processing) {
|
|
@@ -663,7 +664,8 @@ var MessageQueue = class {
|
|
|
663
664
|
queuedMessage.message,
|
|
664
665
|
queuedMessage.model,
|
|
665
666
|
queuedMessage.customInstructions,
|
|
666
|
-
queuedMessage.images
|
|
667
|
+
queuedMessage.images,
|
|
668
|
+
queuedMessage.permissionMode
|
|
667
669
|
);
|
|
668
670
|
} catch (error) {
|
|
669
671
|
console.error("[MessageQueue] Error processing message:", error);
|
|
@@ -983,7 +985,7 @@ Commands: ${hooks.length}
|
|
|
983
985
|
var replicasConfigService = new ReplicasConfigService();
|
|
984
986
|
|
|
985
987
|
// src/services/codex-manager.ts
|
|
986
|
-
var DEFAULT_MODEL = "gpt-5.
|
|
988
|
+
var DEFAULT_MODEL = "gpt-5.2-codex";
|
|
987
989
|
var CodexManager = class {
|
|
988
990
|
codex;
|
|
989
991
|
currentThreadId = null;
|
|
@@ -1025,9 +1027,9 @@ var CodexManager = class {
|
|
|
1025
1027
|
* If already processing, adds to queue.
|
|
1026
1028
|
* @returns Object with queued status, messageId, and position in queue
|
|
1027
1029
|
*/
|
|
1028
|
-
async enqueueMessage(message, model, customInstructions, images) {
|
|
1030
|
+
async enqueueMessage(message, model, customInstructions, images, permissionMode) {
|
|
1029
1031
|
await this.initialized;
|
|
1030
|
-
return this.messageQueue.enqueue(message, model, customInstructions, images);
|
|
1032
|
+
return this.messageQueue.enqueue(message, model, customInstructions, images, permissionMode);
|
|
1031
1033
|
}
|
|
1032
1034
|
/**
|
|
1033
1035
|
* Get the current queue status
|
|
@@ -1066,8 +1068,8 @@ var CodexManager = class {
|
|
|
1066
1068
|
* Legacy sendMessage method - now uses the queue internally
|
|
1067
1069
|
* @deprecated Use enqueueMessage for better control over queue status
|
|
1068
1070
|
*/
|
|
1069
|
-
async sendMessage(message, model, customInstructions, images) {
|
|
1070
|
-
await this.enqueueMessage(message, model, customInstructions, images);
|
|
1071
|
+
async sendMessage(message, model, customInstructions, images, permissionMode) {
|
|
1072
|
+
await this.enqueueMessage(message, model, customInstructions, images, permissionMode);
|
|
1071
1073
|
}
|
|
1072
1074
|
/**
|
|
1073
1075
|
* Helper method to save normalized images to temp files for Codex SDK
|
|
@@ -1089,7 +1091,7 @@ var CodexManager = class {
|
|
|
1089
1091
|
/**
|
|
1090
1092
|
* Internal method that actually processes the message
|
|
1091
1093
|
*/
|
|
1092
|
-
async processMessageInternal(message, model, customInstructions, images) {
|
|
1094
|
+
async processMessageInternal(message, model, customInstructions, images, permissionMode) {
|
|
1093
1095
|
const linearSessionId = process.env.LINEAR_SESSION_ID;
|
|
1094
1096
|
let tempImagePaths = [];
|
|
1095
1097
|
try {
|
|
@@ -1097,19 +1099,20 @@ var CodexManager = class {
|
|
|
1097
1099
|
const normalizedImages = await normalizeImages(images);
|
|
1098
1100
|
tempImagePaths = await this.saveImagesToTempFiles(normalizedImages);
|
|
1099
1101
|
}
|
|
1102
|
+
const sandboxMode = permissionMode === "read" ? "read-only" : "danger-full-access";
|
|
1100
1103
|
if (!this.currentThread) {
|
|
1101
1104
|
if (this.currentThreadId) {
|
|
1102
1105
|
this.currentThread = this.codex.resumeThread(this.currentThreadId, {
|
|
1103
1106
|
workingDirectory: this.workingDirectory,
|
|
1104
1107
|
skipGitRepoCheck: true,
|
|
1105
|
-
sandboxMode
|
|
1108
|
+
sandboxMode,
|
|
1106
1109
|
model: model || DEFAULT_MODEL
|
|
1107
1110
|
});
|
|
1108
1111
|
} else {
|
|
1109
1112
|
this.currentThread = this.codex.startThread({
|
|
1110
1113
|
workingDirectory: this.workingDirectory,
|
|
1111
1114
|
skipGitRepoCheck: true,
|
|
1112
|
-
sandboxMode
|
|
1115
|
+
sandboxMode,
|
|
1113
1116
|
model: model || DEFAULT_MODEL
|
|
1114
1117
|
});
|
|
1115
1118
|
const startHooksInstruction = this.getStartHooksInstruction();
|
|
@@ -1330,11 +1333,11 @@ var codexManager = new CodexManager();
|
|
|
1330
1333
|
codex.post("/send", async (c) => {
|
|
1331
1334
|
try {
|
|
1332
1335
|
const body = await c.req.json();
|
|
1333
|
-
const { message, model, customInstructions, images } = body;
|
|
1336
|
+
const { message, model, customInstructions, images, permissionMode } = body;
|
|
1334
1337
|
if (!message || typeof message !== "string") {
|
|
1335
1338
|
return c.json({ error: "Message is required and must be a string" }, 400);
|
|
1336
1339
|
}
|
|
1337
|
-
const result = await codexManager.enqueueMessage(message, model, customInstructions, images);
|
|
1340
|
+
const result = await codexManager.enqueueMessage(message, model, customInstructions, images, permissionMode);
|
|
1338
1341
|
const response = {
|
|
1339
1342
|
success: true,
|
|
1340
1343
|
message: result.queued ? `Message queued at position ${result.position}` : "Message sent successfully",
|
|
@@ -1509,9 +1512,9 @@ var ClaudeManager = class {
|
|
|
1509
1512
|
* If already processing, adds to queue.
|
|
1510
1513
|
* @returns Object with queued status, messageId, and position in queue
|
|
1511
1514
|
*/
|
|
1512
|
-
async enqueueMessage(message, model, customInstructions, images) {
|
|
1515
|
+
async enqueueMessage(message, model, customInstructions, images, permissionMode) {
|
|
1513
1516
|
await this.initialized;
|
|
1514
|
-
return this.messageQueue.enqueue(message, model, customInstructions, images);
|
|
1517
|
+
return this.messageQueue.enqueue(message, model, customInstructions, images, permissionMode);
|
|
1515
1518
|
}
|
|
1516
1519
|
/**
|
|
1517
1520
|
* Get the current queue status
|
|
@@ -1550,13 +1553,13 @@ var ClaudeManager = class {
|
|
|
1550
1553
|
* Legacy sendMessage method - now uses the queue internally
|
|
1551
1554
|
* @deprecated Use enqueueMessage for better control over queue status
|
|
1552
1555
|
*/
|
|
1553
|
-
async sendMessage(message, model, customInstructions, images) {
|
|
1554
|
-
await this.enqueueMessage(message, model, customInstructions, images);
|
|
1556
|
+
async sendMessage(message, model, customInstructions, images, permissionMode) {
|
|
1557
|
+
await this.enqueueMessage(message, model, customInstructions, images, permissionMode);
|
|
1555
1558
|
}
|
|
1556
1559
|
/**
|
|
1557
1560
|
* Internal method that actually processes the message
|
|
1558
1561
|
*/
|
|
1559
|
-
async processMessageInternal(message, model, customInstructions, images) {
|
|
1562
|
+
async processMessageInternal(message, model, customInstructions, images, permissionMode) {
|
|
1560
1563
|
const linearSessionId = process.env.LINEAR_SESSION_ID;
|
|
1561
1564
|
if (!message || !message.trim()) {
|
|
1562
1565
|
throw new Error("Message cannot be empty");
|
|
@@ -1612,8 +1615,8 @@ var ClaudeManager = class {
|
|
|
1612
1615
|
options: {
|
|
1613
1616
|
resume: this.sessionId || void 0,
|
|
1614
1617
|
cwd: this.workingDirectory,
|
|
1615
|
-
permissionMode: "bypassPermissions",
|
|
1616
|
-
allowDangerouslySkipPermissions:
|
|
1618
|
+
permissionMode: permissionMode === "read" ? "plan" : "bypassPermissions",
|
|
1619
|
+
allowDangerouslySkipPermissions: permissionMode !== "read",
|
|
1617
1620
|
settingSources: ["user", "project", "local"],
|
|
1618
1621
|
systemPrompt: {
|
|
1619
1622
|
type: "preset",
|
|
@@ -1740,11 +1743,11 @@ var claudeManager = new ClaudeManager();
|
|
|
1740
1743
|
claude.post("/send", async (c) => {
|
|
1741
1744
|
try {
|
|
1742
1745
|
const body = await c.req.json();
|
|
1743
|
-
const { message, model, customInstructions, images } = body;
|
|
1746
|
+
const { message, model, customInstructions, images, permissionMode } = body;
|
|
1744
1747
|
if (!message || typeof message !== "string") {
|
|
1745
1748
|
return c.json({ error: "Message is required and must be a string" }, 400);
|
|
1746
1749
|
}
|
|
1747
|
-
const result = await claudeManager.enqueueMessage(message, model, customInstructions, images);
|
|
1750
|
+
const result = await claudeManager.enqueueMessage(message, model, customInstructions, images, permissionMode);
|
|
1748
1751
|
const response = {
|
|
1749
1752
|
success: true,
|
|
1750
1753
|
message: result.queued ? `Message queued at position ${result.position}` : "Message sent successfully",
|
|
@@ -1887,6 +1890,7 @@ import { existsSync as existsSync3 } from "fs";
|
|
|
1887
1890
|
import { join as join5, basename } from "path";
|
|
1888
1891
|
import { homedir as homedir5 } from "os";
|
|
1889
1892
|
var PLANS_DIR = join5(homedir5(), ".replicas", "plans");
|
|
1893
|
+
var CLAUDE_PLANS_DIR = join5(homedir5(), ".claude", "plans");
|
|
1890
1894
|
function isValidFilename(filename) {
|
|
1891
1895
|
if (!filename.endsWith(".md")) {
|
|
1892
1896
|
return false;
|
|
@@ -1898,11 +1902,14 @@ async function ensurePlansDir() {
|
|
|
1898
1902
|
if (!existsSync3(PLANS_DIR)) {
|
|
1899
1903
|
await mkdir5(PLANS_DIR, { recursive: true });
|
|
1900
1904
|
}
|
|
1905
|
+
if (!existsSync3(CLAUDE_PLANS_DIR)) {
|
|
1906
|
+
await mkdir5(CLAUDE_PLANS_DIR, { recursive: true });
|
|
1907
|
+
}
|
|
1901
1908
|
}
|
|
1902
1909
|
async function listPlans() {
|
|
1903
1910
|
await ensurePlansDir();
|
|
1904
1911
|
try {
|
|
1905
|
-
const files = await readdir2(PLANS_DIR);
|
|
1912
|
+
const files = [...await readdir2(PLANS_DIR), ...await readdir2(CLAUDE_PLANS_DIR)];
|
|
1906
1913
|
return files.filter((file) => file.endsWith(".md")).sort((a, b) => a.localeCompare(b));
|
|
1907
1914
|
} catch {
|
|
1908
1915
|
return [];
|
|
@@ -1913,12 +1920,16 @@ async function getPlanContent(filename) {
|
|
|
1913
1920
|
throw new Error("Invalid filename");
|
|
1914
1921
|
}
|
|
1915
1922
|
await ensurePlansDir();
|
|
1916
|
-
const
|
|
1917
|
-
|
|
1918
|
-
|
|
1923
|
+
const safeName = basename(filename);
|
|
1924
|
+
const replicasPath = join5(PLANS_DIR, safeName);
|
|
1925
|
+
const claudePath = join5(CLAUDE_PLANS_DIR, safeName);
|
|
1926
|
+
if (existsSync3(replicasPath)) {
|
|
1927
|
+
return await readFile4(replicasPath, "utf-8");
|
|
1928
|
+
}
|
|
1929
|
+
if (existsSync3(claudePath)) {
|
|
1930
|
+
return await readFile4(claudePath, "utf-8");
|
|
1919
1931
|
}
|
|
1920
|
-
|
|
1921
|
-
return content;
|
|
1932
|
+
throw new Error("Plan not found");
|
|
1922
1933
|
}
|
|
1923
1934
|
|
|
1924
1935
|
// src/routes/plans.ts
|