@prover-coder-ai/docker-git 1.0.36 → 1.0.37
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/docker-git/main.js +254 -220
- package/dist/src/docker-git/main.js.map +1 -1
- package/package.json +1 -1
|
@@ -345,6 +345,228 @@ const runCommandCapture = (spec, okExitCodes, onFailure) => Effect.scoped(
|
|
|
345
345
|
return new TextDecoder("utf-8").decode(bytes);
|
|
346
346
|
})
|
|
347
347
|
);
|
|
348
|
+
const resolveDockerEnvValue = (key) => {
|
|
349
|
+
const value = process.env[key]?.trim();
|
|
350
|
+
return value && value.length > 0 ? value : null;
|
|
351
|
+
};
|
|
352
|
+
const trimDockerPathTrailingSlash = (value) => {
|
|
353
|
+
let end = value.length;
|
|
354
|
+
while (end > 0) {
|
|
355
|
+
const char = value[end - 1];
|
|
356
|
+
if (char !== "/" && char !== "\\") {
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
end -= 1;
|
|
360
|
+
}
|
|
361
|
+
return value.slice(0, end);
|
|
362
|
+
};
|
|
363
|
+
const pathStartsWith = (candidate, prefix) => candidate === prefix || candidate.startsWith(`${prefix}/`) || candidate.startsWith(`${prefix}\\`);
|
|
364
|
+
const translatePathPrefix = (candidate, sourcePrefix, targetPrefix) => pathStartsWith(candidate, sourcePrefix) ? `${targetPrefix}${candidate.slice(sourcePrefix.length)}` : null;
|
|
365
|
+
const resolveContainerProjectsRoot = () => {
|
|
366
|
+
const explicit = resolveDockerEnvValue("DOCKER_GIT_PROJECTS_ROOT");
|
|
367
|
+
if (explicit !== null) {
|
|
368
|
+
return explicit;
|
|
369
|
+
}
|
|
370
|
+
const home = resolveDockerEnvValue("HOME") ?? resolveDockerEnvValue("USERPROFILE");
|
|
371
|
+
return home === null ? null : `${trimDockerPathTrailingSlash(home)}/.docker-git`;
|
|
372
|
+
};
|
|
373
|
+
const resolveProjectsRootHostOverride = () => resolveDockerEnvValue("DOCKER_GIT_PROJECTS_ROOT_HOST");
|
|
374
|
+
const resolveCurrentContainerId = (cwd) => {
|
|
375
|
+
const fromEnv = resolveDockerEnvValue("HOSTNAME");
|
|
376
|
+
if (fromEnv !== null) {
|
|
377
|
+
return Effect.succeed(fromEnv);
|
|
378
|
+
}
|
|
379
|
+
return runCommandCapture(
|
|
380
|
+
{
|
|
381
|
+
cwd,
|
|
382
|
+
command: "hostname",
|
|
383
|
+
args: []
|
|
384
|
+
},
|
|
385
|
+
[0],
|
|
386
|
+
() => new Error("hostname failed")
|
|
387
|
+
).pipe(
|
|
388
|
+
Effect.map((value) => value.trim()),
|
|
389
|
+
Effect.orElseSucceed(() => ""),
|
|
390
|
+
Effect.map((value) => value.length > 0 ? value : null)
|
|
391
|
+
);
|
|
392
|
+
};
|
|
393
|
+
const parseDockerInspectMounts = (raw) => raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).flatMap((line) => {
|
|
394
|
+
const separator = line.indexOf(" ");
|
|
395
|
+
if (separator <= 0 || separator >= line.length - 1) {
|
|
396
|
+
return [];
|
|
397
|
+
}
|
|
398
|
+
const source = line.slice(0, separator).trim();
|
|
399
|
+
const destination = line.slice(separator + 1).trim();
|
|
400
|
+
if (source.length === 0 || destination.length === 0) {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
return [{ source, destination }];
|
|
404
|
+
});
|
|
405
|
+
const remapDockerBindHostPathFromMounts = (hostPath, mounts) => {
|
|
406
|
+
let match = null;
|
|
407
|
+
for (const mount of mounts) {
|
|
408
|
+
if (!pathStartsWith(hostPath, mount.destination)) {
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (match === null || mount.destination.length > match.destination.length) {
|
|
412
|
+
match = mount;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (match === null) {
|
|
416
|
+
return hostPath;
|
|
417
|
+
}
|
|
418
|
+
return `${match.source}${hostPath.slice(match.destination.length)}`;
|
|
419
|
+
};
|
|
420
|
+
const resolveDockerVolumeHostPath = (cwd, hostPath) => Effect.gen(function* (_) {
|
|
421
|
+
const containerProjectsRoot = resolveContainerProjectsRoot();
|
|
422
|
+
const hostProjectsRoot = resolveProjectsRootHostOverride();
|
|
423
|
+
if (containerProjectsRoot !== null && hostProjectsRoot !== null) {
|
|
424
|
+
const remapped = translatePathPrefix(hostPath, containerProjectsRoot, hostProjectsRoot);
|
|
425
|
+
if (remapped !== null) {
|
|
426
|
+
return remapped;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const containerId = yield* _(resolveCurrentContainerId(cwd));
|
|
430
|
+
if (containerId === null) {
|
|
431
|
+
return hostPath;
|
|
432
|
+
}
|
|
433
|
+
const mountsJson = yield* _(
|
|
434
|
+
runCommandCapture(
|
|
435
|
+
{
|
|
436
|
+
cwd,
|
|
437
|
+
command: "docker",
|
|
438
|
+
args: [
|
|
439
|
+
"inspect",
|
|
440
|
+
containerId,
|
|
441
|
+
"--format",
|
|
442
|
+
String.raw`{{range .Mounts}}{{println .Source "\t" .Destination}}{{end}}`
|
|
443
|
+
]
|
|
444
|
+
},
|
|
445
|
+
[0],
|
|
446
|
+
() => new Error("docker inspect current container failed")
|
|
447
|
+
).pipe(Effect.orElseSucceed(() => ""))
|
|
448
|
+
);
|
|
449
|
+
return remapDockerBindHostPathFromMounts(hostPath, parseDockerInspectMounts(mountsJson));
|
|
450
|
+
});
|
|
451
|
+
const resolveDefaultDockerUser = () => {
|
|
452
|
+
const getUid = Reflect.get(process, "getuid");
|
|
453
|
+
const getGid = Reflect.get(process, "getgid");
|
|
454
|
+
if (typeof getUid !== "function" || typeof getGid !== "function") {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
const uid = getUid.call(process);
|
|
458
|
+
const gid = getGid.call(process);
|
|
459
|
+
if (typeof uid !== "number" || typeof gid !== "number") {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
return `${uid}:${gid}`;
|
|
463
|
+
};
|
|
464
|
+
const appendEnvArgs = (base, env) => {
|
|
465
|
+
if (typeof env === "string") {
|
|
466
|
+
const trimmed = env.trim();
|
|
467
|
+
if (trimmed.length > 0) {
|
|
468
|
+
base.push("-e", trimmed);
|
|
469
|
+
}
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
for (const entry of env) {
|
|
473
|
+
const trimmed = entry.trim();
|
|
474
|
+
if (trimmed.length === 0) {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
base.push("-e", trimmed);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
const buildDockerArgs = (spec) => {
|
|
481
|
+
const base = ["run", "--rm"];
|
|
482
|
+
const dockerUser = (spec.user ?? "").trim() || resolveDefaultDockerUser();
|
|
483
|
+
if (dockerUser !== null) {
|
|
484
|
+
base.push("--user", dockerUser);
|
|
485
|
+
}
|
|
486
|
+
if (spec.interactive) {
|
|
487
|
+
base.push("-it");
|
|
488
|
+
}
|
|
489
|
+
if (spec.entrypoint && spec.entrypoint.length > 0) {
|
|
490
|
+
base.push("--entrypoint", spec.entrypoint);
|
|
491
|
+
}
|
|
492
|
+
base.push("-v", `${spec.volume.hostPath}:${spec.volume.containerPath}`);
|
|
493
|
+
if (spec.env !== void 0) {
|
|
494
|
+
appendEnvArgs(base, spec.env);
|
|
495
|
+
}
|
|
496
|
+
return [...base, spec.image, ...spec.args];
|
|
497
|
+
};
|
|
498
|
+
const runDockerAuth = (spec, okExitCodes, onFailure) => Effect.gen(function* (_) {
|
|
499
|
+
const hostPath = yield* _(resolveDockerVolumeHostPath(spec.cwd, spec.volume.hostPath));
|
|
500
|
+
yield* _(
|
|
501
|
+
runCommandWithExitCodes(
|
|
502
|
+
{
|
|
503
|
+
cwd: spec.cwd,
|
|
504
|
+
command: "docker",
|
|
505
|
+
args: buildDockerArgs({ ...spec, volume: { ...spec.volume, hostPath } })
|
|
506
|
+
},
|
|
507
|
+
okExitCodes,
|
|
508
|
+
onFailure
|
|
509
|
+
)
|
|
510
|
+
);
|
|
511
|
+
});
|
|
512
|
+
const runDockerAuthCapture = (spec, okExitCodes, onFailure) => Effect.gen(function* (_) {
|
|
513
|
+
const hostPath = yield* _(resolveDockerVolumeHostPath(spec.cwd, spec.volume.hostPath));
|
|
514
|
+
return yield* _(
|
|
515
|
+
runCommandCapture(
|
|
516
|
+
{
|
|
517
|
+
cwd: spec.cwd,
|
|
518
|
+
command: "docker",
|
|
519
|
+
args: buildDockerArgs({ ...spec, volume: { ...spec.volume, hostPath } })
|
|
520
|
+
},
|
|
521
|
+
okExitCodes,
|
|
522
|
+
onFailure
|
|
523
|
+
)
|
|
524
|
+
);
|
|
525
|
+
});
|
|
526
|
+
const runDockerAuthExitCode = (spec) => Effect.gen(function* (_) {
|
|
527
|
+
const hostPath = yield* _(resolveDockerVolumeHostPath(spec.cwd, spec.volume.hostPath));
|
|
528
|
+
return yield* _(
|
|
529
|
+
runCommandExitCode({
|
|
530
|
+
cwd: spec.cwd,
|
|
531
|
+
command: "docker",
|
|
532
|
+
args: buildDockerArgs({ ...spec, volume: { ...spec.volume, hostPath } })
|
|
533
|
+
})
|
|
534
|
+
);
|
|
535
|
+
});
|
|
536
|
+
const composeSpec = (cwd, args) => ({
|
|
537
|
+
cwd,
|
|
538
|
+
command: "docker",
|
|
539
|
+
args: ["compose", "--ansi", "never", "--progress", "plain", ...args]
|
|
540
|
+
});
|
|
541
|
+
const resolveProjectsRootCandidate = () => {
|
|
542
|
+
const explicit = resolveDockerEnvValue("DOCKER_GIT_PROJECTS_ROOT");
|
|
543
|
+
if (explicit !== null) {
|
|
544
|
+
return explicit;
|
|
545
|
+
}
|
|
546
|
+
const home = resolveDockerEnvValue("HOME") ?? resolveDockerEnvValue("USERPROFILE");
|
|
547
|
+
return home === null ? null : `${trimDockerPathTrailingSlash(home)}/.docker-git`;
|
|
548
|
+
};
|
|
549
|
+
const resolveDockerComposeEnv = (cwd) => Effect.gen(function* (_) {
|
|
550
|
+
const projectsRoot = resolveProjectsRootCandidate();
|
|
551
|
+
if (projectsRoot === null) {
|
|
552
|
+
return {};
|
|
553
|
+
}
|
|
554
|
+
const remappedProjectsRoot = yield* _(resolveDockerVolumeHostPath(cwd, projectsRoot));
|
|
555
|
+
return remappedProjectsRoot === projectsRoot ? {} : { DOCKER_GIT_PROJECTS_ROOT_HOST: remappedProjectsRoot };
|
|
556
|
+
});
|
|
557
|
+
const parseInspectNetworkEntry = (line) => {
|
|
558
|
+
const idx = line.indexOf("=");
|
|
559
|
+
if (idx <= 0) {
|
|
560
|
+
return [];
|
|
561
|
+
}
|
|
562
|
+
const network = line.slice(0, idx).trim();
|
|
563
|
+
const ip = line.slice(idx + 1).trim();
|
|
564
|
+
if (network.length === 0 || ip.length === 0) {
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
const entry = [network, ip];
|
|
568
|
+
return [entry];
|
|
569
|
+
};
|
|
348
570
|
class FileExistsError extends Data.TaggedError("FileExistsError") {
|
|
349
571
|
}
|
|
350
572
|
class ConfigNotFoundError extends Data.TaggedError("ConfigNotFoundError") {
|
|
@@ -513,34 +735,32 @@ const runDockerPsPublishedHostPorts = (cwd) => pipe(
|
|
|
513
735
|
),
|
|
514
736
|
Effect.map((output) => parseDockerPublishedHostPorts(output))
|
|
515
737
|
);
|
|
516
|
-
const
|
|
517
|
-
cwd
|
|
518
|
-
|
|
519
|
-
|
|
738
|
+
const runCompose = (cwd, args, okExitCodes) => Effect.gen(function* (_) {
|
|
739
|
+
const env = yield* _(resolveDockerComposeEnv(cwd));
|
|
740
|
+
yield* _(
|
|
741
|
+
runCommandWithExitCodes(
|
|
742
|
+
{
|
|
743
|
+
...composeSpec(cwd, args),
|
|
744
|
+
...Object.keys(env).length > 0 ? { env } : {}
|
|
745
|
+
},
|
|
746
|
+
okExitCodes,
|
|
747
|
+
(exitCode) => new DockerCommandError({ exitCode })
|
|
748
|
+
)
|
|
749
|
+
);
|
|
750
|
+
});
|
|
751
|
+
const runComposeCapture = (cwd, args, okExitCodes) => Effect.gen(function* (_) {
|
|
752
|
+
const env = yield* _(resolveDockerComposeEnv(cwd));
|
|
753
|
+
return yield* _(
|
|
754
|
+
runCommandCapture(
|
|
755
|
+
{
|
|
756
|
+
...composeSpec(cwd, args),
|
|
757
|
+
...Object.keys(env).length > 0 ? { env } : {}
|
|
758
|
+
},
|
|
759
|
+
okExitCodes,
|
|
760
|
+
(exitCode) => new DockerCommandError({ exitCode })
|
|
761
|
+
)
|
|
762
|
+
);
|
|
520
763
|
});
|
|
521
|
-
const parseInspectNetworkEntry = (line) => {
|
|
522
|
-
const idx = line.indexOf("=");
|
|
523
|
-
if (idx <= 0) {
|
|
524
|
-
return [];
|
|
525
|
-
}
|
|
526
|
-
const network = line.slice(0, idx).trim();
|
|
527
|
-
const ip = line.slice(idx + 1).trim();
|
|
528
|
-
if (network.length === 0 || ip.length === 0) {
|
|
529
|
-
return [];
|
|
530
|
-
}
|
|
531
|
-
const entry = [network, ip];
|
|
532
|
-
return [entry];
|
|
533
|
-
};
|
|
534
|
-
const runCompose = (cwd, args, okExitCodes) => runCommandWithExitCodes(
|
|
535
|
-
composeSpec(cwd, args),
|
|
536
|
-
okExitCodes,
|
|
537
|
-
(exitCode) => new DockerCommandError({ exitCode })
|
|
538
|
-
);
|
|
539
|
-
const runComposeCapture = (cwd, args, okExitCodes) => runCommandCapture(
|
|
540
|
-
composeSpec(cwd, args),
|
|
541
|
-
okExitCodes,
|
|
542
|
-
(exitCode) => new DockerCommandError({ exitCode })
|
|
543
|
-
);
|
|
544
764
|
const dockerComposeUpRetrySchedule = Schedule.addDelay(
|
|
545
765
|
Schedule.recurs(2),
|
|
546
766
|
() => Duration.seconds(2)
|
|
@@ -851,194 +1071,6 @@ const renderError = (error) => {
|
|
|
851
1071
|
}
|
|
852
1072
|
return renderNonParseError(error);
|
|
853
1073
|
};
|
|
854
|
-
const resolveEnvValue = (key) => {
|
|
855
|
-
const value = process.env[key]?.trim();
|
|
856
|
-
return value && value.length > 0 ? value : null;
|
|
857
|
-
};
|
|
858
|
-
const trimTrailingSlash$1 = (value) => {
|
|
859
|
-
let end = value.length;
|
|
860
|
-
while (end > 0) {
|
|
861
|
-
const char = value[end - 1];
|
|
862
|
-
if (char !== "/" && char !== "\\") {
|
|
863
|
-
break;
|
|
864
|
-
}
|
|
865
|
-
end -= 1;
|
|
866
|
-
}
|
|
867
|
-
return value.slice(0, end);
|
|
868
|
-
};
|
|
869
|
-
const pathStartsWith = (candidate, prefix) => candidate === prefix || candidate.startsWith(`${prefix}/`) || candidate.startsWith(`${prefix}\\`);
|
|
870
|
-
const translatePathPrefix = (candidate, sourcePrefix, targetPrefix) => pathStartsWith(candidate, sourcePrefix) ? `${targetPrefix}${candidate.slice(sourcePrefix.length)}` : null;
|
|
871
|
-
const resolveContainerProjectsRoot = () => {
|
|
872
|
-
const explicit = resolveEnvValue("DOCKER_GIT_PROJECTS_ROOT");
|
|
873
|
-
if (explicit !== null) {
|
|
874
|
-
return explicit;
|
|
875
|
-
}
|
|
876
|
-
const home = resolveEnvValue("HOME") ?? resolveEnvValue("USERPROFILE");
|
|
877
|
-
return home === null ? null : `${trimTrailingSlash$1(home)}/.docker-git`;
|
|
878
|
-
};
|
|
879
|
-
const resolveProjectsRootHostOverride = () => resolveEnvValue("DOCKER_GIT_PROJECTS_ROOT_HOST");
|
|
880
|
-
const resolveCurrentContainerId = (cwd) => {
|
|
881
|
-
const fromEnv = resolveEnvValue("HOSTNAME");
|
|
882
|
-
if (fromEnv !== null) {
|
|
883
|
-
return Effect.succeed(fromEnv);
|
|
884
|
-
}
|
|
885
|
-
return runCommandCapture(
|
|
886
|
-
{
|
|
887
|
-
cwd,
|
|
888
|
-
command: "hostname",
|
|
889
|
-
args: []
|
|
890
|
-
},
|
|
891
|
-
[0],
|
|
892
|
-
() => new Error("hostname failed")
|
|
893
|
-
).pipe(
|
|
894
|
-
Effect.map((value) => value.trim()),
|
|
895
|
-
Effect.orElseSucceed(() => ""),
|
|
896
|
-
Effect.map((value) => value.length > 0 ? value : null)
|
|
897
|
-
);
|
|
898
|
-
};
|
|
899
|
-
const parseDockerInspectMounts = (raw) => raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).flatMap((line) => {
|
|
900
|
-
const separator = line.indexOf(" ");
|
|
901
|
-
if (separator <= 0 || separator >= line.length - 1) {
|
|
902
|
-
return [];
|
|
903
|
-
}
|
|
904
|
-
const source = line.slice(0, separator).trim();
|
|
905
|
-
const destination = line.slice(separator + 1).trim();
|
|
906
|
-
if (source.length === 0 || destination.length === 0) {
|
|
907
|
-
return [];
|
|
908
|
-
}
|
|
909
|
-
return [{ source, destination }];
|
|
910
|
-
});
|
|
911
|
-
const remapDockerBindHostPathFromMounts = (hostPath, mounts) => {
|
|
912
|
-
let match = null;
|
|
913
|
-
for (const mount of mounts) {
|
|
914
|
-
if (!pathStartsWith(hostPath, mount.destination)) {
|
|
915
|
-
continue;
|
|
916
|
-
}
|
|
917
|
-
if (match === null || mount.destination.length > match.destination.length) {
|
|
918
|
-
match = mount;
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
if (match === null) {
|
|
922
|
-
return hostPath;
|
|
923
|
-
}
|
|
924
|
-
return `${match.source}${hostPath.slice(match.destination.length)}`;
|
|
925
|
-
};
|
|
926
|
-
const resolveDockerVolumeHostPath = (cwd, hostPath) => Effect.gen(function* (_) {
|
|
927
|
-
const containerProjectsRoot = resolveContainerProjectsRoot();
|
|
928
|
-
const hostProjectsRoot = resolveProjectsRootHostOverride();
|
|
929
|
-
if (containerProjectsRoot !== null && hostProjectsRoot !== null) {
|
|
930
|
-
const remapped = translatePathPrefix(hostPath, containerProjectsRoot, hostProjectsRoot);
|
|
931
|
-
if (remapped !== null) {
|
|
932
|
-
return remapped;
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
const containerId = yield* _(resolveCurrentContainerId(cwd));
|
|
936
|
-
if (containerId === null) {
|
|
937
|
-
return hostPath;
|
|
938
|
-
}
|
|
939
|
-
const mountsJson = yield* _(
|
|
940
|
-
runCommandCapture(
|
|
941
|
-
{
|
|
942
|
-
cwd,
|
|
943
|
-
command: "docker",
|
|
944
|
-
args: [
|
|
945
|
-
"inspect",
|
|
946
|
-
containerId,
|
|
947
|
-
"--format",
|
|
948
|
-
String.raw`{{range .Mounts}}{{println .Source "\t" .Destination}}{{end}}`
|
|
949
|
-
]
|
|
950
|
-
},
|
|
951
|
-
[0],
|
|
952
|
-
() => new Error("docker inspect current container failed")
|
|
953
|
-
).pipe(Effect.orElseSucceed(() => ""))
|
|
954
|
-
);
|
|
955
|
-
return remapDockerBindHostPathFromMounts(hostPath, parseDockerInspectMounts(mountsJson));
|
|
956
|
-
});
|
|
957
|
-
const resolveDefaultDockerUser = () => {
|
|
958
|
-
const getUid = Reflect.get(process, "getuid");
|
|
959
|
-
const getGid = Reflect.get(process, "getgid");
|
|
960
|
-
if (typeof getUid !== "function" || typeof getGid !== "function") {
|
|
961
|
-
return null;
|
|
962
|
-
}
|
|
963
|
-
const uid = getUid.call(process);
|
|
964
|
-
const gid = getGid.call(process);
|
|
965
|
-
if (typeof uid !== "number" || typeof gid !== "number") {
|
|
966
|
-
return null;
|
|
967
|
-
}
|
|
968
|
-
return `${uid}:${gid}`;
|
|
969
|
-
};
|
|
970
|
-
const appendEnvArgs = (base, env) => {
|
|
971
|
-
if (typeof env === "string") {
|
|
972
|
-
const trimmed = env.trim();
|
|
973
|
-
if (trimmed.length > 0) {
|
|
974
|
-
base.push("-e", trimmed);
|
|
975
|
-
}
|
|
976
|
-
return;
|
|
977
|
-
}
|
|
978
|
-
for (const entry of env) {
|
|
979
|
-
const trimmed = entry.trim();
|
|
980
|
-
if (trimmed.length === 0) {
|
|
981
|
-
continue;
|
|
982
|
-
}
|
|
983
|
-
base.push("-e", trimmed);
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
const buildDockerArgs = (spec) => {
|
|
987
|
-
const base = ["run", "--rm"];
|
|
988
|
-
const dockerUser = (spec.user ?? "").trim() || resolveDefaultDockerUser();
|
|
989
|
-
if (dockerUser !== null) {
|
|
990
|
-
base.push("--user", dockerUser);
|
|
991
|
-
}
|
|
992
|
-
if (spec.interactive) {
|
|
993
|
-
base.push("-it");
|
|
994
|
-
}
|
|
995
|
-
if (spec.entrypoint && spec.entrypoint.length > 0) {
|
|
996
|
-
base.push("--entrypoint", spec.entrypoint);
|
|
997
|
-
}
|
|
998
|
-
base.push("-v", `${spec.volume.hostPath}:${spec.volume.containerPath}`);
|
|
999
|
-
if (spec.env !== void 0) {
|
|
1000
|
-
appendEnvArgs(base, spec.env);
|
|
1001
|
-
}
|
|
1002
|
-
return [...base, spec.image, ...spec.args];
|
|
1003
|
-
};
|
|
1004
|
-
const runDockerAuth = (spec, okExitCodes, onFailure) => Effect.gen(function* (_) {
|
|
1005
|
-
const hostPath = yield* _(resolveDockerVolumeHostPath(spec.cwd, spec.volume.hostPath));
|
|
1006
|
-
yield* _(
|
|
1007
|
-
runCommandWithExitCodes(
|
|
1008
|
-
{
|
|
1009
|
-
cwd: spec.cwd,
|
|
1010
|
-
command: "docker",
|
|
1011
|
-
args: buildDockerArgs({ ...spec, volume: { ...spec.volume, hostPath } })
|
|
1012
|
-
},
|
|
1013
|
-
okExitCodes,
|
|
1014
|
-
onFailure
|
|
1015
|
-
)
|
|
1016
|
-
);
|
|
1017
|
-
});
|
|
1018
|
-
const runDockerAuthCapture = (spec, okExitCodes, onFailure) => Effect.gen(function* (_) {
|
|
1019
|
-
const hostPath = yield* _(resolveDockerVolumeHostPath(spec.cwd, spec.volume.hostPath));
|
|
1020
|
-
return yield* _(
|
|
1021
|
-
runCommandCapture(
|
|
1022
|
-
{
|
|
1023
|
-
cwd: spec.cwd,
|
|
1024
|
-
command: "docker",
|
|
1025
|
-
args: buildDockerArgs({ ...spec, volume: { ...spec.volume, hostPath } })
|
|
1026
|
-
},
|
|
1027
|
-
okExitCodes,
|
|
1028
|
-
onFailure
|
|
1029
|
-
)
|
|
1030
|
-
);
|
|
1031
|
-
});
|
|
1032
|
-
const runDockerAuthExitCode = (spec) => Effect.gen(function* (_) {
|
|
1033
|
-
const hostPath = yield* _(resolveDockerVolumeHostPath(spec.cwd, spec.volume.hostPath));
|
|
1034
|
-
return yield* _(
|
|
1035
|
-
runCommandExitCode({
|
|
1036
|
-
cwd: spec.cwd,
|
|
1037
|
-
command: "docker",
|
|
1038
|
-
args: buildDockerArgs({ ...spec, volume: { ...spec.volume, hostPath } })
|
|
1039
|
-
})
|
|
1040
|
-
);
|
|
1041
|
-
});
|
|
1042
1074
|
const normalizeAccountLabel = (value, fallback) => {
|
|
1043
1075
|
const trimmed = value?.trim() ?? "";
|
|
1044
1076
|
if (trimmed.length === 0) {
|
|
@@ -3622,15 +3654,15 @@ if [[ -n "$AGENT_PROMPT" ]]; then
|
|
|
3622
3654
|
chmod 644 "$AGENT_PROMPT_FILE"
|
|
3623
3655
|
fi`
|
|
3624
3656
|
].join("\n\n");
|
|
3625
|
-
const renderAgentPromptCommand = (mode) => mode === "claude" ? String.raw`claude --dangerously-skip-permissions -p \"\$(cat $AGENT_PROMPT_FILE)\"` : String.raw`codex
|
|
3657
|
+
const renderAgentPromptCommand = (mode) => mode === "claude" ? String.raw`claude --dangerously-skip-permissions -p \"\$(cat \"$AGENT_PROMPT_FILE\")\"` : String.raw`codex exec \"\$(cat \"$AGENT_PROMPT_FILE\")\"`;
|
|
3658
|
+
const renderAgentAutoLaunchCommand = (config, mode) => String.raw`su - ${config.sshUser} -s /bin/bash -c "bash -lc '. /etc/profile 2>/dev/null || true; . \"$AGENT_ENV_FILE\" 2>/dev/null || true; cd \"$TARGET_DIR\" && ${renderAgentPromptCommand(mode)}'"`;
|
|
3626
3659
|
const renderAgentModeBlock = (config, mode) => {
|
|
3627
3660
|
const startMessage = `[agent] starting ${mode}...`;
|
|
3628
3661
|
const interactiveMessage = `[agent] ${mode} started in interactive mode (use SSH to connect)`;
|
|
3629
3662
|
return String.raw`"${mode}")
|
|
3630
3663
|
echo "${startMessage}"
|
|
3631
3664
|
if [[ -n "$AGENT_PROMPT" ]]; then
|
|
3632
|
-
if
|
|
3633
|
-
-c ". /run/docker-git/agent-env.sh 2>/dev/null; cd '$TARGET_DIR' && ${renderAgentPromptCommand(mode)}"; then
|
|
3665
|
+
if ${renderAgentAutoLaunchCommand(config, mode)}; then
|
|
3634
3666
|
AGENT_OK=1
|
|
3635
3667
|
fi
|
|
3636
3668
|
else
|
|
@@ -3961,6 +3993,8 @@ const renderAgentModeEnv = (agentMode) => agentMode !== void 0 && agentMode.leng
|
|
|
3961
3993
|
` : "";
|
|
3962
3994
|
const renderAgentAutoEnv = (agentAuto) => agentAuto === true ? ` AGENT_AUTO: "1"
|
|
3963
3995
|
` : "";
|
|
3996
|
+
const renderProjectsRootHostMount = (projectsRoot) => `\${DOCKER_GIT_PROJECTS_ROOT_HOST:-${projectsRoot}}`;
|
|
3997
|
+
const renderSharedCodexHostMount = (projectsRoot) => `\${DOCKER_GIT_PROJECTS_ROOT_HOST:-${projectsRoot}}/.orch/auth/codex`;
|
|
3964
3998
|
const buildPlaywrightFragments = (config, networkName) => {
|
|
3965
3999
|
if (!config.enableMcpPlaywright) {
|
|
3966
4000
|
return {
|
|
@@ -4052,10 +4086,10 @@ ${fragments.maybePlaywrightEnv}${fragments.maybeDependsOn} env_file:
|
|
|
4052
4086
|
- "127.0.0.1:${config.sshPort}:22"
|
|
4053
4087
|
volumes:
|
|
4054
4088
|
- ${config.volumeName}:/home/${config.sshUser}
|
|
4055
|
-
- ${config.dockerGitPath}:/home/${config.sshUser}/.docker-git
|
|
4089
|
+
- ${renderProjectsRootHostMount(config.dockerGitPath)}:/home/${config.sshUser}/.docker-git
|
|
4056
4090
|
- ${config.authorizedKeysPath}:/authorized_keys:ro
|
|
4057
4091
|
- ${config.codexAuthPath}:${config.codexHome}
|
|
4058
|
-
- ${config.
|
|
4092
|
+
- ${renderSharedCodexHostMount(config.dockerGitPath)}:${config.codexHome}-shared
|
|
4059
4093
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
4060
4094
|
networks:
|
|
4061
4095
|
- ${fragments.networkName}
|