@outerlayer/cli 0.17.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 +72 -0
- package/README.md +36 -2
- package/dist/agent-setup-TPR4BBFV.js +27 -0
- package/dist/{artifact-link-cmd-2F47LT7F.js → artifact-link-cmd-W7XF5BFB.js} +4 -3
- package/dist/{build-BG2YENGK.js → build-TQ6X5PYN.js} +5 -4
- package/dist/build-info.json +1 -1
- package/dist/{builder-2D3WSOOY.js → builder-C4QNTYMS.js} +5 -6
- package/dist/{check-5XE7XMC4.js → check-UWQAL2MN.js} +56 -52
- package/dist/{chunk-R7PF5OOU.js → chunk-3CWUOFV6.js} +21 -14
- package/dist/{chunk-4NPZVMJU.js → chunk-3UZTIRLF.js} +60 -4
- package/dist/chunk-452TM7J4.js +502 -0
- package/dist/{chunk-NNRTPG7X.js → chunk-5GHGAF6P.js} +4 -4
- package/dist/{chunk-WVUIRTWA.js → chunk-5MYFOW5V.js} +196 -37
- package/dist/{chunk-HGECYFEI.js → chunk-5TN7GLYX.js} +138 -109
- package/dist/{chunk-VQYBXPI7.js → chunk-6D7GT22T.js} +5 -5
- package/dist/{chunk-G5NPRL2K.js → chunk-6U3MV7TZ.js} +687 -76
- package/dist/{chunk-42ZI52JW.js → chunk-6X4SQ5MY.js} +4 -3
- package/dist/{chunk-MAK5LYRF.js → chunk-7KSSBQTS.js} +278 -535
- package/dist/{chunk-NWQTTSBB.js → chunk-7SJPQWBM.js} +41 -16
- package/dist/{chunk-J5M7BSJQ.js → chunk-7VUK5RFS.js} +23 -4
- package/dist/{chunk-OZGHL5Y5.js → chunk-7YP7T6GV.js} +2 -2
- package/dist/{chunk-TI7B7UEO.js → chunk-AMFWYESY.js} +1 -1
- package/dist/{chunk-YRYMNBGQ.js → chunk-ANPNT6PM.js} +2 -1
- package/dist/{chunk-4KSQKQXE.js → chunk-BM63HB2M.js} +20 -16
- package/dist/{chunk-4Q7OMKAT.js → chunk-BQXFBI7T.js} +81 -5
- package/dist/{chunk-ADJRGVZC.js → chunk-BWSUPRDK.js} +1 -1
- package/dist/{chunk-3NSNIIBE.js → chunk-CG36IONK.js} +18 -17
- package/dist/chunk-CJJDJ7AT.js +56 -0
- package/dist/chunk-CRB3POP4.js +34 -0
- package/dist/{chunk-LWSJQJC6.js → chunk-DADWEUH3.js} +7 -7
- package/dist/{chunk-KG5ECZGJ.js → chunk-DJ3ZUSC3.js} +11 -11
- package/dist/{chunk-F47JBIAW.js → chunk-DSF2FWAZ.js} +2 -1
- package/dist/{chunk-N5FOE5PS.js → chunk-ECODQ7II.js} +4 -33
- package/dist/{chunk-HHJDN6AU.js → chunk-ESVW4MJY.js} +1 -1
- package/dist/{chunk-YO4PSLVB.js → chunk-FVMYKL6L.js} +1 -1
- package/dist/chunk-G2YNJIGF.js +44 -0
- package/dist/{chunk-WUYTWNMA.js → chunk-G3IJ3N6F.js} +5 -3
- package/dist/{chunk-QKFB4K7X.js → chunk-GGOMT6KF.js} +1 -1
- package/dist/{chunk-N6LURUEF.js → chunk-GOSFARMS.js} +1 -1
- package/dist/{chunk-S3NYLI2P.js → chunk-HPJNLETG.js} +93 -38
- package/dist/{chunk-IP7BIBXJ.js → chunk-IF2OSI5T.js} +35 -1
- package/dist/{chunk-C5Y5ZJJZ.js → chunk-IXYZUUYQ.js} +5 -4
- package/dist/chunk-JBJTC3UU.js +35 -0
- package/dist/chunk-KYS3TQAG.js +296 -0
- package/dist/chunk-LLM3I5YU.js +89 -0
- package/dist/{chunk-YU3VKZ5F.js → chunk-LRG3ZMZD.js} +6 -7
- package/dist/{chunk-V7NIVOFD.js → chunk-M2ZWWTWZ.js} +1 -1
- package/dist/{chunk-ERI5GBNI.js → chunk-MLAAT4S6.js} +3 -3
- package/dist/{chunk-O765JR4W.js → chunk-MTP2QEVO.js} +1 -1
- package/dist/{chunk-ZM2IMMYN.js → chunk-N2PXGQRL.js} +9 -1
- package/dist/{chunk-BWQ66M6N.js → chunk-NFIR3GEE.js} +98 -24
- package/dist/{chunk-POJMEEJJ.js → chunk-NNLA7LLQ.js} +1 -1
- package/dist/{chunk-PLMTLGYH.js → chunk-NTRCK4NH.js} +5 -4
- package/dist/{chunk-22RMZBGW.js → chunk-P53VEAOF.js} +1 -1
- package/dist/{chunk-RLYZLUQ7.js → chunk-QEFKA2QD.js} +2 -2
- package/dist/{chunk-JXYVA45C.js → chunk-QNLX477Q.js} +1200 -322
- package/dist/{chunk-UGP76IZ5.js → chunk-S5PCA3SN.js} +1 -1
- package/dist/{chunk-RMWLBUCJ.js → chunk-SADUQSO4.js} +1 -1
- package/dist/{chunk-GQD22KKN.js → chunk-T2Q7ISPE.js} +2 -1
- package/dist/chunk-TUSYOL2O.js +113 -0
- package/dist/{chunk-NBGDBTO2.js → chunk-TWF3RICI.js} +9 -8
- package/dist/{chunk-ONKJUM6R.js → chunk-UVG35MWF.js} +1 -1
- package/dist/{chunk-KMDLFI4P.js → chunk-VMJPFQNE.js} +1 -1
- package/dist/chunk-VRRGENS4.js +144 -0
- package/dist/{chunk-PTW6W5NR.js → chunk-VYAL7PUE.js} +1 -1
- package/dist/{chunk-OHVJA253.js → chunk-WFSUUUAN.js} +47 -30
- package/dist/{chunk-RSNSZ2LJ.js → chunk-X5H2WYMB.js} +1 -1
- package/dist/{chunk-HYZRY4KZ.js → chunk-XNGMQ27R.js} +16 -6
- package/dist/chunk-XSZD4AZ6.js +490 -0
- package/dist/chunk-YQR6E6OV.js +109 -0
- package/dist/{chunk-XCK2YAY5.js → chunk-YVZJ6GKF.js} +3 -2
- package/dist/{chunk-2MNPHL23.js → chunk-ZHAUSEEN.js} +38 -15
- package/dist/claude-launcher-FPPHZPMR.js +115 -0
- package/dist/{cli-A76AXELQ.js → cli-HROW5T7X.js} +567 -285
- package/dist/{command-R2QCVX55.js → command-OEAV7BVX.js} +42 -40
- package/dist/{config-N3C6DFQA.js → config-CLSGABD5.js} +2 -3
- package/dist/{connect-cmd-JBKAQNSF.js → connect-cmd-UNYKGDAL.js} +10 -9
- package/dist/context-cleanup-HSVYDGMI.js +9 -0
- package/dist/control-plane-launch-NYVDJESK.js +216 -0
- package/dist/{dist-LKDWQWZ7.js → dist-WO7NOJNG.js} +2 -2
- package/dist/{docker-4J77Q2BF.js → docker-BFU3AQGY.js} +7 -8
- package/dist/{doctor-4TAIARIG.js → doctor-23BBJWBX.js} +48 -42
- package/dist/{emit-artifact-cmd-MPZVR56N.js → emit-artifact-cmd-O6SCM7TV.js} +27 -24
- package/dist/emit-cmd-7SP3I6UZ.js +14 -0
- package/dist/{emit-criteria-cmd-EFGYI23V.js → emit-criteria-cmd-LQNERZRV.js} +17 -16
- package/dist/{emit-finding-cmd-5GF3V4LR.js → emit-finding-cmd-AJPKHIOV.js} +18 -17
- package/dist/{emit-result-cmd-I4OADKMD.js → emit-result-cmd-RUICOKWQ.js} +22 -19
- package/dist/emit-step-cmd-347XNGPQ.js +26 -0
- package/dist/{exec-client-CQV746UF.js → exec-client-7UMESIE2.js} +3 -4
- package/dist/governing-source-V5EEGPTA.js +34 -0
- package/dist/guest-init-KPBQOFE5.js +9 -0
- package/dist/{hook-fast-R4FVSZ2H.js → hook-fast-YAZG5MDX.js} +5 -2
- package/dist/host-key-U4B5QETR.js +8 -0
- package/dist/{import-capture-cmd-EQ35EARA.js → import-capture-cmd-KKFFOGWP.js} +7 -5
- package/dist/{import-ruler-cmd-BGAZXCQM.js → import-ruler-cmd-5P6JOXQN.js} +5 -3
- package/dist/index.js +8 -4
- package/dist/{init-PWU5YVL7.js → init-LWHDMZQG.js} +40 -38
- package/dist/init-MOINY2DD.js +53 -0
- package/dist/{init-cmd-XAVO7HYZ.js → init-cmd-HSMRID6A.js} +75 -30
- package/dist/{init-update-CVCWD6VS.js → init-update-LWX5MPPR.js} +29 -29
- package/dist/{install-HDBIPHTX.js → install-4SEFIIW2.js} +4 -5
- package/dist/{install-cmd-5HYMXLEW.js → install-cmd-QDOTR4OM.js} +5 -4
- package/dist/{login-browser-QZCS3WW6.js → login-browser-DX35MARZ.js} +5 -4
- package/dist/{logout-cmd-QAUFDJ6J.js → logout-cmd-5V5MMBSY.js} +3 -2
- package/dist/{logs-H55NWW4H.js → logs-AMLKC3VP.js} +3 -1
- package/dist/loop-SYYPVFYW.js +77 -0
- package/dist/machine-6X63G2KH.js +48 -0
- package/dist/{mcp-install-cmd-FDTPQQS6.js → mcp-install-cmd-GGWB3JJ2.js} +3 -2
- package/dist/{mcp-serve-cmd-3KVYEUXG.js → mcp-serve-cmd-N3UTY6EE.js} +11 -9
- package/dist/paths-7XP63OAX.js +7 -0
- package/dist/pending-532ABZYC.js +8 -0
- package/dist/{pidfile-UZRH774M.js → pidfile-3DM4OBKO.js} +4 -2
- package/dist/{record-C43U4PKS.js → record-3WP6V2K5.js} +3 -2
- package/dist/{runner-env-EN7YE7QX.js → runner-env-FRZFFHDF.js} +5 -6
- package/dist/{runner-key-6SLBI7PP.js → runner-key-276SJU5R.js} +40 -38
- package/dist/session-sender-GGIY5OAX.js +36 -0
- package/dist/{pending-MXLSRYMO.js → shell-function-NRD4KVUK.js} +1 -2
- package/dist/spec-cmd-SIZBRN7D.js +115 -0
- package/dist/{starter-pack-KF66HGZR.js → starter-pack-6LQVLBIA.js} +7 -5
- package/dist/{status-7VNQN5PW.js → status-NAK6DYSF.js} +46 -42
- package/dist/{statusline-fast-SVTMBMD7.js → statusline-fast-KN3BX67H.js} +2 -1
- package/dist/sync-cmd-G7GF4UTW.js +35 -0
- package/dist/{watch-23HSAEI6.js → watch-EVM5GSMP.js} +22 -15
- package/dist/{work-claim-cmd-LKL3GHFQ.js → work-claim-cmd-3J3QW56U.js} +26 -29
- package/dist/work-cmd-5EPPD33Y.js +24 -0
- package/dist/{work-comment-cmd-AWHP56M2.js → work-comment-cmd-2ACOZQAE.js} +16 -15
- package/dist/{work-launch-R5HTAP6X.js → work-launch-LEQ2MPM3.js} +3 -1
- package/dist/work-logs-cmd-QDD2NMJL.js +60 -0
- package/dist/{work-open-pr-cmd-IOM4AVQQ.js → work-open-pr-cmd-XNCEI4ZM.js} +18 -17
- package/dist/work-pr-cmd-H4OQR26N.js +25 -0
- package/package.json +3 -2
- package/skill-pack/maintained/outerlayer-amend/SKILL.md +4 -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 +18 -2
- package/skill-pack/template/build/SKILL.md +23 -10
- package/skill-pack/template/build/references/agent-briefs.md +3 -1
- package/skill-pack/template/build/references/criteria-judge.md +27 -0
- package/skill-pack/template/build/references/release.md +22 -29
- package/skill-pack/template/spec/SKILL.md +35 -10
- package/skill-pack/validators/acceptance-criteria.yaml +25 -26
- package/dist/agent-setup-T624CWPD.js +0 -27
- package/dist/chunk-6Y5RUTHO.js +0 -39
- package/dist/chunk-BYT5O5RV.js +0 -61
- package/dist/chunk-WTE3MQML.js +0 -133
- package/dist/chunk-XCCLFVXM.js +0 -401
- package/dist/chunk-YZ5F4PIS.js +0 -797
- package/dist/context-adopt-NFHCLVUB.js +0 -108
- package/dist/context-materialize-IV2TUUFO.js +0 -22
- package/dist/emit-cmd-IJ3GVRFD.js +0 -12
- package/dist/guest-init-LJP5GPZF.js +0 -9
- package/dist/host-key-YMLXY6QB.js +0 -7
- package/dist/init-6XPDRDTC.js +0 -51
- package/dist/loop-FK3LPMMZ.js +0 -73
- package/dist/machine-SQXEBAM2.js +0 -46
- package/dist/paths-OYKMVYJP.js +0 -6
- package/dist/session-sender-FO3LCREV.js +0 -29
- package/dist/sync-cmd-GVPPFZ3G.js +0 -28
- package/dist/work-cmd-Z2WXLZPH.js +0 -23
- package/dist/work-pr-cmd-HNEUIEN7.js +0 -24
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { checkStarterFiles, contextIsGoverned } from './chunk-
|
|
4
|
-
import { resolveCredentials, getJson, WorkCommandError } from './chunk-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
3
|
+
import { checkStarterFiles, contextIsGoverned } from './chunk-TWF3RICI.js';
|
|
4
|
+
import { resolveCredentials, getJson, WorkCommandError } from './chunk-HPJNLETG.js';
|
|
5
|
+
import { isLinkedRepository } from './chunk-CG36IONK.js';
|
|
6
|
+
import { sanitizeTerminal } from './chunk-G3IJ3N6F.js';
|
|
7
|
+
import { sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, hookFiredMarkerPath, refreshCommand } from './chunk-NFIR3GEE.js';
|
|
8
|
+
import { readStatuslineState, STATE_FRESH_MS } from './chunk-DSF2FWAZ.js';
|
|
9
|
+
import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-QNLX477Q.js';
|
|
10
|
+
import { C } from './chunk-ANPNT6PM.js';
|
|
10
11
|
import { readSettings, settingsPath, isOurStatuslineSlot, statuslineWrappedOriginal, REGISTERED_EVENTS, isOurHookCommand, ourCommandBins, cliBinResolvable, ourDirectScriptBins, wrappedOriginalCommand } from './chunk-5QRP3MVS.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
|
|
15
|
-
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
16
|
-
import { sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, hookFiredMarkerPath, refreshCommand } from './chunk-BWQ66M6N.js';
|
|
17
|
-
import { deadHooksState, preparePackageManagerCommand, contextExcludesPresent } from './chunk-XCCLFVXM.js';
|
|
12
|
+
import { checkFormerSkillNames } from './chunk-IXYZUUYQ.js';
|
|
13
|
+
import { defaultFetch } from './chunk-FVMYKL6L.js';
|
|
14
|
+
import { resolveGatewayCredentials } from './chunk-NTRCK4NH.js';
|
|
18
15
|
import { findGitDirs } from './chunk-BJ3KTMDH.js';
|
|
16
|
+
import { hookCommandEscapesControlPlane, CONTROL_PLANE_DIR_VARIABLE } from './chunk-G2YNJIGF.js';
|
|
17
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
18
|
+
import { readDeliveryRecord, readDegraded, readSourceCache } from './chunk-YQR6E6OV.js';
|
|
19
|
+
import { deadHooksState, preparePackageManagerCommand } from './chunk-TUSYOL2O.js';
|
|
19
20
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
20
21
|
import { readFileSync, mkdirSync, writeFileSync, renameSync, existsSync, accessSync, constants, statSync, readdirSync, realpathSync } from 'fs';
|
|
21
22
|
import { join, dirname, resolve, delimiter } from 'path';
|
|
@@ -192,13 +193,15 @@ function runDoctor(env = {}) {
|
|
|
192
193
|
...starter?.checks ?? [],
|
|
193
194
|
...laptop ? checkRenamedSkills(env.cwd) : [],
|
|
194
195
|
...starter !== void 0 && !starter.mcpOutdated ? checkMcpCommand(env.cwd, env.processEnv) : [],
|
|
195
|
-
...checkContextSource(
|
|
196
|
+
...checkContextSource(env.cwd),
|
|
197
|
+
...checkGovernsList(env.cwd),
|
|
198
|
+
...checkControlPlaneHooks(env.cwd),
|
|
196
199
|
...checkInstalledCli(home, env.cwd ?? process.cwd())
|
|
197
200
|
];
|
|
198
201
|
}
|
|
199
202
|
function checkRenamedSkills(cwd) {
|
|
200
203
|
const dirs = findGitDirs(cwd ?? process.cwd());
|
|
201
|
-
if (dirs === void 0 || contextIsGoverned(dirs.
|
|
204
|
+
if (dirs === void 0 || contextIsGoverned(dirs.gitCommonDir)) return [];
|
|
202
205
|
return checkFormerSkillNames(dirs.repoRoot);
|
|
203
206
|
}
|
|
204
207
|
function checkInstalledCli(home, cwd) {
|
|
@@ -275,11 +278,11 @@ function checkStatusline(home, now, cwd) {
|
|
|
275
278
|
name,
|
|
276
279
|
status: "warn",
|
|
277
280
|
detail: `the OuterLayer segment was installed (recorded ${record.updatedAt}) but the slot no longer holds it \u2014 settings were rewritten or reset${record.original !== void 0 ? `; it wrapped: ${record.original}` : ""}`,
|
|
278
|
-
fix:
|
|
281
|
+
fix: `Run \`${cliInvocation()} init\` to reinstall the segment.`
|
|
279
282
|
}];
|
|
280
283
|
}
|
|
281
284
|
return [
|
|
282
|
-
foreign !== void 0 ? { name, status: "warn", detail: `slot occupied by: ${foreign}`, fix:
|
|
285
|
+
foreign !== void 0 ? { name, status: "warn", detail: `slot occupied by: ${foreign}`, fix: `Run \`${cliInvocation()} init\` to add the OuterLayer segment (wraps the existing command, never replaces it).` } : { name, status: "warn", detail: "not installed", fix: `Run \`${cliInvocation()} init\`.` }
|
|
283
286
|
];
|
|
284
287
|
}
|
|
285
288
|
const checks = [
|
|
@@ -288,12 +291,12 @@ function checkStatusline(home, now, cwd) {
|
|
|
288
291
|
const stateName = "Status-line state";
|
|
289
292
|
const state = readStatuslineState(home);
|
|
290
293
|
if (!state) {
|
|
291
|
-
checks.push({ name: stateName, status: "warn", detail: "no state file \u2014 line runs degraded (session cost only)", fix:
|
|
294
|
+
checks.push({ name: stateName, status: "warn", detail: "no state file \u2014 line runs degraded (session cost only)", fix: `Start \`${cliInvocation()} daemon\` (it maintains this file).` });
|
|
292
295
|
return checks;
|
|
293
296
|
}
|
|
294
297
|
const age = now() - Date.parse(state.generatedAt);
|
|
295
298
|
if (!Number.isFinite(age) || age > STATE_FRESH_MS) {
|
|
296
|
-
checks.push({ name: stateName, status: "warn", detail: `state ${formatAgo(age)} \u2014 line runs degraded`, fix:
|
|
299
|
+
checks.push({ name: stateName, status: "warn", detail: `state ${formatAgo(age)} \u2014 line runs degraded`, fix: `Restart \`${cliInvocation()} daemon\`.` });
|
|
297
300
|
return checks;
|
|
298
301
|
}
|
|
299
302
|
checks.push({ name: stateName, status: "pass", detail: `fresh (${formatAgo(age)})` });
|
|
@@ -339,7 +342,7 @@ function checkTranscripts(transcripts, now) {
|
|
|
339
342
|
return { name: "Transcripts", status: "warn", detail: "no projects directory yet", fix: "Run a Claude Code session, then re-check." };
|
|
340
343
|
}
|
|
341
344
|
if (transcripts.count === 0) {
|
|
342
|
-
return { name: "Transcripts", status: "warn", detail: "0 transcripts found", fix:
|
|
345
|
+
return { name: "Transcripts", status: "warn", detail: "0 transcripts found", fix: `Run a Claude Code session, then run \`${cliInvocation()} doctor\` again.` };
|
|
343
346
|
}
|
|
344
347
|
const age = formatAgeH(now() - transcripts.newest);
|
|
345
348
|
return { name: "Transcripts", status: "pass", detail: `${transcripts.count} transcripts, newest ${age}` };
|
|
@@ -402,7 +405,7 @@ function checkHooksInstalled(home, cwd, firingFresh) {
|
|
|
402
405
|
name,
|
|
403
406
|
status: "fail",
|
|
404
407
|
detail: `hooks in ${path} run ${missing.join(", ")}, which no longer exists \u2014 no session is being captured`,
|
|
405
|
-
fix:
|
|
408
|
+
fix: `Run \`${cliInvocation()} init\` to reinstall.`
|
|
406
409
|
};
|
|
407
410
|
}
|
|
408
411
|
const unexecutable = ourDirectScriptBins(settings).filter((bin) => !isExecutable(bin));
|
|
@@ -411,13 +414,13 @@ function checkHooksInstalled(home, cwd, firingFresh) {
|
|
|
411
414
|
name,
|
|
412
415
|
status: "fail",
|
|
413
416
|
detail: `hooks in ${path} run ${unexecutable.join(", ")} directly, and it is not executable \u2014 every hook fails with "Permission denied" and no session is linked to its work item`,
|
|
414
|
-
fix:
|
|
417
|
+
fix: `Run \`${cliInvocation()} init\` to rewrite the hooks so they run through node.`
|
|
415
418
|
};
|
|
416
419
|
}
|
|
417
420
|
return { name, status: "pass", detail: `${installed.join(", ")} (${scope})` };
|
|
418
421
|
}
|
|
419
422
|
if (installed.length > 0) {
|
|
420
|
-
return { name, status: "warn", detail: `only ${installed.join(", ")} installed`, fix:
|
|
423
|
+
return { name, status: "warn", detail: `only ${installed.join(", ")} installed`, fix: `Run \`${cliInvocation()} init\` to (re)install all lifecycle hooks.` };
|
|
421
424
|
}
|
|
422
425
|
}
|
|
423
426
|
const manifest = readManifest(home);
|
|
@@ -428,13 +431,13 @@ function checkHooksInstalled(home, cwd, firingFresh) {
|
|
|
428
431
|
name,
|
|
429
432
|
status: "fail",
|
|
430
433
|
detail: `hooks were installed into ${recorded} (recorded ${record.updatedAt}) but the settings file no longer contains them \u2014 it was rewritten or reset`,
|
|
431
|
-
fix:
|
|
434
|
+
fix: `Run \`${cliInvocation()} init\` to reinstall.`
|
|
432
435
|
};
|
|
433
436
|
}
|
|
434
437
|
if (firingFresh) {
|
|
435
438
|
return { name, status: "pass", detail: "not in user/project settings, but hooks are firing \u2014 installed in another scope (managed settings?)" };
|
|
436
439
|
}
|
|
437
|
-
return { name, status: "fail", detail: "no OuterLayer hooks found", fix:
|
|
440
|
+
return { name, status: "fail", detail: "no OuterLayer hooks found", fix: `Run \`${cliInvocation()} init\`.` };
|
|
438
441
|
}
|
|
439
442
|
function checkWrappedHooks(home, cwd) {
|
|
440
443
|
const manifest = readManifest(home);
|
|
@@ -469,7 +472,7 @@ function checkWrappedHooks(home, cwd) {
|
|
|
469
472
|
name: "Wrapped hooks",
|
|
470
473
|
status: "warn",
|
|
471
474
|
detail: `recorded as wrapped but the settings no longer carry the wrapped form \u2014 ${missing.join("; ")}`,
|
|
472
|
-
fix:
|
|
475
|
+
fix: `Run \`${cliInvocation()} hooks wrap\` to re-wrap, or \`${cliInvocation()} hooks unwrap\` if the wrap is no longer wanted.`
|
|
473
476
|
};
|
|
474
477
|
}
|
|
475
478
|
function checkHooksFiring(transcripts, lastFired, now) {
|
|
@@ -488,7 +491,7 @@ function checkHooksFiring(transcripts, lastFired, now) {
|
|
|
488
491
|
name,
|
|
489
492
|
status: "fail",
|
|
490
493
|
detail: `sessions as recent as ${formatAgeH(now() - transcripts.newest)}, but no lifecycle hook has fired since ${formatAgeH(now() - lastFired)}`,
|
|
491
|
-
fix:
|
|
494
|
+
fix: `Hooks are configured but not running \u2014 run \`${cliInvocation()} init\` and check \`claude --debug\` hook output.`
|
|
492
495
|
};
|
|
493
496
|
}
|
|
494
497
|
return { name, status: "pass", detail: `last fired ${formatAgeH(now() - lastFired)}` };
|
|
@@ -504,7 +507,7 @@ function checkDeadHooksState(cwd) {
|
|
|
504
507
|
name,
|
|
505
508
|
status: "fail",
|
|
506
509
|
detail: `${sanitizeForContext(state.hooksDir)} could not be read (${state.unreadableError.code ?? state.unreadableError.message}) \u2014 git's hooks status is unknown, not confirmed healthy`,
|
|
507
|
-
fix:
|
|
510
|
+
fix: `Fix the directory's permissions so it can be listed, then re-run \`${cliInvocation()} doctor\`.`
|
|
508
511
|
}
|
|
509
512
|
];
|
|
510
513
|
}
|
|
@@ -536,15 +539,15 @@ function checkSpoolWritable(home) {
|
|
|
536
539
|
function checkLastSync(home, now) {
|
|
537
540
|
const name = "Cloud sync";
|
|
538
541
|
if (!existsSync(join(home, ".outerlayer", "config.json"))) {
|
|
539
|
-
return { name, status: "warn", detail: "not configured \u2014 sessions stay on this machine", fix:
|
|
542
|
+
return { name, status: "warn", detail: "not configured \u2014 sessions stay on this machine", fix: `Run \`${cliInvocation()} login\` to connect.` };
|
|
540
543
|
}
|
|
541
544
|
const health = assessSyncHealth(readSyncStatus(home), now(), SYNC_STALE_AFTER_MS);
|
|
542
545
|
const detail = [health.headline, ...health.details].join("; ");
|
|
543
546
|
if (health.level === "error") {
|
|
544
|
-
return { name, status: "fail", detail, fix:
|
|
547
|
+
return { name, status: "fail", detail, fix: `Check the destination and API key in ~/.outerlayer/config.json, then run \`${cliInvocation()} sync\` to see the full error.` };
|
|
545
548
|
}
|
|
546
549
|
if (health.level === "warn" || health.level === "unknown") {
|
|
547
|
-
return { name, status: "warn", detail, fix:
|
|
550
|
+
return { name, status: "warn", detail, fix: `Run \`${cliInvocation()} sync\` to confirm the connection works.` };
|
|
548
551
|
}
|
|
549
552
|
return { name, status: "pass", detail };
|
|
550
553
|
}
|
|
@@ -552,17 +555,17 @@ function checkDaemon(home) {
|
|
|
552
555
|
const pidfile = join(home, ".outerlayer", "daemon.pid");
|
|
553
556
|
const heartbeat = join(home, ".outerlayer", "daemon.heartbeat");
|
|
554
557
|
if (!existsSync(pidfile)) {
|
|
555
|
-
return { name: "Daemon running", status: "warn", detail: "not running", fix:
|
|
558
|
+
return { name: "Daemon running", status: "warn", detail: "not running", fix: `Start it with \`${cliInvocation()} daemon\` (or a login agent).` };
|
|
556
559
|
}
|
|
557
560
|
try {
|
|
558
561
|
const beatMs = statSync(heartbeat).mtimeMs;
|
|
559
562
|
const staleMin = (Date.now() - beatMs) / 6e4;
|
|
560
563
|
if (staleMin > 30) {
|
|
561
|
-
return { name: "Daemon running", status: "warn", detail: `heartbeat ${Math.round(staleMin)}m stale`, fix:
|
|
564
|
+
return { name: "Daemon running", status: "warn", detail: `heartbeat ${Math.round(staleMin)}m stale`, fix: `Restart \`${cliInvocation()} daemon\`.` };
|
|
562
565
|
}
|
|
563
566
|
return { name: "Daemon running", status: "pass", detail: "heartbeat fresh" };
|
|
564
567
|
} catch {
|
|
565
|
-
return { name: "Daemon running", status: "warn", detail: "pidfile present, no heartbeat", fix:
|
|
568
|
+
return { name: "Daemon running", status: "warn", detail: "pidfile present, no heartbeat", fix: `Restart \`${cliInvocation()} daemon\`.` };
|
|
566
569
|
}
|
|
567
570
|
}
|
|
568
571
|
function checkCleanupPeriod(home) {
|
|
@@ -580,11 +583,11 @@ function checkCleanupPeriod(home) {
|
|
|
580
583
|
name: "Retention (cleanupPeriodDays)",
|
|
581
584
|
status: "fail",
|
|
582
585
|
detail: "set to 0 \u2014 this DISABLES transcript persistence (upstream anthropics/claude-code#23710 and #59248)",
|
|
583
|
-
fix:
|
|
586
|
+
fix: `Remove cleanupPeriodDays or set it \u226514; run \`${cliInvocation()} daemon\` to mirror before deletion.`
|
|
584
587
|
};
|
|
585
588
|
}
|
|
586
589
|
if (days < 14) {
|
|
587
|
-
return { name: "Retention (cleanupPeriodDays)", status: "warn", detail: `${days}d \u2014 transcripts deleted quickly`, fix:
|
|
590
|
+
return { name: "Retention (cleanupPeriodDays)", status: "warn", detail: `${days}d \u2014 transcripts deleted quickly`, fix: `Run \`${cliInvocation()} daemon\` so raws are mirrored before cleanup.` };
|
|
588
591
|
}
|
|
589
592
|
return { name: "Retention (cleanupPeriodDays)", status: "pass", detail: `${days}d` };
|
|
590
593
|
}
|
|
@@ -606,7 +609,7 @@ function checkClaudeVersion(env) {
|
|
|
606
609
|
const parsed = version.match(/\d+\.\d+\.\d+/)?.[0];
|
|
607
610
|
if (!parsed) return { name: "Claude Code version", status: "warn", detail: `unrecognized: ${version}` };
|
|
608
611
|
if (compareVersions(parsed, SUPPORTED_VERSIONS.max) > 0) {
|
|
609
|
-
return { name: "Claude Code version", status: "
|
|
612
|
+
return { name: "Claude Code version", status: "pass", detail: `${parsed} (newer than ${SUPPORTED_VERSIONS.max}, the latest version this release was tested with)` };
|
|
610
613
|
}
|
|
611
614
|
if (compareVersions(parsed, SUPPORTED_VERSIONS.min) < 0) {
|
|
612
615
|
return { name: "Claude Code version", status: "warn", detail: `${parsed} is older than validated (${SUPPORTED_VERSIONS.min})` };
|
|
@@ -666,29 +669,96 @@ function defaultClaudeInstalls() {
|
|
|
666
669
|
function contextDegradedFix(kind) {
|
|
667
670
|
switch (kind) {
|
|
668
671
|
case "unreachable":
|
|
669
|
-
return
|
|
672
|
+
return `Check network/VPN access to the control plane, then start Claude Code with \`${cliInvocation()} claude\`.`;
|
|
670
673
|
case "no-access":
|
|
671
674
|
return "Check your git credentials (SSH key or token) and org/SSO access to the control plane, then retry.";
|
|
672
675
|
case "designation-unverified":
|
|
673
|
-
return
|
|
676
|
+
return `Check OuterLayer cloud connectivity/config (~/.outerlayer/config.json), then start Claude Code with \`${cliInvocation()} claude\`.`;
|
|
674
677
|
case "not-governed":
|
|
675
|
-
return "
|
|
678
|
+
return "A record from an earlier CLI. It is cleared the next time `outerlayer claude` asks which control plane governs this repository.";
|
|
676
679
|
case "adoption-conflict":
|
|
677
|
-
return "
|
|
680
|
+
return "A record from an earlier CLI. Committed AGENTS.md or .claude files no longer block the control plane, and the record is cleared the next time `outerlayer claude` asks which control plane governs this repository.";
|
|
678
681
|
case "conflict":
|
|
679
|
-
return
|
|
682
|
+
return `This record is stale: a gateway that stores the control plane never reports two. Start Claude Code with \`${cliInvocation()} claude\` to clear it.`;
|
|
680
683
|
}
|
|
681
684
|
}
|
|
682
|
-
function
|
|
683
|
-
const dir = cwd ?? process.cwd();
|
|
685
|
+
function checkGovernsList(cwd) {
|
|
684
686
|
let repoRoot;
|
|
685
|
-
let gitCommonDir;
|
|
686
687
|
try {
|
|
687
|
-
repoRoot = execFileSync("git", ["-C",
|
|
688
|
+
repoRoot = execFileSync("git", ["-C", cwd ?? process.cwd(), "rev-parse", "--show-toplevel"], {
|
|
688
689
|
encoding: "utf8",
|
|
689
690
|
stdio: ["ignore", "pipe", "ignore"],
|
|
690
691
|
timeout: 2e3
|
|
691
692
|
}).trim();
|
|
693
|
+
} catch {
|
|
694
|
+
return [];
|
|
695
|
+
}
|
|
696
|
+
let config;
|
|
697
|
+
try {
|
|
698
|
+
config = JSON.parse(readFileSync(join(repoRoot, ".outerlayer", "config.json"), "utf8"));
|
|
699
|
+
} catch {
|
|
700
|
+
return [];
|
|
701
|
+
}
|
|
702
|
+
if (typeof config !== "object" || config === null || !("governs" in config)) return [];
|
|
703
|
+
return [
|
|
704
|
+
{
|
|
705
|
+
name: "Governs list",
|
|
706
|
+
status: "warn",
|
|
707
|
+
detail: "`governs` in .outerlayer/config.json is ignored. A control plane governs every repository its factory links, so the list decides nothing.",
|
|
708
|
+
fix: "Delete `governs` from .outerlayer/config.json once every machine and runner host runs CLI 0.17.0 or later. Older CLIs still read it."
|
|
709
|
+
}
|
|
710
|
+
];
|
|
711
|
+
}
|
|
712
|
+
function hookCommandsOf(settings) {
|
|
713
|
+
const hooks = settings?.hooks;
|
|
714
|
+
if (typeof hooks !== "object" || hooks === null) return [];
|
|
715
|
+
const commands = [];
|
|
716
|
+
for (const groups of Object.values(hooks)) {
|
|
717
|
+
if (!Array.isArray(groups)) continue;
|
|
718
|
+
for (const group of groups) {
|
|
719
|
+
const entries = group?.hooks;
|
|
720
|
+
if (!Array.isArray(entries)) continue;
|
|
721
|
+
for (const entry of entries) {
|
|
722
|
+
const command = entry?.command;
|
|
723
|
+
if (typeof command === "string") commands.push(command);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return commands;
|
|
728
|
+
}
|
|
729
|
+
function checkControlPlaneHooks(cwd) {
|
|
730
|
+
let repoRoot;
|
|
731
|
+
try {
|
|
732
|
+
repoRoot = execFileSync("git", ["-C", cwd ?? process.cwd(), "rev-parse", "--show-toplevel"], {
|
|
733
|
+
encoding: "utf8",
|
|
734
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
735
|
+
timeout: 2e3
|
|
736
|
+
}).trim();
|
|
737
|
+
} catch {
|
|
738
|
+
return [];
|
|
739
|
+
}
|
|
740
|
+
if (!existsSync(join(repoRoot, ".outerlayer"))) return [];
|
|
741
|
+
let settings;
|
|
742
|
+
try {
|
|
743
|
+
settings = JSON.parse(readFileSync(join(repoRoot, ".claude", "settings.json"), "utf8"));
|
|
744
|
+
} catch {
|
|
745
|
+
return [];
|
|
746
|
+
}
|
|
747
|
+
const escaping = hookCommandsOf(settings).filter(hookCommandEscapesControlPlane);
|
|
748
|
+
if (escaping.length === 0) return [];
|
|
749
|
+
return [
|
|
750
|
+
{
|
|
751
|
+
name: "Control plane hook paths",
|
|
752
|
+
status: "warn",
|
|
753
|
+
detail: `${escaping.length === 1 ? "this hook command reaches" : "these hook commands reach"} a .claude directory by a path a governed build does not provide, so ${escaping.length === 1 ? "it fails" : "they fail"} there without a message: ${escaping.map((command) => `\`${command}\``).join(", ")}`,
|
|
754
|
+
fix: `Name the script as \`\${${CONTROL_PLANE_DIR_VARIABLE}:-$CLAUDE_PROJECT_DIR}/.claude/\u2026\`. A governed build sets ${CONTROL_PLANE_DIR_VARIABLE} to where it reads the control plane; a checkout that holds its own copy falls back to the project directory.`
|
|
755
|
+
}
|
|
756
|
+
];
|
|
757
|
+
}
|
|
758
|
+
function checkContextSource(cwd) {
|
|
759
|
+
const dir = cwd ?? process.cwd();
|
|
760
|
+
let gitCommonDir;
|
|
761
|
+
try {
|
|
692
762
|
gitCommonDir = execFileSync("git", ["-C", dir, "rev-parse", "--path-format=absolute", "--git-common-dir"], {
|
|
693
763
|
encoding: "utf8",
|
|
694
764
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -697,72 +767,31 @@ function checkContextSource(home, cwd) {
|
|
|
697
767
|
} catch {
|
|
698
768
|
return [];
|
|
699
769
|
}
|
|
700
|
-
if (!
|
|
701
|
-
const
|
|
702
|
-
const manifest = readContextManifest(gitCommonDir);
|
|
770
|
+
if (!gitCommonDir) return [];
|
|
771
|
+
const delivery = readDeliveryRecord(gitCommonDir);
|
|
703
772
|
const degraded = readDegraded(gitCommonDir);
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
if (!pin && !manifest && !degraded && !looksGoverned) return [];
|
|
773
|
+
const governed = readSourceCache(gitCommonDir)?.status === "governed";
|
|
774
|
+
if (!governed && delivery === void 0 && !degraded) return [];
|
|
707
775
|
const checks = [];
|
|
708
776
|
const name = "Context source";
|
|
709
|
-
if (
|
|
777
|
+
if (delivery !== void 0 && existsSync(delivery.dir)) {
|
|
778
|
+
checks.push({ name, status: degraded ? "warn" : "pass", detail: `control plane delivered at ${delivery.sha.slice(0, 7)}` });
|
|
779
|
+
} else if (governed) {
|
|
710
780
|
checks.push({
|
|
711
781
|
name,
|
|
712
782
|
status: "warn",
|
|
713
|
-
detail:
|
|
714
|
-
fix:
|
|
783
|
+
detail: delivery === void 0 ? "a control plane governs this repository, and no copy of it has been delivered to this machine" : `the delivered control plane is no longer at ${delivery.dir}`,
|
|
784
|
+
fix: `Start Claude Code with \`${cliInvocation()} claude\`.`
|
|
715
785
|
});
|
|
716
|
-
} else if (pin ?? manifest) {
|
|
717
|
-
const sha = (pin ?? manifest).sha;
|
|
718
|
-
checks.push({ name, status: degraded ? "warn" : "pass", detail: `materialized at ${sha.slice(0, 7)}` });
|
|
719
786
|
}
|
|
720
787
|
if (degraded) {
|
|
721
788
|
checks.push({
|
|
722
789
|
name: "Context source degradation",
|
|
723
|
-
status: degraded.kind === "
|
|
790
|
+
status: degraded.kind === "conflict" ? "fail" : "warn",
|
|
724
791
|
detail: degraded.message,
|
|
725
792
|
fix: contextDegradedFix(degraded.kind)
|
|
726
793
|
});
|
|
727
794
|
}
|
|
728
|
-
if ((pin || manifest) && !contextExcludesPresent(gitCommonDir)) {
|
|
729
|
-
checks.push({
|
|
730
|
-
name: "Context exclude block",
|
|
731
|
-
status: "warn",
|
|
732
|
-
detail: "materialized paths are not excluded in .git/info/exclude",
|
|
733
|
-
fix: "Run `outerlayer context materialize` to repair it."
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
if (pin && !readCloudConfig(home).url) {
|
|
737
|
-
checks.push({
|
|
738
|
-
name,
|
|
739
|
-
status: "warn",
|
|
740
|
-
detail: "a pin exists but OuterLayer cloud sync isn't configured \u2014 the designation cannot be confirmed",
|
|
741
|
-
fix: "Run `outerlayer login` to connect."
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
if (looksGoverned) {
|
|
745
|
-
let tracked = "";
|
|
746
|
-
try {
|
|
747
|
-
tracked = execFileSync("git", ["-C", repoRoot, "ls-files", "--", "AGENTS.md", ".claude", ".outerlayer"], {
|
|
748
|
-
encoding: "utf8",
|
|
749
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
750
|
-
timeout: 2e3
|
|
751
|
-
}).trim();
|
|
752
|
-
} catch {
|
|
753
|
-
tracked = "";
|
|
754
|
-
}
|
|
755
|
-
if (tracked) {
|
|
756
|
-
const paths = tracked.split("\n");
|
|
757
|
-
const sample = paths.slice(0, 3).join(", ") + (paths.length > 3 ? ", \u2026" : "");
|
|
758
|
-
checks.push({
|
|
759
|
-
name,
|
|
760
|
-
status: "fail",
|
|
761
|
-
detail: `committed context files shadow the control plane: ${sample}`,
|
|
762
|
-
fix: "Remove the committed AGENTS.md/.claude/.outerlayer files in a commit, then run `outerlayer context materialize`."
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
795
|
return checks;
|
|
767
796
|
}
|
|
768
797
|
var PROTECT_DEFAULT_BRANCH_DOCS = "https://docs.outerlayer.ai/github-app-and-build-tokens#protect-the-default-branch";
|
|
@@ -816,7 +845,7 @@ function githubAppRefusalCheck(err) {
|
|
|
816
845
|
if (err instanceof WorkCommandError && err.status === 403) {
|
|
817
846
|
return { name, status: "warn", detail: `the key cannot read the factory's repositories: ${message}`, fix: "Use a key that holds git.read." };
|
|
818
847
|
}
|
|
819
|
-
return { name, status: "warn", detail: `could not read the factory's repositories: ${message}`, fix:
|
|
848
|
+
return { name, status: "warn", detail: `could not read the factory's repositories: ${message}`, fix: `Run \`${cliInvocation()} doctor\` again; check the gateway URL in ~/.outerlayer/config.json.` };
|
|
820
849
|
}
|
|
821
850
|
function describeMissing(missing) {
|
|
822
851
|
const held = missing.granted === null ? "not granted" : `has ${sanitizeTerminal(missing.granted)}`;
|
|
@@ -877,8 +906,8 @@ function repositoryAccessCheck(access) {
|
|
|
877
906
|
return { name, status: "pass", detail: `every permission builds need is accepted; ${pullRequest}` };
|
|
878
907
|
}
|
|
879
908
|
var CREDENTIAL_CHECK_TIMEOUT_MS = 15e3;
|
|
880
|
-
var LOGIN_FIX =
|
|
881
|
-
var CONNECT_FIX =
|
|
909
|
+
var LOGIN_FIX = `Run \`${cliInvocation()} login\` to sign in again.`;
|
|
910
|
+
var CONNECT_FIX = `Run \`${cliInvocation()} connect\` to choose a factory for this repository.`;
|
|
882
911
|
var SETUP_PANEL_FIX = "Link the repository on the factory's setup panel in the dashboard.";
|
|
883
912
|
var MINT_KEY_FIX = "Mint a key for a factory that exists: dashboard \u2192 Settings \u2192 API keys.";
|
|
884
913
|
async function askGateway(fetchImpl, url, path, credential, appId) {
|
|
@@ -906,7 +935,7 @@ function refusalMessage(body) {
|
|
|
906
935
|
const message = body?.error?.message;
|
|
907
936
|
return typeof message === "string" ? sanitizeTerminal(message) : "";
|
|
908
937
|
}
|
|
909
|
-
var NETWORK_FIX =
|
|
938
|
+
var NETWORK_FIX = `Check the network and the gateway address, then run \`${cliInvocation()} doctor\` again.`;
|
|
910
939
|
var UPDATE_FIX = "Update the outerlayer CLI and the gateway to the same release.";
|
|
911
940
|
var skippedCheck = (name, detail, fix) => ({ name, status: "skipped", detail, ...fix ? { fix } : {} });
|
|
912
941
|
function withSkippedRest(first, reason) {
|
|
@@ -976,7 +1005,7 @@ async function loginChecks(fetchImpl, url, token, appId, local, inRepository) {
|
|
|
976
1005
|
return [login, factoryCheck, { name: "Repository", status: "pass", detail: `${shown} is linked to ${factorySlug(factory)}` }];
|
|
977
1006
|
}
|
|
978
1007
|
const elsewhere = factories.find((f) => f.id !== factory.id && f.linked === true);
|
|
979
|
-
const fix = elsewhere === void 0 ? SETUP_PANEL_FIX : `Run
|
|
1008
|
+
const fix = elsewhere === void 0 ? SETUP_PANEL_FIX : `Run \`${cliInvocation()} connect --factory ${factorySlug(elsewhere)}\` to use the factory this repository is linked to.`;
|
|
980
1009
|
return [login, factoryCheck, { name: "Repository", status: "warn", detail: `${shown} is not linked to ${factorySlug(factory)}`, fix }];
|
|
981
1010
|
}
|
|
982
1011
|
async function factoryKeyChecks(fetchImpl, url, key, appId, source, local) {
|
|
@@ -1074,7 +1103,7 @@ async function credentialChecks(options = {}) {
|
|
|
1074
1103
|
const resolved = resolveGatewayCredentials({ home: options.home, env, cwd });
|
|
1075
1104
|
if (resolved.credential === void 0 || resolved.url === void 0) {
|
|
1076
1105
|
const reason = resolved.credential === void 0 ? "no login and no factory key is saved" : "no gateway address is saved";
|
|
1077
|
-
return withSkippedRest(skippedCheck("Credential", reason,
|
|
1106
|
+
return withSkippedRest(skippedCheck("Credential", reason, `Run \`${cliInvocation()} login\` to sign in.`), "there is no credential to check");
|
|
1078
1107
|
}
|
|
1079
1108
|
const fetchImpl = options.fetchImpl ?? defaultFetch;
|
|
1080
1109
|
const local = resolveRepoIdentity(cwd).gitRepo;
|
|
@@ -1093,7 +1122,7 @@ async function governanceChecks(options = {}) {
|
|
|
1093
1122
|
const cwd = options.cwd ?? process.cwd();
|
|
1094
1123
|
const resolved = resolveGatewayCredentials({ home: options.home, env, cwd });
|
|
1095
1124
|
if (resolved.credential === void 0 || resolved.url === void 0) {
|
|
1096
|
-
return [skippedCheck(name, "there is no credential to ask with",
|
|
1125
|
+
return [skippedCheck(name, "there is no credential to ask with", `Run \`${cliInvocation()} login\` to sign in.`)];
|
|
1097
1126
|
}
|
|
1098
1127
|
const local = resolveRepoIdentity(cwd).gitRepo;
|
|
1099
1128
|
if (local === void 0) return [skippedCheck(name, "not inside a git repository with a remote")];
|
|
@@ -1103,7 +1132,7 @@ async function governanceChecks(options = {}) {
|
|
|
1103
1132
|
const unanswered = unansweredDetail(reply);
|
|
1104
1133
|
if (unanswered !== void 0 && !("failure" in reply) && reply.status === 503) {
|
|
1105
1134
|
const message = refusalMessage(reply.body);
|
|
1106
|
-
return [{ name, status: "warn", detail: message === "" ? unanswered : `governed, but ${message}`, fix:
|
|
1135
|
+
return [{ name, status: "warn", detail: message === "" ? unanswered : `governed, but ${message}`, fix: `Check that the GitHub App can read the control plane, then run \`${cliInvocation()} doctor\` again.` }];
|
|
1107
1136
|
}
|
|
1108
1137
|
if (unanswered !== void 0) return [{ name, status: "warn", detail: unanswered, fix: NETWORK_FIX }];
|
|
1109
1138
|
const { status, body } = reply;
|
|
@@ -1140,7 +1169,7 @@ function doctorExitCode(checks) {
|
|
|
1140
1169
|
|
|
1141
1170
|
// src/doctor-report.ts
|
|
1142
1171
|
async function gatherDoctorChecks() {
|
|
1143
|
-
const { defaultRunnerConfigPath, hasRunnerBlock, loadRunnerConfig, runnerVmOf } = await import('./config-
|
|
1172
|
+
const { defaultRunnerConfigPath, hasRunnerBlock, loadRunnerConfig, runnerVmOf } = await import('./config-CLSGABD5.js');
|
|
1144
1173
|
const configPath = defaultRunnerConfigPath();
|
|
1145
1174
|
const checks = runDoctor({ runnerHost: hasRunnerBlock(configPath) });
|
|
1146
1175
|
const credential = await credentialChecks();
|
|
@@ -1152,7 +1181,7 @@ async function gatherDoctorChecks() {
|
|
|
1152
1181
|
const { runnerVmCheck } = await import('./doctor-53F2PYY7.js');
|
|
1153
1182
|
checks.push(runnerVmCheck(configPath, { lima: realLima(), home: homeFromEnv(), instance: runnerVm.instance }));
|
|
1154
1183
|
} else if (hasRunnerBlock(configPath)) {
|
|
1155
|
-
const { runnerHostChecks } = await import('./doctor-
|
|
1184
|
+
const { runnerHostChecks } = await import('./doctor-23BBJWBX.js');
|
|
1156
1185
|
const hooks = (() => {
|
|
1157
1186
|
try {
|
|
1158
1187
|
return loadRunnerConfig(configPath).hooks;
|
|
@@ -1187,7 +1216,7 @@ async function gatherDoctorChecks() {
|
|
|
1187
1216
|
const { existsSync: existsSync3 } = await import('fs');
|
|
1188
1217
|
if (process.platform !== "linux" || !existsSync3("/run/systemd/system")) return void 0;
|
|
1189
1218
|
const { inspectService, realInspectProbes } = await import('./inspect-6UYAAXH7.js');
|
|
1190
|
-
const { DEFAULT_UNIT_NAME } = await import('./install-
|
|
1219
|
+
const { DEFAULT_UNIT_NAME } = await import('./install-4SEFIIW2.js');
|
|
1191
1220
|
const { dirname: dirname2 } = await import('path');
|
|
1192
1221
|
return inspectService(DEFAULT_UNIT_NAME, dirname2(configPath), realInspectProbes());
|
|
1193
1222
|
})();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { runnerCredentialProblem } from './chunk-
|
|
7
|
-
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-7YP7T6GV.js';
|
|
4
|
+
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-UVG35MWF.js';
|
|
5
|
+
import { MIN_ENGINE_MAJOR } from './chunk-7KSSBQTS.js';
|
|
6
|
+
import { runnerCredentialProblem } from './chunk-P53VEAOF.js';
|
|
7
|
+
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-N2PXGQRL.js';
|
|
8
8
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
9
9
|
import { dirname } from 'path';
|
|
10
10
|
|