@outerlayer/cli 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +21 -2
- package/dist/{agent-setup-RBTEACYU.js → agent-setup-TPR4BBFV.js} +15 -16
- package/dist/{artifact-link-cmd-AVM2EKTV.js → artifact-link-cmd-W7XF5BFB.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-UWQAL2MN.js} +44 -43
- package/dist/{chunk-S26M3YBJ.js → chunk-3UZTIRLF.js} +1 -1
- package/dist/{chunk-W5VPCONO.js → chunk-452TM7J4.js} +33 -227
- package/dist/{chunk-UYOYTKE2.js → chunk-5GHGAF6P.js} +3 -3
- package/dist/{chunk-QQM2UJ6T.js → chunk-5MYFOW5V.js} +182 -28
- package/dist/{chunk-Y5GE76XC.js → chunk-5TN7GLYX.js} +33 -81
- package/dist/{chunk-GOBOJMOJ.js → chunk-6D7GT22T.js} +4 -4
- package/dist/{chunk-3OFZM4X6.js → chunk-6U3MV7TZ.js} +151 -20
- package/dist/{chunk-F4XSVQJ4.js → chunk-6X4SQ5MY.js} +2 -2
- package/dist/{chunk-Y5MXET4M.js → chunk-7KSSBQTS.js} +11 -10
- package/dist/{chunk-JF42URPU.js → chunk-7SJPQWBM.js} +33 -9
- package/dist/{chunk-N3CUDFCW.js → chunk-7VUK5RFS.js} +15 -2
- package/dist/{chunk-SWCTGCSC.js → chunk-7YP7T6GV.js} +1 -1
- package/dist/{chunk-KDVIU23F.js → chunk-BWSUPRDK.js} +1 -1
- package/dist/{chunk-S76AYB4M.js → chunk-CG36IONK.js} +5 -5
- package/dist/chunk-CJJDJ7AT.js +56 -0
- package/dist/{chunk-FUB7LRUE.js → chunk-DADWEUH3.js} +5 -5
- package/dist/{chunk-RAZTWYZN.js → chunk-DJ3ZUSC3.js} +7 -8
- package/dist/{chunk-MQJSXHV7.js → chunk-G3IJ3N6F.js} +5 -3
- package/dist/{chunk-KK4VBOH6.js → chunk-HPJNLETG.js} +10 -11
- package/dist/{chunk-IP7BIBXJ.js → chunk-IF2OSI5T.js} +35 -1
- package/dist/{chunk-T4Y6SCG3.js → chunk-IXYZUUYQ.js} +2 -2
- 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-ULSIJGLS.js → chunk-NFIR3GEE.js} +56 -14
- package/dist/{chunk-MNTSH4CL.js → chunk-NNLA7LLQ.js} +1 -1
- package/dist/{chunk-WGAUY5LE.js → chunk-QEFKA2QD.js} +1 -1
- package/dist/{chunk-BMYGAGBJ.js → chunk-QNLX477Q.js} +155 -23
- package/dist/chunk-TUSYOL2O.js +113 -0
- package/dist/{chunk-ESC6UR76.js → chunk-TWF3RICI.js} +6 -6
- package/dist/{chunk-NL4XPC7W.js → chunk-UVG35MWF.js} +1 -1
- package/dist/{chunk-L2USZT6T.js → chunk-VMJPFQNE.js} +1 -1
- package/dist/chunk-VRRGENS4.js +144 -0
- package/dist/{chunk-X5N6KC6V.js → chunk-WFSUUUAN.js} +2 -3
- package/dist/{chunk-6CHIYEZZ.js → chunk-XSZD4AZ6.js} +9 -83
- package/dist/{chunk-LXAY4A2G.js → chunk-YQR6E6OV.js} +34 -49
- package/dist/{chunk-47TTLEDX.js → chunk-ZHAUSEEN.js} +35 -13
- package/dist/{claude-launcher-YVXI76NX.js → claude-launcher-FPPHZPMR.js} +20 -7
- package/dist/{cli-C77H54BV.js → cli-HROW5T7X.js} +203 -228
- package/dist/{command-H5CILO4S.js → command-OEAV7BVX.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-HSVYDGMI.js +9 -0
- package/dist/control-plane-launch-NYVDJESK.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-23BBJWBX.js} +32 -33
- package/dist/{emit-artifact-cmd-7MP63KXU.js → emit-artifact-cmd-O6SCM7TV.js} +17 -17
- package/dist/{emit-cmd-PPN4QQF2.js → emit-cmd-7SP3I6UZ.js} +6 -6
- package/dist/{emit-criteria-cmd-3RXPDLNK.js → emit-criteria-cmd-LQNERZRV.js} +11 -12
- package/dist/{emit-finding-cmd-OL7JB6H3.js → emit-finding-cmd-AJPKHIOV.js} +12 -13
- package/dist/{emit-result-cmd-UZVMOCF4.js → emit-result-cmd-RUICOKWQ.js} +17 -17
- package/dist/emit-step-cmd-347XNGPQ.js +26 -0
- package/dist/{governing-source-BUU4IABS.js → governing-source-V5EEGPTA.js} +21 -22
- package/dist/{hook-fast-W5MKHMJT.js → hook-fast-YAZG5MDX.js} +3 -3
- package/dist/{import-capture-cmd-ZO6KGHI2.js → import-capture-cmd-KKFFOGWP.js} +4 -4
- package/dist/{import-ruler-cmd-KJMWL5V6.js → import-ruler-cmd-5P6JOXQN.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/{init-WNXXYMO7.js → init-LWHDMZQG.js} +30 -31
- package/dist/{init-VWXIZEAN.js → init-MOINY2DD.js} +30 -31
- package/dist/{init-cmd-WS6TIRYT.js → init-cmd-HSMRID6A.js} +67 -26
- package/dist/{init-update-E3J6TVIN.js → init-update-LWX5MPPR.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-SYYPVFYW.js} +44 -43
- package/dist/{machine-JOW4RNZ7.js → machine-6X63G2KH.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-276SJU5R.js} +30 -31
- package/dist/{session-sender-NNVPSPY7.js → session-sender-GGIY5OAX.js} +19 -15
- package/dist/shell-function-NRD4KVUK.js +6 -0
- package/dist/{spec-cmd-OWVTBB4J.js → spec-cmd-SIZBRN7D.js} +12 -13
- package/dist/{starter-pack-OPWUDOWX.js → starter-pack-6LQVLBIA.js} +5 -5
- package/dist/{status-TKCLLKFG.js → status-NAK6DYSF.js} +33 -32
- package/dist/{sync-cmd-Q6VYNPWG.js → sync-cmd-G7GF4UTW.js} +18 -14
- package/dist/{watch-ARAGADTF.js → watch-EVM5GSMP.js} +18 -14
- package/dist/{work-claim-cmd-34FERLYX.js → work-claim-cmd-3J3QW56U.js} +16 -17
- package/dist/{work-cmd-7S5B2H2P.js → work-cmd-5EPPD33Y.js} +12 -13
- package/dist/{work-comment-cmd-SZJSPM5S.js → work-comment-cmd-2ACOZQAE.js} +12 -13
- package/dist/work-logs-cmd-QDD2NMJL.js +60 -0
- package/dist/{work-open-pr-cmd-RPXKCBWS.js → work-open-pr-cmd-XNCEI4ZM.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-5TN7GLYX.js';
|
|
4
|
+
import './chunk-TWF3RICI.js';
|
|
5
|
+
import { verifiedTrackerNames, TRACKERS } from './chunk-HPJNLETG.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-NFIR3GEE.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-IXYZUUYQ.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
|
+
import './chunk-WFSUUUAN.js';
|
|
28
|
+
import './chunk-7VUK5RFS.js';
|
|
27
29
|
import './chunk-EABW6AJQ.js';
|
|
30
|
+
import { cliInvocation, packageRunnerOf } from './chunk-CRB3POP4.js';
|
|
31
|
+
import { cloneIsGoverned } from './chunk-YQR6E6OV.js';
|
|
32
|
+
import { removeJournalHooks, removePreCommitGuardHook } from './chunk-TUSYOL2O.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-LWX5MPPR.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,19 @@ states under Starter files.
|
|
|
3917
3884
|
fail(outcome.text);
|
|
3918
3885
|
return;
|
|
3919
3886
|
}
|
|
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
|
+
}
|
|
3920
3893
|
if (opts.json) writeJson(outcome.result);
|
|
3921
3894
|
else process.stdout.write(outcome.text);
|
|
3922
3895
|
return;
|
|
3923
3896
|
}
|
|
3924
|
-
const { runInitCommand } = await import('./init-cmd-
|
|
3897
|
+
const { runInitCommand } = await import('./init-cmd-HSMRID6A.js');
|
|
3925
3898
|
const code = await runInitCommand(
|
|
3926
|
-
{ json: opts.json, factory: opts.factory },
|
|
3899
|
+
{ json: opts.json, factory: opts.factory, shellFunction: opts.shellFunction },
|
|
3927
3900
|
{
|
|
3928
3901
|
connect: await realConnectDepsForCwd(),
|
|
3929
3902
|
stdout: process.stdout,
|
|
@@ -3933,10 +3906,26 @@ states under Starter files.
|
|
|
3933
3906
|
return { ok, text, detail };
|
|
3934
3907
|
},
|
|
3935
3908
|
runAgentSetup: async () => {
|
|
3936
|
-
const { runAgentSetup } = await import('./agent-setup-
|
|
3909
|
+
const { runAgentSetup } = await import('./agent-setup-TPR4BBFV.js');
|
|
3937
3910
|
return runAgentSetup({ cwd: process.cwd() });
|
|
3938
3911
|
},
|
|
3939
|
-
runDoctorChecks: gatherDoctorChecks
|
|
3912
|
+
runDoctorChecks: gatherDoctorChecks,
|
|
3913
|
+
shell: {
|
|
3914
|
+
home: homeFromEnv(),
|
|
3915
|
+
shellPath: process.env.SHELL,
|
|
3916
|
+
interactive: Boolean(process.stdin.isTTY && process.stderr.isTTY) && opts.json !== true,
|
|
3917
|
+
ask: async () => {
|
|
3918
|
+
const { promptOnTerminal } = await import('./connect-cmd-UNYKGDAL.js');
|
|
3919
|
+
const answer = await promptOnTerminal({
|
|
3920
|
+
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.`,
|
|
3921
|
+
options: [
|
|
3922
|
+
{ label: "Yes, add the block", value: "yes" },
|
|
3923
|
+
{ label: "No, I will run outerlayer claude myself", value: "no" }
|
|
3924
|
+
]
|
|
3925
|
+
});
|
|
3926
|
+
return answer === "yes";
|
|
3927
|
+
}
|
|
3928
|
+
}
|
|
3940
3929
|
}
|
|
3941
3930
|
);
|
|
3942
3931
|
if (code !== 0) process.exitCode = code;
|
|
@@ -3965,7 +3954,7 @@ linked (true, false, or null when it could not be checked) and, when false,
|
|
|
3965
3954
|
linkUrl.
|
|
3966
3955
|
`
|
|
3967
3956
|
).action(async (opts) => {
|
|
3968
|
-
const { runConnectCommand } = await import('./connect-cmd-
|
|
3957
|
+
const { runConnectCommand } = await import('./connect-cmd-UNYKGDAL.js');
|
|
3969
3958
|
const code = await runConnectCommand({ factory: opts.factory, json: opts.json }, await realConnectDepsForCwd(), {
|
|
3970
3959
|
stdout: process.stdout,
|
|
3971
3960
|
stderr: process.stderr
|
|
@@ -4004,7 +3993,7 @@ Every later command reads the saved file, so none of them needs a key on
|
|
|
4004
3993
|
its command line. A saved key is checked for real on the first \`sync\`.
|
|
4005
3994
|
`
|
|
4006
3995
|
).action(async (opts) => {
|
|
4007
|
-
const { runLoginCommand, realLoginDeps } = await import('./login-browser-
|
|
3996
|
+
const { runLoginCommand, realLoginDeps } = await import('./login-browser-DX35MARZ.js');
|
|
4008
3997
|
const code = await runLoginCommand(
|
|
4009
3998
|
{
|
|
4010
3999
|
browser: opts.browser !== false,
|
|
@@ -4036,15 +4025,14 @@ code is 1: revoke the token on /profile/security.
|
|
|
4036
4025
|
"after",
|
|
4037
4026
|
"\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
4027
|
).action(async (opts) => {
|
|
4039
|
-
warnIfApiKeyFlag(opts);
|
|
4040
4028
|
if (opts.link !== void 0) {
|
|
4041
|
-
const { lookupArtifactLink } = await import('./artifact-link-cmd-
|
|
4029
|
+
const { lookupArtifactLink } = await import('./artifact-link-cmd-W7XF5BFB.js');
|
|
4042
4030
|
const found = lookupArtifactLink(opts.link);
|
|
4043
4031
|
if (found.ok) process.stdout.write(found.url + "\n");
|
|
4044
4032
|
else fail(found.reason);
|
|
4045
4033
|
return;
|
|
4046
4034
|
}
|
|
4047
|
-
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-
|
|
4035
|
+
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-G7GF4UTW.js');
|
|
4048
4036
|
try {
|
|
4049
4037
|
const result = await runSync({
|
|
4050
4038
|
url: opts.url,
|
|
@@ -4075,7 +4063,7 @@ code is 1: revoke the token on /profile/security.
|
|
|
4075
4063
|
if (invokedCommandToken(argv) === "watch") {
|
|
4076
4064
|
warnDeprecated(`\`${cliInvocation()} watch\` is now \`${cliInvocation()} daemon\`; the old name will be removed in a future release.`);
|
|
4077
4065
|
}
|
|
4078
|
-
const { runWatch } = await import('./watch-
|
|
4066
|
+
const { runWatch } = await import('./watch-EVM5GSMP.js');
|
|
4079
4067
|
await runWatch({ once: opts.once });
|
|
4080
4068
|
});
|
|
4081
4069
|
program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
|
|
@@ -4084,7 +4072,7 @@ code is 1: revoke the token on /profile/security.
|
|
|
4084
4072
|
});
|
|
4085
4073
|
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
4074
|
});
|
|
4087
|
-
program2.command("claude [args...]"
|
|
4075
|
+
program2.command("claude [args...]").description("start Claude Code with the repository's control plane attached").allowUnknownOption().helpOption(false).action(() => {
|
|
4088
4076
|
});
|
|
4089
4077
|
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
4078
|
const { startRelay } = await import('./relay-L76HDX72.js');
|
|
@@ -4131,7 +4119,7 @@ code is 1: revoke the token on /profile/security.
|
|
|
4131
4119
|
}
|
|
4132
4120
|
});
|
|
4133
4121
|
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-
|
|
4122
|
+
const { runSessionSender } = await import('./session-sender-GGIY5OAX.js');
|
|
4135
4123
|
try {
|
|
4136
4124
|
await runSessionSender();
|
|
4137
4125
|
} catch (err) {
|
|
@@ -4167,7 +4155,7 @@ async function runCli(processArgv) {
|
|
|
4167
4155
|
await buildProgram(argv).parseAsync(argv);
|
|
4168
4156
|
}
|
|
4169
4157
|
async function compileContext(opts) {
|
|
4170
|
-
const { runEmit, EmitError } = await import('./emit-cmd-
|
|
4158
|
+
const { runEmit, EmitError } = await import('./emit-cmd-7SP3I6UZ.js');
|
|
4171
4159
|
try {
|
|
4172
4160
|
const result = runEmit({ cwd: opts.dir, check: opts.check, json: opts.json });
|
|
4173
4161
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -4204,7 +4192,8 @@ criterion's thread instead \u2014 see \`${cliInvocation()} work comment\`.
|
|
|
4204
4192
|
|
|
4205
4193
|
Subcommands: \`emit artifact <file>\` for screenshots, recordings, reports and
|
|
4206
4194
|
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
|
|
4195
|
+
\`emit criteria <file>\` to record a work item's acceptance criteria;
|
|
4196
|
+
\`emit step <name>\` to report that you started a step.
|
|
4208
4197
|
Compiling .outerlayer/ moved to \`${cliInvocation()} context emit\`.
|
|
4209
4198
|
`
|
|
4210
4199
|
).action(async (name, opts) => {
|
|
@@ -4213,8 +4202,7 @@ Compiling .outerlayer/ moved to \`${cliInvocation()} context emit\`.
|
|
|
4213
4202
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
4214
4203
|
return;
|
|
4215
4204
|
}
|
|
4216
|
-
|
|
4217
|
-
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-UZVMOCF4.js');
|
|
4205
|
+
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-RUICOKWQ.js');
|
|
4218
4206
|
try {
|
|
4219
4207
|
const result = await runEmitResult({
|
|
4220
4208
|
name,
|
|
@@ -4264,8 +4252,7 @@ everywhere, bytes and deep link untouched; a still-queued one is cancelled
|
|
|
4264
4252
|
locally so it never uploads. One correction can retire several duplicates.
|
|
4265
4253
|
`
|
|
4266
4254
|
).action(async (file, opts) => {
|
|
4267
|
-
|
|
4268
|
-
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-7MP63KXU.js');
|
|
4255
|
+
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-O6SCM7TV.js');
|
|
4269
4256
|
let pr;
|
|
4270
4257
|
if (opts.pr !== void 0) {
|
|
4271
4258
|
pr = parseTrackerNumber(opts.pr);
|
|
@@ -4324,8 +4311,7 @@ recent events with their ids. --find <text> searches all of them.
|
|
|
4324
4311
|
item that session was launched for is used automatically.
|
|
4325
4312
|
`
|
|
4326
4313
|
).action(async (opts) => {
|
|
4327
|
-
|
|
4328
|
-
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-OL7JB6H3.js');
|
|
4314
|
+
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-AJPKHIOV.js');
|
|
4329
4315
|
try {
|
|
4330
4316
|
refuseRemovedFindingFlags(opts);
|
|
4331
4317
|
const result = await runEmitFinding({
|
|
@@ -4392,8 +4378,7 @@ the whole batch. "untimed": true records one with no time on purpose.
|
|
|
4392
4378
|
that session was launched for is used automatically.
|
|
4393
4379
|
`
|
|
4394
4380
|
).action(async (file, opts) => {
|
|
4395
|
-
|
|
4396
|
-
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-OL7JB6H3.js');
|
|
4381
|
+
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-AJPKHIOV.js');
|
|
4397
4382
|
try {
|
|
4398
4383
|
const result = await runEmitFindings({
|
|
4399
4384
|
file,
|
|
@@ -4412,6 +4397,40 @@ that session was launched for is used automatically.
|
|
|
4412
4397
|
throw err;
|
|
4413
4398
|
}
|
|
4414
4399
|
});
|
|
4400
|
+
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(
|
|
4401
|
+
"after",
|
|
4402
|
+
`
|
|
4403
|
+
${cliInvocation()} emit step "Review round 2"
|
|
4404
|
+
${cliInvocation()} emit step "Plan" --item 412
|
|
4405
|
+
|
|
4406
|
+
Run it when you start a step. The name is free text: 1 to 80 characters on one
|
|
4407
|
+
line. A step has a start and nothing else, so run it again for the next step.
|
|
4408
|
+
--item names the work item; without it, inside a recorded session, the item that
|
|
4409
|
+
session was launched for is used.
|
|
4410
|
+
|
|
4411
|
+
If the gateway cannot be reached, the step is queued with the time you ran the
|
|
4412
|
+
command, the command exits 0, and \`sync\` sends it later. If the gateway refuses
|
|
4413
|
+
the step, the command prints why and exits 1.
|
|
4414
|
+
`
|
|
4415
|
+
).action(async (name, opts) => {
|
|
4416
|
+
const { runEmitStep, EmitStepError } = await import('./emit-step-cmd-347XNGPQ.js');
|
|
4417
|
+
try {
|
|
4418
|
+
await runEmitStep({
|
|
4419
|
+
name,
|
|
4420
|
+
item: opts.item,
|
|
4421
|
+
json: opts.json,
|
|
4422
|
+
url: opts.url,
|
|
4423
|
+
apiKey: opts.apiKey,
|
|
4424
|
+
appId: opts.appId
|
|
4425
|
+
});
|
|
4426
|
+
} catch (err) {
|
|
4427
|
+
if (err instanceof EmitStepError) {
|
|
4428
|
+
fail(err.message);
|
|
4429
|
+
return;
|
|
4430
|
+
}
|
|
4431
|
+
throw err;
|
|
4432
|
+
}
|
|
4433
|
+
});
|
|
4415
4434
|
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
4435
|
"after",
|
|
4417
4436
|
`
|
|
@@ -4432,8 +4451,7 @@ agent session, with your own login. A key bound to no member cannot replace it e
|
|
|
4432
4451
|
session was launched for is used automatically.
|
|
4433
4452
|
`
|
|
4434
4453
|
).action(async (file, opts) => {
|
|
4435
|
-
|
|
4436
|
-
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-3RXPDLNK.js');
|
|
4454
|
+
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-LQNERZRV.js');
|
|
4437
4455
|
try {
|
|
4438
4456
|
const result = await runEmitCriteria({
|
|
4439
4457
|
file,
|
|
@@ -4456,11 +4474,10 @@ session was launched for is used automatically.
|
|
|
4456
4474
|
function registerSpecCommands(program2) {
|
|
4457
4475
|
const specCmd = program2.command("spec").description("Find, file and edit the issue a spec lives in, in your factory's tracker");
|
|
4458
4476
|
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');
|
|
4477
|
+
const run = async (action) => {
|
|
4478
|
+
const { WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4462
4479
|
try {
|
|
4463
|
-
await action(await import('./spec-cmd-
|
|
4480
|
+
await action(await import('./spec-cmd-SIZBRN7D.js'));
|
|
4464
4481
|
} catch (err) {
|
|
4465
4482
|
if (err instanceof WorkCommandError) {
|
|
4466
4483
|
fail(err.message);
|
|
@@ -4471,16 +4488,16 @@ function registerSpecCommands(program2) {
|
|
|
4471
4488
|
};
|
|
4472
4489
|
credentialOptions(
|
|
4473
4490
|
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(
|
|
4491
|
+
).action((opts) => run((spec) => spec.runSpecTarget(opts)));
|
|
4475
4492
|
credentialOptions(
|
|
4476
4493
|
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(
|
|
4494
|
+
).action((query, opts) => run((spec) => spec.runSpecSearch({ ...opts, query })));
|
|
4478
4495
|
credentialOptions(
|
|
4479
4496
|
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(
|
|
4497
|
+
).action((opts) => run((spec) => spec.runSpecFile(opts)));
|
|
4481
4498
|
credentialOptions(
|
|
4482
4499
|
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(
|
|
4500
|
+
).action((key, opts) => run((spec) => spec.runSpecEdit({ ...opts, key })));
|
|
4484
4501
|
}
|
|
4485
4502
|
function registerWorkCommands(program2) {
|
|
4486
4503
|
const workCmd = program2.command("work").description("Start, remove, or read what the factory is working on (the Work page)");
|
|
@@ -4501,8 +4518,7 @@ takes it, and prints the line that starts your session on it. That
|
|
|
4501
4518
|
session links itself and holds the item's lease while it works.
|
|
4502
4519
|
`
|
|
4503
4520
|
).action(async (opts) => {
|
|
4504
|
-
|
|
4505
|
-
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4521
|
+
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4506
4522
|
try {
|
|
4507
4523
|
await runWorkBuild(opts);
|
|
4508
4524
|
} catch (err) {
|
|
@@ -4525,8 +4541,7 @@ renews that session's own 20-minute lease, unless --no-lease or
|
|
|
4525
4541
|
--ended is given, or another worker already holds a live one.
|
|
4526
4542
|
`
|
|
4527
4543
|
).action(async (number, opts) => {
|
|
4528
|
-
|
|
4529
|
-
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4544
|
+
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4530
4545
|
try {
|
|
4531
4546
|
await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false, logFailures: opts.logFailures === true });
|
|
4532
4547
|
} catch (err) {
|
|
@@ -4550,9 +4565,8 @@ criterion's new proof; --ready hands the thread back to a person. At
|
|
|
4550
4565
|
most one action flag may be given.
|
|
4551
4566
|
`
|
|
4552
4567
|
).action(async (opts) => {
|
|
4553
|
-
|
|
4554
|
-
const {
|
|
4555
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4568
|
+
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-2ACOZQAE.js');
|
|
4569
|
+
const { WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4556
4570
|
try {
|
|
4557
4571
|
await runWorkComment(opts);
|
|
4558
4572
|
} catch (err) {
|
|
@@ -4573,9 +4587,8 @@ criterion that carries proof or a comment, each with who is waiting
|
|
|
4573
4587
|
on whom next.
|
|
4574
4588
|
`
|
|
4575
4589
|
).action(async (opts) => {
|
|
4576
|
-
|
|
4577
|
-
const {
|
|
4578
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4590
|
+
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-2ACOZQAE.js');
|
|
4591
|
+
const { WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4579
4592
|
try {
|
|
4580
4593
|
await runWorkThreads(opts);
|
|
4581
4594
|
} catch (err) {
|
|
@@ -4586,6 +4599,31 @@ on whom next.
|
|
|
4586
4599
|
throw err;
|
|
4587
4600
|
}
|
|
4588
4601
|
});
|
|
4602
|
+
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(
|
|
4603
|
+
"after",
|
|
4604
|
+
`
|
|
4605
|
+
${cliInvocation()} work logs --item 7
|
|
4606
|
+
${cliInvocation()} work logs --item 7 --attempt 7b0a3c52-9f1e-4d6b-8a21-5c3e9d2f1a40
|
|
4607
|
+
|
|
4608
|
+
Prints what the runner did around the agent on that attempt, one line
|
|
4609
|
+
per event with its timestamp, with secrets removed on the host. The
|
|
4610
|
+
runner sends it when it releases the attempt, so an attempt that is
|
|
4611
|
+
still running, or that an older runner released, has no log and the
|
|
4612
|
+
command exits 1.
|
|
4613
|
+
`
|
|
4614
|
+
).action(async (opts) => {
|
|
4615
|
+
const { runWorkLogs, WorkLogsCommandError } = await import('./work-logs-cmd-QDD2NMJL.js');
|
|
4616
|
+
const { WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4617
|
+
try {
|
|
4618
|
+
await runWorkLogs(opts);
|
|
4619
|
+
} catch (err) {
|
|
4620
|
+
if (err instanceof WorkLogsCommandError || err instanceof WorkCommandError) {
|
|
4621
|
+
fail(err.message);
|
|
4622
|
+
return;
|
|
4623
|
+
}
|
|
4624
|
+
throw err;
|
|
4625
|
+
}
|
|
4626
|
+
});
|
|
4589
4627
|
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
4628
|
"after",
|
|
4591
4629
|
`
|
|
@@ -4596,8 +4634,7 @@ deletes anything \u2014 the item is removed from Work only once no
|
|
|
4596
4634
|
live addition remains on it.
|
|
4597
4635
|
`
|
|
4598
4636
|
).action(async (opts) => {
|
|
4599
|
-
|
|
4600
|
-
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4637
|
+
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4601
4638
|
try {
|
|
4602
4639
|
await runWorkRemove(opts);
|
|
4603
4640
|
} catch (err) {
|
|
@@ -4609,8 +4646,7 @@ live addition remains on it.
|
|
|
4609
4646
|
}
|
|
4610
4647
|
});
|
|
4611
4648
|
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');
|
|
4649
|
+
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4614
4650
|
try {
|
|
4615
4651
|
await runWorkStatus(opts);
|
|
4616
4652
|
} catch (err) {
|
|
@@ -4622,8 +4658,7 @@ live addition remains on it.
|
|
|
4622
4658
|
}
|
|
4623
4659
|
});
|
|
4624
4660
|
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');
|
|
4661
|
+
const { runWorkList, WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4627
4662
|
try {
|
|
4628
4663
|
await runWorkList(opts);
|
|
4629
4664
|
} catch (err) {
|
|
@@ -4644,8 +4679,7 @@ by a different key is refused; claiming again with the same key extends
|
|
|
4644
4679
|
it. --host is a label only.
|
|
4645
4680
|
`
|
|
4646
4681
|
).action(async (opts) => {
|
|
4647
|
-
|
|
4648
|
-
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-34FERLYX.js');
|
|
4682
|
+
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-3J3QW56U.js');
|
|
4649
4683
|
try {
|
|
4650
4684
|
await runWorkClaim(opts);
|
|
4651
4685
|
} catch (err) {
|
|
@@ -4665,8 +4699,7 @@ Extends the live lease this API key holds. Refused with a 410 if the
|
|
|
4665
4699
|
lease has expired, or a 403 if a different key holds it.
|
|
4666
4700
|
`
|
|
4667
4701
|
).action(async (opts) => {
|
|
4668
|
-
|
|
4669
|
-
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-34FERLYX.js');
|
|
4702
|
+
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-3J3QW56U.js');
|
|
4670
4703
|
try {
|
|
4671
4704
|
await runWorkRenew(opts);
|
|
4672
4705
|
} catch (err) {
|
|
@@ -4698,8 +4731,7 @@ applies to a host's lease only. A later tool call in the session
|
|
|
4698
4731
|
takes the lease again.
|
|
4699
4732
|
`
|
|
4700
4733
|
).action(async (opts) => {
|
|
4701
|
-
|
|
4702
|
-
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-34FERLYX.js');
|
|
4734
|
+
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-3J3QW56U.js');
|
|
4703
4735
|
try {
|
|
4704
4736
|
await runWorkRelease(opts);
|
|
4705
4737
|
} catch (err) {
|
|
@@ -4726,8 +4758,7 @@ Idempotent: declaring the same pull request twice is a no-op.
|
|
|
4726
4758
|
needs your own login; an agent session or a factory key is refused.
|
|
4727
4759
|
`
|
|
4728
4760
|
).action(async (number, opts) => {
|
|
4729
|
-
|
|
4730
|
-
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-5LGANL32.js');
|
|
4761
|
+
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-H4OQR26N.js');
|
|
4731
4762
|
try {
|
|
4732
4763
|
await runWorkPr({ ...opts, number });
|
|
4733
4764
|
} catch (err) {
|
|
@@ -4752,9 +4783,8 @@ login, then declares the pull request on the item, as \`work pr\` does.
|
|
|
4752
4783
|
Run it again after a change to the title or description.
|
|
4753
4784
|
`
|
|
4754
4785
|
).action(async (opts) => {
|
|
4755
|
-
|
|
4756
|
-
const {
|
|
4757
|
-
const { WorkCommandError } = await import('./work-cmd-7S5B2H2P.js');
|
|
4786
|
+
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-XNCEI4ZM.js');
|
|
4787
|
+
const { WorkCommandError } = await import('./work-cmd-5EPPD33Y.js');
|
|
4758
4788
|
try {
|
|
4759
4789
|
await runWorkOpenPr(opts);
|
|
4760
4790
|
} catch (err) {
|
|
@@ -4770,8 +4800,8 @@ function registerRunnerCommands(program2) {
|
|
|
4770
4800
|
const runnerCmd = program2.command("runner").description("Take work from the implement and amend queues on this machine");
|
|
4771
4801
|
const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
|
|
4772
4802
|
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-
|
|
4803
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-CLSGABD5.js');
|
|
4804
|
+
const { start, RunnerStartError } = await import('./loop-SYYPVFYW.js');
|
|
4775
4805
|
const { RunnerAlreadyRunningError } = await import('./pidfile-3DM4OBKO.js');
|
|
4776
4806
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4777
4807
|
try {
|
|
@@ -4786,8 +4816,8 @@ function registerRunnerCommands(program2) {
|
|
|
4786
4816
|
}
|
|
4787
4817
|
});
|
|
4788
4818
|
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-
|
|
4819
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
4820
|
+
const { runRunnerCheck } = await import('./check-UWQAL2MN.js');
|
|
4791
4821
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4792
4822
|
const result = await runRunnerCheck(configPath);
|
|
4793
4823
|
if (!result.ok) {
|
|
@@ -4803,7 +4833,7 @@ function registerRunnerCommands(program2) {
|
|
|
4803
4833
|
`);
|
|
4804
4834
|
});
|
|
4805
4835
|
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-
|
|
4836
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-CLSGABD5.js');
|
|
4807
4837
|
const { runRunnerInstall, RunnerInstallError, launcherSummary, restartNote } = await import('./install-cmd-QDOTR4OM.js');
|
|
4808
4838
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4809
4839
|
if (opts.service !== true) {
|
|
@@ -4816,7 +4846,7 @@ function registerRunnerCommands(program2) {
|
|
|
4816
4846
|
}
|
|
4817
4847
|
try {
|
|
4818
4848
|
if (opts.service === true) {
|
|
4819
|
-
const { installServiceCommand } = await import('./command-
|
|
4849
|
+
const { installServiceCommand } = await import('./command-OEAV7BVX.js');
|
|
4820
4850
|
const result2 = await installServiceCommand({
|
|
4821
4851
|
configPath,
|
|
4822
4852
|
print: opts.print,
|
|
@@ -4871,8 +4901,8 @@ To keep it running, run ${C.yellow}${cliInvocation()} runner install --service${
|
|
|
4871
4901
|
fail(`pass --service: \`${cliInvocation()} runner uninstall --service\` removes the runner's service.`);
|
|
4872
4902
|
return;
|
|
4873
4903
|
}
|
|
4874
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
4875
|
-
const { uninstallServiceCommand } = await import('./command-
|
|
4904
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
4905
|
+
const { uninstallServiceCommand } = await import('./command-OEAV7BVX.js');
|
|
4876
4906
|
const result = await uninstallServiceCommand({ configPath: opts.config ?? defaultRunnerConfigPath(), unitName: opts.unitName, home: homeFromEnv() });
|
|
4877
4907
|
if (result.ok) for (const line of result.lines) process.stdout.write(`${C.green}\u2713${C.reset} ${line}
|
|
4878
4908
|
`);
|
|
@@ -4899,12 +4929,12 @@ already in runner.env is used.
|
|
|
4899
4929
|
printf '%s' "$CLAUDE_CODE_OAUTH_TOKEN" | ${cliInvocation()} runner init --agent claude --factory <org>/<factory>
|
|
4900
4930
|
`
|
|
4901
4931
|
).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-
|
|
4932
|
+
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-CLSGABD5.js');
|
|
4933
|
+
const { prepareRunnerInit, runRunnerInit, RunnerInitError, writeRunnerInit } = await import('./init-MOINY2DD.js');
|
|
4934
|
+
const { obtainRunnerKey, runnerKeyLogin } = await import('./runner-key-276SJU5R.js');
|
|
4935
|
+
const { detectMachine } = await import('./machine-6X63G2KH.js');
|
|
4936
|
+
const { chooseVm, runVmInit, VmInitError } = await import('./init-LWHDMZQG.js');
|
|
4937
|
+
const { AGENT_COMMANDS, credentialFromStdin, isAgentName, restartForCredential, RunnerEnvError } = await import('./runner-env-FRZFFHDF.js');
|
|
4908
4938
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4909
4939
|
if (opts.agent !== void 0 && !isAgentName(opts.agent)) {
|
|
4910
4940
|
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 +4948,7 @@ already in runner.env is used.
|
|
|
4918
4948
|
try {
|
|
4919
4949
|
let credential;
|
|
4920
4950
|
if (agent !== void 0) {
|
|
4921
|
-
const { readPipedKey } = await import('./login-browser-
|
|
4951
|
+
const { readPipedKey } = await import('./login-browser-DX35MARZ.js');
|
|
4922
4952
|
credential = credentialFromStdin(
|
|
4923
4953
|
await readPipedKey(process.stdin, {
|
|
4924
4954
|
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 +5084,7 @@ ${C.yellow}The runner will not update itself: ${installErr.message}${C.reset}
|
|
|
5054
5084
|
let serviceUp = false;
|
|
5055
5085
|
let restart;
|
|
5056
5086
|
if (installedLayout) {
|
|
5057
|
-
const { installServiceCommand } = await import('./command-
|
|
5087
|
+
const { installServiceCommand } = await import('./command-OEAV7BVX.js');
|
|
5058
5088
|
const service = await installServiceCommand({
|
|
5059
5089
|
configPath,
|
|
5060
5090
|
entryPath: process.argv[1] ?? "",
|
|
@@ -5098,12 +5128,12 @@ Next:
|
|
|
5098
5128
|
"after",
|
|
5099
5129
|
"\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
5130
|
).action(async (opts) => {
|
|
5101
|
-
const { defaultRunnerConfigPath } = await import('./config-
|
|
5131
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
5102
5132
|
const { buildRepositoryImage, RecipeError } = await import('./build-TQ6X5PYN.js');
|
|
5103
5133
|
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-
|
|
5134
|
+
const { createDockerHost } = await import('./docker-BFU3AQGY.js');
|
|
5135
|
+
const { builderSpec } = await import('./builder-C4QNTYMS.js');
|
|
5136
|
+
const { loadRunnerConfig } = await import('./config-CLSGABD5.js');
|
|
5107
5137
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
5108
5138
|
const loaded = (() => {
|
|
5109
5139
|
try {
|
|
@@ -5114,7 +5144,7 @@ Next:
|
|
|
5114
5144
|
})();
|
|
5115
5145
|
const memory = loaded?.build?.memory ?? "8g";
|
|
5116
5146
|
try {
|
|
5117
|
-
const { imageTargetFor } = await import('./governing-source-
|
|
5147
|
+
const { imageTargetFor } = await import('./governing-source-V5EEGPTA.js');
|
|
5118
5148
|
const target = await imageTargetFor({ config: loaded, repository: opts.repository, fetchImpl: fetch });
|
|
5119
5149
|
if (!target.ok) {
|
|
5120
5150
|
if (opts.json) {
|
|
@@ -5177,16 +5207,16 @@ Next:
|
|
|
5177
5207
|
}
|
|
5178
5208
|
});
|
|
5179
5209
|
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-
|
|
5210
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
5211
|
+
const { requestStop } = await import('./loop-SYYPVFYW.js');
|
|
5182
5212
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
5183
5213
|
await requestStop(configPath, Boolean(opts.now));
|
|
5184
5214
|
});
|
|
5185
5215
|
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-
|
|
5216
|
+
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-CLSGABD5.js');
|
|
5187
5217
|
const { jobsDir, runnerDir } = await import('./paths-7XP63OAX.js');
|
|
5188
|
-
const { listJobFiles, runnerProcessState } = await import('./loop-
|
|
5189
|
-
const { renderStatus } = await import('./status-
|
|
5218
|
+
const { listJobFiles, runnerProcessState } = await import('./loop-SYYPVFYW.js');
|
|
5219
|
+
const { renderStatus } = await import('./status-NAK6DYSF.js');
|
|
5190
5220
|
const { readHousekeepingRecord } = await import('./record-3WP6V2K5.js');
|
|
5191
5221
|
const path2 = await import('path');
|
|
5192
5222
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
@@ -5206,7 +5236,7 @@ Next:
|
|
|
5206
5236
|
const service = await (async () => {
|
|
5207
5237
|
if (process.platform !== "linux" || !existsSync("/run/systemd/system")) return void 0;
|
|
5208
5238
|
const { inspectService, realInspectProbes } = await import('./inspect-6UYAAXH7.js');
|
|
5209
|
-
const { DEFAULT_UNIT_NAME } = await import('./install-
|
|
5239
|
+
const { DEFAULT_UNIT_NAME } = await import('./install-4SEFIIW2.js');
|
|
5210
5240
|
const facts = inspectService(DEFAULT_UNIT_NAME, path2.dirname(configPath), realInspectProbes());
|
|
5211
5241
|
return facts === void 0 ? void 0 : { unit: facts.unit, running: facts.mainPid !== void 0, delegated: facts.delegate };
|
|
5212
5242
|
})();
|
|
@@ -5241,8 +5271,8 @@ Next:
|
|
|
5241
5271
|
);
|
|
5242
5272
|
});
|
|
5243
5273
|
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-
|
|
5274
|
+
const { defaultRunnerConfigPath } = await import('./config-CLSGABD5.js');
|
|
5275
|
+
const { listJobFiles } = await import('./loop-SYYPVFYW.js');
|
|
5246
5276
|
const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-AMLKC3VP.js');
|
|
5247
5277
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
5248
5278
|
const item = parseTrackerNumber(itemArg);
|
|
@@ -5277,32 +5307,22 @@ function registerHooksCommands(program2) {
|
|
|
5277
5307
|
"after",
|
|
5278
5308
|
"\n`init` auto-wraps PreToolUse/PostToolUse hooks; these subcommands cover the\nrest: manual re-scans, other events, and undo.\n"
|
|
5279
5309
|
);
|
|
5280
|
-
hooksCmd.command("install-git").description("
|
|
5310
|
+
hooksCmd.command("install-git").description("Remove the git hooks an earlier version installed in this repo").addHelpText(
|
|
5281
5311
|
"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
|
-
}
|
|
5312
|
+
"\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"
|
|
5313
|
+
).action(() => {
|
|
5292
5314
|
const removal = removeJournalHooks(process.cwd());
|
|
5293
5315
|
if (removal.removed) {
|
|
5294
5316
|
process.stdout.write(`${C.green}\u2713${C.reset} removed the commit journal hooks an earlier version installed \u2192 ${removal.path}
|
|
5295
5317
|
`);
|
|
5296
5318
|
}
|
|
5297
|
-
const guard =
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
return;
|
|
5319
|
+
const guard = removePreCommitGuardHook(process.cwd());
|
|
5320
|
+
if (guard.removed) {
|
|
5321
|
+
process.stdout.write(`${C.green}\u2713${C.reset} removed the pre-commit guard an earlier version installed \u2192 ${guard.path}
|
|
5322
|
+
`);
|
|
5302
5323
|
}
|
|
5303
|
-
|
|
5324
|
+
if (!removal.removed && !guard.removed) process.stdout.write(`${C.dim}No git hooks from an earlier version were found.${C.reset}
|
|
5304
5325
|
`);
|
|
5305
|
-
if (report.exitCode !== void 0) process.exitCode = report.exitCode;
|
|
5306
5326
|
});
|
|
5307
5327
|
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
5328
|
const report = [];
|
|
@@ -5501,7 +5521,7 @@ caller from the bearer token, the gateway answers 401 without that header.
|
|
|
5501
5521
|
"after",
|
|
5502
5522
|
"\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
5523
|
).action(async (opts) => {
|
|
5504
|
-
const { runMcpServe, handleMcpServeError } = await import('./mcp-serve-cmd-
|
|
5524
|
+
const { runMcpServe, handleMcpServeError } = await import('./mcp-serve-cmd-N3UTY6EE.js');
|
|
5505
5525
|
try {
|
|
5506
5526
|
await runMcpServe({ url: opts.url, appId: opts.appId });
|
|
5507
5527
|
} catch (err) {
|
|
@@ -5512,7 +5532,7 @@ caller from the bearer token, the gateway answers 401 without that header.
|
|
|
5512
5532
|
function registerImportCommands(program2) {
|
|
5513
5533
|
const importCmd = program2.command("import").description("Import an existing config format into .outerlayer/");
|
|
5514
5534
|
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-
|
|
5535
|
+
const { runImportRuler, ImportRulerError } = await import('./import-ruler-cmd-5P6JOXQN.js');
|
|
5516
5536
|
try {
|
|
5517
5537
|
const result = runImportRuler({ cwd: opts.dir, json: opts.json });
|
|
5518
5538
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
@@ -5528,7 +5548,7 @@ function registerImportCommands(program2) {
|
|
|
5528
5548
|
"after",
|
|
5529
5549
|
"\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
5550
|
).action(async (opts) => {
|
|
5531
|
-
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-
|
|
5551
|
+
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-KKFFOGWP.js');
|
|
5532
5552
|
try {
|
|
5533
5553
|
runImportCapture({ cwd: opts.dir, json: opts.json });
|
|
5534
5554
|
} catch (err) {
|
|
@@ -5540,59 +5560,14 @@ function registerImportCommands(program2) {
|
|
|
5540
5560
|
}
|
|
5541
5561
|
});
|
|
5542
5562
|
}
|
|
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
5563
|
function registerContextCommands(program2) {
|
|
5566
|
-
const contextCmd = program2.command("context").description("Compile
|
|
5564
|
+
const contextCmd = program2.command("context").description("Compile agent context");
|
|
5567
5565
|
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
5566
|
"after",
|
|
5569
5567
|
'\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
5568
|
).action(async (opts) => {
|
|
5571
5569
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
5572
5570
|
});
|
|
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
5571
|
}
|
|
5597
5572
|
|
|
5598
|
-
export { buildProgram,
|
|
5573
|
+
export { buildProgram, formatInitOutput, runCli };
|