replicas-engine 0.1.328 → 0.1.330
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 +249 -69
- package/package.json +2 -1
package/dist/src/index.js
CHANGED
|
@@ -287,7 +287,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
287
287
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
288
288
|
|
|
289
289
|
// ../shared/src/e2b.ts
|
|
290
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-
|
|
290
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-20-v2";
|
|
291
291
|
|
|
292
292
|
// ../shared/src/runtime-env.ts
|
|
293
293
|
function parsePosixEnvFile(content) {
|
|
@@ -2123,11 +2123,13 @@ var DESKTOP_NOVNC_PORT = 6080;
|
|
|
2123
2123
|
var DEFAULT_CHAT_TITLES = {
|
|
2124
2124
|
claude: "Claude Code",
|
|
2125
2125
|
codex: "Codex",
|
|
2126
|
+
cursor: "Cursor",
|
|
2126
2127
|
relay: "Relay"
|
|
2127
2128
|
};
|
|
2128
2129
|
var CLAUDE_OPUS_1M_MODEL = "opus[1m]";
|
|
2129
2130
|
var LEGACY_CLAUDE_OPUS_1M_MODEL = "opus-1m";
|
|
2130
2131
|
var DEFAULT_CODEX_MODEL = "gpt-5.5";
|
|
2132
|
+
var DEFAULT_CURSOR_MODEL = "composer-2";
|
|
2131
2133
|
function normalizeClaudeModel(model) {
|
|
2132
2134
|
if (model === LEGACY_CLAUDE_OPUS_1M_MODEL) {
|
|
2133
2135
|
return CLAUDE_OPUS_1M_MODEL;
|
|
@@ -2137,6 +2139,7 @@ function normalizeClaudeModel(model) {
|
|
|
2137
2139
|
var AGENT_MODELS = {
|
|
2138
2140
|
claude: [CLAUDE_OPUS_1M_MODEL, "sonnet", "haiku"],
|
|
2139
2141
|
codex: [DEFAULT_CODEX_MODEL, "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex", "gpt-5.2"],
|
|
2142
|
+
cursor: [DEFAULT_CURSOR_MODEL, "composer-2.5"],
|
|
2140
2143
|
relay: [CLAUDE_OPUS_1M_MODEL, "sonnet"]
|
|
2141
2144
|
};
|
|
2142
2145
|
var MODEL_LABELS = {
|
|
@@ -2146,6 +2149,8 @@ var MODEL_LABELS = {
|
|
|
2146
2149
|
[LEGACY_CLAUDE_OPUS_1M_MODEL]: "Opus 4.8 (1M)",
|
|
2147
2150
|
haiku: "Haiku 4.5",
|
|
2148
2151
|
[DEFAULT_CODEX_MODEL]: "GPT-5.5",
|
|
2152
|
+
[DEFAULT_CURSOR_MODEL]: "Composer 2",
|
|
2153
|
+
"composer-2.5": "Composer 2.5",
|
|
2149
2154
|
"gpt-5.4": "GPT-5.4",
|
|
2150
2155
|
"gpt-5.4-mini": "GPT-5.4 Mini",
|
|
2151
2156
|
"gpt-5.3-codex": "GPT-5.3 Codex",
|
|
@@ -2825,6 +2830,7 @@ function loadEngineEnv() {
|
|
|
2825
2830
|
SLACK_THREAD_TS: readEnv("SLACK_THREAD_TS"),
|
|
2826
2831
|
ANTHROPIC_API_KEY: readEnv("ANTHROPIC_API_KEY"),
|
|
2827
2832
|
OPENAI_API_KEY: readEnv("OPENAI_API_KEY"),
|
|
2833
|
+
CURSOR_API_KEY: readEnv("CURSOR_API_KEY"),
|
|
2828
2834
|
CLAUDE_CODE_USE_BEDROCK: readEnv("CLAUDE_CODE_USE_BEDROCK"),
|
|
2829
2835
|
AWS_ACCESS_KEY_ID: readEnv("AWS_ACCESS_KEY_ID"),
|
|
2830
2836
|
AWS_SECRET_ACCESS_KEY: readEnv("AWS_SECRET_ACCESS_KEY"),
|
|
@@ -4198,6 +4204,9 @@ function detectCodexAuthMethod() {
|
|
|
4198
4204
|
}
|
|
4199
4205
|
return "none";
|
|
4200
4206
|
}
|
|
4207
|
+
function detectCursorAuthMethod() {
|
|
4208
|
+
return ENGINE_ENV.CURSOR_API_KEY ? "api_key" : "none";
|
|
4209
|
+
}
|
|
4201
4210
|
async function detectGitIdentityConfigured() {
|
|
4202
4211
|
try {
|
|
4203
4212
|
const { stdout } = await execFileAsync("git", ["config", "--global", "user.name"]);
|
|
@@ -4237,6 +4246,7 @@ function createDefaultDetails() {
|
|
|
4237
4246
|
googleAccessConfigured: false,
|
|
4238
4247
|
claudeAuthMethod: "none",
|
|
4239
4248
|
codexAuthMethod: "none",
|
|
4249
|
+
cursorAuthMethod: "none",
|
|
4240
4250
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4241
4251
|
};
|
|
4242
4252
|
}
|
|
@@ -4267,6 +4277,7 @@ var EnvironmentDetailsService = class {
|
|
|
4267
4277
|
details.engineVersion = E2B_TEMPLATE_NAME;
|
|
4268
4278
|
details.claudeAuthMethod = detectClaudeAuthMethod();
|
|
4269
4279
|
details.codexAuthMethod = detectCodexAuthMethod();
|
|
4280
|
+
details.cursorAuthMethod = detectCursorAuthMethod();
|
|
4270
4281
|
details.gitIdentityConfigured = gitIdentityConfigured;
|
|
4271
4282
|
const ghConfigured = existsSync3(GH_HOSTS_PATH);
|
|
4272
4283
|
details.githubAccessConfigured = ghConfigured;
|
|
@@ -5015,9 +5026,9 @@ async function registerDesktopPreview() {
|
|
|
5015
5026
|
|
|
5016
5027
|
// src/services/chat/chat-service.ts
|
|
5017
5028
|
import { existsSync as existsSync7 } from "fs";
|
|
5018
|
-
import { appendFile as
|
|
5029
|
+
import { appendFile as appendFile5, copyFile, mkdir as mkdir12, readFile as readFile13, rename as rename2, rm } from "fs/promises";
|
|
5019
5030
|
import { homedir as homedir14 } from "os";
|
|
5020
|
-
import { join as
|
|
5031
|
+
import { join as join18 } from "path";
|
|
5021
5032
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
5022
5033
|
|
|
5023
5034
|
// src/managers/claude-manager.ts
|
|
@@ -6290,15 +6301,19 @@ var ClaudeAuthError = class extends Error {
|
|
|
6290
6301
|
}
|
|
6291
6302
|
};
|
|
6292
6303
|
var ClaudeTransientTurnError = class extends Error {
|
|
6293
|
-
constructor(message) {
|
|
6304
|
+
constructor(message, midTurn = false) {
|
|
6294
6305
|
super(message);
|
|
6306
|
+
this.midTurn = midTurn;
|
|
6295
6307
|
this.name = "ClaudeTransientTurnError";
|
|
6296
6308
|
}
|
|
6309
|
+
midTurn;
|
|
6297
6310
|
};
|
|
6298
6311
|
var MAX_AUTH_RETRIES = 2;
|
|
6299
6312
|
var MAX_TRANSIENT_RETRIES = 2;
|
|
6313
|
+
var MAX_MIDTURN_CONTINUE_RETRIES = 2;
|
|
6300
6314
|
var TRANSIENT_RETRY_DELAYS_MS = [1e3, 2500];
|
|
6301
6315
|
var CLAUDE_TRANSIENT_HTTP_STATUSES = [408, 500, 502, 503, 504, 529];
|
|
6316
|
+
var CLAUDE_MIDTURN_CONTINUE_PROMPT = "Your previous turn was interrupted by a transient network error before it could finish. Continue from exactly where you left off. Do not repeat any tool calls, commits, messages, or other actions you have already completed \u2014 first check what is already done, then do only the remaining work.";
|
|
6302
6317
|
var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
6303
6318
|
historyFile;
|
|
6304
6319
|
sessionId = null;
|
|
@@ -6468,10 +6483,12 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6468
6483
|
let attempt = 0;
|
|
6469
6484
|
let authRetries = 0;
|
|
6470
6485
|
let transientRetries = 0;
|
|
6486
|
+
let midTurnContinues = 0;
|
|
6487
|
+
let currentRequest = request;
|
|
6471
6488
|
try {
|
|
6472
6489
|
while (true) {
|
|
6473
6490
|
try {
|
|
6474
|
-
await this.executeQuery(
|
|
6491
|
+
await this.executeQuery(currentRequest, { skipUserMessageRecord: attempt > 0 });
|
|
6475
6492
|
return;
|
|
6476
6493
|
} catch (error) {
|
|
6477
6494
|
lastError = error;
|
|
@@ -6496,6 +6513,23 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6496
6513
|
attempt++;
|
|
6497
6514
|
continue;
|
|
6498
6515
|
}
|
|
6516
|
+
if (error instanceof ClaudeTransientTurnError && error.midTurn) {
|
|
6517
|
+
if (midTurnContinues >= MAX_MIDTURN_CONTINUE_RETRIES) {
|
|
6518
|
+
await this.emitMidTurnExhaustedEvent(error);
|
|
6519
|
+
return;
|
|
6520
|
+
}
|
|
6521
|
+
midTurnContinues++;
|
|
6522
|
+
const delayMs = TRANSIENT_RETRY_DELAYS_MS[midTurnContinues - 1] ?? TRANSIENT_RETRY_DELAYS_MS[TRANSIENT_RETRY_DELAYS_MS.length - 1];
|
|
6523
|
+
console.warn(
|
|
6524
|
+
`[ClaudeManager] Mid-turn transient failure detected (attempt ${midTurnContinues}/${MAX_MIDTURN_CONTINUE_RETRIES}), resuming session and continuing in ${delayMs}ms...`,
|
|
6525
|
+
error
|
|
6526
|
+
);
|
|
6527
|
+
await this.tearDownSession();
|
|
6528
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
6529
|
+
currentRequest = { ...request, message: CLAUDE_MIDTURN_CONTINUE_PROMPT, images: [] };
|
|
6530
|
+
attempt++;
|
|
6531
|
+
continue;
|
|
6532
|
+
}
|
|
6499
6533
|
if (_ClaudeManager.isTransientTurnError(error) && transientRetries < MAX_TRANSIENT_RETRIES) {
|
|
6500
6534
|
transientRetries++;
|
|
6501
6535
|
const delayMs = TRANSIENT_RETRY_DELAYS_MS[transientRetries - 1] ?? TRANSIENT_RETRY_DELAYS_MS[TRANSIENT_RETRY_DELAYS_MS.length - 1];
|
|
@@ -6523,8 +6557,9 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6523
6557
|
}
|
|
6524
6558
|
}
|
|
6525
6559
|
}
|
|
6526
|
-
|
|
6527
|
-
|
|
6560
|
+
// `errors` is the field the dashboard renders (see claude-parser); `result` is
|
|
6561
|
+
// only retained on the raw event for debugging. The user-facing message goes in `errors`.
|
|
6562
|
+
async emitTerminalErrorResult(result, errors, logLabel) {
|
|
6528
6563
|
const event = {
|
|
6529
6564
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6530
6565
|
type: "claude-result",
|
|
@@ -6532,8 +6567,8 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6532
6567
|
type: "result",
|
|
6533
6568
|
subtype: "error_during_execution",
|
|
6534
6569
|
is_error: true,
|
|
6535
|
-
result
|
|
6536
|
-
errors
|
|
6570
|
+
result,
|
|
6571
|
+
errors,
|
|
6537
6572
|
session_id: this.sessionId ?? "",
|
|
6538
6573
|
parent_tool_use_id: null
|
|
6539
6574
|
}
|
|
@@ -6541,10 +6576,26 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6541
6576
|
try {
|
|
6542
6577
|
await appendFile2(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
6543
6578
|
} catch (writeError) {
|
|
6544
|
-
console.error(
|
|
6579
|
+
console.error(`[ClaudeManager] Failed to record ${logLabel} event:`, writeError);
|
|
6545
6580
|
}
|
|
6546
6581
|
this.onEvent(event);
|
|
6547
6582
|
}
|
|
6583
|
+
async emitAuthRetryExhaustedEvent(error) {
|
|
6584
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
6585
|
+
await this.emitTerminalErrorResult(
|
|
6586
|
+
detail,
|
|
6587
|
+
["Couldn't authenticate with Claude after multiple attempts. Check your credentials in Settings \u2192 Agents and try again."],
|
|
6588
|
+
"auth-retry-exhausted"
|
|
6589
|
+
);
|
|
6590
|
+
}
|
|
6591
|
+
async emitMidTurnExhaustedEvent(error) {
|
|
6592
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
6593
|
+
await this.emitTerminalErrorResult(
|
|
6594
|
+
detail,
|
|
6595
|
+
["The connection to Claude dropped mid-response and could not be resumed after multiple attempts."],
|
|
6596
|
+
"mid-turn-exhausted"
|
|
6597
|
+
);
|
|
6598
|
+
}
|
|
6548
6599
|
async executeQuery(request, options = {}) {
|
|
6549
6600
|
const {
|
|
6550
6601
|
message,
|
|
@@ -6772,12 +6823,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6772
6823
|
}
|
|
6773
6824
|
return;
|
|
6774
6825
|
}
|
|
6775
|
-
const transientErrorMessage = _ClaudeManager.detectTransientTurnErrorInMessage(
|
|
6776
|
-
msg,
|
|
6777
|
-
this.pendingTurn?.sawActivity ?? false
|
|
6778
|
-
);
|
|
6826
|
+
const transientErrorMessage = _ClaudeManager.detectTransientTurnErrorInMessage(msg);
|
|
6779
6827
|
if (transientErrorMessage) {
|
|
6780
|
-
this.
|
|
6828
|
+
const sawActivity = this.pendingTurn?.sawActivity ?? false;
|
|
6829
|
+
this.failPendingTurn(new ClaudeTransientTurnError(transientErrorMessage, sawActivity));
|
|
6781
6830
|
try {
|
|
6782
6831
|
response.close();
|
|
6783
6832
|
} catch (err) {
|
|
@@ -6809,7 +6858,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6809
6858
|
} finally {
|
|
6810
6859
|
this.sessionLinearForwarder?.flushThoughtAsResponse();
|
|
6811
6860
|
const pending = this.pendingTurn;
|
|
6812
|
-
const pendingError = loopError ? pending?.sawActivity && _ClaudeManager.isTransientTurnError(loopError) ? new
|
|
6861
|
+
const pendingError = loopError ? pending?.sawActivity && _ClaudeManager.isTransientTurnError(loopError) ? new ClaudeTransientTurnError("Claude session ended unexpectedly mid-response", true) : loopError : pending && !pending.sawActivity ? new ClaudeTransientTurnError("Claude session ended unexpectedly before producing a response") : new Error("Claude session ended unexpectedly");
|
|
6813
6862
|
this.failPendingTurn(pendingError);
|
|
6814
6863
|
if (this.activeQuery === response) {
|
|
6815
6864
|
this.clearSessionState();
|
|
@@ -6931,8 +6980,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6931
6980
|
static isTransientTurnErrorText(text) {
|
|
6932
6981
|
return isTransientErrorText(text, { httpStatuses: CLAUDE_TRANSIENT_HTTP_STATUSES });
|
|
6933
6982
|
}
|
|
6934
|
-
static detectTransientTurnErrorInMessage(message
|
|
6935
|
-
if (sawActivity) return null;
|
|
6983
|
+
static detectTransientTurnErrorInMessage(message) {
|
|
6936
6984
|
if (message.type === "assistant" && "error" in message && typeof message.error === "string") {
|
|
6937
6985
|
return _ClaudeManager.isTransientTurnErrorText(message.error) ? message.error : null;
|
|
6938
6986
|
}
|
|
@@ -7291,7 +7339,7 @@ var AspClient = class {
|
|
|
7291
7339
|
// src/managers/codex-asp/app-server-process.ts
|
|
7292
7340
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
7293
7341
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
7294
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
7342
|
+
var ENGINE_PACKAGE_VERSION = "0.1.330";
|
|
7295
7343
|
var INITIALIZE_METHOD = "initialize";
|
|
7296
7344
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
7297
7345
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -9089,6 +9137,120 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
9089
9137
|
}
|
|
9090
9138
|
};
|
|
9091
9139
|
|
|
9140
|
+
// src/managers/cursor-manager.ts
|
|
9141
|
+
import { appendFile as appendFile4, mkdir as mkdir11 } from "fs/promises";
|
|
9142
|
+
import { dirname as dirname4, join as join15 } from "path";
|
|
9143
|
+
import { Agent as CursorAgent } from "@cursor/sdk";
|
|
9144
|
+
var CursorManager = class extends CodingAgentManager {
|
|
9145
|
+
agent = null;
|
|
9146
|
+
activeRun = null;
|
|
9147
|
+
historyFile;
|
|
9148
|
+
constructor(options) {
|
|
9149
|
+
super(options);
|
|
9150
|
+
this.historyFile = options.historyFilePath ?? join15(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
|
|
9151
|
+
this.initializeManager(this.processMessageInternal.bind(this));
|
|
9152
|
+
}
|
|
9153
|
+
async initialize() {
|
|
9154
|
+
await mkdir11(dirname4(this.historyFile), { recursive: true });
|
|
9155
|
+
}
|
|
9156
|
+
async interruptActiveTurn() {
|
|
9157
|
+
await this.activeRun?.cancel();
|
|
9158
|
+
}
|
|
9159
|
+
async getHistory() {
|
|
9160
|
+
return {
|
|
9161
|
+
thread_id: this.agent?.agentId ?? this.initialSessionId,
|
|
9162
|
+
events: await readJSONL(this.historyFile),
|
|
9163
|
+
goal: null
|
|
9164
|
+
};
|
|
9165
|
+
}
|
|
9166
|
+
async ensureAgent(request) {
|
|
9167
|
+
if (this.agent) return this.agent;
|
|
9168
|
+
const apiKey = ENGINE_ENV.CURSOR_API_KEY;
|
|
9169
|
+
if (!apiKey) {
|
|
9170
|
+
throw new Error("Cursor API key is not configured for this workspace.");
|
|
9171
|
+
}
|
|
9172
|
+
const model = { id: request.model ?? DEFAULT_CURSOR_MODEL };
|
|
9173
|
+
this.agent = this.initialSessionId ? await CursorAgent.resume(this.initialSessionId, {
|
|
9174
|
+
apiKey,
|
|
9175
|
+
model,
|
|
9176
|
+
local: { cwd: this.workingDirectory }
|
|
9177
|
+
}) : await CursorAgent.create({
|
|
9178
|
+
apiKey,
|
|
9179
|
+
model,
|
|
9180
|
+
local: { cwd: this.workingDirectory }
|
|
9181
|
+
});
|
|
9182
|
+
await this.onSaveSessionId(this.agent.agentId);
|
|
9183
|
+
return this.agent;
|
|
9184
|
+
}
|
|
9185
|
+
async processMessageInternal(request) {
|
|
9186
|
+
try {
|
|
9187
|
+
const agent = await this.ensureAgent(request);
|
|
9188
|
+
const message = await this.toCursorMessage(request);
|
|
9189
|
+
this.recordHistoryEvent("event_msg", {
|
|
9190
|
+
type: "user_message",
|
|
9191
|
+
message: request.message
|
|
9192
|
+
});
|
|
9193
|
+
const run = await agent.send(message, {
|
|
9194
|
+
model: { id: request.model ?? DEFAULT_CURSOR_MODEL },
|
|
9195
|
+
mode: request.planMode ? "plan" : "agent"
|
|
9196
|
+
});
|
|
9197
|
+
this.activeRun = run;
|
|
9198
|
+
for await (const event of run.stream()) {
|
|
9199
|
+
this.recordCursorEvent(event);
|
|
9200
|
+
}
|
|
9201
|
+
const result = await run.wait();
|
|
9202
|
+
if (result.status === "error") {
|
|
9203
|
+
this.recordHistoryEvent("cursor-error", {
|
|
9204
|
+
type: "error",
|
|
9205
|
+
message: result.result || "Cursor run failed",
|
|
9206
|
+
runId: result.id
|
|
9207
|
+
});
|
|
9208
|
+
}
|
|
9209
|
+
} catch (error) {
|
|
9210
|
+
this.recordHistoryEvent("cursor-error", {
|
|
9211
|
+
type: "error",
|
|
9212
|
+
message: error instanceof Error ? error.message : String(error)
|
|
9213
|
+
});
|
|
9214
|
+
} finally {
|
|
9215
|
+
this.activeRun = null;
|
|
9216
|
+
await this.onTurnComplete();
|
|
9217
|
+
}
|
|
9218
|
+
}
|
|
9219
|
+
async toCursorMessage(request) {
|
|
9220
|
+
if (!request.images || request.images.length === 0) {
|
|
9221
|
+
return request.message;
|
|
9222
|
+
}
|
|
9223
|
+
const images = await normalizeImages(request.images);
|
|
9224
|
+
return {
|
|
9225
|
+
text: request.message,
|
|
9226
|
+
images: images.map((image) => ({
|
|
9227
|
+
data: image.source.data,
|
|
9228
|
+
mimeType: image.source.media_type
|
|
9229
|
+
}))
|
|
9230
|
+
};
|
|
9231
|
+
}
|
|
9232
|
+
recordCursorEvent(event) {
|
|
9233
|
+
this.recordHistoryEvent(`cursor-${event.type}`, event);
|
|
9234
|
+
}
|
|
9235
|
+
recordHistoryEvent(type, payload) {
|
|
9236
|
+
const eventPayload = {};
|
|
9237
|
+
if (payload && typeof payload === "object") {
|
|
9238
|
+
Object.assign(eventPayload, payload);
|
|
9239
|
+
} else {
|
|
9240
|
+
eventPayload.value = payload;
|
|
9241
|
+
}
|
|
9242
|
+
const event = {
|
|
9243
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9244
|
+
type,
|
|
9245
|
+
payload: eventPayload
|
|
9246
|
+
};
|
|
9247
|
+
this.onEvent(event);
|
|
9248
|
+
appendFile4(this.historyFile, `${JSON.stringify(event)}
|
|
9249
|
+
`, "utf-8").catch(() => {
|
|
9250
|
+
});
|
|
9251
|
+
}
|
|
9252
|
+
};
|
|
9253
|
+
|
|
9092
9254
|
// src/managers/relay-tools.ts
|
|
9093
9255
|
import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
9094
9256
|
import { z } from "zod";
|
|
@@ -9670,10 +9832,10 @@ var keepAliveService = new KeepAliveService();
|
|
|
9670
9832
|
// src/services/canvas-service.ts
|
|
9671
9833
|
import { readdir as readdir4, readFile as readFile11, stat as stat3 } from "fs/promises";
|
|
9672
9834
|
import { homedir as homedir12 } from "os";
|
|
9673
|
-
import { join as
|
|
9835
|
+
import { join as join16 } from "path";
|
|
9674
9836
|
var CANVAS_DIRECTORIES = [
|
|
9675
|
-
|
|
9676
|
-
|
|
9837
|
+
join16(homedir12(), ".claude", "plans"),
|
|
9838
|
+
join16(homedir12(), ".replicas", "canvas")
|
|
9677
9839
|
];
|
|
9678
9840
|
var CanvasService = class {
|
|
9679
9841
|
async listItems() {
|
|
@@ -9692,7 +9854,7 @@ var CanvasService = class {
|
|
|
9692
9854
|
const { kind } = classifyCanvasFilename(entry.name);
|
|
9693
9855
|
let sizeBytes = 0;
|
|
9694
9856
|
try {
|
|
9695
|
-
const s = await stat3(
|
|
9857
|
+
const s = await stat3(join16(directory, entry.name));
|
|
9696
9858
|
sizeBytes = s.size;
|
|
9697
9859
|
} catch {
|
|
9698
9860
|
continue;
|
|
@@ -9707,7 +9869,7 @@ var CanvasService = class {
|
|
|
9707
9869
|
if (!safe) return null;
|
|
9708
9870
|
const { kind, mimeType } = classifyCanvasFilename(safe);
|
|
9709
9871
|
for (const directory of CANVAS_DIRECTORIES) {
|
|
9710
|
-
const filePath =
|
|
9872
|
+
const filePath = join16(directory, safe);
|
|
9711
9873
|
let sizeBytes = 0;
|
|
9712
9874
|
let updatedAt = "";
|
|
9713
9875
|
try {
|
|
@@ -9844,13 +10006,13 @@ async function reconcileCanvasItems(filenames) {
|
|
|
9844
10006
|
|
|
9845
10007
|
// src/services/upload-chat-transcripts.ts
|
|
9846
10008
|
import { readdir as readdir5, readFile as readFile12 } from "fs/promises";
|
|
9847
|
-
import { basename, join as
|
|
10009
|
+
import { basename, join as join17 } from "path";
|
|
9848
10010
|
import { homedir as homedir13 } from "os";
|
|
9849
|
-
var ENGINE_DIR2 =
|
|
10011
|
+
var ENGINE_DIR2 = join17(homedir13(), ".replicas", "engine");
|
|
9850
10012
|
var HISTORY_DIRS = [
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
10013
|
+
join17(ENGINE_DIR2, "claude-histories"),
|
|
10014
|
+
join17(ENGINE_DIR2, "relay-histories"),
|
|
10015
|
+
join17(ENGINE_DIR2, "codex-histories")
|
|
9854
10016
|
];
|
|
9855
10017
|
async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
9856
10018
|
let flushed = 0;
|
|
@@ -9867,7 +10029,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
|
9867
10029
|
if (!entry.endsWith(".jsonl")) continue;
|
|
9868
10030
|
const chatId = basename(entry, ".jsonl");
|
|
9869
10031
|
tasks.push(
|
|
9870
|
-
uploadChatTranscript(chatId,
|
|
10032
|
+
uploadChatTranscript(chatId, join17(dir, entry), chatsById.get(chatId)).then(() => {
|
|
9871
10033
|
flushed++;
|
|
9872
10034
|
}).catch((err) => {
|
|
9873
10035
|
failed++;
|
|
@@ -9937,18 +10099,20 @@ var DuplicateDefaultChatError = class extends Error {
|
|
|
9937
10099
|
};
|
|
9938
10100
|
|
|
9939
10101
|
// src/services/chat/chat-service.ts
|
|
9940
|
-
var ENGINE_DIR3 =
|
|
9941
|
-
var CHATS_FILE =
|
|
9942
|
-
var CLAUDE_HISTORY_DIR =
|
|
9943
|
-
var RELAY_HISTORY_DIR =
|
|
9944
|
-
var CODEX_HISTORY_DIR =
|
|
10102
|
+
var ENGINE_DIR3 = join18(homedir14(), ".replicas", "engine");
|
|
10103
|
+
var CHATS_FILE = join18(ENGINE_DIR3, "chats.json");
|
|
10104
|
+
var CLAUDE_HISTORY_DIR = join18(ENGINE_DIR3, "claude-histories");
|
|
10105
|
+
var RELAY_HISTORY_DIR = join18(ENGINE_DIR3, "relay-histories");
|
|
10106
|
+
var CODEX_HISTORY_DIR = join18(ENGINE_DIR3, "codex-histories");
|
|
10107
|
+
var CURSOR_HISTORY_DIR = join18(ENGINE_DIR3, "cursor-histories");
|
|
9945
10108
|
var HISTORY_DIR_BY_PROVIDER = {
|
|
9946
10109
|
claude: CLAUDE_HISTORY_DIR,
|
|
9947
10110
|
relay: RELAY_HISTORY_DIR,
|
|
9948
|
-
codex: CODEX_HISTORY_DIR
|
|
10111
|
+
codex: CODEX_HISTORY_DIR,
|
|
10112
|
+
cursor: CURSOR_HISTORY_DIR
|
|
9949
10113
|
};
|
|
9950
|
-
var CHAT_SENDERS_DIR =
|
|
9951
|
-
var CODEX_AUTH_PATH2 =
|
|
10114
|
+
var CHAT_SENDERS_DIR = join18(ENGINE_DIR3, "chat-senders");
|
|
10115
|
+
var CODEX_AUTH_PATH2 = join18(homedir14(), ".codex", "auth.json");
|
|
9952
10116
|
var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
|
|
9953
10117
|
function isChatMessageSender(value) {
|
|
9954
10118
|
if (!isRecord4(value)) return false;
|
|
@@ -9998,7 +10162,7 @@ function isPersistedChat(value) {
|
|
|
9998
10162
|
return false;
|
|
9999
10163
|
}
|
|
10000
10164
|
const candidate = value;
|
|
10001
|
-
return typeof candidate.id === "string" && (candidate.provider === "claude" || candidate.provider === "codex" || candidate.provider === "relay") && typeof candidate.title === "string" && typeof candidate.createdAt === "string" && typeof candidate.updatedAt === "string" && (candidate.providerSessionId === null || typeof candidate.providerSessionId === "string") && (candidate.parentChatId === void 0 || candidate.parentChatId === null || typeof candidate.parentChatId === "string");
|
|
10165
|
+
return typeof candidate.id === "string" && (candidate.provider === "claude" || candidate.provider === "codex" || candidate.provider === "cursor" || candidate.provider === "relay") && typeof candidate.title === "string" && typeof candidate.createdAt === "string" && typeof candidate.updatedAt === "string" && (candidate.providerSessionId === null || typeof candidate.providerSessionId === "string") && (candidate.parentChatId === void 0 || candidate.parentChatId === null || typeof candidate.parentChatId === "string");
|
|
10002
10166
|
}
|
|
10003
10167
|
function normalizePersistedChat(chat) {
|
|
10004
10168
|
const isLegacyCodexSdkChat = chat.provider === "codex" && (chat.codexBackend === "sdk" || chat.codexBackend === void 0 && chat.providerSessionId !== null);
|
|
@@ -10046,11 +10210,12 @@ var ChatService = class {
|
|
|
10046
10210
|
persistInFlight = false;
|
|
10047
10211
|
persistQueued = false;
|
|
10048
10212
|
async initialize() {
|
|
10049
|
-
await
|
|
10050
|
-
await
|
|
10051
|
-
await
|
|
10052
|
-
await
|
|
10053
|
-
await
|
|
10213
|
+
await mkdir12(ENGINE_DIR3, { recursive: true });
|
|
10214
|
+
await mkdir12(CLAUDE_HISTORY_DIR, { recursive: true });
|
|
10215
|
+
await mkdir12(RELAY_HISTORY_DIR, { recursive: true });
|
|
10216
|
+
await mkdir12(CODEX_HISTORY_DIR, { recursive: true });
|
|
10217
|
+
await mkdir12(CURSOR_HISTORY_DIR, { recursive: true });
|
|
10218
|
+
await mkdir12(CHAT_SENDERS_DIR, { recursive: true });
|
|
10054
10219
|
const persisted = await this.loadChats();
|
|
10055
10220
|
for (const chat of persisted) {
|
|
10056
10221
|
const runtime = this.createRuntimeChat(chat);
|
|
@@ -10062,12 +10227,18 @@ var ChatService = class {
|
|
|
10062
10227
|
const hasCodexDefault = [...this.chats.values()].some(
|
|
10063
10228
|
(c) => c.persisted.provider === "codex" && c.persisted.title === "Codex"
|
|
10064
10229
|
);
|
|
10230
|
+
const hasCursorDefault = [...this.chats.values()].some(
|
|
10231
|
+
(c) => c.persisted.provider === "cursor" && c.persisted.title === "Cursor"
|
|
10232
|
+
);
|
|
10065
10233
|
if (!hasClaudeDefault) {
|
|
10066
10234
|
await this.createChat({ provider: "claude", title: "Claude Code" });
|
|
10067
10235
|
}
|
|
10068
10236
|
if (!hasCodexDefault) {
|
|
10069
10237
|
await this.createChat({ provider: "codex", title: "Codex" });
|
|
10070
10238
|
}
|
|
10239
|
+
if (!hasCursorDefault) {
|
|
10240
|
+
await this.createChat({ provider: "cursor", title: "Cursor" });
|
|
10241
|
+
}
|
|
10071
10242
|
const hasRelayDefault = [...this.chats.values()].some(
|
|
10072
10243
|
(c) => c.persisted.provider === "relay" && c.persisted.title === "Relay"
|
|
10073
10244
|
);
|
|
@@ -10149,11 +10320,11 @@ var ChatService = class {
|
|
|
10149
10320
|
};
|
|
10150
10321
|
}
|
|
10151
10322
|
senderFilePath(chatId) {
|
|
10152
|
-
return
|
|
10323
|
+
return join18(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
|
|
10153
10324
|
}
|
|
10154
10325
|
async appendSender(chatId, sender) {
|
|
10155
10326
|
try {
|
|
10156
|
-
await
|
|
10327
|
+
await appendFile5(this.senderFilePath(chatId), JSON.stringify(sender) + "\n", "utf-8");
|
|
10157
10328
|
} catch (error) {
|
|
10158
10329
|
console.error("[ChatService] Failed to append sender record:", error);
|
|
10159
10330
|
}
|
|
@@ -10305,7 +10476,7 @@ var ChatService = class {
|
|
|
10305
10476
|
return descendants;
|
|
10306
10477
|
}
|
|
10307
10478
|
async deleteHistoryFile(persisted) {
|
|
10308
|
-
await rm(
|
|
10479
|
+
await rm(join18(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
|
|
10309
10480
|
await rm(this.senderFilePath(persisted.id), { force: true });
|
|
10310
10481
|
}
|
|
10311
10482
|
async getChatHistory(chatId) {
|
|
@@ -10376,7 +10547,7 @@ var ChatService = class {
|
|
|
10376
10547
|
if (persisted.provider === "claude") {
|
|
10377
10548
|
provider = new ClaudeManager({
|
|
10378
10549
|
workingDirectory: this.workingDirectory,
|
|
10379
|
-
historyFilePath:
|
|
10550
|
+
historyFilePath: join18(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
10380
10551
|
initialSessionId: persisted.providerSessionId,
|
|
10381
10552
|
onSaveSessionId: saveSession,
|
|
10382
10553
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -10385,7 +10556,7 @@ var ChatService = class {
|
|
|
10385
10556
|
} else if (persisted.provider === "relay") {
|
|
10386
10557
|
provider = new RelayManager({
|
|
10387
10558
|
workingDirectory: this.workingDirectory,
|
|
10388
|
-
historyFilePath:
|
|
10559
|
+
historyFilePath: join18(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
10389
10560
|
initialSessionId: persisted.providerSessionId,
|
|
10390
10561
|
onSaveSessionId: saveSession,
|
|
10391
10562
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -10393,10 +10564,19 @@ var ChatService = class {
|
|
|
10393
10564
|
chatId: persisted.id,
|
|
10394
10565
|
codexAvailable: isCodexAvailable()
|
|
10395
10566
|
});
|
|
10567
|
+
} else if (persisted.provider === "cursor") {
|
|
10568
|
+
provider = new CursorManager({
|
|
10569
|
+
workingDirectory: this.workingDirectory,
|
|
10570
|
+
historyFilePath: join18(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
10571
|
+
initialSessionId: persisted.providerSessionId,
|
|
10572
|
+
onSaveSessionId: saveSession,
|
|
10573
|
+
onTurnComplete: onProviderTurnComplete,
|
|
10574
|
+
onEvent: onProviderEvent
|
|
10575
|
+
});
|
|
10396
10576
|
} else {
|
|
10397
10577
|
provider = new CodexAspManager({
|
|
10398
10578
|
workingDirectory: this.workingDirectory,
|
|
10399
|
-
historyFilePath:
|
|
10579
|
+
historyFilePath: join18(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
10400
10580
|
initialSessionId: persisted.providerSessionId,
|
|
10401
10581
|
onSaveSessionId: saveSession,
|
|
10402
10582
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -10535,7 +10715,7 @@ var ChatService = class {
|
|
|
10535
10715
|
});
|
|
10536
10716
|
uploadChatTranscript(
|
|
10537
10717
|
chatId,
|
|
10538
|
-
|
|
10718
|
+
join18(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
|
|
10539
10719
|
this.toSummary(chat)
|
|
10540
10720
|
).catch((err) => {
|
|
10541
10721
|
console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
|
|
@@ -10651,7 +10831,7 @@ var ChatService = class {
|
|
|
10651
10831
|
// src/services/repo-file-service.ts
|
|
10652
10832
|
import { execFile as execFile2 } from "child_process";
|
|
10653
10833
|
import { readFile as readFile14, realpath, stat as stat4 } from "fs/promises";
|
|
10654
|
-
import { join as
|
|
10834
|
+
import { join as join19, resolve as resolve2, extname } from "path";
|
|
10655
10835
|
var CACHE_TTL_MS = 3e4;
|
|
10656
10836
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
10657
10837
|
var MAX_CONTENT_BYTES = 256 * 1024;
|
|
@@ -10811,7 +10991,7 @@ var RepoFileService = class {
|
|
|
10811
10991
|
const repo = repos.find((r) => r.name === repoName);
|
|
10812
10992
|
if (!repo) return null;
|
|
10813
10993
|
try {
|
|
10814
|
-
const fullPath = await realpath(resolve2(
|
|
10994
|
+
const fullPath = await realpath(resolve2(join19(repo.path, filePath)));
|
|
10815
10995
|
const repoRoot = await realpath(repo.path);
|
|
10816
10996
|
const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
|
|
10817
10997
|
if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
|
|
@@ -10919,20 +11099,20 @@ var RepoFileService = class {
|
|
|
10919
11099
|
import { Hono } from "hono";
|
|
10920
11100
|
import { z as z2 } from "zod";
|
|
10921
11101
|
import { readdir as readdir7, stat as stat5, readFile as readFile17 } from "fs/promises";
|
|
10922
|
-
import { join as
|
|
11102
|
+
import { join as join22, resolve as resolve3 } from "path";
|
|
10923
11103
|
|
|
10924
11104
|
// src/services/warm-hooks-service.ts
|
|
10925
11105
|
import { spawn as spawn4 } from "child_process";
|
|
10926
11106
|
import { readFile as readFile16 } from "fs/promises";
|
|
10927
11107
|
import { existsSync as existsSync8 } from "fs";
|
|
10928
|
-
import { join as
|
|
11108
|
+
import { join as join21 } from "path";
|
|
10929
11109
|
|
|
10930
11110
|
// src/services/warm-hook-logs-service.ts
|
|
10931
|
-
import { mkdir as
|
|
11111
|
+
import { mkdir as mkdir13, readFile as readFile15, writeFile as writeFile6, readdir as readdir6, appendFile as appendFile6, unlink as unlink3 } from "fs/promises";
|
|
10932
11112
|
import { homedir as homedir15 } from "os";
|
|
10933
|
-
import { join as
|
|
10934
|
-
var LOGS_DIR2 =
|
|
10935
|
-
var CURRENT_RUN_LOG =
|
|
11113
|
+
import { join as join20 } from "path";
|
|
11114
|
+
var LOGS_DIR2 = join20(homedir15(), ".replicas", "warm-hook-logs");
|
|
11115
|
+
var CURRENT_RUN_LOG = join20(LOGS_DIR2, "current-run.log");
|
|
10936
11116
|
var GLOBAL_FILENAME = "global.json";
|
|
10937
11117
|
function withPreview2(stored) {
|
|
10938
11118
|
const preview = buildHookOutputPreview(stored.output);
|
|
@@ -10940,7 +11120,7 @@ function withPreview2(stored) {
|
|
|
10940
11120
|
}
|
|
10941
11121
|
var WarmHookLogsService = class {
|
|
10942
11122
|
async ensureDir() {
|
|
10943
|
-
await
|
|
11123
|
+
await mkdir13(LOGS_DIR2, { recursive: true });
|
|
10944
11124
|
}
|
|
10945
11125
|
async saveGlobalHookLog(entry) {
|
|
10946
11126
|
await this.ensureDir();
|
|
@@ -10949,7 +11129,7 @@ var WarmHookLogsService = class {
|
|
|
10949
11129
|
hookName: "organization",
|
|
10950
11130
|
...entry
|
|
10951
11131
|
};
|
|
10952
|
-
await writeFile6(
|
|
11132
|
+
await writeFile6(join20(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
|
|
10953
11133
|
`, "utf-8");
|
|
10954
11134
|
}
|
|
10955
11135
|
async saveEnvironmentHookLog(entry) {
|
|
@@ -10959,7 +11139,7 @@ var WarmHookLogsService = class {
|
|
|
10959
11139
|
hookName: "environment",
|
|
10960
11140
|
...entry
|
|
10961
11141
|
};
|
|
10962
|
-
await writeFile6(
|
|
11142
|
+
await writeFile6(join20(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
|
|
10963
11143
|
`, "utf-8");
|
|
10964
11144
|
}
|
|
10965
11145
|
async saveRepoHookLog(repoName, entry) {
|
|
@@ -10969,7 +11149,7 @@ var WarmHookLogsService = class {
|
|
|
10969
11149
|
hookName: repoName,
|
|
10970
11150
|
...entry
|
|
10971
11151
|
};
|
|
10972
|
-
await writeFile6(
|
|
11152
|
+
await writeFile6(join20(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
|
|
10973
11153
|
`, "utf-8");
|
|
10974
11154
|
}
|
|
10975
11155
|
async getAllLogs() {
|
|
@@ -10988,7 +11168,7 @@ var WarmHookLogsService = class {
|
|
|
10988
11168
|
continue;
|
|
10989
11169
|
}
|
|
10990
11170
|
try {
|
|
10991
|
-
const raw = await readFile15(
|
|
11171
|
+
const raw = await readFile15(join20(LOGS_DIR2, file), "utf-8");
|
|
10992
11172
|
const stored = JSON.parse(raw);
|
|
10993
11173
|
logs.push(withPreview2(stored));
|
|
10994
11174
|
} catch {
|
|
@@ -11013,7 +11193,7 @@ var WarmHookLogsService = class {
|
|
|
11013
11193
|
}
|
|
11014
11194
|
async appendCurrentRunLog(chunk) {
|
|
11015
11195
|
if (!chunk) return;
|
|
11016
|
-
await
|
|
11196
|
+
await appendFile6(CURRENT_RUN_LOG, chunk, "utf-8");
|
|
11017
11197
|
}
|
|
11018
11198
|
async getCurrentRunLog() {
|
|
11019
11199
|
try {
|
|
@@ -11026,7 +11206,7 @@ var WarmHookLogsService = class {
|
|
|
11026
11206
|
async getFullOutput(hookType, hookName) {
|
|
11027
11207
|
const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
11028
11208
|
try {
|
|
11029
|
-
const raw = await readFile15(
|
|
11209
|
+
const raw = await readFile15(join20(LOGS_DIR2, filename), "utf-8");
|
|
11030
11210
|
const stored = JSON.parse(raw);
|
|
11031
11211
|
if (stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
11032
11212
|
return null;
|
|
@@ -11045,7 +11225,7 @@ var warmHookLogsService = new WarmHookLogsService();
|
|
|
11045
11225
|
// src/services/warm-hooks-service.ts
|
|
11046
11226
|
async function readRepoWarmHook(repoPath) {
|
|
11047
11227
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
11048
|
-
const configPath =
|
|
11228
|
+
const configPath = join21(repoPath, filename);
|
|
11049
11229
|
if (!existsSync8(configPath)) {
|
|
11050
11230
|
continue;
|
|
11051
11231
|
}
|
|
@@ -11310,7 +11490,7 @@ var setWorkspaceNameSchema = z2.object({
|
|
|
11310
11490
|
name: z2.string().min(1).max(48)
|
|
11311
11491
|
});
|
|
11312
11492
|
var createChatSchema = z2.object({
|
|
11313
|
-
provider: z2.enum(["claude", "codex", "relay"]),
|
|
11493
|
+
provider: z2.enum(["claude", "codex", "cursor", "relay"]),
|
|
11314
11494
|
title: z2.string().min(1).optional(),
|
|
11315
11495
|
parentChatId: z2.string().uuid().optional()
|
|
11316
11496
|
});
|
|
@@ -12000,7 +12180,7 @@ function createV1Routes(deps) {
|
|
|
12000
12180
|
const logFiles = files.filter((f) => f.endsWith(".log"));
|
|
12001
12181
|
const sessions = await Promise.all(
|
|
12002
12182
|
logFiles.map(async (filename) => {
|
|
12003
|
-
const filePath =
|
|
12183
|
+
const filePath = join22(LOG_DIR, filename);
|
|
12004
12184
|
const fileStat = await stat5(filePath);
|
|
12005
12185
|
const sessionId = filename.replace(/\.log$/, "");
|
|
12006
12186
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "replicas-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.330",
|
|
4
4
|
"description": "Lightweight API server for Replicas workspaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@anthropic-ai/claude-agent-sdk": "0.3.168",
|
|
34
|
+
"@cursor/sdk": "1.0.19",
|
|
34
35
|
"@hono/node-server": "^1.19.5",
|
|
35
36
|
"hono": "^4.10.3",
|
|
36
37
|
"smol-toml": "^1.6.0",
|