@outerlayer/cli 0.2.0 → 0.4.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 +124 -0
- package/README.md +226 -59
- package/dist/agent-setup-IFH3FB5X.js +197 -0
- package/dist/build-TZUUTRGH.js +9 -0
- package/dist/build-info.json +1 -1
- package/dist/check-WQP2CZDW.js +94 -0
- package/dist/chunk-2E54Z3P5.js +232 -0
- package/dist/chunk-3TT7RQYB.js +55 -0
- package/dist/{chunk-U32VSRLO.js → chunk-3YPKXE5L.js} +90 -632
- package/dist/{chunk-Q6CL5THG.js → chunk-5DLBAXY5.js} +208 -61
- package/dist/{chunk-R5KBGVII.js → chunk-5QRP3MVS.js} +30 -14
- package/dist/chunk-5Y3QQRUH.js +300 -0
- package/dist/chunk-6Y63SXFO.js +383 -0
- package/dist/chunk-774HEQL6.js +178 -0
- package/dist/chunk-7A6RVXPZ.js +2233 -0
- package/dist/chunk-7YIOOFVJ.js +71 -0
- package/dist/chunk-ABIWDUMS.js +104 -0
- package/dist/chunk-AUFG23AA.js +534 -0
- package/dist/chunk-B2G7JHHB.js +42 -0
- package/dist/chunk-BCJNHMZT.js +34 -0
- package/dist/chunk-BCLJSQCV.js +56 -0
- package/dist/chunk-BFESLKPP.js +61 -0
- package/dist/chunk-BJ3KTMDH.js +63 -0
- package/dist/chunk-BKO6JEZI.js +47 -0
- package/dist/chunk-BOLTI6LR.js +37 -0
- package/dist/chunk-CBPPJSAR.js +89 -0
- package/dist/chunk-CBZB6XY6.js +102 -0
- package/dist/{chunk-65WXAANR.js → chunk-DVDEBNQJ.js} +17 -2
- package/dist/{work-pr-cmd-AZQPWH4H.js → chunk-DVYHCMB2.js} +9 -26
- package/dist/{chunk-TFUIDMOB.js → chunk-EABW6AJQ.js} +12 -1
- package/dist/{chunk-KFYJV2ZG.js → chunk-EMY4I27X.js} +1 -1
- package/dist/{chunk-NTTPJV35.js → chunk-F47JBIAW.js} +3 -1
- package/dist/chunk-F6GFZXZ3.js +60 -0
- package/dist/{chunk-YOOSBOKS.js → chunk-F7CU5ABH.js} +1 -1
- package/dist/chunk-FAJSS2WN.js +1357 -0
- package/dist/chunk-FS2VYGZT.js +1764 -0
- package/dist/chunk-FV2CCGXK.js +9 -0
- package/dist/{chunk-4TNZMO7V.js → chunk-G7FSV7JX.js} +3452 -751
- package/dist/{emit-cmd-TWSYYEZI.js → chunk-H5NCNVDA.js} +68 -17
- package/dist/chunk-HE2D4EY5.js +83 -0
- package/dist/chunk-L2DBRKRA.js +94 -0
- package/dist/chunk-LF6MLJCY.js +38 -0
- package/dist/chunk-M5POMKKW.js +1051 -0
- package/dist/{mcp-install-cmd-FDQH6SEN.js → chunk-MQ3IPHIZ.js} +35 -18
- package/dist/{chunk-D77LS3UI.js → chunk-N5FOE5PS.js} +33 -4
- package/dist/chunk-N6LURUEF.js +64 -0
- package/dist/chunk-NYC54VBD.js +1084 -0
- package/dist/chunk-OGFGZQA3.js +23 -0
- package/dist/chunk-QOZKPLVJ.js +226 -0
- package/dist/chunk-RA3O54FC.js +30 -0
- package/dist/chunk-TBT347UY.js +41 -0
- package/dist/{chunk-NXLLURA4.js → chunk-UFFXNXLQ.js} +115 -71
- package/dist/chunk-USO2DKBD.js +421 -0
- package/dist/chunk-W4SQCOZU.js +206 -0
- package/dist/{chunk-A3WLZX2F.js → chunk-WIOZAJ2W.js} +15 -2
- package/dist/chunk-WO2BXCTQ.js +83 -0
- package/dist/{chunk-I3ETLSNE.js → chunk-XCCLFVXM.js} +120 -11
- package/dist/{context-materialize-6WKT3RBQ.js → chunk-XDDW4FRS.js} +134 -26
- package/dist/chunk-YYYXRJUW.js +101 -0
- package/dist/chunk-ZM2IMMYN.js +76 -0
- package/dist/chunk-ZMYPLFG3.js +71 -0
- package/dist/chunk-ZNA27WEV.js +470 -0
- package/dist/{cli-G7DILYJY.js → cli-NHUXABYH.js} +590 -876
- package/dist/{paths-D2VGWWFI.js → cli-build-K56DK4DS.js} +1 -1
- package/dist/config-XVJYZ4IQ.js +9 -0
- package/dist/connect-cmd-OOG4TPU7.js +16 -0
- package/dist/context-adopt-UMA4O5NY.js +105 -0
- package/dist/context-materialize-G2FUFC72.js +19 -0
- package/dist/dist-RW4UPPC2.js +6 -0
- package/dist/docker-NEGDLU6D.js +7 -0
- package/dist/doctor-53F2PYY7.js +43 -0
- package/dist/doctor-UFVL4PZY.js +426 -0
- package/dist/{emit-artifact-cmd-UQVT3OKW.js → emit-artifact-cmd-KTYW2TN2.js} +24 -20
- package/dist/emit-cmd-DCERAU27.js +9 -0
- package/dist/emit-criteria-cmd-VAUUSAYD.js +166 -0
- package/dist/{emit-finding-cmd-FDOU2OPD.js → emit-finding-cmd-UR4ID45Z.js} +34 -31
- package/dist/{emit-result-cmd-H2T4C2K3.js → emit-result-cmd-FDTUKGKE.js} +34 -62
- package/dist/exec-client-4XGXV3XN.js +8 -0
- package/dist/guest-init-GENRHNP7.js +8 -0
- package/dist/hook-fast-EYENPK6F.js +9 -0
- package/dist/{hook-wrap-fast-KXYNX3AD.js → hook-wrap-fast-NPLHJXFK.js} +2 -2
- package/dist/host-key-KDYZ5ECC.js +7 -0
- package/dist/import-capture-cmd-AVZ4VIVJ.js +68 -0
- package/dist/{import-ruler-cmd-7LH2QOMG.js → import-ruler-cmd-GUHL6IY5.js} +1 -1
- package/dist/index.js +4 -4
- package/dist/init-DXBCOAJK.js +36 -0
- package/dist/init-YEXK35CF.js +221 -0
- package/dist/init-cmd-NHR7PRSQ.js +135 -0
- package/dist/install-cmd-7WXOIFDO.js +55 -0
- package/dist/lima-XN65D7GN.js +55 -0
- package/dist/login-browser-7XGSV7MA.js +10 -0
- package/dist/{config-POF7DEQW.js → logout-cmd-QAUFDJ6J.js} +3 -1
- package/dist/{logs-TRNPQM42.js → logs-7RYUH5A6.js} +1 -1
- package/dist/loop-VZOLL4WQ.js +43 -0
- package/dist/machine-WSG52J75.js +35 -0
- package/dist/mcp-install-cmd-RLK4SO3N.js +9 -0
- package/dist/{mcp-serve-cmd-57EZZOTL.js → mcp-serve-cmd-JPTP5FMS.js} +20 -9
- package/dist/paths-OYKMVYJP.js +6 -0
- package/dist/{pidfile-PTW76F56.js → pidfile-UZRH774M.js} +2 -3
- package/dist/real-deps-SU24ZA2K.js +21 -0
- package/dist/relay-L76HDX72.js +46 -0
- package/dist/settings-J2652U5N.js +7 -0
- package/dist/starter-pack-LIZYMKYQ.js +10 -0
- package/dist/{status-I27IST4L.js → status-2UZKKNB7.js} +30 -13
- package/dist/{statusline-fast-3C5OXHDD.js → statusline-fast-SVTMBMD7.js} +3 -2
- package/dist/sync-cmd-VPPYCNNM.js +28 -0
- package/dist/version-BWM6VLDI.js +6 -0
- package/dist/{watch-3DTPJETH.js → watch-5C4ZBBGO.js} +19 -8
- package/dist/{work-claim-cmd-5AUNCLS2.js → work-claim-cmd-LSO2B2EX.js} +33 -20
- package/dist/work-cmd-UOQO2AD4.js +17 -0
- package/dist/work-comment-cmd-WF3EOLAE.js +106 -0
- package/dist/{work-launch-LT663PB3.js → work-launch-YI4CJDAP.js} +1 -1
- package/dist/work-open-pr-cmd-4SSQZMYG.js +156 -0
- package/dist/work-pr-cmd-6AN6RRQJ.js +16 -0
- package/package.json +13 -3
- package/skill-pack/maintained/amend/SKILL.md +104 -0
- package/skill-pack/maintained/emitting-evidence/SKILL.md +99 -0
- package/skill-pack/maintained/emitting-evidence/references/agents-snippet.md +20 -0
- package/skill-pack/maintained/outerlayer/SKILL.md +55 -0
- package/skill-pack/maintained/reporting-findings/SKILL.md +148 -0
- package/skill-pack/template/build/SKILL.md +193 -0
- package/skill-pack/template/build/references/agent-briefs.md +243 -0
- package/skill-pack/template/build/references/criteria-judge.md +91 -0
- package/skill-pack/template/build/references/evidence.md +42 -0
- package/skill-pack/template/build/references/release.md +74 -0
- package/skill-pack/template/build/references/review-briefs.md +275 -0
- package/skill-pack/template/build/references/review-loop.md +158 -0
- package/skill-pack/template/build/scripts/record-criteria.mjs +235 -0
- package/skill-pack/template/spec/SKILL.md +84 -0
- package/skill-pack/template/writing-specs/SKILL.md +134 -0
- package/dist/chunk-DCNOXRMV.js +0 -589
- package/dist/chunk-JJP7YLMN.js +0 -25
- package/dist/chunk-OZ7C3XUE.js +0 -34
- package/dist/chunk-WQ6VGRGZ.js +0 -150
- package/dist/hook-fast-J5LCDHUJ.js +0 -8
- package/dist/import-capture-cmd-EUMBGIV3.js +0 -176
- package/dist/init-PTBITAUO.js +0 -103
- package/dist/login-cmd-IRX6LZT7.js +0 -62
- package/dist/loop-ASZRX3CZ.js +0 -648
- package/dist/sync-cmd-BBAUZ5JD.js +0 -17
- package/dist/work-cmd-2P4BVX47.js +0 -18
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-WO2BXCTQ.js';
|
|
4
|
+
import './chunk-EMY4I27X.js';
|
|
5
|
+
import './chunk-RA3O54FC.js';
|
|
6
|
+
import './chunk-Z5GEFMRW.js';
|
|
7
|
+
import { statSync, existsSync, readFileSync, writeFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
|
|
10
|
+
createRequire(import.meta.url);
|
|
11
|
+
var GREEN = "\x1B[32m";
|
|
12
|
+
var DIM = "\x1B[2m";
|
|
13
|
+
var YELLOW = "\x1B[33m";
|
|
14
|
+
var RESET = "\x1B[0m";
|
|
15
|
+
var ImportCaptureError = class extends Error {
|
|
16
|
+
};
|
|
17
|
+
var SNIPPET_PATH = ".outerlayer/skills/emitting-evidence/references/agents-snippet.md";
|
|
18
|
+
var AGENTS_MD_PATH = ".outerlayer/AGENTS.md";
|
|
19
|
+
var AGENTS_MD_MARKER = "<!-- outerlayer:capture-pack -->";
|
|
20
|
+
function runImportCapture(opts = {}) {
|
|
21
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
22
|
+
let cwdStat;
|
|
23
|
+
try {
|
|
24
|
+
cwdStat = statSync(cwd);
|
|
25
|
+
} catch {
|
|
26
|
+
throw new ImportCaptureError(`no such directory: ${cwd}`);
|
|
27
|
+
}
|
|
28
|
+
if (!cwdStat.isDirectory()) throw new ImportCaptureError(`not a directory: ${cwd}`);
|
|
29
|
+
const bundle = loadMaintainedFiles();
|
|
30
|
+
const { created: files, rewritten } = writeMaintainedFiles(cwd, bundle);
|
|
31
|
+
const snippet = bundle.find((f) => f.path === SNIPPET_PATH)?.content ?? "";
|
|
32
|
+
let appendedAgentsMd = false;
|
|
33
|
+
const agentsMdAbs = join(cwd, AGENTS_MD_PATH);
|
|
34
|
+
if (existsSync(agentsMdAbs)) {
|
|
35
|
+
const existing = readFileSync(agentsMdAbs, "utf8");
|
|
36
|
+
if (!existing.includes(AGENTS_MD_MARKER)) {
|
|
37
|
+
writeFileSync(agentsMdAbs, existing + "\n" + snippet);
|
|
38
|
+
appendedAgentsMd = true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
let output;
|
|
42
|
+
if (opts.json) {
|
|
43
|
+
output = JSON.stringify({ files, rewritten, appendedAgentsMd });
|
|
44
|
+
} else {
|
|
45
|
+
const lines = [
|
|
46
|
+
...files.map((f) => `${GREEN}\u2713${RESET} wrote ${f}`),
|
|
47
|
+
...rewritten.map((f) => `${YELLOW}!${RESET} rewrote ${f} to match this CLI's bundle (local edits were overwritten)`)
|
|
48
|
+
];
|
|
49
|
+
if (appendedAgentsMd) lines.push(`${GREEN}\u2713${RESET} appended the evidence snippet to ${AGENTS_MD_PATH}`);
|
|
50
|
+
if (files.length === 0 && rewritten.length === 0 && !appendedAgentsMd) {
|
|
51
|
+
lines.push(`${DIM}capture pack already installed \u2014 nothing to write${RESET}`);
|
|
52
|
+
}
|
|
53
|
+
lines.push(`Run ${YELLOW}\`outerlayer emit\`${RESET} to compile the pack into your agent's native files.`);
|
|
54
|
+
output = lines.join("\n");
|
|
55
|
+
}
|
|
56
|
+
if (!opts.quiet) {
|
|
57
|
+
process.stdout.write(output + "\n");
|
|
58
|
+
if (!opts.json && !appendedAgentsMd && !existsSync(agentsMdAbs)) {
|
|
59
|
+
process.stdout.write(
|
|
60
|
+
`${DIM} no ${AGENTS_MD_PATH} to append to \u2014 paste ${SNIPPET_PATH} into your instructions file if your harness reads no skills${RESET}
|
|
61
|
+
`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { files, rewritten, appendedAgentsMd, output };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { ImportCaptureError, runImportCapture };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { normalizePath } from './chunk-
|
|
3
|
+
import { normalizePath } from './chunk-EMY4I27X.js';
|
|
4
4
|
import './chunk-Z5GEFMRW.js';
|
|
5
5
|
import { existsSync, readdirSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
6
6
|
import { join, dirname } from 'path';
|
package/dist/index.js
CHANGED
|
@@ -6,20 +6,20 @@ createRequire(import.meta.url);
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
var argv = process.argv.slice(2);
|
|
8
8
|
if (argv[0] === "hook") {
|
|
9
|
-
const { runHookFast } = await import('./hook-fast-
|
|
9
|
+
const { runHookFast } = await import('./hook-fast-EYENPK6F.js');
|
|
10
10
|
await runHookFast(argv[1]);
|
|
11
11
|
process.exit(0);
|
|
12
12
|
}
|
|
13
13
|
if (argv[0] === "hook-wrap") {
|
|
14
|
-
const { runHookWrapFast, parseHookWrapArgs } = await import('./hook-wrap-fast-
|
|
14
|
+
const { runHookWrapFast, parseHookWrapArgs } = await import('./hook-wrap-fast-NPLHJXFK.js');
|
|
15
15
|
const { id, captureOutput } = parseHookWrapArgs(argv.slice(1));
|
|
16
16
|
const code = await runHookWrapFast(id, { captureOutput });
|
|
17
17
|
process.exit(code);
|
|
18
18
|
}
|
|
19
19
|
if (argv[0] === "statusline") {
|
|
20
|
-
const { runStatuslineFast } = await import('./statusline-fast-
|
|
20
|
+
const { runStatuslineFast } = await import('./statusline-fast-SVTMBMD7.js');
|
|
21
21
|
await runStatuslineFast(argv.slice(1));
|
|
22
22
|
process.exit(0);
|
|
23
23
|
}
|
|
24
|
-
var { runCli } = await import('./cli-
|
|
24
|
+
var { runCli } = await import('./cli-NHUXABYH.js');
|
|
25
25
|
await runCli(process.argv);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
export { PLACEHOLDER_MARKER, RunnerInitError, isPlaceholderCommand, readConfigObject, runRunnerInit } from './chunk-CBZB6XY6.js';
|
|
4
|
+
import './chunk-L2DBRKRA.js';
|
|
5
|
+
import './chunk-7A6RVXPZ.js';
|
|
6
|
+
import './chunk-ZNA27WEV.js';
|
|
7
|
+
import './chunk-N5FOE5PS.js';
|
|
8
|
+
import './chunk-OGFGZQA3.js';
|
|
9
|
+
import './chunk-774HEQL6.js';
|
|
10
|
+
import './chunk-QOZKPLVJ.js';
|
|
11
|
+
import './chunk-W4SQCOZU.js';
|
|
12
|
+
import './chunk-B2G7JHHB.js';
|
|
13
|
+
import './chunk-5DLBAXY5.js';
|
|
14
|
+
import './chunk-BFESLKPP.js';
|
|
15
|
+
import './chunk-6Y63SXFO.js';
|
|
16
|
+
import './chunk-G7FSV7JX.js';
|
|
17
|
+
import './chunk-F6GFZXZ3.js';
|
|
18
|
+
import './chunk-AUFG23AA.js';
|
|
19
|
+
import './chunk-WZBHBH3J.js';
|
|
20
|
+
import './chunk-XDDW4FRS.js';
|
|
21
|
+
import './chunk-WIOZAJ2W.js';
|
|
22
|
+
import './chunk-WO2BXCTQ.js';
|
|
23
|
+
import './chunk-EMY4I27X.js';
|
|
24
|
+
import './chunk-ZJSNLVCE.js';
|
|
25
|
+
import './chunk-BCLJSQCV.js';
|
|
26
|
+
import './chunk-BOLTI6LR.js';
|
|
27
|
+
import './chunk-EABW6AJQ.js';
|
|
28
|
+
import './chunk-RA3O54FC.js';
|
|
29
|
+
import './chunk-M5POMKKW.js';
|
|
30
|
+
import './chunk-ZM2IMMYN.js';
|
|
31
|
+
import './chunk-XCCLFVXM.js';
|
|
32
|
+
import './chunk-BJ3KTMDH.js';
|
|
33
|
+
import './chunk-VNVZDWO3.js';
|
|
34
|
+
import './chunk-Z5GEFMRW.js';
|
|
35
|
+
|
|
36
|
+
createRequire(import.meta.url);
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { execStartCommand } from './chunk-YYYXRJUW.js';
|
|
4
|
+
import { writeLaunchAgent } from './chunk-LF6MLJCY.js';
|
|
5
|
+
import { readConfigObject, RunnerInitError, isPlaceholderCommand } from './chunk-CBZB6XY6.js';
|
|
6
|
+
import './chunk-L2DBRKRA.js';
|
|
7
|
+
import './chunk-7A6RVXPZ.js';
|
|
8
|
+
import './chunk-ZNA27WEV.js';
|
|
9
|
+
import './chunk-N5FOE5PS.js';
|
|
10
|
+
import './chunk-OGFGZQA3.js';
|
|
11
|
+
import './chunk-774HEQL6.js';
|
|
12
|
+
import './chunk-QOZKPLVJ.js';
|
|
13
|
+
import './chunk-W4SQCOZU.js';
|
|
14
|
+
import './chunk-B2G7JHHB.js';
|
|
15
|
+
import './chunk-5DLBAXY5.js';
|
|
16
|
+
import './chunk-BFESLKPP.js';
|
|
17
|
+
import './chunk-6Y63SXFO.js';
|
|
18
|
+
import './chunk-G7FSV7JX.js';
|
|
19
|
+
import { resolveBuild } from './chunk-5Y3QQRUH.js';
|
|
20
|
+
import { parseSize } from './chunk-F6GFZXZ3.js';
|
|
21
|
+
import './chunk-AUFG23AA.js';
|
|
22
|
+
import './chunk-WZBHBH3J.js';
|
|
23
|
+
import './chunk-XDDW4FRS.js';
|
|
24
|
+
import './chunk-WIOZAJ2W.js';
|
|
25
|
+
import './chunk-WO2BXCTQ.js';
|
|
26
|
+
import './chunk-EMY4I27X.js';
|
|
27
|
+
import './chunk-ZJSNLVCE.js';
|
|
28
|
+
import './chunk-BCLJSQCV.js';
|
|
29
|
+
import './chunk-BOLTI6LR.js';
|
|
30
|
+
import './chunk-EABW6AJQ.js';
|
|
31
|
+
import './chunk-RA3O54FC.js';
|
|
32
|
+
import './chunk-M5POMKKW.js';
|
|
33
|
+
import { hostKeyPath } from './chunk-ZM2IMMYN.js';
|
|
34
|
+
import './chunk-XCCLFVXM.js';
|
|
35
|
+
import './chunk-BJ3KTMDH.js';
|
|
36
|
+
import './chunk-VNVZDWO3.js';
|
|
37
|
+
import './chunk-Z5GEFMRW.js';
|
|
38
|
+
import { readFileSync, writeFileSync, existsSync, rmSync } from 'fs';
|
|
39
|
+
|
|
40
|
+
createRequire(import.meta.url);
|
|
41
|
+
|
|
42
|
+
// src/runner/vm/service.ts
|
|
43
|
+
var VM_SERVICE_NAME = "outerlayer-runner";
|
|
44
|
+
var STOP_MARGIN_MINUTES = 10;
|
|
45
|
+
function runnerUnit(unit) {
|
|
46
|
+
const dir = `${unit.home}/.outerlayer`;
|
|
47
|
+
return `[Unit]
|
|
48
|
+
Description=OuterLayer runner
|
|
49
|
+
After=network-online.target docker.service
|
|
50
|
+
Wants=network-online.target
|
|
51
|
+
Requires=docker.service
|
|
52
|
+
|
|
53
|
+
[Service]
|
|
54
|
+
User=${unit.user}
|
|
55
|
+
ExecStart=${unit.execStart}
|
|
56
|
+
EnvironmentFile=-${dir}/runner.env
|
|
57
|
+
Restart=on-failure
|
|
58
|
+
RestartForceExitStatus=75
|
|
59
|
+
RestartSec=30
|
|
60
|
+
KillSignal=SIGTERM
|
|
61
|
+
KillMode=mixed
|
|
62
|
+
TimeoutStopSec=${unit.timeLimitMinutes + STOP_MARGIN_MINUTES}min
|
|
63
|
+
|
|
64
|
+
[Install]
|
|
65
|
+
WantedBy=multi-user.target
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/runner/vm/sizing.ts
|
|
70
|
+
var GIB = 1024 ** 3;
|
|
71
|
+
var EXTRA_CPUS = 1;
|
|
72
|
+
var EXTRA_MEMORY_GIB = 2;
|
|
73
|
+
var EXTRA_DISK_GIB = 30;
|
|
74
|
+
var gib = (size) => parseSize(size) / GIB;
|
|
75
|
+
function sizeVm(build, concurrency, host) {
|
|
76
|
+
return {
|
|
77
|
+
cpus: Math.max(1, Math.min(Math.ceil(build.cpus * concurrency) + EXTRA_CPUS, host.cpus)),
|
|
78
|
+
memoryGiB: Math.max(1, Math.min(Math.ceil(gib(build.memory) * concurrency) + EXTRA_MEMORY_GIB, Math.floor(host.memoryBytes / GIB))),
|
|
79
|
+
diskGiB: Math.ceil(gib(build.disk) * concurrency) + EXTRA_DISK_GIB
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/runner/vm/init.ts
|
|
84
|
+
var VM_INSTANCE = "outerlayer-runner";
|
|
85
|
+
var VmInitError = class extends Error {
|
|
86
|
+
};
|
|
87
|
+
var MIN_NODE_MAJOR = 22;
|
|
88
|
+
var DEFAULT_TIME_LIMIT_MINUTES = 480;
|
|
89
|
+
var TARBALL_IN_VM = "/tmp/outerlayer-cli.tgz";
|
|
90
|
+
var NODE_VERSION = /^v(\d+)\./;
|
|
91
|
+
var quote = (text) => `'${text.replace(/'/g, `'\\''`)}'`;
|
|
92
|
+
function commandsAreReal(block) {
|
|
93
|
+
const commands = block?.commands ?? {};
|
|
94
|
+
const given = [commands.implement, commands.amend].filter((command) => typeof command === "string");
|
|
95
|
+
return given.length > 0 && given.every((command) => !isPlaceholderCommand(command));
|
|
96
|
+
}
|
|
97
|
+
async function runVmInit(configPath, deps) {
|
|
98
|
+
const { lima } = deps;
|
|
99
|
+
const instance = deps.instance ?? VM_INSTANCE;
|
|
100
|
+
const progress = deps.progress ?? (() => void 0);
|
|
101
|
+
const limactl = lima.locate();
|
|
102
|
+
if (limactl === void 0) {
|
|
103
|
+
throw new VmInitError(
|
|
104
|
+
"limactl is not installed, and the Linux VM needs it. Install Lima with `brew install lima` (https://lima-vm.io/docs/installation/), then run this again."
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const config = readConfigObject(configPath);
|
|
108
|
+
const noted = config.runnerVm;
|
|
109
|
+
if (noted !== void 0) {
|
|
110
|
+
throw new RunnerInitError(
|
|
111
|
+
`${configPath}: the runner already lives in the VM ${noted.instance}. Start it with \`limactl start ${noted.instance}\`, or remove the runnerVm key after deleting the VM.`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (typeof config.url !== "string" || typeof config.apiKey !== "string" || typeof config.appId !== "string") {
|
|
115
|
+
throw new RunnerInitError(`${configPath}: url, apiKey and appId are needed to move the runner into a VM. Run \`outerlayer login\` first.`);
|
|
116
|
+
}
|
|
117
|
+
const block = config.runner;
|
|
118
|
+
const { hooks: _ownHooks, ...carried } = block ?? {};
|
|
119
|
+
for (const hook of [block?.hooks?.provision, block?.hooks?.cleanup]) {
|
|
120
|
+
if (hook !== void 0 && hook !== "builtin:process") {
|
|
121
|
+
throw new RunnerInitError(
|
|
122
|
+
`${configPath}: the runner block names its own hooks (${hook}), and only a builtin:process block moves into the VM. Remove the block and run this again.`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (lima.status(instance) !== void 0) {
|
|
127
|
+
throw new VmInitError(
|
|
128
|
+
`a Lima instance named ${instance} already exists. Delete it with \`limactl delete --force ${instance}\`, or use it, then run this again.`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const build = resolveBuild(configPath, carried.build);
|
|
132
|
+
const concurrency = typeof carried.concurrency === "number" ? carried.concurrency : 1;
|
|
133
|
+
const timeLimitMinutes = typeof carried.timeLimitMinutes === "number" ? carried.timeLimitMinutes : DEFAULT_TIME_LIMIT_MINUTES;
|
|
134
|
+
const size = sizeVm(build, concurrency, { cpus: deps.hostCpus, memoryBytes: deps.hostMemoryBytes });
|
|
135
|
+
const leftBehind = `The VM ${instance} was left as it is; delete it with \`limactl delete --force ${instance}\` to start over.`;
|
|
136
|
+
const failed = (what, result) => new VmInitError(`${what} failed: ${result.stderr.trim() || result.stdout.trim() || `exit status ${result.status}`}. ${leftBehind}`);
|
|
137
|
+
const sh = async (argv, stdin) => {
|
|
138
|
+
const result = await lima.shell(instance, argv, stdin === void 0 ? void 0 : { stdin });
|
|
139
|
+
if (result.status !== 0) throw failed(`the VM step \`${argv.join(" ")}\``, result);
|
|
140
|
+
return result.stdout;
|
|
141
|
+
};
|
|
142
|
+
progress(`creating the Linux VM ${instance}: this downloads an image and can take several minutes`);
|
|
143
|
+
const created = await lima.create({ instance, cpus: size.cpus, memoryGiB: size.memoryGiB, diskGiB: size.diskGiB });
|
|
144
|
+
if (created.status !== 0) throw failed("`limactl create`", created);
|
|
145
|
+
progress("starting the VM");
|
|
146
|
+
const started = await lima.start(instance);
|
|
147
|
+
if (started.status !== 0) throw failed("`limactl start`", started);
|
|
148
|
+
const user = (await sh(["id", "-un"])).trim();
|
|
149
|
+
const home = (await sh(["printenv", "HOME"])).trim();
|
|
150
|
+
progress("installing Node and the OuterLayer CLI in the VM");
|
|
151
|
+
await sh(["sudo", "apt-get", "update"]);
|
|
152
|
+
await sh(["sudo", "apt-get", "install", "-y", "nodejs", "npm"]);
|
|
153
|
+
const node = (await sh(["node", "--version"])).trim();
|
|
154
|
+
if (!(Number(NODE_VERSION.exec(node)?.[1]) >= MIN_NODE_MAJOR)) {
|
|
155
|
+
throw new VmInitError(`the VM's Node is ${node}, and the runner needs Node ${MIN_NODE_MAJOR} or later. ${leftBehind}`);
|
|
156
|
+
}
|
|
157
|
+
if (deps.cliPackage === void 0) {
|
|
158
|
+
await sh(["sudo", "npm", "install", "--global", `@outerlayer/cli@${deps.version}`]);
|
|
159
|
+
} else {
|
|
160
|
+
await sh(["sh", "-c", `cat > ${TARBALL_IN_VM} && sudo npm install --global ${TARBALL_IN_VM}`], readFileSync(deps.cliPackage));
|
|
161
|
+
}
|
|
162
|
+
await sh(["sudo", "usermod", "-aG", "docker", user]);
|
|
163
|
+
const outerlayer = (await sh(["sh", "-c", "command -v outerlayer"])).trim();
|
|
164
|
+
progress("setting up the runner in the VM");
|
|
165
|
+
const vmConfig = `${home}/.outerlayer/config.json`;
|
|
166
|
+
const handoff = {
|
|
167
|
+
url: config.url,
|
|
168
|
+
apiKey: config.apiKey,
|
|
169
|
+
appId: config.appId,
|
|
170
|
+
...config.repos === void 0 ? {} : { repos: config.repos },
|
|
171
|
+
...config.scrub === void 0 ? {} : { scrub: config.scrub },
|
|
172
|
+
...block === void 0 ? {} : { runner: carried }
|
|
173
|
+
};
|
|
174
|
+
const innerOut = await sh(["sg", "docker", "-c", `${quote(outerlayer)} runner init --config-stdin --config ${quote(vmConfig)}`], JSON.stringify(handoff));
|
|
175
|
+
await sh(["sh", "-c", `${quote(outerlayer)} runner install --config ${quote(vmConfig)}`]);
|
|
176
|
+
const nodePath = (await sh(["sh", "-c", "command -v node"])).trim();
|
|
177
|
+
const execStart = execStartCommand(vmConfig, nodePath);
|
|
178
|
+
await sh(["sudo", "tee", `/etc/systemd/system/${VM_SERVICE_NAME}.service`], runnerUnit({ user, home, execStart, timeLimitMinutes }));
|
|
179
|
+
await sh(["sudo", "systemctl", "daemon-reload"]);
|
|
180
|
+
const enabled = commandsAreReal(block);
|
|
181
|
+
if (enabled) await sh(["sudo", "systemctl", "enable", "--now", VM_SERVICE_NAME]);
|
|
182
|
+
let agent;
|
|
183
|
+
let hadHostKey;
|
|
184
|
+
try {
|
|
185
|
+
agent = writeLaunchAgent(deps.home, limactl, instance);
|
|
186
|
+
const { apiKey: _apiKey, runner: _runner, ...kept } = config;
|
|
187
|
+
writeFileSync(configPath, `${JSON.stringify({ ...kept, runnerVm: { instance, since: (deps.now ?? (() => /* @__PURE__ */ new Date()))().toISOString() } }, null, 2)}
|
|
188
|
+
`);
|
|
189
|
+
hadHostKey = existsSync(hostKeyPath(configPath));
|
|
190
|
+
rmSync(hostKeyPath(configPath), { force: true });
|
|
191
|
+
} catch (err) {
|
|
192
|
+
throw new VmInitError(`the VM ${instance} is ready, but this Mac could not be updated: ${err instanceof Error ? err.message : String(err)}. ${leftBehind}`);
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
instance,
|
|
196
|
+
enabled,
|
|
197
|
+
lines: [
|
|
198
|
+
`created the Linux VM ${instance}: ${size.cpus} CPUs, ${size.memoryGiB} GiB memory, ${size.diskGiB} GiB disk`,
|
|
199
|
+
...innerOut.split("\n").map((line) => line.trim()).filter((line) => line !== ""),
|
|
200
|
+
`the VM starts at login through ${agent}`,
|
|
201
|
+
`moved the runner key into the VM: apiKey and runner are gone from ${configPath}`,
|
|
202
|
+
...hadHostKey ? ["deleted this Mac's old host key. If the runner key was bound to it, a member uses Clear host key on the API keys page before the VM's first claim"] : [],
|
|
203
|
+
"run outerlayer login again to use capture on this Mac, with a key that is not the runner key",
|
|
204
|
+
`put CLAUDE_CODE_OAUTH_TOKEN in ${home}/.outerlayer/runner.env inside the VM${enabled ? `, then restart the runner so it reads the file: limactl shell ${instance} sudo systemctl restart ${VM_SERVICE_NAME}` : ""}`,
|
|
205
|
+
enabled ? `the runner is running in the VM: limactl shell ${instance} outerlayer runner status` : `Edit the command lines in the VM's config, then run: limactl shell ${instance} sudo systemctl enable --now ${VM_SERVICE_NAME}`
|
|
206
|
+
]
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
async function chooseVm(options) {
|
|
210
|
+
if (options.flag === false) return false;
|
|
211
|
+
if (options.flag === true) {
|
|
212
|
+
if (options.platform !== "darwin") {
|
|
213
|
+
throw new RunnerInitError(`--vm is for macOS: this machine is ${options.platform}, where the runner runs directly.`);
|
|
214
|
+
}
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
if (options.platform !== "darwin" || !options.isTTY) return false;
|
|
218
|
+
return options.ask();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export { VM_INSTANCE, VmInitError, chooseVm, runVmInit };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { summarizeChecks, summaryText, renderDoctorText } from './chunk-NYC54VBD.js';
|
|
4
|
+
import { runConnect } from './chunk-2E54Z3P5.js';
|
|
5
|
+
import './chunk-3TT7RQYB.js';
|
|
6
|
+
import './chunk-F47JBIAW.js';
|
|
7
|
+
import './chunk-BKO6JEZI.js';
|
|
8
|
+
import './chunk-5DLBAXY5.js';
|
|
9
|
+
import './chunk-BFESLKPP.js';
|
|
10
|
+
import './chunk-6Y63SXFO.js';
|
|
11
|
+
import './chunk-G7FSV7JX.js';
|
|
12
|
+
import './chunk-USO2DKBD.js';
|
|
13
|
+
import './chunk-N6LURUEF.js';
|
|
14
|
+
import { C } from './chunk-YRYMNBGQ.js';
|
|
15
|
+
import './chunk-WZBHBH3J.js';
|
|
16
|
+
import './chunk-5QRP3MVS.js';
|
|
17
|
+
import './chunk-WIOZAJ2W.js';
|
|
18
|
+
import './chunk-EMY4I27X.js';
|
|
19
|
+
import './chunk-BCLJSQCV.js';
|
|
20
|
+
import './chunk-BOLTI6LR.js';
|
|
21
|
+
import './chunk-EABW6AJQ.js';
|
|
22
|
+
import './chunk-M5POMKKW.js';
|
|
23
|
+
import './chunk-ZM2IMMYN.js';
|
|
24
|
+
import './chunk-UFFXNXLQ.js';
|
|
25
|
+
import './chunk-XCCLFVXM.js';
|
|
26
|
+
import './chunk-BJ3KTMDH.js';
|
|
27
|
+
import './chunk-VNVZDWO3.js';
|
|
28
|
+
import './chunk-Z5GEFMRW.js';
|
|
29
|
+
|
|
30
|
+
createRequire(import.meta.url);
|
|
31
|
+
|
|
32
|
+
// src/init-cmd.ts
|
|
33
|
+
var STEP_NAMES = ["connect", "hooks", "agent-setup", "doctor"];
|
|
34
|
+
var COMMIT_LINE = "Commit and push .outerlayer/ so the factory reads your policy and skills. No checks run on your pull requests until the policy is on your default branch.";
|
|
35
|
+
var CLOSING_LINE = "Add an issue on the Work page and press Build.";
|
|
36
|
+
var errorMessage = (err) => err instanceof Error ? err.message : String(err);
|
|
37
|
+
async function runInitCommand(flags, deps) {
|
|
38
|
+
const steps = {};
|
|
39
|
+
for (const name of STEP_NAMES) steps[name] = { outcome: "skipped", reason: "not reached" };
|
|
40
|
+
let text = "";
|
|
41
|
+
const say = (line) => {
|
|
42
|
+
text += line;
|
|
43
|
+
};
|
|
44
|
+
let unlinked;
|
|
45
|
+
const finish = () => {
|
|
46
|
+
const failed = STEP_NAMES.some((n) => steps[n].outcome === "failed");
|
|
47
|
+
if (unlinked !== void 0) {
|
|
48
|
+
say(`
|
|
49
|
+
Next
|
|
50
|
+
Link ${unlinked.repository} on the factory's Work page: ${unlinked.url}
|
|
51
|
+
Then run \`outerlayer connect\` again.
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
if (flags.json) {
|
|
55
|
+
deps.stdout.write(JSON.stringify({ status: failed ? "failed" : "done", steps }, null, 2) + "\n");
|
|
56
|
+
} else {
|
|
57
|
+
deps.stdout.write(text + closing());
|
|
58
|
+
}
|
|
59
|
+
return failed ? 1 : 0;
|
|
60
|
+
};
|
|
61
|
+
const closing = () => {
|
|
62
|
+
if (unlinked !== void 0 || STEP_NAMES.some((n) => steps[n].outcome === "failed")) return "";
|
|
63
|
+
const setup = steps["agent-setup"];
|
|
64
|
+
const leftFiles = (setup.paths?.length ?? 0) > 0 || (setup.kept?.length ?? 0) > 0;
|
|
65
|
+
return `${leftFiles ? `
|
|
66
|
+
${COMMIT_LINE}
|
|
67
|
+
` : ""}
|
|
68
|
+
${CLOSING_LINE}
|
|
69
|
+
`;
|
|
70
|
+
};
|
|
71
|
+
const connect = await runConnect({ factory: flags.factory }, deps.connect).catch(
|
|
72
|
+
(err) => ({
|
|
73
|
+
code: 1,
|
|
74
|
+
outcome: "failed",
|
|
75
|
+
reason: errorMessage(err),
|
|
76
|
+
text: `${errorMessage(err)}
|
|
77
|
+
`
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
steps.connect = {
|
|
81
|
+
outcome: connect.outcome,
|
|
82
|
+
reason: connect.reason,
|
|
83
|
+
...connect.linked === void 0 ? {} : { linked: connect.linked },
|
|
84
|
+
...connect.linkUrl === void 0 ? {} : { linkUrl: connect.linkUrl }
|
|
85
|
+
};
|
|
86
|
+
if (connect.linkUrl !== void 0 && connect.repository !== void 0) unlinked = { repository: connect.repository, url: connect.linkUrl };
|
|
87
|
+
const connected = connect.outcome === "done";
|
|
88
|
+
if (connect.outcome === "done") {
|
|
89
|
+
(flags.json ? deps.stderr : { write: (s) => (say(`${C.green}\u2713${C.reset} ${s}`), true) }).write(connect.text);
|
|
90
|
+
} else if (connect.outcome === "skipped") {
|
|
91
|
+
say(`${C.dim}- Connect skipped: ${connect.reason}${C.reset}
|
|
92
|
+
`);
|
|
93
|
+
if (connect.next) say(` ${connect.next}
|
|
94
|
+
`);
|
|
95
|
+
} else {
|
|
96
|
+
deps.stderr.write(`${C.red}\u2717${C.reset} ${connect.text}`);
|
|
97
|
+
}
|
|
98
|
+
const hooks = await Promise.resolve().then(() => deps.runHooks({ connected })).catch((err) => ({ ok: false, text: `could not install the hooks: ${errorMessage(err)}
|
|
99
|
+
`, detail: errorMessage(err) }));
|
|
100
|
+
steps.hooks = { outcome: hooks.ok ? "done" : "failed", reason: hooks.detail };
|
|
101
|
+
if (!hooks.ok) {
|
|
102
|
+
deps.stderr.write(hooks.text);
|
|
103
|
+
return finish();
|
|
104
|
+
}
|
|
105
|
+
say(hooks.text);
|
|
106
|
+
const agent = await Promise.resolve().then(() => deps.runAgentSetup()).catch(
|
|
107
|
+
(err) => ({
|
|
108
|
+
outcome: "failed",
|
|
109
|
+
reason: errorMessage(err),
|
|
110
|
+
text: `${C.red}\u2717${C.reset} agent setup could not run: ${errorMessage(err)}
|
|
111
|
+
`,
|
|
112
|
+
paths: []
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
steps["agent-setup"] = {
|
|
116
|
+
outcome: agent.outcome,
|
|
117
|
+
reason: agent.reason,
|
|
118
|
+
paths: agent.paths,
|
|
119
|
+
...agent.kept !== void 0 && agent.kept.length > 0 ? { kept: agent.kept } : {}
|
|
120
|
+
};
|
|
121
|
+
say(agent.text);
|
|
122
|
+
try {
|
|
123
|
+
const checks = await deps.runDoctorChecks();
|
|
124
|
+
const summary = summarizeChecks(checks);
|
|
125
|
+
steps.doctor = { outcome: summary.failures > 0 ? "failed" : "done", reason: summaryText(summary) };
|
|
126
|
+
say(renderDoctorText(checks));
|
|
127
|
+
} catch (err) {
|
|
128
|
+
steps.doctor = { outcome: "failed", reason: errorMessage(err) };
|
|
129
|
+
deps.stderr.write(`${C.red}\u2717${C.reset} doctor could not run: ${errorMessage(err)}
|
|
130
|
+
`);
|
|
131
|
+
}
|
|
132
|
+
return finish();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { runInitCommand };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { isInLayout, packageRootIn, versionDir, switchCurrent, execStartLine } from './chunk-YYYXRJUW.js';
|
|
4
|
+
import { RUNNER_DIR_MODE } from './chunk-ZM2IMMYN.js';
|
|
5
|
+
import './chunk-Z5GEFMRW.js';
|
|
6
|
+
import { realpathSync, readFileSync, mkdirSync, rmSync, cpSync, existsSync } from 'fs';
|
|
7
|
+
import { dirname, sep, join } from 'path';
|
|
8
|
+
|
|
9
|
+
createRequire(import.meta.url);
|
|
10
|
+
var RunnerInstallError = class extends Error {
|
|
11
|
+
};
|
|
12
|
+
function runRunnerInstall(args) {
|
|
13
|
+
const { configPath, nodePath } = args;
|
|
14
|
+
let entry;
|
|
15
|
+
try {
|
|
16
|
+
entry = realpathSync(args.entryPath);
|
|
17
|
+
} catch {
|
|
18
|
+
throw new RunnerInstallError(`cannot read the running CLI at ${args.entryPath}`);
|
|
19
|
+
}
|
|
20
|
+
const packageRoot = dirname(dirname(entry));
|
|
21
|
+
if (!packageRoot.split(sep).includes("node_modules")) {
|
|
22
|
+
throw new RunnerInstallError(
|
|
23
|
+
`${packageRoot} is not an installed package: run \`outerlayer runner install\` from a CLI installed with npm, not from a source checkout`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
let manifest;
|
|
27
|
+
try {
|
|
28
|
+
manifest = JSON.parse(readFileSync(`${packageRoot}/package.json`, "utf8"));
|
|
29
|
+
} catch {
|
|
30
|
+
manifest = {};
|
|
31
|
+
}
|
|
32
|
+
if (manifest.name !== "@outerlayer/cli") throw new RunnerInstallError(`${packageRoot} is not the @outerlayer/cli package`);
|
|
33
|
+
const version = manifest.version;
|
|
34
|
+
if (typeof version !== "string" || version === "") throw new RunnerInstallError(`${packageRoot}/package.json has no version`);
|
|
35
|
+
if (!isInLayout(configPath, entry)) {
|
|
36
|
+
const target = packageRootIn(versionDir(configPath, version));
|
|
37
|
+
mkdirSync(dirname(target), { recursive: true, mode: RUNNER_DIR_MODE });
|
|
38
|
+
rmSync(target, { recursive: true, force: true });
|
|
39
|
+
cpSync(packageRoot, target, { recursive: true });
|
|
40
|
+
carryHoistedDevcontainerCli(packageRoot, target);
|
|
41
|
+
}
|
|
42
|
+
switchCurrent(configPath, version);
|
|
43
|
+
return { version, execStart: execStartLine(configPath, nodePath) };
|
|
44
|
+
}
|
|
45
|
+
function carryHoistedDevcontainerCli(packageRoot, target) {
|
|
46
|
+
const dependency = join("@devcontainers", "cli");
|
|
47
|
+
if (existsSync(join(packageRoot, "node_modules", dependency))) return;
|
|
48
|
+
const hoisted = join(dirname(dirname(packageRoot)), dependency);
|
|
49
|
+
if (!existsSync(hoisted)) return;
|
|
50
|
+
const carried = join(dirname(dirname(target)), dependency);
|
|
51
|
+
mkdirSync(dirname(carried), { recursive: true, mode: RUNNER_DIR_MODE });
|
|
52
|
+
cpSync(hoisted, carried, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { RunnerInstallError, runRunnerInstall };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import './chunk-Z5GEFMRW.js';
|
|
4
|
+
import { spawnSync, spawn } from 'child_process';
|
|
5
|
+
import { statSync, accessSync, constants } from 'fs';
|
|
6
|
+
import { delimiter, resolve } from 'path';
|
|
7
|
+
|
|
8
|
+
createRequire(import.meta.url);
|
|
9
|
+
var NOT_INSTALLED = { status: 127, stdout: "", stderr: "limactl is not installed" };
|
|
10
|
+
function realLima(env = process.env) {
|
|
11
|
+
const locate = () => {
|
|
12
|
+
for (const dir of (env.PATH ?? "").split(delimiter)) {
|
|
13
|
+
if (dir === "") continue;
|
|
14
|
+
const candidate = resolve(dir, "limactl");
|
|
15
|
+
try {
|
|
16
|
+
if (!statSync(candidate).isFile()) continue;
|
|
17
|
+
accessSync(candidate, constants.X_OK);
|
|
18
|
+
return candidate;
|
|
19
|
+
} catch {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return void 0;
|
|
24
|
+
};
|
|
25
|
+
const run = (argv, stdin) => {
|
|
26
|
+
const path = locate();
|
|
27
|
+
if (path === void 0) return Promise.resolve(NOT_INSTALLED);
|
|
28
|
+
return new Promise((done) => {
|
|
29
|
+
const child = spawn(path, argv, { env, stdio: ["pipe", "pipe", "pipe"] });
|
|
30
|
+
const out = [];
|
|
31
|
+
const err = [];
|
|
32
|
+
child.stdout.on("data", (chunk) => out.push(chunk));
|
|
33
|
+
child.stderr.on("data", (chunk) => err.push(chunk));
|
|
34
|
+
child.on("error", (error) => done({ status: 127, stdout: "", stderr: error.message }));
|
|
35
|
+
child.on("close", (code) => done({ status: code ?? 1, stdout: Buffer.concat(out).toString("utf8"), stderr: Buffer.concat(err).toString("utf8") }));
|
|
36
|
+
child.stdin.on("error", () => void 0);
|
|
37
|
+
child.stdin.end(stdin);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
locate,
|
|
42
|
+
status(instance) {
|
|
43
|
+
const path = locate();
|
|
44
|
+
if (path === void 0) return void 0;
|
|
45
|
+
const listed = spawnSync(path, ["list", "--format", "{{.Status}}", instance], { env, encoding: "utf8" });
|
|
46
|
+
const text = listed.status === 0 ? listed.stdout.trim() : "";
|
|
47
|
+
return text === "" ? void 0 : text;
|
|
48
|
+
},
|
|
49
|
+
create: ({ instance, cpus, memoryGiB, diskGiB }) => run(["create", "--tty=false", `--name=${instance}`, `--cpus=${cpus}`, `--memory=${memoryGiB}`, `--disk=${diskGiB}`, "--mount-none", "template:docker-rootful"]),
|
|
50
|
+
start: (instance) => run(["start", instance]),
|
|
51
|
+
shell: (instance, argv, options) => run(["shell", "--workdir", "/", instance, "--", ...argv], options?.stdin)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { realLima };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
export { DEFAULT_DASHBOARD, readPipedKey, realLoginDeps, runLoginCommand, sanitizeMachineName, stdinKind } from './chunk-USO2DKBD.js';
|
|
4
|
+
import './chunk-N6LURUEF.js';
|
|
5
|
+
import './chunk-YRYMNBGQ.js';
|
|
6
|
+
import './chunk-EABW6AJQ.js';
|
|
7
|
+
import './chunk-VNVZDWO3.js';
|
|
8
|
+
import './chunk-Z5GEFMRW.js';
|
|
9
|
+
|
|
10
|
+
createRequire(import.meta.url);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
export {
|
|
3
|
+
export { realLogoutDeps, revokeTokenOnDashboard, runLogoutCommand } from './chunk-N6LURUEF.js';
|
|
4
|
+
import './chunk-YRYMNBGQ.js';
|
|
5
|
+
import './chunk-EABW6AJQ.js';
|
|
4
6
|
import './chunk-VNVZDWO3.js';
|
|
5
7
|
import './chunk-Z5GEFMRW.js';
|
|
6
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { jobsDir } from './chunk-
|
|
3
|
+
import { jobsDir } from './chunk-ZM2IMMYN.js';
|
|
4
4
|
import './chunk-Z5GEFMRW.js';
|
|
5
5
|
import { existsSync, watch, statSync, createReadStream } from 'fs';
|
|
6
6
|
import { join } from 'path';
|