@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,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
3
|
+
import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
|
|
4
4
|
import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
|
|
5
|
+
import { CONTROL_PLANE_DIR_VARIABLE } from './chunk-G2YNJIGF.js';
|
|
6
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
7
|
+
import { deadHooksState, huskyPrepareScript, preparePackageManagerCommand } from './chunk-TUSYOL2O.js';
|
|
5
8
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
9
|
import { readFileSync, mkdirSync, writeFileSync, renameSync, existsSync, statSync, appendFileSync, opendirSync, unlinkSync } from 'fs';
|
|
7
10
|
import { spawn, execFileSync } from 'child_process';
|
|
@@ -56,7 +59,7 @@ function assessSyncHealth(status, now = Date.now(), staleAfterMs = SYNC_STALE_AF
|
|
|
56
59
|
return {
|
|
57
60
|
level: "unknown",
|
|
58
61
|
headline: "no sync has run on this machine yet",
|
|
59
|
-
details: [
|
|
62
|
+
details: [`run \`${cliInvocation()} sync\` once to verify the connection`]
|
|
60
63
|
};
|
|
61
64
|
}
|
|
62
65
|
const host = status.url ? safeHost(status.url) : "the configured endpoint";
|
|
@@ -71,7 +74,7 @@ function assessSyncHealth(status, now = Date.now(), staleAfterMs = SYNC_STALE_AF
|
|
|
71
74
|
);
|
|
72
75
|
if (status.pending) details.push(`${status.pending} session(s) waiting to ship`);
|
|
73
76
|
if (status.held) details.push(`${status.held} transcript(s) held \u2014 their launch could not be determined`);
|
|
74
|
-
details.push(
|
|
77
|
+
details.push(`run \`${cliInvocation()} doctor\` for the full picture`);
|
|
75
78
|
return {
|
|
76
79
|
level: "error",
|
|
77
80
|
headline: `sync is FAILING \u2014 last attempt ${formatAgo(now - Date.parse(status.at))}`,
|
|
@@ -104,7 +107,7 @@ function assessSyncHealth(status, now = Date.now(), staleAfterMs = SYNC_STALE_AF
|
|
|
104
107
|
headline: `sync ran ${formatAgo(age)} but ${host} has never been reached`,
|
|
105
108
|
details: [
|
|
106
109
|
"every run so far had an empty queue, so the connection is unproven",
|
|
107
|
-
|
|
110
|
+
`run \`${cliInvocation()} sync --all\` to verify it`
|
|
108
111
|
]
|
|
109
112
|
};
|
|
110
113
|
}
|
|
@@ -388,7 +391,7 @@ function hookErrorsContext(home, writtenBytes, seenBytes) {
|
|
|
388
391
|
}
|
|
389
392
|
async function handleWorkLaunch(sessionId, home, env, spawnImpl = spawnDetached, cwd = process.cwd()) {
|
|
390
393
|
if (!sessionId || env.OUTERLAYER_WORK === void 0) return void 0;
|
|
391
|
-
const { parseWorkItemEnv, appendLaunchRecord } = await import('./work-launch-
|
|
394
|
+
const { parseWorkItemEnv, appendLaunchRecord } = await import('./work-launch-LEQ2MPM3.js');
|
|
392
395
|
const parsed = parseWorkItemEnv(env.OUTERLAYER_WORK);
|
|
393
396
|
if ("reason" in parsed) {
|
|
394
397
|
logHookError(home, new Error(`OUTERLAYER_WORK ignored: ${parsed.reason}`));
|
|
@@ -433,7 +436,7 @@ async function missingRenewalHookContext(home, cwd) {
|
|
|
433
436
|
const registeredIn = (settings) => (settings.hooks?.PostToolUse ?? []).some((block) => (block.hooks ?? []).some((h) => isOurHookCommand(h)));
|
|
434
437
|
const registered = userSettings !== null && registeredIn(userSettings) || projectSettings !== null && registeredIn(projectSettings);
|
|
435
438
|
if (registered) return void 0;
|
|
436
|
-
return
|
|
439
|
+
return `This install has no PostToolUse hook, so this session's work-item lease will never be renewed while it works and may be lost to another worker mid-session. Run \`${cliInvocation()} init\` to register it.`;
|
|
437
440
|
} catch {
|
|
438
441
|
return void 0;
|
|
439
442
|
}
|
|
@@ -454,7 +457,7 @@ async function maybeRenewWorkLease(event, sessionId, home = homeFromEnv(), env =
|
|
|
454
457
|
if (now - statSync(marker).mtimeMs < WORK_LEASE_RENEW_DEBOUNCE_MS) return;
|
|
455
458
|
} catch {
|
|
456
459
|
}
|
|
457
|
-
const { parseWorkItemEnv } = await import('./work-launch-
|
|
460
|
+
const { parseWorkItemEnv } = await import('./work-launch-LEQ2MPM3.js');
|
|
458
461
|
const parsed = parseWorkItemEnv(env.OUTERLAYER_WORK);
|
|
459
462
|
if ("reason" in parsed) return;
|
|
460
463
|
writeFileSync(marker, String(now));
|
|
@@ -470,7 +473,7 @@ async function handleWorkSessionEnd(event, sessionId, _home = homeFromEnv(), env
|
|
|
470
473
|
try {
|
|
471
474
|
if (event !== "SessionEnd") return;
|
|
472
475
|
if (!sessionId || env.OUTERLAYER_WORK === void 0) return;
|
|
473
|
-
const { parseWorkItemEnv } = await import('./work-launch-
|
|
476
|
+
const { parseWorkItemEnv } = await import('./work-launch-LEQ2MPM3.js');
|
|
474
477
|
const parsed = parseWorkItemEnv(env.OUTERLAYER_WORK);
|
|
475
478
|
if ("reason" in parsed) return;
|
|
476
479
|
spawnImpl(
|
|
@@ -487,7 +490,7 @@ function syncHealthContext(home) {
|
|
|
487
490
|
if (health.level !== "error") return null;
|
|
488
491
|
return [`OuterLayer sync is failing on this machine: ${health.headline}`, ...health.details.map((d) => ` - ${d}`)].join("\n");
|
|
489
492
|
}
|
|
490
|
-
var UNTRUSTED_STALE_CLI_CONTEXT =
|
|
493
|
+
var UNTRUSTED_STALE_CLI_CONTEXT = `The installed OuterLayer CLI appears stale relative to a checkout near your working directory; run \`${cliInvocation()} doctor\` for details.`;
|
|
491
494
|
function installedCliStalenessContext(home, cwd) {
|
|
492
495
|
const result = checkInstalledCliStaleness({ home, cwd });
|
|
493
496
|
if (result === null || !result.stale) return null;
|
|
@@ -499,15 +502,16 @@ function installedCliStalenessContext(home, cwd) {
|
|
|
499
502
|
return `The installed OuterLayer CLI (~/.outerlayer/cli) is behind the workspace build: installed ${installedLabel}, workspace ${workspaceLabel}.
|
|
500
503
|
${howToRefresh}`;
|
|
501
504
|
}
|
|
502
|
-
function writeSessionStartContext(event, home, cwd, write, extraParts = []) {
|
|
505
|
+
function writeSessionStartContext(event, home, cwd, write, systemMessage, extraParts = []) {
|
|
503
506
|
try {
|
|
504
507
|
if (event !== "SessionStart") return;
|
|
505
508
|
const parts = [syncHealthContext(home), installedCliStalenessContext(home, cwd), ...extraParts].filter(
|
|
506
509
|
(s) => s !== null
|
|
507
510
|
);
|
|
508
|
-
if (parts.length === 0) return;
|
|
511
|
+
if (parts.length === 0 && systemMessage === void 0) return;
|
|
509
512
|
write(
|
|
510
513
|
JSON.stringify({
|
|
514
|
+
...systemMessage === void 0 ? {} : { systemMessage },
|
|
511
515
|
hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: parts.join("\n\n") }
|
|
512
516
|
})
|
|
513
517
|
);
|
|
@@ -547,10 +551,10 @@ function deadHooksAutoHealContext(cwd, home) {
|
|
|
547
551
|
const hooksDirLabel = sanitizeForContext(state.hooksDir);
|
|
548
552
|
const script = huskyPrepareScript(state.repoRoot);
|
|
549
553
|
if (script === null) {
|
|
550
|
-
return `Git hooks are dead in this checkout (${hooksDirLabel} is missing or empty, via core.hooksPath) and package.json declares no husky prepare script to run automatically. Run
|
|
554
|
+
return `Git hooks are dead in this checkout (${hooksDirLabel} is missing or empty, via core.hooksPath) and package.json declares no husky prepare script to run automatically. Run \`${cliInvocation()} doctor\` for the fix.`;
|
|
551
555
|
}
|
|
552
556
|
if (recentHealFailure(home, state.repoRoot)) {
|
|
553
|
-
return `Git hooks are still dead in this checkout (${hooksDirLabel}) \u2014 a previous auto-heal attempt failed recently, so it will not retry yet. Run
|
|
557
|
+
return `Git hooks are still dead in this checkout (${hooksDirLabel}) \u2014 a previous auto-heal attempt failed recently, so it will not retry yet. Run \`${cliInvocation()} doctor\` for the fix.`;
|
|
554
558
|
}
|
|
555
559
|
const command = preparePackageManagerCommand(state.repoRoot);
|
|
556
560
|
const [bin, ...args] = command.split(" ");
|
|
@@ -563,12 +567,11 @@ function deadHooksAutoHealContext(cwd, home) {
|
|
|
563
567
|
const after = deadHooksState(state.repoRoot);
|
|
564
568
|
if (after.dead) {
|
|
565
569
|
markHealFailure(home, state.repoRoot);
|
|
566
|
-
return `OuterLayer ran \`${command}\` to regenerate dead git hooks, but ${hooksDirLabel} is still missing or empty afterward. Run
|
|
570
|
+
return `OuterLayer ran \`${command}\` to regenerate dead git hooks, but ${hooksDirLabel} is still missing or empty afterward. Run \`${cliInvocation()} doctor\` for the fix.`;
|
|
567
571
|
}
|
|
568
572
|
clearHealFailureMarker(home, state.repoRoot);
|
|
569
573
|
return null;
|
|
570
574
|
}
|
|
571
|
-
var PIN_FILENAME = ".outerlayer-pin.json";
|
|
572
575
|
function sourceCachePath(gitCommonDir) {
|
|
573
576
|
return join(gitCommonDir, "outerlayer", "source.json");
|
|
574
577
|
}
|
|
@@ -576,8 +579,8 @@ function contextPossiblyGoverned(cwd, home = homeFromEnv()) {
|
|
|
576
579
|
try {
|
|
577
580
|
const found = findGitDirs(cwd);
|
|
578
581
|
if (found === void 0) return false;
|
|
579
|
-
const {
|
|
580
|
-
if (existsSync(join(
|
|
582
|
+
const { gitCommonDir } = found;
|
|
583
|
+
if (existsSync(join(gitCommonDir, "outerlayer", "delivery.json"))) return true;
|
|
581
584
|
if (!existsSync(join(home, ".outerlayer", "config.json"))) return false;
|
|
582
585
|
let cache;
|
|
583
586
|
try {
|
|
@@ -594,6 +597,73 @@ function contextPossiblyGoverned(cwd, home = homeFromEnv()) {
|
|
|
594
597
|
return false;
|
|
595
598
|
}
|
|
596
599
|
}
|
|
600
|
+
function recordDeliveredContext(cwd, sessionId, home) {
|
|
601
|
+
const dirs = findGitDirs(cwd);
|
|
602
|
+
if (dirs === void 0) return;
|
|
603
|
+
let record;
|
|
604
|
+
try {
|
|
605
|
+
record = JSON.parse(readFileSync(join(dirs.gitCommonDir, "outerlayer", "delivery.json"), "utf8"));
|
|
606
|
+
} catch {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (typeof record.repository !== "string" || typeof record.sha !== "string") return;
|
|
610
|
+
appendContextProvenance(
|
|
611
|
+
{
|
|
612
|
+
t: (/* @__PURE__ */ new Date()).toISOString(),
|
|
613
|
+
sessionId,
|
|
614
|
+
repoRoot: dirs.repoRoot,
|
|
615
|
+
repository: record.repository,
|
|
616
|
+
...typeof record.ref === "string" ? { ref: record.ref } : {},
|
|
617
|
+
sha: record.sha,
|
|
618
|
+
verification: "verified"
|
|
619
|
+
},
|
|
620
|
+
home
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
async function missingControlPlane(cwd, sessionId, home, env) {
|
|
624
|
+
const dirs = findGitDirs(cwd);
|
|
625
|
+
if (dirs === void 0) return void 0;
|
|
626
|
+
if (existsSync(join(dirs.gitCommonDir, "outerlayer", "materialized.json")) || hasExcludeBlock(dirs.gitCommonDir)) {
|
|
627
|
+
const { cleanupEarlierCopies } = await import('./context-cleanup-HSVYDGMI.js');
|
|
628
|
+
cleanupEarlierCopies(dirs);
|
|
629
|
+
}
|
|
630
|
+
if (!contextPossiblyGoverned(cwd, home)) return void 0;
|
|
631
|
+
const { governanceOf } = await import('./control-plane-launch-NYVDJESK.js');
|
|
632
|
+
if (await governanceOf({ cwd, env, home }) !== "governed") return void 0;
|
|
633
|
+
recordMissingContext(dirs, sessionId, home);
|
|
634
|
+
const launcher = `${cliInvocation()} claude`;
|
|
635
|
+
return {
|
|
636
|
+
person: `This repository's shared instructions and skills are missing from this session, because it did not start through \`${launcher}\`. Start Claude Code with \`${launcher}\`, or run \`${cliInvocation()} init\` once to make plain \`claude\` do the same.`,
|
|
637
|
+
agent: `This repository is governed by a control plane, and this session did not start through \`${launcher}\`, so the control plane's shared instructions and skills are not loaded. Tell the person to start Claude Code with \`${launcher}\`.`
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
function recordMissingContext(dirs, sessionId, home) {
|
|
641
|
+
let cache;
|
|
642
|
+
try {
|
|
643
|
+
cache = JSON.parse(readFileSync(sourceCachePath(dirs.gitCommonDir), "utf8"));
|
|
644
|
+
} catch {
|
|
645
|
+
cache = {};
|
|
646
|
+
}
|
|
647
|
+
appendContextProvenance(
|
|
648
|
+
{
|
|
649
|
+
t: (/* @__PURE__ */ new Date()).toISOString(),
|
|
650
|
+
sessionId,
|
|
651
|
+
repoRoot: dirs.repoRoot,
|
|
652
|
+
...typeof cache.repository === "string" ? { repository: cache.repository } : {},
|
|
653
|
+
...typeof cache.ref === "string" ? { ref: cache.ref } : {},
|
|
654
|
+
sha: null,
|
|
655
|
+
verification: "none"
|
|
656
|
+
},
|
|
657
|
+
home
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
function hasExcludeBlock(gitCommonDir) {
|
|
661
|
+
try {
|
|
662
|
+
return readFileSync(join(gitCommonDir, "info", "exclude"), "utf8").includes("# BEGIN outerlayer context materialization");
|
|
663
|
+
} catch {
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
597
667
|
async function runHookFast(event, home = homeFromEnv(), read = readStdin, env = process.env, spawnImpl = spawnDetached) {
|
|
598
668
|
try {
|
|
599
669
|
const stdin = read();
|
|
@@ -623,7 +693,7 @@ async function runHookFast(event, home = homeFromEnv(), read = readStdin, env =
|
|
|
623
693
|
const hookSessionId = typeof payload.session_id === "string" ? payload.session_id : void 0;
|
|
624
694
|
await maybeRenewWorkLease(resolvedEvent, hookSessionId, home, env, spawnImpl, Date.now(), sessionCwd);
|
|
625
695
|
await handleWorkSessionEnd(resolvedEvent, hookSessionId, home, env, spawnImpl, sessionCwd);
|
|
626
|
-
let
|
|
696
|
+
let missingPlane;
|
|
627
697
|
let deadHooksMessage;
|
|
628
698
|
let workLaunchMessage;
|
|
629
699
|
let hookErrorsMessage;
|
|
@@ -632,12 +702,15 @@ async function runHookFast(event, home = homeFromEnv(), read = readStdin, env =
|
|
|
632
702
|
const hookErrorsBytes = fileSizeBytes(join(dir, "hook-errors.log"));
|
|
633
703
|
const hookErrorsSeen = hookErrorsSeenBytes(home);
|
|
634
704
|
recordHookErrorsSeen(home, hookErrorsBytes);
|
|
635
|
-
if (
|
|
705
|
+
if (env[CONTROL_PLANE_DIR_VARIABLE] !== void 0) {
|
|
706
|
+
try {
|
|
707
|
+
recordDeliveredContext(sessionCwd, typeof payload.session_id === "string" ? payload.session_id : "unknown", home);
|
|
708
|
+
} catch (err) {
|
|
709
|
+
logHookError(home, err);
|
|
710
|
+
}
|
|
711
|
+
} else {
|
|
636
712
|
try {
|
|
637
|
-
|
|
638
|
-
const sessionId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
|
|
639
|
-
const result = await materialize({ cwd: sessionCwd, sessionId, home });
|
|
640
|
-
materializeMessage = result.message;
|
|
713
|
+
missingPlane = await missingControlPlane(sessionCwd, typeof payload.session_id === "string" ? payload.session_id : "unknown", home, env);
|
|
641
714
|
} catch (err) {
|
|
642
715
|
logHookError(home, err);
|
|
643
716
|
}
|
|
@@ -665,7 +738,8 @@ async function runHookFast(event, home = homeFromEnv(), read = readStdin, env =
|
|
|
665
738
|
home,
|
|
666
739
|
sessionCwd,
|
|
667
740
|
(out) => process.stdout.write(out),
|
|
668
|
-
|
|
741
|
+
missingPlane?.person,
|
|
742
|
+
[missingPlane?.agent, deadHooksMessage, workLaunchMessage, hookErrorsMessage, renewalHookMessage].filter(
|
|
669
743
|
(s) => s !== void 0
|
|
670
744
|
)
|
|
671
745
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { splitRawFile } from './chunk-
|
|
3
|
+
import { splitRawFile } from './chunk-WFSUUUAN.js';
|
|
4
4
|
import { resolvePackageVersion } from './chunk-RA3O54FC.js';
|
|
5
5
|
import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'fs';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
4
3
|
import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
|
|
4
|
+
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
5
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
5
6
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
7
|
|
|
7
8
|
createRequire(import.meta.url);
|
|
8
9
|
|
|
9
10
|
// src/credentials.ts
|
|
10
|
-
var MISSING_HELP =
|
|
11
|
-
var NO_FACTORY_MESSAGE =
|
|
11
|
+
var MISSING_HELP = `Run \`${cliInvocation()} login\` to sign in, or set OUTERLAYER_URL / OUTERLAYER_API_KEY / OUTERLAYER_APP_ID. Mint a key in the dashboard: Settings \u2192 API keys.`;
|
|
12
|
+
var NO_FACTORY_MESSAGE = `you are logged in, but no factory is chosen for this repository. Run \`${cliInvocation()} connect\` to choose one, or pass --app-id / set OUTERLAYER_APP_ID.`;
|
|
12
13
|
var NO_FACTORY_OUTSIDE_REPOSITORY_MESSAGE = "you are logged in, but this directory is not in a git repository, so no factory is chosen. Pass --app-id / set OUTERLAYER_APP_ID, or run this from inside a connected repository.";
|
|
13
14
|
var LOGIN_TOKEN_PREFIX = "olu_";
|
|
14
15
|
function unauthorizedMessage(credential) {
|
|
15
|
-
return credential.startsWith(LOGIN_TOKEN_PREFIX) ?
|
|
16
|
+
return credential.startsWith(LOGIN_TOKEN_PREFIX) ? `not authorized \u2014 the login is expired or was revoked. Run \`${cliInvocation()} login\` to sign in again.` : "not authorized \u2014 the API key is unknown, expired, or bound to a different factory. Mint a fresh key: dashboard \u2192 Settings \u2192 API keys.";
|
|
16
17
|
}
|
|
17
18
|
function resolveGatewayCredentials(sources = {}) {
|
|
18
19
|
const env = sources.env ?? process.env;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { MAX_ALLOW_HOSTS, allowHostProblem } from './chunk-UXYLWVTQ.js';
|
|
4
4
|
import { parseSize } from './chunk-7RQ73DLO.js';
|
|
5
|
-
import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-4Q7OMKAT.js';
|
|
6
5
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
|
+
import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-BQXFBI7T.js';
|
|
7
7
|
import { existsSync, statSync, accessSync, constants, readFileSync } from 'fs';
|
|
8
8
|
import { hostname } from 'os';
|
|
9
9
|
import { join } from 'path';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { builtinKind } from './chunk-
|
|
3
|
+
import { builtinKind } from './chunk-P53VEAOF.js';
|
|
4
4
|
import { parseSize } from './chunk-7RQ73DLO.js';
|
|
5
|
-
import { runnerDir } from './chunk-
|
|
5
|
+
import { runnerDir } from './chunk-N2PXGQRL.js';
|
|
6
6
|
import { dirname } from 'path';
|
|
7
7
|
import { spawnSync } from 'child_process';
|
|
8
8
|
|