@spencer-kit/coder-studio 0.3.0 → 0.3.2
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/CHANGELOG.md +12 -0
- package/README.md +14 -79
- package/dist/esm/bin.mjs +572 -284
- package/dist/esm/bin.mjs.map +4 -4
- package/dist/esm/server-runner.mjs +450 -168
- package/dist/esm/server-runner.mjs.map +4 -4
- package/dist/web/assets/index-BjrMfcUG.js +111 -0
- package/dist/web/assets/index-BjrMfcUG.js.map +1 -0
- package/dist/web/assets/index-mL_Aq31j.css +1 -0
- package/dist/web/favicon.ico +0 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/favicon.svg +19 -0
- package/dist/web/index.html +4 -4
- package/package.json +2 -2
- package/src/bin.test.ts +1 -1
- package/src/bin.ts +6 -379
- package/src/browser.test.ts +50 -0
- package/src/browser.ts +1 -0
- package/src/cli.ts +347 -0
- package/src/package-manifest.test.ts +14 -0
- package/src/package-manifest.ts +28 -0
- package/src/pm2-control.test.ts +89 -1
- package/src/pm2-control.ts +99 -57
- package/src/server-control.test.ts +19 -0
- package/src/server-control.ts +1 -1
- package/src/server-runner.test.ts +14 -0
- package/src/server-runner.ts +2 -0
- package/dist/web/assets/index-A-2YPePM.js +0 -111
- package/dist/web/assets/index-A-2YPePM.js.map +0 -1
- package/dist/web/assets/index-BLMivSS1.css +0 -1
|
@@ -115,8 +115,8 @@ var init_plugin = __esm({
|
|
|
115
115
|
init_web_ui_routing();
|
|
116
116
|
init_login_protection();
|
|
117
117
|
AUTH_COOKIE_NAME = "coder_studio_auth";
|
|
118
|
-
isPublicPath = (
|
|
119
|
-
const pathname = getRequestPathname(
|
|
118
|
+
isPublicPath = (path9) => {
|
|
119
|
+
const pathname = getRequestPathname(path9);
|
|
120
120
|
return pathname === "/" || pathname === "/login" || pathname === "/healthz" || pathname === "/auth/status" || pathname === "/auth/login" || pathname === "/auth/logout" || pathname.startsWith("/@") || isPublicStaticPath(pathname);
|
|
121
121
|
};
|
|
122
122
|
parseCookies = (cookieHeader) => {
|
|
@@ -307,6 +307,25 @@ function parseLogLevel(value) {
|
|
|
307
307
|
return void 0;
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
+
function resolveDefaultAppVersion() {
|
|
311
|
+
if (cachedAppVersion) {
|
|
312
|
+
return cachedAppVersion;
|
|
313
|
+
}
|
|
314
|
+
const packageJsonPath = [new URL("../../cli/package.json", import.meta.url)].find(
|
|
315
|
+
(candidate) => fs.existsSync(candidate)
|
|
316
|
+
);
|
|
317
|
+
if (!packageJsonPath) {
|
|
318
|
+
cachedAppVersion = "0.0.0";
|
|
319
|
+
return cachedAppVersion;
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
323
|
+
cachedAppVersion = typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
324
|
+
} catch {
|
|
325
|
+
cachedAppVersion = "0.0.0";
|
|
326
|
+
}
|
|
327
|
+
return cachedAppVersion;
|
|
328
|
+
}
|
|
310
329
|
function resolveDbPath(explicit) {
|
|
311
330
|
if (explicit) return explicit;
|
|
312
331
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -345,6 +364,7 @@ function parseServerConfig(overrides) {
|
|
|
345
364
|
uploadsDir,
|
|
346
365
|
logLevel: overrides?.logLevel ?? parseLogLevel(process.env.LOG_LEVEL) ?? "info",
|
|
347
366
|
webRoot: overrides?.webRoot,
|
|
367
|
+
appVersion: overrides?.appVersion ?? process.env.CODER_STUDIO_APP_VERSION ?? resolveDefaultAppVersion(),
|
|
348
368
|
auth: overrides?.auth || {
|
|
349
369
|
enabled: !noAuth && !!password,
|
|
350
370
|
password
|
|
@@ -357,7 +377,7 @@ function ensureDataDir(config) {
|
|
|
357
377
|
}
|
|
358
378
|
fs.mkdirSync(path.dirname(config.dataDir), { recursive: true });
|
|
359
379
|
}
|
|
360
|
-
var cachedTestUploadsDir;
|
|
380
|
+
var cachedTestUploadsDir, cachedAppVersion;
|
|
361
381
|
var init_config = __esm({
|
|
362
382
|
"packages/server/src/config.ts"() {
|
|
363
383
|
"use strict";
|
|
@@ -365,7 +385,7 @@ var init_config = __esm({
|
|
|
365
385
|
});
|
|
366
386
|
|
|
367
387
|
// packages/core/src/runtime.ts
|
|
368
|
-
import { existsSync as
|
|
388
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
369
389
|
import { homedir as homedir2 } from "node:os";
|
|
370
390
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
371
391
|
function getRuntimeDir() {
|
|
@@ -385,14 +405,14 @@ function getRuntimePath() {
|
|
|
385
405
|
function writeRuntimeConfig(config) {
|
|
386
406
|
const runtimePath = getRuntimePath();
|
|
387
407
|
const runtimeDir = dirname2(runtimePath);
|
|
388
|
-
if (!
|
|
408
|
+
if (!existsSync4(runtimeDir)) {
|
|
389
409
|
mkdirSync2(runtimeDir, { recursive: true });
|
|
390
410
|
}
|
|
391
411
|
writeFileSync2(runtimePath, JSON.stringify(config, null, 2), "utf-8");
|
|
392
412
|
}
|
|
393
413
|
function deleteRuntimeConfig() {
|
|
394
414
|
const runtimePath = getRuntimePath();
|
|
395
|
-
if (
|
|
415
|
+
if (existsSync4(runtimePath)) {
|
|
396
416
|
unlinkSync(runtimePath);
|
|
397
417
|
}
|
|
398
418
|
}
|
|
@@ -765,6 +785,190 @@ var init_src = __esm({
|
|
|
765
785
|
}
|
|
766
786
|
});
|
|
767
787
|
|
|
788
|
+
// packages/utils/src/direct-execution.ts
|
|
789
|
+
import { posix, resolve as resolve2 } from "node:path";
|
|
790
|
+
function isWindowsDrivePath(path9) {
|
|
791
|
+
return /^[A-Za-z]:\//.test(path9);
|
|
792
|
+
}
|
|
793
|
+
function normalizeComparablePath(path9) {
|
|
794
|
+
let normalized = path9.replace(/\\/g, "/");
|
|
795
|
+
if (/^\/[A-Za-z]:\//.test(normalized)) {
|
|
796
|
+
normalized = normalized.slice(1);
|
|
797
|
+
}
|
|
798
|
+
if (normalized.startsWith("//")) {
|
|
799
|
+
normalized = `//${posix.normalize(normalized.slice(2))}`;
|
|
800
|
+
} else {
|
|
801
|
+
normalized = posix.normalize(normalized);
|
|
802
|
+
}
|
|
803
|
+
if (isWindowsDrivePath(normalized) || normalized.startsWith("//")) {
|
|
804
|
+
normalized = normalized.toLowerCase();
|
|
805
|
+
}
|
|
806
|
+
return normalized;
|
|
807
|
+
}
|
|
808
|
+
function normalizeModuleUrlPath(moduleUrl) {
|
|
809
|
+
let url;
|
|
810
|
+
try {
|
|
811
|
+
url = new URL(moduleUrl);
|
|
812
|
+
} catch {
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
if (url.protocol !== "file:") {
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
818
|
+
const path9 = `${url.host ? `//${url.host}` : ""}${decodeURIComponent(url.pathname)}`;
|
|
819
|
+
return normalizeComparablePath(path9);
|
|
820
|
+
}
|
|
821
|
+
function normalizeArgvPath(argv1) {
|
|
822
|
+
const isAbsoluteWindowsPath = /^[A-Za-z]:[\\/]/.test(argv1) || /^\\\\/.test(argv1);
|
|
823
|
+
return normalizeComparablePath(isAbsoluteWindowsPath ? argv1 : resolve2(argv1));
|
|
824
|
+
}
|
|
825
|
+
function isDirectExecution(moduleUrl, argv1 = process.argv[1]) {
|
|
826
|
+
if (argv1 === void 0) {
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
const modulePath = normalizeModuleUrlPath(moduleUrl);
|
|
830
|
+
if (modulePath === null) {
|
|
831
|
+
return false;
|
|
832
|
+
}
|
|
833
|
+
return modulePath === normalizeArgvPath(argv1);
|
|
834
|
+
}
|
|
835
|
+
var init_direct_execution = __esm({
|
|
836
|
+
"packages/utils/src/direct-execution.ts"() {
|
|
837
|
+
"use strict";
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
// packages/utils/src/windows-shim.ts
|
|
842
|
+
function shouldUseShellForCommand(command, platform = process.platform) {
|
|
843
|
+
return platform === "win32" && WINDOWS_CMD_SHIMS.has(command.toLowerCase());
|
|
844
|
+
}
|
|
845
|
+
var WINDOWS_CMD_SHIMS;
|
|
846
|
+
var init_windows_shim = __esm({
|
|
847
|
+
"packages/utils/src/windows-shim.ts"() {
|
|
848
|
+
"use strict";
|
|
849
|
+
WINDOWS_CMD_SHIMS = /* @__PURE__ */ new Set(["pnpm", "npm", "npx"]);
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// packages/utils/src/windows-shim-resolver.ts
|
|
854
|
+
import * as fs2 from "node:fs";
|
|
855
|
+
import * as path2 from "node:path";
|
|
856
|
+
function resolveSpawnArgv(argv, deps = {}) {
|
|
857
|
+
const platform = deps.platform ?? process.platform;
|
|
858
|
+
if (platform !== "win32") {
|
|
859
|
+
return [...argv];
|
|
860
|
+
}
|
|
861
|
+
const command = argv[0];
|
|
862
|
+
if (command === void 0) {
|
|
863
|
+
return [];
|
|
864
|
+
}
|
|
865
|
+
const restArgs = argv.slice(1);
|
|
866
|
+
const readFileSync9 = deps.readFileSync ?? ((file) => fs2.readFileSync(file, "utf8"));
|
|
867
|
+
const existsSync10 = deps.existsSync ?? fs2.existsSync;
|
|
868
|
+
const pathEnv = deps.pathEnv ?? process.env.Path ?? process.env.PATH ?? "";
|
|
869
|
+
const pathExt = deps.pathExt ?? process.env.PATHEXT ?? DEFAULT_PATHEXT;
|
|
870
|
+
const resolved = resolveExecutablePath(command, pathEnv, pathExt, existsSync10);
|
|
871
|
+
if (!resolved) {
|
|
872
|
+
return [...argv];
|
|
873
|
+
}
|
|
874
|
+
const ext = path2.win32.extname(resolved).toLowerCase();
|
|
875
|
+
if (ext === ".exe" || ext === ".com") {
|
|
876
|
+
return [resolved, ...restArgs];
|
|
877
|
+
}
|
|
878
|
+
if (ext === ".cmd" || ext === ".bat") {
|
|
879
|
+
let content;
|
|
880
|
+
try {
|
|
881
|
+
content = readFileSync9(resolved);
|
|
882
|
+
} catch {
|
|
883
|
+
return ["cmd.exe", "/d", "/s", "/c", resolved, ...restArgs];
|
|
884
|
+
}
|
|
885
|
+
const parsed = parseCmdShim(resolved, content);
|
|
886
|
+
if (parsed) {
|
|
887
|
+
return [parsed.node, parsed.entry, ...restArgs];
|
|
888
|
+
}
|
|
889
|
+
return ["cmd.exe", "/d", "/s", "/c", resolved, ...restArgs];
|
|
890
|
+
}
|
|
891
|
+
return [...argv];
|
|
892
|
+
}
|
|
893
|
+
function parseCmdShim(shimPath, content) {
|
|
894
|
+
const dp0Dir = path2.win32.dirname(shimPath);
|
|
895
|
+
const entryMatch = content.match(/"([^"\r\n]+\.js)"\s+%\*/i);
|
|
896
|
+
const entryRaw = entryMatch?.[1];
|
|
897
|
+
if (!entryRaw) {
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
const entry = expandShimVars(entryRaw, dp0Dir);
|
|
901
|
+
const nodeMatch = content.match(/"([^"\r\n]*node\.exe)"/i) ?? content.match(/"([^"\r\n]*node)"/i);
|
|
902
|
+
const nodeRaw = nodeMatch?.[1];
|
|
903
|
+
const node = nodeRaw ? expandShimVars(nodeRaw, dp0Dir) : "node";
|
|
904
|
+
return { node, entry };
|
|
905
|
+
}
|
|
906
|
+
function expandShimVars(value, dp0Dir) {
|
|
907
|
+
const dp0WithSlash = dp0Dir.endsWith("\\") ? dp0Dir : `${dp0Dir}\\`;
|
|
908
|
+
let expanded = value;
|
|
909
|
+
expanded = expanded.replace(/%~dp0/gi, dp0WithSlash);
|
|
910
|
+
expanded = expanded.replace(/%dp0%/gi, dp0WithSlash);
|
|
911
|
+
if (path2.win32.isAbsolute(expanded)) {
|
|
912
|
+
return path2.win32.normalize(expanded);
|
|
913
|
+
}
|
|
914
|
+
return path2.win32.resolve(dp0Dir, expanded);
|
|
915
|
+
}
|
|
916
|
+
function parsePathExt(pathExt) {
|
|
917
|
+
return pathExt.split(";").map((entry) => entry.trim().toLowerCase()).filter((entry) => entry.length > 0);
|
|
918
|
+
}
|
|
919
|
+
function resolveExecutablePath(command, pathEnv, pathExt, existsSync10) {
|
|
920
|
+
const hasExt = path2.win32.extname(command).length > 0;
|
|
921
|
+
const extensions = parsePathExt(pathExt);
|
|
922
|
+
if (path2.win32.isAbsolute(command)) {
|
|
923
|
+
if (existsSync10(command)) {
|
|
924
|
+
return command;
|
|
925
|
+
}
|
|
926
|
+
if (!hasExt) {
|
|
927
|
+
for (const ext of extensions) {
|
|
928
|
+
const candidate = command + ext;
|
|
929
|
+
if (existsSync10(candidate)) {
|
|
930
|
+
return candidate;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return null;
|
|
935
|
+
}
|
|
936
|
+
const dirs = pathEnv.split(";").map((dir) => dir.trim()).filter((dir) => dir.length > 0);
|
|
937
|
+
for (const dir of dirs) {
|
|
938
|
+
if (hasExt) {
|
|
939
|
+
const candidate = path2.win32.join(dir, command);
|
|
940
|
+
if (existsSync10(candidate)) {
|
|
941
|
+
return candidate;
|
|
942
|
+
}
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
for (const ext of extensions) {
|
|
946
|
+
const candidate = path2.win32.join(dir, command + ext);
|
|
947
|
+
if (existsSync10(candidate)) {
|
|
948
|
+
return candidate;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
return null;
|
|
953
|
+
}
|
|
954
|
+
var DEFAULT_PATHEXT;
|
|
955
|
+
var init_windows_shim_resolver = __esm({
|
|
956
|
+
"packages/utils/src/windows-shim-resolver.ts"() {
|
|
957
|
+
"use strict";
|
|
958
|
+
DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC";
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
// packages/utils/src/index.ts
|
|
963
|
+
var init_src2 = __esm({
|
|
964
|
+
"packages/utils/src/index.ts"() {
|
|
965
|
+
"use strict";
|
|
966
|
+
init_direct_execution();
|
|
967
|
+
init_windows_shim();
|
|
968
|
+
init_windows_shim_resolver();
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
|
|
768
972
|
// packages/server/src/fs/image.ts
|
|
769
973
|
import { extname } from "path";
|
|
770
974
|
function getImageTypeInfo(filePath) {
|
|
@@ -791,10 +995,10 @@ var init_image = __esm({
|
|
|
791
995
|
// packages/server/src/fs/file-io.ts
|
|
792
996
|
import { createHash } from "crypto";
|
|
793
997
|
import { readFile as fsReadFile, writeFile as fsWriteFile, mkdir, rm, stat } from "fs/promises";
|
|
794
|
-
import { dirname as dirname3, resolve as
|
|
795
|
-
async function statSafe(
|
|
998
|
+
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
999
|
+
async function statSafe(path9) {
|
|
796
1000
|
try {
|
|
797
|
-
return await stat(
|
|
1001
|
+
return await stat(path9);
|
|
798
1002
|
} catch {
|
|
799
1003
|
return null;
|
|
800
1004
|
}
|
|
@@ -825,8 +1029,8 @@ async function deleteEntry(rootPath, relPath) {
|
|
|
825
1029
|
await rm(abs, { recursive: true });
|
|
826
1030
|
}
|
|
827
1031
|
function resolveSafe(root, relPath) {
|
|
828
|
-
const absRoot =
|
|
829
|
-
const abs =
|
|
1032
|
+
const absRoot = resolve3(root);
|
|
1033
|
+
const abs = resolve3(absRoot, relPath);
|
|
830
1034
|
if (!abs.startsWith(absRoot + "/") && abs !== absRoot) {
|
|
831
1035
|
throw { code: "path_escape", message: "Path escapes workspace root" };
|
|
832
1036
|
}
|
|
@@ -964,7 +1168,7 @@ var init_constants = __esm({
|
|
|
964
1168
|
// packages/server/src/uploads/paths.ts
|
|
965
1169
|
import { randomUUID } from "node:crypto";
|
|
966
1170
|
import { lstat, mkdir as mkdir2 } from "node:fs/promises";
|
|
967
|
-
import
|
|
1171
|
+
import path3 from "node:path";
|
|
968
1172
|
function sanitizeOriginalName(input) {
|
|
969
1173
|
let sanitized = "";
|
|
970
1174
|
for (const char of input.trim()) {
|
|
@@ -1000,9 +1204,9 @@ async function assertDirectorySegmentSafe(segmentPath) {
|
|
|
1000
1204
|
}
|
|
1001
1205
|
}
|
|
1002
1206
|
async function ensureSafeUploadDir(rootDir, targetDir) {
|
|
1003
|
-
const resolvedRoot =
|
|
1004
|
-
const resolvedTarget =
|
|
1005
|
-
if (resolvedTarget !== resolvedRoot && !resolvedTarget.startsWith(`${resolvedRoot}${
|
|
1207
|
+
const resolvedRoot = path3.resolve(rootDir);
|
|
1208
|
+
const resolvedTarget = path3.resolve(targetDir);
|
|
1209
|
+
if (resolvedTarget !== resolvedRoot && !resolvedTarget.startsWith(`${resolvedRoot}${path3.sep}`)) {
|
|
1006
1210
|
throw new Error(`target dir escaped uploads root: ${resolvedTarget}`);
|
|
1007
1211
|
}
|
|
1008
1212
|
try {
|
|
@@ -1015,13 +1219,13 @@ async function ensureSafeUploadDir(rootDir, targetDir) {
|
|
|
1015
1219
|
await mkdir2(resolvedRoot, { recursive: true });
|
|
1016
1220
|
await assertDirectorySegmentSafe(resolvedRoot);
|
|
1017
1221
|
}
|
|
1018
|
-
const relative3 =
|
|
1222
|
+
const relative3 = path3.relative(resolvedRoot, resolvedTarget);
|
|
1019
1223
|
if (!relative3) {
|
|
1020
1224
|
return;
|
|
1021
1225
|
}
|
|
1022
1226
|
let current = resolvedRoot;
|
|
1023
|
-
for (const segment of relative3.split(
|
|
1024
|
-
current =
|
|
1227
|
+
for (const segment of relative3.split(path3.sep)) {
|
|
1228
|
+
current = path3.join(current, segment);
|
|
1025
1229
|
try {
|
|
1026
1230
|
await assertDirectorySegmentSafe(current);
|
|
1027
1231
|
continue;
|
|
@@ -1046,11 +1250,11 @@ function generateBucketPath(input) {
|
|
|
1046
1250
|
validateWorkspaceId(input.workspaceId);
|
|
1047
1251
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
1048
1252
|
const dateStr = now.toISOString().slice(0, 10);
|
|
1049
|
-
const dir =
|
|
1253
|
+
const dir = path3.join(input.uploadsDir, input.workspaceId, dateStr);
|
|
1050
1254
|
const sanitizedName = sanitizeOriginalName(input.originalName);
|
|
1051
1255
|
const uuid8 = randomUUID().replace(/-/g, "").slice(0, 8);
|
|
1052
|
-
const absolutePath =
|
|
1053
|
-
const uploadsRoot = `${
|
|
1256
|
+
const absolutePath = path3.resolve(dir, `${uuid8}-${sanitizedName}`);
|
|
1257
|
+
const uploadsRoot = `${path3.resolve(input.uploadsDir)}${path3.sep}`;
|
|
1054
1258
|
if (!absolutePath.startsWith(uploadsRoot)) {
|
|
1055
1259
|
throw new Error(`generated upload path escaped uploads root: ${absolutePath}`);
|
|
1056
1260
|
}
|
|
@@ -1073,7 +1277,7 @@ var init_paths = __esm({
|
|
|
1073
1277
|
|
|
1074
1278
|
// packages/server/src/uploads/cleanup.ts
|
|
1075
1279
|
import { readdir, rm as rm2, rmdir, stat as stat3, unlink } from "node:fs/promises";
|
|
1076
|
-
import
|
|
1280
|
+
import path4 from "node:path";
|
|
1077
1281
|
async function listFilesRecursive(root) {
|
|
1078
1282
|
let entries;
|
|
1079
1283
|
try {
|
|
@@ -1086,7 +1290,7 @@ async function listFilesRecursive(root) {
|
|
|
1086
1290
|
}
|
|
1087
1291
|
const files = [];
|
|
1088
1292
|
for (const entry of entries) {
|
|
1089
|
-
const childPath =
|
|
1293
|
+
const childPath = path4.join(root, entry.name);
|
|
1090
1294
|
if (entry.isDirectory()) {
|
|
1091
1295
|
files.push(...await listFilesRecursive(childPath));
|
|
1092
1296
|
continue;
|
|
@@ -1117,7 +1321,7 @@ async function pruneEmptyDirectories(root) {
|
|
|
1117
1321
|
if (!entry.isDirectory()) {
|
|
1118
1322
|
continue;
|
|
1119
1323
|
}
|
|
1120
|
-
await pruneEmptyDirectories(
|
|
1324
|
+
await pruneEmptyDirectories(path4.join(root, entry.name));
|
|
1121
1325
|
}
|
|
1122
1326
|
const remainingEntries = await readdir(root).catch(() => []);
|
|
1123
1327
|
if (remainingEntries.length === 0) {
|
|
@@ -1126,12 +1330,12 @@ async function pruneEmptyDirectories(root) {
|
|
|
1126
1330
|
}
|
|
1127
1331
|
async function deleteWorkspaceUploads(uploadsDir, workspaceId) {
|
|
1128
1332
|
validateWorkspaceId(workspaceId);
|
|
1129
|
-
const bucket =
|
|
1333
|
+
const bucket = path4.join(uploadsDir, workspaceId);
|
|
1130
1334
|
await rm2(bucket, { recursive: true, force: true });
|
|
1131
1335
|
}
|
|
1132
1336
|
async function enforceBucketCap(uploadsDir, workspaceId, capBytes, logger) {
|
|
1133
1337
|
validateWorkspaceId(workspaceId);
|
|
1134
|
-
const bucket =
|
|
1338
|
+
const bucket = path4.join(uploadsDir, workspaceId);
|
|
1135
1339
|
const files = await listFilesRecursive(bucket);
|
|
1136
1340
|
const totalBytes = files.reduce((sum, file) => sum + file.size, 0);
|
|
1137
1341
|
if (totalBytes <= capBytes) {
|
|
@@ -1171,7 +1375,7 @@ async function runStartupGc(uploadsDir, logger) {
|
|
|
1171
1375
|
if (!workspaceEntry.isDirectory()) {
|
|
1172
1376
|
continue;
|
|
1173
1377
|
}
|
|
1174
|
-
const workspaceDir =
|
|
1378
|
+
const workspaceDir = path4.join(uploadsDir, workspaceEntry.name);
|
|
1175
1379
|
const dateEntries = await readdir(workspaceDir, { withFileTypes: true }).catch(
|
|
1176
1380
|
() => []
|
|
1177
1381
|
);
|
|
@@ -1179,7 +1383,7 @@ async function runStartupGc(uploadsDir, logger) {
|
|
|
1179
1383
|
if (!dateEntry.isDirectory()) {
|
|
1180
1384
|
continue;
|
|
1181
1385
|
}
|
|
1182
|
-
const dateDir =
|
|
1386
|
+
const dateDir = path4.join(workspaceDir, dateEntry.name);
|
|
1183
1387
|
const files = await listFilesRecursive(dateDir);
|
|
1184
1388
|
for (const file of files) {
|
|
1185
1389
|
if (file.mtimeMs >= cutoffMs) {
|
|
@@ -1570,7 +1774,7 @@ var init_app = __esm({
|
|
|
1570
1774
|
});
|
|
1571
1775
|
|
|
1572
1776
|
// packages/server/src/config/codex-config-audit.ts
|
|
1573
|
-
import { existsSync as
|
|
1777
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1574
1778
|
import { homedir as homedir3 } from "node:os";
|
|
1575
1779
|
import { dirname as dirname4, join as join3 } from "node:path";
|
|
1576
1780
|
function resolveCodexConfigPath() {
|
|
@@ -1581,15 +1785,15 @@ function resolveCodexConfigPath() {
|
|
|
1581
1785
|
return join3(homedir3(), ".codex", "config.toml");
|
|
1582
1786
|
}
|
|
1583
1787
|
function auditCodexConfigToml(configPath) {
|
|
1584
|
-
const
|
|
1585
|
-
if (!
|
|
1586
|
-
return { configPath:
|
|
1788
|
+
const path9 = configPath ?? resolveCodexConfigPath();
|
|
1789
|
+
if (!existsSync6(path9)) {
|
|
1790
|
+
return { configPath: path9, exists: false, findings: [] };
|
|
1587
1791
|
}
|
|
1588
1792
|
let content;
|
|
1589
1793
|
try {
|
|
1590
|
-
content =
|
|
1794
|
+
content = readFileSync5(path9, "utf-8");
|
|
1591
1795
|
} catch {
|
|
1592
|
-
return { configPath:
|
|
1796
|
+
return { configPath: path9, exists: false, findings: [] };
|
|
1593
1797
|
}
|
|
1594
1798
|
const lines = content.split(/\r?\n/);
|
|
1595
1799
|
const findings = [];
|
|
@@ -1597,13 +1801,13 @@ function auditCodexConfigToml(configPath) {
|
|
|
1597
1801
|
if (notifyFinding) findings.push(notifyFinding);
|
|
1598
1802
|
const codexHooksFinding = detectCodexHooksFlag(lines);
|
|
1599
1803
|
if (codexHooksFinding) findings.push(codexHooksFinding);
|
|
1600
|
-
return { configPath:
|
|
1804
|
+
return { configPath: path9, exists: true, findings };
|
|
1601
1805
|
}
|
|
1602
1806
|
function cleanupCodexConfigToml(configPath, opts) {
|
|
1603
1807
|
if (opts.removeIds.length === 0) {
|
|
1604
1808
|
return { removed: [], backupPath: null, noop: true };
|
|
1605
1809
|
}
|
|
1606
|
-
if (!
|
|
1810
|
+
if (!existsSync6(configPath)) {
|
|
1607
1811
|
return { removed: [], backupPath: null, noop: true };
|
|
1608
1812
|
}
|
|
1609
1813
|
const audit = auditCodexConfigToml(configPath);
|
|
@@ -1611,7 +1815,7 @@ function cleanupCodexConfigToml(configPath, opts) {
|
|
|
1611
1815
|
if (selected.length === 0) {
|
|
1612
1816
|
return { removed: [], backupPath: null, noop: true };
|
|
1613
1817
|
}
|
|
1614
|
-
const original =
|
|
1818
|
+
const original = readFileSync5(configPath, "utf-8");
|
|
1615
1819
|
const backupPath = writeBackup(configPath, original, opts.backupDir);
|
|
1616
1820
|
const linesToDrop = /* @__PURE__ */ new Set();
|
|
1617
1821
|
for (const finding of selected) {
|
|
@@ -1713,7 +1917,7 @@ function countBrackets(s) {
|
|
|
1713
1917
|
}
|
|
1714
1918
|
function writeBackup(configPath, original, backupDir) {
|
|
1715
1919
|
const dir = backupDir ?? dirname4(configPath);
|
|
1716
|
-
if (!
|
|
1920
|
+
if (!existsSync6(dir)) {
|
|
1717
1921
|
mkdirSync3(dir, { recursive: true });
|
|
1718
1922
|
}
|
|
1719
1923
|
const ts = formatTimestamp(/* @__PURE__ */ new Date());
|
|
@@ -1754,35 +1958,78 @@ var init_codex_config_audit = __esm({
|
|
|
1754
1958
|
}
|
|
1755
1959
|
});
|
|
1756
1960
|
|
|
1961
|
+
// packages/server/src/provider-runtime/command-runner.ts
|
|
1962
|
+
import { spawn } from "node:child_process";
|
|
1963
|
+
async function runCommandAsString(file, args, options) {
|
|
1964
|
+
return new Promise((resolve4, reject) => {
|
|
1965
|
+
const child = spawn(file, args, {
|
|
1966
|
+
shell: shouldUseShellForCommand(file, process.platform),
|
|
1967
|
+
windowsHide: options?.windowsHide ?? true
|
|
1968
|
+
});
|
|
1969
|
+
const stdoutChunks = [];
|
|
1970
|
+
const stderrChunks = [];
|
|
1971
|
+
child.stdout?.on("data", (chunk) => {
|
|
1972
|
+
stdoutChunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
1973
|
+
});
|
|
1974
|
+
child.stderr?.on("data", (chunk) => {
|
|
1975
|
+
stderrChunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
1976
|
+
});
|
|
1977
|
+
child.on("error", (error) => {
|
|
1978
|
+
reject(
|
|
1979
|
+
Object.assign(error, {
|
|
1980
|
+
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
1981
|
+
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
1982
|
+
})
|
|
1983
|
+
);
|
|
1984
|
+
});
|
|
1985
|
+
child.on("close", (code) => {
|
|
1986
|
+
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
1987
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
1988
|
+
if (code === 0) {
|
|
1989
|
+
resolve4({ stdout, stderr });
|
|
1990
|
+
return;
|
|
1991
|
+
}
|
|
1992
|
+
reject(
|
|
1993
|
+
Object.assign(new Error(`Command failed with exit code ${code ?? "unknown"}`), {
|
|
1994
|
+
exitCode: code ?? void 0,
|
|
1995
|
+
stdout,
|
|
1996
|
+
stderr
|
|
1997
|
+
})
|
|
1998
|
+
);
|
|
1999
|
+
});
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
2002
|
+
var init_command_runner = __esm({
|
|
2003
|
+
"packages/server/src/provider-runtime/command-runner.ts"() {
|
|
2004
|
+
"use strict";
|
|
2005
|
+
init_src2();
|
|
2006
|
+
}
|
|
2007
|
+
});
|
|
2008
|
+
|
|
1757
2009
|
// packages/server/src/provider-runtime/command-check.ts
|
|
1758
|
-
import { execFile as nodeExecFile } from "node:child_process";
|
|
1759
|
-
import { promisify } from "node:util";
|
|
1760
2010
|
function getCommandLookupExecutable(platform) {
|
|
1761
2011
|
return platform === "win32" ? "where" : "which";
|
|
1762
2012
|
}
|
|
1763
2013
|
async function checkCommandAvailable(command, deps = {}) {
|
|
1764
2014
|
const platform = deps.platform ?? process.platform;
|
|
1765
|
-
const
|
|
2015
|
+
const runCommand2 = deps.runCommand ?? runCommandAsString;
|
|
1766
2016
|
const lookup = getCommandLookupExecutable(platform);
|
|
1767
2017
|
try {
|
|
1768
|
-
await
|
|
1769
|
-
return
|
|
2018
|
+
const { stdout } = await runCommand2(lookup, [command], { windowsHide: true });
|
|
2019
|
+
return stdout.trim().length > 0;
|
|
1770
2020
|
} catch {
|
|
1771
2021
|
return false;
|
|
1772
2022
|
}
|
|
1773
2023
|
}
|
|
1774
|
-
var execFileAsync;
|
|
1775
2024
|
var init_command_check = __esm({
|
|
1776
2025
|
"packages/server/src/provider-runtime/command-check.ts"() {
|
|
1777
2026
|
"use strict";
|
|
1778
|
-
|
|
2027
|
+
init_command_runner();
|
|
1779
2028
|
}
|
|
1780
2029
|
});
|
|
1781
2030
|
|
|
1782
2031
|
// packages/server/src/provider-runtime/install-manager.ts
|
|
1783
|
-
import { execFile as nodeExecFile2 } from "node:child_process";
|
|
1784
2032
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
1785
|
-
import { promisify as promisify2 } from "node:util";
|
|
1786
2033
|
function getErrorDetails(error) {
|
|
1787
2034
|
if (error instanceof Error) {
|
|
1788
2035
|
const record = error;
|
|
@@ -1857,12 +2104,12 @@ function cloneFailure(failure) {
|
|
|
1857
2104
|
}
|
|
1858
2105
|
};
|
|
1859
2106
|
}
|
|
1860
|
-
var
|
|
2107
|
+
var EXCERPT_LIMIT, ProviderInstallManager;
|
|
1861
2108
|
var init_install_manager = __esm({
|
|
1862
2109
|
"packages/server/src/provider-runtime/install-manager.ts"() {
|
|
1863
2110
|
"use strict";
|
|
1864
2111
|
init_command_check();
|
|
1865
|
-
|
|
2112
|
+
init_command_runner();
|
|
1866
2113
|
EXCERPT_LIMIT = 400;
|
|
1867
2114
|
ProviderInstallManager = class {
|
|
1868
2115
|
providers = /* @__PURE__ */ new Map();
|
|
@@ -2047,7 +2294,7 @@ var init_install_manager = __esm({
|
|
|
2047
2294
|
};
|
|
2048
2295
|
}
|
|
2049
2296
|
async runPreparedJob(provider, job) {
|
|
2050
|
-
const
|
|
2297
|
+
const runCommand2 = this.deps.runCommand ?? runCommandAsString;
|
|
2051
2298
|
job.status = "running";
|
|
2052
2299
|
this.jobs.set(job.jobId, job);
|
|
2053
2300
|
for (const step of job.steps) {
|
|
@@ -2074,7 +2321,7 @@ var init_install_manager = __esm({
|
|
|
2074
2321
|
return;
|
|
2075
2322
|
}
|
|
2076
2323
|
} else {
|
|
2077
|
-
const result = await
|
|
2324
|
+
const result = await runCommand2(step.command, step.args, { windowsHide: true });
|
|
2078
2325
|
step.stdoutExcerpt = excerpt(result.stdout);
|
|
2079
2326
|
step.stderrExcerpt = excerpt(result.stderr);
|
|
2080
2327
|
}
|
|
@@ -2410,7 +2657,7 @@ var init_idle_heuristics2 = __esm({
|
|
|
2410
2657
|
});
|
|
2411
2658
|
|
|
2412
2659
|
// packages/core/src/index.ts
|
|
2413
|
-
var
|
|
2660
|
+
var init_src3 = __esm({
|
|
2414
2661
|
"packages/core/src/index.ts"() {
|
|
2415
2662
|
"use strict";
|
|
2416
2663
|
init_events();
|
|
@@ -2447,14 +2694,16 @@ var init_provider_config = __esm({
|
|
|
2447
2694
|
SUPPORTED_PROVIDER_IDS = ["claude", "codex"];
|
|
2448
2695
|
supportedProviderIds = new Set(SUPPORTED_PROVIDER_IDS);
|
|
2449
2696
|
ProviderLaunchConfigInputSchema = z4.object({
|
|
2450
|
-
additionalArgs: z4.array(z4.string()).optional()
|
|
2697
|
+
additionalArgs: z4.array(z4.string()).optional(),
|
|
2698
|
+
envVars: z4.record(z4.string(), z4.string()).optional()
|
|
2451
2699
|
}).strict();
|
|
2452
2700
|
ProviderSettingsSchema = z4.object({
|
|
2453
2701
|
claude: ProviderLaunchConfigInputSchema.optional(),
|
|
2454
2702
|
codex: ProviderLaunchConfigInputSchema.optional()
|
|
2455
2703
|
}).strict();
|
|
2456
2704
|
ProviderLaunchConfigSchema = z4.object({
|
|
2457
|
-
additionalArgs: z4.array(z4.string()).default([])
|
|
2705
|
+
additionalArgs: z4.array(z4.string()).default([]),
|
|
2706
|
+
envVars: z4.record(z4.string(), z4.string()).optional()
|
|
2458
2707
|
});
|
|
2459
2708
|
}
|
|
2460
2709
|
});
|
|
@@ -2720,7 +2969,7 @@ var NOOP_SESSION_LOGGER, SessionManager, ActiveSession;
|
|
|
2720
2969
|
var init_manager = __esm({
|
|
2721
2970
|
"packages/server/src/session/manager.ts"() {
|
|
2722
2971
|
"use strict";
|
|
2723
|
-
|
|
2972
|
+
init_src3();
|
|
2724
2973
|
init_provider_config();
|
|
2725
2974
|
init_session_repo();
|
|
2726
2975
|
init_pty_state_detector();
|
|
@@ -3261,7 +3510,7 @@ var init_database = __esm({
|
|
|
3261
3510
|
|
|
3262
3511
|
// packages/server/src/storage/db.ts
|
|
3263
3512
|
import { DatabaseSync } from "node:sqlite";
|
|
3264
|
-
import { readFileSync as
|
|
3513
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
3265
3514
|
import { join as join4 } from "path";
|
|
3266
3515
|
function normalizeSql(sql) {
|
|
3267
3516
|
return (sql ?? "").replace(/\s+/g, " ").trim();
|
|
@@ -3410,7 +3659,7 @@ var init_db = __esm({
|
|
|
3410
3659
|
"use strict";
|
|
3411
3660
|
init_database();
|
|
3412
3661
|
SCHEMA_PATH = join4(import.meta.dirname, "migrations", "001_init.sql");
|
|
3413
|
-
SCHEMA_SQL =
|
|
3662
|
+
SCHEMA_SQL = readFileSync6(SCHEMA_PATH, "utf-8");
|
|
3414
3663
|
LEGACY_TABLES = ["hook_registrations", "_migrations"];
|
|
3415
3664
|
LEGACY_SESSION_COLUMNS = ["resume_id", "transcript_path"];
|
|
3416
3665
|
EXPECTED_SCHEMA_ENTRIES = buildExpectedSchemaEntries();
|
|
@@ -3960,11 +4209,11 @@ function parseOrdinaryChangedEntry(record, staged, modified, deleted) {
|
|
|
3960
4209
|
if (!xy) {
|
|
3961
4210
|
return;
|
|
3962
4211
|
}
|
|
3963
|
-
const
|
|
3964
|
-
if (!
|
|
4212
|
+
const path9 = parts.slice(8).join(" ");
|
|
4213
|
+
if (!path9) {
|
|
3965
4214
|
return;
|
|
3966
4215
|
}
|
|
3967
|
-
pushChange({ path:
|
|
4216
|
+
pushChange({ path: path9 }, xy, staged, modified, deleted);
|
|
3968
4217
|
}
|
|
3969
4218
|
function parseRenamedEntry(record, oldPathRecord, staged, modified, deleted) {
|
|
3970
4219
|
const parts = record.split(" ");
|
|
@@ -3976,12 +4225,12 @@ function parseRenamedEntry(record, oldPathRecord, staged, modified, deleted) {
|
|
|
3976
4225
|
const pathAndMaybeOldPath = pathTokens.join(" ");
|
|
3977
4226
|
const inlinePathParts = pathAndMaybeOldPath.split(" ");
|
|
3978
4227
|
const fallbackPath = !oldPathRecord && inlinePathParts.length === 1 && pathTokens.length > 1 ? pathTokens.slice(0, -1).join(" ") : void 0;
|
|
3979
|
-
const
|
|
3980
|
-
if (!
|
|
4228
|
+
const path9 = fallbackPath ?? inlinePathParts[0];
|
|
4229
|
+
if (!path9) {
|
|
3981
4230
|
return;
|
|
3982
4231
|
}
|
|
3983
4232
|
const oldPath = (oldPathRecord && !oldPathRecord.startsWith("#") ? oldPathRecord : void 0) ?? inlinePathParts[1] ?? (pathTokens.length > 1 ? pathTokens[pathTokens.length - 1] : void 0);
|
|
3984
|
-
pushChange({ path:
|
|
4233
|
+
pushChange({ path: path9, oldPath }, xy, staged, modified, deleted);
|
|
3985
4234
|
}
|
|
3986
4235
|
function pushChange(change, xy, staged, modified, deleted) {
|
|
3987
4236
|
const indexStatus = xy[0];
|
|
@@ -4008,9 +4257,9 @@ var init_status_parser = __esm({
|
|
|
4008
4257
|
import { execFile } from "child_process";
|
|
4009
4258
|
import { mkdir as mkdir3, mkdtemp, rm as rm4, writeFile as writeFile3 } from "fs/promises";
|
|
4010
4259
|
import os2 from "os";
|
|
4011
|
-
import
|
|
4260
|
+
import path5 from "path";
|
|
4012
4261
|
async function runGit(cwd, args, options = {}) {
|
|
4013
|
-
return new Promise((
|
|
4262
|
+
return new Promise((resolve4, reject) => {
|
|
4014
4263
|
const gitArgs = [
|
|
4015
4264
|
...options.config?.flatMap(([key, value]) => ["-c", `${key}=${value}`]) ?? [],
|
|
4016
4265
|
...args
|
|
@@ -4030,13 +4279,14 @@ async function runGit(cwd, args, options = {}) {
|
|
|
4030
4279
|
...options.env
|
|
4031
4280
|
},
|
|
4032
4281
|
maxBuffer: 10 * 1024 * 1024,
|
|
4033
|
-
timeout: options.timeoutMs
|
|
4282
|
+
timeout: options.timeoutMs,
|
|
4283
|
+
windowsHide: true
|
|
4034
4284
|
},
|
|
4035
4285
|
(err, stdout, stderr) => {
|
|
4036
4286
|
if (err) {
|
|
4037
4287
|
reject(new GitError(err.message, stderr));
|
|
4038
4288
|
} else {
|
|
4039
|
-
|
|
4289
|
+
resolve4({ stdout, stderr });
|
|
4040
4290
|
}
|
|
4041
4291
|
}
|
|
4042
4292
|
);
|
|
@@ -4085,12 +4335,12 @@ async function discardChanges(cwd, paths) {
|
|
|
4085
4335
|
if (paths.length === 0) return;
|
|
4086
4336
|
const trackedPaths = [];
|
|
4087
4337
|
const untrackedPaths = [];
|
|
4088
|
-
for (const
|
|
4338
|
+
for (const path9 of paths) {
|
|
4089
4339
|
try {
|
|
4090
|
-
await runGit(cwd, ["ls-files", "--error-unmatch", "--",
|
|
4091
|
-
trackedPaths.push(
|
|
4340
|
+
await runGit(cwd, ["ls-files", "--error-unmatch", "--", path9]);
|
|
4341
|
+
trackedPaths.push(path9);
|
|
4092
4342
|
} catch {
|
|
4093
|
-
untrackedPaths.push(
|
|
4343
|
+
untrackedPaths.push(path9);
|
|
4094
4344
|
}
|
|
4095
4345
|
}
|
|
4096
4346
|
if (trackedPaths.length > 0) {
|
|
@@ -4358,9 +4608,9 @@ async function prepareGitAuthExecution(auth, remoteMetadata) {
|
|
|
4358
4608
|
}
|
|
4359
4609
|
};
|
|
4360
4610
|
}
|
|
4361
|
-
const tempDir = await mkdtemp(
|
|
4362
|
-
const hooksDir =
|
|
4363
|
-
const askPassPath =
|
|
4611
|
+
const tempDir = await mkdtemp(path5.join(os2.tmpdir(), "coder-studio-git-auth-"));
|
|
4612
|
+
const hooksDir = path5.join(tempDir, "hooks");
|
|
4613
|
+
const askPassPath = path5.join(tempDir, "askpass.sh");
|
|
4364
4614
|
await mkdir3(hooksDir, { recursive: true, mode: 448 });
|
|
4365
4615
|
await writeFile3(
|
|
4366
4616
|
askPassPath,
|
|
@@ -4714,31 +4964,31 @@ var init_context_builder = __esm({
|
|
|
4714
4964
|
});
|
|
4715
4965
|
|
|
4716
4966
|
// packages/server/src/terminal/pty-host.ts
|
|
4717
|
-
import { chmodSync, existsSync as
|
|
4967
|
+
import { chmodSync, existsSync as existsSync7, statSync } from "node:fs";
|
|
4718
4968
|
import { createRequire } from "node:module";
|
|
4719
|
-
import
|
|
4969
|
+
import path6 from "node:path";
|
|
4720
4970
|
function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
4721
4971
|
const platform = deps.platform ?? process.platform;
|
|
4722
4972
|
if (platform !== "darwin") {
|
|
4723
4973
|
return;
|
|
4724
4974
|
}
|
|
4725
4975
|
const arch = deps.arch ?? process.arch;
|
|
4726
|
-
const
|
|
4727
|
-
const fileExists = deps.existsSync ??
|
|
4976
|
+
const resolve4 = deps.resolve ?? ((id) => require2.resolve(id));
|
|
4977
|
+
const fileExists = deps.existsSync ?? existsSync7;
|
|
4728
4978
|
const stat7 = deps.statSync ?? statSync;
|
|
4729
4979
|
const chmod = deps.chmodSync ?? chmodSync;
|
|
4730
4980
|
let packageJsonPath;
|
|
4731
4981
|
try {
|
|
4732
|
-
packageJsonPath =
|
|
4982
|
+
packageJsonPath = resolve4(NODE_PTY_PKG);
|
|
4733
4983
|
} catch {
|
|
4734
4984
|
return;
|
|
4735
4985
|
}
|
|
4736
|
-
const packageDir =
|
|
4986
|
+
const packageDir = path6.dirname(packageJsonPath);
|
|
4737
4987
|
const helperDir = arch === "arm64" ? "darwin-arm64" : arch === "x64" ? "darwin-x64" : null;
|
|
4738
4988
|
if (!helperDir) {
|
|
4739
4989
|
return;
|
|
4740
4990
|
}
|
|
4741
|
-
const helperPath =
|
|
4991
|
+
const helperPath = path6.join(packageDir, "prebuilds", helperDir, "spawn-helper");
|
|
4742
4992
|
try {
|
|
4743
4993
|
if (!fileExists(helperPath)) {
|
|
4744
4994
|
return;
|
|
@@ -4794,7 +5044,7 @@ async function escalateKillWithPolling(pid, signal, options) {
|
|
|
4794
5044
|
const startTime = Date.now();
|
|
4795
5045
|
const deadline = startTime + timeoutMs;
|
|
4796
5046
|
while (Date.now() < deadline) {
|
|
4797
|
-
await new Promise((
|
|
5047
|
+
await new Promise((resolve4) => setTimeout(resolve4, pollIntervalMs));
|
|
4798
5048
|
if (!isProcessAlive(pid)) {
|
|
4799
5049
|
return true;
|
|
4800
5050
|
}
|
|
@@ -4806,6 +5056,7 @@ var require2, NODE_PTY_PKG, DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, NodePt
|
|
|
4806
5056
|
var init_pty_host = __esm({
|
|
4807
5057
|
"packages/server/src/terminal/pty-host.ts"() {
|
|
4808
5058
|
"use strict";
|
|
5059
|
+
init_src2();
|
|
4809
5060
|
require2 = createRequire(import.meta.url);
|
|
4810
5061
|
NODE_PTY_PKG = "node-pty/package.json";
|
|
4811
5062
|
DEFAULT_POLL_INTERVAL_MS = 50;
|
|
@@ -4820,7 +5071,13 @@ var init_pty_host = __esm({
|
|
|
4820
5071
|
const message = err instanceof Error ? err.message : String(err);
|
|
4821
5072
|
throw new Error(`node-pty native module not available. ${message}`);
|
|
4822
5073
|
}
|
|
4823
|
-
|
|
5074
|
+
if (argv.length === 0) {
|
|
5075
|
+
throw new Error("PTY spawn requires a command");
|
|
5076
|
+
}
|
|
5077
|
+
const [command, ...args] = resolveSpawnArgv(argv, {
|
|
5078
|
+
pathEnv: options.env.Path ?? options.env.PATH,
|
|
5079
|
+
pathExt: options.env.PATHEXT
|
|
5080
|
+
});
|
|
4824
5081
|
if (command === void 0) {
|
|
4825
5082
|
throw new Error("PTY spawn requires a command");
|
|
4826
5083
|
}
|
|
@@ -4881,13 +5138,13 @@ var SUPERVISOR_EVALUATION_TIMEOUT_SETTING_KEY;
|
|
|
4881
5138
|
var init_settings = __esm({
|
|
4882
5139
|
"packages/server/src/supervisor/settings.ts"() {
|
|
4883
5140
|
"use strict";
|
|
4884
|
-
|
|
5141
|
+
init_src3();
|
|
4885
5142
|
SUPERVISOR_EVALUATION_TIMEOUT_SETTING_KEY = "supervisor.evaluationTimeoutSec";
|
|
4886
5143
|
}
|
|
4887
5144
|
});
|
|
4888
5145
|
|
|
4889
5146
|
// packages/server/src/supervisor/evaluator.ts
|
|
4890
|
-
import { spawn } from "node:child_process";
|
|
5147
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
4891
5148
|
function buildPrompt(context) {
|
|
4892
5149
|
const agentOutput = context.transcriptExcerpt ?? context.terminalExcerpt ?? "";
|
|
4893
5150
|
const userInput = context.latestUserInput?.trim() ?? "";
|
|
@@ -4918,12 +5175,13 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
4918
5175
|
if (options.signal?.aborted) {
|
|
4919
5176
|
throw createSupervisorEvalAbortedError();
|
|
4920
5177
|
}
|
|
4921
|
-
return await new Promise((
|
|
4922
|
-
const child =
|
|
5178
|
+
return await new Promise((resolve4, reject) => {
|
|
5179
|
+
const child = spawn2(command.argv[0], command.argv.slice(1), {
|
|
4923
5180
|
cwd: command.cwd,
|
|
4924
5181
|
detached: process.platform !== "win32",
|
|
4925
5182
|
env: { ...process.env, ...command.env },
|
|
4926
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
5183
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
5184
|
+
windowsHide: true
|
|
4927
5185
|
});
|
|
4928
5186
|
const stdout = [];
|
|
4929
5187
|
const stderr = [];
|
|
@@ -4947,7 +5205,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
4947
5205
|
}
|
|
4948
5206
|
settled = true;
|
|
4949
5207
|
cleanup();
|
|
4950
|
-
|
|
5208
|
+
resolve4(value);
|
|
4951
5209
|
};
|
|
4952
5210
|
const terminate = (error) => {
|
|
4953
5211
|
if (terminationError) {
|
|
@@ -5154,7 +5412,7 @@ var NOOP_LOGGER2, SupervisorEvaluator;
|
|
|
5154
5412
|
var init_evaluator = __esm({
|
|
5155
5413
|
"packages/server/src/supervisor/evaluator.ts"() {
|
|
5156
5414
|
"use strict";
|
|
5157
|
-
|
|
5415
|
+
init_src3();
|
|
5158
5416
|
init_provider_config();
|
|
5159
5417
|
init_pty_host();
|
|
5160
5418
|
init_settings();
|
|
@@ -5257,7 +5515,7 @@ var INJECTABLE_SESSION_STATES, SupervisorInjector;
|
|
|
5257
5515
|
var init_injector = __esm({
|
|
5258
5516
|
"packages/server/src/supervisor/injector.ts"() {
|
|
5259
5517
|
"use strict";
|
|
5260
|
-
|
|
5518
|
+
init_src3();
|
|
5261
5519
|
INJECTABLE_SESSION_STATES = /* @__PURE__ */ new Set([
|
|
5262
5520
|
"idle",
|
|
5263
5521
|
"running"
|
|
@@ -5334,12 +5592,12 @@ var init_scheduler = __esm({
|
|
|
5334
5592
|
|
|
5335
5593
|
// packages/server/src/supervisor/manager.ts
|
|
5336
5594
|
function createDeferredCompletion() {
|
|
5337
|
-
let
|
|
5595
|
+
let resolve4 = () => {
|
|
5338
5596
|
};
|
|
5339
5597
|
const promise = new Promise((innerResolve) => {
|
|
5340
|
-
|
|
5598
|
+
resolve4 = innerResolve;
|
|
5341
5599
|
});
|
|
5342
|
-
return { promise, resolve:
|
|
5600
|
+
return { promise, resolve: resolve4 };
|
|
5343
5601
|
}
|
|
5344
5602
|
function generateSupervisorId() {
|
|
5345
5603
|
return `sup_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -5369,7 +5627,7 @@ var NOOP_LOGGER3, SupervisorManager;
|
|
|
5369
5627
|
var init_manager2 = __esm({
|
|
5370
5628
|
"packages/server/src/supervisor/manager.ts"() {
|
|
5371
5629
|
"use strict";
|
|
5372
|
-
|
|
5630
|
+
init_src3();
|
|
5373
5631
|
init_context_builder();
|
|
5374
5632
|
init_evaluator();
|
|
5375
5633
|
init_injector();
|
|
@@ -6278,8 +6536,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
6278
6536
|
if (this.pendingWriteCount === 0) {
|
|
6279
6537
|
return Promise.resolve();
|
|
6280
6538
|
}
|
|
6281
|
-
return new Promise((
|
|
6282
|
-
this.drainResolvers.push(
|
|
6539
|
+
return new Promise((resolve4) => {
|
|
6540
|
+
this.drainResolvers.push(resolve4);
|
|
6283
6541
|
});
|
|
6284
6542
|
}
|
|
6285
6543
|
resolveDrainIfIdle() {
|
|
@@ -6288,8 +6546,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
6288
6546
|
}
|
|
6289
6547
|
const resolvers = this.drainResolvers;
|
|
6290
6548
|
this.drainResolvers = [];
|
|
6291
|
-
for (const
|
|
6292
|
-
|
|
6549
|
+
for (const resolve4 of resolvers) {
|
|
6550
|
+
resolve4();
|
|
6293
6551
|
}
|
|
6294
6552
|
}
|
|
6295
6553
|
requireTerminal() {
|
|
@@ -6608,10 +6866,10 @@ var init_manager3 = __esm({
|
|
|
6608
6866
|
}
|
|
6609
6867
|
return existing.promise;
|
|
6610
6868
|
}
|
|
6611
|
-
let
|
|
6869
|
+
let resolve4 = () => {
|
|
6612
6870
|
};
|
|
6613
6871
|
const promise = new Promise((innerResolve) => {
|
|
6614
|
-
|
|
6872
|
+
resolve4 = innerResolve;
|
|
6615
6873
|
});
|
|
6616
6874
|
let markKillCompleted = () => {
|
|
6617
6875
|
};
|
|
@@ -6624,7 +6882,7 @@ var init_manager3 = __esm({
|
|
|
6624
6882
|
markKillCompleted,
|
|
6625
6883
|
finalized: false,
|
|
6626
6884
|
promise,
|
|
6627
|
-
resolve:
|
|
6885
|
+
resolve: resolve4
|
|
6628
6886
|
});
|
|
6629
6887
|
void terminal.pty.kill(signal).finally(() => {
|
|
6630
6888
|
const waiter = this.explicitCloseWaiters.get(terminalId);
|
|
@@ -6753,14 +7011,14 @@ var init_manager3 = __esm({
|
|
|
6753
7011
|
// packages/server/src/workspace/validator.ts
|
|
6754
7012
|
import { constants } from "fs";
|
|
6755
7013
|
import { access, stat as stat5 } from "fs/promises";
|
|
6756
|
-
async function validatePath(
|
|
7014
|
+
async function validatePath(path9) {
|
|
6757
7015
|
try {
|
|
6758
|
-
const stats = await stat5(
|
|
7016
|
+
const stats = await stat5(path9);
|
|
6759
7017
|
if (!stats.isDirectory()) {
|
|
6760
7018
|
return { valid: false, error: "Path is not a directory" };
|
|
6761
7019
|
}
|
|
6762
|
-
await access(
|
|
6763
|
-
await access(
|
|
7020
|
+
await access(path9, constants.R_OK);
|
|
7021
|
+
await access(path9, constants.W_OK);
|
|
6764
7022
|
return { valid: true };
|
|
6765
7023
|
} catch (error) {
|
|
6766
7024
|
if (error.code === "ENOENT") {
|
|
@@ -6777,8 +7035,8 @@ var init_validator = __esm({
|
|
|
6777
7035
|
"packages/server/src/workspace/validator.ts"() {
|
|
6778
7036
|
"use strict";
|
|
6779
7037
|
WorkspaceValidator = class {
|
|
6780
|
-
async validate(
|
|
6781
|
-
const result = await validatePath(
|
|
7038
|
+
async validate(path9) {
|
|
7039
|
+
const result = await validatePath(path9);
|
|
6782
7040
|
if (!result.valid) {
|
|
6783
7041
|
throw new Error(`Invalid workspace path: ${result.error}`);
|
|
6784
7042
|
}
|
|
@@ -6788,14 +7046,14 @@ var init_validator = __esm({
|
|
|
6788
7046
|
});
|
|
6789
7047
|
|
|
6790
7048
|
// packages/server/src/fs/gitignore.ts
|
|
6791
|
-
import { existsSync as
|
|
7049
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
6792
7050
|
import ignore from "ignore";
|
|
6793
7051
|
import { join as join5, relative } from "path";
|
|
6794
|
-
function normalizePath(
|
|
6795
|
-
return
|
|
7052
|
+
function normalizePath(path9) {
|
|
7053
|
+
return path9.replace(/\\/g, "/");
|
|
6796
7054
|
}
|
|
6797
|
-
function relativeToRoot(rootPath,
|
|
6798
|
-
return normalizePath(relative(rootPath,
|
|
7055
|
+
function relativeToRoot(rootPath, path9) {
|
|
7056
|
+
return normalizePath(relative(rootPath, path9));
|
|
6799
7057
|
}
|
|
6800
7058
|
function isDefaultTreeIgnored(name) {
|
|
6801
7059
|
return name.startsWith(".") || name === "node_modules" || name === ".git";
|
|
@@ -6803,18 +7061,18 @@ function isDefaultTreeIgnored(name) {
|
|
|
6803
7061
|
function isAlwaysTreeIgnored(name) {
|
|
6804
7062
|
return name === "node_modules" || name === ".git";
|
|
6805
7063
|
}
|
|
6806
|
-
function isIgnoredByGitignore(ig,
|
|
6807
|
-
if (!
|
|
7064
|
+
function isIgnoredByGitignore(ig, path9) {
|
|
7065
|
+
if (!path9 || path9.startsWith("..")) {
|
|
6808
7066
|
return false;
|
|
6809
7067
|
}
|
|
6810
|
-
return ig.ignores(
|
|
7068
|
+
return ig.ignores(path9) || ig.ignores(`${path9}/`);
|
|
6811
7069
|
}
|
|
6812
7070
|
function createGitignoreFilter(rootPath, dirPath) {
|
|
6813
7071
|
const gitignorePath = join5(rootPath, ".gitignore");
|
|
6814
|
-
if (!
|
|
7072
|
+
if (!existsSync8(gitignorePath)) {
|
|
6815
7073
|
return (name) => !isDefaultTreeIgnored(name);
|
|
6816
7074
|
}
|
|
6817
|
-
const gitignoreContent =
|
|
7075
|
+
const gitignoreContent = readFileSync7(gitignorePath, "utf-8");
|
|
6818
7076
|
const ig = ignore().add(gitignoreContent);
|
|
6819
7077
|
return (name) => {
|
|
6820
7078
|
if (isAlwaysTreeIgnored(name)) {
|
|
@@ -6826,17 +7084,17 @@ function createGitignoreFilter(rootPath, dirPath) {
|
|
|
6826
7084
|
}
|
|
6827
7085
|
function createWatcherIgnoreFilter(rootPath) {
|
|
6828
7086
|
const gitignorePath = join5(rootPath, ".gitignore");
|
|
6829
|
-
if (!
|
|
6830
|
-
return (
|
|
7087
|
+
if (!existsSync8(gitignorePath)) {
|
|
7088
|
+
return (path9) => DEFAULT_WATCHER_IGNORED_PATTERNS.some((p) => p.test(normalizePath(path9)));
|
|
6831
7089
|
}
|
|
6832
|
-
const gitignoreContent =
|
|
7090
|
+
const gitignoreContent = readFileSync7(gitignorePath, "utf-8");
|
|
6833
7091
|
const ig = ignore().add(gitignoreContent);
|
|
6834
|
-
return (
|
|
6835
|
-
const normalizedPath = normalizePath(
|
|
7092
|
+
return (path9) => {
|
|
7093
|
+
const normalizedPath = normalizePath(path9);
|
|
6836
7094
|
if (DEFAULT_WATCHER_IGNORED_PATTERNS.some((p) => p.test(normalizedPath))) {
|
|
6837
7095
|
return true;
|
|
6838
7096
|
}
|
|
6839
|
-
const relativePath = relativeToRoot(rootPath,
|
|
7097
|
+
const relativePath = relativeToRoot(rootPath, path9);
|
|
6840
7098
|
return isIgnoredByGitignore(ig, relativePath);
|
|
6841
7099
|
};
|
|
6842
7100
|
}
|
|
@@ -6859,7 +7117,7 @@ var WorkspaceWatcher;
|
|
|
6859
7117
|
var init_watcher = __esm({
|
|
6860
7118
|
"packages/server/src/fs/watcher.ts"() {
|
|
6861
7119
|
"use strict";
|
|
6862
|
-
|
|
7120
|
+
init_src3();
|
|
6863
7121
|
init_gitignore();
|
|
6864
7122
|
WorkspaceWatcher = class {
|
|
6865
7123
|
constructor(workspaceId, rootPath, broadcaster) {
|
|
@@ -7111,12 +7369,12 @@ var init_manager4 = __esm({
|
|
|
7111
7369
|
* @param path - Workspace path
|
|
7112
7370
|
* @returns Workspace or undefined
|
|
7113
7371
|
*/
|
|
7114
|
-
getByPath(
|
|
7372
|
+
getByPath(path9) {
|
|
7115
7373
|
const row = this.deps.db.prepare(
|
|
7116
7374
|
`SELECT id, path, target_runtime, wsl_distro, opened_at, last_active_at, ui_state
|
|
7117
7375
|
FROM workspaces
|
|
7118
7376
|
WHERE path = ?`
|
|
7119
|
-
).get(
|
|
7377
|
+
).get(path9);
|
|
7120
7378
|
if (!row) return void 0;
|
|
7121
7379
|
return {
|
|
7122
7380
|
id: row.id,
|
|
@@ -7320,16 +7578,16 @@ async function debounce(key, op, windowMs) {
|
|
|
7320
7578
|
clearTimeout(entry.timer);
|
|
7321
7579
|
entry.op = op;
|
|
7322
7580
|
} else {
|
|
7323
|
-
let
|
|
7581
|
+
let resolve4;
|
|
7324
7582
|
let reject;
|
|
7325
7583
|
const promise = new Promise((res, rej) => {
|
|
7326
|
-
|
|
7584
|
+
resolve4 = res;
|
|
7327
7585
|
reject = rej;
|
|
7328
7586
|
});
|
|
7329
7587
|
entry = {
|
|
7330
7588
|
timer: void 0,
|
|
7331
7589
|
promise,
|
|
7332
|
-
resolve:
|
|
7590
|
+
resolve: resolve4,
|
|
7333
7591
|
reject,
|
|
7334
7592
|
op
|
|
7335
7593
|
};
|
|
@@ -7505,7 +7763,7 @@ var TerminalInputActivitySchema, TerminalInputSchema, pendingTerminalInput, next
|
|
|
7505
7763
|
var init_terminal = __esm({
|
|
7506
7764
|
"packages/server/src/commands/terminal.ts"() {
|
|
7507
7765
|
"use strict";
|
|
7508
|
-
|
|
7766
|
+
init_src3();
|
|
7509
7767
|
init_dispatch();
|
|
7510
7768
|
TerminalInputActivitySchema = z5.enum(TERMINAL_INPUT_ACTIVITIES).optional();
|
|
7511
7769
|
TerminalInputSchema = z5.union([
|
|
@@ -8113,7 +8371,7 @@ var BINARY_PAYLOAD_TIMEOUT_MS, isBinaryTerminalInputArgs, WsHub;
|
|
|
8113
8371
|
var init_hub = __esm({
|
|
8114
8372
|
"packages/server/src/ws/hub.ts"() {
|
|
8115
8373
|
"use strict";
|
|
8116
|
-
|
|
8374
|
+
init_src3();
|
|
8117
8375
|
init_terminal();
|
|
8118
8376
|
init_client();
|
|
8119
8377
|
init_dispatch();
|
|
@@ -8152,7 +8410,10 @@ var init_hub = __esm({
|
|
|
8152
8410
|
status: "connected",
|
|
8153
8411
|
clientId: client.id,
|
|
8154
8412
|
authEnabled: this.deps.config.auth.enabled,
|
|
8155
|
-
binaryTerminalTransport: true
|
|
8413
|
+
binaryTerminalTransport: true,
|
|
8414
|
+
version: this.deps.config.appVersion ?? "0.0.0",
|
|
8415
|
+
serverInstanceId: `server-${process.pid}`,
|
|
8416
|
+
isWriter: false
|
|
8156
8417
|
});
|
|
8157
8418
|
client.onMessage((msg) => this.routeMessage(client, msg));
|
|
8158
8419
|
client.onClose(() => this.handleClose(client));
|
|
@@ -8206,7 +8467,7 @@ var init_hub = __esm({
|
|
|
8206
8467
|
}
|
|
8207
8468
|
}
|
|
8208
8469
|
awaitBinaryPayload(clientId) {
|
|
8209
|
-
return new Promise((
|
|
8470
|
+
return new Promise((resolve4, reject) => {
|
|
8210
8471
|
const timer = setTimeout(() => {
|
|
8211
8472
|
const waiters = this.pendingBinaryWaiters.get(clientId);
|
|
8212
8473
|
if (!waiters) return;
|
|
@@ -8218,7 +8479,7 @@ var init_hub = __esm({
|
|
|
8218
8479
|
}
|
|
8219
8480
|
reject(new Error("Timeout waiting for terminal input binary payload"));
|
|
8220
8481
|
}, BINARY_PAYLOAD_TIMEOUT_MS);
|
|
8221
|
-
const waiter = { resolve:
|
|
8482
|
+
const waiter = { resolve: resolve4, reject, timer };
|
|
8222
8483
|
const queue = this.pendingBinaryWaiters.get(clientId);
|
|
8223
8484
|
if (queue) {
|
|
8224
8485
|
queue.push(waiter);
|
|
@@ -9025,7 +9286,7 @@ var init_file = __esm({
|
|
|
9025
9286
|
// packages/server/src/git/diff.ts
|
|
9026
9287
|
import { mkdtemp as mkdtemp2, rm as rm5 } from "fs/promises";
|
|
9027
9288
|
import os3 from "os";
|
|
9028
|
-
import
|
|
9289
|
+
import path7 from "path";
|
|
9029
9290
|
async function isTrackedPath(cwd, filePath) {
|
|
9030
9291
|
try {
|
|
9031
9292
|
await runGit(cwd, ["ls-files", "--error-unmatch", "--", filePath]);
|
|
@@ -9035,8 +9296,8 @@ async function isTrackedPath(cwd, filePath) {
|
|
|
9035
9296
|
}
|
|
9036
9297
|
}
|
|
9037
9298
|
async function getUntrackedFileDiff(cwd, filePath) {
|
|
9038
|
-
const tempDir = await mkdtemp2(
|
|
9039
|
-
const tempIndex =
|
|
9299
|
+
const tempDir = await mkdtemp2(path7.join(os3.tmpdir(), "coder-studio-git-diff-"));
|
|
9300
|
+
const tempIndex = path7.join(tempDir, "index");
|
|
9040
9301
|
try {
|
|
9041
9302
|
try {
|
|
9042
9303
|
await runGit(cwd, ["read-tree", "HEAD"], {
|
|
@@ -9061,11 +9322,11 @@ async function getUntrackedFileDiff(cwd, filePath) {
|
|
|
9061
9322
|
await rm5(tempDir, { recursive: true, force: true });
|
|
9062
9323
|
}
|
|
9063
9324
|
}
|
|
9064
|
-
async function getFileDiff(cwd,
|
|
9065
|
-
if (!staged && !await isTrackedPath(cwd,
|
|
9066
|
-
return getUntrackedFileDiff(cwd,
|
|
9325
|
+
async function getFileDiff(cwd, path9, staged = false) {
|
|
9326
|
+
if (!staged && !await isTrackedPath(cwd, path9)) {
|
|
9327
|
+
return getUntrackedFileDiff(cwd, path9);
|
|
9067
9328
|
}
|
|
9068
|
-
const args = staged ? ["diff", "--staged", "--",
|
|
9329
|
+
const args = staged ? ["diff", "--staged", "--", path9] : ["diff", "--", path9];
|
|
9069
9330
|
const result = await runGit(cwd, args);
|
|
9070
9331
|
return result.stdout;
|
|
9071
9332
|
}
|
|
@@ -9314,7 +9575,7 @@ var init_git2 = __esm({
|
|
|
9314
9575
|
});
|
|
9315
9576
|
|
|
9316
9577
|
// packages/server/src/config/config-io.ts
|
|
9317
|
-
import { existsSync as
|
|
9578
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
9318
9579
|
import { homedir as homedir5 } from "node:os";
|
|
9319
9580
|
import { basename as basename3, dirname as dirname5, join as join8 } from "node:path";
|
|
9320
9581
|
function resolveConfigPath(configType) {
|
|
@@ -9336,11 +9597,11 @@ function resolveConfigPath(configType) {
|
|
|
9336
9597
|
}
|
|
9337
9598
|
function readConfigFile(configType) {
|
|
9338
9599
|
const configPath = resolveConfigPath(configType);
|
|
9339
|
-
if (!
|
|
9600
|
+
if (!existsSync9(configPath)) {
|
|
9340
9601
|
return { configPath, content: "", exists: false };
|
|
9341
9602
|
}
|
|
9342
9603
|
try {
|
|
9343
|
-
const content =
|
|
9604
|
+
const content = readFileSync8(configPath, "utf-8");
|
|
9344
9605
|
return { configPath, content, exists: true };
|
|
9345
9606
|
} catch {
|
|
9346
9607
|
return { configPath, content: "", exists: false };
|
|
@@ -9350,11 +9611,11 @@ function writeConfigFile(configType, content) {
|
|
|
9350
9611
|
try {
|
|
9351
9612
|
const configPath = resolveConfigPath(configType);
|
|
9352
9613
|
const parentDir = dirname5(configPath);
|
|
9353
|
-
if (!
|
|
9614
|
+
if (!existsSync9(parentDir)) {
|
|
9354
9615
|
mkdirSync4(parentDir, { recursive: true });
|
|
9355
9616
|
}
|
|
9356
9617
|
let backupPath = null;
|
|
9357
|
-
if (
|
|
9618
|
+
if (existsSync9(configPath)) {
|
|
9358
9619
|
backupPath = createBackup(configPath);
|
|
9359
9620
|
}
|
|
9360
9621
|
const tempPath = `${configPath}.tmp`;
|
|
@@ -9370,7 +9631,7 @@ function writeConfigFile(configType, content) {
|
|
|
9370
9631
|
}
|
|
9371
9632
|
}
|
|
9372
9633
|
function createBackup(filePath) {
|
|
9373
|
-
const original =
|
|
9634
|
+
const original = readFileSync8(filePath, "utf-8");
|
|
9374
9635
|
const ext = filePath.split(".").pop() ?? "";
|
|
9375
9636
|
const base = basename3(filePath, `.${ext}`);
|
|
9376
9637
|
const dir = dirname5(filePath);
|
|
@@ -9408,7 +9669,7 @@ var EMPTY_CODEX_AUDIT, SettingsSchema;
|
|
|
9408
9669
|
var init_settings2 = __esm({
|
|
9409
9670
|
"packages/server/src/commands/settings.ts"() {
|
|
9410
9671
|
"use strict";
|
|
9411
|
-
|
|
9672
|
+
init_src3();
|
|
9412
9673
|
init_config_io();
|
|
9413
9674
|
init_provider_config();
|
|
9414
9675
|
init_provider_config_repo();
|
|
@@ -9688,9 +9949,9 @@ var init_supervisor2 = __esm({
|
|
|
9688
9949
|
});
|
|
9689
9950
|
|
|
9690
9951
|
// packages/server/src/git/worktree.ts
|
|
9691
|
-
import
|
|
9952
|
+
import path8 from "node:path";
|
|
9692
9953
|
function normalizeWorktreePath(worktreePath) {
|
|
9693
|
-
return
|
|
9954
|
+
return path8.resolve(worktreePath);
|
|
9694
9955
|
}
|
|
9695
9956
|
async function resolveWorktreePath(repoPath, worktreePath) {
|
|
9696
9957
|
const normalizedRequested = normalizeWorktreePath(worktreePath);
|
|
@@ -9777,19 +10038,19 @@ async function getWorktreeTree(worktreePath) {
|
|
|
9777
10038
|
for (const line of lines) {
|
|
9778
10039
|
const isDir = line.endsWith("/");
|
|
9779
10040
|
const name = isDir ? line.slice(0, -1) : line;
|
|
9780
|
-
const
|
|
10041
|
+
const path9 = `${worktreePath}/${name}`;
|
|
9781
10042
|
nodes.push({
|
|
9782
10043
|
name,
|
|
9783
|
-
path:
|
|
10044
|
+
path: path9,
|
|
9784
10045
|
kind: isDir ? "dir" : "file"
|
|
9785
10046
|
});
|
|
9786
10047
|
}
|
|
9787
10048
|
return nodes;
|
|
9788
10049
|
}
|
|
9789
|
-
async function createWorktree(repoPath, branch,
|
|
9790
|
-
await runGit(repoPath, ["worktree", "add",
|
|
10050
|
+
async function createWorktree(repoPath, branch, path9) {
|
|
10051
|
+
await runGit(repoPath, ["worktree", "add", path9, branch]);
|
|
9791
10052
|
const worktrees = await listWorktrees(repoPath);
|
|
9792
|
-
const created = worktrees.find((wt) => wt.path ===
|
|
10053
|
+
const created = worktrees.find((wt) => wt.path === path9);
|
|
9793
10054
|
if (!created) {
|
|
9794
10055
|
throw new Error("Failed to find created worktree");
|
|
9795
10056
|
}
|
|
@@ -9987,8 +10248,6 @@ var init_commands = __esm({
|
|
|
9987
10248
|
});
|
|
9988
10249
|
|
|
9989
10250
|
// packages/server/src/server.ts
|
|
9990
|
-
import { execFile as nodeExecFile3 } from "node:child_process";
|
|
9991
|
-
import { promisify as promisify3 } from "node:util";
|
|
9992
10251
|
function createCodexConfigAuditApi() {
|
|
9993
10252
|
return {
|
|
9994
10253
|
audit: () => ({ codex: auditCodexConfigToml() }),
|
|
@@ -10016,7 +10275,6 @@ async function logCodexConfigFindings(auditApi, logger) {
|
|
|
10016
10275
|
}
|
|
10017
10276
|
}
|
|
10018
10277
|
async function createServer(configOverrides) {
|
|
10019
|
-
const execFileAsync3 = promisify3(nodeExecFile3);
|
|
10020
10278
|
const config = parseServerConfig(configOverrides);
|
|
10021
10279
|
ensureDataDir(config);
|
|
10022
10280
|
const db = openDatabase(config.dataDir);
|
|
@@ -10098,7 +10356,7 @@ async function createServer(configOverrides) {
|
|
|
10098
10356
|
const providerRuntimeDeps = {};
|
|
10099
10357
|
const providerInstallMgr = new ProviderInstallManager(providerRegistry, {
|
|
10100
10358
|
...providerRuntimeDeps,
|
|
10101
|
-
|
|
10359
|
+
runCommand: runCommandAsString
|
|
10102
10360
|
});
|
|
10103
10361
|
const commandContext = {
|
|
10104
10362
|
workspaceMgr,
|
|
@@ -10261,10 +10519,12 @@ var init_server = __esm({
|
|
|
10261
10519
|
"use strict";
|
|
10262
10520
|
init_runtime();
|
|
10263
10521
|
init_src();
|
|
10522
|
+
init_src2();
|
|
10264
10523
|
init_app();
|
|
10265
10524
|
init_event_bus();
|
|
10266
10525
|
init_codex_config_audit();
|
|
10267
10526
|
init_config();
|
|
10527
|
+
init_command_runner();
|
|
10268
10528
|
init_install_manager();
|
|
10269
10529
|
init_manager();
|
|
10270
10530
|
init_db();
|
|
@@ -10284,7 +10544,7 @@ var init_server = __esm({
|
|
|
10284
10544
|
init_fencing();
|
|
10285
10545
|
init_hub();
|
|
10286
10546
|
init_commands();
|
|
10287
|
-
if (import.meta.url
|
|
10547
|
+
if (isDirectExecution(import.meta.url)) {
|
|
10288
10548
|
const server = await createServer();
|
|
10289
10549
|
process.on("SIGINT", async () => {
|
|
10290
10550
|
console.log("\nShutting down...");
|
|
@@ -10434,8 +10694,8 @@ var init_workspace_repo = __esm({
|
|
|
10434
10694
|
/**
|
|
10435
10695
|
* Finds a workspace by path
|
|
10436
10696
|
*/
|
|
10437
|
-
findByPath(
|
|
10438
|
-
const row = this.db.prepare("SELECT * FROM workspaces WHERE path = ?").get(
|
|
10697
|
+
findByPath(path9) {
|
|
10698
|
+
const row = this.db.prepare("SELECT * FROM workspaces WHERE path = ?").get(path9);
|
|
10439
10699
|
return row ? this.rowToWorkspace(row) : void 0;
|
|
10440
10700
|
}
|
|
10441
10701
|
/**
|
|
@@ -10556,7 +10816,7 @@ __export(src_exports, {
|
|
|
10556
10816
|
sessionToRow: () => sessionToRow,
|
|
10557
10817
|
withTransaction: () => withTransaction
|
|
10558
10818
|
});
|
|
10559
|
-
var
|
|
10819
|
+
var init_src4 = __esm({
|
|
10560
10820
|
async "packages/server/src/index.ts"() {
|
|
10561
10821
|
"use strict";
|
|
10562
10822
|
init_auth();
|
|
@@ -10580,12 +10840,12 @@ function getCliConfigPath() {
|
|
|
10580
10840
|
return join(homedir(), ".coder-studio", "config.json");
|
|
10581
10841
|
}
|
|
10582
10842
|
function readCliConfig() {
|
|
10583
|
-
const
|
|
10584
|
-
if (!existsSync(
|
|
10843
|
+
const path9 = getCliConfigPath();
|
|
10844
|
+
if (!existsSync(path9)) {
|
|
10585
10845
|
return null;
|
|
10586
10846
|
}
|
|
10587
10847
|
try {
|
|
10588
|
-
const parsed = JSON.parse(readFileSync(
|
|
10848
|
+
const parsed = JSON.parse(readFileSync(path9, "utf-8"));
|
|
10589
10849
|
if (parsed.host !== void 0 && typeof parsed.host !== "string" || parsed.port !== void 0 && typeof parsed.port !== "number" || parsed.dataDir !== void 0 && typeof parsed.dataDir !== "string" || parsed.password !== void 0 && typeof parsed.password !== "string") {
|
|
10590
10850
|
return null;
|
|
10591
10851
|
}
|
|
@@ -10639,11 +10899,33 @@ function assertSupportedNodeVersion(version = process.versions.node) {
|
|
|
10639
10899
|
);
|
|
10640
10900
|
}
|
|
10641
10901
|
|
|
10902
|
+
// packages/cli/src/package-manifest.ts
|
|
10903
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
10904
|
+
function resolveCliPackageManifestUrl(importMetaUrl) {
|
|
10905
|
+
const manifestUrl = [
|
|
10906
|
+
new URL("../package.json", importMetaUrl),
|
|
10907
|
+
new URL("../../package.json", importMetaUrl)
|
|
10908
|
+
].find((candidate) => existsSync3(candidate));
|
|
10909
|
+
if (!manifestUrl) {
|
|
10910
|
+
throw new Error("Unable to locate CLI package.json");
|
|
10911
|
+
}
|
|
10912
|
+
return manifestUrl;
|
|
10913
|
+
}
|
|
10914
|
+
function getCliPackageManifest(importMetaUrl) {
|
|
10915
|
+
return JSON.parse(
|
|
10916
|
+
readFileSync2(resolveCliPackageManifestUrl(importMetaUrl), "utf-8")
|
|
10917
|
+
);
|
|
10918
|
+
}
|
|
10919
|
+
function getCliVersion(importMetaUrl) {
|
|
10920
|
+
return getCliPackageManifest(importMetaUrl).version ?? "0.0.0";
|
|
10921
|
+
}
|
|
10922
|
+
|
|
10642
10923
|
// packages/cli/src/server-runner.ts
|
|
10643
10924
|
var MISSING_WEB_ASSETS_WARNING = "Warning: Web assets not found. Frontend will not be available.";
|
|
10644
10925
|
var buildServerConfig = () => {
|
|
10645
10926
|
const savedConfig = readCliConfig();
|
|
10646
10927
|
const config = {
|
|
10928
|
+
appVersion: getCliVersion(import.meta.url),
|
|
10647
10929
|
...savedConfig?.host !== void 0 ? { host: savedConfig.host } : {},
|
|
10648
10930
|
...savedConfig?.port !== void 0 && savedConfig.port > 0 ? { port: savedConfig.port } : {},
|
|
10649
10931
|
...savedConfig?.dataDir !== void 0 ? { dataDir: savedConfig.dataDir } : {},
|
|
@@ -10686,7 +10968,7 @@ var runServerEntrypoint = async (moduleUrl, argvEntry) => {
|
|
|
10686
10968
|
};
|
|
10687
10969
|
var startServer = async () => {
|
|
10688
10970
|
assertSupportedNodeVersion();
|
|
10689
|
-
const { createServer: createServer2 } = await
|
|
10971
|
+
const { createServer: createServer2 } = await init_src4().then(() => src_exports);
|
|
10690
10972
|
const server = await createServer2(buildServerConfig());
|
|
10691
10973
|
const shutdown = createShutdownHandler(server);
|
|
10692
10974
|
process.on("SIGINT", shutdown);
|