@outerlayer/cli 0.18.0 → 0.19.1
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 +33 -0
- package/README.md +21 -2
- package/dist/{agent-setup-RBTEACYU.js → agent-setup-AM42SA2D.js} +15 -16
- package/dist/{artifact-link-cmd-AVM2EKTV.js → artifact-link-cmd-OWRI5AJX.js} +2 -2
- package/dist/build-info.json +1 -1
- package/dist/{builder-DUI2ZH2H.js → builder-C4QNTYMS.js} +3 -3
- package/dist/{check-5C4YDZYV.js → check-W2JGXN3B.js} +44 -43
- package/dist/{chunk-S26M3YBJ.js → chunk-3UZTIRLF.js} +1 -1
- package/dist/{chunk-Y5MXET4M.js → chunk-3ZR7Y23Y.js} +11 -10
- package/dist/{chunk-47TTLEDX.js → chunk-5VML45HH.js} +35 -13
- package/dist/{chunk-F4XSVQJ4.js → chunk-6X4SQ5MY.js} +2 -2
- package/dist/{chunk-T4Y6SCG3.js → chunk-7UWVLZXD.js} +2 -2
- package/dist/{chunk-N3CUDFCW.js → chunk-7VUK5RFS.js} +15 -2
- package/dist/{chunk-SWCTGCSC.js → chunk-7YP7T6GV.js} +1 -1
- package/dist/{chunk-3OFZM4X6.js → chunk-B6SCN5NY.js} +151 -20
- package/dist/{chunk-KDVIU23F.js → chunk-BWSUPRDK.js} +1 -1
- package/dist/{chunk-S76AYB4M.js → chunk-CG36IONK.js} +5 -5
- package/dist/{chunk-RAZTWYZN.js → chunk-CGGPS7SI.js} +7 -8
- package/dist/chunk-CJJDJ7AT.js +56 -0
- package/dist/{chunk-W5VPCONO.js → chunk-EAEELQVQ.js} +33 -227
- package/dist/{chunk-QQM2UJ6T.js → chunk-F2KXHIFI.js} +182 -28
- package/dist/{chunk-KK4VBOH6.js → chunk-FBTGMSQF.js} +10 -11
- package/dist/{chunk-MQJSXHV7.js → chunk-G3IJ3N6F.js} +5 -3
- package/dist/{chunk-FUB7LRUE.js → chunk-GEMQLBMW.js} +5 -5
- package/dist/{chunk-Y5GE76XC.js → chunk-HOKXGFDR.js} +33 -81
- package/dist/{chunk-IP7BIBXJ.js → chunk-IF2OSI5T.js} +35 -1
- package/dist/{chunk-UYOYTKE2.js → chunk-JHGEBPLE.js} +3 -3
- package/dist/chunk-KYS3TQAG.js +296 -0
- package/dist/chunk-LLM3I5YU.js +89 -0
- package/dist/{chunk-B3UKB46N.js → chunk-LRG3ZMZD.js} +4 -5
- package/dist/{chunk-NL4XPC7W.js → chunk-LW7G5TJB.js} +1 -1
- package/dist/{chunk-MNTSH4CL.js → chunk-NNLA7LLQ.js} +1 -1
- package/dist/{chunk-GOBOJMOJ.js → chunk-PIZRPNKR.js} +4 -4
- package/dist/{chunk-ULSIJGLS.js → chunk-PSN33ERW.js} +56 -14
- package/dist/{chunk-WGAUY5LE.js → chunk-QEFKA2QD.js} +1 -1
- package/dist/{chunk-BMYGAGBJ.js → chunk-QNLX477Q.js} +155 -23
- package/dist/{chunk-JF42URPU.js → chunk-R22NZSGA.js} +33 -9
- package/dist/chunk-TUSYOL2O.js +113 -0
- package/dist/{chunk-ESC6UR76.js → chunk-TWF3RICI.js} +6 -6
- package/dist/{chunk-L2USZT6T.js → chunk-VMJPFQNE.js} +1 -1
- package/dist/{chunk-X5N6KC6V.js → chunk-WFSUUUAN.js} +2 -3
- package/dist/{chunk-6CHIYEZZ.js → chunk-XZ4H4X5F.js} +9 -83
- package/dist/{chunk-LXAY4A2G.js → chunk-YQR6E6OV.js} +34 -49
- package/dist/chunk-Z7K3L4FC.js +174 -0
- package/dist/{claude-launcher-YVXI76NX.js → claude-launcher-J5M44PFS.js} +20 -7
- package/dist/{cli-C77H54BV.js → cli-EXX2R73G.js} +206 -230
- package/dist/{command-H5CILO4S.js → command-ZQNEPDS6.js} +29 -30
- package/dist/{config-FXDG4NPJ.js → config-CLSGABD5.js} +2 -2
- package/dist/{connect-cmd-ZW5FV3ZW.js → connect-cmd-UNYKGDAL.js} +7 -7
- package/dist/context-cleanup-CHEWNYU6.js +11 -0
- package/dist/control-plane-launch-34LNRJWR.js +216 -0
- package/dist/{dist-QTX4RSCL.js → dist-WO7NOJNG.js} +2 -2
- package/dist/{docker-RC3PRX3Q.js → docker-BFU3AQGY.js} +4 -4
- package/dist/{doctor-2NQQML6P.js → doctor-DHUM5DBB.js} +32 -33
- package/dist/{emit-artifact-cmd-7MP63KXU.js → emit-artifact-cmd-XBHM647X.js} +17 -17
- package/dist/{emit-cmd-PPN4QQF2.js → emit-cmd-W55AEBCA.js} +6 -6
- package/dist/{emit-criteria-cmd-3RXPDLNK.js → emit-criteria-cmd-CRTYEF7D.js} +11 -12
- package/dist/{emit-finding-cmd-OL7JB6H3.js → emit-finding-cmd-7JHVRYOP.js} +12 -13
- package/dist/{emit-result-cmd-UZVMOCF4.js → emit-result-cmd-5NZMLCJK.js} +17 -17
- package/dist/emit-step-cmd-347XNGPQ.js +26 -0
- package/dist/{governing-source-BUU4IABS.js → governing-source-HAA4OW57.js} +21 -22
- package/dist/{hook-fast-W5MKHMJT.js → hook-fast-RL5E5OXE.js} +3 -3
- package/dist/{import-capture-cmd-ZO6KGHI2.js → import-capture-cmd-TK4XY7RD.js} +4 -4
- package/dist/{import-ruler-cmd-KJMWL5V6.js → import-ruler-cmd-T6LLO6Q7.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/{init-WNXXYMO7.js → init-V6FOMD2V.js} +30 -31
- package/dist/{init-VWXIZEAN.js → init-XG47KCI4.js} +30 -31
- package/dist/{init-cmd-WS6TIRYT.js → init-cmd-Z4O4PPLZ.js} +70 -27
- package/dist/{init-update-E3J6TVIN.js → init-update-7DVAKWW3.js} +21 -22
- package/dist/{install-CBWIEF3R.js → install-4SEFIIW2.js} +3 -3
- package/dist/{login-browser-O63QZN7D.js → login-browser-DX35MARZ.js} +2 -2
- package/dist/{loop-UGI2BJOT.js → loop-TPUYUMSY.js} +44 -43
- package/dist/{machine-JOW4RNZ7.js → machine-TRHBT5NE.js} +26 -27
- package/dist/{mcp-serve-cmd-DOTY5FKY.js → mcp-serve-cmd-N3UTY6EE.js} +5 -5
- package/dist/{runner-env-4NB2GA7O.js → runner-env-FRZFFHDF.js} +4 -4
- package/dist/{runner-key-TC3NFWFV.js → runner-key-5FOWCW7J.js} +30 -31
- package/dist/{session-sender-NNVPSPY7.js → session-sender-U2BBUWNO.js} +19 -15
- package/dist/shell-function-NRD4KVUK.js +6 -0
- package/dist/{spec-cmd-OWVTBB4J.js → spec-cmd-FVLJOFGC.js} +12 -13
- package/dist/{starter-pack-OPWUDOWX.js → starter-pack-6LQVLBIA.js} +5 -5
- package/dist/{status-TKCLLKFG.js → status-BINH7MBG.js} +33 -32
- package/dist/{sync-cmd-Q6VYNPWG.js → sync-cmd-VXOUFS4I.js} +18 -14
- package/dist/{watch-ARAGADTF.js → watch-OH645CV2.js} +18 -14
- package/dist/{work-claim-cmd-34FERLYX.js → work-claim-cmd-ZRPSHMPT.js} +16 -17
- package/dist/{work-cmd-7S5B2H2P.js → work-cmd-5I3J2XQQ.js} +12 -13
- package/dist/{work-comment-cmd-SZJSPM5S.js → work-comment-cmd-UCCPWUSR.js} +12 -13
- package/dist/work-logs-cmd-7352CJPG.js +60 -0
- package/dist/{work-open-pr-cmd-RPXKCBWS.js → work-open-pr-cmd-LSH4VHJM.js} +13 -14
- package/dist/{work-pr-cmd-5LGANL32.js → work-pr-cmd-H4OQR26N.js} +12 -13
- package/package.json +2 -2
- package/skill-pack/maintained/outerlayer-cli/SKILL.md +9 -2
- package/skill-pack/maintained/outerlayer-cli/references/find-out-why-a-build-ended.md +76 -0
- package/skill-pack/shipped.json +1 -0
- package/skill-pack/template/build/references/release.md +3 -1
- package/dist/chunk-WBT5X3NH.js +0 -40
- package/dist/chunk-XCCLFVXM.js +0 -401
- package/dist/context-adopt-O5OFXMKI.js +0 -109
- package/dist/context-materialize-Y5IJ4MQT.js +0 -23
- package/dist/{chunk-NACDBXUG.js → chunk-BM63HB2M.js} +1 -1
- package/dist/{chunk-ZRL6HKBY.js → chunk-FVMYKL6L.js} +1 -1
- package/dist/{chunk-52NC2FIU.js → chunk-NTRCK4NH.js} +1 -1
- package/dist/{chunk-XGP3VYOG.js → chunk-P53VEAOF.js} +1 -1
|
@@ -1,41 +1,40 @@
|
|
|
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-
|
|
5
|
-
import { verifiedTrackerNames, TRACKERS } from './chunk-
|
|
6
|
-
import './chunk-
|
|
7
|
-
import './chunk-
|
|
8
|
-
import './chunk-
|
|
9
|
-
import './chunk-
|
|
3
|
+
import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-HOKXGFDR.js';
|
|
4
|
+
import './chunk-TWF3RICI.js';
|
|
5
|
+
import { verifiedTrackerNames, TRACKERS } from './chunk-FBTGMSQF.js';
|
|
6
|
+
import './chunk-IF2OSI5T.js';
|
|
7
|
+
import './chunk-CG36IONK.js';
|
|
8
|
+
import './chunk-G3IJ3N6F.js';
|
|
9
|
+
import './chunk-BM63HB2M.js';
|
|
10
|
+
import { hookFiredMarkerPath, installedCliDistDir } from './chunk-PSN33ERW.js';
|
|
10
11
|
import './chunk-DSF2FWAZ.js';
|
|
11
12
|
import './chunk-BKO6JEZI.js';
|
|
12
|
-
import './chunk-
|
|
13
|
+
import './chunk-QNLX477Q.js';
|
|
13
14
|
import './chunk-YVZJ6GKF.js';
|
|
14
|
-
import './chunk-
|
|
15
|
-
import './chunk-NACDBXUG.js';
|
|
15
|
+
import './chunk-6X4SQ5MY.js';
|
|
16
16
|
import './chunk-GOSFARMS.js';
|
|
17
|
-
import { C,
|
|
17
|
+
import { C, warnDeprecated, API_KEY_FLAG_DEPRECATION, NO_COLOR_FLAG, stripNoColor } from './chunk-ANPNT6PM.js';
|
|
18
18
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
19
19
|
import { settingsPath, readSettings, SettingsParseError, listHookCandidates, wrapHooks, writeSettings, unwrapHooks, REGISTERED_EVENTS, cliCommand, removeHooks, removeStatusline, cliBinResolvable, mergeHooks, repointWrappedHooks, AUTO_WRAP_EVENTS, mergeStatusline } from './chunk-5QRP3MVS.js';
|
|
20
|
-
import
|
|
21
|
-
import './chunk-
|
|
22
|
-
import './chunk-
|
|
23
|
-
import './chunk-
|
|
24
|
-
import './chunk-
|
|
25
|
-
import './chunk-
|
|
26
|
-
import './chunk-
|
|
20
|
+
import './chunk-7UWVLZXD.js';
|
|
21
|
+
import './chunk-FVMYKL6L.js';
|
|
22
|
+
import './chunk-NTRCK4NH.js';
|
|
23
|
+
import './chunk-ZJSNLVCE.js';
|
|
24
|
+
import { findGitDirs } from './chunk-BJ3KTMDH.js';
|
|
25
|
+
import './chunk-G2YNJIGF.js';
|
|
26
|
+
import './chunk-NNLA7LLQ.js';
|
|
27
27
|
import './chunk-EABW6AJQ.js';
|
|
28
|
+
import { cliInvocation, packageRunnerOf } from './chunk-CRB3POP4.js';
|
|
29
|
+
import { cloneIsGoverned } from './chunk-YQR6E6OV.js';
|
|
30
|
+
import { removeJournalHooks, removePreCommitGuardHook } from './chunk-TUSYOL2O.js';
|
|
31
|
+
import './chunk-WFSUUUAN.js';
|
|
32
|
+
import './chunk-7VUK5RFS.js';
|
|
33
|
+
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
28
34
|
import { resolveVersion } from './chunk-RA3O54FC.js';
|
|
29
35
|
import './chunk-M2ZWWTWZ.js';
|
|
30
36
|
import './chunk-N2PXGQRL.js';
|
|
31
37
|
import './chunk-BQXFBI7T.js';
|
|
32
|
-
import { hookFiredMarkerPath, installedCliDistDir } from './chunk-ULSIJGLS.js';
|
|
33
|
-
import './chunk-G2YNJIGF.js';
|
|
34
|
-
import { managedHookScripts, removeJournalHooks, installPreCommitGuardHook, removePreCommitGuardHook } from './chunk-XCCLFVXM.js';
|
|
35
|
-
import './chunk-ZJSNLVCE.js';
|
|
36
|
-
import './chunk-BJ3KTMDH.js';
|
|
37
|
-
import { cliInvocation, packageRunnerOf } from './chunk-CRB3POP4.js';
|
|
38
|
-
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
39
38
|
import './chunk-Z5GEFMRW.js';
|
|
40
39
|
import { EventEmitter } from 'events';
|
|
41
40
|
import childProcess, { execFileSync } from 'child_process';
|
|
@@ -3548,7 +3547,6 @@ function runInit(opts) {
|
|
|
3548
3547
|
recordStatusline(manifestHome, path2, statuslineWrappedCommand !== void 0 ? "wrapped" : "installed", statuslineWrappedCommand);
|
|
3549
3548
|
}
|
|
3550
3549
|
const gitHookRemoval = removeJournalHooks(opts.cwd ?? process.cwd());
|
|
3551
|
-
const guardHook = installPreCommitGuardHook(opts.cwd ?? process.cwd());
|
|
3552
3550
|
let gitignoreUpdated = false;
|
|
3553
3551
|
if (scope === "project" && opts.addGitignore) {
|
|
3554
3552
|
gitignoreUpdated = ensureGitignore(opts.cwd ?? process.cwd());
|
|
@@ -3560,7 +3558,6 @@ function runInit(opts) {
|
|
|
3560
3558
|
events: REGISTERED_EVENTS,
|
|
3561
3559
|
gitignoreUpdated,
|
|
3562
3560
|
...gitHookRemoval.removed ? { gitHookRemoved: true } : {},
|
|
3563
|
-
guardHook,
|
|
3564
3561
|
wrapped,
|
|
3565
3562
|
...statusline ? { statusline } : {},
|
|
3566
3563
|
...statuslineWrappedCommand ? { statuslineWrappedCommand } : {}
|
|
@@ -3578,8 +3575,12 @@ function tracksOwnOuterlayerDir(cwd) {
|
|
|
3578
3575
|
return false;
|
|
3579
3576
|
}
|
|
3580
3577
|
}
|
|
3578
|
+
function isGovernedCheckout(cwd) {
|
|
3579
|
+
const dirs = findGitDirs(cwd);
|
|
3580
|
+
return dirs !== void 0 && cloneIsGoverned(dirs.gitCommonDir);
|
|
3581
|
+
}
|
|
3581
3582
|
function ensureGitignore(cwd) {
|
|
3582
|
-
if (tracksOwnOuterlayerDir(cwd) ||
|
|
3583
|
+
if (tracksOwnOuterlayerDir(cwd) || isGovernedCheckout(cwd)) return false;
|
|
3583
3584
|
const gitignore = join(cwd, ".gitignore");
|
|
3584
3585
|
const entry = ".outerlayer/";
|
|
3585
3586
|
let contents = "";
|
|
@@ -3647,11 +3648,8 @@ function writeJson(value) {
|
|
|
3647
3648
|
function apiKeyOption() {
|
|
3648
3649
|
return new Option("--api-key <key>", `deprecated: use \`${cliInvocation()} login\` or OUTERLAYER_API_KEY`).hideHelp();
|
|
3649
3650
|
}
|
|
3650
|
-
function warnIfApiKeyFlag(opts) {
|
|
3651
|
-
if (opts.apiKey !== void 0) warnDeprecated(API_KEY_FLAG_DEPRECATION);
|
|
3652
|
-
}
|
|
3653
3651
|
async function installStarterPackInRepo() {
|
|
3654
|
-
const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-
|
|
3652
|
+
const { installStarterPack, formatStarterPackOutput } = await import('./starter-pack-6LQVLBIA.js');
|
|
3655
3653
|
const cwd = process.cwd();
|
|
3656
3654
|
let repoRoot = cwd;
|
|
3657
3655
|
try {
|
|
@@ -3743,39 +3741,6 @@ turn and at the end of the session, at most once every five minutes.
|
|
|
3743
3741
|
);
|
|
3744
3742
|
return lines.join("");
|
|
3745
3743
|
}
|
|
3746
|
-
function formatGuardInstallOutput(guard) {
|
|
3747
|
-
switch (guard.status) {
|
|
3748
|
-
case "installed":
|
|
3749
|
-
case "updated":
|
|
3750
|
-
case "unchanged":
|
|
3751
|
-
return { lines: [`${C.green}\u2713${C.reset} materialized-context commit guard ${guard.status} \u2192 ${guard.path}`] };
|
|
3752
|
-
case "skipped-foreign":
|
|
3753
|
-
if (guard.adopted) {
|
|
3754
|
-
return { lines: [`${C.green}\u2713${C.reset} materialized-context commit guard hand-adopted into ${guard.path} \u2014 left untouched.`] };
|
|
3755
|
-
}
|
|
3756
|
-
return {
|
|
3757
|
-
lines: [
|
|
3758
|
-
`${C.yellow}!${C.reset} a pre-commit hook we did not write already exists (${guard.path}) \u2014 left untouched.`,
|
|
3759
|
-
` Append the guard script yourself: ${C.yellow}${cliInvocation()} hooks install-git --print${C.reset}`,
|
|
3760
|
-
` Place it before any exit in the existing hook \u2014 code after an early exit never runs.`
|
|
3761
|
-
],
|
|
3762
|
-
exitCode: 1
|
|
3763
|
-
};
|
|
3764
|
-
case "skipped-custom-hooks-path":
|
|
3765
|
-
if (guard.adopted) {
|
|
3766
|
-
return { lines: [`${C.green}\u2713${C.reset} materialized-context commit guard hand-adopted at ${guard.path} (core.hooksPath) \u2014 left untouched.`] };
|
|
3767
|
-
}
|
|
3768
|
-
return {
|
|
3769
|
-
lines: [
|
|
3770
|
-
`${C.yellow}!${C.reset} this repo manages hooks in its working tree (core.hooksPath) \u2014 nothing written.`,
|
|
3771
|
-
` Add the script to your hook manager instead: ${C.yellow}${cliInvocation()} hooks install-git --print${C.reset}`
|
|
3772
|
-
],
|
|
3773
|
-
exitCode: 1
|
|
3774
|
-
};
|
|
3775
|
-
case "not-a-repo":
|
|
3776
|
-
return { lines: [], error: "not inside a git repository." };
|
|
3777
|
-
}
|
|
3778
|
-
}
|
|
3779
3744
|
async function installHooks(opts, resolvedBin, connected, starterTemplate, withNext = true) {
|
|
3780
3745
|
const scope = opts.project ? "project" : "user";
|
|
3781
3746
|
let cliBin;
|
|
@@ -3814,8 +3779,8 @@ ${starter.output}`),
|
|
|
3814
3779
|
}
|
|
3815
3780
|
}
|
|
3816
3781
|
async function realConnectDepsForCwd() {
|
|
3817
|
-
const { realConnectDeps } = await import('./connect-cmd-
|
|
3818
|
-
const { resolveRepoIdentity } = await import('./dist-
|
|
3782
|
+
const { realConnectDeps } = await import('./connect-cmd-UNYKGDAL.js');
|
|
3783
|
+
const { resolveRepoIdentity } = await import('./dist-WO7NOJNG.js');
|
|
3819
3784
|
return {
|
|
3820
3785
|
...realConnectDeps(),
|
|
3821
3786
|
home: homeFromEnv(),
|
|
@@ -3830,13 +3795,15 @@ function invokedCommandToken(argv) {
|
|
|
3830
3795
|
}
|
|
3831
3796
|
function buildProgram(argv = process.argv) {
|
|
3832
3797
|
const program2 = new Command();
|
|
3833
|
-
program2.name(cliInvocation()).description("OuterLayer \u2014 see what your coding agents actually do").enablePositionalOptions().version(resolveVersion()).
|
|
3834
|
-
|
|
3798
|
+
program2.name(cliInvocation()).description("OuterLayer \u2014 see what your coding agents actually do").enablePositionalOptions().version(resolveVersion()).hook("preAction", (_root, command) => {
|
|
3799
|
+
if (command.opts().apiKey !== void 0) warnDeprecated(API_KEY_FLAG_DEPRECATION);
|
|
3800
|
+
}).option(NO_COLOR_FLAG, "disable color (NO_COLOR=1 does the same)").addHelpText("after", SUPPORT_TEXT);
|
|
3801
|
+
program2.command("init").description("Connect this repository, install hooks and agent skills, run doctor").option("--user", "install into user settings [default]").option("--project", "install into project settings (./.claude/settings.json)").option("--org", "print a managed-settings.json snippet for MDM/GPO rollout").option("--remove", "uninstall OuterLayer hooks").option("--local", "install the hooks only: no connect step and no network call").option("--factory <org/factory>", `the factory to connect this repository to (see \`${cliInvocation()} connect\`)`).option("--gitignore", "also add .outerlayer/ to .gitignore (project scope)").option("--template <name>", "install the starter skills and a policy file (only: default)").option("--update", "update the files init wrote that you have not edited, and write missing ones").option("--dry-run", "with --update: print the plan and write nothing").option("--no-wrap-hooks", "leave PreToolUse/PostToolUse hooks unwrapped").option("--statusline", "install the status-line segment [default]").option("--no-statusline", "leave the statusLine slot untouched").option("--shell-function", "make plain claude run `outerlayer claude` (edits ~/.zshrc or ~/.bashrc)").option("--no-shell-function", "do not set up the shell function, and remove it if it is there").option("--json", "machine-readable JSON output").addHelpText(
|
|
3835
3802
|
"after",
|
|
3836
3803
|
`
|
|
3837
3804
|
In a repository, init runs four steps: connect the repository to a
|
|
3838
3805
|
factory (\`${cliInvocation()} connect\`), install the hooks, set up the coding agent,
|
|
3839
|
-
and run \`${cliInvocation()} doctor\`. It never signs in
|
|
3806
|
+
and run \`${cliInvocation()} doctor\`. It never signs in. With no
|
|
3840
3807
|
login it skips the connect step and says to run \`${cliInvocation()} login\`. With
|
|
3841
3808
|
--json it prints one document naming the outcome of each step: done,
|
|
3842
3809
|
skipped or failed. The exit code is 1 when a step failed.
|
|
@@ -3876,7 +3843,7 @@ states under Starter files.
|
|
|
3876
3843
|
`
|
|
3877
3844
|
).action(async (opts) => {
|
|
3878
3845
|
if (opts.update || opts.dryRun) {
|
|
3879
|
-
const { runInitUpdate, formatInitUpdate, updateFlagProblem } = await import('./init-update-
|
|
3846
|
+
const { runInitUpdate, formatInitUpdate, updateFlagProblem } = await import('./init-update-7DVAKWW3.js');
|
|
3880
3847
|
const problem = updateFlagProblem(opts);
|
|
3881
3848
|
if (problem !== void 0) {
|
|
3882
3849
|
fail(problem);
|
|
@@ -3890,7 +3857,7 @@ states under Starter files.
|
|
|
3890
3857
|
}
|
|
3891
3858
|
let starterTemplate;
|
|
3892
3859
|
if (opts.template !== void 0) {
|
|
3893
|
-
const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-
|
|
3860
|
+
const { assertKnownTemplate, StarterPackError } = await import('./starter-pack-6LQVLBIA.js');
|
|
3894
3861
|
try {
|
|
3895
3862
|
assertKnownTemplate(opts.template);
|
|
3896
3863
|
} catch (err) {
|
|
@@ -3917,13 +3884,20 @@ states under Starter files.
|
|
|
3917
3884
|
fail(outcome.text);
|
|
3918
3885
|
return;
|
|
3919
3886
|
}
|
|
3920
|
-
if (opts.
|
|
3921
|
-
|
|
3887
|
+
if (opts.remove) {
|
|
3888
|
+
const { removeShellFunction } = await import('./shell-function-NRD4KVUK.js');
|
|
3889
|
+
const changed = removeShellFunction({ home: homeFromEnv() });
|
|
3890
|
+
if (changed.length > 0 && !opts.json) process.stdout.write(`Removed the claude function from ${changed.join(", ")}.
|
|
3891
|
+
`);
|
|
3892
|
+
}
|
|
3893
|
+
const shell = !opts.remove && opts.shellFunction !== void 0 ? (await import('./init-cmd-Z4O4PPLZ.js')).applyShellFunctionFlag(opts.shellFunction, { home: homeFromEnv(), shellPath: process.env.SHELL }) : void 0;
|
|
3894
|
+
if (opts.json) writeJson(shell === void 0 ? outcome.result : { ...outcome.result, shellFunction: { outcome: shell.outcome, reason: shell.reason } });
|
|
3895
|
+
else process.stdout.write(outcome.text + (shell?.text ?? ""));
|
|
3922
3896
|
return;
|
|
3923
3897
|
}
|
|
3924
|
-
const { runInitCommand } = await import('./init-cmd-
|
|
3898
|
+
const { runInitCommand } = await import('./init-cmd-Z4O4PPLZ.js');
|
|
3925
3899
|
const code = await runInitCommand(
|
|
3926
|
-
{ json: opts.json, factory: opts.factory },
|
|
3900
|
+
{ json: opts.json, factory: opts.factory, shellFunction: opts.shellFunction },
|
|
3927
3901
|
{
|
|
3928
3902
|
connect: await realConnectDepsForCwd(),
|
|
3929
3903
|
stdout: process.stdout,
|
|
@@ -3933,10 +3907,26 @@ states under Starter files.
|
|
|
3933
3907
|
return { ok, text, detail };
|
|
3934
3908
|
},
|
|
3935
3909
|
runAgentSetup: async () => {
|
|
3936
|
-
const { runAgentSetup } = await import('./agent-setup-
|
|
3910
|
+
const { runAgentSetup } = await import('./agent-setup-AM42SA2D.js');
|
|
3937
3911
|
return runAgentSetup({ cwd: process.cwd() });
|
|
3938
3912
|
},
|
|
3939
|
-
runDoctorChecks: gatherDoctorChecks
|
|
3913
|
+
runDoctorChecks: gatherDoctorChecks,
|
|
3914
|
+
shell: {
|
|
3915
|
+
home: homeFromEnv(),
|
|
3916
|
+
shellPath: process.env.SHELL,
|
|
3917
|
+
interactive: Boolean(process.stdin.isTTY && process.stderr.isTTY) && opts.json !== true,
|
|
3918
|
+
ask: async () => {
|
|
3919
|
+
const { promptOnTerminal } = await import('./connect-cmd-UNYKGDAL.js');
|
|
3920
|
+
const answer = await promptOnTerminal({
|
|
3921
|
+
message: `Should plain claude start Claude Code through ${cliInvocation()} claude? That is how a session in a governed repository gets its control plane. It adds one block to your zsh or bash startup file.`,
|
|
3922
|
+
options: [
|
|
3923
|
+
{ label: "Yes, add the block", value: "yes" },
|
|
3924
|
+
{ label: "No, I will run outerlayer claude myself", value: "no" }
|
|
3925
|
+
]
|
|
3926
|
+
});
|
|
3927
|
+
return answer === "yes";
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3940
3930
|
}
|
|
3941
3931
|
);
|
|
3942
3932
|
if (code !== 0) process.exitCode = code;
|
|
@@ -3965,7 +3955,7 @@ linked (true, false, or null when it could not be checked) and, when false,
|
|
|
3965
3955
|
linkUrl.
|
|
3966
3956
|
`
|
|
3967
3957
|
).action(async (opts) => {
|
|
3968
|
-
const { runConnectCommand } = await import('./connect-cmd-
|
|
3958
|
+
const { runConnectCommand } = await import('./connect-cmd-UNYKGDAL.js');
|
|
3969
3959
|
const code = await runConnectCommand({ factory: opts.factory, json: opts.json }, await realConnectDepsForCwd(), {
|
|
3970
3960
|
stdout: process.stdout,
|
|
3971
3961
|
stderr: process.stderr
|
|
@@ -4004,7 +3994,7 @@ Every later command reads the saved file, so none of them needs a key on
|
|
|
4004
3994
|
its command line. A saved key is checked for real on the first \`sync\`.
|
|
4005
3995
|
`
|
|
4006
3996
|
).action(async (opts) => {
|
|
4007
|
-
const { runLoginCommand, realLoginDeps } = await import('./login-browser-
|
|
3997
|
+
const { runLoginCommand, realLoginDeps } = await import('./login-browser-DX35MARZ.js');
|
|
4008
3998
|
const code = await runLoginCommand(
|
|
4009
3999
|
{
|
|
4010
4000
|
browser: opts.browser !== false,
|
|
@@ -4036,15 +4026,14 @@ code is 1: revoke the token on /profile/security.
|
|
|
4036
4026
|
"after",
|
|
4037
4027
|
"\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"
|
|
4038
4028
|
).action(async (opts) => {
|
|
4039
|
-
warnIfApiKeyFlag(opts);
|
|
4040
4029
|
if (opts.link !== void 0) {
|
|
4041
|
-
const { lookupArtifactLink } = await import('./artifact-link-cmd-
|
|
4030
|
+
const { lookupArtifactLink } = await import('./artifact-link-cmd-OWRI5AJX.js');
|
|
4042
4031
|
const found = lookupArtifactLink(opts.link);
|
|
4043
4032
|
if (found.ok) process.stdout.write(found.url + "\n");
|
|
4044
4033
|
else fail(found.reason);
|
|
4045
4034
|
return;
|
|
4046
4035
|
}
|
|
4047
|
-
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-
|
|
4036
|
+
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-VXOUFS4I.js');
|
|
4048
4037
|
try {
|
|
4049
4038
|
const result = await runSync({
|
|
4050
4039
|
url: opts.url,
|
|
@@ -4075,7 +4064,7 @@ code is 1: revoke the token on /profile/security.
|
|
|
4075
4064
|
if (invokedCommandToken(argv) === "watch") {
|
|
4076
4065
|
warnDeprecated(`\`${cliInvocation()} watch\` is now \`${cliInvocation()} daemon\`; the old name will be removed in a future release.`);
|
|
4077
4066
|
}
|
|
4078
|
-
const { runWatch } = await import('./watch-
|
|
4067
|
+
const { runWatch } = await import('./watch-OH645CV2.js');
|
|
4079
4068
|
await runWatch({ once: opts.once });
|
|
4080
4069
|
});
|
|
4081
4070
|
program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
|
|
@@ -4084,7 +4073,7 @@ code is 1: revoke the token on /profile/security.
|
|
|
4084
4073
|
});
|
|
4085
4074
|
program2.command("hook-wrap", { hidden: true }).description("runs a hook wrapped by `hooks wrap`, recording exec evidence").option("--id <base64>", "the original hook command, base64-encoded").option("--capture-output", "tee stdout/stderr into a bounded tail").action(() => {
|
|
4086
4075
|
});
|
|
4087
|
-
program2.command("claude [args...]"
|
|
4076
|
+
program2.command("claude [args...]").description("start Claude Code with the repository's control plane attached").allowUnknownOption().helpOption(false).action(() => {
|
|
4088
4077
|
});
|
|
4089
4078
|
program2.command("broker-relay", { hidden: true }).description("relay a build's loopback connections to the runner's tunnel and destinations").requiredOption("--port <port>", "the loopback port to listen on").requiredOption("--socket <path>", "the runner's tunnel socket").option("--forward <port=socket>", "also relay a loopback port to a destination's socket; repeatable", (value, previous) => [...previous, value], []).action(async (opts) => {
|
|
4090
4079
|
const { startRelay } = await import('./relay-L76HDX72.js');
|
|
@@ -4131,7 +4120,7 @@ code is 1: revoke the token on /profile/security.
|
|
|
4131
4120
|
}
|
|
4132
4121
|
});
|
|
4133
4122
|
program2.command("session-sender", { hidden: true }).description("stream a runner build's sessions to its work item while the build runs").action(async () => {
|
|
4134
|
-
const { runSessionSender } = await import('./session-sender-
|
|
4123
|
+
const { runSessionSender } = await import('./session-sender-U2BBUWNO.js');
|
|
4135
4124
|
try {
|
|
4136
4125
|
await runSessionSender();
|
|
4137
4126
|
} catch (err) {
|
|
@@ -4167,7 +4156,7 @@ async function runCli(processArgv) {
|
|
|
4167
4156
|
await buildProgram(argv).parseAsync(argv);
|
|
4168
4157
|
}
|
|
4169
4158
|
async function compileContext(opts) {
|
|
4170
|
-
const { runEmit, EmitError } = await import('./emit-cmd-
|
|
4159
|
+
const { runEmit, EmitError } = await import('./emit-cmd-W55AEBCA.js');
|
|
4171
4160
|
try {
|
|
4172
4161
|
const result = runEmit({ cwd: opts.dir, check: opts.check, json: opts.json });
|
|
4173
4162
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -4204,7 +4193,8 @@ criterion's thread instead \u2014 see \`${cliInvocation()} work comment\`.
|
|
|
4204
4193
|
|
|
4205
4194
|
Subcommands: \`emit artifact <file>\` for screenshots, recordings, reports and
|
|
4206
4195
|
logs; \`emit finding\` / \`emit findings <file>\` to record a problem in the factory;
|
|
4207
|
-
\`emit criteria <file>\` to record a work item's acceptance criteria
|
|
4196
|
+
\`emit criteria <file>\` to record a work item's acceptance criteria;
|
|
4197
|
+
\`emit step <name>\` to report that you started a step.
|
|
4208
4198
|
Compiling .outerlayer/ moved to \`${cliInvocation()} context emit\`.
|
|
4209
4199
|
`
|
|
4210
4200
|
).action(async (name, opts) => {
|
|
@@ -4213,8 +4203,7 @@ Compiling .outerlayer/ moved to \`${cliInvocation()} context emit\`.
|
|
|
4213
4203
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
4214
4204
|
return;
|
|
4215
4205
|
}
|
|
4216
|
-
|
|
4217
|
-
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-UZVMOCF4.js');
|
|
4206
|
+
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-5NZMLCJK.js');
|
|
4218
4207
|
try {
|
|
4219
4208
|
const result = await runEmitResult({
|
|
4220
4209
|
name,
|
|
@@ -4264,8 +4253,7 @@ everywhere, bytes and deep link untouched; a still-queued one is cancelled
|
|
|
4264
4253
|
locally so it never uploads. One correction can retire several duplicates.
|
|
4265
4254
|
`
|
|
4266
4255
|
).action(async (file, opts) => {
|
|
4267
|
-
|
|
4268
|
-
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-7MP63KXU.js');
|
|
4256
|
+
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-XBHM647X.js');
|
|
4269
4257
|
let pr;
|
|
4270
4258
|
if (opts.pr !== void 0) {
|
|
4271
4259
|
pr = parseTrackerNumber(opts.pr);
|
|
@@ -4324,8 +4312,7 @@ recent events with their ids. --find <text> searches all of them.
|
|
|
4324
4312
|
item that session was launched for is used automatically.
|
|
4325
4313
|
`
|
|
4326
4314
|
).action(async (opts) => {
|
|
4327
|
-
|
|
4328
|
-
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-OL7JB6H3.js');
|
|
4315
|
+
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-7JHVRYOP.js');
|
|
4329
4316
|
try {
|
|
4330
4317
|
refuseRemovedFindingFlags(opts);
|
|
4331
4318
|
const result = await runEmitFinding({
|
|
@@ -4392,8 +4379,7 @@ the whole batch. "untimed": true records one with no time on purpose.
|
|
|
4392
4379
|
that session was launched for is used automatically.
|
|
4393
4380
|
`
|
|
4394
4381
|
).action(async (file, opts) => {
|
|
4395
|
-
|
|
4396
|
-
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-OL7JB6H3.js');
|
|
4382
|
+
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-7JHVRYOP.js');
|
|
4397
4383
|
try {
|
|
4398
4384
|
const result = await runEmitFindings({
|
|
4399
4385
|
file,
|
|
@@ -4412,6 +4398,40 @@ that session was launched for is used automatically.
|
|
|
4412
4398
|
throw err;
|
|
4413
4399
|
}
|
|
4414
4400
|
});
|
|
4401
|
+
emitCmd.command("step <name>").description("Report that you started a step; the work item's Activity tab shows it").option("--item <number>", "work item to report on, 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(
|
|
4402
|
+
"after",
|
|
4403
|
+
`
|
|
4404
|
+
${cliInvocation()} emit step "Review round 2"
|
|
4405
|
+
${cliInvocation()} emit step "Plan" --item 412
|
|
4406
|
+
|
|
4407
|
+
Run it when you start a step. The name is free text: 1 to 80 characters on one
|
|
4408
|
+
line. A step has a start and nothing else, so run it again for the next step.
|
|
4409
|
+
--item names the work item; without it, inside a recorded session, the item that
|
|
4410
|
+
session was launched for is used.
|
|
4411
|
+
|
|
4412
|
+
If the gateway cannot be reached, the step is queued with the time you ran the
|
|
4413
|
+
command, the command exits 0, and \`sync\` sends it later. If the gateway refuses
|
|
4414
|
+
the step, the command prints why and exits 1.
|
|
4415
|
+
`
|
|
4416
|
+
).action(async (name, opts) => {
|
|
4417
|
+
const { runEmitStep, EmitStepError } = await import('./emit-step-cmd-347XNGPQ.js');
|
|
4418
|
+
try {
|
|
4419
|
+
await runEmitStep({
|
|
4420
|
+
name,
|
|
4421
|
+
item: opts.item,
|
|
4422
|
+
json: opts.json,
|
|
4423
|
+
url: opts.url,
|
|
4424
|
+
apiKey: opts.apiKey,
|
|
4425
|
+
appId: opts.appId
|
|
4426
|
+
});
|
|
4427
|
+
} catch (err) {
|
|
4428
|
+
if (err instanceof EmitStepError) {
|
|
4429
|
+
fail(err.message);
|
|
4430
|
+
return;
|
|
4431
|
+
}
|
|
4432
|
+
throw err;
|
|
4433
|
+
}
|
|
4434
|
+
});
|
|
4415
4435
|
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(
|
|
4416
4436
|
"after",
|
|
4417
4437
|
`
|
|
@@ -4432,8 +4452,7 @@ agent session, with your own login. A key bound to no member cannot replace it e
|
|
|
4432
4452
|
session was launched for is used automatically.
|
|
4433
4453
|
`
|
|
4434
4454
|
).action(async (file, opts) => {
|
|
4435
|
-
|
|
4436
|
-
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-3RXPDLNK.js');
|
|
4455
|
+
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-CRTYEF7D.js');
|
|
4437
4456
|
try {
|
|
4438
4457
|
const result = await runEmitCriteria({
|
|
4439
4458
|
file,
|
|
@@ -4456,11 +4475,10 @@ session was launched for is used automatically.
|
|
|
4456
4475
|
function registerSpecCommands(program2) {
|
|
4457
4476
|
const specCmd = program2.command("spec").description("Find, file and edit the issue a spec lives in, in your factory's tracker");
|
|
4458
4477
|
const credentialOptions = (command) => command.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)");
|
|
4459
|
-
const run = async (
|
|
4460
|
-
|
|
4461
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4478
|
+
const run = async (action) => {
|
|
4479
|
+
const { WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4462
4480
|
try {
|
|
4463
|
-
await action(await import('./spec-cmd-
|
|
4481
|
+
await action(await import('./spec-cmd-FVLJOFGC.js'));
|
|
4464
4482
|
} catch (err) {
|
|
4465
4483
|
if (err instanceof WorkCommandError) {
|
|
4466
4484
|
fail(err.message);
|
|
@@ -4471,16 +4489,16 @@ function registerSpecCommands(program2) {
|
|
|
4471
4489
|
};
|
|
4472
4490
|
credentialOptions(
|
|
4473
4491
|
specCmd.command("target").description("Say where a spec would be filed, and whether this factory can file there").option("--tracker <name>", "one connected tracker, when the factory has more than one")
|
|
4474
|
-
).action((opts) => run(
|
|
4492
|
+
).action((opts) => run((spec) => spec.runSpecTarget(opts)));
|
|
4475
4493
|
credentialOptions(
|
|
4476
4494
|
specCmd.command("search").description("Find open and closed issues that match a query, before filing a duplicate").argument("<query>", "words from the title or body").option("--tracker <name>", "one connected tracker, when the factory has more than one")
|
|
4477
|
-
).action((query, opts) => run(
|
|
4495
|
+
).action((query, opts) => run((spec) => spec.runSpecSearch({ ...opts, query })));
|
|
4478
4496
|
credentialOptions(
|
|
4479
4497
|
specCmd.command("file").description("File a spec as an issue and print its key, URL and the command that builds it").requiredOption("--title <text>", "the issue title").option("--body-file <path>", "the spec as Markdown; - reads standard input").option("--repo <owner/name>", "the repository to file in (GitHub), or the one the work lands in").option("--tracker <name>", "the tracker, when the factory files in more than one").option("--scope <key>", "the Linear team or Jira project, when the connection covers several")
|
|
4480
|
-
).action((opts) => run(
|
|
4498
|
+
).action((opts) => run((spec) => spec.runSpecFile(opts)));
|
|
4481
4499
|
credentialOptions(
|
|
4482
4500
|
specCmd.command("edit").description("Replace the body of an issue that holds a spec").argument("<key>", "the issue key, such as acme/api#12 or ENG-142").option("--body-file <path>", "the new body as Markdown; - reads standard input").option("--updated-at <timestamp>", "the updatedAt you read; the edit is refused if the issue has changed since")
|
|
4483
|
-
).action((key, opts) => run(
|
|
4501
|
+
).action((key, opts) => run((spec) => spec.runSpecEdit({ ...opts, key })));
|
|
4484
4502
|
}
|
|
4485
4503
|
function registerWorkCommands(program2) {
|
|
4486
4504
|
const workCmd = program2.command("work").description("Start, remove, or read what the factory is working on (the Work page)");
|
|
@@ -4501,8 +4519,7 @@ takes it, and prints the line that starts your session on it. That
|
|
|
4501
4519
|
session links itself and holds the item's lease while it works.
|
|
4502
4520
|
`
|
|
4503
4521
|
).action(async (opts) => {
|
|
4504
|
-
|
|
4505
|
-
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4522
|
+
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4506
4523
|
try {
|
|
4507
4524
|
await runWorkBuild(opts);
|
|
4508
4525
|
} catch (err) {
|
|
@@ -4525,8 +4542,7 @@ renews that session's own 20-minute lease, unless --no-lease or
|
|
|
4525
4542
|
--ended is given, or another worker already holds a live one.
|
|
4526
4543
|
`
|
|
4527
4544
|
).action(async (number, opts) => {
|
|
4528
|
-
|
|
4529
|
-
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4545
|
+
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4530
4546
|
try {
|
|
4531
4547
|
await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false, logFailures: opts.logFailures === true });
|
|
4532
4548
|
} catch (err) {
|
|
@@ -4550,9 +4566,8 @@ criterion's new proof; --ready hands the thread back to a person. At
|
|
|
4550
4566
|
most one action flag may be given.
|
|
4551
4567
|
`
|
|
4552
4568
|
).action(async (opts) => {
|
|
4553
|
-
|
|
4554
|
-
const {
|
|
4555
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4569
|
+
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-UCCPWUSR.js');
|
|
4570
|
+
const { WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4556
4571
|
try {
|
|
4557
4572
|
await runWorkComment(opts);
|
|
4558
4573
|
} catch (err) {
|
|
@@ -4573,9 +4588,8 @@ criterion that carries proof or a comment, each with who is waiting
|
|
|
4573
4588
|
on whom next.
|
|
4574
4589
|
`
|
|
4575
4590
|
).action(async (opts) => {
|
|
4576
|
-
|
|
4577
|
-
const {
|
|
4578
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4591
|
+
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-UCCPWUSR.js');
|
|
4592
|
+
const { WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4579
4593
|
try {
|
|
4580
4594
|
await runWorkThreads(opts);
|
|
4581
4595
|
} catch (err) {
|
|
@@ -4586,6 +4600,31 @@ on whom next.
|
|
|
4586
4600
|
throw err;
|
|
4587
4601
|
}
|
|
4588
4602
|
});
|
|
4603
|
+
workCmd.command("logs").description("Read the runner's log for a host attempt on a work item").requiredOption("--item <number>", "the item's number inside this factory").option("--attempt <claim id>", "an attempt's id, from `work status --json` (default: the newest)").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(
|
|
4604
|
+
"after",
|
|
4605
|
+
`
|
|
4606
|
+
${cliInvocation()} work logs --item 7
|
|
4607
|
+
${cliInvocation()} work logs --item 7 --attempt 7b0a3c52-9f1e-4d6b-8a21-5c3e9d2f1a40
|
|
4608
|
+
|
|
4609
|
+
Prints what the runner did around the agent on that attempt, one line
|
|
4610
|
+
per event with its timestamp, with secrets removed on the host. The
|
|
4611
|
+
runner sends it when it releases the attempt, so an attempt that is
|
|
4612
|
+
still running, or that an older runner released, has no log and the
|
|
4613
|
+
command exits 1.
|
|
4614
|
+
`
|
|
4615
|
+
).action(async (opts) => {
|
|
4616
|
+
const { runWorkLogs, WorkLogsCommandError } = await import('./work-logs-cmd-7352CJPG.js');
|
|
4617
|
+
const { WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4618
|
+
try {
|
|
4619
|
+
await runWorkLogs(opts);
|
|
4620
|
+
} catch (err) {
|
|
4621
|
+
if (err instanceof WorkLogsCommandError || err instanceof WorkCommandError) {
|
|
4622
|
+
fail(err.message);
|
|
4623
|
+
return;
|
|
4624
|
+
}
|
|
4625
|
+
throw err;
|
|
4626
|
+
}
|
|
4627
|
+
});
|
|
4589
4628
|
workCmd.command("remove").description("Withdraw a source's addition \u2014 never deletes the item").option("--item <number>", "the item's number inside this factory").option("--issue <number>", "issue number or Linear/Jira key (default: named by --item instead)").option(TRACKER_OPTION_FLAG, "tracker for a keyed --issue, when both hold the key").option("--repo <owner/name>", "repository for an issue number (default: the checkout's remote)").requiredOption("--reason <text>", "why this source is no longer working on it").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(
|
|
4590
4629
|
"after",
|
|
4591
4630
|
`
|
|
@@ -4596,8 +4635,7 @@ deletes anything \u2014 the item is removed from Work only once no
|
|
|
4596
4635
|
live addition remains on it.
|
|
4597
4636
|
`
|
|
4598
4637
|
).action(async (opts) => {
|
|
4599
|
-
|
|
4600
|
-
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4638
|
+
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4601
4639
|
try {
|
|
4602
4640
|
await runWorkRemove(opts);
|
|
4603
4641
|
} catch (err) {
|
|
@@ -4609,8 +4647,7 @@ live addition remains on it.
|
|
|
4609
4647
|
}
|
|
4610
4648
|
});
|
|
4611
4649
|
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, or a Linear/Jira key like ENG-123").option(TRACKER_OPTION_FLAG, "tracker for a keyed --issue, when both hold the key").option("--repo <owner/name>", "repository for an issue number (default: the 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) => {
|
|
4612
|
-
|
|
4613
|
-
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4650
|
+
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4614
4651
|
try {
|
|
4615
4652
|
await runWorkStatus(opts);
|
|
4616
4653
|
} catch (err) {
|
|
@@ -4622,8 +4659,7 @@ live addition remains on it.
|
|
|
4622
4659
|
}
|
|
4623
4660
|
});
|
|
4624
4661
|
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) => {
|
|
4625
|
-
|
|
4626
|
-
const { runWorkList, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4662
|
+
const { runWorkList, WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4627
4663
|
try {
|
|
4628
4664
|
await runWorkList(opts);
|
|
4629
4665
|
} catch (err) {
|
|
@@ -4644,8 +4680,7 @@ by a different key is refused; claiming again with the same key extends
|
|
|
4644
4680
|
it. --host is a label only.
|
|
4645
4681
|
`
|
|
4646
4682
|
).action(async (opts) => {
|
|
4647
|
-
|
|
4648
|
-
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-34FERLYX.js');
|
|
4683
|
+
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-ZRPSHMPT.js');
|
|
4649
4684
|
try {
|
|
4650
4685
|
await runWorkClaim(opts);
|
|
4651
4686
|
} catch (err) {
|
|
@@ -4665,8 +4700,7 @@ Extends the live lease this API key holds. Refused with a 410 if the
|
|
|
4665
4700
|
lease has expired, or a 403 if a different key holds it.
|
|
4666
4701
|
`
|
|
4667
4702
|
).action(async (opts) => {
|
|
4668
|
-
|
|
4669
|
-
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-34FERLYX.js');
|
|
4703
|
+
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-ZRPSHMPT.js');
|
|
4670
4704
|
try {
|
|
4671
4705
|
await runWorkRenew(opts);
|
|
4672
4706
|
} catch (err) {
|
|
@@ -4698,8 +4732,7 @@ applies to a host's lease only. A later tool call in the session
|
|
|
4698
4732
|
takes the lease again.
|
|
4699
4733
|
`
|
|
4700
4734
|
).action(async (opts) => {
|
|
4701
|
-
|
|
4702
|
-
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-34FERLYX.js');
|
|
4735
|
+
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-ZRPSHMPT.js');
|
|
4703
4736
|
try {
|
|
4704
4737
|
await runWorkRelease(opts);
|
|
4705
4738
|
} catch (err) {
|
|
@@ -4726,8 +4759,7 @@ Idempotent: declaring the same pull request twice is a no-op.
|
|
|
4726
4759
|
needs your own login; an agent session or a factory key is refused.
|
|
4727
4760
|
`
|
|
4728
4761
|
).action(async (number, opts) => {
|
|
4729
|
-
|
|
4730
|
-
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-5LGANL32.js');
|
|
4762
|
+
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-H4OQR26N.js');
|
|
4731
4763
|
try {
|
|
4732
4764
|
await runWorkPr({ ...opts, number });
|
|
4733
4765
|
} catch (err) {
|
|
@@ -4752,9 +4784,8 @@ login, then declares the pull request on the item, as \`work pr\` does.
|
|
|
4752
4784
|
Run it again after a change to the title or description.
|
|
4753
4785
|
`
|
|
4754
4786
|
).action(async (opts) => {
|
|
4755
|
-
|
|
4756
|
-
const {
|
|
4757
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4787
|
+
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-LSH4VHJM.js');
|
|
4788
|
+
const { WorkCommandError } = await import('./work-cmd-5I3J2XQQ.js');
|
|
4758
4789
|
try {
|
|
4759
4790
|
await runWorkOpenPr(opts);
|
|
4760
4791
|
} catch (err) {
|
|
@@ -4770,8 +4801,8 @@ function registerRunnerCommands(program2) {
|
|
|
4770
4801
|
const runnerCmd = program2.command("runner").description("Take work from the implement and amend queues on this machine");
|
|
4771
4802
|
const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
|
|
4772
4803
|
runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
|
|
4773
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4774
|
-
const { start, RunnerStartError } = await import('./loop-
|
|
4804
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-CLSGABD5.js');
|
|
4805
|
+
const { start, RunnerStartError } = await import('./loop-TPUYUMSY.js');
|
|
4775
4806
|
const { RunnerAlreadyRunningError } = await import('./pidfile-3DM4OBKO.js');
|
|
4776
4807
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4777
4808
|
try {
|
|
@@ -4786,8 +4817,8 @@ function registerRunnerCommands(program2) {
|
|
|
4786
4817
|
}
|
|
4787
4818
|
});
|
|
4788
4819
|
runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
|
|
4789
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4790
|
-
const { runRunnerCheck } = await import('./check-
|
|
4820
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
4821
|
+
const { runRunnerCheck } = await import('./check-W2JGXN3B.js');
|
|
4791
4822
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4792
4823
|
const result = await runRunnerCheck(configPath);
|
|
4793
4824
|
if (!result.ok) {
|
|
@@ -4803,7 +4834,7 @@ function registerRunnerCommands(program2) {
|
|
|
4803
4834
|
`);
|
|
4804
4835
|
});
|
|
4805
4836
|
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) => {
|
|
4806
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4837
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-CLSGABD5.js');
|
|
4807
4838
|
const { runRunnerInstall, RunnerInstallError, launcherSummary, restartNote } = await import('./install-cmd-QDOTR4OM.js');
|
|
4808
4839
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4809
4840
|
if (opts.service !== true) {
|
|
@@ -4816,7 +4847,7 @@ function registerRunnerCommands(program2) {
|
|
|
4816
4847
|
}
|
|
4817
4848
|
try {
|
|
4818
4849
|
if (opts.service === true) {
|
|
4819
|
-
const { installServiceCommand } = await import('./command-
|
|
4850
|
+
const { installServiceCommand } = await import('./command-ZQNEPDS6.js');
|
|
4820
4851
|
const result2 = await installServiceCommand({
|
|
4821
4852
|
configPath,
|
|
4822
4853
|
print: opts.print,
|
|
@@ -4871,8 +4902,8 @@ To keep it running, run ${C.yellow}${cliInvocation()} runner install --service${
|
|
|
4871
4902
|
fail(`pass --service: \`${cliInvocation()} runner uninstall --service\` removes the runner's service.`);
|
|
4872
4903
|
return;
|
|
4873
4904
|
}
|
|
4874
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4875
|
-
const { uninstallServiceCommand } = await import('./command-
|
|
4905
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
4906
|
+
const { uninstallServiceCommand } = await import('./command-ZQNEPDS6.js');
|
|
4876
4907
|
const result = await uninstallServiceCommand({ configPath: opts.config ?? defaultRunnerConfigPath(), unitName: opts.unitName, home: homeFromEnv() });
|
|
4877
4908
|
if (result.ok) for (const line of result.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
|
|
4878
4909
|
`);
|
|
@@ -4899,12 +4930,12 @@ already in runner.env is used.
|
|
|
4899
4930
|
printf '%s' "$CLAUDE_CODE_OAUTH_TOKEN" | ${cliInvocation()} runner init --agent claude --factory <org>/<factory>
|
|
4900
4931
|
`
|
|
4901
4932
|
).action(async (opts) => {
|
|
4902
|
-
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-
|
|
4903
|
-
const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-
|
|
4904
|
-
const { obtainRunnerKey, runnerKeyLogin } = await import('./runner-key-
|
|
4905
|
-
const { detectMachine } = await import('./machine-
|
|
4906
|
-
const { chooseVm, runVmInit, VmInitError } = await import('./init-
|
|
4907
|
-
const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-
|
|
4933
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-CLSGABD5.js');
|
|
4934
|
+
const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-XG47KCI4.js');
|
|
4935
|
+
const { obtainRunnerKey, runnerKeyLogin } = await import('./runner-key-5FOWCW7J.js');
|
|
4936
|
+
const { detectMachine } = await import('./machine-TRHBT5NE.js');
|
|
4937
|
+
const { chooseVm, runVmInit, VmInitError } = await import('./init-V6FOMD2V.js');
|
|
4938
|
+
const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-FRZFFHDF.js');
|
|
4908
4939
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4909
4940
|
if (opts.agent !== void 0 && !isAgentName(opts.agent)) {
|
|
4910
4941
|
fail(`--agent ${opts.agent}: runner init writes commands for ${Object.keys(AGENT_COMMANDS).join(", ")}. For another agent, leave --agent out and edit runner.commands.`);
|
|
@@ -4918,7 +4949,7 @@ already in runner.env is used.
|
|
|
4918
4949
|
try {
|
|
4919
4950
|
let credential;
|
|
4920
4951
|
if (agent !== void 0) {
|
|
4921
|
-
const { readPipedKey } = await import('./login-browser-
|
|
4952
|
+
const { readPipedKey } = await import('./login-browser-DX35MARZ.js');
|
|
4922
4953
|
credential = credentialFromStdin(
|
|
4923
4954
|
await readPipedKey(process.stdin, {
|
|
4924
4955
|
onWaiting: () => process.stderr.write(`runner init is waiting for Claude's credential on stdin; close stdin to use the one already in runner.env
|
|
@@ -5054,7 +5085,7 @@ ${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
|
|
|
5054
5085
|
let serviceUp = false;
|
|
5055
5086
|
let restart;
|
|
5056
5087
|
if (installedLayout) {
|
|
5057
|
-
const { installServiceCommand } = await import('./command-
|
|
5088
|
+
const { installServiceCommand } = await import('./command-ZQNEPDS6.js');
|
|
5058
5089
|
const service = await installServiceCommand({
|
|
5059
5090
|
configPath,
|
|
5060
5091
|
entryPath: process.argv[1] ?? "",
|
|
@@ -5098,12 +5129,12 @@ Next:
|
|
|
5098
5129
|
"after",
|
|
5099
5130
|
"\nA repository governed by a control plane builds the control plane's image, at the commit\nthe gateway has stored for it. A repository that governs itself fetches the head of its\ndefault branch into the runner's cache. Either way it reads .devcontainer/devcontainer.json\nand 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"
|
|
5100
5131
|
).action(async (opts) => {
|
|
5101
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
5132
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
5102
5133
|
const { buildRepositoryImage, RecipeError } = await import('./build-TQ6X5PYN.js');
|
|
5103
5134
|
const { currentCliBuild } = await import('./cli-build-K56DK4DS.js');
|
|
5104
|
-
const { createDockerHost } = await import('./docker-
|
|
5105
|
-
const { builderSpec } = await import('./builder-
|
|
5106
|
-
const { loadRunnerConfig } = await import('./config-
|
|
5135
|
+
const { createDockerHost } = await import('./docker-BFU3AQGY.js');
|
|
5136
|
+
const { builderSpec } = await import('./builder-C4QNTYMS.js');
|
|
5137
|
+
const { loadRunnerConfig } = await import('./config-CLSGABD5.js');
|
|
5107
5138
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
5108
5139
|
const loaded = (() => {
|
|
5109
5140
|
try {
|
|
@@ -5114,7 +5145,7 @@ Next:
|
|
|
5114
5145
|
})();
|
|
5115
5146
|
const memory = loaded?.build?.memory ?? "8g";
|
|
5116
5147
|
try {
|
|
5117
|
-
const { imageTargetFor } = await import('./governing-source-
|
|
5148
|
+
const { imageTargetFor } = await import('./governing-source-HAA4OW57.js');
|
|
5118
5149
|
const target = await imageTargetFor({ config: loaded, repository: opts.repository, fetchImpl: fetch });
|
|
5119
5150
|
if (!target.ok) {
|
|
5120
5151
|
if (opts.json) {
|
|
@@ -5177,16 +5208,16 @@ Next:
|
|
|
5177
5208
|
}
|
|
5178
5209
|
});
|
|
5179
5210
|
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) => {
|
|
5180
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
5181
|
-
const { requestStop } = await import('./loop-
|
|
5211
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
5212
|
+
const { requestStop } = await import('./loop-TPUYUMSY.js');
|
|
5182
5213
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
5183
5214
|
await requestStop(configPath, Boolean(opts.now));
|
|
5184
5215
|
});
|
|
5185
5216
|
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) => {
|
|
5186
|
-
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-
|
|
5217
|
+
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-CLSGABD5.js');
|
|
5187
5218
|
const { jobsDir, runnerDir } = await import('./paths-7XP63OAX.js');
|
|
5188
|
-
const { listJobFiles, runnerProcessState } = await import('./loop-
|
|
5189
|
-
const { renderStatus } = await import('./status-
|
|
5219
|
+
const { listJobFiles, runnerProcessState } = await import('./loop-TPUYUMSY.js');
|
|
5220
|
+
const { renderStatus } = await import('./status-BINH7MBG.js');
|
|
5190
5221
|
const { readHousekeepingRecord } = await import('./record-3WP6V2K5.js');
|
|
5191
5222
|
const path2 = await import('path');
|
|
5192
5223
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
@@ -5206,7 +5237,7 @@ Next:
|
|
|
5206
5237
|
const service = await (async () => {
|
|
5207
5238
|
if (process.platform !== "linux" || !existsSync("/run/systemd/system")) return void 0;
|
|
5208
5239
|
const { inspectService, realInspectProbes } = await import('./inspect-6UYAAXH7.js');
|
|
5209
|
-
const { DEFAULT_UNIT_NAME } = await import('./install-
|
|
5240
|
+
const { DEFAULT_UNIT_NAME } = await import('./install-4SEFIIW2.js');
|
|
5210
5241
|
const facts = inspectService(DEFAULT_UNIT_NAME, path2.dirname(configPath), realInspectProbes());
|
|
5211
5242
|
return facts === void 0 ? void 0 : { unit: facts.unit, running: facts.mainPid !== void 0, delegated: facts.delegate };
|
|
5212
5243
|
})();
|
|
@@ -5241,8 +5272,8 @@ Next:
|
|
|
5241
5272
|
);
|
|
5242
5273
|
});
|
|
5243
5274
|
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) => {
|
|
5244
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
5245
|
-
const { listJobFiles } = await import('./loop-
|
|
5275
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
5276
|
+
const { listJobFiles } = await import('./loop-TPUYUMSY.js');
|
|
5246
5277
|
const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-AMLKC3VP.js');
|
|
5247
5278
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
5248
5279
|
const item = parseTrackerNumber(itemArg);
|
|
@@ -5277,32 +5308,22 @@ function registerHooksCommands(program2) {
|
|
|
5277
5308
|
"after",
|
|
5278
5309
|
"\n`init` auto-wraps PreToolUse/PostToolUse hooks; these subcommands cover the\nrest: manual re-scans, other events, and undo.\n"
|
|
5279
5310
|
);
|
|
5280
|
-
hooksCmd.command("install-git").description("
|
|
5311
|
+
hooksCmd.command("install-git").description("Remove the git hooks an earlier version installed in this repo").addHelpText(
|
|
5281
5312
|
"after",
|
|
5282
|
-
"\
|
|
5283
|
-
).action((
|
|
5284
|
-
if (opts.print) {
|
|
5285
|
-
for (const [name, script] of managedHookScripts()) {
|
|
5286
|
-
process.stdout.write(`# ==== ${name} ====
|
|
5287
|
-
${script}
|
|
5288
|
-
`);
|
|
5289
|
-
}
|
|
5290
|
-
return;
|
|
5291
|
-
}
|
|
5313
|
+
"\nEarlier versions installed a pre-commit guard and commit journal hooks. This removes\nthe ones OuterLayer wrote and leaves any hook it did not write untouched.\n"
|
|
5314
|
+
).action(() => {
|
|
5292
5315
|
const removal = removeJournalHooks(process.cwd());
|
|
5293
5316
|
if (removal.removed) {
|
|
5294
5317
|
process.stdout.write(`${C.green}\u2713${C.reset} removed the commit journal hooks an earlier version installed \u2192 ${removal.path}
|
|
5295
5318
|
`);
|
|
5296
5319
|
}
|
|
5297
|
-
const guard =
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
return;
|
|
5320
|
+
const guard = removePreCommitGuardHook(process.cwd());
|
|
5321
|
+
if (guard.removed) {
|
|
5322
|
+
process.stdout.write(`${C.green}\u2713${C.reset} removed the pre-commit guard an earlier version installed \u2192 ${guard.path}
|
|
5323
|
+
`);
|
|
5302
5324
|
}
|
|
5303
|
-
|
|
5325
|
+
if (!removal.removed && !guard.removed) process.stdout.write(`${C.dim}No git hooks from an earlier version were found.${C.reset}
|
|
5304
5326
|
`);
|
|
5305
|
-
if (report.exitCode !== void 0) process.exitCode = report.exitCode;
|
|
5306
5327
|
});
|
|
5307
5328
|
hooksCmd.command("status").description("List hook entries in user and project settings, marking the wrapped ones").option("--json", "machine-readable JSON output").action((opts) => {
|
|
5308
5329
|
const report = [];
|
|
@@ -5501,7 +5522,7 @@ caller from the bearer token, the gateway answers 401 without that header.
|
|
|
5501
5522
|
"after",
|
|
5502
5523
|
"\nWhat the stdio .mcp.json entry spawns. Reads newline-delimited JSON-RPC 2.0 on\nstdin and writes responses on stdout. The API key comes from OUTERLAYER_API_KEY\nor ~/.outerlayer/config.json at start-up; with neither the command exits 1 and\nprints why, which the MCP client shows as the connect error.\n"
|
|
5503
5524
|
).action(async (opts) => {
|
|
5504
|
-
const { runMcpServe, handleMcpServeError } = await import('./mcp-serve-cmd-
|
|
5525
|
+
const { runMcpServe, handleMcpServeError } = await import('./mcp-serve-cmd-N3UTY6EE.js');
|
|
5505
5526
|
try {
|
|
5506
5527
|
await runMcpServe({ url: opts.url, appId: opts.appId });
|
|
5507
5528
|
} catch (err) {
|
|
@@ -5512,7 +5533,7 @@ caller from the bearer token, the gateway answers 401 without that header.
|
|
|
5512
5533
|
function registerImportCommands(program2) {
|
|
5513
5534
|
const importCmd = program2.command("import").description("Import an existing config format into .outerlayer/");
|
|
5514
5535
|
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) => {
|
|
5515
|
-
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-
|
|
5536
|
+
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-T6LLO6Q7.js');
|
|
5516
5537
|
try {
|
|
5517
5538
|
const result = runImportRuler({ cwd: opts.dir, json: opts.json });
|
|
5518
5539
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -5528,7 +5549,7 @@ function registerImportCommands(program2) {
|
|
|
5528
5549
|
"after",
|
|
5529
5550
|
"\nInstalls the four maintained skills (outerlayer-evidence, outerlayer-amend,\nouterlayer-findings, outerlayer-cli) 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"
|
|
5530
5551
|
).action(async (opts) => {
|
|
5531
|
-
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-
|
|
5552
|
+
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-TK4XY7RD.js');
|
|
5532
5553
|
try {
|
|
5533
5554
|
runImportCapture({ cwd: opts.dir, json: opts.json });
|
|
5534
5555
|
} catch (err) {
|
|
@@ -5540,59 +5561,14 @@ function registerImportCommands(program2) {
|
|
|
5540
5561
|
}
|
|
5541
5562
|
});
|
|
5542
5563
|
}
|
|
5543
|
-
function formatContextMaterializeOutput(result) {
|
|
5544
|
-
switch (result.status) {
|
|
5545
|
-
case "not-a-repo":
|
|
5546
|
-
return { stdout: [], stderr: [`${C.red}\u2717${C.reset} not inside a git repository.`], exitCode: 1 };
|
|
5547
|
-
case "self":
|
|
5548
|
-
return { stdout: [`${C.dim}This repository is self-sourced \u2014 nothing to materialize.${C.reset}`], stderr: [] };
|
|
5549
|
-
case "materialized": {
|
|
5550
|
-
const stdout = [`${C.green}\u2713${C.reset} Materialized context at ${C.dim}${result.sha?.slice(0, 7)}${C.reset}`];
|
|
5551
|
-
if (result.message) stdout.push(`${C.yellow}!${C.reset} ${result.message}`);
|
|
5552
|
-
return { stdout, stderr: [] };
|
|
5553
|
-
}
|
|
5554
|
-
case "debounced": {
|
|
5555
|
-
const stdout = [`${C.green}\u2713${C.reset} Already current at ${C.dim}${result.sha?.slice(0, 7)}${C.reset} (verification: ${result.verification})`];
|
|
5556
|
-
if (result.message) stdout.push(`${C.yellow}!${C.reset} ${result.message}`);
|
|
5557
|
-
return { stdout, stderr: [] };
|
|
5558
|
-
}
|
|
5559
|
-
case "adoption-conflict":
|
|
5560
|
-
return { stdout: [`${C.yellow}!${C.reset} ${result.message}`], stderr: [], exitCode: 1 };
|
|
5561
|
-
default:
|
|
5562
|
-
return { stdout: [`${C.yellow}!${C.reset} ${result.message ?? result.status}`], stderr: [], exitCode: 1 };
|
|
5563
|
-
}
|
|
5564
|
-
}
|
|
5565
5564
|
function registerContextCommands(program2) {
|
|
5566
|
-
const contextCmd = program2.command("context").description("Compile
|
|
5565
|
+
const contextCmd = program2.command("context").description("Compile agent context");
|
|
5567
5566
|
contextCmd.command("emit").description("Compile .outerlayer/ into each configured target tool's native files").option("--check", "compare against disk, write nothing, exit 1 on drift (CI mode)").option("--dir <path>", "repo root to read from (default: cwd)").option("--json", "machine-readable JSON output").addHelpText(
|
|
5568
5567
|
"after",
|
|
5569
5568
|
'\nTargets come from .outerlayer/config.json only; there is no --target flag.\nMissing or empty config: {"targets": [...]}, e.g. {"targets": ["claude-code"]}.\nKnown targets: claude-code, cursor, codex, copilot, factory.\n\nThe maintained skills (outerlayer-evidence, outerlayer-amend, outerlayer-findings,\nouterlayer-cli) follow this CLI: emit rewrites one that differs from its bundle, and --check\nreports it as drift. A copy under an earlier name (amend, emitting-evidence,\nreporting-findings, outerlayer) is deleted, and --check reports it as retired.\nTemplates (spec, writing-specs, writing-tests, build) are never rewritten or reported.\n\nOrphan detection (--check) only covers header-carrying outputs: every markdown\ntarget file gets a generated-by comment, but .mcp.json and .cursor/mcp.json are\nJSON with no comment syntax, so they can never be flagged as orphaned; missing\nand content drift still apply to them.\n'
|
|
5570
5569
|
).action(async (opts) => {
|
|
5571
5570
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
5572
5571
|
});
|
|
5573
|
-
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) => {
|
|
5574
|
-
const { runContextAdopt } = await import('./context-adopt-O5OFXMKI.js');
|
|
5575
|
-
const { exitCode, stdout } = runContextAdopt(stagedDir, process.cwd());
|
|
5576
|
-
process.stdout.write(stdout);
|
|
5577
|
-
process.exitCode = exitCode;
|
|
5578
|
-
});
|
|
5579
|
-
contextCmd.command("materialize").description("Materialize this repository's governed context from its control plane").option("--json", "machine-readable JSON output").addHelpText(
|
|
5580
|
-
"after",
|
|
5581
|
-
"\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"
|
|
5582
|
-
).action(async (opts) => {
|
|
5583
|
-
const { materializeContext } = await import('./context-materialize-Y5IJ4MQT.js');
|
|
5584
|
-
const result = await materializeContext({ cwd: process.cwd(), sessionId: `manual-${Date.now()}` });
|
|
5585
|
-
const output = formatContextMaterializeOutput(result);
|
|
5586
|
-
if (output.exitCode !== void 0) process.exitCode = output.exitCode;
|
|
5587
|
-
if (opts.json) {
|
|
5588
|
-
writeJson(result);
|
|
5589
|
-
return;
|
|
5590
|
-
}
|
|
5591
|
-
for (const line of output.stdout) process.stdout.write(`${line}
|
|
5592
|
-
`);
|
|
5593
|
-
for (const line of output.stderr) process.stderr.write(`${line}
|
|
5594
|
-
`);
|
|
5595
|
-
});
|
|
5596
5572
|
}
|
|
5597
5573
|
|
|
5598
|
-
export { buildProgram,
|
|
5574
|
+
export { buildProgram, formatInitOutput, runCli };
|