@outerlayer/cli 0.5.1 → 0.7.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 +29 -0
- package/README.md +19 -0
- package/dist/{agent-setup-IFH3FB5X.js → agent-setup-TXLDY5RV.js} +7 -6
- package/dist/{build-PAEKVYVK.js → build-JF5UOWKJ.js} +2 -1
- package/dist/build-info.json +1 -1
- package/dist/{check-4Q33B5ZE.js → check-ASZL5BEO.js} +39 -23
- package/dist/chunk-2VO25HHO.js +75 -0
- package/dist/{chunk-XDDW4FRS.js → chunk-5FWNEQNZ.js} +3 -3
- package/dist/{chunk-CHLVJNTE.js → chunk-6IYLDODX.js} +18 -6
- package/dist/{chunk-W7UTFZDH.js → chunk-6QWV3YDJ.js} +2 -2
- package/dist/{chunk-EGABNHZG.js → chunk-6ZZHWY2Z.js} +149 -18
- package/dist/{lima-XN65D7GN.js → chunk-77MM5RYD.js} +0 -1
- package/dist/chunk-7FTNIAHS.js +211 -0
- package/dist/{chunk-EMY4I27X.js → chunk-7ZR5UPMB.js} +555 -5
- package/dist/{chunk-F4NU4H3V.js → chunk-AII7CKTH.js} +133 -35
- package/dist/{chunk-ZXBITXTS.js → chunk-AIW6GLET.js} +1 -1
- package/dist/{chunk-UWH5DSUP.js → chunk-AJKEHABI.js} +507 -90
- package/dist/{chunk-RTXKYLCA.js → chunk-AQ54MKSQ.js} +2 -2
- package/dist/{chunk-Z62HNKEJ.js → chunk-CEBIA5FD.js} +31 -5
- package/dist/{chunk-EX6M5JPR.js → chunk-D6FXM5OW.js} +6302 -28611
- package/dist/{chunk-RMAZ2NWA.js → chunk-DGAIVMMN.js} +23 -2
- package/dist/{chunk-3DD6AOWC.js → chunk-DTXOJDEH.js} +26 -2
- package/dist/{chunk-T52PKE2Y.js → chunk-E4PIFIC3.js} +244 -17
- package/dist/{chunk-H5NCNVDA.js → chunk-EV3M3EH7.js} +2 -2
- package/dist/chunk-FBTE2A2X.js +38 -0
- package/dist/{chunk-DVDEBNQJ.js → chunk-GQD22KKN.js} +17 -6
- package/dist/{chunk-BCJNHMZT.js → chunk-HHJDN6AU.js} +18 -3
- package/dist/chunk-HKMPVPO7.js +55 -0
- package/dist/{chunk-UFFXNXLQ.js → chunk-JPR2WHHF.js} +31 -29
- package/dist/{chunk-ZMYPLFG3.js → chunk-M3SQ4YGD.js} +1 -1
- package/dist/{chunk-H4CK2YK4.js → chunk-MQPRB5K7.js} +18 -10
- package/dist/{chunk-AUFG23AA.js → chunk-OD2VTIHN.js} +19 -47
- package/dist/chunk-OUUINEYB.js +27 -0
- package/dist/chunk-PUN7LMNS.js +39 -0
- package/dist/{install-cmd-7WXOIFDO.js → chunk-Q5G2ODUZ.js} +1 -2
- package/dist/{chunk-B2G7JHHB.js → chunk-R7STSBLC.js} +1 -1
- package/dist/{chunk-OR6AEEDO.js → chunk-SSU747O6.js} +85 -25
- package/dist/chunk-T6OIJQRT.js +31 -0
- package/dist/{chunk-YYYXRJUW.js → chunk-TI7B7UEO.js} +1 -1
- package/dist/{chunk-WO2BXCTQ.js → chunk-VXLJORHL.js} +1 -1
- package/dist/{chunk-CBPPJSAR.js → chunk-WVGSB3Z2.js} +2 -2
- package/dist/{chunk-JLDZTG3A.js → chunk-X2FSFU4C.js} +4 -1
- package/dist/chunk-YNJEOGDL.js +22434 -0
- package/dist/{chunk-W4SQCOZU.js → chunk-ZOAEPWGL.js} +1 -1
- package/dist/{chunk-WOBNRVQT.js → chunk-ZYHKJKSU.js} +1 -1
- package/dist/{chunk-WIOZAJ2W.js → chunk-ZZXLM64C.js} +1 -1
- package/dist/{cli-LHSUYYMI.js → cli-LEVCGAQV.js} +154 -79
- package/dist/command-FLSYCGIB.js +187 -0
- package/dist/config-I3TVFYLH.js +10 -0
- package/dist/{connect-cmd-OJBFHZWP.js → connect-cmd-MJMUONDY.js} +4 -4
- package/dist/{context-adopt-UMA4O5NY.js → context-adopt-CE4KDXS3.js} +5 -4
- package/dist/{context-materialize-G2FUFC72.js → context-materialize-QL33HDJN.js} +5 -4
- package/dist/{dist-WDV7U7UJ.js → dist-PXBSA7QX.js} +2 -1
- package/dist/{doctor-MOA3RIEP.js → doctor-FVDT3KJZ.js} +46 -19
- package/dist/{emit-artifact-cmd-FDWYKURA.js → emit-artifact-cmd-7RPMRSVP.js} +13 -7
- package/dist/{emit-cmd-DCERAU27.js → emit-cmd-2QRMYPYO.js} +4 -3
- package/dist/{emit-criteria-cmd-OCXHLK34.js → emit-criteria-cmd-MKI7WETO.js} +12 -3
- package/dist/{emit-finding-cmd-POW7PKIA.js → emit-finding-cmd-RMLGZASB.js} +14 -3
- package/dist/{emit-result-cmd-ID35SH53.js → emit-result-cmd-MTXAZ2GV.js} +15 -9
- 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-EYENPK6F.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 -2
- package/dist/{init-FYDJAKTM.js → init-BACXESVV.js} +21 -14
- package/dist/{init-2IPOIXJV.js → init-VLW7H6RW.js} +40 -62
- package/dist/{init-cmd-KLIDRVXQ.js → init-cmd-VJFB5L7X.js} +10 -9
- package/dist/inspect-XAUSB7L3.js +63 -0
- package/dist/install-NMAPLLBQ.js +14 -0
- package/dist/install-cmd-B5SEU3G7.js +8 -0
- package/dist/lima-7NPCNGWT.js +6 -0
- package/dist/{logs-7RYUH5A6.js → logs-H55NWW4H.js} +1 -0
- package/dist/loop-D3243JKT.js +64 -0
- package/dist/{machine-ECU3QCZD.js → machine-EB3GEVI4.js} +20 -13
- package/dist/session-sender-LMACEJJS.js +29 -0
- package/dist/{starter-pack-LIZYMKYQ.js → starter-pack-MUXMAU4S.js} +4 -3
- package/dist/{status-CLATHCTQ.js → status-F4THTJJK.js} +36 -16
- package/dist/{sync-cmd-SWQ5KLPL.js → sync-cmd-M6JA3OEE.js} +7 -7
- package/dist/{watch-3YW6Z3DQ.js → watch-NB5TGPEZ.js} +7 -7
- package/dist/{work-claim-cmd-3OPWA77E.js → work-claim-cmd-UHMWOS3G.js} +14 -7
- package/dist/{work-cmd-NUR4CAG6.js → work-cmd-6UMCFTAW.js} +9 -3
- package/dist/{work-comment-cmd-6TTTYGHM.js → work-comment-cmd-E4LEUIXZ.js} +9 -3
- package/dist/{work-launch-YI4CJDAP.js → work-launch-R5HTAP6X.js} +1 -1
- package/dist/{work-open-pr-cmd-KZ7QQFLD.js → work-open-pr-cmd-OPZWGSEQ.js} +10 -4
- package/dist/{work-pr-cmd-QNUBE6IQ.js → work-pr-cmd-IDIAFFRU.js} +9 -2
- package/package.json +2 -1
- package/skill-pack/template/build/scripts/record-criteria.mjs +2 -1
- package/dist/chunk-D2KWEAN6.js +0 -55
- package/dist/chunk-ZOC7JSYC.js +0 -83
- package/dist/config-HL2AIR3K.js +0 -9
- package/dist/loop-NEBUGD2Q.js +0 -45
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-
|
|
3
|
+
import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-YNJEOGDL.js';
|
|
4
4
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
5
5
|
import { mkdirSync, appendFileSync, writeFileSync, renameSync, existsSync, unlinkSync, readdirSync, readFileSync } from 'fs';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { CONTEXT_PIN_SCHEMA_VERSION, CONTEXT_PIN_FILENAME } from './chunk-
|
|
3
|
+
import { CONTEXT_PIN_SCHEMA_VERSION, CONTEXT_PIN_FILENAME } from './chunk-7ZR5UPMB.js';
|
|
4
4
|
import { readFileSync, existsSync, writeFileSync, mkdirSync, utimesSync, statSync, unlinkSync } from 'fs';
|
|
5
5
|
import { join, dirname } from 'path';
|
|
6
6
|
|
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-
|
|
4
|
-
import './chunk-D2KWEAN6.js';
|
|
3
|
+
import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-MQPRB5K7.js';
|
|
5
4
|
import './chunk-F47JBIAW.js';
|
|
6
5
|
import './chunk-BKO6JEZI.js';
|
|
7
|
-
import './chunk-
|
|
6
|
+
import './chunk-DGAIVMMN.js';
|
|
7
|
+
import './chunk-PUN7LMNS.js';
|
|
8
8
|
import './chunk-BFESLKPP.js';
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
9
|
+
import './chunk-SSU747O6.js';
|
|
10
|
+
import './chunk-ZYHKJKSU.js';
|
|
11
|
+
import './chunk-D6FXM5OW.js';
|
|
11
12
|
import './chunk-USO2DKBD.js';
|
|
12
13
|
import './chunk-N6LURUEF.js';
|
|
13
14
|
import { C, NO_COLOR_FLAG, warnDeprecated, stripNoColor, API_KEY_FLAG_DEPRECATION } from './chunk-YRYMNBGQ.js';
|
|
14
15
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
15
16
|
import { settingsPath, readSettings, SettingsParseError, listHookCandidates, wrapHooks, writeSettings, unwrapHooks, REGISTERED_EVENTS, cliCommand, removeHooks, removeStatusline, cliBinResolvable, mergeHooks, repointWrappedHooks, AUTO_WRAP_EVENTS, mergeStatusline } from './chunk-5QRP3MVS.js';
|
|
16
|
-
import { pinExists } from './chunk-
|
|
17
|
-
import './chunk-
|
|
17
|
+
import { pinExists } from './chunk-ZZXLM64C.js';
|
|
18
|
+
import './chunk-7ZR5UPMB.js';
|
|
18
19
|
import './chunk-BCLJSQCV.js';
|
|
19
20
|
import './chunk-BOLTI6LR.js';
|
|
21
|
+
import './chunk-YNJEOGDL.js';
|
|
20
22
|
import './chunk-EABW6AJQ.js';
|
|
21
23
|
import { resolveVersion } from './chunk-RA3O54FC.js';
|
|
22
24
|
import './chunk-M5POMKKW.js';
|
|
23
25
|
import './chunk-ZM2IMMYN.js';
|
|
24
|
-
import { hookFiredMarkerPath, installedCliDistDir } from './chunk-
|
|
26
|
+
import { hookFiredMarkerPath, installedCliDistDir } from './chunk-JPR2WHHF.js';
|
|
25
27
|
import { managedHookScripts, removeJournalHooks, installPreCommitGuardHook, removePreCommitGuardHook } from './chunk-XCCLFVXM.js';
|
|
26
28
|
import './chunk-BJ3KTMDH.js';
|
|
27
29
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
28
30
|
import './chunk-Z5GEFMRW.js';
|
|
29
31
|
import { EventEmitter } from 'events';
|
|
30
32
|
import childProcess, { execFileSync } from 'child_process';
|
|
31
|
-
import path, {
|
|
33
|
+
import path, { join, dirname, isAbsolute } from 'path';
|
|
32
34
|
import fs, { existsSync, unlinkSync, mkdirSync, cpSync, readdirSync, renameSync, statSync, rmSync, readFileSync, writeFileSync, realpathSync } from 'fs';
|
|
33
35
|
import process2 from 'process';
|
|
34
36
|
import { stripVTControlCharacters } from 'util';
|
|
@@ -3632,7 +3634,7 @@ function warnIfApiKeyFlag(opts) {
|
|
|
3632
3634
|
if (opts.apiKey !== void 0) warnDeprecated(API_KEY_FLAG_DEPRECATION);
|
|
3633
3635
|
}
|
|
3634
3636
|
async function installStarterPackInRepo() {
|
|
3635
|
-
const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-
|
|
3637
|
+
const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-MUXMAU4S.js');
|
|
3636
3638
|
const cwd = process.cwd();
|
|
3637
3639
|
let repoRoot = cwd;
|
|
3638
3640
|
try {
|
|
@@ -3792,8 +3794,8 @@ ${starter.output}`),
|
|
|
3792
3794
|
}
|
|
3793
3795
|
}
|
|
3794
3796
|
async function realConnectDepsForCwd() {
|
|
3795
|
-
const { realConnectDeps } = await import('./connect-cmd-
|
|
3796
|
-
const { resolveRepoIdentity } = await import('./dist-
|
|
3797
|
+
const { realConnectDeps } = await import('./connect-cmd-MJMUONDY.js');
|
|
3798
|
+
const { resolveRepoIdentity } = await import('./dist-PXBSA7QX.js');
|
|
3797
3799
|
return {
|
|
3798
3800
|
...realConnectDeps(),
|
|
3799
3801
|
home: homeFromEnv(),
|
|
@@ -3815,7 +3817,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3815
3817
|
).action(async (opts) => {
|
|
3816
3818
|
let starterTemplate;
|
|
3817
3819
|
if (opts.template !== void 0) {
|
|
3818
|
-
const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-
|
|
3820
|
+
const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-MUXMAU4S.js');
|
|
3819
3821
|
try {
|
|
3820
3822
|
assertKnownTemplate(opts.template);
|
|
3821
3823
|
} catch (err) {
|
|
@@ -3846,7 +3848,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3846
3848
|
else process.stdout.write(outcome.text);
|
|
3847
3849
|
return;
|
|
3848
3850
|
}
|
|
3849
|
-
const { runInitCommand } = await import('./init-cmd-
|
|
3851
|
+
const { runInitCommand } = await import('./init-cmd-VJFB5L7X.js');
|
|
3850
3852
|
const code = await runInitCommand(
|
|
3851
3853
|
{ json: opts.json, factory: opts.factory },
|
|
3852
3854
|
{
|
|
@@ -3858,7 +3860,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3858
3860
|
return { ok, text, detail };
|
|
3859
3861
|
},
|
|
3860
3862
|
runAgentSetup: async () => {
|
|
3861
|
-
const { runAgentSetup } = await import('./agent-setup-
|
|
3863
|
+
const { runAgentSetup } = await import('./agent-setup-TXLDY5RV.js');
|
|
3862
3864
|
return runAgentSetup({ cwd: process.cwd() });
|
|
3863
3865
|
},
|
|
3864
3866
|
runDoctorChecks: gatherDoctorChecks
|
|
@@ -3870,7 +3872,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3870
3872
|
"after",
|
|
3871
3873
|
"\nRun it in a repository, after `outerlayer login`. With a login, connect lists\nthe factories you can use and takes the first rule that leaves one answer:\n 1. --factory <org>/<factory>, or a factory id\n 2. the factory this repository is already connected to\n 3. the one factory this repository is linked to\n 4. the one factory you can use\n 5. on a terminal, ask; with no terminal, exit 1 and list each --factory value\n\nIt says what it chose and why. The choice is saved in this repository's git\ndirectory (outerlayer/connection.json), shared by every worktree of the\nclone and never committed. A factory key already belongs to one factory, so\nconnect changes nothing for it. Connect never links a repository.\n\nAfter it saves the choice, connect checks that this repository is linked to\nthe factory. If it is not, connect says so, prints the factory's Work page\nlink where you link it, and exits 2. The choice is saved either way. Run\nconnect again once the repository is linked. With --json, the document has\nlinked (true, false, or null when it could not be checked) and, when false,\nlinkUrl.\n"
|
|
3872
3874
|
).action(async (opts) => {
|
|
3873
|
-
const { runConnectCommand } = await import('./connect-cmd-
|
|
3875
|
+
const { runConnectCommand } = await import('./connect-cmd-MJMUONDY.js');
|
|
3874
3876
|
const code = await runConnectCommand({ factory: opts.factory, json: opts.json }, await realConnectDepsForCwd(), {
|
|
3875
3877
|
stdout: process.stdout,
|
|
3876
3878
|
stderr: process.stderr
|
|
@@ -3918,7 +3920,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3918
3920
|
"\nIncremental: only sessions newer than the last checkpoint ship. The tier\nis applied on this machine before anything leaves it; `--dry-run` prints\nexactly what would. The hook-triggered background sync runs `--quiet`.\nExit 2 means the server rejected at least one session.\n"
|
|
3919
3921
|
).action(async (opts) => {
|
|
3920
3922
|
warnIfApiKeyFlag(opts);
|
|
3921
|
-
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-
|
|
3923
|
+
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-M6JA3OEE.js');
|
|
3922
3924
|
try {
|
|
3923
3925
|
const result = await runSync({
|
|
3924
3926
|
url: opts.url,
|
|
@@ -3947,7 +3949,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3947
3949
|
if (invokedCommandToken(argv) === "watch") {
|
|
3948
3950
|
warnDeprecated("`outerlayer watch` is now `outerlayer daemon`; the old name will be removed in a future release.");
|
|
3949
3951
|
}
|
|
3950
|
-
const { runWatch } = await import('./watch-
|
|
3952
|
+
const { runWatch } = await import('./watch-NB5TGPEZ.js');
|
|
3951
3953
|
await runWatch({ once: opts.once });
|
|
3952
3954
|
});
|
|
3953
3955
|
program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
|
|
@@ -3976,7 +3978,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3976
3978
|
await startRelay({ port, socketPath: opts.socket, forwards });
|
|
3977
3979
|
});
|
|
3978
3980
|
program2.command("vm-exec", { hidden: true }).description("run a command in a microVM build's guest through its exec agent").requiredOption("--socket <path>", "the Unix socket Firecracker serves the build's vsock device on").option("--user <user>", "the user to run as", "").option("--cwd <dir>", "the working directory", "/").option("--env <NAME=value>", "an environment value the command line carries; repeatable", (value, previous) => [...previous, value], []).option("--pass <NAME>", "an environment variable whose value is read from this process; repeatable", (value, previous) => [...previous, value], []).argument("<argv...>", "the command and its arguments").action(async (argv2, opts) => {
|
|
3979
|
-
const { runVmExec } = await import('./exec-client-
|
|
3981
|
+
const { runVmExec } = await import('./exec-client-NPYNUAF3.js');
|
|
3980
3982
|
const env = {};
|
|
3981
3983
|
for (const entry of opts.env) {
|
|
3982
3984
|
const eq = entry.indexOf("=");
|
|
@@ -4000,8 +4002,16 @@ function buildProgram(argv = process.argv) {
|
|
|
4000
4002
|
process.exit(255);
|
|
4001
4003
|
}
|
|
4002
4004
|
});
|
|
4005
|
+
program2.command("session-sender", { hidden: true }).description("stream a runner build's sessions to its work item while the build runs").action(async () => {
|
|
4006
|
+
const { runSessionSender } = await import('./session-sender-LMACEJJS.js');
|
|
4007
|
+
try {
|
|
4008
|
+
await runSessionSender();
|
|
4009
|
+
} catch (err) {
|
|
4010
|
+
fail(`session-sender: ${err instanceof Error ? err.message : String(err)}`);
|
|
4011
|
+
}
|
|
4012
|
+
});
|
|
4003
4013
|
program2.command("vm-init", { hidden: true }).description("lay out a microVM build's guest; the guest helper runs it").action(async () => {
|
|
4004
|
-
const { realGuestHost, runGuestInit } = await import('./guest-init-
|
|
4014
|
+
const { realGuestHost, runGuestInit } = await import('./guest-init-JWNNAH2H.js');
|
|
4005
4015
|
const { readFileSync: readFileSync3 } = await import('fs');
|
|
4006
4016
|
try {
|
|
4007
4017
|
runGuestInit(realGuestHost(), readFileSync3("/proc/cmdline", "utf8"));
|
|
@@ -4028,7 +4038,7 @@ async function runCli(processArgv) {
|
|
|
4028
4038
|
await buildProgram(argv).parseAsync(argv);
|
|
4029
4039
|
}
|
|
4030
4040
|
async function compileContext(opts) {
|
|
4031
|
-
const { runEmit, EmitError } = await import('./emit-cmd-
|
|
4041
|
+
const { runEmit, EmitError } = await import('./emit-cmd-2QRMYPYO.js');
|
|
4032
4042
|
try {
|
|
4033
4043
|
const result = runEmit({ cwd: opts.dir, check: opts.check, json: opts.json });
|
|
4034
4044
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -4051,7 +4061,7 @@ function registerEmitCommands(program2) {
|
|
|
4051
4061
|
return;
|
|
4052
4062
|
}
|
|
4053
4063
|
warnIfApiKeyFlag(opts);
|
|
4054
|
-
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-
|
|
4064
|
+
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-MTXAZ2GV.js');
|
|
4055
4065
|
try {
|
|
4056
4066
|
const result = await runEmitResult({
|
|
4057
4067
|
name,
|
|
@@ -4102,7 +4112,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4102
4112
|
`
|
|
4103
4113
|
).action(async (file, opts) => {
|
|
4104
4114
|
warnIfApiKeyFlag(opts);
|
|
4105
|
-
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-
|
|
4115
|
+
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-7RPMRSVP.js');
|
|
4106
4116
|
let pr;
|
|
4107
4117
|
if (opts.pr !== void 0) {
|
|
4108
4118
|
pr = parseTrackerNumber(opts.pr);
|
|
@@ -4137,7 +4147,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4137
4147
|
'\n outerlayer emit finding --id gate-skip --category tooling \\\n --title "The pre-push gate prints green when a step was skipped" \\\n --file scripts/git/pre-push-checks.mjs --where "build session"\n\nRecords one problem you hit in the factory: an instruction that is wrong or\nmissing (context), a flaky test, a misbehaving script (tooling), a local\nsetup trap (environment), a bug outside your own change (defect), or\nanything else. A problem in your own change is fixed, not recorded.\nA context finding needs --rule-path and --rule-relation, and --rule-quote\nunless the relation is missing.\n--item names the work item; without it, inside a recorded session, the\nitem that session was launched for is used automatically.\n'
|
|
4138
4148
|
).action(async (opts) => {
|
|
4139
4149
|
warnIfApiKeyFlag(opts);
|
|
4140
|
-
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-
|
|
4150
|
+
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-RMLGZASB.js');
|
|
4141
4151
|
try {
|
|
4142
4152
|
refuseRemovedFindingFlags(opts);
|
|
4143
4153
|
const result = await runEmitFinding({
|
|
@@ -4176,7 +4186,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4176
4186
|
"\n outerlayer emit findings review.json --item 412\n\nRecords a whole batch at once \u2014 a FindingBatch JSON file (schemaVersion,\noptional headSha / contextSourceSha, and 1-500 findings), validated against\nthe same contract `emit finding` uses before anything is sent. Re-emitting\nan id already on the item replaces that row rather than adding a second one.\n--item names the work item; without it, inside a recorded session, the item\nthat session was launched for is used automatically.\n"
|
|
4177
4187
|
).action(async (file, opts) => {
|
|
4178
4188
|
warnIfApiKeyFlag(opts);
|
|
4179
|
-
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-
|
|
4189
|
+
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-RMLGZASB.js');
|
|
4180
4190
|
try {
|
|
4181
4191
|
const result = await runEmitFindings({
|
|
4182
4192
|
file,
|
|
@@ -4200,7 +4210,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4200
4210
|
'\n outerlayer emit criteria criteria.json --item 412\n\nRecords the item\'s acceptance criteria as one list. The file is JSON:\n { "criteria": [ { "id": "AC-1", "text": "Given ...", "proof": null },\n { "id": "login.redirect", "text": "...", "proof": "screenshot" } ] }\nAn id is 1-64 characters of A-Z a-z 0-9 . _ : - and is the id evidence is bound to with\n`emit artifact --for`. proof is video, screenshot, report, log, test, file or null (any bound\nartifact proves it). The list holds 1 to 200 criteria, each text at most 2,000\ncharacters, and no id twice. The list is validated before anything is sent.\nOnce an item has a list, only a person can replace it: run the command outside an\nagent session, with your own login. A key bound to no member cannot replace it either.\n--item names the work item; without it, inside a recorded session, the item that\nsession was launched for is used automatically.\n'
|
|
4201
4211
|
).action(async (file, opts) => {
|
|
4202
4212
|
warnIfApiKeyFlag(opts);
|
|
4203
|
-
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-
|
|
4213
|
+
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-MKI7WETO.js');
|
|
4204
4214
|
try {
|
|
4205
4215
|
const result = await runEmitCriteria({
|
|
4206
4216
|
file,
|
|
@@ -4227,7 +4237,7 @@ function registerWorkCommands(program2) {
|
|
|
4227
4237
|
"\n outerlayer work build --issue 42 # a host builds it\n outerlayer work build --item 7 # retry an item already on Work\n outerlayer work build --issue 42 --local # you build it\n outerlayer work build --issue ENG-123 --tracker linear # a Linear issue\n\nWithout --local, records a build request: a host takes the item when it\nhas a free slot. It never links the calling session and never takes a\nlease, even run from inside one.\n\nWith --local, puts the item on Work with no build request, so no host\ntakes it, and prints the line that starts your session on it. That\nsession links itself and holds the item's lease while it works.\n"
|
|
4228
4238
|
).action(async (opts) => {
|
|
4229
4239
|
warnIfApiKeyFlag(opts);
|
|
4230
|
-
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-
|
|
4240
|
+
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4231
4241
|
try {
|
|
4232
4242
|
await runWorkBuild(opts);
|
|
4233
4243
|
} catch (err) {
|
|
@@ -4238,14 +4248,14 @@ function registerWorkCommands(program2) {
|
|
|
4238
4248
|
throw err;
|
|
4239
4249
|
}
|
|
4240
4250
|
});
|
|
4241
|
-
workCmd.command("link-session").description("Link the calling session to a work item that already exists").argument("<number>", "the item's number inside this factory").option("--session-id <id>", "session id to record as-is, skipping detection (used by the SessionStart hook)").option("--retry <count>", "resend after a failure that may pass, with backoff").option("--no-lease", "link only \u2014 ask for no session lease (used by a host's own job)").option("--ended", "release this session's lease instead of taking or renewing one").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").addHelpText(
|
|
4251
|
+
workCmd.command("link-session").description("Link the calling session to a work item that already exists").argument("<number>", "the item's number inside this factory").option("--session-id <id>", "session id to record as-is, skipping detection (used by the SessionStart hook)").option("--retry <count>", "resend after a failure that may pass, with backoff").option("--no-lease", "link only \u2014 ask for no session lease (used by a host's own job)").option("--ended", "release this session's lease instead of taking or renewing one").addOption(new Option("--log-failures", "append a failure to the hook error log (used by hooks)").hideHelp()).option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").addHelpText(
|
|
4242
4252
|
"after",
|
|
4243
4253
|
"\n outerlayer work link-session 42\n\nNames an item that already exists on the calling session \u2014 it never\ncreates one. Create one with `outerlayer work build --local`. Linking\nthe same session to the same item twice is a no-op. Also takes or\nrenews that session's own 20-minute lease, unless --no-lease or\n--ended is given, or another worker already holds a live one.\n"
|
|
4244
4254
|
).action(async (number, opts) => {
|
|
4245
4255
|
warnIfApiKeyFlag(opts);
|
|
4246
|
-
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-
|
|
4256
|
+
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4247
4257
|
try {
|
|
4248
|
-
await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false });
|
|
4258
|
+
await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false, logFailures: opts.logFailures === true });
|
|
4249
4259
|
} catch (err) {
|
|
4250
4260
|
if (err instanceof WorkCommandError) {
|
|
4251
4261
|
fail(err.message);
|
|
@@ -4268,8 +4278,8 @@ most one action flag may be given.
|
|
|
4268
4278
|
`
|
|
4269
4279
|
).action(async (opts) => {
|
|
4270
4280
|
warnIfApiKeyFlag(opts);
|
|
4271
|
-
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-
|
|
4272
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4281
|
+
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-E4LEUIXZ.js');
|
|
4282
|
+
const { WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4273
4283
|
try {
|
|
4274
4284
|
await runWorkComment(opts);
|
|
4275
4285
|
} catch (err) {
|
|
@@ -4285,8 +4295,8 @@ most one action flag may be given.
|
|
|
4285
4295
|
"\n outerlayer work threads --item 7\n\nPrints the item's general thread, then one thread per acceptance\ncriterion that carries proof or a comment, each with who is waiting\non whom next.\n"
|
|
4286
4296
|
).action(async (opts) => {
|
|
4287
4297
|
warnIfApiKeyFlag(opts);
|
|
4288
|
-
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-
|
|
4289
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4298
|
+
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-E4LEUIXZ.js');
|
|
4299
|
+
const { WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4290
4300
|
try {
|
|
4291
4301
|
await runWorkThreads(opts);
|
|
4292
4302
|
} catch (err) {
|
|
@@ -4308,7 +4318,7 @@ live addition remains on it.
|
|
|
4308
4318
|
`
|
|
4309
4319
|
).action(async (opts) => {
|
|
4310
4320
|
warnIfApiKeyFlag(opts);
|
|
4311
|
-
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-
|
|
4321
|
+
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4312
4322
|
try {
|
|
4313
4323
|
await runWorkRemove(opts);
|
|
4314
4324
|
} catch (err) {
|
|
@@ -4321,7 +4331,7 @@ live addition remains on it.
|
|
|
4321
4331
|
});
|
|
4322
4332
|
workCmd.command("status").description("Show one item's stage, gate ledger, and additions").option("--item <number>", "the item's number inside this factory").option("--issue <number>", "issue number").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
|
|
4323
4333
|
warnIfApiKeyFlag(opts);
|
|
4324
|
-
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-
|
|
4334
|
+
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4325
4335
|
try {
|
|
4326
4336
|
await runWorkStatus(opts);
|
|
4327
4337
|
} catch (err) {
|
|
@@ -4334,7 +4344,7 @@ live addition remains on it.
|
|
|
4334
4344
|
});
|
|
4335
4345
|
workCmd.command("list").description("List live work items for this factory").option("--stage <spec|build|review>", "filter by stage").option("--section <attention|waiting|flowing>", "filter by Queue section").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--unclaimed", "only items with no live lease").option("--claimed", "only items with a live lease, held by a host or a local session").option("--startable", "only items with an unused build request and no live lease").option("--needs <amend>", "only items with a thread waiting on an agent").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
|
|
4336
4346
|
warnIfApiKeyFlag(opts);
|
|
4337
|
-
const { runWorkList, WorkCommandError } = await import('./work-cmd-
|
|
4347
|
+
const { runWorkList, WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4338
4348
|
try {
|
|
4339
4349
|
await runWorkList(opts);
|
|
4340
4350
|
} catch (err) {
|
|
@@ -4350,7 +4360,7 @@ live addition remains on it.
|
|
|
4350
4360
|
"\n outerlayer work claim --item 42 --kind implement\n\nRecords a lease for this host. A live lease already held by a\ndifferent host is refused; claiming again under the same host extends\nit.\n"
|
|
4351
4361
|
).action(async (opts) => {
|
|
4352
4362
|
warnIfApiKeyFlag(opts);
|
|
4353
|
-
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-
|
|
4363
|
+
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-UHMWOS3G.js');
|
|
4354
4364
|
try {
|
|
4355
4365
|
await runWorkClaim(opts);
|
|
4356
4366
|
} catch (err) {
|
|
@@ -4366,7 +4376,7 @@ live addition remains on it.
|
|
|
4366
4376
|
"\n outerlayer work renew --item 42\n\nExtends this host's own live lease. Refused with a 410 if the lease\nhas expired, or a 403 if a different host holds it.\n"
|
|
4367
4377
|
).action(async (opts) => {
|
|
4368
4378
|
warnIfApiKeyFlag(opts);
|
|
4369
|
-
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-
|
|
4379
|
+
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-UHMWOS3G.js');
|
|
4370
4380
|
try {
|
|
4371
4381
|
await runWorkRenew(opts);
|
|
4372
4382
|
} catch (err) {
|
|
@@ -4385,7 +4395,7 @@ live addition remains on it.
|
|
|
4385
4395
|
"\n outerlayer work release --item 42 --outcome ok\n\nMarks this host's lease released, optionally with an outcome.\nReleasing an already-released lease is a no-op that returns the\nrecorded release time and outcome.\n"
|
|
4386
4396
|
).action(async (opts) => {
|
|
4387
4397
|
warnIfApiKeyFlag(opts);
|
|
4388
|
-
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-
|
|
4398
|
+
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-UHMWOS3G.js');
|
|
4389
4399
|
try {
|
|
4390
4400
|
await runWorkRelease(opts);
|
|
4391
4401
|
} catch (err) {
|
|
@@ -4401,7 +4411,7 @@ live addition remains on it.
|
|
|
4401
4411
|
"\n outerlayer work pr 481\n\nRun inside a session already on a work item. Records that pull\nrequest 481 in the checkout's repository belongs to that item \u2014 the\nsame fact a `pr-link` in the session's own transcript records on\nsync. Idempotent: declaring the same pull request twice is a no-op.\n"
|
|
4402
4412
|
).action(async (number, opts) => {
|
|
4403
4413
|
warnIfApiKeyFlag(opts);
|
|
4404
|
-
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-
|
|
4414
|
+
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-IDIAFFRU.js');
|
|
4405
4415
|
try {
|
|
4406
4416
|
await runWorkPr({ ...opts, number });
|
|
4407
4417
|
} catch (err) {
|
|
@@ -4417,8 +4427,8 @@ live addition remains on it.
|
|
|
4417
4427
|
'\n outerlayer work open-pr --title "Add the thing" --body-file pr.md\n\nIn a host build, which holds an item key, the gateway opens the pull\nrequest as the factory\'s GitHub App, from the branch the claim named,\nor edits the one already open on that branch. No gh command runs.\nIn your own session it runs `gh pr create` (or `gh pr edit`) under your\nlogin, then declares the pull request on the item, as `work pr` does.\nRun it again after a change to the title or description.\n'
|
|
4418
4428
|
).action(async (opts) => {
|
|
4419
4429
|
warnIfApiKeyFlag(opts);
|
|
4420
|
-
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-
|
|
4421
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4430
|
+
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-OPZWGSEQ.js');
|
|
4431
|
+
const { WorkCommandError } = await import('./work-cmd-6UMCFTAW.js');
|
|
4422
4432
|
try {
|
|
4423
4433
|
await runWorkOpenPr(opts);
|
|
4424
4434
|
} catch (err) {
|
|
@@ -4434,8 +4444,8 @@ function registerRunnerCommands(program2) {
|
|
|
4434
4444
|
const runnerCmd = program2.command("runner").description("Take work from the implement and amend queues on this machine");
|
|
4435
4445
|
const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
|
|
4436
4446
|
runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
|
|
4437
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4438
|
-
const { start, RunnerStartError } = await import('./loop-
|
|
4447
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-I3TVFYLH.js');
|
|
4448
|
+
const { start, RunnerStartError } = await import('./loop-D3243JKT.js');
|
|
4439
4449
|
const { RunnerAlreadyRunningError } = await import('./pidfile-UZRH774M.js');
|
|
4440
4450
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4441
4451
|
try {
|
|
@@ -4450,8 +4460,8 @@ function registerRunnerCommands(program2) {
|
|
|
4450
4460
|
}
|
|
4451
4461
|
});
|
|
4452
4462
|
runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
|
|
4453
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4454
|
-
const { runRunnerCheck } = await import('./check-
|
|
4463
|
+
const { defaultRunnerConfigPath } = await import('./config-I3TVFYLH.js');
|
|
4464
|
+
const { runRunnerCheck } = await import('./check-ASZL5BEO.js');
|
|
4455
4465
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4456
4466
|
const result = await runRunnerCheck(configPath);
|
|
4457
4467
|
if (!result.ok) {
|
|
@@ -4466,33 +4476,71 @@ function registerRunnerCommands(program2) {
|
|
|
4466
4476
|
process.stdout.write(`${result.lines.join("\n")}
|
|
4467
4477
|
`);
|
|
4468
4478
|
});
|
|
4469
|
-
runnerCmd.command("install").description("Put this CLI
|
|
4470
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4471
|
-
const { runRunnerInstall, RunnerInstallError } = await import('./install-cmd-
|
|
4479
|
+
runnerCmd.command("install").description("Put this CLI in the runner's install layout; --service adds its service").option("--config <path>", configOption).option("--service", "set up the service that keeps the runner running").option("--print", "with --service, print the unit and set up nothing").option("--user <account>", "with --service, the account the service runs as").option("--replace", "with --service, replace a unit this command did not write").addOption(new Option("--unit-name <name>", "with --service, the unit's name").hideHelp()).action(async (opts) => {
|
|
4480
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-I3TVFYLH.js');
|
|
4481
|
+
const { runRunnerInstall, RunnerInstallError } = await import('./install-cmd-B5SEU3G7.js');
|
|
4472
4482
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4483
|
+
if (opts.service !== true) {
|
|
4484
|
+
for (const flag of ["print", "user", "replace", "unitName"]) {
|
|
4485
|
+
if (opts[flag] !== void 0) {
|
|
4486
|
+
fail(`--${flag === "unitName" ? "unit-name" : flag} is for --service.`);
|
|
4487
|
+
return;
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4473
4491
|
try {
|
|
4492
|
+
if (opts.service === true) {
|
|
4493
|
+
const { installServiceCommand } = await import('./command-FLSYCGIB.js');
|
|
4494
|
+
const result2 = await installServiceCommand({
|
|
4495
|
+
configPath,
|
|
4496
|
+
print: opts.print,
|
|
4497
|
+
user: opts.user,
|
|
4498
|
+
replace: opts.replace,
|
|
4499
|
+
unitName: opts.unitName,
|
|
4500
|
+
entryPath: process.argv[1] ?? "",
|
|
4501
|
+
nodePath: process.execPath,
|
|
4502
|
+
home: homeFromEnv()
|
|
4503
|
+
});
|
|
4504
|
+
if (result2.unit !== void 0) process.stdout.write(result2.unit);
|
|
4505
|
+
if (result2.ok) for (const line of result2.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
|
|
4506
|
+
`);
|
|
4507
|
+
else fail(result2.lines.length > 0 ? result2.lines.join("\n ") : "the service was not set up");
|
|
4508
|
+
return;
|
|
4509
|
+
}
|
|
4474
4510
|
const result = runRunnerInstall({ configPath, entryPath: process.argv[1] ?? "", nodePath: process.execPath });
|
|
4475
4511
|
process.stdout.write(`${C.green}\u2713${C.reset} installed ${result.version} for the runner; \`current\` names it
|
|
4476
4512
|
`);
|
|
4477
4513
|
process.stdout.write(
|
|
4478
4514
|
`
|
|
4479
|
-
|
|
4515
|
+
To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}. To start the runner from the install layout yourself, use this line, then restart the service:
|
|
4480
4516
|
${C.yellow}${result.execStart}${C.reset}
|
|
4481
4517
|
`
|
|
4482
4518
|
);
|
|
4483
4519
|
} catch (err) {
|
|
4484
|
-
if (err instanceof RunnerInstallError) {
|
|
4520
|
+
if (err instanceof RunnerInstallError || err instanceof RunnerConfigError) {
|
|
4485
4521
|
fail(err.message);
|
|
4486
4522
|
return;
|
|
4487
4523
|
}
|
|
4488
4524
|
throw err;
|
|
4489
4525
|
}
|
|
4490
4526
|
});
|
|
4491
|
-
runnerCmd.command("
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4527
|
+
runnerCmd.command("uninstall").description("Stop the runner's service and remove it (needs --service)").option("--config <path>", configOption).option("--service", "remove the service, and the launch agent or scheduled task").addOption(new Option("--unit-name <name>", "the unit's name").hideHelp()).action(async (opts) => {
|
|
4528
|
+
if (opts.service !== true) {
|
|
4529
|
+
fail("pass --service: `outerlayer runner uninstall --service` removes the runner's service.");
|
|
4530
|
+
return;
|
|
4531
|
+
}
|
|
4532
|
+
const { defaultRunnerConfigPath } = await import('./config-I3TVFYLH.js');
|
|
4533
|
+
const { uninstallServiceCommand } = await import('./command-FLSYCGIB.js');
|
|
4534
|
+
const result = await uninstallServiceCommand({ configPath: opts.config ?? defaultRunnerConfigPath(), unitName: opts.unitName, home: homeFromEnv() });
|
|
4535
|
+
if (result.ok) for (const line of result.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
|
|
4536
|
+
`);
|
|
4537
|
+
else fail(result.lines.length > 0 ? result.lines.join("\n ") : "the service was not removed");
|
|
4538
|
+
});
|
|
4539
|
+
runnerCmd.command("init").description("Write a runner block that fits this machine; on macOS, offers a Linux VM").option("--config <path>", configOption).option("--vm", "on macOS, run the runner in a Linux VM (Lima), with container builds").option("--no-vm", "on macOS, skip the VM and run builds as unisolated processes").option("--allow-process-builds", "where builds cannot be isolated, run them as processes anyway").addOption(new Option("--config-stdin", "the VM-side hand-off: read the whole config as JSON on stdin").hideHelp()).addOption(new Option("--vm-cli-package <path>", "install this packed CLI tarball in the VM instead of the published version").hideHelp()).addOption(new Option("--unit-name <name>", "the service unit's name").hideHelp()).action(async (opts) => {
|
|
4540
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-I3TVFYLH.js');
|
|
4541
|
+
const { runRunnerInit, RunnerInitError } = await import('./init-BACXESVV.js');
|
|
4542
|
+
const { detectMachine } = await import('./machine-EB3GEVI4.js');
|
|
4543
|
+
const { chooseVm, runVmInit, VmInitError } = await import('./init-VLW7H6RW.js');
|
|
4496
4544
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4497
4545
|
try {
|
|
4498
4546
|
const machine = detectMachine();
|
|
@@ -4524,7 +4572,7 @@ hooks: ${result2.hooks}
|
|
|
4524
4572
|
}
|
|
4525
4573
|
});
|
|
4526
4574
|
if (useVm) {
|
|
4527
|
-
const { realLima } = await import('./lima-
|
|
4575
|
+
const { realLima } = await import('./lima-7NPCNGWT.js');
|
|
4528
4576
|
const { cpus, totalmem } = await import('os');
|
|
4529
4577
|
const { resolvePackageVersion } = await import('./version-BWM6VLDI.js');
|
|
4530
4578
|
const result2 = await runVmInit(configPath, {
|
|
@@ -4561,17 +4609,36 @@ ${C.yellow}${result.note}${C.reset}
|
|
|
4561
4609
|
To isolate builds in containers instead, run ${C.yellow}outerlayer runner init --vm${C.reset}.
|
|
4562
4610
|
`);
|
|
4563
4611
|
}
|
|
4564
|
-
const { runRunnerInstall, RunnerInstallError } = await import('./install-cmd-
|
|
4565
|
-
let
|
|
4612
|
+
const { runRunnerInstall, RunnerInstallError } = await import('./install-cmd-B5SEU3G7.js');
|
|
4613
|
+
let installedLayout = false;
|
|
4566
4614
|
try {
|
|
4567
4615
|
const installed = runRunnerInstall({ configPath, entryPath: process.argv[1] ?? "", nodePath: process.execPath });
|
|
4568
|
-
|
|
4616
|
+
installedLayout = true;
|
|
4569
4617
|
process.stdout.write(`${C.green}\u2713${C.reset} installed ${installed.version} for the runner, so it can update itself
|
|
4570
4618
|
`);
|
|
4571
4619
|
} catch (installErr) {
|
|
4572
4620
|
if (!(installErr instanceof RunnerInstallError)) throw installErr;
|
|
4573
4621
|
process.stdout.write(`
|
|
4574
4622
|
${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
|
|
4623
|
+
`);
|
|
4624
|
+
}
|
|
4625
|
+
let serviceUp = false;
|
|
4626
|
+
if (installedLayout) {
|
|
4627
|
+
const { installServiceCommand } = await import('./command-FLSYCGIB.js');
|
|
4628
|
+
const service = await installServiceCommand({
|
|
4629
|
+
configPath,
|
|
4630
|
+
entryPath: process.argv[1] ?? "",
|
|
4631
|
+
nodePath: process.execPath,
|
|
4632
|
+
home: homeFromEnv(),
|
|
4633
|
+
unitName: opts.unitName,
|
|
4634
|
+
layoutInstalled: true
|
|
4635
|
+
});
|
|
4636
|
+
serviceUp = service.ok && service.state !== "needs-wsl-shutdown";
|
|
4637
|
+
for (const line of service.lines) process.stdout.write(service.ok ? `${C.green}\u2713${C.reset} ${line}
|
|
4638
|
+
` : `${C.yellow}${line}${C.reset}
|
|
4639
|
+
`);
|
|
4640
|
+
} else {
|
|
4641
|
+
process.stdout.write(`${C.yellow}No service was set up: it starts the runner from the install layout, which needs a CLI installed with npm.${C.reset}
|
|
4575
4642
|
`);
|
|
4576
4643
|
}
|
|
4577
4644
|
process.stdout.write(
|
|
@@ -4579,9 +4646,8 @@ ${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
|
|
|
4579
4646
|
Next:
|
|
4580
4647
|
1. Edit the command lines in ${result.configPath} to start your agent.
|
|
4581
4648
|
2. ${C.yellow}outerlayer runner check${C.reset}
|
|
4582
|
-
|
|
4583
|
-
`
|
|
4584
|
-
${C.yellow}${execStart}${C.reset}
|
|
4649
|
+
` + (serviceUp ? ` The runner service claims nothing until step 1 is done and a Claude credential is in ${join(dirname(configPath), "runner.env")}; ${C.yellow}outerlayer runner status${C.reset} shows what it is doing.
|
|
4650
|
+
` : ` 3. ${C.yellow}outerlayer runner start${C.reset}, or ${C.yellow}outerlayer runner install --service${C.reset} to keep it running.
|
|
4585
4651
|
`)
|
|
4586
4652
|
);
|
|
4587
4653
|
} catch (err) {
|
|
@@ -4596,8 +4662,8 @@ Next:
|
|
|
4596
4662
|
"after",
|
|
4597
4663
|
"\nFetches the head of the default branch into the runner's cache, reads its\n.devcontainer/devcontainer.json, and builds the image with the devcontainer CLI. Settings\nthat reach the host or widen the container's privileges are ignored and listed. The\nimage holds this CLI and a pinned Claude Code. Nothing runs inside the image.\n"
|
|
4598
4664
|
).action(async (opts) => {
|
|
4599
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4600
|
-
const { buildRepositoryImage, RecipeError } = await import('./build-
|
|
4665
|
+
const { defaultRunnerConfigPath } = await import('./config-I3TVFYLH.js');
|
|
4666
|
+
const { buildRepositoryImage, RecipeError } = await import('./build-JF5UOWKJ.js');
|
|
4601
4667
|
const { currentCliBuild } = await import('./cli-build-K56DK4DS.js');
|
|
4602
4668
|
const { createDockerHost } = await import('./docker-NEGDLU6D.js');
|
|
4603
4669
|
try {
|
|
@@ -4648,16 +4714,16 @@ Next:
|
|
|
4648
4714
|
}
|
|
4649
4715
|
});
|
|
4650
4716
|
runnerCmd.command("stop").description("Take no more work; wait for running jobs to finish, then exit").option("--config <path>", "the cloud config file naming the runner to stop").option("--now", "end running jobs immediately, with outcome stopped").action(async (opts) => {
|
|
4651
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4652
|
-
const { requestStop } = await import('./loop-
|
|
4717
|
+
const { defaultRunnerConfigPath } = await import('./config-I3TVFYLH.js');
|
|
4718
|
+
const { requestStop } = await import('./loop-D3243JKT.js');
|
|
4653
4719
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4654
4720
|
await requestStop(configPath, Boolean(opts.now));
|
|
4655
4721
|
});
|
|
4656
4722
|
runnerCmd.command("status").description("List running jobs; with --recent, finished ones too").option("--config <path>", "the cloud config file naming the runner to inspect").option("--recent", "also list finished jobs, newest first, capped at 20").option("--json", "machine-readable JSON output").action(async (opts) => {
|
|
4657
|
-
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-
|
|
4723
|
+
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-I3TVFYLH.js');
|
|
4658
4724
|
const { jobsDir, runnerDir } = await import('./paths-OYKMVYJP.js');
|
|
4659
|
-
const { listJobFiles, runnerProcessState } = await import('./loop-
|
|
4660
|
-
const { renderStatus } = await import('./status-
|
|
4725
|
+
const { listJobFiles, runnerProcessState } = await import('./loop-D3243JKT.js');
|
|
4726
|
+
const { renderStatus } = await import('./status-F4THTJJK.js');
|
|
4661
4727
|
const { readHousekeepingRecord } = await import('./record-C43U4PKS.js');
|
|
4662
4728
|
const path2 = await import('path');
|
|
4663
4729
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
@@ -4672,11 +4738,19 @@ Next:
|
|
|
4672
4738
|
} catch {
|
|
4673
4739
|
}
|
|
4674
4740
|
const processState = runnerProcessState(configPath);
|
|
4741
|
+
const service = await (async () => {
|
|
4742
|
+
if (process.platform !== "linux" || !existsSync("/run/systemd/system")) return void 0;
|
|
4743
|
+
const { inspectService, realInspectProbes } = await import('./inspect-XAUSB7L3.js');
|
|
4744
|
+
const { DEFAULT_UNIT_NAME } = await import('./install-NMAPLLBQ.js');
|
|
4745
|
+
const facts = inspectService(DEFAULT_UNIT_NAME, path2.dirname(configPath), realInspectProbes());
|
|
4746
|
+
return facts === void 0 ? void 0 : { unit: facts.unit, running: facts.mainPid !== void 0, delegated: facts.delegate };
|
|
4747
|
+
})();
|
|
4675
4748
|
if (opts.json) {
|
|
4676
4749
|
writeJson({
|
|
4677
4750
|
host,
|
|
4678
4751
|
configPath,
|
|
4679
4752
|
process: processState,
|
|
4753
|
+
service,
|
|
4680
4754
|
concurrency,
|
|
4681
4755
|
// A hold is only true of a runner that is running.
|
|
4682
4756
|
housekeeping: processState.state === "running" ? housekeeping : { ...housekeeping, holding: void 0 },
|
|
@@ -4693,15 +4767,16 @@ Next:
|
|
|
4693
4767
|
jobs: all,
|
|
4694
4768
|
now: /* @__PURE__ */ new Date(),
|
|
4695
4769
|
recent: Boolean(opts.recent),
|
|
4696
|
-
housekeeping
|
|
4770
|
+
housekeeping,
|
|
4771
|
+
service
|
|
4697
4772
|
})}
|
|
4698
4773
|
`
|
|
4699
4774
|
);
|
|
4700
4775
|
});
|
|
4701
4776
|
runnerCmd.command("logs").argument("<item>", "the work item's number in the factory").description("Print the newest attempt's log for one item").option("--config <path>", "the cloud config file naming the runner to inspect").option("-f, --follow", "keep printing as the log grows").action(async (itemArg, opts) => {
|
|
4702
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4703
|
-
const { listJobFiles } = await import('./loop-
|
|
4704
|
-
const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-
|
|
4777
|
+
const { defaultRunnerConfigPath } = await import('./config-I3TVFYLH.js');
|
|
4778
|
+
const { listJobFiles } = await import('./loop-D3243JKT.js');
|
|
4779
|
+
const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-H55NWW4H.js');
|
|
4705
4780
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4706
4781
|
const item = parseTrackerNumber(itemArg);
|
|
4707
4782
|
if (item === void 0) {
|
|
@@ -4957,7 +5032,7 @@ function registerMcpCommands(program2) {
|
|
|
4957
5032
|
function registerImportCommands(program2) {
|
|
4958
5033
|
const importCmd = program2.command("import").description("Import an existing config format into .outerlayer/");
|
|
4959
5034
|
importCmd.command("ruler").description("Port a .ruler/ tree into the equivalent .outerlayer/ tree").option("--dir <path>", "repo root to read from (default: cwd)").option("--json", "machine-readable JSON output").addHelpText("after", "\nRuler: https://github.com/intellectronica/ruler. Mostly a rename.\n").action(async (opts) => {
|
|
4960
|
-
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-
|
|
5035
|
+
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-SG3UVGI7.js');
|
|
4961
5036
|
try {
|
|
4962
5037
|
const result = runImportRuler({ cwd: opts.dir, json: opts.json });
|
|
4963
5038
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -4973,7 +5048,7 @@ function registerImportCommands(program2) {
|
|
|
4973
5048
|
"after",
|
|
4974
5049
|
"\nInstalls the four maintained skills (emitting-evidence, amend,\nreporting-findings, outerlayer) and an AGENTS.md snippet teaching agents to run\n`emit artifact`. A skill that differs from this CLI's bundle is rewritten to it, and the output says so.\n"
|
|
4975
5050
|
).action(async (opts) => {
|
|
4976
|
-
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-
|
|
5051
|
+
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-T4556ELW.js');
|
|
4977
5052
|
try {
|
|
4978
5053
|
runImportCapture({ cwd: opts.dir, json: opts.json });
|
|
4979
5054
|
} catch (err) {
|
|
@@ -5016,7 +5091,7 @@ function registerContextCommands(program2) {
|
|
|
5016
5091
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
5017
5092
|
});
|
|
5018
5093
|
contextCmd.command("adopt <stagedDir>", { hidden: true }).description("Copy context the runner staged into this checkout (container builds)").option("--json", "machine-readable JSON output").action(async (stagedDir) => {
|
|
5019
|
-
const { runContextAdopt } = await import('./context-adopt-
|
|
5094
|
+
const { runContextAdopt } = await import('./context-adopt-CE4KDXS3.js');
|
|
5020
5095
|
const { exitCode, stdout } = runContextAdopt(stagedDir, process.cwd());
|
|
5021
5096
|
process.stdout.write(stdout);
|
|
5022
5097
|
process.exitCode = exitCode;
|
|
@@ -5025,7 +5100,7 @@ function registerContextCommands(program2) {
|
|
|
5025
5100
|
"after",
|
|
5026
5101
|
"\nThe same flow SessionStart runs automatically, exposed for a manual retry or a\nfirst check outside a session. Writes AGENTS.md, .claude/**, and .outerlayer/**.\n"
|
|
5027
5102
|
).action(async (opts) => {
|
|
5028
|
-
const { materializeContext } = await import('./context-materialize-
|
|
5103
|
+
const { materializeContext } = await import('./context-materialize-QL33HDJN.js');
|
|
5029
5104
|
const result = await materializeContext({ cwd: process.cwd(), sessionId: `manual-${Date.now()}` });
|
|
5030
5105
|
const output = formatContextMaterializeOutput(result);
|
|
5031
5106
|
if (output.exitCode !== void 0) process.exitCode = output.exitCode;
|