@outerlayer/cli 0.26.4 → 0.27.1
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 +23 -0
- package/README.md +12 -9
- package/dist/{agent-setup-5DXPEO64.js → agent-setup-UW36TAQM.js} +11 -11
- package/dist/{bridge-5KZ36YDG.js → bridge-B5VJVECY.js} +2 -2
- package/dist/build-HRLACBOZ.js +12 -0
- package/dist/build-info.json +1 -1
- package/dist/{builder-KDUXCHTY.js → builder-6Y6ZWGNH.js} +6 -6
- package/dist/{check-ZSYCR5WG.js → check-YTXFVWK7.js} +41 -40
- package/dist/{chunk-B6K7R5UY.js → chunk-2BTFKNTR.js} +2 -2
- package/dist/{chunk-H57M3HC7.js → chunk-2F762IXY.js} +2 -2
- package/dist/{chunk-2K3TCQHW.js → chunk-2I3LIRZP.js} +26 -8
- package/dist/{chunk-6CGXSMKX.js → chunk-55GNQPO6.js} +17 -6
- package/dist/{chunk-V3YJFEZA.js → chunk-5VMDGJGH.js} +274 -45
- package/dist/{chunk-OQUD3UYF.js → chunk-64GMBWAK.js} +5 -5
- package/dist/{chunk-MWPBF2XG.js → chunk-6KKM7VGZ.js} +32 -4
- package/dist/{chunk-VPEGE3QZ.js → chunk-6TRNCUM4.js} +1 -1
- package/dist/{chunk-27RDUTQH.js → chunk-6VFH52MP.js} +195 -39
- package/dist/{chunk-6SPXKRQR.js → chunk-7AQ5AM7U.js} +12 -5
- package/dist/{chunk-HBISTTG3.js → chunk-7OUOLGUV.js} +20 -5
- package/dist/{chunk-NWPRNKZ5.js → chunk-ABXQBEYK.js} +1 -1
- package/dist/{chunk-EHBDYLM6.js → chunk-B7DJVG25.js} +3 -3
- package/dist/{chunk-4UFSTKE5.js → chunk-BPKO76QR.js} +4 -4
- package/dist/{chunk-MCSINUVC.js → chunk-BWH36FOC.js} +1 -1
- package/dist/{chunk-IZAOO5AR.js → chunk-D7ECMB7B.js} +4 -4
- package/dist/{chunk-UZEQVPKF.js → chunk-DJHNEGNM.js} +27 -3
- package/dist/{chunk-O4362FPA.js → chunk-E5IJ5533.js} +2 -2
- package/dist/{chunk-JWRX5ZTT.js → chunk-EPPIISRD.js} +2 -2
- package/dist/{chunk-QUP6CVBQ.js → chunk-EX5MQYEF.js} +5 -5
- package/dist/{chunk-KNBWOL2B.js → chunk-FP23SVDD.js} +5 -5
- package/dist/{chunk-VGHKTSHU.js → chunk-GFUE5TKO.js} +3 -3
- package/dist/{chunk-XLC7KEUV.js → chunk-GLUKDQS4.js} +1 -1
- package/dist/{chunk-GFHLEVUE.js → chunk-HWDYLXHH.js} +7 -4
- package/dist/chunk-IMOB4IOI.js +181 -0
- package/dist/{chunk-JKNYTNYD.js → chunk-LOKSLO25.js} +1 -1
- package/dist/{chunk-ZMZGWLYD.js → chunk-LPFOWUHG.js} +13 -13
- package/dist/{chunk-2J46BQ5Y.js → chunk-M3MHHIUW.js} +1 -1
- package/dist/{chunk-7Z2WMXM5.js → chunk-MATUHHN4.js} +1 -1
- package/dist/{chunk-MQ743JX3.js → chunk-MHX7YX7Y.js} +1 -1
- package/dist/{chunk-PZA6ZFYW.js → chunk-N4D5TMVU.js} +2 -2
- package/dist/{chunk-WK35HB56.js → chunk-O2IJTY7L.js} +2 -2
- package/dist/{chunk-6WTAYEKJ.js → chunk-P33PZIWS.js} +55 -7
- package/dist/{chunk-K4FXNMV5.js → chunk-QHH4OSD4.js} +1 -1
- package/dist/{chunk-Y4BXRVDI.js → chunk-QKIQ2R7F.js} +3 -3
- package/dist/{chunk-SBW4K3XZ.js → chunk-R7SGBXUD.js} +76 -30
- package/dist/{chunk-F3BBEBPL.js → chunk-RHAGBUL5.js} +1 -1
- package/dist/{chunk-OFTFW7TH.js → chunk-RHGF73IU.js} +1 -1
- package/dist/{chunk-6MZSX4M7.js → chunk-STSLH5EJ.js} +3 -1
- package/dist/{chunk-VQ7OAG6H.js → chunk-VS27BP3E.js} +4 -4
- package/dist/{chunk-OZKEEXVH.js → chunk-WSYXLLA5.js} +6 -6
- package/dist/{chunk-WX2WEERU.js → chunk-WUL2OP5A.js} +3 -3
- package/dist/{chunk-MXTN35XN.js → chunk-XBPUTQ7E.js} +1 -1
- package/dist/{chunk-UNF7MWEL.js → chunk-XS3FDWSZ.js} +1 -1
- package/dist/{chunk-VJBFQP3H.js → chunk-XZ6Q6ZNR.js} +9 -5
- package/dist/{chunk-GWRDL75D.js → chunk-Y4OKEFAX.js} +1 -1
- package/dist/{chunk-Q2SVLBMI.js → chunk-Y7ZCHBYB.js} +2 -2
- package/dist/chunk-YB3CSYXX.js +95 -0
- package/dist/chunk-YJLHUKYS.js +38 -0
- package/dist/{chunk-UOGQZQXN.js → chunk-ZFBJUOYT.js} +6 -6
- package/dist/{claude-launcher-TTLTS4N6.js → claude-launcher-NQSZBTQ5.js} +8 -4
- package/dist/{cli-SKF3AMZ5.js → cli-GHEOBXC7.js} +133 -127
- package/dist/{command-E5OG5NCH.js → command-V7B7GTPZ.js} +30 -29
- package/dist/{config-JJ3EO7SB.js → config-TWS5VZEN.js} +3 -3
- package/dist/{connect-cmd-SL4S5HJM.js → connect-cmd-HGS7YPA2.js} +7 -7
- package/dist/{container-start-IA2HK4QI.js → container-start-FHB2VDC4.js} +29 -28
- package/dist/{control-plane-launch-JIQOE6BP.js → control-plane-launch-DBQA3KLJ.js} +8 -8
- package/dist/{docker-KKE5Q5S2.js → docker-YT6Z3LXI.js} +6 -6
- package/dist/{doctor-U2N7AF3N.js → doctor-Y4NCNSJM.js} +181 -34
- package/dist/{emit-artifact-cmd-SDG5H6D7.js → emit-artifact-cmd-ALDK55Y2.js} +11 -11
- package/dist/{emit-cmd-WQH2NK7H.js → emit-cmd-VAQHRWJR.js} +4 -4
- package/dist/{emit-criteria-cmd-QGSP77AG.js → emit-criteria-cmd-Q7SM6VP2.js} +8 -8
- package/dist/{emit-finding-cmd-6FGMTEFM.js → emit-finding-cmd-2NBAPDSV.js} +8 -8
- package/dist/{emit-result-cmd-AUPIXPEU.js → emit-result-cmd-KUSL56RI.js} +11 -11
- package/dist/{emit-step-cmd-PORHEKHN.js → emit-step-cmd-KD4AKEAT.js} +9 -9
- package/dist/{exec-client-J6L5FDRR.js → exec-client-6WVS7DRZ.js} +3 -3
- package/dist/{governing-source-YPBK4H5H.js → governing-source-VVUA5TKB.js} +13 -13
- package/dist/{guest-init-CXIHA5VI.js → guest-init-H5K2RW3P.js} +4 -4
- package/dist/{hook-fast-XMZFMBKC.js → hook-fast-3SUJM765.js} +1 -1
- package/dist/{host-key-GQFBRX3J.js → host-key-XNKZCWTS.js} +3 -3
- package/dist/{image-tag-W4JKVNP4.js → image-tag-R34J4O3F.js} +3 -3
- package/dist/index.js +4 -4
- package/dist/{init-Y64OAKKQ.js → init-3DAGX7UY.js} +30 -29
- package/dist/{init-GEFKJNJU.js → init-SWKYV6CL.js} +29 -28
- package/dist/{init-cmd-YR4LLIRU.js → init-cmd-RIDBVSE4.js} +15 -14
- package/dist/{init-update-46G6QJHB.js → init-update-ECWNG47R.js} +55 -26
- package/dist/{inspect-6UYAAXH7.js → inspect-IPFA7AAT.js} +1 -1
- package/dist/{install-AFMXH25X.js → install-6OIY3KHZ.js} +6 -5
- package/dist/{install-cmd-X5XCUTSX.js → install-cmd-JMT67P35.js} +5 -5
- package/dist/{layout-UOJQGEPW.js → layout-XNFDTOET.js} +2 -2
- package/dist/{logs-PKNQOJN6.js → logs-XHAS6LMZ.js} +2 -2
- package/dist/loop-AIJZVUNA.js +79 -0
- package/dist/{machine-3W4LKTEW.js → machine-OOQ2NXC3.js} +24 -23
- package/dist/machine-skills-FLIRJYP7.js +11 -0
- package/dist/{mcp-serve-cmd-MJIJHSQ6.js → mcp-serve-cmd-LY5A3CE7.js} +4 -4
- package/dist/{paths-6V7572NN.js → paths-LHSPNORF.js} +2 -2
- package/dist/{pending-GUHHKO42.js → pending-3YZCSKON.js} +3 -3
- package/dist/{pidfile-ZQOFDY7T.js → pidfile-DKMYYXLH.js} +3 -3
- package/dist/{record-C4ZVSLKV.js → record-3LPTY3G5.js} +3 -3
- package/dist/{runner-env-6Q2RMENH.js → runner-env-YRRNRKF4.js} +8 -7
- package/dist/{runner-identity-DP577A7S.js → runner-identity-YS2BZXZV.js} +6 -6
- package/dist/{runner-key-LR5P2EJ5.js → runner-key-EFNTZWNX.js} +29 -28
- package/dist/{session-sender-ZTPWIU5L.js → session-sender-SC5PSU2G.js} +12 -12
- package/dist/{spec-cmd-RLZMX67G.js → spec-cmd-JGYHHJ4P.js} +9 -9
- package/dist/{starter-pack-55EFILC5.js → starter-pack-GPU4X6B7.js} +2 -2
- package/dist/{status-GNUOTHRH.js → status-7WM7S7JX.js} +31 -30
- package/dist/{sync-cmd-GLWEAULP.js → sync-cmd-ATXJVS7S.js} +11 -11
- package/dist/{watch-F47NPUDX.js → watch-M7NR3DOW.js} +11 -11
- package/dist/{work-claim-cmd-GXPIRRBG.js → work-claim-cmd-DNUDZKJA.js} +13 -13
- package/dist/{work-cmd-S2FHIFJA.js → work-cmd-VECTYST6.js} +9 -9
- package/dist/{work-comment-cmd-UJRKULO6.js → work-comment-cmd-F3NRWKPZ.js} +9 -9
- package/dist/{work-logs-cmd-SCAHJXSP.js → work-logs-cmd-QF6P32FE.js} +9 -9
- package/dist/{work-open-pr-cmd-BGMHUQGD.js → work-open-pr-cmd-XE23JA3R.js} +10 -10
- package/dist/{work-pr-cmd-EDDRP5DK.js → work-pr-cmd-BH56GUKN.js} +9 -9
- package/dist/{work-stop-cmd-ADE5K6UX.js → work-stop-cmd-C3F5HNUO.js} +9 -9
- package/package.json +1 -1
- package/skill-pack/maintained/outerlayer-cli/SKILL.md +6 -5
- package/skill-pack/shipped.json +1 -0
- package/skill-pack/template/build/SKILL.md +1 -1
- package/dist/build-F5QWH7G5.js +0 -12
- package/dist/chunk-7RQ73DLO.js +0 -23
- package/dist/loop-3TJKFRN7.js +0 -78
|
@@ -1,48 +1,50 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { readsJobState, READ_JOB_STATE_FORMATS, jobStateFormatOf } from './chunk-ZVB57WI6.js';
|
|
4
|
-
import { senderPidfile } from './chunk-
|
|
5
|
-
import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-
|
|
6
|
-
import { writeDockerClientConfig } from './chunk-
|
|
7
|
-
import { installScrubContext } from './chunk-
|
|
8
|
-
import { ADDED_USER, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps,
|
|
9
|
-
import {
|
|
4
|
+
import { senderPidfile } from './chunk-Y7ZCHBYB.js';
|
|
5
|
+
import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-6KKM7VGZ.js';
|
|
6
|
+
import { writeDockerClientConfig } from './chunk-XS3FDWSZ.js';
|
|
7
|
+
import { installScrubContext } from './chunk-VS27BP3E.js';
|
|
8
|
+
import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, senderAliveScript, helperFirecrackerNote, HelperRefusal, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-R7SGBXUD.js';
|
|
9
|
+
import { describeCallFailure, resolveGoverningSource, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, removeKeptContext, formatDuration, retrySend, formatClock, keptContextTree } from './chunk-WSYXLLA5.js';
|
|
10
|
+
import { fdName } from './chunk-YB3CSYXX.js';
|
|
11
|
+
import { readBranchHead, fetchCommit, diffBetween } from './chunk-HWDYLXHH.js';
|
|
10
12
|
import { isSameProcess, startTimeOf } from './chunk-JBJTC3UU.js';
|
|
11
|
-
import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile,
|
|
12
|
-
import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-
|
|
13
|
-
import { waitForAgent, vmExecArgs } from './chunk-
|
|
14
|
-
import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-
|
|
15
|
-
import {
|
|
16
|
-
import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-6CGXSMKX.js';
|
|
13
|
+
import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR, COMMAND_DIR } from './chunk-EX5MQYEF.js';
|
|
14
|
+
import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-2BTFKNTR.js';
|
|
15
|
+
import { waitForAgent, vmExecArgs } from './chunk-XBPUTQ7E.js';
|
|
16
|
+
import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-GLUKDQS4.js';
|
|
17
|
+
import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-55GNQPO6.js';
|
|
17
18
|
import { planArtifactUpload } from './chunk-BUP5N3X6.js';
|
|
18
|
-
import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-
|
|
19
|
-
import { parseSize } from './chunk-
|
|
19
|
+
import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-EPPIISRD.js';
|
|
20
|
+
import { parseSize } from './chunk-YJLHUKYS.js';
|
|
21
|
+
import { resolvePackRoot, MAINTAINED_SKILLS } from './chunk-7OUOLGUV.js';
|
|
20
22
|
import { scrubText } from './chunk-QE3UQAHK.js';
|
|
21
23
|
import { readCloudConfig } from './chunk-PJDQPF5N.js';
|
|
22
|
-
import { resolvePackRoot } from './chunk-HBISTTG3.js';
|
|
23
24
|
import { parsePolicy } from './chunk-RKOTJQVG.js';
|
|
24
25
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
25
26
|
import { resolveVersion } from './chunk-RA3O54FC.js';
|
|
26
|
-
import { signerFor } from './chunk-
|
|
27
|
-
import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath } from './chunk-
|
|
28
|
-
import { claudeCredential, repositoriesOf, primaryOf, buildEnvironment,
|
|
27
|
+
import { signerFor } from './chunk-Y4OKEFAX.js';
|
|
28
|
+
import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath } from './chunk-RHAGBUL5.js';
|
|
29
|
+
import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, RELAY_PORT, repositoryPath, lifecycleWorkdir, checkEnvironment, EVAL_INPUT_DIR } from './chunk-2I3LIRZP.js';
|
|
29
30
|
import { RUNNER_WORDED_REASONS, UNKNOWN_TRACKING_REASON } from './chunk-JGD5TWQ2.js';
|
|
30
|
-
import { existsSync, statSync, appendFileSync, mkdirSync, chmodSync, writeFileSync, accessSync, constants, openSync, readFileSync, closeSync,
|
|
31
|
+
import { existsSync, statSync, appendFileSync, rmSync, mkdirSync, chmodSync, writeFileSync, accessSync, constants, openSync, readFileSync, closeSync, readdirSync, linkSync, lstatSync, fstatSync, readSync, realpathSync } from 'fs';
|
|
31
32
|
import { join, isAbsolute, dirname, delimiter, sep } from 'path';
|
|
32
|
-
import { spawn, spawnSync } from 'child_process';
|
|
33
|
-
import { randomBytes, createHash } from 'crypto';
|
|
34
33
|
import { once } from 'events';
|
|
35
34
|
import { createServer } from 'net';
|
|
35
|
+
import { spawn, spawnSync } from 'child_process';
|
|
36
|
+
import { randomBytes, createHash } from 'crypto';
|
|
36
37
|
import { pathToFileURL } from 'url';
|
|
37
38
|
|
|
38
39
|
createRequire(import.meta.url);
|
|
39
40
|
var PROBE_TIMEOUT_MS = 3e4;
|
|
40
41
|
var PROBE_BYTES = 256 * 1024;
|
|
41
|
-
|
|
42
|
+
function probeScript(dir, alive) {
|
|
43
|
+
return `d=${dir}
|
|
42
44
|
code=$(cat "$d/exit-code" 2>/dev/null | tr -d ' \\r\\n')
|
|
43
45
|
pid=$(cat "$d/command.pid" 2>/dev/null | tr -d ' \\r\\n')
|
|
44
46
|
alive=0
|
|
45
|
-
if [ -n "$pid" ] &&
|
|
47
|
+
if [ -n "$pid" ] && ${alive}; then alive=1; fi
|
|
46
48
|
size=$(wc -c < "$d/command.log" 2>/dev/null || echo 0)
|
|
47
49
|
size=$(echo $size)
|
|
48
50
|
echo "OL-COMMAND exit=$code alive=$alive size=$size"
|
|
@@ -51,8 +53,10 @@ if [ "$n" -gt "$2" ]; then n=$2; fi
|
|
|
51
53
|
if [ "$n" -gt 0 ]; then tail -c +$(($1 + 1)) "$d/command.log" | head -c "$n" | base64 | tr -d '\\n'; fi
|
|
52
54
|
echo
|
|
53
55
|
`;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
}
|
|
57
|
+
var PROBE_SCRIPT = probeScript(COMMAND_DIR, 'grep -qa build-command "/proc/$pid/cmdline" 2>/dev/null');
|
|
58
|
+
function probeArgv(offset, script = PROBE_SCRIPT) {
|
|
59
|
+
return ["/bin/sh", "-c", script, "probe", String(offset), String(PROBE_BYTES)];
|
|
56
60
|
}
|
|
57
61
|
function parseProbe(stdout) {
|
|
58
62
|
const [header = "", body = ""] = stdout.split("\n");
|
|
@@ -97,14 +101,19 @@ function judgeProbe(probe, missedBefore) {
|
|
|
97
101
|
if (probe.alive) return { kind: "running" };
|
|
98
102
|
return missedBefore ? { kind: "lost" } : { kind: "recheck" };
|
|
99
103
|
}
|
|
100
|
-
async function serveLease(socketPath, channel, makeServer = createServer) {
|
|
104
|
+
async function serveLease(socketPath, channel, makeServer = createServer, listenOn) {
|
|
101
105
|
const server = makeServer((socket) => channel.accept(socket));
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
if (listenOn === void 0) {
|
|
107
|
+
rmSync(socketPath, { force: true });
|
|
108
|
+
server.listen(socketPath);
|
|
109
|
+
await once(server, "listening");
|
|
110
|
+
} else {
|
|
111
|
+
await listenOn(server);
|
|
112
|
+
}
|
|
105
113
|
server.on("error", () => void 0);
|
|
106
114
|
return {
|
|
107
115
|
...channel,
|
|
116
|
+
listener: server,
|
|
108
117
|
close() {
|
|
109
118
|
channel.close();
|
|
110
119
|
server.close();
|
|
@@ -112,6 +121,57 @@ async function serveLease(socketPath, channel, makeServer = createServer) {
|
|
|
112
121
|
}
|
|
113
122
|
};
|
|
114
123
|
}
|
|
124
|
+
|
|
125
|
+
// src/runner/microvm/command-state.ts
|
|
126
|
+
var MICROVM_COMMAND_DIR = "/build/.command";
|
|
127
|
+
var SCRIPT = probeScript(MICROVM_COMMAND_DIR, '[ -d "/proc/$pid" ]');
|
|
128
|
+
var GUEST_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
|
|
129
|
+
var STOP_COMMAND_SCRIPT = `pid=$(cat ${MICROVM_COMMAND_DIR}/command.pid 2>/dev/null | tr -d ' \\r\\n'); [ -n "$pid" ] && kill -KILL "-$pid" 2>/dev/null; true`;
|
|
130
|
+
var EXEC_TIMEOUT_MS = 3e4;
|
|
131
|
+
var ABORT_GRACE_MS = 5e3;
|
|
132
|
+
async function withinTime(exec) {
|
|
133
|
+
const controller = new AbortController();
|
|
134
|
+
let abortTimer;
|
|
135
|
+
let graceTimer;
|
|
136
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
137
|
+
abortTimer = setTimeout(() => {
|
|
138
|
+
controller.abort();
|
|
139
|
+
graceTimer = setTimeout(() => reject(new Error("the guest did not end the exec after it was aborted")), ABORT_GRACE_MS);
|
|
140
|
+
}, EXEC_TIMEOUT_MS);
|
|
141
|
+
});
|
|
142
|
+
try {
|
|
143
|
+
return await Promise.race([exec(controller.signal), deadline]);
|
|
144
|
+
} finally {
|
|
145
|
+
clearTimeout(abortTimer);
|
|
146
|
+
clearTimeout(graceTimer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async function probeMicroVmCommand(runtime, state, offset) {
|
|
150
|
+
try {
|
|
151
|
+
const result = await withinTime(
|
|
152
|
+
(signal) => runtime.vm.exec(state.vsockPath, { argv: probeArgv(offset, SCRIPT), user: state.agentUser ?? ADDED_USER, cwd: "/", env: { PATH: GUEST_PATH } }, { signal })
|
|
153
|
+
);
|
|
154
|
+
return result.status === 0 ? parseProbe(result.stdout) : void 0;
|
|
155
|
+
} catch {
|
|
156
|
+
return void 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
var MAX_TAIL_READS2 = 8;
|
|
160
|
+
async function copyMicroVmLogTail(runtime, state, jobDir) {
|
|
161
|
+
for (let reads = 0; reads < MAX_TAIL_READS2; reads++) {
|
|
162
|
+
const offset = commandLogOffset(jobDir, state.commandLogBase);
|
|
163
|
+
const probe = await probeMicroVmCommand(runtime, state, offset);
|
|
164
|
+
if (probe === void 0) return false;
|
|
165
|
+
appendCommandLog(jobDir, probe.bytes);
|
|
166
|
+
if (probe.bytes.length === 0 || offset + probe.bytes.length >= probe.size) return true;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
async function stopMicroVmCommand(runtime, state) {
|
|
171
|
+
await withinTime(
|
|
172
|
+
(signal) => runtime.vm.exec(state.vsockPath, { argv: ["/bin/sh", "-c", STOP_COMMAND_SCRIPT], user: "root", cwd: "/", env: { PATH: GUEST_PATH } }, { signal })
|
|
173
|
+
);
|
|
174
|
+
}
|
|
115
175
|
function unitNameFor(buildId) {
|
|
116
176
|
return `outerlayer-build-${buildId}`;
|
|
117
177
|
}
|
|
@@ -256,6 +316,30 @@ async function microVmOomKills(runtime, state) {
|
|
|
256
316
|
if (state.jailed !== void 0) return helperKills(runtime, state);
|
|
257
317
|
return 0;
|
|
258
318
|
}
|
|
319
|
+
var socketNameOf = (file) => file.replace(/\.sock$/, "");
|
|
320
|
+
async function keepSockets(runtime, buildId, listeners, leaseServer, line, error) {
|
|
321
|
+
const store = runtime.vm.fdStore;
|
|
322
|
+
const status = await store.status();
|
|
323
|
+
if (!status.ok) {
|
|
324
|
+
line(`this build ends with its runner: ${status.reason}`);
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
const sockets = Object.entries(listeners);
|
|
328
|
+
if (leaseServer !== void 0) sockets.push([LEASE_LINK.socket, leaseServer]);
|
|
329
|
+
const stored = [];
|
|
330
|
+
try {
|
|
331
|
+
for (const [file, server] of sockets) {
|
|
332
|
+
const name = fdName(buildId, socketNameOf(file));
|
|
333
|
+
await store.push(name, server);
|
|
334
|
+
stored.push(name);
|
|
335
|
+
}
|
|
336
|
+
} catch (err) {
|
|
337
|
+
error(`this build ends with its runner: its sockets could not be kept for the next one: ${describeCallFailure(err)}`);
|
|
338
|
+
for (const name of stored) await store.remove(name).catch(() => void 0);
|
|
339
|
+
return [];
|
|
340
|
+
}
|
|
341
|
+
return stored;
|
|
342
|
+
}
|
|
259
343
|
async function provisionMicroVm(input) {
|
|
260
344
|
const { config, runtime, item, itemKey, jobDir, log, tokens } = input;
|
|
261
345
|
const { vm } = runtime;
|
|
@@ -363,9 +447,11 @@ async function provisionMicroVm(input) {
|
|
|
363
447
|
mkdirSync(buildDir2, { recursive: true, mode: 448 });
|
|
364
448
|
chmodSync(buildDir2, 448);
|
|
365
449
|
makeBuildsDirPrivate(buildDir2);
|
|
450
|
+
let services;
|
|
366
451
|
try {
|
|
367
452
|
const gitRemote = gitRemoteFor(runtime, { repositories, tokens, buildDir: buildDir2, log: (line) => log.line(`${tag} ${line}`) });
|
|
368
|
-
|
|
453
|
+
services = await startServicesFor(runtime, config, buildDir2, jobDir, itemKey, true, gitRemote);
|
|
454
|
+
runtime.tunnels.set(buildId, services);
|
|
369
455
|
} catch (err) {
|
|
370
456
|
return bail(`the tunnel could not start: ${describeCallFailure(err)}`);
|
|
371
457
|
}
|
|
@@ -376,11 +462,13 @@ async function provisionMicroVm(input) {
|
|
|
376
462
|
};
|
|
377
463
|
const links = vsockLinks({ destinations: config.build?.destinations?.length ?? 0, builtIns: true });
|
|
378
464
|
const served = input.leaseTimeLeftMs === void 0 ? links : [...links, LEASE_LINK];
|
|
465
|
+
let leaseServer;
|
|
379
466
|
if (input.leaseTimeLeftMs !== void 0) {
|
|
380
467
|
try {
|
|
381
468
|
const channel = createLeaseChannel(input.leaseTimeLeftMs);
|
|
382
469
|
const served2 = await serveLease(join(buildDir2, LEASE_LINK.socket), { ...channel, accept: (stream) => runtime.leases.get(buildId)?.accept(stream) });
|
|
383
470
|
runtime.leases.set(buildId, { ...channel, close: served2.close });
|
|
471
|
+
leaseServer = served2.listener;
|
|
384
472
|
} catch (err) {
|
|
385
473
|
return bail(`the lease stream could not start: ${describeCallFailure(err)}`);
|
|
386
474
|
}
|
|
@@ -430,6 +518,11 @@ async function provisionMicroVm(input) {
|
|
|
430
518
|
} catch (err) {
|
|
431
519
|
return bail(`the microVM did not start under the jailer: ${describeCallFailure(err)}`);
|
|
432
520
|
}
|
|
521
|
+
const kept = await keepSockets(runtime, buildId, services.listeners, leaseServer, (line) => log.line(`${tag} ${line}`), (line) => log.error(`${tag} ${line}`));
|
|
522
|
+
if (kept.length > 0) {
|
|
523
|
+
state.fdStore = kept;
|
|
524
|
+
input.save(state, environment);
|
|
525
|
+
}
|
|
433
526
|
} else {
|
|
434
527
|
try {
|
|
435
528
|
state.firecracker = await vm.firecracker.spawn({ binary: assets.firecracker, configPath, consolePath, cgroup: state.cgroup });
|
|
@@ -606,6 +699,38 @@ function microVmCommandLine(input) {
|
|
|
606
699
|
const { options, env } = vmExecFor(input, ["/bin/sh", "-c", commandWithShim(input.job, input.cmdline)]);
|
|
607
700
|
return { line: [process.execPath, input.cli, "vm-exec", ...vmExecArgs(options)].map(shellQuote).join(" "), options, env };
|
|
608
701
|
}
|
|
702
|
+
async function startMicroVmCommand(input) {
|
|
703
|
+
const state = input.job.microvm;
|
|
704
|
+
const env = buildEnvironment({
|
|
705
|
+
config: input.config,
|
|
706
|
+
item: input.job.item,
|
|
707
|
+
itemKey: input.job.itemKey,
|
|
708
|
+
branch: input.job.branch,
|
|
709
|
+
repository: state.repository,
|
|
710
|
+
repositories: input.job.repositories,
|
|
711
|
+
hostEnv: input.runtime.hostEnv,
|
|
712
|
+
containerEnv: state.containerEnv ?? {},
|
|
713
|
+
builtIns: state.builtIns === true,
|
|
714
|
+
identity: input.job.commitIdentity,
|
|
715
|
+
imageEnv: state.imageEnv
|
|
716
|
+
});
|
|
717
|
+
const started = await input.runtime.vm.exec(state.vsockPath, {
|
|
718
|
+
argv: ["/bin/sh", "-c", commandWithShim(input.job, input.cmdline)],
|
|
719
|
+
user: state.agentUser ?? ADDED_USER,
|
|
720
|
+
cwd: CHECKOUT_DIR,
|
|
721
|
+
env: execEnvironment(state.imageEnv, env),
|
|
722
|
+
detach: state.commandDir ?? MICROVM_COMMAND_DIR
|
|
723
|
+
});
|
|
724
|
+
if (started.status !== 0) {
|
|
725
|
+
const said = firstLine(started.stderr);
|
|
726
|
+
throw new Error(`the guest's exec agent exited ${started.status}${said === "" ? "" : `: ${said}`}`);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
async function endMicroVmCommand(runtime, state, jobDir, onError) {
|
|
730
|
+
if (!vmAlive(runtime, state)) return;
|
|
731
|
+
await copyMicroVmLogTail(runtime, state, jobDir).catch((err) => onError(`copying the end of the command's log failed: ${describeCallFailure(err)} \xB7 continuing`));
|
|
732
|
+
await stopMicroVmCommand(runtime, state).catch((err) => onError(`ending the command in the microVM failed: ${describeCallFailure(err)} \xB7 continuing`));
|
|
733
|
+
}
|
|
609
734
|
function microVmSenderCommand(input) {
|
|
610
735
|
const { options, env } = vmExecFor(input, ["outerlayer", "session-sender"]);
|
|
611
736
|
return { command: process.execPath, args: [input.cli, "vm-exec", ...vmExecArgs(options)], env };
|
|
@@ -954,6 +1079,7 @@ async function cleanupMicroVm(runtime, state, jobDir) {
|
|
|
954
1079
|
runtime.tunnels.delete(state.buildId);
|
|
955
1080
|
await tunnel.close();
|
|
956
1081
|
}
|
|
1082
|
+
for (const name of state.fdStore ?? []) await runtime.vm.fdStore.remove(name).catch(() => void 0);
|
|
957
1083
|
rmSync(state.buildDir, { recursive: true, force: true });
|
|
958
1084
|
if (failures.length > 0) throw new Error(failures.join("; "));
|
|
959
1085
|
}
|
|
@@ -961,7 +1087,9 @@ async function stopOrphanedMicroVms(input) {
|
|
|
961
1087
|
const stopped = [];
|
|
962
1088
|
const report = (line) => input.onError?.(line);
|
|
963
1089
|
const jailedByJobs = [];
|
|
1090
|
+
const kept = input.keep ?? /* @__PURE__ */ new Set();
|
|
964
1091
|
for (const { job } of input.jobs) {
|
|
1092
|
+
if (job.microvm !== void 0 && kept.has(job.microvm.buildId)) continue;
|
|
965
1093
|
const states = [job.microvm, job.checkMicrovm].filter((state) => state !== void 0);
|
|
966
1094
|
if (states.length === 0) continue;
|
|
967
1095
|
if (job.pid !== void 0 && job.start !== void 0 && isSameProcess(job.pid, job.start)) {
|
|
@@ -997,6 +1125,7 @@ async function stopOrphanedMicroVms(input) {
|
|
|
997
1125
|
return stopped;
|
|
998
1126
|
}
|
|
999
1127
|
for (const build of builds) {
|
|
1128
|
+
if (kept.has(build)) continue;
|
|
1000
1129
|
try {
|
|
1001
1130
|
await probe.client.stop(build);
|
|
1002
1131
|
} catch (err) {
|
|
@@ -1429,6 +1558,18 @@ function readInside(root, rel) {
|
|
|
1429
1558
|
return void 0;
|
|
1430
1559
|
}
|
|
1431
1560
|
}
|
|
1561
|
+
var MAINTAINED_BRIEF = /^\.(?:agents|outerlayer)\/skills\/(outerlayer-[a-z]+)\/([A-Za-z0-9_./-]+)$/;
|
|
1562
|
+
function readBrief(root, brief) {
|
|
1563
|
+
const own = readInside(root, brief);
|
|
1564
|
+
if (own !== void 0) return own;
|
|
1565
|
+
const match = MAINTAINED_BRIEF.exec(brief);
|
|
1566
|
+
if (match === null || match[2].split("/").includes("..") || !MAINTAINED_SKILLS.includes(match[1])) return void 0;
|
|
1567
|
+
try {
|
|
1568
|
+
return readFileSync(join(resolvePackRoot(), "maintained", match[1], match[2]), "utf8");
|
|
1569
|
+
} catch {
|
|
1570
|
+
return void 0;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1432
1573
|
function validatorFilesIn(root) {
|
|
1433
1574
|
const dir = join(root, VALIDATORS_DIR);
|
|
1434
1575
|
let names;
|
|
@@ -1453,7 +1594,7 @@ function checksIn(root, log, tag) {
|
|
|
1453
1594
|
const hostChecks = loaded.customs.filter((def) => def.runWhere === "host" && def.level !== "off" && def.declaresEmit !== null);
|
|
1454
1595
|
const checks = [];
|
|
1455
1596
|
for (const def of hostChecks) {
|
|
1456
|
-
if (def.judge !== void 0) checks.push({ name: def.declaresEmit, judge: { brief: def.judge.brief, text:
|
|
1597
|
+
if (def.judge !== void 0) checks.push({ name: def.declaresEmit, judge: { brief: def.judge.brief, text: readBrief(root, def.judge.brief) } });
|
|
1457
1598
|
else if (def.command !== void 0) checks.push({ name: def.declaresEmit, command: def.command });
|
|
1458
1599
|
}
|
|
1459
1600
|
return checks;
|
|
@@ -2564,6 +2705,9 @@ async function finishJob(job, jobDirPath, outcome, config, deps, ending) {
|
|
|
2564
2705
|
const build = job.container === void 0 ? void 0 : { state: job.container, runtime: deps.container ?? createContainerRuntime() };
|
|
2565
2706
|
const vmBuild = job.microvm === void 0 ? void 0 : { state: job.microvm, runtime: deps.container ?? createContainerRuntime() };
|
|
2566
2707
|
const commandMayRun = job.pid !== void 0 && isGroupAlive(job.pid) || isContainerTracked(job) && job.exitCode === void 0;
|
|
2708
|
+
if (vmBuild !== void 0 && isMicroVmTracked(job) && job.exitCode === void 0) {
|
|
2709
|
+
await endMicroVmCommand(vmBuild.runtime, vmBuild.state, jobDirPath, (line) => log.error(`${tag} ${line}`));
|
|
2710
|
+
}
|
|
2567
2711
|
if (build !== void 0 && commandMayRun) {
|
|
2568
2712
|
if (isContainerTracked(job) && build.state.stopped !== true) {
|
|
2569
2713
|
await copyCommandLogTail(build.runtime, build.state, jobDirPath).catch((err) => {
|
|
@@ -2637,8 +2781,11 @@ async function finishJob(job, jobDirPath, outcome, config, deps, ending) {
|
|
|
2637
2781
|
}
|
|
2638
2782
|
if (job.checkMicrovm !== void 0 && job.checksRan === true) {
|
|
2639
2783
|
try {
|
|
2640
|
-
|
|
2784
|
+
const runtime = deps.container ?? createContainerRuntime();
|
|
2785
|
+
const again = isMicroVmTracked(job) && outcome === "ok" && !job.cleanupRan;
|
|
2786
|
+
await cleanupMicroVm(runtime, job.checkMicrovm);
|
|
2641
2787
|
delete job.checkMicrovm;
|
|
2788
|
+
if (again) job.checksRan = false;
|
|
2642
2789
|
writeJobFile(jobFilePath, job);
|
|
2643
2790
|
} catch (err) {
|
|
2644
2791
|
log.error(`${tag} removing an earlier attempt's check environment failed: ${describeCallFailure(err)} \xB7 continuing`);
|
|
@@ -2947,6 +3094,15 @@ function unfinishedJobs(jobsDirPath) {
|
|
|
2947
3094
|
function isContainerTracked(job) {
|
|
2948
3095
|
return job.container?.tracking === "container";
|
|
2949
3096
|
}
|
|
3097
|
+
function isMicroVmTracked(job) {
|
|
3098
|
+
return job.microvm?.tracking === "microvm";
|
|
3099
|
+
}
|
|
3100
|
+
function isTracked(job) {
|
|
3101
|
+
return isContainerTracked(job) || isMicroVmTracked(job);
|
|
3102
|
+
}
|
|
3103
|
+
function trackingOf(job) {
|
|
3104
|
+
return job.container?.tracking ?? job.microvm?.tracking;
|
|
3105
|
+
}
|
|
2950
3106
|
function isReadable(job) {
|
|
2951
3107
|
return readsJobState(job, READ_JOB_STATE_FORMATS);
|
|
2952
3108
|
}
|
|
@@ -2956,10 +3112,10 @@ function listUnreadableJobs(jobsDirPath) {
|
|
|
2956
3112
|
function listTrackedJobs(jobsDirPath) {
|
|
2957
3113
|
return unfinishedJobs(jobsDirPath).flatMap(({ dirPath, job }) => {
|
|
2958
3114
|
if (!isReadable(job)) return [];
|
|
2959
|
-
const tracking = job
|
|
3115
|
+
const tracking = trackingOf(job);
|
|
2960
3116
|
if (tracking === void 0) return [];
|
|
2961
|
-
if (tracking === "container" && inTeardown(job)) return [];
|
|
2962
|
-
return [{ dirPath, job, known: tracking === "container" }];
|
|
3117
|
+
if ((tracking === "container" || tracking === "microvm") && inTeardown(job)) return [];
|
|
3118
|
+
return [{ dirPath, job, known: tracking === "container" || tracking === "microvm" }];
|
|
2963
3119
|
});
|
|
2964
3120
|
}
|
|
2965
3121
|
function listAdoptableJobs(jobsDirPath) {
|
|
@@ -2971,12 +3127,12 @@ async function recoverLostJobs(jobsDirPath, config, deps) {
|
|
|
2971
3127
|
const recovered = [];
|
|
2972
3128
|
for (const { dirPath, job } of unfinishedJobs(jobsDirPath)) {
|
|
2973
3129
|
if (!isReadable(job)) continue;
|
|
2974
|
-
const tracking = job
|
|
2975
|
-
if (tracking !== void 0 && tracking !== "container") {
|
|
3130
|
+
const tracking = trackingOf(job);
|
|
3131
|
+
if (tracking !== void 0 && tracking !== "container" && tracking !== "microvm") {
|
|
2976
3132
|
recovered.push(await finishJob(job, dirPath, "interrupted", config, deps, { reason: UNKNOWN_TRACKING_REASON }));
|
|
2977
3133
|
continue;
|
|
2978
3134
|
}
|
|
2979
|
-
if (tracking === "container" && !inTeardown(job)) continue;
|
|
3135
|
+
if ((tracking === "container" || tracking === "microvm") && !inTeardown(job)) continue;
|
|
2980
3136
|
const alive = job.pid !== void 0 && job.start !== void 0 && isSameProcess(job.pid, job.start);
|
|
2981
3137
|
if (alive) continue;
|
|
2982
3138
|
const recorded = outcomeFromExitCode(dirPath);
|
|
@@ -3144,4 +3300,4 @@ async function stopSender(input) {
|
|
|
3144
3300
|
}
|
|
3145
3301
|
}
|
|
3146
3302
|
|
|
3147
|
-
export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, execArgv, execCommandLine, finishJob, hookLimitsFor, hostCommandEnvironment, hostEnvironment, inTeardown, isContainerTracked, isGroupAlive, isIdle, isReadable, isTimedOut, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, listenOnBroker, microVmCommandLine, needsRenew, outcomeFromExitCode, probeCommand, provisionEnvironment, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, resolveHostBuild, restartSender, retryFailedReleases, runCommand, runHook, setStage, startHostServices, startSender, stopOrphanedMicroVms, unfinishedJobs, workdirProblem };
|
|
3303
|
+
export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, MICROVM_COMMAND_DIR, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, execArgv, execCommandLine, finishJob, hookLimitsFor, hostCommandEnvironment, hostEnvironment, inTeardown, isContainerTracked, isGroupAlive, isIdle, isMicroVmTracked, isReadable, isTimedOut, isTracked, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, listenOnBroker, microVmCommandLine, microVmOomKills, needsRenew, outcomeFromExitCode, probeCommand, probeMicroVmCommand, provisionEnvironment, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, resolveHostBuild, restartSender, retryFailedReleases, runCommand, runHook, serveLease, setStage, startHostServices, startMicroVmCommand, startSender, stopOrphanedMicroVms, unfinishedJobs, vmAlive, workdirProblem, writeGuestGhConfig };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { FD_SLOTS_PER_BUILD, FD_STORE_ENV } from './chunk-YB3CSYXX.js';
|
|
4
|
+
import { builtinKind } from './chunk-EPPIISRD.js';
|
|
5
|
+
import { parseSize } from './chunk-YJLHUKYS.js';
|
|
6
|
+
import { runnerDir } from './chunk-RHAGBUL5.js';
|
|
6
7
|
import { dirname } from 'path';
|
|
7
8
|
import { spawnSync } from 'child_process';
|
|
8
9
|
|
|
@@ -28,6 +29,7 @@ ${helperService === void 0 ? "" : `Wants=${helperService}
|
|
|
28
29
|
User=${unit.user}
|
|
29
30
|
ExecStart=${unit.execStart}
|
|
30
31
|
${unit.helper === void 0 ? "" : `Environment=OUTERLAYER_HELPER_SOCKET=${unit.helper.socket}
|
|
32
|
+
`}${unit.fdStore === void 0 ? "" : `Environment=${FD_STORE_ENV}=${unit.fdStore}
|
|
31
33
|
`}EnvironmentFile=-${escapeUnitPath(`${unit.configDir}/runner.env`)}
|
|
32
34
|
Restart=on-failure
|
|
33
35
|
RestartForceExitStatus=75
|
|
@@ -37,7 +39,10 @@ KillMode=mixed
|
|
|
37
39
|
TimeoutStopSec=${unit.timeLimitMinutes + STOP_MARGIN_MINUTES}min
|
|
38
40
|
OOMPolicy=continue
|
|
39
41
|
Delegate=yes
|
|
40
|
-
|
|
42
|
+
${unit.fdStore === void 0 ? "" : `NotifyAccess=all
|
|
43
|
+
FileDescriptorStoreMax=${unit.fdStore}
|
|
44
|
+
FileDescriptorStorePreserve=yes
|
|
45
|
+
`}
|
|
41
46
|
[Install]
|
|
42
47
|
WantedBy=multi-user.target
|
|
43
48
|
`;
|
|
@@ -147,7 +152,9 @@ function installService(request, deps) {
|
|
|
147
152
|
execStart: request.execStart,
|
|
148
153
|
timeLimitMinutes: request.timeLimitMinutes,
|
|
149
154
|
docker: kind === "container" || kind === "vm" || builtinKind(request.hooks.cleanup) === "container" || builtinKind(request.hooks.cleanup) === "vm",
|
|
150
|
-
...request.helperSocket !== void 0 && request.helperUnit !== void 0 ? { helper: { unit: request.helperUnit, socket: request.helperSocket } } : {}
|
|
155
|
+
...request.helperSocket !== void 0 && request.helperUnit !== void 0 ? { helper: { unit: request.helperUnit, socket: request.helperSocket } } : {},
|
|
156
|
+
// A microVM build under the helper keeps its sockets in the descriptor store, so the runner can restart and the build goes on.
|
|
157
|
+
...kind === "vm" && request.helperSocket !== void 0 && request.helperUnit !== void 0 ? { fdStore: Math.max(1, request.concurrency) * FD_SLOTS_PER_BUILD } : {}
|
|
151
158
|
});
|
|
152
159
|
if (request.print === true) return outcome(true, "printed", [], unit);
|
|
153
160
|
if (own) return outcome(false, "refused", [OWN_HOOKS]);
|
|
@@ -13,13 +13,20 @@ function templateClassLine(version) {
|
|
|
13
13
|
return `<!-- yours to edit. Copied once from the default template by outerlayer init ${version}; never overwritten. -->`;
|
|
14
14
|
}
|
|
15
15
|
function maintainedClassLine(version, base) {
|
|
16
|
+
if (base === MACHINE_SKILL_PATH) return `<!-- maintained by OuterLayer ${version}. Edits are overwritten by the next outerlayer command. -->`;
|
|
16
17
|
const command = base === AGENTS_SKILLS_BASE ? "outerlayer init --update" : "outerlayer context emit";
|
|
17
18
|
return `<!-- maintained by OuterLayer ${version}. Edits are overwritten on the next ${command}. -->`;
|
|
18
19
|
}
|
|
19
20
|
var OUTERLAYER_SKILLS_BASE = ".outerlayer/skills";
|
|
20
21
|
var AGENTS_SKILLS_BASE = ".agents/skills";
|
|
22
|
+
var MACHINE_SKILL_PATH = "~/.agents/skills";
|
|
23
|
+
var MAINTAINED_SKILL_PATH_IN_PACK = new RegExp(`${OUTERLAYER_SKILLS_BASE.replace(".", "\\.")}/(outerlayer-[a-z]+)/`, "g");
|
|
21
24
|
function rewriteSkillPaths(content, base) {
|
|
22
|
-
|
|
25
|
+
if (base === OUTERLAYER_SKILLS_BASE) return content;
|
|
26
|
+
if (base === MACHINE_SKILL_PATH) {
|
|
27
|
+
return content.replace(MAINTAINED_SKILL_PATH_IN_PACK, `${MACHINE_SKILL_PATH}/$1/`).split(`${OUTERLAYER_SKILLS_BASE}/`).join(`${AGENTS_SKILLS_BASE}/`);
|
|
28
|
+
}
|
|
29
|
+
return content.split(`${OUTERLAYER_SKILLS_BASE}/`).join(`${base}/`);
|
|
23
30
|
}
|
|
24
31
|
function restoreSkillPaths(content, base) {
|
|
25
32
|
return base === OUTERLAYER_SKILLS_BASE ? content : content.split(`${base}/`).join(`${OUTERLAYER_SKILLS_BASE}/`);
|
|
@@ -74,6 +81,9 @@ function loadTemplateFiles(packRoot = resolvePackRoot(), version = resolvePackag
|
|
|
74
81
|
function loadMaintainedFiles(packRoot = resolvePackRoot(), version = resolvePackageVersion(), base = OUTERLAYER_SKILLS_BASE) {
|
|
75
82
|
return loadClass(packRoot, "maintained", MAINTAINED_SKILLS, version, base);
|
|
76
83
|
}
|
|
84
|
+
function loadMachineSkillFiles(packRoot = resolvePackRoot(), version = resolvePackageVersion()) {
|
|
85
|
+
return loadClass(packRoot, "maintained", MAINTAINED_SKILLS, version, MACHINE_SKILL_PATH).map((file) => ({ ...file, path: file.path.slice(skillDir(file.skill, MACHINE_SKILL_PATH).length + 1) }));
|
|
86
|
+
}
|
|
77
87
|
function writeMaintainedFiles(repoRoot, files) {
|
|
78
88
|
const created = [];
|
|
79
89
|
const rewritten = [];
|
|
@@ -92,19 +102,20 @@ function maintainedFilesForExistingSkills(repoRoot, files, base = OUTERLAYER_SKI
|
|
|
92
102
|
(file) => existsSync(join(repoRoot, skillDir(file.skill, base))) || formerNameExists(repoRoot, file.skill, base) || requiredByBuild(repoRoot, file.skill, base)
|
|
93
103
|
);
|
|
94
104
|
}
|
|
105
|
+
var RELATIVE_CORE = "../outerlayer-build/SKILL.md";
|
|
95
106
|
function namesCore(text) {
|
|
96
107
|
return text.includes("outerlayer-build");
|
|
97
108
|
}
|
|
98
109
|
function requiredByBuild(repoRoot, skill, base) {
|
|
99
110
|
if (skill !== "outerlayer-build") return false;
|
|
100
|
-
const named = (file) => {
|
|
111
|
+
const named = (file, pattern = "outerlayer-build") => {
|
|
101
112
|
try {
|
|
102
|
-
return
|
|
113
|
+
return readFileSync(file, "utf8").includes(pattern);
|
|
103
114
|
} catch {
|
|
104
115
|
return false;
|
|
105
116
|
}
|
|
106
117
|
};
|
|
107
|
-
if (named(join(repoRoot, skillDir("build", base), "SKILL.md"))) return true;
|
|
118
|
+
if (named(join(repoRoot, skillDir("build", base), "SKILL.md"), RELATIVE_CORE)) return true;
|
|
108
119
|
const dir = join(repoRoot, ".outerlayer", "validators");
|
|
109
120
|
try {
|
|
110
121
|
return readdirSync(dir).some((name) => name.endsWith(".yaml") && named(join(dir, name)));
|
|
@@ -119,6 +130,10 @@ var FORMER_MAINTAINED_NAMES = {
|
|
|
119
130
|
outerlayer: "outerlayer-cli"
|
|
120
131
|
};
|
|
121
132
|
var MAINTAINED_LINE = /^<!-- maintained by OuterLayer \S+?\. /m;
|
|
133
|
+
var MAINTAINED_LINE_VERSION = /^<!-- maintained by OuterLayer (\S+?)\. /m;
|
|
134
|
+
function maintainedLineVersion(text) {
|
|
135
|
+
return MAINTAINED_LINE_VERSION.exec(text)?.[1];
|
|
136
|
+
}
|
|
122
137
|
function isMaintainedCopy(repoRoot, skill, base = OUTERLAYER_SKILLS_BASE) {
|
|
123
138
|
try {
|
|
124
139
|
return MAINTAINED_LINE.test(readFileSync(join(repoRoot, skillDir(skill, base), "SKILL.md"), "utf8"));
|
|
@@ -130,4 +145,4 @@ function formerNameExists(repoRoot, skill, base) {
|
|
|
130
145
|
return Object.entries(FORMER_MAINTAINED_NAMES).some(([former, current]) => current === skill && isMaintainedCopy(repoRoot, former, base));
|
|
131
146
|
}
|
|
132
147
|
|
|
133
|
-
export { AGENTS_SKILLS_BASE, FORMER_MAINTAINED_NAMES, MAINTAINED_SKILLS, OUTERLAYER_SKILLS_BASE, TEMPLATE_SKILLS, isMaintainedCopy, loadMaintainedFiles, loadTemplateFiles, maintainedFilesForExistingSkills, namesCore, resolvePackRoot, restoreSkillPaths, rewriteSkillPaths, skillDir, writeMaintainedFiles };
|
|
148
|
+
export { AGENTS_SKILLS_BASE, FORMER_MAINTAINED_NAMES, MACHINE_SKILL_PATH, MAINTAINED_SKILLS, OUTERLAYER_SKILLS_BASE, TEMPLATE_SKILLS, isMaintainedCopy, loadMachineSkillFiles, loadMaintainedFiles, loadTemplateFiles, maintainedFilesForExistingSkills, maintainedLineVersion, namesCore, resolvePackRoot, restoreSkillPaths, rewriteSkillPaths, skillDir, writeMaintainedFiles };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-RHAGBUL5.js';
|
|
4
4
|
import { readFileSync, mkdirSync, writeFileSync, renameSync } from 'fs';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { MIN_ENGINE_MAJOR } from './chunk-
|
|
4
|
-
import { runnerImageVersion } from './chunk-
|
|
5
|
-
import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-
|
|
3
|
+
import { MIN_ENGINE_MAJOR } from './chunk-R7SGBXUD.js';
|
|
4
|
+
import { runnerImageVersion } from './chunk-M3MHHIUW.js';
|
|
5
|
+
import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-2BTFKNTR.js';
|
|
6
6
|
import { spawnSync } from 'child_process';
|
|
7
7
|
import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
|
|
8
8
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { removeRetiredSkills } from './chunk-
|
|
4
|
-
import { defaultFetch, resolveGatewayCredentials } from './chunk-
|
|
3
|
+
import { removeRetiredSkills } from './chunk-MHX7YX7Y.js';
|
|
4
|
+
import { defaultFetch, resolveGatewayCredentials } from './chunk-BWH36FOC.js';
|
|
5
5
|
import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
|
|
6
|
-
import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-
|
|
6
|
+
import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-7OUOLGUV.js';
|
|
7
7
|
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
8
8
|
import { writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, writeContextManifest, SOURCE_CACHE_TTL_SUCCESS_MS, readSourceCache, isSourceCacheFresh, clearDegraded } from './chunk-YQR6E6OV.js';
|
|
9
9
|
import { normalizeRepoName, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-RKOTJQVG.js';
|
|
10
10
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
11
|
-
import { withTokenHeader } from './chunk-
|
|
11
|
+
import { withTokenHeader } from './chunk-2I3LIRZP.js';
|
|
12
12
|
import { execFileSync } from 'child_process';
|
|
13
13
|
import { existsSync, mkdirSync, writeFileSync, chmodSync, lstatSync, readFileSync, copyFileSync } from 'fs';
|
|
14
14
|
import { isAbsolute, join, dirname } from 'path';
|
|
@@ -5,7 +5,7 @@ import { readCloudConfigStrict, readCloudConfig, cloudConfigPath } from './chunk
|
|
|
5
5
|
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
6
6
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
7
7
|
import { resolvePackageVersion } from './chunk-RA3O54FC.js';
|
|
8
|
-
import { signRunnerRequest, signerFor } from './chunk-
|
|
8
|
+
import { signRunnerRequest, signerFor } from './chunk-Y4OKEFAX.js';
|
|
9
9
|
|
|
10
10
|
createRequire(import.meta.url);
|
|
11
11
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { isSameProcess } from './chunk-JBJTC3UU.js';
|
|
4
|
-
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
5
|
-
import { existsSync, readFileSync,
|
|
4
|
+
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-RHAGBUL5.js';
|
|
5
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'fs';
|
|
6
6
|
import { dirname } from 'path';
|
|
7
7
|
|
|
8
8
|
createRequire(import.meta.url);
|
|
@@ -11,7 +11,7 @@ function readPidFile(path) {
|
|
|
11
11
|
try {
|
|
12
12
|
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
13
13
|
if (typeof parsed.pid !== "number" || typeof parsed.start !== "string") return null;
|
|
14
|
-
return { pid: parsed.pid, start: parsed.start };
|
|
14
|
+
return { pid: parsed.pid, start: parsed.start, ...parsed.leaves === true ? { leaves: true } : {} };
|
|
15
15
|
} catch {
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
@@ -39,4 +39,4 @@ function claimPidFile(path, self, isSameProcessFn = isSameProcess) {
|
|
|
39
39
|
writePidFile(path, self);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export { RunnerAlreadyRunningError, claimPidFile, readPidFile, releasePidFile };
|
|
42
|
+
export { RunnerAlreadyRunningError, claimPidFile, readPidFile, releasePidFile, writePidFile };
|