@outerlayer/cli 0.12.0 → 0.13.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 +12 -0
- package/README.md +9 -4
- package/dist/{agent-setup-52LRZ6AY.js → agent-setup-QE6PSCEZ.js} +8 -8
- package/dist/build-info.json +1 -1
- package/dist/{builder-OF67QKDS.js → builder-UUS4ORDH.js} +3 -3
- package/dist/{check-RJOJU2WA.js → check-63IDCEEV.js} +27 -27
- package/dist/{chunk-XR3BJN33.js → chunk-22RMZBGW.js} +20 -1
- package/dist/{chunk-AHZQBGD2.js → chunk-2M63GG56.js} +1 -1
- package/dist/{chunk-27Y7AX2O.js → chunk-3D4OYFCD.js} +4 -4
- package/dist/{chunk-GGMRZPEA.js → chunk-3KTA5UU2.js} +1 -1
- package/dist/{chunk-USO2DKBD.js → chunk-4KSQKQXE.js} +8 -2
- package/dist/{chunk-C7N4TDHW.js → chunk-4QVZCVWT.js} +5 -5
- package/dist/{chunk-NPXQXYVA.js → chunk-6S3H3J6H.js} +2 -2
- package/dist/{chunk-DVT73QJO.js → chunk-C6IV5BV7.js} +10 -10
- package/dist/{chunk-JOXYKGUV.js → chunk-CNFVHDHG.js} +1 -1
- package/dist/{chunk-ANW7VHMH.js → chunk-DPKX26LT.js} +92 -16
- package/dist/{chunk-ZQUCTFXC.js → chunk-DXQ5MHCO.js} +1 -1
- package/dist/{chunk-GATMPAMK.js → chunk-EFZLAYPE.js} +2 -2
- package/dist/{chunk-SZOVKFWB.js → chunk-GI4XXD4I.js} +3 -3
- package/dist/{chunk-G5XY6CVG.js → chunk-HDTVTA6I.js} +2 -2
- package/dist/{chunk-325272HM.js → chunk-J5M7BSJQ.js} +11 -4
- package/dist/{chunk-3ZPYPFNM.js → chunk-JXYVA45C.js} +1 -1
- package/dist/{chunk-G5IEVZGI.js → chunk-LCEXHCHD.js} +1 -1
- package/dist/{chunk-GEBQXUFY.js → chunk-MJXXRX4M.js} +24 -10
- package/dist/{chunk-SKHN72JO.js → chunk-MZN7AQOB.js} +8 -8
- package/dist/{chunk-QEESCZ26.js → chunk-NX57IBNK.js} +1 -1
- package/dist/{chunk-6FH2AHJY.js → chunk-P4MM66C6.js} +30 -17
- package/dist/{chunk-IBB4D4KE.js → chunk-P6FX4D43.js} +1 -1
- package/dist/{chunk-A56PYPDF.js → chunk-R7OQTKWT.js} +2 -1
- package/dist/{chunk-2KLBKHT4.js → chunk-RLYZLUQ7.js} +1 -1
- package/dist/chunk-RMWLBUCJ.js +50 -0
- package/dist/{chunk-YEQL54G5.js → chunk-SFFHGX3G.js} +1 -1
- package/dist/{chunk-G4RXNF2L.js → chunk-SVEP7PVH.js} +12 -12
- package/dist/{chunk-VK25O2ZM.js → chunk-T5VPP6H7.js} +1 -1
- package/dist/{chunk-FO7KKPYG.js → chunk-TCIW27FM.js} +1 -1
- package/dist/{chunk-PDRYXERC.js → chunk-TOPDNXHZ.js} +5 -5
- package/dist/{chunk-5TGQHOUX.js → chunk-XJKL4BNU.js} +3 -3
- package/dist/{cli-JSSRGA6V.js → cli-WSBIAVZU.js} +116 -80
- package/dist/{command-3WYZ2ML5.js → command-N7BAB4XJ.js} +18 -18
- package/dist/{config-MKBX2ZQD.js → config-N3C6DFQA.js} +1 -1
- package/dist/{connect-cmd-A5NGODCJ.js → connect-cmd-FGYRLLXL.js} +5 -5
- package/dist/{context-adopt-BAHGXJZV.js → context-adopt-B3PWGFHL.js} +5 -5
- package/dist/{context-materialize-45OVRRK2.js → context-materialize-7S6NLLRO.js} +5 -5
- package/dist/{dist-EQDW7MZW.js → dist-LKDWQWZ7.js} +2 -2
- package/dist/{docker-VGWEJWI7.js → docker-BZ55BMBJ.js} +4 -4
- package/dist/{doctor-4FFXTQJ2.js → doctor-3H25Q7WT.js} +20 -20
- package/dist/{emit-artifact-cmd-QS7XNKBT.js → emit-artifact-cmd-IQCRXOH7.js} +8 -8
- package/dist/{emit-cmd-LXEIDKLT.js → emit-cmd-KDSM5VAO.js} +4 -4
- package/dist/{emit-criteria-cmd-XN6AKA53.js → emit-criteria-cmd-EYUXME26.js} +6 -6
- package/dist/{emit-finding-cmd-SQJSEHYS.js → emit-finding-cmd-P4RKBPBB.js} +6 -6
- package/dist/{emit-result-cmd-56RHPHOA.js → emit-result-cmd-6XYENU6H.js} +8 -8
- package/dist/{hook-fast-HLESEJAL.js → hook-fast-PXWKQPN6.js} +1 -1
- package/dist/{import-capture-cmd-NHMAFDM6.js → import-capture-cmd-2BKM5I2N.js} +3 -3
- package/dist/{import-ruler-cmd-UYB32YUT.js → import-ruler-cmd-IXR7YK47.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{init-UZKD4RY7.js → init-2LWVS4AH.js} +19 -19
- package/dist/{init-6AY5T3P6.js → init-ZL7ORPTF.js} +38 -28
- package/dist/{init-cmd-XGSX2BCC.js → init-cmd-JXOBCOIB.js} +14 -12
- package/dist/{install-VXXI7UR6.js → install-HDBIPHTX.js} +2 -2
- package/dist/{login-browser-7XGSV7MA.js → login-browser-QZCS3WW6.js} +2 -1
- package/dist/{loop-4NMI2USY.js → loop-XOAE6ZIY.js} +27 -27
- package/dist/{machine-4JX2D4TS.js → machine-G6PY2J2J.js} +15 -15
- package/dist/{mcp-install-cmd-XZARXNYT.js → mcp-install-cmd-VXVIH7PH.js} +1 -1
- package/dist/{runner-env-WAXTJXZK.js → runner-env-XTC53CHN.js} +3 -3
- package/dist/runner-key-TDTLNAKJ.js +154 -0
- package/dist/{session-sender-T7PN4YRC.js → session-sender-XVGZFWRK.js} +6 -6
- package/dist/{starter-pack-Z22VRFPF.js → starter-pack-B7JPGEDO.js} +4 -4
- package/dist/{status-OXBIRWJ7.js → status-MRTPG34B.js} +20 -20
- package/dist/{sync-cmd-EVXNR47N.js → sync-cmd-UBUZMMDN.js} +5 -5
- package/dist/{watch-7NSFOAL5.js → watch-STNPEWD6.js} +5 -5
- package/dist/{work-claim-cmd-KR7UR2AB.js → work-claim-cmd-CWGYEIJE.js} +10 -10
- package/dist/{work-cmd-JPM37MLF.js → work-cmd-X7NMJDFL.js} +7 -7
- package/dist/{work-comment-cmd-3DC6BC34.js → work-comment-cmd-FI2TMAYQ.js} +7 -7
- package/dist/{work-open-pr-cmd-XZQRJBNZ.js → work-open-pr-cmd-OVHJ5I5H.js} +8 -8
- package/dist/{work-pr-cmd-WHGZOP22.js → work-pr-cmd-Y5TDMQ4O.js} +7 -7
- package/package.json +1 -1
- package/skill-pack/template/build/SKILL.md +60 -33
- package/skill-pack/template/build/references/agent-briefs.md +4 -2
- package/skill-pack/template/build/references/release.md +1 -1
- package/skill-pack/template/build/references/review-loop.md +6 -2
- package/skill-pack/template/build/scripts/record-criteria.mjs +109 -143
- package/skill-pack/validators/code-review.yaml +4 -2
- package/dist/chunk-T6OIJQRT.js +0 -31
|
@@ -1,29 +1,29 @@
|
|
|
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-
|
|
3
|
+
import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-DPKX26LT.js';
|
|
4
4
|
import './chunk-F47JBIAW.js';
|
|
5
5
|
import './chunk-BKO6JEZI.js';
|
|
6
|
-
import './chunk-
|
|
7
|
-
import './chunk-
|
|
6
|
+
import './chunk-P4MM66C6.js';
|
|
7
|
+
import './chunk-EFZLAYPE.js';
|
|
8
8
|
import './chunk-IP7BIBXJ.js';
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
11
|
-
import './chunk-
|
|
12
|
-
import './chunk-
|
|
9
|
+
import './chunk-4QVZCVWT.js';
|
|
10
|
+
import './chunk-CNFVHDHG.js';
|
|
11
|
+
import './chunk-JXYVA45C.js';
|
|
12
|
+
import './chunk-4KSQKQXE.js';
|
|
13
13
|
import './chunk-N6LURUEF.js';
|
|
14
14
|
import { C, NO_COLOR_FLAG, warnDeprecated, stripNoColor, API_KEY_FLAG_DEPRECATION } from './chunk-YRYMNBGQ.js';
|
|
15
15
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
16
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';
|
|
17
|
-
import { pinExists } from './chunk-
|
|
18
|
-
import './chunk-
|
|
17
|
+
import { pinExists } from './chunk-LCEXHCHD.js';
|
|
18
|
+
import './chunk-2M63GG56.js';
|
|
19
19
|
import './chunk-YO4PSLVB.js';
|
|
20
20
|
import './chunk-PLMTLGYH.js';
|
|
21
|
-
import './chunk-
|
|
21
|
+
import './chunk-J5M7BSJQ.js';
|
|
22
22
|
import './chunk-EABW6AJQ.js';
|
|
23
23
|
import { resolveVersion } from './chunk-RA3O54FC.js';
|
|
24
24
|
import './chunk-V7NIVOFD.js';
|
|
25
25
|
import './chunk-ZM2IMMYN.js';
|
|
26
|
-
import { hookFiredMarkerPath, installedCliDistDir } from './chunk-
|
|
26
|
+
import { hookFiredMarkerPath, installedCliDistDir } from './chunk-SFFHGX3G.js';
|
|
27
27
|
import { managedHookScripts, removeJournalHooks, installPreCommitGuardHook, removePreCommitGuardHook } from './chunk-XCCLFVXM.js';
|
|
28
28
|
import './chunk-BJ3KTMDH.js';
|
|
29
29
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
@@ -3617,7 +3617,7 @@ function resolveCliBin() {
|
|
|
3617
3617
|
return "outerlayer";
|
|
3618
3618
|
}
|
|
3619
3619
|
}
|
|
3620
|
-
var SUPPORT_TEXT = "\nDocs: https://
|
|
3620
|
+
var SUPPORT_TEXT = "\nDocs: https://docs.outerlayer.ai\nIssues: https://github.com/outerlayerai/outerlayer/issues\n";
|
|
3621
3621
|
function fail(message) {
|
|
3622
3622
|
process.stderr.write(`${C.red}\u2717${C.reset} ${message}
|
|
3623
3623
|
`);
|
|
@@ -3641,7 +3641,7 @@ function warnIfApiKeyFlag(opts) {
|
|
|
3641
3641
|
if (opts.apiKey !== void 0) warnDeprecated(API_KEY_FLAG_DEPRECATION);
|
|
3642
3642
|
}
|
|
3643
3643
|
async function installStarterPackInRepo() {
|
|
3644
|
-
const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-
|
|
3644
|
+
const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-B7JPGEDO.js');
|
|
3645
3645
|
const cwd = process.cwd();
|
|
3646
3646
|
let repoRoot = cwd;
|
|
3647
3647
|
try {
|
|
@@ -3801,8 +3801,8 @@ ${starter.output}`),
|
|
|
3801
3801
|
}
|
|
3802
3802
|
}
|
|
3803
3803
|
async function realConnectDepsForCwd() {
|
|
3804
|
-
const { realConnectDeps } = await import('./connect-cmd-
|
|
3805
|
-
const { resolveRepoIdentity } = await import('./dist-
|
|
3804
|
+
const { realConnectDeps } = await import('./connect-cmd-FGYRLLXL.js');
|
|
3805
|
+
const { resolveRepoIdentity } = await import('./dist-LKDWQWZ7.js');
|
|
3806
3806
|
return {
|
|
3807
3807
|
...realConnectDeps(),
|
|
3808
3808
|
home: homeFromEnv(),
|
|
@@ -3824,7 +3824,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3824
3824
|
).action(async (opts) => {
|
|
3825
3825
|
let starterTemplate;
|
|
3826
3826
|
if (opts.template !== void 0) {
|
|
3827
|
-
const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-
|
|
3827
|
+
const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-B7JPGEDO.js');
|
|
3828
3828
|
try {
|
|
3829
3829
|
assertKnownTemplate(opts.template);
|
|
3830
3830
|
} catch (err) {
|
|
@@ -3855,7 +3855,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3855
3855
|
else process.stdout.write(outcome.text);
|
|
3856
3856
|
return;
|
|
3857
3857
|
}
|
|
3858
|
-
const { runInitCommand } = await import('./init-cmd-
|
|
3858
|
+
const { runInitCommand } = await import('./init-cmd-JXOBCOIB.js');
|
|
3859
3859
|
const code = await runInitCommand(
|
|
3860
3860
|
{ json: opts.json, factory: opts.factory },
|
|
3861
3861
|
{
|
|
@@ -3867,7 +3867,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3867
3867
|
return { ok, text, detail };
|
|
3868
3868
|
},
|
|
3869
3869
|
runAgentSetup: async () => {
|
|
3870
|
-
const { runAgentSetup } = await import('./agent-setup-
|
|
3870
|
+
const { runAgentSetup } = await import('./agent-setup-QE6PSCEZ.js');
|
|
3871
3871
|
return runAgentSetup({ cwd: process.cwd() });
|
|
3872
3872
|
},
|
|
3873
3873
|
runDoctorChecks: gatherDoctorChecks
|
|
@@ -3879,7 +3879,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3879
3879
|
"after",
|
|
3880
3880
|
"\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"
|
|
3881
3881
|
).action(async (opts) => {
|
|
3882
|
-
const { runConnectCommand } = await import('./connect-cmd-
|
|
3882
|
+
const { runConnectCommand } = await import('./connect-cmd-FGYRLLXL.js');
|
|
3883
3883
|
const code = await runConnectCommand({ factory: opts.factory, json: opts.json }, await realConnectDepsForCwd(), {
|
|
3884
3884
|
stdout: process.stdout,
|
|
3885
3885
|
stderr: process.stderr
|
|
@@ -3899,7 +3899,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3899
3899
|
"after",
|
|
3900
3900
|
'\nWith no key on stdin, login prints an approve link and a code. A signed-in\nperson approves it on the dashboard. The login is a token for that person\'s\naccount, made for this machine, saved here and never printed. It picks no\nfactory: run `outerlayer connect` for that. `outerlayer logout` revokes it.\n\nWhen stdout is not a terminal, login does not wait. It prints one JSON\ndocument with the link, the code and a `login --check <id>` command, and\nexits 75. Run the check until it stops exiting 75: 0 is signed in, 1 is\ndenied or expired. A dropped connection or a 5xx also exits 75.\n\nA factory key piped on stdin is saved as it always was, never as a flag and\nnever printed back. A factory key always wins over the login, so CI and\nrunners keep acting as their key.\n\n echo "$OUTERLAYER_KEY" | outerlayer login --url <gateway url> --app-id <factory id>\n\nEvery later command reads the saved file, so none of them needs a key on\nits command line. A saved key is checked for real on the first `sync`.\n'
|
|
3901
3901
|
).action(async (opts) => {
|
|
3902
|
-
const { runLoginCommand, realLoginDeps } = await import('./login-browser-
|
|
3902
|
+
const { runLoginCommand, realLoginDeps } = await import('./login-browser-QZCS3WW6.js');
|
|
3903
3903
|
const code = await runLoginCommand(
|
|
3904
3904
|
{
|
|
3905
3905
|
browser: opts.browser !== false,
|
|
@@ -3927,7 +3927,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3927
3927
|
"\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"
|
|
3928
3928
|
).action(async (opts) => {
|
|
3929
3929
|
warnIfApiKeyFlag(opts);
|
|
3930
|
-
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-
|
|
3930
|
+
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-UBUZMMDN.js');
|
|
3931
3931
|
try {
|
|
3932
3932
|
const result = await runSync({
|
|
3933
3933
|
url: opts.url,
|
|
@@ -3956,7 +3956,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3956
3956
|
if (invokedCommandToken(argv) === "watch") {
|
|
3957
3957
|
warnDeprecated("`outerlayer watch` is now `outerlayer daemon`; the old name will be removed in a future release.");
|
|
3958
3958
|
}
|
|
3959
|
-
const { runWatch } = await import('./watch-
|
|
3959
|
+
const { runWatch } = await import('./watch-STNPEWD6.js');
|
|
3960
3960
|
await runWatch({ once: opts.once });
|
|
3961
3961
|
});
|
|
3962
3962
|
program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
|
|
@@ -4010,7 +4010,7 @@ function buildProgram(argv = process.argv) {
|
|
|
4010
4010
|
}
|
|
4011
4011
|
});
|
|
4012
4012
|
program2.command("session-sender", { hidden: true }).description("stream a runner build's sessions to its work item while the build runs").action(async () => {
|
|
4013
|
-
const { runSessionSender } = await import('./session-sender-
|
|
4013
|
+
const { runSessionSender } = await import('./session-sender-XVGZFWRK.js');
|
|
4014
4014
|
try {
|
|
4015
4015
|
await runSessionSender();
|
|
4016
4016
|
} catch (err) {
|
|
@@ -4045,7 +4045,7 @@ async function runCli(processArgv) {
|
|
|
4045
4045
|
await buildProgram(argv).parseAsync(argv);
|
|
4046
4046
|
}
|
|
4047
4047
|
async function compileContext(opts) {
|
|
4048
|
-
const { runEmit, EmitError } = await import('./emit-cmd-
|
|
4048
|
+
const { runEmit, EmitError } = await import('./emit-cmd-KDSM5VAO.js');
|
|
4049
4049
|
try {
|
|
4050
4050
|
const result = runEmit({ cwd: opts.dir, check: opts.check, json: opts.json });
|
|
4051
4051
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -4068,7 +4068,7 @@ function registerEmitCommands(program2) {
|
|
|
4068
4068
|
return;
|
|
4069
4069
|
}
|
|
4070
4070
|
warnIfApiKeyFlag(opts);
|
|
4071
|
-
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-
|
|
4071
|
+
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-6XYENU6H.js');
|
|
4072
4072
|
try {
|
|
4073
4073
|
const result = await runEmitResult({
|
|
4074
4074
|
name,
|
|
@@ -4119,7 +4119,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4119
4119
|
`
|
|
4120
4120
|
).action(async (file, opts) => {
|
|
4121
4121
|
warnIfApiKeyFlag(opts);
|
|
4122
|
-
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-
|
|
4122
|
+
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-IQCRXOH7.js');
|
|
4123
4123
|
let pr;
|
|
4124
4124
|
if (opts.pr !== void 0) {
|
|
4125
4125
|
pr = parseTrackerNumber(opts.pr);
|
|
@@ -4154,7 +4154,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4154
4154
|
'\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. Add --cause, --detail and --suggestion, and\n--command, --error (first error line), --test or --symbol when there is one.\n\nEvery finding joins a factory-level problem. When one of its keys matches a\nknown problem it joins that problem. Otherwise nothing is stored: the command\nprints the closest problems and exits with code 3. Run it again with\n--problem <id> --link-reason <why> (repeat --problem for each problem the\nfinding reports), or with --new if none of them is the same problem.\nWithout --started-at and --ended-at it lists your recent session events with\nids and times; name the event where you hit the problem and the one where\nyou got past it to record the time it cost.\n--item names the work item; without it, inside a recorded session, the\nitem that session was launched for is used automatically.\n'
|
|
4155
4155
|
).action(async (opts) => {
|
|
4156
4156
|
warnIfApiKeyFlag(opts);
|
|
4157
|
-
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-
|
|
4157
|
+
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-P4RKBPBB.js');
|
|
4158
4158
|
try {
|
|
4159
4159
|
refuseRemovedFindingFlags(opts);
|
|
4160
4160
|
const result = await runEmitFinding({
|
|
@@ -4205,7 +4205,7 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4205
4205
|
"\n outerlayer emit findings review.json --item 412\n\nRecords a whole batch at once \u2014 a FindingBatch JSON file (schemaVersion 3,\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.\nFindings that need a choice between candidate problems are listed and not\nstored; the rest are stored, and the exit code is 3.\n--item names the work item; without it, inside a recorded session, the item\nthat session was launched for is used automatically.\n"
|
|
4206
4206
|
).action(async (file, opts) => {
|
|
4207
4207
|
warnIfApiKeyFlag(opts);
|
|
4208
|
-
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-
|
|
4208
|
+
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-P4RKBPBB.js');
|
|
4209
4209
|
try {
|
|
4210
4210
|
const result = await runEmitFindings({
|
|
4211
4211
|
file,
|
|
@@ -4226,10 +4226,26 @@ locally so it never uploads. One correction can retire several duplicates.
|
|
|
4226
4226
|
});
|
|
4227
4227
|
emitCmd.command("criteria <file>").description("Record a work item's acceptance criteria from a JSON file (- for stdin)").option("--item <number>", "work item to record on directly, by its number in this factory").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(
|
|
4228
4228
|
"after",
|
|
4229
|
-
|
|
4229
|
+
`
|
|
4230
|
+
outerlayer emit criteria criteria.json --item 412
|
|
4231
|
+
|
|
4232
|
+
Records the item's acceptance criteria as one list. The file is JSON:
|
|
4233
|
+
{ "criteria": [ { "id": "AC-1", "text": "Given ...", "proof": null },
|
|
4234
|
+
{ "id": "login.redirect", "text": "...", "proof": "screenshot" } ] }
|
|
4235
|
+
An id is 1-64 characters of A-Z a-z 0-9 . _ : - and is the id evidence is bound to with
|
|
4236
|
+
\`emit artifact --for\`. proof is video, screenshot, report, log, test, file or null (any bound
|
|
4237
|
+
artifact proves it). The list holds 1 to 200 criteria, each text at most 2,000
|
|
4238
|
+
characters, and no id twice. The list is validated before anything is sent.
|
|
4239
|
+
An optional top-level "drafted": true marks a list the build drafted from the issue's
|
|
4240
|
+
description. Only a list an agent records keeps the mark; a person's list never does.
|
|
4241
|
+
Once an item has a list, only a person can replace it: run the command outside an
|
|
4242
|
+
agent session, with your own login. A key bound to no member cannot replace it either.
|
|
4243
|
+
--item names the work item; without it, inside a recorded session, the item that
|
|
4244
|
+
session was launched for is used automatically.
|
|
4245
|
+
`
|
|
4230
4246
|
).action(async (file, opts) => {
|
|
4231
4247
|
warnIfApiKeyFlag(opts);
|
|
4232
|
-
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-
|
|
4248
|
+
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-EYUXME26.js');
|
|
4233
4249
|
try {
|
|
4234
4250
|
const result = await runEmitCriteria({
|
|
4235
4251
|
file,
|
|
@@ -4256,7 +4272,7 @@ function registerWorkCommands(program2) {
|
|
|
4256
4272
|
"\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"
|
|
4257
4273
|
).action(async (opts) => {
|
|
4258
4274
|
warnIfApiKeyFlag(opts);
|
|
4259
|
-
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-
|
|
4275
|
+
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4260
4276
|
try {
|
|
4261
4277
|
await runWorkBuild(opts);
|
|
4262
4278
|
} catch (err) {
|
|
@@ -4272,7 +4288,7 @@ function registerWorkCommands(program2) {
|
|
|
4272
4288
|
"\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"
|
|
4273
4289
|
).action(async (number, opts) => {
|
|
4274
4290
|
warnIfApiKeyFlag(opts);
|
|
4275
|
-
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-
|
|
4291
|
+
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4276
4292
|
try {
|
|
4277
4293
|
await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false, logFailures: opts.logFailures === true });
|
|
4278
4294
|
} catch (err) {
|
|
@@ -4297,8 +4313,8 @@ most one action flag may be given.
|
|
|
4297
4313
|
`
|
|
4298
4314
|
).action(async (opts) => {
|
|
4299
4315
|
warnIfApiKeyFlag(opts);
|
|
4300
|
-
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-
|
|
4301
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4316
|
+
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-FI2TMAYQ.js');
|
|
4317
|
+
const { WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4302
4318
|
try {
|
|
4303
4319
|
await runWorkComment(opts);
|
|
4304
4320
|
} catch (err) {
|
|
@@ -4314,8 +4330,8 @@ most one action flag may be given.
|
|
|
4314
4330
|
"\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"
|
|
4315
4331
|
).action(async (opts) => {
|
|
4316
4332
|
warnIfApiKeyFlag(opts);
|
|
4317
|
-
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-
|
|
4318
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4333
|
+
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-FI2TMAYQ.js');
|
|
4334
|
+
const { WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4319
4335
|
try {
|
|
4320
4336
|
await runWorkThreads(opts);
|
|
4321
4337
|
} catch (err) {
|
|
@@ -4337,7 +4353,7 @@ live addition remains on it.
|
|
|
4337
4353
|
`
|
|
4338
4354
|
).action(async (opts) => {
|
|
4339
4355
|
warnIfApiKeyFlag(opts);
|
|
4340
|
-
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-
|
|
4356
|
+
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4341
4357
|
try {
|
|
4342
4358
|
await runWorkRemove(opts);
|
|
4343
4359
|
} catch (err) {
|
|
@@ -4350,7 +4366,7 @@ live addition remains on it.
|
|
|
4350
4366
|
});
|
|
4351
4367
|
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) => {
|
|
4352
4368
|
warnIfApiKeyFlag(opts);
|
|
4353
|
-
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-
|
|
4369
|
+
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4354
4370
|
try {
|
|
4355
4371
|
await runWorkStatus(opts);
|
|
4356
4372
|
} catch (err) {
|
|
@@ -4363,7 +4379,7 @@ live addition remains on it.
|
|
|
4363
4379
|
});
|
|
4364
4380
|
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 a host can start: a build request, no open PR, 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) => {
|
|
4365
4381
|
warnIfApiKeyFlag(opts);
|
|
4366
|
-
const { runWorkList, WorkCommandError } = await import('./work-cmd-
|
|
4382
|
+
const { runWorkList, WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4367
4383
|
try {
|
|
4368
4384
|
await runWorkList(opts);
|
|
4369
4385
|
} catch (err) {
|
|
@@ -4379,7 +4395,7 @@ live addition remains on it.
|
|
|
4379
4395
|
"\n outerlayer work claim --item 42 --kind implement\n\nRecords a lease held by the API key that sends it. A live lease held\nby a different key is refused; claiming again with the same key extends\nit. --host is a label only.\n"
|
|
4380
4396
|
).action(async (opts) => {
|
|
4381
4397
|
warnIfApiKeyFlag(opts);
|
|
4382
|
-
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-
|
|
4398
|
+
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-CWGYEIJE.js');
|
|
4383
4399
|
try {
|
|
4384
4400
|
await runWorkClaim(opts);
|
|
4385
4401
|
} catch (err) {
|
|
@@ -4395,7 +4411,7 @@ live addition remains on it.
|
|
|
4395
4411
|
"\n outerlayer work renew --item 42\n\nExtends the live lease this API key holds. Refused with a 410 if the\nlease has expired, or a 403 if a different key holds it.\n"
|
|
4396
4412
|
).action(async (opts) => {
|
|
4397
4413
|
warnIfApiKeyFlag(opts);
|
|
4398
|
-
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-
|
|
4414
|
+
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-CWGYEIJE.js');
|
|
4399
4415
|
try {
|
|
4400
4416
|
await runWorkRenew(opts);
|
|
4401
4417
|
} catch (err) {
|
|
@@ -4414,7 +4430,7 @@ live addition remains on it.
|
|
|
4414
4430
|
"\n outerlayer work release --item 42 --outcome ok\n outerlayer work release --item 42\n\nMarks the lease this API key holds released, optionally with an\noutcome. A lease held by a different key is refused. Releasing an\nalready-released lease is a no-op that returns the recorded release\ntime and outcome.\n\nRun inside a session with no --host, it releases that session's own\nlease instead, so the item's review opens without ending the\nsession. It never releases another session's lease. --outcome\napplies to a host's lease only. A later tool call in the session\ntakes the lease again.\n"
|
|
4415
4431
|
).action(async (opts) => {
|
|
4416
4432
|
warnIfApiKeyFlag(opts);
|
|
4417
|
-
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-
|
|
4433
|
+
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-CWGYEIJE.js');
|
|
4418
4434
|
try {
|
|
4419
4435
|
await runWorkRelease(opts);
|
|
4420
4436
|
} catch (err) {
|
|
@@ -4430,7 +4446,7 @@ live addition remains on it.
|
|
|
4430
4446
|
"\n outerlayer work pr 481\n outerlayer work pr 481 --withdraw --item 250\n\nRun inside a session already on a work item. Records that pull\nrequest 481 in the checkout's repository belongs to the item named by\nOUTERLAYER_WORK, or refuses when the session is not on it. The same\nfact a `pr-link` in the session's own transcript records on sync.\nIdempotent: declaring the same pull request twice is a no-op.\n\n--withdraw removes one item's declaration of the pull request. It\nneeds your own login; an agent session or a factory key is refused.\n"
|
|
4431
4447
|
).action(async (number, opts) => {
|
|
4432
4448
|
warnIfApiKeyFlag(opts);
|
|
4433
|
-
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-
|
|
4449
|
+
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-Y5TDMQ4O.js');
|
|
4434
4450
|
try {
|
|
4435
4451
|
await runWorkPr({ ...opts, number });
|
|
4436
4452
|
} catch (err) {
|
|
@@ -4446,8 +4462,8 @@ live addition remains on it.
|
|
|
4446
4462
|
'\n outerlayer work open-pr --title "Add the thing" --body-file pr.md\n outerlayer work open-pr --repository acme/web --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'
|
|
4447
4463
|
).action(async (opts) => {
|
|
4448
4464
|
warnIfApiKeyFlag(opts);
|
|
4449
|
-
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-
|
|
4450
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4465
|
+
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-OVHJ5I5H.js');
|
|
4466
|
+
const { WorkCommandError } = await import('./work-cmd-X7NMJDFL.js');
|
|
4451
4467
|
try {
|
|
4452
4468
|
await runWorkOpenPr(opts);
|
|
4453
4469
|
} catch (err) {
|
|
@@ -4463,8 +4479,8 @@ function registerRunnerCommands(program2) {
|
|
|
4463
4479
|
const runnerCmd = program2.command("runner").description("Take work from the implement and amend queues on this machine");
|
|
4464
4480
|
const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
|
|
4465
4481
|
runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
|
|
4466
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4467
|
-
const { start, RunnerStartError } = await import('./loop-
|
|
4482
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
|
|
4483
|
+
const { start, RunnerStartError } = await import('./loop-XOAE6ZIY.js');
|
|
4468
4484
|
const { RunnerAlreadyRunningError } = await import('./pidfile-UZRH774M.js');
|
|
4469
4485
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4470
4486
|
try {
|
|
@@ -4479,8 +4495,8 @@ function registerRunnerCommands(program2) {
|
|
|
4479
4495
|
}
|
|
4480
4496
|
});
|
|
4481
4497
|
runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
|
|
4482
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4483
|
-
const { runRunnerCheck } = await import('./check-
|
|
4498
|
+
const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
|
|
4499
|
+
const { runRunnerCheck } = await import('./check-63IDCEEV.js');
|
|
4484
4500
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4485
4501
|
const result = await runRunnerCheck(configPath);
|
|
4486
4502
|
if (!result.ok) {
|
|
@@ -4496,7 +4512,7 @@ function registerRunnerCommands(program2) {
|
|
|
4496
4512
|
`);
|
|
4497
4513
|
});
|
|
4498
4514
|
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", "replace a unit or launcher file this command did not write").option("--allow-downgrade", "install this CLI even when it is older than the version the runner runs").option("--unit-name <name>", "with --service, the unit's name, to run a second runner beside the first").action(async (opts) => {
|
|
4499
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4515
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
|
|
4500
4516
|
const { runRunnerInstall, RunnerInstallError, launcherSummary, restartNote } = await import('./install-cmd-5HYMXLEW.js');
|
|
4501
4517
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4502
4518
|
if (opts.service !== true) {
|
|
@@ -4509,7 +4525,7 @@ function registerRunnerCommands(program2) {
|
|
|
4509
4525
|
}
|
|
4510
4526
|
try {
|
|
4511
4527
|
if (opts.service === true) {
|
|
4512
|
-
const { installServiceCommand } = await import('./command-
|
|
4528
|
+
const { installServiceCommand } = await import('./command-N7BAB4XJ.js');
|
|
4513
4529
|
const result2 = await installServiceCommand({
|
|
4514
4530
|
configPath,
|
|
4515
4531
|
print: opts.print,
|
|
@@ -4564,22 +4580,23 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
|
|
|
4564
4580
|
fail("pass --service: `outerlayer runner uninstall --service` removes the runner's service.");
|
|
4565
4581
|
return;
|
|
4566
4582
|
}
|
|
4567
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4568
|
-
const { uninstallServiceCommand } = await import('./command-
|
|
4583
|
+
const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
|
|
4584
|
+
const { uninstallServiceCommand } = await import('./command-N7BAB4XJ.js');
|
|
4569
4585
|
const result = await uninstallServiceCommand({ configPath: opts.config ?? defaultRunnerConfigPath(), unitName: opts.unitName, home: homeFromEnv() });
|
|
4570
4586
|
if (result.ok) for (const line of result.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
|
|
4571
4587
|
`);
|
|
4572
4588
|
else fail(result.lines.length > 0 ? result.lines.join("\n ") : "the service was not removed");
|
|
4573
4589
|
});
|
|
4574
|
-
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()).option("--vm-cli-package <path>", "with --vm, install this packed CLI tarball in the VM").option("--unit-name <name>", "the service unit's name, to run a second runner beside the first").option("--agent <name>", "write commands that start this agent (claude); its credential comes on stdin").addHelpText(
|
|
4590
|
+
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()).option("--vm-cli-package <path>", "with --vm, install this packed CLI tarball in the VM").option("--unit-name <name>", "the service unit's name, to run a second runner beside the first").option("--agent <name>", "write commands that start this agent (claude); its credential comes on stdin").option("--app-id <id>", "factory id to create the runner key on, when it comes from your login").option("--key-name <name>", "name of the runner key created from your login (default: machine name)").addHelpText(
|
|
4575
4591
|
"after",
|
|
4576
|
-
"\nWith --agent claude, the queue commands start Claude Code instead of the\nplaceholder, and Claude's credential is read from stdin: a token from\n`claude setup-token` (sk-ant-oat...) or an API key (sk-ant-api...). It is\nnever printed, and is stored in the runner.env beside the config with mode\n600. Other lines in the file are kept. With nothing piped, a credential\nalready in runner.env is used.\n\n printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude\n"
|
|
4592
|
+
"\nWith no apiKey in the config file, and a login saved by `outerlayer login`,\nrunner init creates the runner key itself, with the Runner preset, on the\nfactory --app-id names (or OUTERLAYER_APP_ID, or this repository's\nconnection). Your login needs factory_keys.insert on that factory.\n\nWith --agent claude, the queue commands start Claude Code instead of the\nplaceholder, and Claude's credential is read from stdin: a token from\n`claude setup-token` (sk-ant-oat...) or an API key (sk-ant-api...). It is\nnever printed, and is stored in the runner.env beside the config with mode\n600. Other lines in the file are kept. With nothing piped, a credential\nalready in runner.env is used.\n\n printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude\n"
|
|
4577
4593
|
).action(async (opts) => {
|
|
4578
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4579
|
-
const { runRunnerInit, RunnerInitError } = await import('./init-
|
|
4580
|
-
const {
|
|
4581
|
-
const {
|
|
4582
|
-
const {
|
|
4594
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-N3C6DFQA.js');
|
|
4595
|
+
const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-2LWVS4AH.js');
|
|
4596
|
+
const { createRunnerKey, runnerKeyLogin } = await import('./runner-key-TDTLNAKJ.js');
|
|
4597
|
+
const { detectMachine } = await import('./machine-G6PY2J2J.js');
|
|
4598
|
+
const { chooseVm, runVmInit, VmInitError } = await import('./init-ZL7ORPTF.js');
|
|
4599
|
+
const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-XTC53CHN.js');
|
|
4583
4600
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4584
4601
|
if (opts.agent !== void 0 && !isAgentName(opts.agent)) {
|
|
4585
4602
|
fail(`--agent ${opts.agent}: runner init writes commands for ${Object.keys(AGENT_COMMANDS).join(", ")}. For another agent, leave --agent out and edit runner.commands.`);
|
|
@@ -4593,7 +4610,7 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
|
|
|
4593
4610
|
try {
|
|
4594
4611
|
let credential;
|
|
4595
4612
|
if (agent !== void 0) {
|
|
4596
|
-
const { readPipedKey } = await import('./login-browser-
|
|
4613
|
+
const { readPipedKey } = await import('./login-browser-QZCS3WW6.js');
|
|
4597
4614
|
credential = credentialFromStdin(
|
|
4598
4615
|
await readPipedKey(process.stdin, {
|
|
4599
4616
|
onWaiting: () => process.stderr.write(`runner init is waiting for Claude's credential on stdin; close stdin to use the one already in runner.env
|
|
@@ -4603,6 +4620,10 @@ To keep it running, run ${C.yellow}outerlayer runner install --service${C.reset}
|
|
|
4603
4620
|
}
|
|
4604
4621
|
const machine = detectMachine();
|
|
4605
4622
|
if (opts.configStdin === true) {
|
|
4623
|
+
if (opts.appId !== void 0 || opts.keyName !== void 0) {
|
|
4624
|
+
fail("the VM-side hand-off carries its runner key in its config on stdin; pass no --app-id or --key-name with it.");
|
|
4625
|
+
return;
|
|
4626
|
+
}
|
|
4606
4627
|
const chunks = [];
|
|
4607
4628
|
for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
|
|
4608
4629
|
const result2 = runRunnerInit(configPath, { machine, configFromStdin: Buffer.concat(chunks).toString("utf8"), requireContainer: true });
|
|
@@ -4615,6 +4636,14 @@ hooks: ${result2.hooks}
|
|
|
4615
4636
|
`);
|
|
4616
4637
|
return;
|
|
4617
4638
|
}
|
|
4639
|
+
const login = runnerKeyLogin(configPath, { appId: opts.appId });
|
|
4640
|
+
if (login === void 0 && opts.keyName !== void 0) {
|
|
4641
|
+
fail(
|
|
4642
|
+
`--key-name names the runner key runner init creates from your login, and it creates none here: ${configPath} already has an apiKey, or no login is saved. Run \`outerlayer login\` first, or leave --key-name out.`
|
|
4643
|
+
);
|
|
4644
|
+
return;
|
|
4645
|
+
}
|
|
4646
|
+
const makeKey = login === void 0 ? void 0 : () => createRunnerKey(login, { name: opts.keyName });
|
|
4618
4647
|
let declinedVm = opts.vm === false;
|
|
4619
4648
|
const useVm = await chooseVm({
|
|
4620
4649
|
platform: machine.platform,
|
|
@@ -4644,6 +4673,7 @@ hooks: ${result2.hooks}
|
|
|
4644
4673
|
cliPackage: opts.vmCliPackage,
|
|
4645
4674
|
agent,
|
|
4646
4675
|
credential,
|
|
4676
|
+
runnerKey: makeKey,
|
|
4647
4677
|
progress: (line) => process.stdout.write(`${line}
|
|
4648
4678
|
`)
|
|
4649
4679
|
});
|
|
@@ -4652,9 +4682,15 @@ hooks: ${result2.hooks}
|
|
|
4652
4682
|
return;
|
|
4653
4683
|
}
|
|
4654
4684
|
const allowProcess = opts.allowProcessBuilds === true || machine.platform === "darwin" && declinedVm;
|
|
4655
|
-
const
|
|
4685
|
+
const prepared = prepareRunnerInit(configPath, { machine, allowProcess, agent, credential, keyFromLogin: makeKey !== void 0 });
|
|
4686
|
+
const created = makeKey === void 0 ? void 0 : await makeKey();
|
|
4687
|
+
const result = writeRunnerInit(prepared, created);
|
|
4656
4688
|
const { ensureHostKey } = await import('./host-key-YMLXY6QB.js');
|
|
4657
4689
|
const hostKey = await ensureHostKey(configPath);
|
|
4690
|
+
if (created !== void 0) {
|
|
4691
|
+
process.stdout.write(`${C.green}\u2713${C.reset} created the runner key ${created.name} from your login, with the Runner preset, and saved it in ${result.configPath}
|
|
4692
|
+
`);
|
|
4693
|
+
}
|
|
4658
4694
|
process.stdout.write(`${C.green}\u2713${C.reset} wrote a runner block into ${result.configPath}
|
|
4659
4695
|
`);
|
|
4660
4696
|
if (agent !== void 0) process.stdout.write(`${C.green}\u2713${C.reset} commands: implement and amend start ${agent}
|
|
@@ -4709,7 +4745,7 @@ ${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
|
|
|
4709
4745
|
let serviceUp = false;
|
|
4710
4746
|
let restart;
|
|
4711
4747
|
if (installedLayout) {
|
|
4712
|
-
const { installServiceCommand } = await import('./command-
|
|
4748
|
+
const { installServiceCommand } = await import('./command-N7BAB4XJ.js');
|
|
4713
4749
|
const service = await installServiceCommand({
|
|
4714
4750
|
configPath,
|
|
4715
4751
|
entryPath: process.argv[1] ?? "",
|
|
@@ -4753,12 +4789,12 @@ Next:
|
|
|
4753
4789
|
"after",
|
|
4754
4790
|
"\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"
|
|
4755
4791
|
).action(async (opts) => {
|
|
4756
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4792
|
+
const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
|
|
4757
4793
|
const { buildRepositoryImage, RecipeError } = await import('./build-LELVCWHV.js');
|
|
4758
4794
|
const { currentCliBuild } = await import('./cli-build-K56DK4DS.js');
|
|
4759
|
-
const { createDockerHost } = await import('./docker-
|
|
4760
|
-
const { builderSpec } = await import('./builder-
|
|
4761
|
-
const { loadRunnerConfig } = await import('./config-
|
|
4795
|
+
const { createDockerHost } = await import('./docker-BZ55BMBJ.js');
|
|
4796
|
+
const { builderSpec } = await import('./builder-UUS4ORDH.js');
|
|
4797
|
+
const { loadRunnerConfig } = await import('./config-N3C6DFQA.js');
|
|
4762
4798
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4763
4799
|
const memory = (() => {
|
|
4764
4800
|
try {
|
|
@@ -4819,16 +4855,16 @@ Next:
|
|
|
4819
4855
|
}
|
|
4820
4856
|
});
|
|
4821
4857
|
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) => {
|
|
4822
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4823
|
-
const { requestStop } = await import('./loop-
|
|
4858
|
+
const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
|
|
4859
|
+
const { requestStop } = await import('./loop-XOAE6ZIY.js');
|
|
4824
4860
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4825
4861
|
await requestStop(configPath, Boolean(opts.now));
|
|
4826
4862
|
});
|
|
4827
4863
|
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) => {
|
|
4828
|
-
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-
|
|
4864
|
+
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-N3C6DFQA.js');
|
|
4829
4865
|
const { jobsDir, runnerDir } = await import('./paths-OYKMVYJP.js');
|
|
4830
|
-
const { listJobFiles, runnerProcessState } = await import('./loop-
|
|
4831
|
-
const { renderStatus } = await import('./status-
|
|
4866
|
+
const { listJobFiles, runnerProcessState } = await import('./loop-XOAE6ZIY.js');
|
|
4867
|
+
const { renderStatus } = await import('./status-MRTPG34B.js');
|
|
4832
4868
|
const { readHousekeepingRecord } = await import('./record-C43U4PKS.js');
|
|
4833
4869
|
const path2 = await import('path');
|
|
4834
4870
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
@@ -4848,7 +4884,7 @@ Next:
|
|
|
4848
4884
|
const service = await (async () => {
|
|
4849
4885
|
if (process.platform !== "linux" || !existsSync("/run/systemd/system")) return void 0;
|
|
4850
4886
|
const { inspectService, realInspectProbes } = await import('./inspect-6UYAAXH7.js');
|
|
4851
|
-
const { DEFAULT_UNIT_NAME } = await import('./install-
|
|
4887
|
+
const { DEFAULT_UNIT_NAME } = await import('./install-HDBIPHTX.js');
|
|
4852
4888
|
const facts = inspectService(DEFAULT_UNIT_NAME, path2.dirname(configPath), realInspectProbes());
|
|
4853
4889
|
return facts === void 0 ? void 0 : { unit: facts.unit, running: facts.mainPid !== void 0, delegated: facts.delegate };
|
|
4854
4890
|
})();
|
|
@@ -4883,8 +4919,8 @@ Next:
|
|
|
4883
4919
|
);
|
|
4884
4920
|
});
|
|
4885
4921
|
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) => {
|
|
4886
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4887
|
-
const { listJobFiles } = await import('./loop-
|
|
4922
|
+
const { defaultRunnerConfigPath } = await import('./config-N3C6DFQA.js');
|
|
4923
|
+
const { listJobFiles } = await import('./loop-XOAE6ZIY.js');
|
|
4888
4924
|
const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-H55NWW4H.js');
|
|
4889
4925
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4890
4926
|
const item = parseTrackerNumber(itemArg);
|
|
@@ -5108,7 +5144,7 @@ function registerMcpCommands(program2) {
|
|
|
5108
5144
|
"after",
|
|
5109
5145
|
"\nThe API key is never a flag and never written to .mcp.json as a literal value.\n stdio (default): the client spawns `outerlayer mcp serve`, which reads the key\n from ~/.outerlayer/config.json (or OUTERLAYER_API_KEY) on every connect, so a\n rotated key is picked up without rewriting the entry.\n http: the entry carries the ${OUTERLAYER_API_KEY} placeholder, which the client\n resolves from the environment it was launched with.\n\n--command: use an absolute or ${HOME}-relative path when the CLI is not on PATH.\n--url: with stdio the endpoint resolves from OUTERLAYER_URL / the config file at\nconnect time; for self-host pass your gateway-node origin + /v1/mcp.\nSelf-host deployments also need --app-id: without a key service to resolve the\ncaller from the bearer token, the gateway answers 401 without that header.\n"
|
|
5110
5146
|
).action(async (opts) => {
|
|
5111
|
-
const { runMcpInstall, handleMcpInstallError, McpInstallError } = await import('./mcp-install-cmd-
|
|
5147
|
+
const { runMcpInstall, handleMcpInstallError, McpInstallError } = await import('./mcp-install-cmd-VXVIH7PH.js');
|
|
5112
5148
|
try {
|
|
5113
5149
|
if (opts.transport !== void 0 && opts.transport !== "stdio" && opts.transport !== "http") {
|
|
5114
5150
|
throw new McpInstallError(`--transport must be "stdio" or "http", got "${opts.transport}"`);
|
|
@@ -5141,7 +5177,7 @@ function registerMcpCommands(program2) {
|
|
|
5141
5177
|
function registerImportCommands(program2) {
|
|
5142
5178
|
const importCmd = program2.command("import").description("Import an existing config format into .outerlayer/");
|
|
5143
5179
|
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) => {
|
|
5144
|
-
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-
|
|
5180
|
+
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-IXR7YK47.js');
|
|
5145
5181
|
try {
|
|
5146
5182
|
const result = runImportRuler({ cwd: opts.dir, json: opts.json });
|
|
5147
5183
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -5157,7 +5193,7 @@ function registerImportCommands(program2) {
|
|
|
5157
5193
|
"after",
|
|
5158
5194
|
"\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"
|
|
5159
5195
|
).action(async (opts) => {
|
|
5160
|
-
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-
|
|
5196
|
+
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-2BKM5I2N.js');
|
|
5161
5197
|
try {
|
|
5162
5198
|
runImportCapture({ cwd: opts.dir, json: opts.json });
|
|
5163
5199
|
} catch (err) {
|
|
@@ -5200,7 +5236,7 @@ function registerContextCommands(program2) {
|
|
|
5200
5236
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
5201
5237
|
});
|
|
5202
5238
|
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) => {
|
|
5203
|
-
const { runContextAdopt } = await import('./context-adopt-
|
|
5239
|
+
const { runContextAdopt } = await import('./context-adopt-B3PWGFHL.js');
|
|
5204
5240
|
const { exitCode, stdout } = runContextAdopt(stagedDir, process.cwd());
|
|
5205
5241
|
process.stdout.write(stdout);
|
|
5206
5242
|
process.exitCode = exitCode;
|
|
@@ -5209,7 +5245,7 @@ function registerContextCommands(program2) {
|
|
|
5209
5245
|
"after",
|
|
5210
5246
|
"\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"
|
|
5211
5247
|
).action(async (opts) => {
|
|
5212
|
-
const { materializeContext } = await import('./context-materialize-
|
|
5248
|
+
const { materializeContext } = await import('./context-materialize-7S6NLLRO.js');
|
|
5213
5249
|
const result = await materializeContext({ cwd: process.cwd(), sessionId: `manual-${Date.now()}` });
|
|
5214
5250
|
const output = formatContextMaterializeOutput(result);
|
|
5215
5251
|
if (output.exitCode !== void 0) process.exitCode = output.exitCode;
|