replicas-engine 0.1.297 → 0.1.299
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 +224 -98
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -14,6 +14,21 @@ function isRecord(value) {
|
|
|
14
14
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// ../shared/src/result.ts
|
|
18
|
+
function createSuccessResult(data) {
|
|
19
|
+
return { ok: true, data };
|
|
20
|
+
}
|
|
21
|
+
function createErrorResult(error) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
error: {
|
|
25
|
+
message: error.message,
|
|
26
|
+
code: error.code,
|
|
27
|
+
details: error.details
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
17
32
|
// ../shared/src/agent.ts
|
|
18
33
|
var CODEX_REASONING_EFFORT_BY_THINKING_LEVEL = {
|
|
19
34
|
low: "low",
|
|
@@ -286,7 +301,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
286
301
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
287
302
|
|
|
288
303
|
// ../shared/src/e2b.ts
|
|
289
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-
|
|
304
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-12-v2";
|
|
290
305
|
|
|
291
306
|
// ../shared/src/runtime-env.ts
|
|
292
307
|
function parsePosixEnvFile(content) {
|
|
@@ -736,8 +751,66 @@ var GITHUB_ABILITY = {
|
|
|
736
751
|
referenceFile: { name: "GITHUB.md", content: REFERENCE3 }
|
|
737
752
|
};
|
|
738
753
|
|
|
754
|
+
// ../shared/src/default-skills/replicas-agent/abilities/gitlab.ts
|
|
755
|
+
var SECTION4 = `### GitLab
|
|
756
|
+
Workspace repos hosted on GitLab use pre-configured git credentials \u2014 push, pull, and open merge requests with plain \`git\`.
|
|
757
|
+
|
|
758
|
+
**Reference:** \`references/GITLAB.md\`
|
|
759
|
+
|
|
760
|
+
Use this when:
|
|
761
|
+
- A repo's remote is on gitlab.com or a self-managed GitLab instance
|
|
762
|
+
- You need to open or update a merge request`;
|
|
763
|
+
var REFERENCE4 = `# GitLab Integration
|
|
764
|
+
|
|
765
|
+
This guide covers how to work with GitLab-hosted repositories from within your Replicas workspace.
|
|
766
|
+
|
|
767
|
+
## Prerequisites
|
|
768
|
+
|
|
769
|
+
Git credentials for the workspace's GitLab hosts are pre-configured in \`~/.git-credentials\` and refreshed automatically. Plain \`git fetch\` / \`git pull\` / \`git push\` over HTTPS work with no additional setup.
|
|
770
|
+
|
|
771
|
+
- Never ask the user for a GitLab token or PAT \u2014 credentials are already wired. If a push fails with an authentication error, report it to the user instead of working around it.
|
|
772
|
+
- There is no \`glab\` CLI in the workspace, and \`gh\` only works for GitHub remotes. Check a repo's host with \`git remote get-url origin\` before choosing the GitHub or GitLab workflow.
|
|
773
|
+
|
|
774
|
+
## Merge Requests
|
|
775
|
+
|
|
776
|
+
Create a merge request directly from a push using push options:
|
|
777
|
+
|
|
778
|
+
\`\`\`bash
|
|
779
|
+
git push -o merge_request.create -o merge_request.target=<default-branch> origin HEAD
|
|
780
|
+
\`\`\`
|
|
781
|
+
|
|
782
|
+
Useful options:
|
|
783
|
+
|
|
784
|
+
\`\`\`bash
|
|
785
|
+
-o merge_request.title="Title"
|
|
786
|
+
-o merge_request.description="Description"
|
|
787
|
+
-o merge_request.draft # open as draft
|
|
788
|
+
-o merge_request.remove_source_branch # delete branch on merge
|
|
789
|
+
\`\`\`
|
|
790
|
+
|
|
791
|
+
GitLab prints the MR URL in the push output \u2014 include it in your reply to the user.
|
|
792
|
+
|
|
793
|
+
## GitLab API (advanced)
|
|
794
|
+
|
|
795
|
+
For operations with no git equivalent (commenting on MRs, reading pipelines), call the REST API with the workspace credential:
|
|
796
|
+
|
|
797
|
+
\`\`\`bash
|
|
798
|
+
TOKEN=$(grep -m1 '://oauth2:' ~/.git-credentials | sed -E 's#https://oauth2:([^@]+)@.*#\\1#')
|
|
799
|
+
curl -s -H "Authorization: Bearer $TOKEN" "https://gitlab.com/api/v4/projects/<url-encoded-path>/merge_requests"
|
|
800
|
+
\`\`\`
|
|
801
|
+
|
|
802
|
+
Use the repo's own host in the API base URL for self-managed instances.
|
|
803
|
+
`;
|
|
804
|
+
var GITLAB_ABILITY = {
|
|
805
|
+
label: "GitLab",
|
|
806
|
+
description: "Pre-configured git credentials for GitLab repos; merge requests via push options.",
|
|
807
|
+
bullet: "- Interacting with GitLab (pushing to GitLab repos, opening merge requests)",
|
|
808
|
+
section: SECTION4,
|
|
809
|
+
referenceFile: { name: "GITLAB.md", content: REFERENCE4 }
|
|
810
|
+
};
|
|
811
|
+
|
|
739
812
|
// ../shared/src/default-skills/replicas-agent/abilities/google.ts
|
|
740
|
-
var
|
|
813
|
+
var SECTION5 = `### Google Workspace (Docs, Sheets, Forms, Drive)
|
|
741
814
|
Create and edit Google Docs, Sheets, and Forms via the Replicas gateway. Files are owned by Replicas \u2014 the integration cannot access pre-existing Google content created outside of it.
|
|
742
815
|
|
|
743
816
|
**Reference:** \`references/GOOGLE.md\`
|
|
@@ -746,7 +819,7 @@ Use this when:
|
|
|
746
819
|
- You need to create or edit a Google Doc, Sheet, or Form
|
|
747
820
|
- You need to share, rename, move, or delete a Replicas-created Google file
|
|
748
821
|
- You need to read responses from a Replicas-created Google Form`;
|
|
749
|
-
var
|
|
822
|
+
var REFERENCE5 = `# Google Workspace (Docs, Sheets, Forms, Drive)
|
|
750
823
|
|
|
751
824
|
This guide covers how to create and edit Google Docs, Sheets, and Forms \u2014 plus do basic Drive file operations \u2014 from inside a Replicas workspace, using the monolith as a gateway to Google's APIs.
|
|
752
825
|
|
|
@@ -1007,12 +1080,12 @@ var GOOGLE_ABILITY = {
|
|
|
1007
1080
|
label: "Google Workspace",
|
|
1008
1081
|
description: "Create / edit Docs, Sheets, Forms, and Drive files via the Replicas gateway.",
|
|
1009
1082
|
bullet: "- Interacting with Google Workspace (creating and editing Docs, Sheets, and Forms, sharing files, reading form responses, etc.)",
|
|
1010
|
-
section:
|
|
1011
|
-
referenceFile: { name: "GOOGLE.md", content:
|
|
1083
|
+
section: SECTION5,
|
|
1084
|
+
referenceFile: { name: "GOOGLE.md", content: REFERENCE5 }
|
|
1012
1085
|
};
|
|
1013
1086
|
|
|
1014
1087
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
1015
|
-
var
|
|
1088
|
+
var SECTION6 = `### Linear
|
|
1016
1089
|
Fetch issues, update state, add comments, and search via the Linear GraphQL API.
|
|
1017
1090
|
|
|
1018
1091
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -1021,7 +1094,7 @@ Use this when:
|
|
|
1021
1094
|
- You encounter a Linear issue link and need to understand the task
|
|
1022
1095
|
- You need to update an issue's state (e.g. mark as done)
|
|
1023
1096
|
- You need to comment on or search for Linear issues`;
|
|
1024
|
-
var
|
|
1097
|
+
var REFERENCE6 = `# Linear Integration
|
|
1025
1098
|
|
|
1026
1099
|
This guide covers how to interact with Linear from within your Replicas workspace.
|
|
1027
1100
|
|
|
@@ -1096,12 +1169,12 @@ var LINEAR_ABILITY = {
|
|
|
1096
1169
|
label: "Linear",
|
|
1097
1170
|
description: "Fetch issues, post comments, update states via the Linear GraphQL API.",
|
|
1098
1171
|
bullet: "- Interacting with Linear (fetching issues, updating state, commenting, etc.)",
|
|
1099
|
-
section:
|
|
1100
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
1172
|
+
section: SECTION6,
|
|
1173
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE6 }
|
|
1101
1174
|
};
|
|
1102
1175
|
|
|
1103
1176
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
1104
|
-
var
|
|
1177
|
+
var SECTION7 = `### Media
|
|
1105
1178
|
Share screenshots, screen recordings, generated diagrams, and audio clips inline in the Replicas chat and natively embedded in external messages.
|
|
1106
1179
|
|
|
1107
1180
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -1110,7 +1183,7 @@ Use this when:
|
|
|
1110
1183
|
- You produce a screenshot, recording, generated image, or audio clip the user should see
|
|
1111
1184
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
1112
1185
|
- You need to embed media in a Slack/Linear/GitHub message AND keep a referenceable copy in the Replicas dashboard`;
|
|
1113
|
-
var
|
|
1186
|
+
var REFERENCE7 = `# Media (Screenshots, Recordings, Audio)
|
|
1114
1187
|
|
|
1115
1188
|
This guide covers how to share screenshots, screen recordings, generated diagrams, and audio clips \u2014 both inline in the Replicas chat and natively embedded in external surfaces (Slack, Linear, GitHub).
|
|
1116
1189
|
|
|
@@ -1361,12 +1434,12 @@ var MEDIA_ABILITY = {
|
|
|
1361
1434
|
label: "Media",
|
|
1362
1435
|
description: "Share screenshots, recordings, generated images, and audio clips.",
|
|
1363
1436
|
bullet: "- Producing or showing the user any media \u2014 screenshots, screen recordings, generated images or diagrams, audio clips \u2014 including in your Replicas chat reply, PR descriptions/comments, and other external platforms",
|
|
1364
|
-
section:
|
|
1365
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
1437
|
+
section: SECTION7,
|
|
1438
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE7 }
|
|
1366
1439
|
};
|
|
1367
1440
|
|
|
1368
1441
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
1369
|
-
var
|
|
1442
|
+
var SECTION8 = `### Previews
|
|
1370
1443
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
1371
1444
|
|
|
1372
1445
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -1375,7 +1448,7 @@ Use this when:
|
|
|
1375
1448
|
- You need to start a service that a human should view or interact with
|
|
1376
1449
|
- The task involves UI work that benefits from human review
|
|
1377
1450
|
- You are verifying frontend/backend integrations visually`;
|
|
1378
|
-
var
|
|
1451
|
+
var REFERENCE8 = `# Preview URLs
|
|
1379
1452
|
|
|
1380
1453
|
When you run services on ports \u2014 such as a web app, API server, or database \u2014 humans may want to interact with them directly. You can expose your locally running services as public preview URLs.
|
|
1381
1454
|
|
|
@@ -1457,12 +1530,12 @@ var PREVIEWS_ABILITY = {
|
|
|
1457
1530
|
label: "Previews",
|
|
1458
1531
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
1459
1532
|
bullet: "- Creating preview URLs for locally running services",
|
|
1460
|
-
section:
|
|
1461
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
1533
|
+
section: SECTION8,
|
|
1534
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE8 }
|
|
1462
1535
|
};
|
|
1463
1536
|
|
|
1464
1537
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
1465
|
-
var
|
|
1538
|
+
var SECTION9 = `### Replicas (in-workspace CLI)
|
|
1466
1539
|
Take action *with* Replicas itself \u2014 manage automations, environments (variables, files), repos, and \`replicas.json\` config \u2014 using the pre-installed, pre-authenticated \`replicas\` CLI.
|
|
1467
1540
|
|
|
1468
1541
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -1472,7 +1545,7 @@ Use this when:
|
|
|
1472
1545
|
- The user asks you to manage environments, environment variables, or environment files
|
|
1473
1546
|
- The user asks "what envs / repos / automations do I have?"
|
|
1474
1547
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo`;
|
|
1475
|
-
var
|
|
1548
|
+
var REFERENCE9 = `# Replicas (in-workspace CLI)
|
|
1476
1549
|
|
|
1477
1550
|
This guide covers how to take action *with* Replicas itself from inside a Replicas workspace \u2014 managing automations, environments (and their variables/files), repos, previews, and the user's \`replicas.json\` config \u2014 using the pre-installed \`replicas\` CLI.
|
|
1478
1551
|
|
|
@@ -1666,13 +1739,13 @@ var REPLICAS_ABILITY = {
|
|
|
1666
1739
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
1667
1740
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
1668
1741
|
bullet: "",
|
|
1669
|
-
section:
|
|
1670
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
1742
|
+
section: SECTION9,
|
|
1743
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE9 },
|
|
1671
1744
|
locked: true
|
|
1672
1745
|
};
|
|
1673
1746
|
|
|
1674
1747
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
1675
|
-
var
|
|
1748
|
+
var SECTION10 = `### Slack
|
|
1676
1749
|
Send messages, read threads, search conversations, and upload files via the Slack Web API.
|
|
1677
1750
|
|
|
1678
1751
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -1682,7 +1755,7 @@ Use this when:
|
|
|
1682
1755
|
- You need to read or fetch a Slack conversation
|
|
1683
1756
|
- You encounter a Slack message link and need to retrieve its content
|
|
1684
1757
|
- The task asks you to notify, update, or communicate via Slack`;
|
|
1685
|
-
var
|
|
1758
|
+
var REFERENCE10 = `# Slack Integration
|
|
1686
1759
|
|
|
1687
1760
|
This guide covers how to interact with Slack from within your Replicas workspace.
|
|
1688
1761
|
|
|
@@ -1783,8 +1856,8 @@ var SLACK_ABILITY = {
|
|
|
1783
1856
|
label: "Slack",
|
|
1784
1857
|
description: "Send messages, read threads, search conversations, upload files.",
|
|
1785
1858
|
bullet: "- Interacting with Slack (sending messages, reading threads, etc.)",
|
|
1786
|
-
section:
|
|
1787
|
-
referenceFile: { name: "SLACK.md", content:
|
|
1859
|
+
section: SECTION10,
|
|
1860
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE10 }
|
|
1788
1861
|
};
|
|
1789
1862
|
|
|
1790
1863
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
@@ -1793,6 +1866,7 @@ var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
|
1793
1866
|
computer: COMPUTER_ABILITY,
|
|
1794
1867
|
docker: DOCKER_ABILITY,
|
|
1795
1868
|
github: GITHUB_ABILITY,
|
|
1869
|
+
gitlab: GITLAB_ABILITY,
|
|
1796
1870
|
google: GOOGLE_ABILITY,
|
|
1797
1871
|
linear: LINEAR_ABILITY,
|
|
1798
1872
|
media: MEDIA_ABILITY,
|
|
@@ -2790,7 +2864,7 @@ var BaseRefreshManager = class {
|
|
|
2790
2864
|
};
|
|
2791
2865
|
|
|
2792
2866
|
// src/services/monolith-service.ts
|
|
2793
|
-
async function monolithRequest(
|
|
2867
|
+
async function monolithRequest(path5, init = {}) {
|
|
2794
2868
|
if (!ENGINE_ENV.WORKSPACE_ID) {
|
|
2795
2869
|
throw new Error("WORKSPACE_ID is not set; cannot call monolith");
|
|
2796
2870
|
}
|
|
@@ -2800,7 +2874,7 @@ async function monolithRequest(path4, init = {}) {
|
|
|
2800
2874
|
"X-Workspace-Id": ENGINE_ENV.WORKSPACE_ID
|
|
2801
2875
|
};
|
|
2802
2876
|
if (!isFormData) headers["Content-Type"] = "application/json";
|
|
2803
|
-
return fetch(`${ENGINE_ENV.MONOLITH_URL}${
|
|
2877
|
+
return fetch(`${ENGINE_ENV.MONOLITH_URL}${path5}`, {
|
|
2804
2878
|
method: init.method ?? "POST",
|
|
2805
2879
|
headers,
|
|
2806
2880
|
body: init.body === void 0 ? void 0 : isFormData ? init.body : JSON.stringify(init.body),
|
|
@@ -2826,13 +2900,13 @@ var MonolithService = class {
|
|
|
2826
2900
|
var monolithService = new MonolithService();
|
|
2827
2901
|
|
|
2828
2902
|
// src/utils/file.ts
|
|
2829
|
-
import { mkdir, rename, unlink, writeFile } from "fs/promises";
|
|
2903
|
+
import { mkdir, readFile, rename, unlink, writeFile } from "fs/promises";
|
|
2830
2904
|
import { dirname } from "path";
|
|
2831
|
-
async function atomicWriteFile(
|
|
2832
|
-
const tmpFile = `${
|
|
2905
|
+
async function atomicWriteFile(path5, data, options) {
|
|
2906
|
+
const tmpFile = `${path5}.${process.pid}.${Date.now()}.tmp`;
|
|
2833
2907
|
try {
|
|
2834
2908
|
await writeFile(tmpFile, data, { encoding: "utf-8", mode: options?.mode });
|
|
2835
|
-
await rename(tmpFile,
|
|
2909
|
+
await rename(tmpFile, path5);
|
|
2836
2910
|
} catch (error) {
|
|
2837
2911
|
await unlink(tmpFile).catch(() => void 0);
|
|
2838
2912
|
throw error;
|
|
@@ -2844,6 +2918,21 @@ async function writeSecureCredentialFile(filePath, content, options) {
|
|
|
2844
2918
|
}
|
|
2845
2919
|
await atomicWriteFile(filePath, content, { mode: 384 });
|
|
2846
2920
|
}
|
|
2921
|
+
var credentialFileQueue = Promise.resolve();
|
|
2922
|
+
function upsertCredentialFileLines(filePath, hosts, lines) {
|
|
2923
|
+
const task = credentialFileQueue.then(async () => {
|
|
2924
|
+
let existing = [];
|
|
2925
|
+
try {
|
|
2926
|
+
existing = (await readFile(filePath, "utf-8")).split("\n").filter(Boolean);
|
|
2927
|
+
} catch {
|
|
2928
|
+
existing = [];
|
|
2929
|
+
}
|
|
2930
|
+
const kept = existing.filter((line) => !hosts.some((host) => line.endsWith(`@${host}`)));
|
|
2931
|
+
await writeSecureCredentialFile(filePath, [...lines, ...kept, ""].join("\n"));
|
|
2932
|
+
});
|
|
2933
|
+
credentialFileQueue = task.catch(() => void 0);
|
|
2934
|
+
return task;
|
|
2935
|
+
}
|
|
2847
2936
|
|
|
2848
2937
|
// src/managers/github-token-manager.ts
|
|
2849
2938
|
var GitHubTokenManager = class extends BaseRefreshManager {
|
|
@@ -2873,10 +2962,10 @@ var GitHubTokenManager = class extends BaseRefreshManager {
|
|
|
2873
2962
|
}
|
|
2874
2963
|
async updateGitCredentials(token) {
|
|
2875
2964
|
const credentialsPath = path.join(ENGINE_ENV.HOME_DIR, ".git-credentials");
|
|
2876
|
-
const credentialsContent = `https://x-access-token:${token}@github.com
|
|
2877
|
-
`;
|
|
2878
2965
|
try {
|
|
2879
|
-
await
|
|
2966
|
+
await upsertCredentialFileLines(credentialsPath, ["github.com"], [
|
|
2967
|
+
`https://x-access-token:${token}@github.com`
|
|
2968
|
+
]);
|
|
2880
2969
|
console.log(`[GitHubTokenManager] Updated ${credentialsPath}`);
|
|
2881
2970
|
} catch (error) {
|
|
2882
2971
|
console.error("[GitHubTokenManager] Failed to update git credentials:", error);
|
|
@@ -2909,9 +2998,44 @@ var GitHubTokenManager = class extends BaseRefreshManager {
|
|
|
2909
2998
|
};
|
|
2910
2999
|
var githubTokenManager = new GitHubTokenManager();
|
|
2911
3000
|
|
|
3001
|
+
// src/managers/gitlab-token-manager.ts
|
|
3002
|
+
import path2 from "path";
|
|
3003
|
+
var GitLabTokenManager = class extends BaseRefreshManager {
|
|
3004
|
+
constructor() {
|
|
3005
|
+
super("GitLabTokenManager");
|
|
3006
|
+
}
|
|
3007
|
+
async doRefresh(_config) {
|
|
3008
|
+
const result = await this.fetchRefresh();
|
|
3009
|
+
if (!result.ok) {
|
|
3010
|
+
throw new Error(`Token refresh failed: ${result.error.message}`);
|
|
3011
|
+
}
|
|
3012
|
+
const data = result.data;
|
|
3013
|
+
if (!data.token) {
|
|
3014
|
+
console.log(`[GitLabTokenManager] No GitLab token to install: ${data.reason}`);
|
|
3015
|
+
return;
|
|
3016
|
+
}
|
|
3017
|
+
const hosts = data.hosts.length > 0 ? data.hosts : ["gitlab.com"];
|
|
3018
|
+
const credentialsPath = path2.join(ENGINE_ENV.HOME_DIR, ".git-credentials");
|
|
3019
|
+
await upsertCredentialFileLines(
|
|
3020
|
+
credentialsPath,
|
|
3021
|
+
hosts,
|
|
3022
|
+
hosts.map((host) => `https://oauth2:${data.token}@${host}`)
|
|
3023
|
+
);
|
|
3024
|
+
console.log(`[GitLabTokenManager] Updated ${credentialsPath} for ${hosts.join(", ")}`);
|
|
3025
|
+
}
|
|
3026
|
+
async fetchRefresh() {
|
|
3027
|
+
const response = await monolithRequest("/v1/engine/gitlab/refresh-token");
|
|
3028
|
+
if (!response.ok) {
|
|
3029
|
+
return createErrorResult({ message: `${response.status} ${await response.text()}` });
|
|
3030
|
+
}
|
|
3031
|
+
return createSuccessResult(await response.json());
|
|
3032
|
+
}
|
|
3033
|
+
};
|
|
3034
|
+
var gitlabTokenManager = new GitLabTokenManager();
|
|
3035
|
+
|
|
2912
3036
|
// src/managers/claude-token-manager.ts
|
|
2913
3037
|
import { promises as fs } from "fs";
|
|
2914
|
-
import
|
|
3038
|
+
import path3 from "path";
|
|
2915
3039
|
|
|
2916
3040
|
// src/managers/auth-env-transition.ts
|
|
2917
3041
|
function applyAuthEnvTransition(params) {
|
|
@@ -3003,7 +3127,7 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
|
|
|
3003
3127
|
});
|
|
3004
3128
|
}
|
|
3005
3129
|
async writeOauthCredentialsFile(credentials) {
|
|
3006
|
-
const credentialsPath =
|
|
3130
|
+
const credentialsPath = path3.join(ENGINE_ENV.HOME_DIR, ".claude", ".credentials.json");
|
|
3007
3131
|
const claudeCliConfig = {
|
|
3008
3132
|
claudeAiOauth: {
|
|
3009
3133
|
accessToken: credentials.accessToken,
|
|
@@ -3025,7 +3149,7 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
|
|
|
3025
3149
|
}
|
|
3026
3150
|
}
|
|
3027
3151
|
async removeOauthCredentialsFile() {
|
|
3028
|
-
const credentialsPath =
|
|
3152
|
+
const credentialsPath = path3.join(ENGINE_ENV.HOME_DIR, ".claude", ".credentials.json");
|
|
3029
3153
|
try {
|
|
3030
3154
|
await fs.unlink(credentialsPath);
|
|
3031
3155
|
} catch {
|
|
@@ -3036,7 +3160,7 @@ var claudeTokenManager = new ClaudeTokenManager();
|
|
|
3036
3160
|
|
|
3037
3161
|
// src/managers/codex-token-manager.ts
|
|
3038
3162
|
import { promises as fs2 } from "fs";
|
|
3039
|
-
import
|
|
3163
|
+
import path4 from "path";
|
|
3040
3164
|
var CodexTokenManager = class extends BaseRefreshManager {
|
|
3041
3165
|
constructor() {
|
|
3042
3166
|
super("CodexTokenManager");
|
|
@@ -3104,7 +3228,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
3104
3228
|
});
|
|
3105
3229
|
}
|
|
3106
3230
|
async writeOauthCredentialsFile(credentials) {
|
|
3107
|
-
const authPath =
|
|
3231
|
+
const authPath = path4.join(ENGINE_ENV.HOME_DIR, ".codex", "auth.json");
|
|
3108
3232
|
const codexAuthConfig = {
|
|
3109
3233
|
OPENAI_API_KEY: null,
|
|
3110
3234
|
tokens: {
|
|
@@ -3127,7 +3251,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
3127
3251
|
}
|
|
3128
3252
|
}
|
|
3129
3253
|
async removeOauthCredentialsFile() {
|
|
3130
|
-
const authPath =
|
|
3254
|
+
const authPath = path4.join(ENGINE_ENV.HOME_DIR, ".codex", "auth.json");
|
|
3131
3255
|
try {
|
|
3132
3256
|
await fs2.unlink(authPath);
|
|
3133
3257
|
} catch {
|
|
@@ -3137,13 +3261,13 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
3137
3261
|
var codexTokenManager = new CodexTokenManager();
|
|
3138
3262
|
|
|
3139
3263
|
// src/git/service.ts
|
|
3140
|
-
import { readdir, readFile as
|
|
3264
|
+
import { readdir, readFile as readFile3, stat } from "fs/promises";
|
|
3141
3265
|
import { existsSync as existsSync2, unlinkSync } from "fs";
|
|
3142
3266
|
import { spawn } from "child_process";
|
|
3143
3267
|
import { join as join5 } from "path";
|
|
3144
3268
|
|
|
3145
3269
|
// src/utils/state.ts
|
|
3146
|
-
import { readFile, mkdir as mkdir2 } from "fs/promises";
|
|
3270
|
+
import { readFile as readFile2, mkdir as mkdir2 } from "fs/promises";
|
|
3147
3271
|
import { existsSync } from "fs";
|
|
3148
3272
|
import { join as join3 } from "path";
|
|
3149
3273
|
import { homedir as homedir3 } from "os";
|
|
@@ -3224,7 +3348,7 @@ async function loadEngineState() {
|
|
|
3224
3348
|
if (!existsSync(STATE_FILE)) {
|
|
3225
3349
|
return { ...DEFAULT_STATE };
|
|
3226
3350
|
}
|
|
3227
|
-
const content = await
|
|
3351
|
+
const content = await readFile2(STATE_FILE, "utf-8");
|
|
3228
3352
|
const state = coerceEngineState(JSON.parse(content));
|
|
3229
3353
|
return {
|
|
3230
3354
|
...DEFAULT_STATE,
|
|
@@ -3600,9 +3724,9 @@ var GitService = class {
|
|
|
3600
3724
|
try {
|
|
3601
3725
|
const paths = await this.listUntrackedPaths(repoPath);
|
|
3602
3726
|
let total = 0;
|
|
3603
|
-
for (const
|
|
3727
|
+
for (const path5 of paths) {
|
|
3604
3728
|
try {
|
|
3605
|
-
const contents = await
|
|
3729
|
+
const contents = await readFile3(join5(repoPath, path5));
|
|
3606
3730
|
if (contents.length === 0 || contents.includes(0)) {
|
|
3607
3731
|
continue;
|
|
3608
3732
|
}
|
|
@@ -3781,12 +3905,12 @@ var GitService = class {
|
|
|
3781
3905
|
await saveRepoState(repo.name, state, state);
|
|
3782
3906
|
return state;
|
|
3783
3907
|
}
|
|
3784
|
-
pathExists(
|
|
3785
|
-
return existsSync2(
|
|
3908
|
+
pathExists(path5) {
|
|
3909
|
+
return existsSync2(path5);
|
|
3786
3910
|
}
|
|
3787
|
-
async safeStat(
|
|
3911
|
+
async safeStat(path5) {
|
|
3788
3912
|
try {
|
|
3789
|
-
return await stat(
|
|
3913
|
+
return await stat(path5);
|
|
3790
3914
|
} catch {
|
|
3791
3915
|
return null;
|
|
3792
3916
|
}
|
|
@@ -3809,8 +3933,8 @@ var StreamWriter = class {
|
|
|
3809
3933
|
backpressured = false;
|
|
3810
3934
|
droppedCount = 0;
|
|
3811
3935
|
flushTimer = null;
|
|
3812
|
-
open(
|
|
3813
|
-
this.stream = createWriteStream(
|
|
3936
|
+
open(path5, highWaterMark = DEFAULT_HIGH_WATER) {
|
|
3937
|
+
this.stream = createWriteStream(path5, { flags: "a", highWaterMark });
|
|
3814
3938
|
this.stream.on("error", () => {
|
|
3815
3939
|
this.stream = null;
|
|
3816
3940
|
});
|
|
@@ -3916,14 +4040,14 @@ var EngineLogger = class {
|
|
|
3916
4040
|
var engineLogger = new EngineLogger();
|
|
3917
4041
|
|
|
3918
4042
|
// src/services/replicas-config-service.ts
|
|
3919
|
-
import { readFile as
|
|
4043
|
+
import { readFile as readFile6, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
|
|
3920
4044
|
import { existsSync as existsSync4 } from "fs";
|
|
3921
4045
|
import { join as join9 } from "path";
|
|
3922
4046
|
import { homedir as homedir7 } from "os";
|
|
3923
4047
|
import { spawn as spawn2 } from "child_process";
|
|
3924
4048
|
|
|
3925
4049
|
// src/services/environment-details-service.ts
|
|
3926
|
-
import { mkdir as mkdir4, readFile as
|
|
4050
|
+
import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
|
|
3927
4051
|
import { existsSync as existsSync3 } from "fs";
|
|
3928
4052
|
import { homedir as homedir5 } from "os";
|
|
3929
4053
|
import { join as join7 } from "path";
|
|
@@ -4000,7 +4124,7 @@ async function readDetails() {
|
|
|
4000
4124
|
if (!existsSync3(DETAILS_FILE)) {
|
|
4001
4125
|
return createDefaultDetails();
|
|
4002
4126
|
}
|
|
4003
|
-
const raw = await
|
|
4127
|
+
const raw = await readFile4(DETAILS_FILE, "utf-8");
|
|
4004
4128
|
const parsed = JSON.parse(raw);
|
|
4005
4129
|
return { ...createDefaultDetails(), ...parsed };
|
|
4006
4130
|
} catch {
|
|
@@ -4095,7 +4219,7 @@ var EnvironmentDetailsService = class {
|
|
|
4095
4219
|
var environmentDetailsService = new EnvironmentDetailsService();
|
|
4096
4220
|
|
|
4097
4221
|
// src/services/start-hook-logs-service.ts
|
|
4098
|
-
import { mkdir as mkdir5, readFile as
|
|
4222
|
+
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3, readdir as readdir2 } from "fs/promises";
|
|
4099
4223
|
import { homedir as homedir6 } from "os";
|
|
4100
4224
|
import { join as join8 } from "path";
|
|
4101
4225
|
|
|
@@ -4172,7 +4296,7 @@ var StartHookLogsService = class {
|
|
|
4172
4296
|
continue;
|
|
4173
4297
|
}
|
|
4174
4298
|
try {
|
|
4175
|
-
const raw = await
|
|
4299
|
+
const raw = await readFile5(join8(LOGS_DIR, file), "utf-8");
|
|
4176
4300
|
const stored = normalizeStored(JSON.parse(raw));
|
|
4177
4301
|
if (stored) {
|
|
4178
4302
|
logs.push(withPreview(stored));
|
|
@@ -4191,7 +4315,7 @@ var StartHookLogsService = class {
|
|
|
4191
4315
|
async getFullOutput(hookType, hookName) {
|
|
4192
4316
|
const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
4193
4317
|
try {
|
|
4194
|
-
const raw = await
|
|
4318
|
+
const raw = await readFile5(join8(LOGS_DIR, filename), "utf-8");
|
|
4195
4319
|
const stored = normalizeStored(JSON.parse(raw));
|
|
4196
4320
|
if (!stored || stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
4197
4321
|
return null;
|
|
@@ -4223,7 +4347,7 @@ async function readReplicasConfigFromDir(dirPath) {
|
|
|
4223
4347
|
if (!existsSync4(configPath)) {
|
|
4224
4348
|
continue;
|
|
4225
4349
|
}
|
|
4226
|
-
const data = await
|
|
4350
|
+
const data = await readFile6(configPath, "utf-8");
|
|
4227
4351
|
const config = parseReplicasConfigString(data, filename);
|
|
4228
4352
|
return { config, filename };
|
|
4229
4353
|
}
|
|
@@ -4654,7 +4778,7 @@ var EventService = class {
|
|
|
4654
4778
|
var eventService = new EventService();
|
|
4655
4779
|
|
|
4656
4780
|
// src/services/preview-service.ts
|
|
4657
|
-
import { mkdir as mkdir8, readFile as
|
|
4781
|
+
import { mkdir as mkdir8, readFile as readFile7 } from "fs/promises";
|
|
4658
4782
|
import { existsSync as existsSync5 } from "fs";
|
|
4659
4783
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
4660
4784
|
import { homedir as homedir9 } from "os";
|
|
@@ -4665,7 +4789,7 @@ async function readPreviewsFile() {
|
|
|
4665
4789
|
if (!existsSync5(PREVIEW_PORTS_FILE)) {
|
|
4666
4790
|
return { previews: [] };
|
|
4667
4791
|
}
|
|
4668
|
-
const raw = await
|
|
4792
|
+
const raw = await readFile7(PREVIEW_PORTS_FILE, "utf-8");
|
|
4669
4793
|
return JSON.parse(raw);
|
|
4670
4794
|
} catch {
|
|
4671
4795
|
return { previews: [] };
|
|
@@ -4770,7 +4894,7 @@ async function registerDesktopPreview() {
|
|
|
4770
4894
|
|
|
4771
4895
|
// src/services/chat/chat-service.ts
|
|
4772
4896
|
import { existsSync as existsSync7 } from "fs";
|
|
4773
|
-
import { appendFile as appendFile4, copyFile, mkdir as mkdir11, readFile as
|
|
4897
|
+
import { appendFile as appendFile4, copyFile, mkdir as mkdir11, readFile as readFile11, rename as rename2, rm } from "fs/promises";
|
|
4774
4898
|
import { homedir as homedir13 } from "os";
|
|
4775
4899
|
import { join as join15 } from "path";
|
|
4776
4900
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -4785,10 +4909,10 @@ import { mkdir as mkdir10, appendFile as appendFile2 } from "fs/promises";
|
|
|
4785
4909
|
import { homedir as homedir11 } from "os";
|
|
4786
4910
|
|
|
4787
4911
|
// src/utils/jsonl-reader.ts
|
|
4788
|
-
import { readFile as
|
|
4912
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
4789
4913
|
async function readJSONL(filePath) {
|
|
4790
4914
|
try {
|
|
4791
|
-
const content = await
|
|
4915
|
+
const content = await readFile8(filePath, "utf-8");
|
|
4792
4916
|
return parseAgentEventJsonl(content);
|
|
4793
4917
|
} catch (error) {
|
|
4794
4918
|
return [];
|
|
@@ -5159,7 +5283,7 @@ async function saveNormalizedImagesToTempFiles(images, tempImageDir = join12(hom
|
|
|
5159
5283
|
return tempPaths;
|
|
5160
5284
|
}
|
|
5161
5285
|
async function removeTempImageFiles(paths) {
|
|
5162
|
-
await Promise.allSettled(paths.map((
|
|
5286
|
+
await Promise.allSettled(paths.map((path5) => unlink2(path5)));
|
|
5163
5287
|
}
|
|
5164
5288
|
|
|
5165
5289
|
// src/services/message-queue-service.ts
|
|
@@ -6617,7 +6741,7 @@ var AspClient = class {
|
|
|
6617
6741
|
// src/managers/codex-asp/app-server-process.ts
|
|
6618
6742
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
6619
6743
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
6620
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
6744
|
+
var ENGINE_PACKAGE_VERSION = "0.1.299";
|
|
6621
6745
|
var INITIALIZE_METHOD = "initialize";
|
|
6622
6746
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
6623
6747
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -6941,16 +7065,16 @@ function transcriptItemsForTurn(turn) {
|
|
|
6941
7065
|
const otherItems = turn.items.filter((item) => item.type !== "userMessage");
|
|
6942
7066
|
return [...userItems, ...otherItems];
|
|
6943
7067
|
}
|
|
6944
|
-
function userImageForLocalPath(
|
|
6945
|
-
const cached = localImageCache.get(
|
|
7068
|
+
function userImageForLocalPath(path5) {
|
|
7069
|
+
const cached = localImageCache.get(path5);
|
|
6946
7070
|
if (cached) return cached;
|
|
6947
|
-
if (!existsSync6(
|
|
7071
|
+
if (!existsSync6(path5)) return null;
|
|
6948
7072
|
const image = {
|
|
6949
7073
|
type: "image",
|
|
6950
|
-
mediaType: inferMediaType(
|
|
6951
|
-
data: readFileSync3(
|
|
7074
|
+
mediaType: inferMediaType(path5),
|
|
7075
|
+
data: readFileSync3(path5).toString("base64")
|
|
6952
7076
|
};
|
|
6953
|
-
if (image.data.length > 0) localImageCache.set(
|
|
7077
|
+
if (image.data.length > 0) localImageCache.set(path5, image);
|
|
6954
7078
|
return image;
|
|
6955
7079
|
}
|
|
6956
7080
|
function userImagesForInput(input) {
|
|
@@ -7308,9 +7432,9 @@ async function buildTurnInput(request) {
|
|
|
7308
7432
|
}
|
|
7309
7433
|
const normalizedImages = await normalizeImages(request.images);
|
|
7310
7434
|
const tempImagePaths = await saveNormalizedImagesToTempFiles(normalizedImages);
|
|
7311
|
-
input.push(...tempImagePaths.map((
|
|
7435
|
+
input.push(...tempImagePaths.map((path5) => ({
|
|
7312
7436
|
type: "localImage",
|
|
7313
|
-
path:
|
|
7437
|
+
path: path5
|
|
7314
7438
|
})));
|
|
7315
7439
|
return { input, tempImagePaths };
|
|
7316
7440
|
}
|
|
@@ -7420,7 +7544,7 @@ var TranscriptUpdateCoalescer = class {
|
|
|
7420
7544
|
};
|
|
7421
7545
|
|
|
7422
7546
|
// src/managers/codex-asp/codex-history-file.ts
|
|
7423
|
-
import { appendFile as appendFile3, readFile as
|
|
7547
|
+
import { appendFile as appendFile3, readFile as readFile9 } from "fs/promises";
|
|
7424
7548
|
var CodexHistoryFile = class {
|
|
7425
7549
|
constructor(filePath) {
|
|
7426
7550
|
this.filePath = filePath;
|
|
@@ -7438,7 +7562,7 @@ var CodexHistoryFile = class {
|
|
|
7438
7562
|
}
|
|
7439
7563
|
async load() {
|
|
7440
7564
|
try {
|
|
7441
|
-
const content = await
|
|
7565
|
+
const content = await readFile9(this.filePath, "utf-8");
|
|
7442
7566
|
return parseAgentEventJsonlWithCodexAspTranscript(content);
|
|
7443
7567
|
} catch (error) {
|
|
7444
7568
|
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
|
|
@@ -8347,9 +8471,9 @@ import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
|
8347
8471
|
import { z } from "zod";
|
|
8348
8472
|
var POLL_INTERVAL_MS = 2e3;
|
|
8349
8473
|
var DEFAULT_SUBAGENT_TIMEOUT_MS = 6e5;
|
|
8350
|
-
async function engineFetch(
|
|
8474
|
+
async function engineFetch(path5, options) {
|
|
8351
8475
|
const baseUrl = `http://localhost:${ENGINE_ENV.REPLICAS_ENGINE_PORT}`;
|
|
8352
|
-
return fetch(`${baseUrl}${
|
|
8476
|
+
return fetch(`${baseUrl}${path5}`, {
|
|
8353
8477
|
...options,
|
|
8354
8478
|
headers: {
|
|
8355
8479
|
"Content-Type": "application/json",
|
|
@@ -8918,7 +9042,7 @@ var KeepAliveService = class _KeepAliveService {
|
|
|
8918
9042
|
var keepAliveService = new KeepAliveService();
|
|
8919
9043
|
|
|
8920
9044
|
// src/services/upload-chat-transcripts.ts
|
|
8921
|
-
import { readdir as readdir3, readFile as
|
|
9045
|
+
import { readdir as readdir3, readFile as readFile10 } from "fs/promises";
|
|
8922
9046
|
import { basename, join as join14 } from "path";
|
|
8923
9047
|
import { homedir as homedir12 } from "os";
|
|
8924
9048
|
var ENGINE_DIR2 = join14(homedir12(), ".replicas", "engine");
|
|
@@ -8955,7 +9079,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
|
8955
9079
|
return { flushed, failed };
|
|
8956
9080
|
}
|
|
8957
9081
|
async function uploadChatTranscript(chatId, filePath, chat) {
|
|
8958
|
-
const bytes = await
|
|
9082
|
+
const bytes = await readFile10(filePath);
|
|
8959
9083
|
if (bytes.byteLength === 0) return;
|
|
8960
9084
|
const form = new FormData();
|
|
8961
9085
|
form.append("chat_id", chatId);
|
|
@@ -9232,7 +9356,7 @@ var ChatService = class {
|
|
|
9232
9356
|
}
|
|
9233
9357
|
async readSenders(chatId) {
|
|
9234
9358
|
try {
|
|
9235
|
-
const content = await
|
|
9359
|
+
const content = await readFile11(this.senderFilePath(chatId), "utf-8");
|
|
9236
9360
|
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
9237
9361
|
const senders = [];
|
|
9238
9362
|
for (const line of lines) {
|
|
@@ -9598,7 +9722,7 @@ var ChatService = class {
|
|
|
9598
9722
|
}
|
|
9599
9723
|
async loadChats() {
|
|
9600
9724
|
try {
|
|
9601
|
-
const content = await
|
|
9725
|
+
const content = await readFile11(CHATS_FILE, "utf-8");
|
|
9602
9726
|
return parsePersistedChatsContent(content);
|
|
9603
9727
|
} catch (error) {
|
|
9604
9728
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
@@ -9613,7 +9737,7 @@ var ChatService = class {
|
|
|
9613
9737
|
console.error("[ChatService] Failed to quarantine corrupt chats file:", renameError);
|
|
9614
9738
|
}
|
|
9615
9739
|
try {
|
|
9616
|
-
const backupContent = await
|
|
9740
|
+
const backupContent = await readFile11(CHATS_BACKUP_FILE, "utf-8");
|
|
9617
9741
|
return parsePersistedChatsContent(backupContent);
|
|
9618
9742
|
} catch (backupError) {
|
|
9619
9743
|
if (backupError && typeof backupError === "object" && "code" in backupError && backupError.code === "ENOENT") {
|
|
@@ -9698,7 +9822,7 @@ var ChatService = class {
|
|
|
9698
9822
|
|
|
9699
9823
|
// src/services/repo-file-service.ts
|
|
9700
9824
|
import { execFile as execFile2 } from "child_process";
|
|
9701
|
-
import { readFile as
|
|
9825
|
+
import { readFile as readFile12, realpath, stat as stat2 } from "fs/promises";
|
|
9702
9826
|
import { join as join16, resolve, extname } from "path";
|
|
9703
9827
|
var CACHE_TTL_MS = 3e4;
|
|
9704
9828
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
@@ -9888,7 +10012,7 @@ var RepoFileService = class {
|
|
|
9888
10012
|
tooLarge: true
|
|
9889
10013
|
};
|
|
9890
10014
|
}
|
|
9891
|
-
const content = await
|
|
10015
|
+
const content = await readFile12(fullPath, "utf-8");
|
|
9892
10016
|
return {
|
|
9893
10017
|
repoName,
|
|
9894
10018
|
path: filePath,
|
|
@@ -9966,11 +10090,11 @@ var RepoFileService = class {
|
|
|
9966
10090
|
// src/v1-routes.ts
|
|
9967
10091
|
import { Hono } from "hono";
|
|
9968
10092
|
import { z as z2 } from "zod";
|
|
9969
|
-
import { readdir as readdir6, stat as stat4, readFile as
|
|
10093
|
+
import { readdir as readdir6, stat as stat4, readFile as readFile16 } from "fs/promises";
|
|
9970
10094
|
import { join as join20, resolve as resolve2 } from "path";
|
|
9971
10095
|
|
|
9972
10096
|
// src/services/canvas-service.ts
|
|
9973
|
-
import { readdir as readdir4, readFile as
|
|
10097
|
+
import { readdir as readdir4, readFile as readFile13, stat as stat3 } from "fs/promises";
|
|
9974
10098
|
import { homedir as homedir14 } from "os";
|
|
9975
10099
|
import { basename as basename2, join as join17 } from "path";
|
|
9976
10100
|
var CANVAS_DIRECTORIES = [
|
|
@@ -10035,10 +10159,10 @@ var CanvasService = class {
|
|
|
10035
10159
|
}
|
|
10036
10160
|
try {
|
|
10037
10161
|
if (isTextKind(kind)) {
|
|
10038
|
-
const content = await
|
|
10162
|
+
const content = await readFile13(filePath, "utf-8");
|
|
10039
10163
|
return { filename: safe, kind, sizeBytes, mimeType, content };
|
|
10040
10164
|
}
|
|
10041
|
-
const buf = await
|
|
10165
|
+
const buf = await readFile13(filePath);
|
|
10042
10166
|
return { filename: safe, kind, sizeBytes, mimeType, base64: buf.toString("base64") };
|
|
10043
10167
|
} catch {
|
|
10044
10168
|
continue;
|
|
@@ -10051,12 +10175,12 @@ var canvasService = new CanvasService();
|
|
|
10051
10175
|
|
|
10052
10176
|
// src/services/warm-hooks-service.ts
|
|
10053
10177
|
import { spawn as spawn4 } from "child_process";
|
|
10054
|
-
import { readFile as
|
|
10178
|
+
import { readFile as readFile15 } from "fs/promises";
|
|
10055
10179
|
import { existsSync as existsSync8 } from "fs";
|
|
10056
10180
|
import { join as join19 } from "path";
|
|
10057
10181
|
|
|
10058
10182
|
// src/services/warm-hook-logs-service.ts
|
|
10059
|
-
import { mkdir as mkdir12, readFile as
|
|
10183
|
+
import { mkdir as mkdir12, readFile as readFile14, writeFile as writeFile6, readdir as readdir5, appendFile as appendFile5, unlink as unlink3 } from "fs/promises";
|
|
10060
10184
|
import { homedir as homedir15 } from "os";
|
|
10061
10185
|
import { join as join18 } from "path";
|
|
10062
10186
|
var LOGS_DIR2 = join18(homedir15(), ".replicas", "warm-hook-logs");
|
|
@@ -10116,7 +10240,7 @@ var WarmHookLogsService = class {
|
|
|
10116
10240
|
continue;
|
|
10117
10241
|
}
|
|
10118
10242
|
try {
|
|
10119
|
-
const raw = await
|
|
10243
|
+
const raw = await readFile14(join18(LOGS_DIR2, file), "utf-8");
|
|
10120
10244
|
const stored = JSON.parse(raw);
|
|
10121
10245
|
logs.push(withPreview2(stored));
|
|
10122
10246
|
} catch {
|
|
@@ -10145,7 +10269,7 @@ var WarmHookLogsService = class {
|
|
|
10145
10269
|
}
|
|
10146
10270
|
async getCurrentRunLog() {
|
|
10147
10271
|
try {
|
|
10148
|
-
return await
|
|
10272
|
+
return await readFile14(CURRENT_RUN_LOG, "utf-8");
|
|
10149
10273
|
} catch (err) {
|
|
10150
10274
|
if (err.code === "ENOENT") return null;
|
|
10151
10275
|
throw err;
|
|
@@ -10154,7 +10278,7 @@ var WarmHookLogsService = class {
|
|
|
10154
10278
|
async getFullOutput(hookType, hookName) {
|
|
10155
10279
|
const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
10156
10280
|
try {
|
|
10157
|
-
const raw = await
|
|
10281
|
+
const raw = await readFile14(join18(LOGS_DIR2, filename), "utf-8");
|
|
10158
10282
|
const stored = JSON.parse(raw);
|
|
10159
10283
|
if (stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
10160
10284
|
return null;
|
|
@@ -10178,7 +10302,7 @@ async function readRepoWarmHook(repoPath) {
|
|
|
10178
10302
|
continue;
|
|
10179
10303
|
}
|
|
10180
10304
|
try {
|
|
10181
|
-
const raw = await
|
|
10305
|
+
const raw = await readFile15(configPath, "utf-8");
|
|
10182
10306
|
const config = parseReplicasConfigString(raw, filename);
|
|
10183
10307
|
if (!config.warmHook) {
|
|
10184
10308
|
return null;
|
|
@@ -10739,11 +10863,11 @@ function createV1Routes(deps) {
|
|
|
10739
10863
|
});
|
|
10740
10864
|
app2.get("/repo-files/content", async (c) => {
|
|
10741
10865
|
const repoName = c.req.query("repoName");
|
|
10742
|
-
const
|
|
10743
|
-
if (!repoName || !
|
|
10866
|
+
const path5 = c.req.query("path");
|
|
10867
|
+
if (!repoName || !path5) {
|
|
10744
10868
|
return c.json(jsonError("repoName and path are required"), 400);
|
|
10745
10869
|
}
|
|
10746
|
-
const result = await deps.repoFileService.readFile(repoName,
|
|
10870
|
+
const result = await deps.repoFileService.readFile(repoName, path5);
|
|
10747
10871
|
if (!result) {
|
|
10748
10872
|
return c.json(jsonError("File not found"), 404);
|
|
10749
10873
|
}
|
|
@@ -11141,7 +11265,7 @@ function createV1Routes(deps) {
|
|
|
11141
11265
|
const limit = Math.min(parseInt(c.req.query("limit") || "500", 10), 5e3);
|
|
11142
11266
|
let content;
|
|
11143
11267
|
try {
|
|
11144
|
-
content = await
|
|
11268
|
+
content = await readFile16(filePath, "utf-8");
|
|
11145
11269
|
} catch {
|
|
11146
11270
|
return c.json(jsonError("Log session not found"), 404);
|
|
11147
11271
|
}
|
|
@@ -11291,6 +11415,7 @@ app.get("/status", async (c) => {
|
|
|
11291
11415
|
app.get("/token-refresh/health", async (c) => {
|
|
11292
11416
|
return c.json({
|
|
11293
11417
|
github: githubTokenManager.getHealthStatus(),
|
|
11418
|
+
gitlab: gitlabTokenManager.getHealthStatus(),
|
|
11294
11419
|
claude: claudeTokenManager.getHealthStatus(),
|
|
11295
11420
|
codex: codexTokenManager.getHealthStatus()
|
|
11296
11421
|
});
|
|
@@ -11436,6 +11561,7 @@ serve(
|
|
|
11436
11561
|
void registerDesktopPreview();
|
|
11437
11562
|
heartbeatService.start(bootTimeMs);
|
|
11438
11563
|
if (!IS_WARMING_MODE) {
|
|
11564
|
+
await gitlabTokenManager.start();
|
|
11439
11565
|
await claudeTokenManager.start();
|
|
11440
11566
|
await codexTokenManager.start();
|
|
11441
11567
|
}
|