replicas-engine 0.1.341 → 0.1.343
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 +114 -8
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -295,7 +295,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
295
295
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
296
296
|
|
|
297
297
|
// ../shared/src/e2b.ts
|
|
298
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-
|
|
298
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-25-v1";
|
|
299
299
|
|
|
300
300
|
// ../shared/src/runtime-env.ts
|
|
301
301
|
function parsePosixEnvFile(content) {
|
|
@@ -1641,7 +1641,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
|
|
|
1641
1641
|
| \`replicas connect <name>\` | SSH into another workspace (requires user creds \u2014 usually only useful when scripting locally) |
|
|
1642
1642
|
| \`replicas repos\` | List repos connected to the org |
|
|
1643
1643
|
| \`replicas environment ...\` | Manage environments, env vars, env files |
|
|
1644
|
-
| \`replicas automation ...\` | Manage automations (cron + GitHub event triggers) |
|
|
1644
|
+
| \`replicas automation ...\` | Manage automations (cron + GitHub/GitLab event triggers) |
|
|
1645
1645
|
| \`replicas preview ...\` | Register / list preview URLs (covered in \`PREVIEWS.md\`) |
|
|
1646
1646
|
| \`replicas media ...\` | Upload screenshots, videos, audio (covered in \`MEDIA.md\`) |
|
|
1647
1647
|
|
|
@@ -1659,6 +1659,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
|
|
|
1659
1659
|
| "Run my nightly automation now" | \`replicas automation run <id>\` |
|
|
1660
1660
|
| "Make an automation that runs every weekday at 9am" | \`replicas automation create\` (interactive) or \`--trigger-cron "0 9 * * 1-5"\` |
|
|
1661
1661
|
| "Make an automation that runs when a PR opens on \`acme/web\`" | \`replicas automation create ... --trigger-github pull_request.opened --trigger-github-repos acme/web\` |
|
|
1662
|
+
| "Make an automation that runs when an MR opens on \`acme/web\`" | \`replicas automation create ... --trigger-gitlab merge_request.opened --trigger-gitlab-repos acme/web\` |
|
|
1662
1663
|
| "What repos are connected?" | \`replicas repos\` |
|
|
1663
1664
|
| "Set up a \`replicas.json\` in this repo" | \`replicas init\` (\`-y\` for YAML) |
|
|
1664
1665
|
|
|
@@ -1717,7 +1718,7 @@ Constraints:
|
|
|
1717
1718
|
|
|
1718
1719
|
## Automations
|
|
1719
1720
|
|
|
1720
|
-
Automations are saved prompts with one or more triggers (cron schedules and/or GitHub events). When fired, they create a workspace using the configured environment and run the prompt with the user's coding agent.
|
|
1721
|
+
Automations are saved prompts with one or more triggers (cron schedules and/or GitHub or GitLab events). When fired, they create a workspace using the configured environment and run the prompt with the user's coding agent.
|
|
1721
1722
|
|
|
1722
1723
|
### List / get / run / delete
|
|
1723
1724
|
|
|
@@ -1747,6 +1748,12 @@ replicas automation create "Review my PRs" \\
|
|
|
1747
1748
|
--trigger-github pull_request.opened \\
|
|
1748
1749
|
--trigger-github-repos acme/web,acme/api
|
|
1749
1750
|
|
|
1751
|
+
replicas automation create "Review my MRs" \\
|
|
1752
|
+
--prompt "Leave a code review on this MR" \\
|
|
1753
|
+
--environment <env-name-or-id> \\
|
|
1754
|
+
--trigger-gitlab merge_request.opened \\
|
|
1755
|
+
--trigger-gitlab-repos acme/web,acme/api
|
|
1756
|
+
|
|
1750
1757
|
# Disable on creation
|
|
1751
1758
|
replicas automation create ... --disabled
|
|
1752
1759
|
|
|
@@ -2466,6 +2473,8 @@ function findPrMergeSignals(request) {
|
|
|
2466
2473
|
["gh-pr-merge", /\bgh\s+pr\s+merge\b/],
|
|
2467
2474
|
["gh-api-pulls-merge", /\bgh\s+api\b[\s\S]*\/pulls\/(?:\d+|[^/\s]+)\/merge\b/],
|
|
2468
2475
|
["github-rest-pulls-merge", /api\.github\.com\/repos\/[^/\s]+\/[^/\s]+\/pulls\/(?:\d+|[^/\s]+)\/merge\b/],
|
|
2476
|
+
["gitlab-rest-mr-merge", /\/projects\/[^/\s]+\/merge_requests\/(?:\d+|[^/\s]+)\/merge\b/],
|
|
2477
|
+
["gitlab-rest-mr-merge-query", /\/projects\/[^/\s]+\/merge_requests\/(?:\d+|[^/\s]+)\b[\s\S]*\bmerge_when_pipeline_succeeds\b/],
|
|
2469
2478
|
["github-rest-ref-update", /\b(?:gh\s+api|curl|wget|python3?)\b[\s\S]*(?:\/repos\/|repos\/)[^/\s]+\/[^/\s]+\/git\/refs\/heads\/(?:main|master|trunk|develop)\b[\s\S]*\b(?:patch|put|sha|oid|force)\b/],
|
|
2470
2479
|
["github-graphql-merge-pr", /\bmergepullrequest\b/],
|
|
2471
2480
|
["github-graphql-enable-auto-merge", /\benablepullrequestautomerge\b/],
|
|
@@ -2480,7 +2489,7 @@ function findPrMergeSignals(request) {
|
|
|
2480
2489
|
["hub-merge", /\bhub\s+merge\b/],
|
|
2481
2490
|
["obfuscated-gh-pr-merge", /printf\s+['"]\\x67\\x68['"][\s\S]*\bpr\b[\s\S]*printf\s+['"]m\\x65rge['"]/],
|
|
2482
2491
|
["mcp-merge-tool", /\bmcp__[^\s"]*merge[^\s"]*\b/],
|
|
2483
|
-
["tool-merge-name", /\b(pr|pull[_-]?request).{0,40}\bmerge\b|\bmerge.{0,40}(pr|pull[_-]?request)\b/],
|
|
2492
|
+
["tool-merge-name", /\b(pr|pull[_-]?request|mr|merge[_-]?request).{0,40}\bmerge\b|\bmerge.{0,40}(pr|pull[_-]?request|mr|merge[_-]?request)\b/],
|
|
2484
2493
|
["merge-word", /(?:^|[^a-z0-9])merge(?:$|[^a-z0-9])/]
|
|
2485
2494
|
];
|
|
2486
2495
|
return checks.flatMap(([name, pattern]) => pattern.test(combined) ? [name] : []);
|
|
@@ -4345,6 +4354,7 @@ var CLAUDE_CREDENTIALS_PATH = join7(homedir5(), ".claude", ".credentials.json");
|
|
|
4345
4354
|
var CODEX_AUTH_PATH = join7(homedir5(), ".codex", "auth.json");
|
|
4346
4355
|
var OPENCODE_AUTH_PATH = join7(homedir5(), ".local", "share", "opencode", "auth.json");
|
|
4347
4356
|
var GH_HOSTS_PATH = join7(homedir5(), ".config", "gh", "hosts.yml");
|
|
4357
|
+
var GIT_CREDENTIALS_PATH = join7(homedir5(), ".git-credentials");
|
|
4348
4358
|
function detectClaudeAuthMethod() {
|
|
4349
4359
|
if (existsSync3(CLAUDE_CREDENTIALS_PATH)) {
|
|
4350
4360
|
return "oauth";
|
|
@@ -4380,6 +4390,20 @@ async function detectGitIdentityConfigured() {
|
|
|
4380
4390
|
return false;
|
|
4381
4391
|
}
|
|
4382
4392
|
}
|
|
4393
|
+
async function detectGitLabAccessConfigured() {
|
|
4394
|
+
try {
|
|
4395
|
+
const credentials = await readFile4(GIT_CREDENTIALS_PATH, "utf-8");
|
|
4396
|
+
return credentials.split("\n").some((line) => {
|
|
4397
|
+
try {
|
|
4398
|
+
return new URL(line).username === "oauth2";
|
|
4399
|
+
} catch {
|
|
4400
|
+
return false;
|
|
4401
|
+
}
|
|
4402
|
+
});
|
|
4403
|
+
} catch {
|
|
4404
|
+
return false;
|
|
4405
|
+
}
|
|
4406
|
+
}
|
|
4383
4407
|
function upsertRepositoryStatus(current, incoming) {
|
|
4384
4408
|
const byName = new Map(current.map((r) => [r.repositoryName, r]));
|
|
4385
4409
|
for (const repo of incoming) {
|
|
@@ -4405,9 +4429,11 @@ function createDefaultDetails() {
|
|
|
4405
4429
|
mcpsInstalled: [],
|
|
4406
4430
|
gitIdentityConfigured: false,
|
|
4407
4431
|
githubCredentialsConfigured: false,
|
|
4432
|
+
gitlabCredentialsConfigured: false,
|
|
4408
4433
|
linearAccessConfigured: false,
|
|
4409
4434
|
slackAccessConfigured: false,
|
|
4410
4435
|
githubAccessConfigured: false,
|
|
4436
|
+
gitlabAccessConfigured: false,
|
|
4411
4437
|
googleAccessConfigured: false,
|
|
4412
4438
|
claudeAuthMethod: "none",
|
|
4413
4439
|
codexAuthMethod: "none",
|
|
@@ -4435,10 +4461,11 @@ async function writeDetails(details) {
|
|
|
4435
4461
|
}
|
|
4436
4462
|
var EnvironmentDetailsService = class {
|
|
4437
4463
|
async getDetails() {
|
|
4438
|
-
const [details, repositories, gitIdentityConfigured] = await Promise.all([
|
|
4464
|
+
const [details, repositories, gitIdentityConfigured, gitlabAccessConfigured] = await Promise.all([
|
|
4439
4465
|
readDetails(),
|
|
4440
4466
|
gitService.listRepositories(),
|
|
4441
|
-
detectGitIdentityConfigured()
|
|
4467
|
+
detectGitIdentityConfigured(),
|
|
4468
|
+
detectGitLabAccessConfigured()
|
|
4442
4469
|
]);
|
|
4443
4470
|
details.engineVersion = E2B_TEMPLATE_NAME;
|
|
4444
4471
|
details.claudeAuthMethod = detectClaudeAuthMethod();
|
|
@@ -4449,6 +4476,8 @@ var EnvironmentDetailsService = class {
|
|
|
4449
4476
|
const ghConfigured = existsSync3(GH_HOSTS_PATH);
|
|
4450
4477
|
details.githubAccessConfigured = ghConfigured;
|
|
4451
4478
|
details.githubCredentialsConfigured = ghConfigured;
|
|
4479
|
+
details.gitlabAccessConfigured = gitlabAccessConfigured;
|
|
4480
|
+
details.gitlabCredentialsConfigured = gitlabAccessConfigured;
|
|
4452
4481
|
details.linearAccessConfigured = Boolean(ENGINE_ENV.LINEAR_SESSION_ID || ENGINE_ENV.LINEAR_ACCESS_TOKEN);
|
|
4453
4482
|
details.slackAccessConfigured = Boolean(ENGINE_ENV.SLACK_BOT_TOKEN);
|
|
4454
4483
|
const freshRepos = repositories.map((repo) => ({
|
|
@@ -7548,7 +7577,7 @@ var AspClient = class {
|
|
|
7548
7577
|
// src/managers/codex-asp/app-server-process.ts
|
|
7549
7578
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
7550
7579
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
7551
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
7580
|
+
var ENGINE_PACKAGE_VERSION = "0.1.343";
|
|
7552
7581
|
var INITIALIZE_METHOD = "initialize";
|
|
7553
7582
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
7554
7583
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -9320,9 +9349,20 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
9320
9349
|
import { mkdir as mkdir11 } from "fs/promises";
|
|
9321
9350
|
import { dirname as dirname5, join as join15 } from "path";
|
|
9322
9351
|
import { Agent as CursorAgent } from "@cursor/sdk";
|
|
9352
|
+
var CURSOR_COMPOSER_CONTEXT_WINDOW = 2e5;
|
|
9353
|
+
var CURSOR_CATEGORY_COLORS = {
|
|
9354
|
+
input: "#3eeba3",
|
|
9355
|
+
cacheRead: "#61afef",
|
|
9356
|
+
cacheWrite: "#e5c07b",
|
|
9357
|
+
output: "#56b6c2"
|
|
9358
|
+
};
|
|
9359
|
+
function finiteNumber(value) {
|
|
9360
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
9361
|
+
}
|
|
9323
9362
|
var CursorManager = class extends CodingAgentManager {
|
|
9324
9363
|
agent = null;
|
|
9325
9364
|
activeRun = null;
|
|
9365
|
+
activeModel = null;
|
|
9326
9366
|
historyFilePath;
|
|
9327
9367
|
historyFile;
|
|
9328
9368
|
constructor(options) {
|
|
@@ -9369,15 +9409,17 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
9369
9409
|
try {
|
|
9370
9410
|
const agent = await this.ensureAgent(request);
|
|
9371
9411
|
const message = await this.toCursorMessage(request);
|
|
9412
|
+
const model = request.model ?? DEFAULT_CURSOR_MODEL;
|
|
9372
9413
|
this.recordHistoryEvent("event_msg", {
|
|
9373
9414
|
type: "user_message",
|
|
9374
9415
|
message: request.message
|
|
9375
9416
|
}, this.historyFile);
|
|
9376
9417
|
const run = await agent.send(message, {
|
|
9377
|
-
model: { id:
|
|
9418
|
+
model: { id: model },
|
|
9378
9419
|
mode: request.planMode ? "plan" : "agent"
|
|
9379
9420
|
});
|
|
9380
9421
|
this.activeRun = run;
|
|
9422
|
+
this.activeModel = model;
|
|
9381
9423
|
for await (const event of run.stream()) {
|
|
9382
9424
|
this.recordCursorEvent(event);
|
|
9383
9425
|
}
|
|
@@ -9396,6 +9438,7 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
9396
9438
|
}, this.historyFile);
|
|
9397
9439
|
} finally {
|
|
9398
9440
|
this.activeRun = null;
|
|
9441
|
+
this.activeModel = null;
|
|
9399
9442
|
await this.historyFile.flush();
|
|
9400
9443
|
await this.onTurnComplete();
|
|
9401
9444
|
}
|
|
@@ -9415,6 +9458,69 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
9415
9458
|
}
|
|
9416
9459
|
recordCursorEvent(event) {
|
|
9417
9460
|
this.recordHistoryEvent(`cursor-${event.type}`, event, this.historyFile);
|
|
9461
|
+
const usage = this.buildCursorContextUsagePayload(event);
|
|
9462
|
+
if (!usage) return;
|
|
9463
|
+
this.historyFile.append(this.emitContextUsage(usage));
|
|
9464
|
+
}
|
|
9465
|
+
buildCursorContextUsagePayload(event) {
|
|
9466
|
+
if (!event || typeof event !== "object" || !("type" in event) || event.type !== "turn-ended") {
|
|
9467
|
+
return null;
|
|
9468
|
+
}
|
|
9469
|
+
const usage = "usage" in event && event.usage && typeof event.usage === "object" ? event.usage : null;
|
|
9470
|
+
if (!usage) return null;
|
|
9471
|
+
const inputTokens = finiteNumber("inputTokens" in usage ? usage.inputTokens : null);
|
|
9472
|
+
const cacheReadTokens = finiteNumber("cacheReadTokens" in usage ? usage.cacheReadTokens : null);
|
|
9473
|
+
const cacheWriteTokens = finiteNumber("cacheWriteTokens" in usage ? usage.cacheWriteTokens : null);
|
|
9474
|
+
const outputTokens = finiteNumber("outputTokens" in usage ? usage.outputTokens : null);
|
|
9475
|
+
const rawTotalTokens = inputTokens + cacheReadTokens + cacheWriteTokens + outputTokens;
|
|
9476
|
+
if (rawTotalTokens <= 0) return null;
|
|
9477
|
+
const maxTokens = CURSOR_COMPOSER_CONTEXT_WINDOW;
|
|
9478
|
+
const { totalTokens, totalProcessedTokens } = clampTokensToWindow(rawTotalTokens, maxTokens);
|
|
9479
|
+
const categories = [
|
|
9480
|
+
{
|
|
9481
|
+
name: "Input",
|
|
9482
|
+
tokens: inputTokens,
|
|
9483
|
+
percentage: percentage(inputTokens, maxTokens),
|
|
9484
|
+
color: CURSOR_CATEGORY_COLORS.input
|
|
9485
|
+
},
|
|
9486
|
+
{
|
|
9487
|
+
name: "Cache read",
|
|
9488
|
+
tokens: cacheReadTokens,
|
|
9489
|
+
percentage: percentage(cacheReadTokens, maxTokens),
|
|
9490
|
+
color: CURSOR_CATEGORY_COLORS.cacheRead
|
|
9491
|
+
},
|
|
9492
|
+
{
|
|
9493
|
+
name: "Cache write",
|
|
9494
|
+
tokens: cacheWriteTokens,
|
|
9495
|
+
percentage: percentage(cacheWriteTokens, maxTokens),
|
|
9496
|
+
color: CURSOR_CATEGORY_COLORS.cacheWrite
|
|
9497
|
+
},
|
|
9498
|
+
{
|
|
9499
|
+
name: "Output",
|
|
9500
|
+
tokens: outputTokens,
|
|
9501
|
+
percentage: percentage(outputTokens, maxTokens),
|
|
9502
|
+
color: CURSOR_CATEGORY_COLORS.output
|
|
9503
|
+
}
|
|
9504
|
+
].filter((category) => category.tokens > 0);
|
|
9505
|
+
return {
|
|
9506
|
+
provider: "cursor",
|
|
9507
|
+
source: "provider_usage",
|
|
9508
|
+
model: this.activeModel,
|
|
9509
|
+
totalTokens,
|
|
9510
|
+
...totalProcessedTokens !== void 0 ? { totalProcessedTokens } : {},
|
|
9511
|
+
maxTokens,
|
|
9512
|
+
rawMaxTokens: maxTokens,
|
|
9513
|
+
percentage: percentage(totalTokens, maxTokens),
|
|
9514
|
+
compactsAutomatically: true,
|
|
9515
|
+
categories,
|
|
9516
|
+
apiUsage: {
|
|
9517
|
+
inputTokens,
|
|
9518
|
+
outputTokens,
|
|
9519
|
+
cacheReadInputTokens: cacheReadTokens,
|
|
9520
|
+
cacheCreationInputTokens: cacheWriteTokens
|
|
9521
|
+
},
|
|
9522
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9523
|
+
};
|
|
9418
9524
|
}
|
|
9419
9525
|
};
|
|
9420
9526
|
|