@outerlayer/cli 0.33.0-next.20261022195547 → 0.33.0-next.20261023002325
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/README.md +5 -0
- package/dist/{agent-setup-RJOVRRHK.js → agent-setup-55ZDEXCS.js} +6 -6
- package/dist/{bridge-BCG2EB7F.js → bridge-NBCXFTT4.js} +2 -2
- package/dist/{build-GKCVFHF4.js → build-G4GUF6LT.js} +4 -4
- package/dist/{build-disk-6QAXMA2J.js → build-disk-3GL3KKEB.js} +5 -5
- package/dist/build-info.json +1 -1
- package/dist/{builder-DPNHJXG3.js → builder-3CUKTVSY.js} +4 -4
- package/dist/{check-64UX323V.js → check-64FD5G3X.js} +35 -37
- package/dist/{chunk-3MXPS7ED.js → chunk-2N67C6IV.js} +5 -4
- package/dist/{chunk-ZQOSIMKU.js → chunk-2WMZPJVE.js} +6 -3
- package/dist/{chunk-5BNWAIHN.js → chunk-3DCB3GOV.js} +41 -3
- package/dist/{chunk-UOFBHIOZ.js → chunk-57L2YAJA.js} +1 -1
- package/dist/{chunk-6NWS455T.js → chunk-5THSC6BD.js} +1 -1
- package/dist/{chunk-QL3LPZ67.js → chunk-6LBSAW6I.js} +1 -1
- package/dist/{chunk-WPGBDY73.js → chunk-6RKD7YZ6.js} +1 -1
- package/dist/{chunk-77B36F5K.js → chunk-6Z4SZHV2.js} +4 -3
- package/dist/{chunk-DETKDTNL.js → chunk-AU346ENF.js} +3 -2
- package/dist/chunk-B2JURP6A.js +41 -0
- package/dist/{chunk-BCCI32ME.js → chunk-BALIE3BA.js} +36 -7
- package/dist/{chunk-BY36DVJV.js → chunk-BKADJZ7F.js} +3 -2
- package/dist/{chunk-H7A3IQH5.js → chunk-CANYZTD5.js} +39 -22
- package/dist/{chunk-L6JFFP3Q.js → chunk-DGI66PGY.js} +32 -20
- package/dist/{chunk-GN2R5Z7G.js → chunk-DXJTBU7A.js} +3 -3
- package/dist/{chunk-WCELNMXT.js → chunk-EUVE2EAE.js} +2 -2
- package/dist/{chunk-DDS2ISML.js → chunk-F5UL23I2.js} +1 -1
- package/dist/{chunk-43PV5KDB.js → chunk-GFVDC5S3.js} +3 -3
- package/dist/{chunk-JEKENLLA.js → chunk-GH246BGV.js} +1 -1
- package/dist/{chunk-W5DOK7BL.js → chunk-HVRQQOMH.js} +3 -3
- package/dist/{chunk-6IKSUAIA.js → chunk-HXA5GIHK.js} +61 -3
- package/dist/{chunk-2QT4JUW3.js → chunk-IP7BIBXJ.js} +1 -35
- package/dist/{chunk-KLXWS5Z7.js → chunk-JPG43G6Y.js} +3 -3
- package/dist/{chunk-D3HRAPNF.js → chunk-JRZCRIEO.js} +1044 -640
- package/dist/{chunk-LWTBE5J6.js → chunk-L26V6ILJ.js} +1 -1
- package/dist/{chunk-ZXBQ6E72.js → chunk-LJUIG5K4.js} +14 -9
- package/dist/{chunk-ZRRUWNJS.js → chunk-LYE3KB6L.js} +3 -3
- package/dist/{chunk-SK4TWCN3.js → chunk-MZBQTVFG.js} +1 -1
- package/dist/{chunk-YKYCE4HY.js → chunk-MZYOUIY5.js} +1 -1
- package/dist/{chunk-OWDSO3PE.js → chunk-NBZ7XBT6.js} +1 -1
- package/dist/{chunk-6C2YWM6N.js → chunk-OOCAF3ID.js} +1 -1
- package/dist/{chunk-AGZNCIIJ.js → chunk-PA6CK6WQ.js} +1 -1
- package/dist/{chunk-QDMMW5PC.js → chunk-Q2CMEQV7.js} +2 -2
- package/dist/{chunk-DNKUSXQU.js → chunk-QFQC5K4J.js} +6 -113
- package/dist/{chunk-DJWKUQLO.js → chunk-QPWFVE3X.js} +1 -1
- package/dist/{chunk-AA6LYZC4.js → chunk-SOI6K5DY.js} +1 -1
- package/dist/{chunk-35IY5HQY.js → chunk-SVDOA4W2.js} +1 -1
- package/dist/{chunk-RBJG5MM4.js → chunk-T5REPMNL.js} +5 -5
- package/dist/{chunk-6KLPC4U7.js → chunk-ULBNTSAD.js} +3 -2
- package/dist/{chunk-CMKY36NV.js → chunk-VT4TTJPG.js} +6 -5
- package/dist/{chunk-FAZDYI2D.js → chunk-XL2XWWU7.js} +3 -2
- package/dist/{chunk-P5FC7VUO.js → chunk-XWFSAOC7.js} +2 -2
- package/dist/{chunk-CUBIZBMF.js → chunk-YERR22SY.js} +3 -3
- package/dist/{chunk-GWDS42JC.js → chunk-Z5IW4DHH.js} +1 -1
- package/dist/{claude-launcher-66GKNIRZ.js → claude-launcher-NTYHJUJM.js} +1 -1
- package/dist/{cli-WICFAKFW.js → cli-WKRURGHC.js} +126 -102
- package/dist/{command-VGR24IPI.js → command-WG54AUHK.js} +23 -23
- package/dist/{config-DUY2PT7K.js → config-LZSFW2O3.js} +2 -3
- package/dist/{connect-cmd-ADRPR6ES.js → connect-cmd-P5GASVAF.js} +5 -5
- package/dist/{container-start-QX53HKXW.js → container-start-DQKFQ3CL.js} +21 -23
- package/dist/context-show-cmd-3EPJ7CJC.js +115 -0
- package/dist/{control-plane-launch-SMHL6MWW.js → control-plane-launch-A3YCHQNQ.js} +5 -5
- package/dist/{docker-GGRJHHBP.js → docker-4ERXWTRW.js} +4 -4
- package/dist/{doctor-N3CDJ66I.js → doctor-GRCEYJXA.js} +24 -26
- package/dist/{emit-artifact-cmd-73OWUBH6.js → emit-artifact-cmd-FDPJKGOO.js} +11 -10
- package/dist/{emit-criteria-cmd-D7OR356Y.js → emit-criteria-cmd-3SVGCMJN.js} +8 -7
- package/dist/{emit-demo-cmd-4AV74GMZ.js → emit-demo-cmd-JSVI56WY.js} +11 -10
- package/dist/{emit-finding-cmd-GEPRJ6KO.js → emit-finding-cmd-TLJWBGQE.js} +8 -7
- package/dist/{emit-result-cmd-N52IABK6.js → emit-result-cmd-CJNVDV5V.js} +10 -9
- package/dist/{emit-step-cmd-CC6MUJ2S.js → emit-step-cmd-347CZO7Y.js} +8 -7
- package/dist/{exec-client-KLI262IX.js → exec-client-7PT4W7JR.js} +3 -3
- package/dist/{findings-cmd-7I72XX2H.js → findings-cmd-LHTYEHYB.js} +8 -7
- package/dist/{fleet-readiness-EZAGL32M.js → fleet-readiness-KGR5AC2J.js} +5 -5
- package/dist/{governing-source-M7ZRJCGY.js → governing-source-JZQZUTMA.js} +10 -9
- package/dist/{guest-init-ZJIE6MU3.js → guest-init-J3F3AEEY.js} +4 -4
- package/dist/{hook-fast-WNKICZ6E.js → hook-fast-6WDMNZG5.js} +1 -1
- package/dist/{pending-I5TY6SQH.js → host-key-UERIQRE6.js} +3 -3
- package/dist/{image-tag-MORUQ4LF.js → image-tag-ADSLWXBA.js} +3 -3
- package/dist/index.js +4 -4
- package/dist/{init-XG4NRZX4.js → init-OKJAI77M.js} +20 -22
- package/dist/{init-VCWDBOT4.js → init-WNO4NAO7.js} +20 -22
- package/dist/{init-cmd-2CAMWMRP.js → init-cmd-PFW4XTG7.js} +11 -10
- package/dist/{init-update-NCM4GA3S.js → init-update-X7YLZL6H.js} +8 -8
- package/dist/{install-NLVYISAV.js → install-GQUCHIGE.js} +4 -5
- package/dist/{install-cmd-HFGINYEE.js → install-cmd-FV7IZ7XF.js} +5 -5
- package/dist/{logs-QSKJ4G6M.js → logs-HI46FO6Z.js} +2 -2
- package/dist/{loop-PXALY3VY.js → loop-2SITCQ6H.js} +35 -37
- package/dist/{machine-AZRL432D.js → machine-YHBCNRUO.js} +20 -18
- package/dist/{mcp-serve-cmd-DQSO6MOL.js → mcp-serve-cmd-7ABBV2QE.js} +4 -4
- package/dist/{paths-KHDFSBEI.js → paths-7HVTDE6J.js} +2 -2
- package/dist/{host-key-REZADWAM.js → pending-5HZACM2V.js} +3 -3
- package/dist/{pidfile-BSY63HIC.js → pidfile-5UDLYPMC.js} +3 -3
- package/dist/{record-7CNTGRLD.js → record-PPZEXAVA.js} +3 -3
- package/dist/{runner-env-26NLQI35.js → runner-env-QYE7KZFP.js} +5 -6
- package/dist/{runner-identity-WGH73DTV.js → runner-identity-FIHOECSH.js} +4 -4
- package/dist/{runner-key-6BIULOR4.js → runner-key-YUKU2MWK.js} +20 -22
- package/dist/{session-sender-MSHKJSBG.js → session-sender-7B3ZDWMC.js} +11 -10
- package/dist/{spec-cmd-AWIMO32E.js → spec-cmd-Q26NE22H.js} +9 -8
- package/dist/{status-BILERIXB.js → status-VBQJMFEX.js} +27 -25
- package/dist/{sync-cmd-BSUZ65CU.js → sync-cmd-SSUYTMLJ.js} +10 -9
- package/dist/{watch-UF6XCGSI.js → watch-L5NCO46E.js} +10 -9
- package/dist/{work-claim-cmd-4FXVAZWF.js → work-claim-cmd-MFND6Z4S.js} +12 -12
- package/dist/{work-cmd-NCP4637R.js → work-cmd-W7WEHMQJ.js} +8 -7
- package/dist/{work-comment-cmd-YNQYVHYS.js → work-comment-cmd-SSUOGVDD.js} +8 -7
- package/dist/{work-logs-cmd-HHWVYQBG.js → work-logs-cmd-WPMWMDX6.js} +8 -7
- package/dist/{work-open-pr-cmd-ALVD7KLY.js → work-open-pr-cmd-NO5YLOXD.js} +9 -8
- package/dist/{work-pr-cmd-KBNFVRB4.js → work-pr-cmd-37B5KECR.js} +8 -7
- package/dist/{work-stop-cmd-DBWNHZJO.js → work-stop-cmd-3BJLXUJ3.js} +8 -7
- package/package.json +1 -1
- package/skill-pack/maintained/outerlayer-build/SKILL.md +4 -2
- package/dist/chunk-I5LGKZ4M.js +0 -107
- package/dist/chunk-UXYLWVTQ.js +0 -43
- package/dist/chunk-WBZJWVT2.js +0 -146
package/dist/chunk-I5LGKZ4M.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
import { MIN_ENGINE_MAJOR } from './chunk-D3HRAPNF.js';
|
|
4
|
-
import { runnerImageVersion } from './chunk-SK4TWCN3.js';
|
|
5
|
-
import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-TGHBOXKJ.js';
|
|
6
|
-
import { spawnSync } from 'child_process';
|
|
7
|
-
import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
|
|
8
|
-
|
|
9
|
-
createRequire(import.meta.url);
|
|
10
|
-
function groupName(gid) {
|
|
11
|
-
try {
|
|
12
|
-
for (const line of readFileSync("/etc/group", "utf8").split("\n")) {
|
|
13
|
-
const [name, , id] = line.split(":");
|
|
14
|
-
if (name !== void 0 && Number(id) === gid) return name;
|
|
15
|
-
}
|
|
16
|
-
} catch {
|
|
17
|
-
}
|
|
18
|
-
return String(gid);
|
|
19
|
-
}
|
|
20
|
-
function detectKvm(device) {
|
|
21
|
-
if (!existsSync(device)) return { state: "absent" };
|
|
22
|
-
try {
|
|
23
|
-
accessSync(device, constants.R_OK | constants.W_OK);
|
|
24
|
-
return { state: "usable" };
|
|
25
|
-
} catch {
|
|
26
|
-
return { state: "no-permission", group: groupName(statSync(device).gid) };
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function readProcVersion() {
|
|
30
|
-
try {
|
|
31
|
-
return readFileSync("/proc/version", "utf8");
|
|
32
|
-
} catch {
|
|
33
|
-
return void 0;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function docker(args) {
|
|
37
|
-
const result = spawnSync("docker", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 15e3 });
|
|
38
|
-
const out = result.status === 0 ? result.stdout.trim() : "";
|
|
39
|
-
return out === "" ? void 0 : out;
|
|
40
|
-
}
|
|
41
|
-
function dockerFailure() {
|
|
42
|
-
const result = spawnSync("docker", ["version", "--format", "{{.Server.Version}}"], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 15e3 });
|
|
43
|
-
if (result.error?.code === "ENOENT") return void 0;
|
|
44
|
-
return /permission denied/i.test(result.stderr ?? "") ? "permission" : "daemon";
|
|
45
|
-
}
|
|
46
|
-
function platformOf(probes) {
|
|
47
|
-
const platform = probes.platform ?? process.platform;
|
|
48
|
-
if (platform === "win32") return "windows";
|
|
49
|
-
if (platform === "darwin") return "darwin";
|
|
50
|
-
if (platform !== "linux") return "other";
|
|
51
|
-
return /microsoft/i.test((probes.procVersion ?? readProcVersion)() ?? "") ? "wsl2" : "linux";
|
|
52
|
-
}
|
|
53
|
-
function detectMachine(probes = {}) {
|
|
54
|
-
const platform = platformOf(probes);
|
|
55
|
-
const kvm = (probes.kvm ?? (() => detectKvm(probes.kvmDevice ?? "/dev/kvm")))();
|
|
56
|
-
const arch = firecrackerArch(probes.nodeArch ?? process.arch);
|
|
57
|
-
const inImage = runnerImageVersion(probes.env ?? process.env) !== void 0 ? { inImage: true } : {};
|
|
58
|
-
const version = (probes.dockerVersion ?? (() => docker(["version", "--format", "{{.Server.Version}}"])))();
|
|
59
|
-
if (version === void 0) {
|
|
60
|
-
const failure = (probes.dockerFailure ?? (probes.dockerVersion === void 0 ? dockerFailure : () => void 0))();
|
|
61
|
-
return { platform, ...inImage, docker: failure === void 0 ? { kind: "none" } : { kind: "unreachable", reason: failure }, kvm, arch };
|
|
62
|
-
}
|
|
63
|
-
const system = (probes.dockerOperatingSystem ?? (() => docker(["info", "--format", "{{.OperatingSystem}}"])))() ?? "";
|
|
64
|
-
return { platform, ...inImage, docker: { kind: /docker desktop/i.test(system) ? "desktop" : "engine", version }, kvm, arch };
|
|
65
|
-
}
|
|
66
|
-
function supportsContainerBuilds(machine) {
|
|
67
|
-
if (machine.platform !== "linux" && machine.platform !== "wsl2") return false;
|
|
68
|
-
const { kind, version } = machine.docker;
|
|
69
|
-
if (kind !== "engine" && !(kind === "desktop" && machine.inImage === true)) return false;
|
|
70
|
-
return Number.parseInt(version ?? "", 10) >= MIN_ENGINE_MAJOR;
|
|
71
|
-
}
|
|
72
|
-
function supportsMicroVmBuilds(machine) {
|
|
73
|
-
return machine.platform === "linux" && machine.kvm?.state === "usable" && supportsContainerBuilds(machine) && microVmAssetsPinned(machine);
|
|
74
|
-
}
|
|
75
|
-
function microVmArchSupported(machine) {
|
|
76
|
-
return MICROVM_ARCHES.includes(machine.arch ?? "");
|
|
77
|
-
}
|
|
78
|
-
function microVmAssetsPinned(machine) {
|
|
79
|
-
return microVmArchSupported(machine) && guestAssetsPinned(machine.arch);
|
|
80
|
-
}
|
|
81
|
-
function reachDockerStep(machine) {
|
|
82
|
-
if (machine.docker.kind !== "unreachable") return void 0;
|
|
83
|
-
return machine.docker.reason === "permission" ? "give this user access to Docker Engine's socket (add it to the docker group, then log in again)" : "start Docker Engine's daemon (for example, sudo systemctl start docker)";
|
|
84
|
-
}
|
|
85
|
-
function describeMachineDocker(machine) {
|
|
86
|
-
const { kind, version, reason } = machine.docker;
|
|
87
|
-
const where = machine.platform === "windows" ? "Windows" : machine.platform === "darwin" ? "macOS" : machine.platform === "wsl2" ? "WSL2" : "Linux";
|
|
88
|
-
if (kind === "desktop") {
|
|
89
|
-
const engine = version === void 0 ? "" : ` with engine ${version}`;
|
|
90
|
-
if (machine.inImage === true && (machine.platform === "linux" || machine.platform === "wsl2")) {
|
|
91
|
-
const major = Number.parseInt(version ?? "", 10);
|
|
92
|
-
if (Number.isNaN(major)) return `Docker Desktop${engine}, whose engine version is not readable`;
|
|
93
|
-
if (major < MIN_ENGINE_MAJOR) return `Docker Desktop${engine}, older than the ${MIN_ENGINE_MAJOR} that container builds need`;
|
|
94
|
-
return `Docker Desktop${engine}`;
|
|
95
|
-
}
|
|
96
|
-
return `Docker Desktop${engine} on ${where}, which a runner accepts only in the runner image`;
|
|
97
|
-
}
|
|
98
|
-
if (kind === "none") return `no Docker on ${where}`;
|
|
99
|
-
if (kind === "unreachable") {
|
|
100
|
-
const problem = reason === "permission" ? "this user has no permission on its socket" : "its daemon is not running";
|
|
101
|
-
return `a docker command on ${where} that cannot reach Docker Engine (${problem})`;
|
|
102
|
-
}
|
|
103
|
-
if (machine.platform !== "linux" && machine.platform !== "wsl2") return `Docker Engine ${version ?? ""} on ${where}, which cannot isolate a build`.replace(" ", " ");
|
|
104
|
-
return `Docker Engine ${version ?? "of no known version"}, older than the ${MIN_ENGINE_MAJOR} that container builds need`;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export { describeMachineDocker, detectMachine, microVmArchSupported, microVmAssetsPinned, reachDockerStep, supportsContainerBuilds, supportsMicroVmBuilds };
|
package/dist/chunk-UXYLWVTQ.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
|
|
4
|
-
createRequire(import.meta.url);
|
|
5
|
-
|
|
6
|
-
// src/runner/allow-hosts.ts
|
|
7
|
-
var MAX_ALLOW_HOSTS = 500;
|
|
8
|
-
var LABEL = /^(?!-)[a-z0-9-]{1,63}(?<!-)$/;
|
|
9
|
-
var IPV4 = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
|
|
10
|
-
function isAddress(text) {
|
|
11
|
-
if (IPV4.test(text)) return true;
|
|
12
|
-
try {
|
|
13
|
-
new URL(`http://[${text}]/`);
|
|
14
|
-
return true;
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function isHostName(text) {
|
|
20
|
-
const labels = text.split(".");
|
|
21
|
-
return text.length <= 253 && labels.every((label) => LABEL.test(label)) && !/^\d+$/.test(labels.at(-1));
|
|
22
|
-
}
|
|
23
|
-
function allowHostProblem(entry) {
|
|
24
|
-
if (typeof entry !== "string") return "is not a string";
|
|
25
|
-
const text = entry.toLowerCase();
|
|
26
|
-
if (isAddress(text)) return void 0;
|
|
27
|
-
if (text.startsWith("*.")) {
|
|
28
|
-
const domain = text.slice(2);
|
|
29
|
-
if (!isHostName(domain)) return "is not a host name after *.";
|
|
30
|
-
if (!domain.includes(".")) return "is too broad: a pattern needs a domain with at least two labels after *.";
|
|
31
|
-
return void 0;
|
|
32
|
-
}
|
|
33
|
-
return isHostName(text) ? void 0 : "is not a host name, a *. pattern or an IP address";
|
|
34
|
-
}
|
|
35
|
-
function hostAllowed(host, allowHosts) {
|
|
36
|
-
const name = host.toLowerCase().replace(/\.$/, "");
|
|
37
|
-
return allowHosts.some((entry) => {
|
|
38
|
-
const pattern = entry.toLowerCase();
|
|
39
|
-
return pattern.startsWith("*.") ? name.endsWith(pattern.slice(1)) : name === pattern;
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export { MAX_ALLOW_HOSTS, allowHostProblem, hostAllowed };
|
package/dist/chunk-WBZJWVT2.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-CUBIZBMF.js';
|
|
4
|
-
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-I5LGKZ4M.js';
|
|
5
|
-
import { MIN_ENGINE_MAJOR } from './chunk-D3HRAPNF.js';
|
|
6
|
-
import { runnerCredentialProblem } from './chunk-5BNWAIHN.js';
|
|
7
|
-
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-AGZNCIIJ.js';
|
|
8
|
-
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
9
|
-
import { dirname } from 'path';
|
|
10
|
-
|
|
11
|
-
createRequire(import.meta.url);
|
|
12
|
-
var RunnerInitError = class extends Error {
|
|
13
|
-
};
|
|
14
|
-
var UNMARKED_PLACEHOLDER_COMMAND = "echo 'edit runner.commands in this config file: it must start your agent on item $OUTERLAYER_WORK' >&2; exit 1";
|
|
15
|
-
var PLACEHOLDER_MARKER = "outerlayer-placeholder";
|
|
16
|
-
var PLACEHOLDER_COMMAND = `${UNMARKED_PLACEHOLDER_COMMAND} # ${PLACEHOLDER_MARKER}`;
|
|
17
|
-
function isolationNote(machine) {
|
|
18
|
-
const has = describeMachineDocker(machine);
|
|
19
|
-
const reach = reachDockerStep(machine);
|
|
20
|
-
const needs = reach !== void 0 ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later: ${reach}, then set both hooks to builtin:container.` : machine.platform === "windows" ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later inside WSL2: install it there, run the runner from a WSL2 shell, and set both hooks to builtin:container.` : `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later on Linux or WSL2. Once it is installed, set both hooks to builtin:container.`;
|
|
21
|
-
return `This machine has ${has}, so builds run as processes under this user (isolation: shared-user), through the tunnel. ${needs}`;
|
|
22
|
-
}
|
|
23
|
-
function processRefusal(machine) {
|
|
24
|
-
const reach = reachDockerStep(machine);
|
|
25
|
-
const needs = machine.platform === "darwin" ? "Isolated builds on a Mac run in the runner image on Docker Desktop (https://docs.outerlayer.ai/run-the-runner-in-a-container) or in a Linux VM: run this again with --vm." : reach !== void 0 ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later: ${reach}, then run this again.` : machine.platform === "windows" ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later inside WSL2: install it there, then run this again from a WSL2 shell.` : `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later on Linux or WSL2: install it, then run this again.`;
|
|
26
|
-
return `This machine has ${describeMachineDocker(machine)}, so it cannot isolate a build. ${needs} To run builds as processes under this user instead, where a build can read this user's files and the runner's Claude credential, run this again with --allow-process-builds.`;
|
|
27
|
-
}
|
|
28
|
-
function isPlaceholderCommand(command) {
|
|
29
|
-
return command === UNMARKED_PLACEHOLDER_COMMAND || command.includes(PLACEHOLDER_MARKER);
|
|
30
|
-
}
|
|
31
|
-
function readConfigObject(configPath) {
|
|
32
|
-
if (!existsSync(configPath)) {
|
|
33
|
-
throw new RunnerInitError(
|
|
34
|
-
`${configPath}: no config file. Run \`outerlayer login\` first, then this command.`
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
return JSON.parse(readFileSync(configPath, "utf8"));
|
|
39
|
-
} catch (err) {
|
|
40
|
-
throw new RunnerInitError(`${configPath}: not valid JSON (${err instanceof Error ? err.message : String(err)})`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function handedCredential(value) {
|
|
44
|
-
if (value === void 0) return void 0;
|
|
45
|
-
if (typeof value !== "string") throw new RunnerInitError("the config on stdin carries a claudeCredential that is not text.");
|
|
46
|
-
return credentialFromStdin(value);
|
|
47
|
-
}
|
|
48
|
-
function handedAgent(value) {
|
|
49
|
-
if (value === void 0) return void 0;
|
|
50
|
-
if (!isAgentName(value)) throw new RunnerInitError("the config on stdin names an agent runner init does not know.");
|
|
51
|
-
return value;
|
|
52
|
-
}
|
|
53
|
-
function parseStdinConfig(configPath, text) {
|
|
54
|
-
if (existsSync(configPath)) {
|
|
55
|
-
throw new RunnerInitError(
|
|
56
|
-
`${configPath}: a config file is already here, so the runner key in it is not replaced. Remove it, or delete the VM and start again.`
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
let config;
|
|
60
|
-
try {
|
|
61
|
-
config = JSON.parse(text);
|
|
62
|
-
} catch (err) {
|
|
63
|
-
throw new RunnerInitError(`the config on stdin is not valid JSON (${err instanceof Error ? err.message : String(err)})`);
|
|
64
|
-
}
|
|
65
|
-
const problem = runnerCredentialProblem(config);
|
|
66
|
-
if (problem !== void 0) throw new RunnerInitError(`the config on stdin: ${problem.field} ${problem.reason}.`);
|
|
67
|
-
const carried = config.runner;
|
|
68
|
-
const credential = handedCredential(config.claudeCredential);
|
|
69
|
-
const agent = handedAgent(config.agent);
|
|
70
|
-
delete config.runner;
|
|
71
|
-
delete config.claudeCredential;
|
|
72
|
-
delete config.agent;
|
|
73
|
-
return { config, carried, credential, agent };
|
|
74
|
-
}
|
|
75
|
-
function runRunnerInit(configPath, opts = {}) {
|
|
76
|
-
return writeRunnerInit(prepareRunnerInit(configPath, opts));
|
|
77
|
-
}
|
|
78
|
-
function prepareRunnerInit(configPath, opts = {}) {
|
|
79
|
-
let config;
|
|
80
|
-
let carried;
|
|
81
|
-
let credential = opts.credential;
|
|
82
|
-
let agent = opts.agent;
|
|
83
|
-
let needsKey = false;
|
|
84
|
-
if (opts.configFromStdin === void 0) {
|
|
85
|
-
config = opts.keyFromLogin === true && !existsSync(configPath) ? {} : readConfigObject(configPath);
|
|
86
|
-
if (config.runner !== void 0) {
|
|
87
|
-
throw new RunnerInitError(`${configPath}: a runner block is already here. Edit it, or remove it and run this again.`);
|
|
88
|
-
}
|
|
89
|
-
needsKey = opts.keyFromLogin === true && config.apiKey === void 0;
|
|
90
|
-
const problem = needsKey ? void 0 : runnerCredentialProblem(config);
|
|
91
|
-
if (problem !== void 0) throw new RunnerInitError(`${configPath}: ${problem.field} ${problem.reason}.`);
|
|
92
|
-
} else {
|
|
93
|
-
const handed = parseStdinConfig(configPath, opts.configFromStdin);
|
|
94
|
-
({ config, carried } = handed);
|
|
95
|
-
credential ??= handed.credential;
|
|
96
|
-
agent ??= handed.agent;
|
|
97
|
-
}
|
|
98
|
-
const machine = opts.machine ?? detectMachine();
|
|
99
|
-
if (opts.requireContainer === true && !supportsContainerBuilds(machine)) {
|
|
100
|
-
const fix = reachDockerStep(machine) ?? `install Docker Engine ${MIN_ENGINE_MAJOR} or later in the VM`;
|
|
101
|
-
throw new RunnerInitError(`the VM has ${describeMachineDocker(machine)}, but the runner in it needs container builds: ${fix}, then run this again.`);
|
|
102
|
-
}
|
|
103
|
-
const hooks = opts.requireContainer !== true && supportsMicroVmBuilds(machine) ? "builtin:vm" : supportsContainerBuilds(machine) ? "builtin:container" : "builtin:process";
|
|
104
|
-
if (hooks === "builtin:process" && opts.allowProcess !== true) throw new RunnerInitError(processRefusal(machine));
|
|
105
|
-
if (agent === "claude" && credential === void 0 && opts.credentialInEnvironment !== true && !hasStoredCredential(configPath)) {
|
|
106
|
-
throw new RunnerInitError(
|
|
107
|
-
"--agent claude needs Claude's credential, and none was piped on stdin or is in the claude.env beside the config. Pipe a token from `claude setup-token`, or an Anthropic API key: printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude"
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
return { configPath, config, carried, credential, agent, machine, hooks, needsKey, host: opts.host };
|
|
111
|
-
}
|
|
112
|
-
function writeRunnerInit(prepared, runnerKey) {
|
|
113
|
-
const { configPath, config, carried, credential, agent, machine, hooks, host } = prepared;
|
|
114
|
-
if (prepared.needsKey && runnerKey === void 0) {
|
|
115
|
-
throw new RunnerInitError(`${configPath}: apiKey is missing, and no runner key was pasted.`);
|
|
116
|
-
}
|
|
117
|
-
if (runnerKey !== void 0) Object.assign(config, { url: runnerKey.url, apiKey: runnerKey.apiKey, appId: runnerKey.appId });
|
|
118
|
-
mkdirSync(runnerDir(configPath), { recursive: true, mode: RUNNER_DIR_MODE });
|
|
119
|
-
config.runner = {
|
|
120
|
-
queues: ["implement", "amend"],
|
|
121
|
-
concurrency: 1,
|
|
122
|
-
pollSeconds: 60,
|
|
123
|
-
timeLimitMinutes: 480,
|
|
124
|
-
idleLimitMinutes: 30,
|
|
125
|
-
// A placeholder that fails loudly. A command line that quietly did
|
|
126
|
-
// nothing would claim an item, run, exit zero, and record `ok` —
|
|
127
|
-
// every attempt reading as a success that produced nothing.
|
|
128
|
-
commands: {
|
|
129
|
-
implement: PLACEHOLDER_COMMAND,
|
|
130
|
-
amend: PLACEHOLDER_COMMAND
|
|
131
|
-
},
|
|
132
|
-
...carried,
|
|
133
|
-
...host === void 0 ? {} : { name: host },
|
|
134
|
-
// The agent was named on this command line, so its commands win over any the hand-off carried.
|
|
135
|
-
...agent === void 0 ? {} : { commands: { ...AGENT_COMMANDS[agent] } },
|
|
136
|
-
hooks: { provision: hooks, cleanup: hooks }
|
|
137
|
-
};
|
|
138
|
-
if (host !== void 0) delete config.runner.host;
|
|
139
|
-
mkdirSync(dirname(configPath), { recursive: true });
|
|
140
|
-
const stored = credential === void 0 ? void 0 : { variable: credential.variable, path: storeClaudeCredential(configPath, credential) };
|
|
141
|
-
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
142
|
-
`, { mode: RUNNER_FILE_MODE });
|
|
143
|
-
return { configPath, hooks, ...hooks === "builtin:process" ? { note: isolationNote(machine) } : {}, credential: stored };
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export { PLACEHOLDER_MARKER, RunnerInitError, isPlaceholderCommand, prepareRunnerInit, readConfigObject, runRunnerInit, writeRunnerInit };
|