@outerlayer/cli 0.26.3 → 0.27.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 +25 -0
- package/README.md +12 -9
- package/dist/{agent-setup-PZYQWN4H.js → agent-setup-UW36TAQM.js} +13 -13
- package/dist/{bridge-5KZ36YDG.js → bridge-B5VJVECY.js} +2 -2
- package/dist/build-TNM7HYCA.js +12 -0
- package/dist/build-info.json +1 -1
- package/dist/{builder-WEGLC2F2.js → builder-LDJGS2JC.js} +6 -6
- package/dist/{check-WJJ325EQ.js → check-JVBAWIN6.js} +44 -43
- package/dist/{chunk-7LVF4E5V.js → chunk-24ID7EQ2.js} +7 -4
- package/dist/{chunk-HXFRJKMU.js → chunk-2F762IXY.js} +2 -2
- package/dist/{chunk-2K3TCQHW.js → chunk-2I3LIRZP.js} +26 -8
- package/dist/{chunk-UKCNOAO6.js → chunk-55GNQPO6.js} +17 -6
- package/dist/{chunk-XSPA5ODY.js → chunk-6BLXUD56.js} +4 -3
- package/dist/{chunk-MWPBF2XG.js → chunk-6KKM7VGZ.js} +32 -4
- package/dist/{chunk-VPEGE3QZ.js → chunk-6TRNCUM4.js} +1 -1
- package/dist/{chunk-MLD2NA7N.js → chunk-7AQ5AM7U.js} +12 -5
- package/dist/{chunk-HBISTTG3.js → chunk-7OUOLGUV.js} +20 -5
- package/dist/{chunk-6FAP657M.js → chunk-ABXQBEYK.js} +1 -1
- package/dist/{chunk-TSW4DGV2.js → chunk-B6K7R5UY.js} +2 -2
- package/dist/chunk-BM7EC3OZ.js +181 -0
- package/dist/{chunk-W3NVHOCS.js → chunk-BPKO76QR.js} +4 -4
- package/dist/{chunk-QRZLUUNN.js → chunk-BWH36FOC.js} +8 -3
- package/dist/{chunk-PYSKSROG.js → chunk-D7ECMB7B.js} +4 -4
- package/dist/{chunk-FO7F6QSV.js → chunk-DJHNEGNM.js} +27 -3
- package/dist/{chunk-TPAF24PK.js → chunk-E5IJ5533.js} +2 -2
- package/dist/{chunk-JWRX5ZTT.js → chunk-EPPIISRD.js} +2 -2
- package/dist/{chunk-6M4LNO22.js → chunk-FP23SVDD.js} +6 -6
- package/dist/{chunk-GOSFARMS.js → chunk-G2JWZDFA.js} +9 -2
- package/dist/{chunk-XFGL53GU.js → chunk-G3EZA6MK.js} +56 -8
- package/dist/{chunk-5PMQDQFV.js → chunk-GFUE5TKO.js} +3 -3
- package/dist/{chunk-XLC7KEUV.js → chunk-GLUKDQS4.js} +1 -1
- package/dist/{chunk-ZLEXMZFW.js → chunk-JH2GQU5T.js} +5 -5
- package/dist/{chunk-YVZJ6GKF.js → chunk-KT4CN6OU.js} +1 -1
- package/dist/{chunk-JKNYTNYD.js → chunk-LOKSLO25.js} +1 -1
- package/dist/{chunk-665QWBNW.js → chunk-M3MHHIUW.js} +1 -1
- package/dist/{chunk-4IFKLYMM.js → chunk-MATUHHN4.js} +1 -1
- package/dist/{chunk-MQ743JX3.js → chunk-MHX7YX7Y.js} +1 -1
- package/dist/{chunk-TEVO3RUV.js → chunk-N4D5TMVU.js} +4 -4
- package/dist/{chunk-EORWWFPA.js → chunk-O2IJTY7L.js} +2 -2
- package/dist/{chunk-EABW6AJQ.js → chunk-PJDQPF5N.js} +18 -5
- package/dist/{chunk-KDDFI5MR.js → chunk-QHH4OSD4.js} +1 -1
- package/dist/{chunk-W7LGHNXT.js → chunk-QIVOTQOQ.js} +5 -5
- package/dist/{chunk-JF572PM5.js → chunk-QKIQ2R7F.js} +3 -3
- package/dist/{chunk-L4CW6LZQ.js → chunk-RHAGBUL5.js} +5 -2
- package/dist/{chunk-TKL74NLB.js → chunk-RHGF73IU.js} +1 -1
- package/dist/{chunk-SKZG7SAN.js → chunk-RK7FWC6B.js} +206 -42
- package/dist/{chunk-6MZSX4M7.js → chunk-STSLH5EJ.js} +3 -1
- package/dist/{chunk-K7FCZCLQ.js → chunk-TXHJ7BGR.js} +13 -13
- package/dist/{chunk-364XDGOK.js → chunk-UQYBCJ2L.js} +3 -3
- package/dist/{chunk-2AKDF6C2.js → chunk-VS27BP3E.js} +5 -5
- package/dist/{chunk-J7BXZLSO.js → chunk-WSYXLLA5.js} +29 -8
- package/dist/{chunk-WX2WEERU.js → chunk-WUL2OP5A.js} +3 -3
- package/dist/{chunk-ZPXI7LMG.js → chunk-WVDP6HVZ.js} +6 -6
- 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-F6DIHHBS.js → chunk-Y4OKEFAX.js} +1 -1
- package/dist/{chunk-XDHYZWEK.js → chunk-Y7ZCHBYB.js} +2 -2
- package/dist/chunk-YB3CSYXX.js +95 -0
- package/dist/{chunk-VHVFU6QU.js → chunk-YF56R4DV.js} +86 -31
- package/dist/chunk-YJLHUKYS.js +38 -0
- package/dist/{chunk-XF77SNB4.js → chunk-ZXRWMOJ3.js} +287 -51
- package/dist/{claude-launcher-O2U6P6ZD.js → claude-launcher-TKX4WCUN.js} +8 -4
- package/dist/{cli-2UUJM3AE.js → cli-XVXQDKZT.js} +141 -135
- package/dist/{command-GQBHC53U.js → command-B2T7VR77.js} +33 -32
- package/dist/{config-JJ3EO7SB.js → config-TWS5VZEN.js} +3 -3
- package/dist/{connect-cmd-2JHSLBXK.js → connect-cmd-HGS7YPA2.js} +10 -10
- package/dist/{container-start-AUJHF2BC.js → container-start-JE7HTKZG.js} +32 -31
- package/dist/{control-plane-launch-654RV5PO.js → control-plane-launch-DBQA3KLJ.js} +9 -9
- package/dist/{docker-NYAIIX2F.js → docker-MJEEHUUA.js} +6 -6
- package/dist/{doctor-NV2PUERZ.js → doctor-6ZIF2BRZ.js} +184 -37
- package/dist/{emit-artifact-cmd-XXTCHP6V.js → emit-artifact-cmd-ALDK55Y2.js} +14 -14
- package/dist/{emit-cmd-WQH2NK7H.js → emit-cmd-VAQHRWJR.js} +4 -4
- package/dist/{emit-criteria-cmd-VMZIRJCQ.js → emit-criteria-cmd-Q7SM6VP2.js} +11 -11
- package/dist/{emit-finding-cmd-KMJNYQI7.js → emit-finding-cmd-2NBAPDSV.js} +11 -11
- package/dist/{emit-result-cmd-HRTXGZLK.js → emit-result-cmd-KUSL56RI.js} +14 -14
- package/dist/{emit-step-cmd-AUHA3EXY.js → emit-step-cmd-KD4AKEAT.js} +12 -12
- package/dist/{exec-client-J6L5FDRR.js → exec-client-6WVS7DRZ.js} +3 -3
- package/dist/{governing-source-PTJ6EAA3.js → governing-source-VVUA5TKB.js} +16 -16
- package/dist/{guest-init-CXIHA5VI.js → guest-init-H5K2RW3P.js} +4 -4
- package/dist/{hook-fast-SDFXJEAW.js → hook-fast-3SUJM765.js} +1 -1
- package/dist/{host-key-5TKBNUZ4.js → host-key-XNKZCWTS.js} +3 -3
- package/dist/{image-tag-5SJ6ZKT7.js → image-tag-R34J4O3F.js} +3 -3
- package/dist/index.js +4 -4
- package/dist/init-ETKGFCXR.js +55 -0
- package/dist/{init-UZWRJMPZ.js → init-Q2RPUUVP.js} +33 -32
- package/dist/{init-cmd-SQKWPACS.js → init-cmd-M6MQRGOU.js} +19 -18
- package/dist/{init-update-FJDKY4SJ.js → init-update-N4HTZGVS.js} +59 -30
- package/dist/{inspect-6UYAAXH7.js → inspect-IPFA7AAT.js} +1 -1
- package/dist/{install-QSTTBUHX.js → install-6OIY3KHZ.js} +6 -5
- package/dist/{install-cmd-3DXJJUAA.js → install-cmd-JMT67P35.js} +5 -5
- package/dist/{layout-UOJQGEPW.js → layout-XNFDTOET.js} +2 -2
- package/dist/{login-browser-4OMZFP3U.js → login-browser-EWXSGHM7.js} +3 -3
- package/dist/{logout-cmd-5V5MMBSY.js → logout-cmd-5WE2N5B5.js} +2 -2
- package/dist/{logs-VN2HKDSH.js → logs-XHAS6LMZ.js} +2 -2
- package/dist/loop-2Y4CUFNP.js +79 -0
- package/dist/machine-Z2S47JW7.js +50 -0
- package/dist/machine-skills-RRF4HLAD.js +11 -0
- package/dist/{mcp-install-cmd-GGWB3JJ2.js → mcp-install-cmd-LD7KYAOP.js} +2 -2
- package/dist/{mcp-serve-cmd-U5N5DK3H.js → mcp-serve-cmd-LY5A3CE7.js} +5 -5
- package/dist/{paths-ZC6BMWMT.js → paths-LHSPNORF.js} +2 -2
- package/dist/{pending-54HC7MM3.js → pending-3YZCSKON.js} +3 -3
- package/dist/{pidfile-BY5Z6YH7.js → pidfile-DKMYYXLH.js} +3 -3
- package/dist/{record-K23IN6QN.js → record-3LPTY3G5.js} +3 -3
- package/dist/{runner-env-2D7MPOIJ.js → runner-env-YRRNRKF4.js} +8 -7
- package/dist/{runner-identity-YYENYKDH.js → runner-identity-EX7HXPUE.js} +6 -6
- package/dist/{runner-key-AZVXBQIB.js → runner-key-GO277GW2.js} +32 -31
- package/dist/{session-sender-VH2EKAT5.js → session-sender-SC5PSU2G.js} +15 -15
- package/dist/{spec-cmd-BOUPLX7X.js → spec-cmd-JGYHHJ4P.js} +12 -12
- package/dist/{starter-pack-55EFILC5.js → starter-pack-GPU4X6B7.js} +2 -2
- package/dist/{status-3WC2IGVI.js → status-CJCE2FHD.js} +34 -33
- package/dist/{sync-cmd-GT2WTQRA.js → sync-cmd-ATXJVS7S.js} +14 -14
- package/dist/{watch-JED7SYAA.js → watch-M7NR3DOW.js} +14 -14
- package/dist/{work-claim-cmd-MY4N74HA.js → work-claim-cmd-DNUDZKJA.js} +16 -16
- package/dist/{work-cmd-UQ45HDM4.js → work-cmd-VECTYST6.js} +12 -12
- package/dist/{work-comment-cmd-I7NNSNDP.js → work-comment-cmd-F3NRWKPZ.js} +12 -12
- package/dist/{work-logs-cmd-YIQJVENH.js → work-logs-cmd-QF6P32FE.js} +12 -12
- package/dist/{work-open-pr-cmd-VP5NNTCW.js → work-open-pr-cmd-XE23JA3R.js} +13 -13
- package/dist/{work-pr-cmd-DKTBEFHO.js → work-pr-cmd-BH56GUKN.js} +12 -12
- package/dist/{work-stop-cmd-GN2WX73C.js → work-stop-cmd-C3F5HNUO.js} +12 -12
- 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-EBQYXL7Y.js +0 -12
- package/dist/chunk-7RQ73DLO.js +0 -23
- package/dist/init-KIGYMLDM.js +0 -54
- package/dist/loop-OE32U2IZ.js +0 -78
- package/dist/machine-L7INJ4JN.js +0 -49
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { WorkCommandError, postJson } from './chunk-
|
|
4
|
-
import { defaultGitRunner, materializeContext, isStagingWriteFault, lookupGoverningSource } from './chunk-
|
|
5
|
-
import { signingFetchFor } from './chunk-
|
|
6
|
-
import { unsupportedLayout, layoutRefusalReason, composeDelivery } from './chunk-
|
|
3
|
+
import { WorkCommandError, postJson } from './chunk-55GNQPO6.js';
|
|
4
|
+
import { defaultGitRunner, materializeContext, isStagingWriteFault, lookupGoverningSource } from './chunk-BPKO76QR.js';
|
|
5
|
+
import { signingFetchFor } from './chunk-BWH36FOC.js';
|
|
6
|
+
import { unsupportedLayout, layoutRefusalReason, composeDelivery } from './chunk-6TRNCUM4.js';
|
|
7
7
|
import { SHIM_SCRIPT, GOVERNANCE_VARIABLE } from './chunk-HCVLP7XA.js';
|
|
8
8
|
import { readDegraded, readContextManifest, readSourceCache } from './chunk-YQR6E6OV.js';
|
|
9
|
-
import { signerFor } from './chunk-
|
|
10
|
-
import { SHIM_DIR, stagedContextDir, contextHomeDir, deliveryDir } from './chunk-
|
|
11
|
-
import { fstatSync, mkdirSync, writeFileSync, chmodSync, rmSync, lstatSync } from 'fs';
|
|
9
|
+
import { signerFor } from './chunk-Y4OKEFAX.js';
|
|
10
|
+
import { SHIM_DIR, stagedContextDir, contextHomeDir, deliveryDir, keptContextDir } from './chunk-RHAGBUL5.js';
|
|
11
|
+
import { fstatSync, mkdirSync, writeFileSync, chmodSync, rmSync, cpSync, readFileSync, existsSync, lstatSync } from 'fs';
|
|
12
12
|
import { relative, join, dirname } from 'path';
|
|
13
13
|
|
|
14
14
|
createRequire(import.meta.url);
|
|
@@ -464,6 +464,27 @@ async function controlPlaneAccess(ask, candidates, repository, log, tag) {
|
|
|
464
464
|
function removeStagedContext(buildDir) {
|
|
465
465
|
rmSync(stagedContextDir(buildDir), { recursive: true, force: true });
|
|
466
466
|
}
|
|
467
|
+
function keepStagedContext(staged, jobDir) {
|
|
468
|
+
const kept = keptContextDir(jobDir);
|
|
469
|
+
rmSync(kept, { recursive: true, force: true });
|
|
470
|
+
const tree = join(staged.dir, "tree");
|
|
471
|
+
cpSync(tree, join(kept, "tree"), { recursive: true, verbatimSymlinks: true, filter: (source) => source !== join(tree, ".git") });
|
|
472
|
+
writeFileSync(join(kept, "kept.json"), JSON.stringify({ schemaVersion: 1, repository: staged.repository, sha: staged.sha }) + "\n");
|
|
473
|
+
}
|
|
474
|
+
function keptContextTree(jobDir, governing) {
|
|
475
|
+
const kept = keptContextDir(jobDir);
|
|
476
|
+
let record;
|
|
477
|
+
try {
|
|
478
|
+
record = JSON.parse(readFileSync(join(kept, "kept.json"), "utf8"));
|
|
479
|
+
} catch {
|
|
480
|
+
return void 0;
|
|
481
|
+
}
|
|
482
|
+
if (governing === void 0 || record.sha !== governing.commit || String(record.repository).toLowerCase() !== governing.repository.toLowerCase()) return void 0;
|
|
483
|
+
return existsSync(join(kept, "tree")) ? join(kept, "tree") : void 0;
|
|
484
|
+
}
|
|
485
|
+
function removeKeptContext(jobDir) {
|
|
486
|
+
rmSync(keptContextDir(jobDir), { recursive: true, force: true });
|
|
487
|
+
}
|
|
467
488
|
|
|
468
489
|
// src/runner/governing-source.ts
|
|
469
490
|
var unavailable2 = (why) => ({ ok: false, reason: `context_unavailable: ${why}` });
|
|
@@ -494,4 +515,4 @@ async function imageTargetFor(input) {
|
|
|
494
515
|
return { ok: true, repository: resolved.source.repository, pinned: { commit: resolved.source.sha, ref: resolved.source.ref } };
|
|
495
516
|
}
|
|
496
517
|
|
|
497
|
-
export { BuildTokens, classifyRefusal, commandWithShim, controlPlaneTokenFailure, createRunnerLog, describeCallFailure, formatClock, formatDuration, imageTargetFor, logStamp, pinnedSourceOf, refusalCode, relativeToRunner, removeStagedContext, resolveGoverningSource, retrySend, shimScript, shortClaim, stageGovernedContext };
|
|
518
|
+
export { BuildTokens, classifyRefusal, commandWithShim, controlPlaneTokenFailure, createRunnerLog, describeCallFailure, formatClock, formatDuration, imageTargetFor, keepStagedContext, keptContextTree, logStamp, pinnedSourceOf, refusalCode, relativeToRunner, removeKeptContext, removeStagedContext, resolveGoverningSource, retrySend, shimScript, shortClaim, stageGovernedContext };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
3
|
+
import { isAgentsMdLayout, discoverOuterlayerPaths, isForeignTree, toRepoRelative } from './chunk-LOKSLO25.js';
|
|
4
|
+
import { retiredSkillPaths, removeRetiredSkills } from './chunk-MHX7YX7Y.js';
|
|
5
|
+
import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-7OUOLGUV.js';
|
|
4
6
|
import { C } from './chunk-ANPNT6PM.js';
|
|
5
|
-
import { isAgentsMdLayout, discoverOuterlayerPaths, isForeignTree, toRepoRelative } from './chunk-JKNYTNYD.js';
|
|
6
|
-
import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-HBISTTG3.js';
|
|
7
7
|
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
8
8
|
import { emitTree, generatedHeaderSource, parseOuterlayerConfig, classifyTree } from './chunk-RKOTJQVG.js';
|
|
9
9
|
import { existsSync, readFileSync, mkdirSync, writeFileSync, copyFileSync, unlinkSync, rmdirSync, readdirSync } from 'fs';
|
|
@@ -1,12 +1,12 @@
|
|
|
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-
|
|
3
|
+
import { isPlaceholderCommand } from './chunk-QIVOTQOQ.js';
|
|
4
|
+
import { describeCallFailure } from './chunk-WSYXLLA5.js';
|
|
5
|
+
import { WorkCommandError, getJson } from './chunk-55GNQPO6.js';
|
|
6
6
|
import { sanitizeTerminal } from './chunk-BUP5N3X6.js';
|
|
7
|
-
import { builtinKind } from './chunk-
|
|
8
|
-
import { signerFor } from './chunk-
|
|
9
|
-
import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-
|
|
7
|
+
import { builtinKind } from './chunk-EPPIISRD.js';
|
|
8
|
+
import { signerFor } from './chunk-Y4OKEFAX.js';
|
|
9
|
+
import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-2I3LIRZP.js';
|
|
10
10
|
|
|
11
11
|
createRequire(import.meta.url);
|
|
12
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { RELAY_PORT, BUILD_HOME } from './chunk-
|
|
3
|
+
import { RELAY_PORT, BUILD_HOME } from './chunk-2I3LIRZP.js';
|
|
4
4
|
import { createServer, connect } from 'net';
|
|
5
5
|
|
|
6
6
|
createRequire(import.meta.url);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
+
import { resolvePackRoot, OUTERLAYER_SKILLS_BASE, loadTemplateFiles, AGENTS_SKILLS_BASE, loadMaintainedFiles, rewriteSkillPaths, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS, MACHINE_SKILL_PATH } from './chunk-7OUOLGUV.js';
|
|
3
4
|
import { C } from './chunk-ANPNT6PM.js';
|
|
4
|
-
import { resolvePackRoot, OUTERLAYER_SKILLS_BASE, loadTemplateFiles, loadMaintainedFiles, rewriteSkillPaths, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-HBISTTG3.js';
|
|
5
5
|
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
6
6
|
import { linkedAgentsPath } from './chunk-VWFOKRYS.js';
|
|
7
7
|
import { resolvePackageVersion } from './chunk-RA3O54FC.js';
|
|
@@ -31,7 +31,7 @@ function installStarterPack(opts) {
|
|
|
31
31
|
const linked = base.startsWith(".agents/") ? linkedAgentsPath(opts.repoRoot) : void 0;
|
|
32
32
|
if (linked !== void 0) throw new StarterPackError(`${linked} is a link, and a write there would land outside the repository; replace it with a folder and run this again`);
|
|
33
33
|
const templateFiles = loadTemplateFiles(packRoot, version, base);
|
|
34
|
-
const maintainedFiles = loadMaintainedFiles(packRoot, version, base);
|
|
34
|
+
const maintainedFiles = base === AGENTS_SKILLS_BASE ? [] : loadMaintainedFiles(packRoot, version, base);
|
|
35
35
|
const validatorFiles = VALIDATOR_FILES.map(({ name }) => ({
|
|
36
36
|
path: `${VALIDATORS_DIR}/${name}`,
|
|
37
37
|
content: rewriteSkillPaths(readFileSync(join(packRoot, "validators", name), "utf8"), base)
|
|
@@ -94,9 +94,13 @@ function formatStarterPackOutput(result) {
|
|
|
94
94
|
result.kept.includes(skill) ? ` ${C.dim}kept${C.reset} ${skillDir(skill, base)}/ ${C.dim}(already exists, left exactly as it is)${C.reset}` : ` ${skillFile(skill, base)}`
|
|
95
95
|
);
|
|
96
96
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
if (base === OUTERLAYER_SKILLS_BASE) {
|
|
98
|
+
lines.push("", "Rewritten on every emit \u2014 edits are overwritten by the installed CLI:");
|
|
99
|
+
for (const skill of MAINTAINED_SKILLS) lines.push(` ${skillFile(skill, base)}`);
|
|
100
|
+
} else {
|
|
101
|
+
lines.push("", `Kept once per machine, not in this repository. \`${cliInvocation()} init\` installs them, and every later command keeps them at its own version:`);
|
|
102
|
+
for (const skill of MAINTAINED_SKILLS) lines.push(` ${skillFile(skill, MACHINE_SKILL_PATH)}`);
|
|
103
|
+
}
|
|
100
104
|
lines.push(
|
|
101
105
|
"",
|
|
102
106
|
result.policy === "written" ? `${C.green}\u2713${C.reset} Wrote ${POLICY_PATH} (review required)` : `${C.dim}${POLICY_PATH} already exists \u2014 left as it is${C.reset}`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { hostKeyPath, runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { hostKeyPath, runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-RHAGBUL5.js';
|
|
4
4
|
import { generateKeyPairSync, createPrivateKey, createPublicKey, sign } from 'crypto';
|
|
5
5
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { LiveUploader } from './chunk-
|
|
4
|
-
import { spoolDir } from './chunk-
|
|
3
|
+
import { LiveUploader } from './chunk-VS27BP3E.js';
|
|
4
|
+
import { spoolDir } from './chunk-DJHNEGNM.js';
|
|
5
5
|
import { CaptureDaemon } from './chunk-QE3UQAHK.js';
|
|
6
6
|
import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
|
|
7
7
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
|
|
5
|
+
createRequire(import.meta.url);
|
|
6
|
+
var FD_STORE_ENV = "OUTERLAYER_FD_STORE";
|
|
7
|
+
var MIN_SYSTEMD = 254;
|
|
8
|
+
var LISTEN_FDS_START = 3;
|
|
9
|
+
var FD_SLOTS_PER_BUILD = 64;
|
|
10
|
+
function fdName(buildId, socket) {
|
|
11
|
+
return `ol-${buildId}-${socket}`;
|
|
12
|
+
}
|
|
13
|
+
function listenFdOf(server) {
|
|
14
|
+
const handle = server._handle;
|
|
15
|
+
return typeof handle?.fd === "number" && handle.fd >= 0 ? handle.fd : void 0;
|
|
16
|
+
}
|
|
17
|
+
function parseListenFds(env, pid) {
|
|
18
|
+
const found = /* @__PURE__ */ new Map();
|
|
19
|
+
if (env.LISTEN_PID !== String(pid)) return found;
|
|
20
|
+
const count = Number(env.LISTEN_FDS);
|
|
21
|
+
if (!Number.isInteger(count) || count <= 0) return found;
|
|
22
|
+
const names = (env.LISTEN_FDNAMES ?? "").split(":");
|
|
23
|
+
for (let index = 0; index < count; index++) {
|
|
24
|
+
const name = names[index];
|
|
25
|
+
if (name !== void 0 && name !== "" && name !== "stored") found.set(name, LISTEN_FDS_START + index);
|
|
26
|
+
}
|
|
27
|
+
return found;
|
|
28
|
+
}
|
|
29
|
+
function listenOnFd(server, fd) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
server.once("error", reject);
|
|
32
|
+
server.listen({ fd }, () => {
|
|
33
|
+
server.off("error", reject);
|
|
34
|
+
resolve();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function run(spawnFn, command, args, fd) {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
let stdout = "";
|
|
41
|
+
let stderr = "";
|
|
42
|
+
let child;
|
|
43
|
+
try {
|
|
44
|
+
child = spawnFn(command, args, { stdio: ["ignore", "pipe", "pipe", ...fd === void 0 ? [] : [fd]] });
|
|
45
|
+
} catch (err) {
|
|
46
|
+
resolve({ status: null, stdout, stderr: err instanceof Error ? err.message : String(err) });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
child.stdout?.on("data", (chunk) => stdout += chunk.toString("utf8"));
|
|
50
|
+
child.stderr?.on("data", (chunk) => stderr += chunk.toString("utf8"));
|
|
51
|
+
child.on("error", (err) => resolve({ status: null, stdout, stderr: err.message }));
|
|
52
|
+
child.on("close", (status) => resolve({ status, stdout, stderr }));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function systemdVersion(ran) {
|
|
56
|
+
const match = /^systemd (\d+)/.exec(ran.stdout);
|
|
57
|
+
return ran.status === 0 && match !== null ? Number(match[1]) : void 0;
|
|
58
|
+
}
|
|
59
|
+
function realFdStorePort(options = {}) {
|
|
60
|
+
const env = options.env ?? process.env;
|
|
61
|
+
const pid = options.pid ?? process.pid;
|
|
62
|
+
const command = options.command ?? "systemd-notify";
|
|
63
|
+
const spawnFn = options.spawn ?? spawn;
|
|
64
|
+
let inherited;
|
|
65
|
+
let version;
|
|
66
|
+
return {
|
|
67
|
+
async status() {
|
|
68
|
+
if (env.NOTIFY_SOCKET === void 0 || env.NOTIFY_SOCKET === "") return { ok: false, reason: "NOTIFY_SOCKET is not set, so this runner was not started by a service that accepts descriptors" };
|
|
69
|
+
const size = Number(env[FD_STORE_ENV]);
|
|
70
|
+
if (!Number.isInteger(size) || size <= 0) return { ok: false, reason: `${FD_STORE_ENV} is not set, so the service's unit keeps no descriptor store` };
|
|
71
|
+
version ??= run(spawnFn, command, ["--version"]).then(systemdVersion);
|
|
72
|
+
const found = await version;
|
|
73
|
+
if (found === void 0) return { ok: false, reason: `${command} could not be run, so no descriptor can be stored` };
|
|
74
|
+
if (found < MIN_SYSTEMD) return { ok: false, reason: `systemd ${found} cannot store a descriptor sent from a child process: it needs systemd ${MIN_SYSTEMD} or later` };
|
|
75
|
+
return { ok: true };
|
|
76
|
+
},
|
|
77
|
+
async push(name, server) {
|
|
78
|
+
const fd = listenFdOf(server);
|
|
79
|
+
if (fd === void 0) throw new Error(`${name} has no descriptor to store`);
|
|
80
|
+
const ran = await run(spawnFn, command, [`--fd=${LISTEN_FDS_START}`, `--fdname=${name}`, "FDSTORE=1"], fd);
|
|
81
|
+
if (ran.status !== 0) throw new Error(`storing ${name} failed${ran.status === null ? "" : ` (exit ${ran.status})`}: ${ran.stderr.trim().split("\n")[0] ?? ""}`);
|
|
82
|
+
},
|
|
83
|
+
async remove(name) {
|
|
84
|
+
const ran = await run(spawnFn, command, [`--fdname=${name}`, "FDSTOREREMOVE=1"]);
|
|
85
|
+
if (ran.status !== 0) throw new Error(`removing ${name} from the store failed${ran.status === null ? "" : ` (exit ${ran.status})`}: ${ran.stderr.trim().split("\n")[0] ?? ""}`);
|
|
86
|
+
},
|
|
87
|
+
inherited() {
|
|
88
|
+
inherited ??= parseListenFds(env, pid);
|
|
89
|
+
return inherited;
|
|
90
|
+
},
|
|
91
|
+
listenOn: listenOnFd
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { FD_SLOTS_PER_BUILD, FD_STORE_ENV, fdName, realFdStorePort };
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { keepStagedContext, describeCallFailure, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript } from './chunk-WSYXLLA5.js';
|
|
4
|
+
import { runnerImageVersion } from './chunk-M3MHHIUW.js';
|
|
5
|
+
import { realFdStorePort } from './chunk-YB3CSYXX.js';
|
|
6
|
+
import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-24ID7EQ2.js';
|
|
5
7
|
import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
|
|
6
8
|
import { currentCliBuild } from './chunk-OGFGZQA3.js';
|
|
7
|
-
import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, JUDGE_DIR, JUDGE_REPORT, MAX_REPORT_BYTES, spawnRun } from './chunk-
|
|
8
|
-
import { FIRECRACKER_VERSION, hostHelperPinned, firecrackerArch, MICROVM_ARCHES, RecipeError, DOCKER_FEATURE, CLAUDE_CODE_VERSION, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, DEFAULT_BASE_IMAGE } from './chunk-
|
|
9
|
-
import { execCapture } from './chunk-
|
|
10
|
-
import { GUEST_CID } from './chunk-
|
|
11
|
-
import {
|
|
12
|
-
import { WorkCommandError } from './chunk-UKCNOAO6.js';
|
|
9
|
+
import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, JUDGE_DIR, JUDGE_REPORT, MAX_REPORT_BYTES, spawnRun } from './chunk-JH2GQU5T.js';
|
|
10
|
+
import { FIRECRACKER_VERSION, hostHelperPinned, firecrackerArch, MICROVM_ARCHES, RecipeError, DOCKER_FEATURE, CLAUDE_CODE_VERSION, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, DEFAULT_BASE_IMAGE } from './chunk-B6K7R5UY.js';
|
|
11
|
+
import { execCapture } from './chunk-XBPUTQ7E.js';
|
|
12
|
+
import { GUEST_CID } from './chunk-GLUKDQS4.js';
|
|
13
|
+
import { WorkCommandError } from './chunk-55GNQPO6.js';
|
|
13
14
|
import { hostAllowed } from './chunk-UXYLWVTQ.js';
|
|
14
|
-
import {
|
|
15
|
-
import { sharedSkillNames, skillConflictMessage } from './chunk-
|
|
15
|
+
import { readDu } from './chunk-YJLHUKYS.js';
|
|
16
|
+
import { sharedSkillNames, skillConflictMessage } from './chunk-6TRNCUM4.js';
|
|
16
17
|
import { versionAtLeast, MINIMUM_CLAUDE_VERSION } from './chunk-HCVLP7XA.js';
|
|
17
18
|
import { setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-QE3UQAHK.js';
|
|
18
19
|
import { orderSessions, extractFacts, sessionsToTimeline } from './chunk-RKOTJQVG.js';
|
|
19
20
|
import { downconvertSession } from './chunk-QZBXLLTV.js';
|
|
20
|
-
import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, SHIM_DIR } from './chunk-
|
|
21
|
-
import { repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT } from './chunk-
|
|
21
|
+
import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, SHIM_DIR } from './chunk-RHAGBUL5.js';
|
|
22
|
+
import { repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT } from './chunk-2I3LIRZP.js';
|
|
22
23
|
import { RELAY_USER, RELAY_ID, UNKNOWN_TRANSPORT_REASON, DOCKER_DESKTOP_REASON, MAX_MALFORMED_SESSIONS, MALFORMED_REASON, MAX_OPEN_STREAMS, STREAM_WINDOW, SESSION_WINDOW, targetOfPath } from './chunk-JGD5TWQ2.js';
|
|
23
24
|
import { readFileSync, mkdirSync, existsSync, mkdtempSync, rmSync, chmodSync, truncateSync, writeFileSync, readdirSync, lstatSync, copyFileSync, accessSync, constants, statSync, rmdirSync, renameSync, unlinkSync, openSync, closeSync, createWriteStream, createReadStream } from 'fs';
|
|
24
25
|
import { join, dirname, basename } from 'path';
|
|
@@ -210,6 +211,9 @@ function helperClient(socketPath, options = {}) {
|
|
|
210
211
|
async list() {
|
|
211
212
|
const reply = await ask(socketPath, { v: 1, op: "list" }, REQUEST_TIMEOUT_MS);
|
|
212
213
|
return Array.isArray(reply.builds) ? reply.builds.map(String) : [];
|
|
214
|
+
},
|
|
215
|
+
async relink(build) {
|
|
216
|
+
await ask(socketPath, { v: 1, op: "relink", build }, REQUEST_TIMEOUT_MS);
|
|
213
217
|
}
|
|
214
218
|
};
|
|
215
219
|
}
|
|
@@ -815,6 +819,13 @@ async function createBuildDisk(input) {
|
|
|
815
819
|
function deleteBuildDisk(path) {
|
|
816
820
|
rmSync(path, { force: true });
|
|
817
821
|
}
|
|
822
|
+
var clearBit = (bit) => `0b${"x".repeat(31 - bit)}0${"x".repeat(bit)}`;
|
|
823
|
+
var CPU_TEMPLATE = {
|
|
824
|
+
cpuid_modifiers: [
|
|
825
|
+
{ leaf: "0x1", subleaf: "0x0", flags: 0, modifiers: [{ register: "ecx", bitmap: clearBit(5) }] },
|
|
826
|
+
{ leaf: "0x80000001", subleaf: "0x0", flags: 0, modifiers: [{ register: "ecx", bitmap: clearBit(2) }] }
|
|
827
|
+
]
|
|
828
|
+
};
|
|
818
829
|
var MIB = 1024 ** 2;
|
|
819
830
|
var INIT = "/opt/outerlayer/bin/outerlayer-guest";
|
|
820
831
|
function machineConfig(limits2, paths) {
|
|
@@ -842,7 +853,8 @@ function machineConfig(limits2, paths) {
|
|
|
842
853
|
{ drive_id: "build", path_on_host: paths.buildDisk, is_root_device: false, is_read_only: false }
|
|
843
854
|
],
|
|
844
855
|
"machine-config": { vcpu_count: limits2.cpus, mem_size_mib: Math.max(1, Math.floor(limits2.memoryBytes / MIB)), smt: false },
|
|
845
|
-
vsock: { guest_cid: GUEST_CID, uds_path: paths.vsock }
|
|
856
|
+
vsock: { guest_cid: GUEST_CID, uds_path: paths.vsock },
|
|
857
|
+
"cpu-config": CPU_TEMPLATE
|
|
846
858
|
};
|
|
847
859
|
}
|
|
848
860
|
function firecrackerCommand(input) {
|
|
@@ -907,6 +919,7 @@ function createMicroVmPorts(over = {}) {
|
|
|
907
919
|
firecracker: over.firecracker ?? createFirecrackerHost(),
|
|
908
920
|
cgroup: over.cgroup ?? realCgroupPort(),
|
|
909
921
|
helper: over.helper ?? realHelperPort(),
|
|
922
|
+
fdStore: over.fdStore ?? realFdStorePort(),
|
|
910
923
|
exec: over.exec ?? execCapture
|
|
911
924
|
};
|
|
912
925
|
}
|
|
@@ -1048,6 +1061,11 @@ async function runBuildSteps(input) {
|
|
|
1048
1061
|
const delivered = await deliver(input, staged);
|
|
1049
1062
|
if (!delivered.ok) return delivered;
|
|
1050
1063
|
controlPlane = { repository: staged.repository, commit: staged.sha };
|
|
1064
|
+
try {
|
|
1065
|
+
if (input.keepIn !== void 0) keepStagedContext(staged, input.keepIn);
|
|
1066
|
+
} catch (err) {
|
|
1067
|
+
log.error(`${tag} the governed context could not be kept for the host's checks: ${describeCallFailure(err)} \xB7 they fetch it again`);
|
|
1068
|
+
}
|
|
1051
1069
|
log.line(`${tag} governed context ${staged.sha.slice(0, 7)} delivered to ${deliveryDir(staged.repository, staged.sha)} (${staged.files.length} files)`);
|
|
1052
1070
|
} finally {
|
|
1053
1071
|
input.removeStagedContext();
|
|
@@ -2090,6 +2108,9 @@ var V4 = [
|
|
|
2090
2108
|
["private", "10.0.0.0/8"],
|
|
2091
2109
|
["private", "172.16.0.0/12"],
|
|
2092
2110
|
["private", "192.168.0.0/16"],
|
|
2111
|
+
["protocol-assignments", "192.0.0.0/24"],
|
|
2112
|
+
["benchmarking", "198.18.0.0/15"],
|
|
2113
|
+
["azure-wireserver", "168.63.129.16/32"],
|
|
2093
2114
|
["link-local", "169.254.0.0/16"],
|
|
2094
2115
|
["shared-address", "100.64.0.0/10"],
|
|
2095
2116
|
["multicast", "224.0.0.0/4"],
|
|
@@ -2100,6 +2121,8 @@ var V6 = [
|
|
|
2100
2121
|
["loopback", "::1/128"],
|
|
2101
2122
|
["ipv4-mapped", "::ffff:0:0/96"],
|
|
2102
2123
|
["nat64", "64:ff9b::/96"],
|
|
2124
|
+
// The location of an embedded IPv4 address depends on the translator's prefix length, so the whole prefix is refused.
|
|
2125
|
+
["nat64-local", "64:ff9b:1::/48"],
|
|
2103
2126
|
["ipv4-compatible", "::/96"],
|
|
2104
2127
|
["link-local", "fe80::/10"],
|
|
2105
2128
|
["unique-local", "fc00::/7"],
|
|
@@ -2164,6 +2187,12 @@ function build6() {
|
|
|
2164
2187
|
var RANGES_4 = build4();
|
|
2165
2188
|
var RANGES_6 = build6();
|
|
2166
2189
|
[...RANGES_4, ...RANGES_6].map(({ name, cidr }) => ({ name, cidr }));
|
|
2190
|
+
function carried6to4(address) {
|
|
2191
|
+
const v6 = parseV6(address);
|
|
2192
|
+
if (v6 === void 0 || v6 >> BigInt(112) !== BigInt(8194)) return void 0;
|
|
2193
|
+
const v4 = Number(v6 >> BigInt(80) & BigInt(4294967295));
|
|
2194
|
+
return [v4 >>> 24, v4 >>> 16 & 255, v4 >>> 8 & 255, v4 & 255].join(".");
|
|
2195
|
+
}
|
|
2167
2196
|
function classifyAddress(address) {
|
|
2168
2197
|
const v4 = parseV4(address);
|
|
2169
2198
|
if (v4 !== void 0) {
|
|
@@ -2175,6 +2204,11 @@ function classifyAddress(address) {
|
|
|
2175
2204
|
}
|
|
2176
2205
|
const v6 = parseV6(address);
|
|
2177
2206
|
if (v6 === void 0) return UNPARSEABLE;
|
|
2207
|
+
const carries = carried6to4(address);
|
|
2208
|
+
if (carries !== void 0) {
|
|
2209
|
+
const inner = classifyAddress(carries);
|
|
2210
|
+
return inner === void 0 ? void 0 : { ...inner, carries };
|
|
2211
|
+
}
|
|
2178
2212
|
for (const range of RANGES_6) {
|
|
2179
2213
|
const shift = BigInt(128 - range.bits);
|
|
2180
2214
|
if (v6 >> shift === range.base >> shift) return { name: range.name, cidr: range.cidr };
|
|
@@ -2309,13 +2343,15 @@ async function startTunnel(socketPath, opts = {}) {
|
|
|
2309
2343
|
const own = new Set(ownAddresses().map(normalize));
|
|
2310
2344
|
let firstRefusal;
|
|
2311
2345
|
for (const { address: address2 } of addresses) {
|
|
2312
|
-
const
|
|
2346
|
+
const carried = carried6to4(address2);
|
|
2347
|
+
const range = own.has(normalize(address2)) || carried !== void 0 && own.has(carried) ? { name: "host-address", cidr: address2, ...carried === void 0 ? {} : { carries: carried } } : classifyAddress(address2);
|
|
2313
2348
|
if (range === void 0) return { ok: true, address: address2 };
|
|
2314
|
-
firstRefusal ??= { address: address2, name: range.name, cidr: range.cidr };
|
|
2349
|
+
firstRefusal ??= { address: address2, name: range.name, cidr: range.cidr, carries: range.carries };
|
|
2315
2350
|
}
|
|
2316
|
-
const { address, name, cidr } = firstRefusal;
|
|
2351
|
+
const { address, name, cidr, carries } = firstRefusal;
|
|
2317
2352
|
refused2(host, address, name);
|
|
2318
|
-
|
|
2353
|
+
const via = carries === void 0 ? "" : `, which carries ${carries}`;
|
|
2354
|
+
return { ok: false, status: 403, body: `refused: ${host} is ${address}${via}, in the ${name} range ${cidr}
|
|
2319
2355
|
` };
|
|
2320
2356
|
}
|
|
2321
2357
|
const sockets = /* @__PURE__ */ new Set();
|
|
@@ -2432,12 +2468,16 @@ ${body}`);
|
|
|
2432
2468
|
req.pipe(upstream);
|
|
2433
2469
|
}
|
|
2434
2470
|
if (opts.socket !== false) {
|
|
2435
|
-
if (
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2471
|
+
if (opts.listenOn !== void 0) {
|
|
2472
|
+
await opts.listenOn(server);
|
|
2473
|
+
} else {
|
|
2474
|
+
if (existsSync(socketPath)) unlinkSync(socketPath);
|
|
2475
|
+
await new Promise((resolveListen, reject) => {
|
|
2476
|
+
server.once("error", reject);
|
|
2477
|
+
server.listen(socketPath, () => resolveListen());
|
|
2478
|
+
});
|
|
2479
|
+
chmodSync(socketPath, 438);
|
|
2480
|
+
}
|
|
2441
2481
|
}
|
|
2442
2482
|
const tcpServers = [];
|
|
2443
2483
|
return {
|
|
@@ -2445,6 +2485,7 @@ ${body}`);
|
|
|
2445
2485
|
record,
|
|
2446
2486
|
destinationUsed,
|
|
2447
2487
|
acceptStream: (stream) => void server.emit("connection", stream),
|
|
2488
|
+
listener: () => opts.socket === false ? void 0 : server,
|
|
2448
2489
|
async listenTcp(address) {
|
|
2449
2490
|
const tcp = createServer$1((socket) => server.emit("connection", socket));
|
|
2450
2491
|
await new Promise((resolveListen, reject) => {
|
|
@@ -2883,7 +2924,8 @@ async function provisionContainer(input) {
|
|
|
2883
2924
|
const delivered = await deliverJobFiles(runtime, state, ["context"], secrets);
|
|
2884
2925
|
return delivered.ok ? delivered : { ok: false, reason: `context_unavailable: ${delivered.reason}` };
|
|
2885
2926
|
},
|
|
2886
|
-
removeStagedContext: () => removeStagedContext(buildDir2)
|
|
2927
|
+
removeStagedContext: () => removeStagedContext(buildDir2),
|
|
2928
|
+
keepIn: jobDir
|
|
2887
2929
|
});
|
|
2888
2930
|
if (!steps.ok) return bail(steps.reason, steps.aborted === true);
|
|
2889
2931
|
state.startCommit = steps.startCommit;
|
|
@@ -2972,16 +3014,28 @@ async function stopContainer(runtime, state) {
|
|
|
2972
3014
|
await runtime.host.stop(state.container);
|
|
2973
3015
|
state.stopped = true;
|
|
2974
3016
|
}
|
|
3017
|
+
var DISK_CHECK_MS = 12e4;
|
|
2975
3018
|
async function measureDisk(runtime, state) {
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
env: NO_ENV,
|
|
2980
|
-
argv: ["du", "-skx", "/build"]
|
|
3019
|
+
let timer;
|
|
3020
|
+
const late = new Promise((resolve) => {
|
|
3021
|
+
timer = setTimeout(() => resolve({ failure: "du ran past 2 minutes" }), DISK_CHECK_MS);
|
|
2981
3022
|
});
|
|
2982
|
-
|
|
3023
|
+
try {
|
|
3024
|
+
const run = runtime.host.exec(
|
|
3025
|
+
{
|
|
3026
|
+
container: state.container,
|
|
3027
|
+
user: state.agentUser ?? ADDED_USER,
|
|
3028
|
+
env: { literals: { LC_ALL: "C" }, passed: {} },
|
|
3029
|
+
argv: ["du", "-skx", "/build"]
|
|
3030
|
+
},
|
|
3031
|
+
{ timeoutMs: DISK_CHECK_MS + 1e4 }
|
|
3032
|
+
).then(readDu, (err) => ({ failure: `docker exec did not run: ${err instanceof Error ? err.message.slice(0, 200) : "unknown error"}` }));
|
|
3033
|
+
return await Promise.race([run, late]);
|
|
3034
|
+
} finally {
|
|
3035
|
+
clearTimeout(timer);
|
|
3036
|
+
}
|
|
2983
3037
|
}
|
|
2984
|
-
async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, builtIns, gitRemote, serve = "socket", lease) {
|
|
3038
|
+
async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, builtIns, gitRemote, serve = "socket", lease, inherit) {
|
|
2985
3039
|
return startBuildServices({
|
|
2986
3040
|
startTunnel: runtime.startTunnel,
|
|
2987
3041
|
tunnelOptions: { ...runtime.tunnelOptions, ...gitRemote === void 0 ? {} : { gitRemote } },
|
|
@@ -2991,6 +3045,7 @@ async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, bui
|
|
|
2991
3045
|
allowHosts: config.build?.allowHosts,
|
|
2992
3046
|
serve,
|
|
2993
3047
|
...lease === void 0 ? {} : { lease },
|
|
3048
|
+
...inherit === void 0 ? {} : { inherit },
|
|
2994
3049
|
...builtIns ? { builtIns: { gatewayUrl: config.url, itemKey, claudeUpstream: runtime.claudeUpstream } } : {},
|
|
2995
3050
|
hostEnv: runtime.hostEnv,
|
|
2996
3051
|
destinationOptions: runtime.destinationOptions
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
|
|
4
|
+
createRequire(import.meta.url);
|
|
5
|
+
|
|
6
|
+
// src/runner/container/disk.ts
|
|
7
|
+
var UNITS = { "": 1, k: 1024, m: 1024 ** 2, g: 1024 ** 3 };
|
|
8
|
+
function parseSize(text) {
|
|
9
|
+
const match = /^(\d+(?:\.\d+)?)([kKmMgG]?)$/.exec(text);
|
|
10
|
+
if (match === null) return void 0;
|
|
11
|
+
const bytes = Number(match[1]) * UNITS[match[2].toLowerCase()];
|
|
12
|
+
return bytes > 0 ? bytes : void 0;
|
|
13
|
+
}
|
|
14
|
+
function exceedsDisk(usedKilobytes, limit) {
|
|
15
|
+
const bytes = parseSize(limit);
|
|
16
|
+
return usedKilobytes * 1024 > (bytes ?? Number.POSITIVE_INFINITY);
|
|
17
|
+
}
|
|
18
|
+
var TOTAL = /^(\d+)\t\/build$/;
|
|
19
|
+
var GONE = /: No such file or directory$/;
|
|
20
|
+
var LINE_MAX = 200;
|
|
21
|
+
function readDu(result) {
|
|
22
|
+
const stdoutLines = result.stdout.split("\n");
|
|
23
|
+
const totalAt = stdoutLines.map((line) => TOTAL.test(line)).lastIndexOf(true);
|
|
24
|
+
const kib = totalAt === -1 ? void 0 : Number(TOTAL.exec(stdoutLines[totalAt])[1]);
|
|
25
|
+
const lines = [...result.stderr.split("\n"), ...stdoutLines.filter((_, index) => index !== totalAt)].map((line) => line.trim()).filter((line) => line !== "");
|
|
26
|
+
const other = lines.find((line) => !GONE.test(line));
|
|
27
|
+
if (kib !== void 0 && result.status === 0) return { kib };
|
|
28
|
+
if (kib !== void 0 && other === void 0 && lines.length > 0) return { kib };
|
|
29
|
+
const detail = other === void 0 ? "" : `: ${cut(other.replace(/[\u0000-\u001f\u007f]/g, " "))}`;
|
|
30
|
+
return { ...kib === void 0 ? {} : { kib }, failure: `docker exec exited ${result.status}${detail}` };
|
|
31
|
+
}
|
|
32
|
+
function cut(line) {
|
|
33
|
+
const head = line.slice(0, LINE_MAX);
|
|
34
|
+
const last = head.charCodeAt(head.length - 1);
|
|
35
|
+
return last >= 55296 && last <= 56319 ? head.slice(0, -1) : head;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { exceedsDisk, parseSize, readDu };
|