@outerlayer/cli 0.6.0 → 0.8.0
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 +34 -0
- package/README.md +15 -5
- package/dist/{agent-setup-USZ2SAXC.js → agent-setup-C7PLRXZO.js} +7 -6
- package/dist/{build-PAEKVYVK.js → build-MS34XEGN.js} +3 -1
- package/dist/build-info.json +1 -1
- package/dist/builder-G52A6GW2.js +13 -0
- package/dist/{check-CCVPBN7A.js → check-FOF3PUKI.js} +35 -26
- package/dist/{chunk-ZILGTTY6.js → chunk-3S4P55NE.js} +3 -3
- package/dist/{chunk-MIGEDH5P.js → chunk-4A5E2G4E.js} +9 -9
- package/dist/chunk-4ACZCY4I.js +39 -0
- package/dist/{chunk-OIRNH6UO.js → chunk-5FWNEQNZ.js} +3 -3
- package/dist/{chunk-BNMCXPG7.js → chunk-5QLNZGAQ.js} +12 -3
- package/dist/chunk-5TNS3PL7.js +263 -0
- package/dist/chunk-7RQ73DLO.js +23 -0
- package/dist/{chunk-VMJ3MMBX.js → chunk-7VNURP6M.js} +538 -46
- package/dist/{chunk-EMY4I27X.js → chunk-7ZR5UPMB.js} +555 -5
- package/dist/{chunk-UMFWVGJO.js → chunk-AIL2R4SI.js} +4 -3
- package/dist/{chunk-NQXFAGHU.js → chunk-AX23QKHS.js} +7 -3
- package/dist/{chunk-RZSF5B46.js → chunk-CM5QTKM4.js} +152 -158
- package/dist/chunk-CX22S5BA.js +45 -0
- package/dist/{chunk-H5NCNVDA.js → chunk-EV3M3EH7.js} +2 -2
- package/dist/{chunk-ANK2B36Y.js → chunk-GAYWY4GI.js} +6190 -28615
- package/dist/chunk-HKMPVPO7.js +55 -0
- package/dist/{chunk-43J3M6KB.js → chunk-IJBVPLZZ.js} +91 -39
- package/dist/{chunk-PMAMOSTP.js → chunk-ILEA3YHM.js} +85 -25
- package/dist/{chunk-MXB5VB4Y.js → chunk-IRCBTGWF.js} +6 -6
- package/dist/{chunk-OUUINEYB.js → chunk-JKIWMRFH.js} +1 -1
- package/dist/{chunk-FA2BOX4O.js → chunk-JPR2WHHF.js} +1 -1
- package/dist/{chunk-IASWYRVG.js → chunk-K35RW5HP.js} +4 -1
- package/dist/{chunk-ZMYPLFG3.js → chunk-M3SQ4YGD.js} +1 -1
- package/dist/{chunk-4NLKY4WR.js → chunk-NALVDFIS.js} +2 -2
- package/dist/{chunk-AUFG23AA.js → chunk-OD2VTIHN.js} +19 -47
- package/dist/{chunk-JWOQNNN2.js → chunk-OEK4JEB3.js} +33 -4
- package/dist/chunk-PTW6W5NR.js +127 -0
- package/dist/{chunk-3DD6AOWC.js → chunk-PWBILI5P.js} +28 -3
- package/dist/{chunk-B2G7JHHB.js → chunk-R7STSBLC.js} +1 -1
- package/dist/{chunk-YYYXRJUW.js → chunk-TI7B7UEO.js} +1 -1
- package/dist/{chunk-Z62HNKEJ.js → chunk-TTNFGMHO.js} +72 -54
- package/dist/{chunk-RBOMWNOG.js → chunk-TUUMW4TC.js} +2 -2
- package/dist/{chunk-774HEQL6.js → chunk-U3GOI2B4.js} +91 -8
- package/dist/{chunk-F6GFZXZ3.js → chunk-UXYLWVTQ.js} +1 -18
- package/dist/{chunk-WO2BXCTQ.js → chunk-VXLJORHL.js} +1 -1
- package/dist/{chunk-CBPPJSAR.js → chunk-WVGSB3Z2.js} +2 -2
- package/dist/chunk-YNJEOGDL.js +22434 -0
- package/dist/{chunk-W4SQCOZU.js → chunk-ZOAEPWGL.js} +1 -1
- package/dist/{chunk-3DEVYTNQ.js → chunk-ZYHKJKSU.js} +1 -1
- package/dist/{chunk-WIOZAJ2W.js → chunk-ZZXLM64C.js} +1 -1
- package/dist/{cli-7WCNPBYC.js → cli-AOJPAVFX.js} +109 -81
- package/dist/{command-ARFK3OYF.js → command-SY3SVLAI.js} +67 -27
- package/dist/config-Z3USDBLU.js +11 -0
- package/dist/{connect-cmd-PCESZLTR.js → connect-cmd-PNZ6IJLJ.js} +4 -4
- package/dist/{context-adopt-G5JAELE7.js → context-adopt-CE4KDXS3.js} +5 -4
- package/dist/{context-materialize-3HLPZAF6.js → context-materialize-QL33HDJN.js} +5 -4
- package/dist/{dist-RDLP4GGJ.js → dist-3ZTZF2TP.js} +2 -1
- package/dist/docker-676FD3CQ.js +15 -0
- package/dist/{doctor-VOMYOHQU.js → doctor-WR6TRPSU.js} +49 -19
- package/dist/{emit-artifact-cmd-TBF46VXZ.js → emit-artifact-cmd-AVM4YXMQ.js} +11 -4
- package/dist/{emit-cmd-DCERAU27.js → emit-cmd-2QRMYPYO.js} +4 -3
- package/dist/{emit-criteria-cmd-3427XKFW.js → emit-criteria-cmd-LDBE4YDS.js} +10 -1
- package/dist/{emit-finding-cmd-GSI75K36.js → emit-finding-cmd-6R5WBPCH.js} +12 -1
- package/dist/{emit-result-cmd-3PRQKB55.js → emit-result-cmd-2DMN6O6U.js} +13 -6
- package/dist/{exec-client-4XGXV3XN.js → exec-client-NPYNUAF3.js} +4 -3
- package/dist/{guest-init-GENRHNP7.js → guest-init-JWNNAH2H.js} +4 -3
- package/dist/{hook-fast-NJBBZQ5Q.js → hook-fast-XBOZ3N6L.js} +1 -1
- package/dist/{import-capture-cmd-AVZ4VIVJ.js → import-capture-cmd-T4556ELW.js} +3 -2
- package/dist/{import-ruler-cmd-GUHL6IY5.js → import-ruler-cmd-SG3UVGI7.js} +2 -1
- package/dist/index.js +3 -3
- package/dist/init-KDK5QLQZ.js +46 -0
- package/dist/{init-OHYFIKZD.js → init-R2FJ5KNS.js} +35 -21
- package/dist/{init-cmd-HMFNIFPI.js → init-cmd-BYZYAJ5P.js} +10 -9
- package/dist/{install-DSUZE2TJ.js → install-FHTVJZS6.js} +7 -5
- package/dist/{install-cmd-453C7IZT.js → install-cmd-DCF7TVXD.js} +3 -2
- package/dist/{logs-7RYUH5A6.js → logs-H55NWW4H.js} +1 -0
- package/dist/{loop-UAJB34KA.js → loop-AG3PLXPO.js} +35 -26
- package/dist/machine-LV6WBRRK.js +45 -0
- package/dist/{session-sender-ED26V45B.js → session-sender-Q5HAMOL2.js} +6 -5
- package/dist/{starter-pack-LIZYMKYQ.js → starter-pack-MUXMAU4S.js} +4 -3
- package/dist/{status-6WNXX2O7.js → status-HH4OSOHR.js} +29 -20
- package/dist/{sync-cmd-YONVGUYS.js → sync-cmd-CAEPJR7B.js} +5 -4
- package/dist/{watch-HHKAF26L.js → watch-LAAZFBHH.js} +5 -4
- package/dist/{work-claim-cmd-LXBZTMJA.js → work-claim-cmd-ARIYZARE.js} +15 -7
- package/dist/{work-cmd-OVNF44FY.js → work-cmd-B3FOXZAL.js} +9 -3
- package/dist/{work-comment-cmd-6DGQNTAH.js → work-comment-cmd-O5WGRI6K.js} +9 -3
- package/dist/{work-open-pr-cmd-FCZHFHZS.js → work-open-pr-cmd-M6CQW7KW.js} +10 -4
- package/dist/{work-pr-cmd-QJJVHZDC.js → work-pr-cmd-C4YEGKD6.js} +9 -2
- package/package.json +1 -1
- package/skill-pack/template/build/scripts/record-criteria.mjs +2 -1
- package/dist/chunk-7DBI6SNT.js +0 -55
- package/dist/config-HL2AIR3K.js +0 -9
- package/dist/docker-NEGDLU6D.js +0 -7
- package/dist/init-WVR4BZQ4.js +0 -36
- package/dist/machine-2JOWGRSZ.js +0 -35
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
|
|
4
|
+
createRequire(import.meta.url);
|
|
5
|
+
|
|
6
|
+
// src/runner/commit-identity.ts
|
|
7
|
+
var NOREPLY_SUFFIX = "@users.noreply.github.com";
|
|
8
|
+
var MAX_LENGTH = 200;
|
|
9
|
+
function parseIdentity(value) {
|
|
10
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
11
|
+
const { name, email } = value;
|
|
12
|
+
if (typeof name !== "string" || typeof email !== "string") return void 0;
|
|
13
|
+
if (name.trim() === "" || name.length > MAX_LENGTH || /[\r\n\0<>]/.test(name)) return void 0;
|
|
14
|
+
if (email.length > MAX_LENGTH || !email.endsWith(NOREPLY_SUFFIX) || /[\s\0<>]/.test(email) || email.length === NOREPLY_SUFFIX.length) return void 0;
|
|
15
|
+
return { name, email };
|
|
16
|
+
}
|
|
17
|
+
function parseClaimIdentity(data) {
|
|
18
|
+
const author = parseIdentity(data.commitAuthor);
|
|
19
|
+
if (author === void 0) return void 0;
|
|
20
|
+
const coAuthor = parseIdentity(data.coAuthor);
|
|
21
|
+
return coAuthor === void 0 ? { author } : { author, coAuthor };
|
|
22
|
+
}
|
|
23
|
+
function authorEnvironment(identity) {
|
|
24
|
+
if (identity === void 0) return {};
|
|
25
|
+
return {
|
|
26
|
+
GIT_AUTHOR_NAME: identity.name,
|
|
27
|
+
GIT_AUTHOR_EMAIL: identity.email,
|
|
28
|
+
GIT_COMMITTER_NAME: identity.name,
|
|
29
|
+
GIT_COMMITTER_EMAIL: identity.email
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function configCount(env) {
|
|
33
|
+
const raw = String(env.GIT_CONFIG_COUNT);
|
|
34
|
+
return /^[0-9]+$/.test(raw) ? Number(raw) : 0;
|
|
35
|
+
}
|
|
36
|
+
function withGitConfig(env, key, value) {
|
|
37
|
+
const at = configCount(env);
|
|
38
|
+
return {
|
|
39
|
+
...env,
|
|
40
|
+
GIT_CONFIG_COUNT: String(at + 1),
|
|
41
|
+
[`GIT_CONFIG_KEY_${at}`]: key,
|
|
42
|
+
[`GIT_CONFIG_VALUE_${at}`]: value
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function withHooksPath(env, dir) {
|
|
46
|
+
return withGitConfig(env, "core.hooksPath", dir);
|
|
47
|
+
}
|
|
48
|
+
function commitIdentityRecord(identity) {
|
|
49
|
+
return {
|
|
50
|
+
author: identity === void 0 ? "host" : "app",
|
|
51
|
+
coAuthor: identity?.coAuthor !== void 0 && identity.hooksPath !== void 0 ? "credited" : "none"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { authorEnvironment, commitIdentityRecord, parseClaimIdentity, withGitConfig, withHooksPath };
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-ABIWDUMS.js';
|
|
4
|
-
import {
|
|
5
|
-
import { LEASE_SECONDS, releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startSender, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, ALREADY_RELEASED } from './chunk-VMJ3MMBX.js';
|
|
4
|
+
import { LEASE_SECONDS, releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startSender, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, ALREADY_RELEASED } from './chunk-7VNURP6M.js';
|
|
6
5
|
import { writeJobFile, readJobFile, readJobFileChecked } from './chunk-T6OIJQRT.js';
|
|
7
6
|
import { RUNNER_PROTOCOL } from './chunk-AIW6GLET.js';
|
|
8
7
|
import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-UGP76IZ5.js';
|
|
9
|
-
import { placeholderQueues, placeholderProblem } from './chunk-
|
|
8
|
+
import { placeholderQueues, placeholderProblem } from './chunk-IRCBTGWF.js';
|
|
9
|
+
import { readMarker, currentVersion, removeMarker, writeMarker, entryIn, versionDir, switchCurrent, cleanVersions, isInLayout, startedThroughCurrent, stagingDir } from './chunk-TI7B7UEO.js';
|
|
10
10
|
import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
|
|
11
11
|
import { RepoFilter } from './chunk-TBT347UY.js';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, measureDisk, createRunnerLog, setUpRunnerCgroup, ensureTunnel, keepGhConfigCurrent, createContainerRuntime, formatClock } from './chunk-CM5QTKM4.js';
|
|
13
|
+
import { checkFit } from './chunk-JKIWMRFH.js';
|
|
14
14
|
import { startTimeOf, claimPidFile, readPidFile, isSameProcess, releasePidFile } from './chunk-N5FOE5PS.js';
|
|
15
|
-
import { spawnRun } from './chunk-
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
15
|
+
import { spawnRun } from './chunk-U3GOI2B4.js';
|
|
16
|
+
import { builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, BUILD_LABEL, RUNNER_LABEL } from './chunk-5TNS3PL7.js';
|
|
17
|
+
import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-5QLNZGAQ.js';
|
|
18
|
+
import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind } from './chunk-PWBILI5P.js';
|
|
19
|
+
import { exceedsDisk } from './chunk-7RQ73DLO.js';
|
|
20
|
+
import { sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-OD2VTIHN.js';
|
|
21
|
+
import { parseClaimIdentity } from './chunk-HKMPVPO7.js';
|
|
20
22
|
import { resolveVersion } from './chunk-RA3O54FC.js';
|
|
21
23
|
import { loadHostKey, ensureHostKey, signerFor } from './chunk-M5POMKKW.js';
|
|
22
24
|
import { RUNNER_DIR_MODE, runnerDir, buildDir, attemptStamp, jobDir, jobsDir, pidFilePath, spoolDir, RUNNER_FILE_MODE, rootfsDir } from './chunk-ZM2IMMYN.js';
|
|
@@ -36,7 +38,7 @@ function openKvm() {
|
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
function realBlockedProbes() {
|
|
39
|
-
return { env: process.env, kvm: openKvm, totalMemoryBytes: totalmem };
|
|
41
|
+
return { env: process.env, kvm: openKvm, totalMemoryBytes: totalmem, imageBuilder: "unknown" };
|
|
40
42
|
}
|
|
41
43
|
var DEFAULT_BUILD_MEMORY = "8g";
|
|
42
44
|
function checkBlocked(config, probes) {
|
|
@@ -60,6 +62,13 @@ function checkBlocked(config, probes) {
|
|
|
60
62
|
reason: "the runner cannot open /dev/kvm, so builtin:vm cannot start a microVM. Add the runner's account to the kvm group, then restart the service, because a service reads its groups only when it starts"
|
|
61
63
|
};
|
|
62
64
|
}
|
|
65
|
+
if (kind === "container" || kind === "vm") {
|
|
66
|
+
const builder = probes.imageBuilder;
|
|
67
|
+
if (builder === "unknown") {
|
|
68
|
+
return { reason: "the runner is still preparing its image builder, the container that limits image builds to runner.build.memory, so it claims nothing yet" };
|
|
69
|
+
}
|
|
70
|
+
if (builder !== "usable") return { reason: `${builder.problem}. The runner takes work again once its image builder works` };
|
|
71
|
+
}
|
|
63
72
|
if (kind !== "own" && claudeCredential(probes.env) === void 0) {
|
|
64
73
|
return {
|
|
65
74
|
reason: "there is no Claude credential in the runner's environment. Put CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`) or ANTHROPIC_API_KEY in the runner.env beside the config, then restart the service"
|
|
@@ -670,8 +679,9 @@ function createHousekeepingDocker(deps) {
|
|
|
670
679
|
if (result.status !== 0) throw failure(result, `docker rmi ${id}`);
|
|
671
680
|
},
|
|
672
681
|
async builderPrune(keepBytes) {
|
|
673
|
-
const result = await run("docker", ["
|
|
674
|
-
if (result.status !== 0
|
|
682
|
+
const result = await run("docker", ["buildx", "prune", "--builder", deps.builder, "--force", "--max-used-space", String(keepBytes)]);
|
|
683
|
+
if (result.status !== 0 && /no builder .* found/i.test(result.stderr)) return { freedBytes: 0 };
|
|
684
|
+
if (result.status !== 0) throw failure(result, "docker buildx prune");
|
|
675
685
|
return { freedBytes: parsePrunedBytes(result.stdout) };
|
|
676
686
|
}
|
|
677
687
|
};
|
|
@@ -690,7 +700,7 @@ function selectJobDirs(entries, nowMs, keepDays) {
|
|
|
690
700
|
function liveBuildIds(jobs) {
|
|
691
701
|
const ids = /* @__PURE__ */ new Set();
|
|
692
702
|
for (const job of jobs) {
|
|
693
|
-
for (const id of [job.container?.buildId, job.microvm?.buildId, job.build?.buildId]) if (id !== void 0) ids.add(id);
|
|
703
|
+
for (const id of [job.container?.buildId, job.microvm?.buildId, job.build?.buildId, job.checkContainer?.buildId]) if (id !== void 0) ids.add(id);
|
|
694
704
|
}
|
|
695
705
|
return ids;
|
|
696
706
|
}
|
|
@@ -842,7 +852,7 @@ async function runHousekeeping(options) {
|
|
|
842
852
|
try {
|
|
843
853
|
const pruned = await docker.builderPrune(options.buildCacheMax);
|
|
844
854
|
freed += pruned.freedBytes;
|
|
845
|
-
log.line(`housekeeping: pruned the build cache down to ${formatBytes(options.buildCacheMax)}, freed ${formatBytes(pruned.freedBytes)}`);
|
|
855
|
+
log.line(`housekeeping: pruned the image builder's build cache down to ${formatBytes(options.buildCacheMax)}, freed ${formatBytes(pruned.freedBytes)}`);
|
|
846
856
|
} catch (err) {
|
|
847
857
|
log.error(`housekeeping: the build cache could not be pruned: ${describeCallFailure(err)}`);
|
|
848
858
|
}
|
|
@@ -1136,10 +1146,39 @@ async function tick(state) {
|
|
|
1136
1146
|
}
|
|
1137
1147
|
await sendTickHeartbeat(state, state.lastWorkRequest);
|
|
1138
1148
|
}
|
|
1149
|
+
function imageBuilderState(state) {
|
|
1150
|
+
const kind = builtinKind(state.config.hooks.provision);
|
|
1151
|
+
if (kind !== "container" && kind !== "vm") return "usable";
|
|
1152
|
+
if (state.deps.container?.buildImage !== void 0 || state.deps.container?.imageHost !== void 0) return "usable";
|
|
1153
|
+
const memory = state.config.build?.memory ?? "8g";
|
|
1154
|
+
let probe = state.imageBuilder;
|
|
1155
|
+
if (probe === void 0 || probe.memory !== memory) probe = state.imageBuilder = { memory, at: 0, running: false };
|
|
1156
|
+
if (probe.result?.ok === true && !probe.running && probe.failures !== void 0 && ensureFailureCount() !== probe.failures) probe.result = void 0;
|
|
1157
|
+
const nowMs = nowOf(state).getTime();
|
|
1158
|
+
const recheckMs = 10 * 6e4;
|
|
1159
|
+
const due = !probe.running && (probe.result === void 0 || !probe.result.ok || nowMs - probe.at >= recheckMs);
|
|
1160
|
+
if (due) {
|
|
1161
|
+
const checking = probe;
|
|
1162
|
+
checking.running = true;
|
|
1163
|
+
const spec = builderSpec(state.config.configPath, memory, state.deps.container?.hostEnv ?? process.env);
|
|
1164
|
+
const check = state.deps.builderProbe ?? ((s) => ensureBuilder(spawnRun, s, { bootstrap: true }));
|
|
1165
|
+
void check(spec).catch((err) => ({ ok: false, problem: `the image builder could not be checked: ${describeCallFailure(err)}` })).then((result2) => {
|
|
1166
|
+
checking.result = result2;
|
|
1167
|
+
checking.failures = ensureFailureCount();
|
|
1168
|
+
checking.at = nowOf(state).getTime();
|
|
1169
|
+
checking.running = false;
|
|
1170
|
+
if (result2.ok && state.blocked !== void 0 && state.pollTimerSeconds !== void 0) void tick(state);
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
const result = probe.result;
|
|
1174
|
+
if (result === void 0) return "unknown";
|
|
1175
|
+
return result.ok ? "usable" : { problem: result.problem };
|
|
1176
|
+
}
|
|
1139
1177
|
function holdWhenBlocked(state) {
|
|
1140
1178
|
const probes = {
|
|
1141
1179
|
...realBlockedProbes(),
|
|
1142
1180
|
...state.deps.container?.hostEnv === void 0 ? {} : { env: state.deps.container.hostEnv },
|
|
1181
|
+
...state.deps.blocked?.imageBuilder === void 0 ? { imageBuilder: imageBuilderState(state) } : {},
|
|
1143
1182
|
...state.deps.blocked
|
|
1144
1183
|
};
|
|
1145
1184
|
const blocked = checkBlocked(state.config, probes);
|
|
@@ -1193,7 +1232,7 @@ async function housekeepingPass(state) {
|
|
|
1193
1232
|
state.housekeepingRunning = true;
|
|
1194
1233
|
try {
|
|
1195
1234
|
state.deps.housekeeping ??= {};
|
|
1196
|
-
state.deps.housekeeping.docker ??= createHousekeepingDocker({ runnerId: runnerLabelValue(state.config.configPath) });
|
|
1235
|
+
state.deps.housekeeping.docker ??= createHousekeepingDocker({ runnerId: runnerLabelValue(state.config.configPath), builder: builderName(state.config.configPath) });
|
|
1197
1236
|
const result = await runHousekeeping({
|
|
1198
1237
|
configPath: state.config.configPath,
|
|
1199
1238
|
keepDays: config.jobsKeepDays,
|
|
@@ -1267,7 +1306,7 @@ var CLAIM_REFUSAL_CODES = new Set(
|
|
|
1267
1306
|
"pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous branch_claimed_elsewhere".split(" ")
|
|
1268
1307
|
);
|
|
1269
1308
|
async function tryClaimAndStart(state, item, queue) {
|
|
1270
|
-
const { postJson: postJson2 } = await import('./work-cmd-
|
|
1309
|
+
const { postJson: postJson2 } = await import('./work-cmd-B3FOXZAL.js');
|
|
1271
1310
|
const log = logOf(state);
|
|
1272
1311
|
const hostKey = await loadHostKey(state.config.configPath);
|
|
1273
1312
|
const claim = await retrySend(
|
|
@@ -1395,6 +1434,7 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity)
|
|
|
1395
1434
|
itemKey,
|
|
1396
1435
|
branch,
|
|
1397
1436
|
commitIdentity: identity,
|
|
1437
|
+
...item.specRepository === void 0 || item.specRepository === null || item.specRepository === "" ? {} : { repository: item.specRepository },
|
|
1398
1438
|
startedAt: startedAt.toISOString()
|
|
1399
1439
|
};
|
|
1400
1440
|
writeJobFile(jobFilePath, job);
|
|
@@ -1864,8 +1904,39 @@ async function endJob(state, active, outcome, ending) {
|
|
|
1864
1904
|
state.jobs.delete(active.dirPath);
|
|
1865
1905
|
}
|
|
1866
1906
|
}
|
|
1907
|
+
async function renewLeaseIfDue(state, active, nowMs) {
|
|
1908
|
+
const log = logOf(state);
|
|
1909
|
+
const tag = `#${active.job.item}`;
|
|
1910
|
+
if (!needsRenew(active.lastRenewAtMs, nowMs)) return true;
|
|
1911
|
+
const renew = await retrySend(() => renewLease(state.config, active.job.item, state.deps.fetchImpl), {
|
|
1912
|
+
now: state.deps.now,
|
|
1913
|
+
sleep: state.deps.sleep
|
|
1914
|
+
});
|
|
1915
|
+
const result = renew.ok ? renew.value : "retry_later";
|
|
1916
|
+
if (result === "lease_lost") {
|
|
1917
|
+
if (active.ending) {
|
|
1918
|
+
log.error(`${tag} lease lost while the checks ran`);
|
|
1919
|
+
return false;
|
|
1920
|
+
}
|
|
1921
|
+
log.error(`${tag} lease lost \xB7 ending job as lease_lost`);
|
|
1922
|
+
await endJob(state, active, "lease_lost");
|
|
1923
|
+
return false;
|
|
1924
|
+
}
|
|
1925
|
+
if (result === "renewed") {
|
|
1926
|
+
active.job.lastRenewAt = new Date(nowMs).toISOString();
|
|
1927
|
+
writeJobFile(join(active.dirPath, "job.json"), active.job);
|
|
1928
|
+
log.line(`${tag} lease renewed \xB7 expires ${formatClock(new Date(nowMs + LEASE_SECONDS * 1e3), new Date(nowMs))}`);
|
|
1929
|
+
} else {
|
|
1930
|
+
log.error(`${tag} renew did not land \xB7 retrying in ${RENEW_INTERVAL_SECONDS / 60}m`);
|
|
1931
|
+
}
|
|
1932
|
+
active.lastRenewAtMs = nowMs;
|
|
1933
|
+
return true;
|
|
1934
|
+
}
|
|
1867
1935
|
async function watchTick(state, active, nowMs, logMtimeMs) {
|
|
1868
|
-
if (active.ending)
|
|
1936
|
+
if (active.ending) {
|
|
1937
|
+
if (active.job.stage === "checks") await renewLeaseIfDue(state, active, nowMs);
|
|
1938
|
+
return;
|
|
1939
|
+
}
|
|
1869
1940
|
const log = logOf(state);
|
|
1870
1941
|
const tag = `#${active.job.item}`;
|
|
1871
1942
|
const pid = active.job.pid;
|
|
@@ -1883,26 +1954,7 @@ async function watchTick(state, active, nowMs, logMtimeMs) {
|
|
|
1883
1954
|
}
|
|
1884
1955
|
return;
|
|
1885
1956
|
}
|
|
1886
|
-
if (
|
|
1887
|
-
const renew = await retrySend(() => renewLease(state.config, active.job.item, state.deps.fetchImpl), {
|
|
1888
|
-
now: state.deps.now,
|
|
1889
|
-
sleep: state.deps.sleep
|
|
1890
|
-
});
|
|
1891
|
-
const result = renew.ok ? renew.value : "retry_later";
|
|
1892
|
-
if (result === "lease_lost") {
|
|
1893
|
-
log.error(`${tag} lease lost \xB7 ending job as lease_lost`);
|
|
1894
|
-
await endJob(state, active, "lease_lost");
|
|
1895
|
-
return;
|
|
1896
|
-
}
|
|
1897
|
-
if (result === "renewed") {
|
|
1898
|
-
active.job.lastRenewAt = new Date(nowMs).toISOString();
|
|
1899
|
-
writeJobFile(join(active.dirPath, "job.json"), active.job);
|
|
1900
|
-
log.line(`${tag} lease renewed \xB7 expires ${formatClock(new Date(nowMs + LEASE_SECONDS * 1e3), new Date(nowMs))}`);
|
|
1901
|
-
} else {
|
|
1902
|
-
log.error(`${tag} renew did not land \xB7 retrying in ${RENEW_INTERVAL_SECONDS / 60}m`);
|
|
1903
|
-
}
|
|
1904
|
-
active.lastRenewAtMs = nowMs;
|
|
1905
|
-
}
|
|
1957
|
+
if (!await renewLeaseIfDue(state, active, nowMs)) return;
|
|
1906
1958
|
const tokens = active.job.container === void 0 && active.job.microvm === void 0 ? void 0 : runtimeOf(state).credentials.get(active.dirPath);
|
|
1907
1959
|
if (tokens !== void 0) {
|
|
1908
1960
|
await tokens.renewReadIfDue();
|
|
@@ -1978,7 +2030,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
|
|
|
1978
2030
|
const outcome = await onStartUnderMarker({
|
|
1979
2031
|
configPath,
|
|
1980
2032
|
own: ownVersionOf(deps),
|
|
1981
|
-
check: update.check ? () => update.check(configPath) : async () => (await import('./check-
|
|
2033
|
+
check: update.check ? () => update.check(configPath) : async () => (await import('./check-FOF3PUKI.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
|
|
1982
2034
|
now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
|
|
1983
2035
|
log
|
|
1984
2036
|
});
|
|
@@ -1,13 +1,62 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { sanitizeTerminal } from './chunk-ZYHKJKSU.js';
|
|
4
|
+
import { remoteLookupFailed } from './chunk-GAYWY4GI.js';
|
|
5
|
+
import { DEFAULT_DASHBOARD } from './chunk-USO2DKBD.js';
|
|
6
6
|
import { resolveGatewayCredentials } from './chunk-BOLTI6LR.js';
|
|
7
|
-
import {
|
|
7
|
+
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
8
|
+
import { writeRepoConnection, findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
|
|
8
9
|
import { createInterface } from 'readline/promises';
|
|
9
10
|
|
|
10
11
|
createRequire(import.meta.url);
|
|
12
|
+
|
|
13
|
+
// src/repository-link.ts
|
|
14
|
+
var LINKS_TIMEOUT_MS = 15e3;
|
|
15
|
+
var GITHUB_PREFIX = "github.com/";
|
|
16
|
+
function isLinkedRepository(local, linked) {
|
|
17
|
+
if (linked.provider !== "github" || typeof linked.repository !== "string") return false;
|
|
18
|
+
return local.toLowerCase() === `${GITHUB_PREFIX}${linked.repository.toLowerCase()}`;
|
|
19
|
+
}
|
|
20
|
+
function ownerAndName(repository) {
|
|
21
|
+
return repository.toLowerCase().startsWith(GITHUB_PREFIX) ? repository.slice(GITHUB_PREFIX.length) : repository;
|
|
22
|
+
}
|
|
23
|
+
async function isRepositoryLinked(fetchImpl, gatewayUrl, token, appId, repository) {
|
|
24
|
+
if (!repository.toLowerCase().startsWith(GITHUB_PREFIX)) return null;
|
|
25
|
+
let res;
|
|
26
|
+
try {
|
|
27
|
+
res = await fetchImpl(`${gatewayUrl.replace(/\/+$/, "")}/v1/apps/${encodeURIComponent(appId)}/git/links`, {
|
|
28
|
+
method: "GET",
|
|
29
|
+
headers: { authorization: `Bearer ${token}`, "x-outerlayer-app-id": appId },
|
|
30
|
+
signal: AbortSignal.timeout(LINKS_TIMEOUT_MS)
|
|
31
|
+
});
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (!res.ok) return null;
|
|
36
|
+
const listed = (await res.json().catch(() => void 0))?.data;
|
|
37
|
+
if (!Array.isArray(listed)) return null;
|
|
38
|
+
return listed.some((entry) => isLinkedRepository(repository, entry ?? {}));
|
|
39
|
+
}
|
|
40
|
+
function dashboardBase(home) {
|
|
41
|
+
const saved = readCloudConfig(home).dashboard;
|
|
42
|
+
const base = typeof saved === "string" && saved.trim() !== "" ? saved : DEFAULT_DASHBOARD;
|
|
43
|
+
return base.replace(/\/+$/, "");
|
|
44
|
+
}
|
|
45
|
+
function workPageUrl(home, organization, factory) {
|
|
46
|
+
return `${dashboardBase(home)}/orgs/${encodeURIComponent(organization)}/factories/${encodeURIComponent(factory)}/work`;
|
|
47
|
+
}
|
|
48
|
+
function notLinkedText(factoryName, repository, url) {
|
|
49
|
+
const shown = sanitizeTerminal(repository);
|
|
50
|
+
const name = sanitizeTerminal(ownerAndName(repository));
|
|
51
|
+
return `${factoryName} has no link to ${shown} yet, so work from this repository cannot reach it.
|
|
52
|
+
Link it on the factory's Work page: ${url}
|
|
53
|
+
1. Connect GitHub repository, and grant the App access to ${name}.
|
|
54
|
+
2. Link repository, and pick ${name} and its default branch.
|
|
55
|
+
Then run \`outerlayer connect\` again.
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/connect-cmd.ts
|
|
11
60
|
var REQUEST_TIMEOUT_MS = 15e3;
|
|
12
61
|
var EXIT_NOT_LINKED = 2;
|
|
13
62
|
var REASON_TEXT = {
|
|
@@ -72,10 +121,10 @@ function parseFactories(body) {
|
|
|
72
121
|
function listText(factories, repository) {
|
|
73
122
|
return factories.map((f) => ` ${slug(f)} ${f.displayName}${f.linked === true ? ` (linked to ${repository})` : ""}`).join("\n");
|
|
74
123
|
}
|
|
75
|
-
async function fetchFactories(
|
|
124
|
+
async function fetchFactories(fetchImpl, url, token, repository) {
|
|
76
125
|
let res;
|
|
77
126
|
try {
|
|
78
|
-
res = await
|
|
127
|
+
res = await fetchImpl(`${url.replace(/\/+$/, "")}/v1/me/factories?${new URLSearchParams({ repository }).toString()}`, {
|
|
79
128
|
method: "GET",
|
|
80
129
|
headers: { authorization: `Bearer ${token}` },
|
|
81
130
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
@@ -99,6 +148,26 @@ async function fetchFactories(deps, url, token, repository) {
|
|
|
99
148
|
}
|
|
100
149
|
return { ok: true, factories };
|
|
101
150
|
}
|
|
151
|
+
function selectFactory(factories, saved, repository) {
|
|
152
|
+
const remembered = saved && factories.find((f) => f.id === saved.appId);
|
|
153
|
+
if (remembered) return { factory: remembered, reason: "saved" };
|
|
154
|
+
const linked = factories.filter((f) => f.linked === true);
|
|
155
|
+
if (linked.length === 1) return { factory: linked[0], reason: "linked" };
|
|
156
|
+
if (factories.length === 1) return { factory: factories[0], reason: "only" };
|
|
157
|
+
return { factory: void 0, values: factories.map(slug), text: listText(factories, repository) };
|
|
158
|
+
}
|
|
159
|
+
function saveFactoryConnection(gitCommonDir, saved, factory, now) {
|
|
160
|
+
if (saved?.appId === factory.id) return;
|
|
161
|
+
writeRepoConnection(gitCommonDir, {
|
|
162
|
+
appId: factory.id,
|
|
163
|
+
organization: { name: factory.organization.name, displayName: factory.organization.displayName },
|
|
164
|
+
factory: { name: factory.name, displayName: factory.displayName },
|
|
165
|
+
savedAt: now.toISOString()
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function connectedLine(repository, factory, reason) {
|
|
169
|
+
return `Connected ${repository} to factory "${factory.displayName}" in ${factory.organization.displayName} (${REASON_TEXT[reason]}).`;
|
|
170
|
+
}
|
|
102
171
|
async function choose(flags, deps, factories, saved, repository) {
|
|
103
172
|
if (flags.factory !== void 0) {
|
|
104
173
|
const wanted = flags.factory.toLowerCase();
|
|
@@ -108,11 +177,9 @@ async function choose(flags, deps, factories, saved, repository) {
|
|
|
108
177
|
${listText(factories, repository)}`;
|
|
109
178
|
return result(1, "failed", `--factory ${flags.factory} names no factory you can use`, message);
|
|
110
179
|
}
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
180
|
+
const decided = selectFactory(factories, saved, repository);
|
|
181
|
+
if (decided.factory) return { factory: decided.factory, reason: decided.reason };
|
|
113
182
|
const linked = factories.filter((f) => f.linked === true);
|
|
114
|
-
if (linked.length === 1) return { factory: linked[0], reason: "linked" };
|
|
115
|
-
if (factories.length === 1) return { factory: factories[0], reason: "only" };
|
|
116
183
|
if (!deps.isTerminal) {
|
|
117
184
|
const why = linked.length > 1 ? `${repository} is linked to more than one factory you can use` : `you can use more than one factory, and none is the only one ${repository} is linked to`;
|
|
118
185
|
const message = `${why}, and there is no terminal to ask on.
|
|
@@ -169,7 +236,7 @@ async function runConnect(flags, deps) {
|
|
|
169
236
|
const message = "no gateway address is saved. Run `outerlayer login` to sign in.";
|
|
170
237
|
return result(1, "failed", message, message);
|
|
171
238
|
}
|
|
172
|
-
const listed = await fetchFactories(deps, creds.url, creds.credential, repository);
|
|
239
|
+
const listed = await fetchFactories(deps.fetchImpl, creds.url, creds.credential, repository);
|
|
173
240
|
if (!listed.ok) return listed.result;
|
|
174
241
|
const { factories } = listed;
|
|
175
242
|
if (factories.length === 0) {
|
|
@@ -181,20 +248,13 @@ async function runConnect(flags, deps) {
|
|
|
181
248
|
const choice = await choose(flags, deps, factories, saved, repository);
|
|
182
249
|
if ("code" in choice) return choice;
|
|
183
250
|
const { factory, reason } = choice;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
factory: { name: factory.name, displayName: factory.displayName },
|
|
190
|
-
savedAt: deps.now().toISOString()
|
|
191
|
-
});
|
|
192
|
-
} catch (err) {
|
|
193
|
-
const message = `could not save the connection under ${dirs.gitCommonDir}: ${err instanceof Error ? err.message : String(err)}`;
|
|
194
|
-
return result(1, "failed", "could not save the connection", message);
|
|
195
|
-
}
|
|
251
|
+
try {
|
|
252
|
+
saveFactoryConnection(dirs.gitCommonDir, saved, factory, deps.now());
|
|
253
|
+
} catch (err) {
|
|
254
|
+
const message = `could not save the connection under ${dirs.gitCommonDir}: ${err instanceof Error ? err.message : String(err)}`;
|
|
255
|
+
return result(1, "failed", "could not save the connection", message);
|
|
196
256
|
}
|
|
197
|
-
const connected =
|
|
257
|
+
const connected = `${connectedLine(repository, factory, reason)}
|
|
198
258
|
`;
|
|
199
259
|
const why = `connected to ${slug(factory)}: ${REASON_TEXT[reason]}`;
|
|
200
260
|
const linked = await isRepositoryLinked(deps.fetchImpl, creds.url, creds.credential, factory.id, repository);
|
|
@@ -229,4 +289,4 @@ async function runConnectCommand(flags, deps, out) {
|
|
|
229
289
|
return r.code;
|
|
230
290
|
}
|
|
231
291
|
|
|
232
|
-
export { promptOnTerminal, realConnectDeps, runConnect, runConnectCommand };
|
|
292
|
+
export { connectedLine, fetchFactories, isLinkedRepository, promptOnTerminal, realConnectDeps, runConnect, runConnectCommand, saveFactoryConnection, selectFactory };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { isPlaceholderCommand } from './chunk-
|
|
4
|
-
import { describeCallFailure } from './chunk-
|
|
5
|
-
import { WorkCommandError, getJson } from './chunk-
|
|
6
|
-
import { sanitizeTerminal } from './chunk-
|
|
7
|
-
import { builtinKind } from './chunk-
|
|
8
|
-
import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-
|
|
3
|
+
import { isPlaceholderCommand } from './chunk-NALVDFIS.js';
|
|
4
|
+
import { describeCallFailure } from './chunk-CM5QTKM4.js';
|
|
5
|
+
import { WorkCommandError, getJson } from './chunk-5QLNZGAQ.js';
|
|
6
|
+
import { sanitizeTerminal } from './chunk-ZYHKJKSU.js';
|
|
7
|
+
import { builtinKind } from './chunk-PWBILI5P.js';
|
|
8
|
+
import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-OD2VTIHN.js';
|
|
9
9
|
import { signerFor } from './chunk-M5POMKKW.js';
|
|
10
10
|
|
|
11
11
|
createRequire(import.meta.url);
|
|
@@ -628,7 +628,7 @@ async function runHookFast(event, home = homeFromEnv(), read = readStdin, env =
|
|
|
628
628
|
recordHookErrorsSeen(home, hookErrorsBytes);
|
|
629
629
|
if (contextPossiblyGoverned(sessionCwd, home)) {
|
|
630
630
|
try {
|
|
631
|
-
const { materializeContext: materialize } = await import('./context-materialize-
|
|
631
|
+
const { materializeContext: materialize } = await import('./context-materialize-QL33HDJN.js');
|
|
632
632
|
const sessionId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
|
|
633
633
|
const result = await materialize({ cwd: sessionCwd, sessionId, home });
|
|
634
634
|
materializeMessage = result.message;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
+
import { autoConnect } from './chunk-4ACZCY4I.js';
|
|
3
4
|
import { detectActiveSession } from './chunk-BFESLKPP.js';
|
|
4
|
-
import { resolveRepoIdentity } from './chunk-
|
|
5
|
+
import { resolveRepoIdentity } from './chunk-GAYWY4GI.js';
|
|
5
6
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
6
7
|
import { defaultFetch } from './chunk-BCLJSQCV.js';
|
|
7
8
|
import { unauthorizedMessage, resolveGatewayCredentials } from './chunk-BOLTI6LR.js';
|
|
@@ -37,6 +38,8 @@ async function runWorkPr(opts) {
|
|
|
37
38
|
const cwd = opts.cwd ?? process.cwd();
|
|
38
39
|
const env = opts.env ?? process.env;
|
|
39
40
|
const home = opts.home ?? homeFromEnv(env);
|
|
41
|
+
const refusal = await autoConnect(opts);
|
|
42
|
+
if (refusal !== void 0) throw new WorkPrCommandError(refusal);
|
|
40
43
|
const creds = resolveCredentials(opts);
|
|
41
44
|
const prNumber = resolvePrNumber(opts.number);
|
|
42
45
|
const repository = resolveRepository(opts.repo, cwd);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { C } from './chunk-YRYMNBGQ.js';
|
|
4
|
-
import { resolvePackRoot, loadTemplateFiles, loadMaintainedFiles, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-
|
|
4
|
+
import { resolvePackRoot, loadTemplateFiles, loadMaintainedFiles, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-VXLJORHL.js';
|
|
5
5
|
import { resolvePackageVersion } from './chunk-RA3O54FC.js';
|
|
6
6
|
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
7
7
|
import { join, dirname } from 'path';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-
|
|
4
|
-
import { MIN_ENGINE_MAJOR } from './chunk-
|
|
3
|
+
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-TUUMW4TC.js';
|
|
4
|
+
import { MIN_ENGINE_MAJOR } from './chunk-CM5QTKM4.js';
|
|
5
5
|
import { RUNNER_DIR_MODE, runnerDir, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
|
|
6
6
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
7
7
|
import { dirname } from 'path';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
+
import { authorEnvironment, withHooksPath } from './chunk-HKMPVPO7.js';
|
|
3
4
|
import { existsSync, unlinkSync, chmodSync } from 'fs';
|
|
4
5
|
import { request as request$1, createServer } from 'http';
|
|
5
6
|
import { request } from 'https';
|
|
@@ -344,52 +345,6 @@ async function startBuildServices(input) {
|
|
|
344
345
|
}
|
|
345
346
|
}
|
|
346
347
|
|
|
347
|
-
// src/runner/commit-identity.ts
|
|
348
|
-
var NOREPLY_SUFFIX = "@users.noreply.github.com";
|
|
349
|
-
var MAX_LENGTH = 200;
|
|
350
|
-
function parseIdentity(value) {
|
|
351
|
-
if (typeof value !== "object" || value === null) return void 0;
|
|
352
|
-
const { name, email } = value;
|
|
353
|
-
if (typeof name !== "string" || typeof email !== "string") return void 0;
|
|
354
|
-
if (name.trim() === "" || name.length > MAX_LENGTH || /[\r\n\0<>]/.test(name)) return void 0;
|
|
355
|
-
if (email.length > MAX_LENGTH || !email.endsWith(NOREPLY_SUFFIX) || /[\s\0<>]/.test(email) || email.length === NOREPLY_SUFFIX.length) return void 0;
|
|
356
|
-
return { name, email };
|
|
357
|
-
}
|
|
358
|
-
function parseClaimIdentity(data) {
|
|
359
|
-
const author = parseIdentity(data.commitAuthor);
|
|
360
|
-
if (author === void 0) return void 0;
|
|
361
|
-
const coAuthor = parseIdentity(data.coAuthor);
|
|
362
|
-
return coAuthor === void 0 ? { author } : { author, coAuthor };
|
|
363
|
-
}
|
|
364
|
-
function authorEnvironment(identity) {
|
|
365
|
-
if (identity === void 0) return {};
|
|
366
|
-
return {
|
|
367
|
-
GIT_AUTHOR_NAME: identity.name,
|
|
368
|
-
GIT_AUTHOR_EMAIL: identity.email,
|
|
369
|
-
GIT_COMMITTER_NAME: identity.name,
|
|
370
|
-
GIT_COMMITTER_EMAIL: identity.email
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
function configCount(env) {
|
|
374
|
-
const raw = String(env.GIT_CONFIG_COUNT);
|
|
375
|
-
return /^[0-9]+$/.test(raw) ? Number(raw) : 0;
|
|
376
|
-
}
|
|
377
|
-
function withHooksPath(env, dir) {
|
|
378
|
-
const at = configCount(env);
|
|
379
|
-
return {
|
|
380
|
-
...env,
|
|
381
|
-
GIT_CONFIG_COUNT: String(at + 1),
|
|
382
|
-
[`GIT_CONFIG_KEY_${at}`]: "core.hooksPath",
|
|
383
|
-
[`GIT_CONFIG_VALUE_${at}`]: dir
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
function commitIdentityRecord(identity) {
|
|
387
|
-
return {
|
|
388
|
-
author: identity === void 0 ? "host" : "app",
|
|
389
|
-
coAuthor: identity?.coAuthor !== void 0 && identity.hooksPath !== void 0 ? "credited" : "none"
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
|
|
393
348
|
// src/runner/container/environment.ts
|
|
394
349
|
var RELAY_PORT = 3128;
|
|
395
350
|
var JOB_MOUNT = "/outerlayer/job";
|
|
@@ -498,6 +453,23 @@ function buildEnvironment(input) {
|
|
|
498
453
|
skippedTokenVariables
|
|
499
454
|
};
|
|
500
455
|
}
|
|
456
|
+
function checkEnvironment(input) {
|
|
457
|
+
const env = buildEnvironment({
|
|
458
|
+
config: input.config,
|
|
459
|
+
item: input.item,
|
|
460
|
+
itemKey: void 0,
|
|
461
|
+
repository: input.repository,
|
|
462
|
+
hostEnv: input.hostEnv,
|
|
463
|
+
containerEnv: input.containerEnv,
|
|
464
|
+
builtIns: false
|
|
465
|
+
});
|
|
466
|
+
const withheld = /* @__PURE__ */ new Set(["OUTERLAYER_URL", "OUTERLAYER_API_KEY", ...CLAUDE_CREDENTIAL_VARIABLES]);
|
|
467
|
+
const literals = {};
|
|
468
|
+
for (const [name, value] of Object.entries(env.literals)) if (!withheld.has(name)) literals[name] = value;
|
|
469
|
+
const passed = {};
|
|
470
|
+
for (const [name, value] of Object.entries(env.passed)) if (!withheld.has(name)) passed[name] = value;
|
|
471
|
+
return { literals, passed };
|
|
472
|
+
}
|
|
501
473
|
function parseIsolation(value) {
|
|
502
474
|
return value === "container" || value === "vm" ? value : "shared-user";
|
|
503
475
|
}
|
|
@@ -531,4 +503,4 @@ function withTunnelRecord(environment, record, onlyWhenUsed = false) {
|
|
|
531
503
|
};
|
|
532
504
|
}
|
|
533
505
|
|
|
534
|
-
export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT,
|
|
506
|
+
export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseIsolation, proxyEnvironment, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
|