@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,23 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
3
|
+
import { uploadSpooledSteps } from './chunk-KYS3TQAG.js';
|
|
4
|
+
import { LaunchFilter } from './chunk-ESVW4MJY.js';
|
|
4
5
|
import { RepoFilter } from './chunk-TBT347UY.js';
|
|
6
|
+
import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, acquireArtifactSpoolLock, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-G3IJ3N6F.js';
|
|
7
|
+
import { writeSyncStatus, spoolDir } from './chunk-NFIR3GEE.js';
|
|
5
8
|
import { hookExecSpoolPath } from './chunk-F7CU5ABH.js';
|
|
6
9
|
import { applyReportedCost } from './chunk-BKO6JEZI.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
10
|
+
import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-QNLX477Q.js';
|
|
11
|
+
import { C } from './chunk-ANPNT6PM.js';
|
|
12
|
+
import { readLaunchSpoolState, launchStatusIsDecisive, launchedItemsBySession, launchesPath } from './chunk-T2Q7ISPE.js';
|
|
13
|
+
import { defaultFetch } from './chunk-FVMYKL6L.js';
|
|
14
|
+
import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-NTRCK4NH.js';
|
|
11
15
|
import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
|
|
12
|
-
import { defaultFetch } from './chunk-YO4PSLVB.js';
|
|
13
|
-
import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-PLMTLGYH.js';
|
|
14
|
-
import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-J5M7BSJQ.js';
|
|
15
|
-
import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-EABW6AJQ.js';
|
|
16
|
-
import { signerFor, signRunnerRequest } from './chunk-V7NIVOFD.js';
|
|
17
|
-
import { writeSyncStatus, spoolDir } from './chunk-BWQ66M6N.js';
|
|
18
|
-
import { removeJournalHooks } from './chunk-XCCLFVXM.js';
|
|
19
16
|
import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
|
|
17
|
+
import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-7VUK5RFS.js';
|
|
18
|
+
import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-EABW6AJQ.js';
|
|
19
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
20
|
+
import { removeJournalHooks } from './chunk-TUSYOL2O.js';
|
|
20
21
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
22
|
+
import { signerFor, signRunnerRequest } from './chunk-M2ZWWTWZ.js';
|
|
21
23
|
import { dirname, basename, join } from 'path';
|
|
22
24
|
import { statSync, readFileSync, readdirSync, mkdirSync, writeFileSync, renameSync, existsSync, rmSync } from 'fs';
|
|
23
25
|
import { execFileSync } from 'child_process';
|
|
@@ -668,7 +670,7 @@ var LiveUploader = class {
|
|
|
668
670
|
const credential = this.env.OUTERLAYER_API_KEY;
|
|
669
671
|
const appId = this.env.OUTERLAYER_APP_ID;
|
|
670
672
|
if (!url || !credential || !appId) {
|
|
671
|
-
this.warnOnce("incomplete", `live upload is idle: this build's environment lacks ${[!url && "OUTERLAYER_URL", !credential && "OUTERLAYER_API_KEY", !appId && "OUTERLAYER_APP_ID"].filter(Boolean).join(", ")}, so nothing streams until
|
|
673
|
+
this.warnOnce("incomplete", `live upload is idle: this build's environment lacks ${[!url && "OUTERLAYER_URL", !credential && "OUTERLAYER_API_KEY", !appId && "OUTERLAYER_APP_ID"].filter(Boolean).join(", ")}, so nothing streams until \`${cliInvocation()} sync\` runs.
|
|
672
674
|
`);
|
|
673
675
|
return false;
|
|
674
676
|
}
|
|
@@ -724,7 +726,7 @@ var LiveUploader = class {
|
|
|
724
726
|
this.stopped = true;
|
|
725
727
|
this.onUnauthorized?.();
|
|
726
728
|
this.stderr(
|
|
727
|
-
destination.credential.startsWith("olu_") ? `live upload stopped: the login was refused (expired or revoked). No session streams from this daemon until you run
|
|
729
|
+
destination.credential.startsWith("olu_") ? `live upload stopped: the login was refused (expired or revoked). No session streams from this daemon until you run \`${cliInvocation()} login\` and it restarts.
|
|
728
730
|
` : `live upload stopped: the API key was refused. No session streams from this daemon until it restarts with a valid key.
|
|
729
731
|
`
|
|
730
732
|
);
|
|
@@ -739,7 +741,7 @@ var LiveUploader = class {
|
|
|
739
741
|
lastError: reason,
|
|
740
742
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
741
743
|
});
|
|
742
|
-
this.stderr(`live upload stopped for session ${prepared.id}: ${reason}. The next
|
|
744
|
+
this.stderr(`live upload stopped for session ${prepared.id}: ${reason}. The next \`${cliInvocation()} sync\` uploads it whole.
|
|
743
745
|
`);
|
|
744
746
|
return true;
|
|
745
747
|
}
|
|
@@ -1439,7 +1441,7 @@ async function runSyncInner(opts, stats) {
|
|
|
1439
1441
|
if (opts.quiet || shippedBatches === 0) return;
|
|
1440
1442
|
process.stderr.write(
|
|
1441
1443
|
`
|
|
1442
|
-
${C.yellow}!${C.reset} progress saved: ${synced} session(s) in ${shippedBatches}/${batches.length} batch(es) shipped before the failure \u2014 re-run ${C.dim}
|
|
1444
|
+
${C.yellow}!${C.reset} progress saved: ${synced} session(s) in ${shippedBatches}/${batches.length} batch(es) shipped before the failure \u2014 re-run ${C.dim}${cliInvocation()} sync${C.reset} to resume from there.
|
|
1443
1445
|
`
|
|
1444
1446
|
);
|
|
1445
1447
|
};
|
|
@@ -1796,6 +1798,29 @@ ${C.yellow}!${C.reset} batch ${shippedBatches + 1}/${batches.length} accounting
|
|
|
1796
1798
|
}
|
|
1797
1799
|
}
|
|
1798
1800
|
releaseArtifactLock();
|
|
1801
|
+
const stepPass = await uploadSpooledSteps({
|
|
1802
|
+
home,
|
|
1803
|
+
url,
|
|
1804
|
+
apiKey,
|
|
1805
|
+
appId,
|
|
1806
|
+
kind: resolved.kind,
|
|
1807
|
+
onlyItem: itemScope?.item,
|
|
1808
|
+
fetchImpl,
|
|
1809
|
+
quiet: opts.quiet,
|
|
1810
|
+
lockWaitMs: opts.artifactLockWaitMs
|
|
1811
|
+
});
|
|
1812
|
+
if (stepPass !== void 0) {
|
|
1813
|
+
if (stepPass.uploaded > 0) stats.contacted = true;
|
|
1814
|
+
if (!opts.quiet) {
|
|
1815
|
+
process.stderr.write(
|
|
1816
|
+
`${C.dim}steps${C.reset} ${stepPass.uploaded} uploaded \xB7 ${stepPass.pending} queued \xB7 ${stepPass.dropped} dropped
|
|
1817
|
+
`
|
|
1818
|
+
);
|
|
1819
|
+
}
|
|
1820
|
+
if (stepPass.unauthorized !== void 0) {
|
|
1821
|
+
throw new SyncTransportError(stepPass.unauthorized, 401);
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1799
1824
|
if (shippedBatches === batches.length && (opts.url || opts.apiKey || opts.appId)) {
|
|
1800
1825
|
if (isLoopbackUrl(url)) {
|
|
1801
1826
|
if (!opts.quiet) {
|
|
@@ -21728,12 +21728,13 @@ var UsageSchema = external_exports.looseObject({
|
|
|
21728
21728
|
* open string: the provider adds tiers over time. Absent means standard. */
|
|
21729
21729
|
speed: external_exports.string().min(1).max(SPEED_MAX_LENGTH).optional()
|
|
21730
21730
|
});
|
|
21731
|
-
var INPUT_BAND_BOUNDARIES = [128e3, 2e5, 256e3, 272e3, 512e3];
|
|
21731
|
+
var INPUT_BAND_BOUNDARIES = [1e5, 128e3, 2e5, 256e3, 272e3, 512e3];
|
|
21732
21732
|
function inputBandOf(totalInput) {
|
|
21733
21733
|
let band = 0;
|
|
21734
21734
|
for (const boundary of INPUT_BAND_BOUNDARIES) if (totalInput >= boundary) band = boundary;
|
|
21735
21735
|
return band;
|
|
21736
21736
|
}
|
|
21737
|
+
var BAND_BOUNDARIES_MAX = 64;
|
|
21737
21738
|
var TOKEN_BUCKETS_MAX = 1024;
|
|
21738
21739
|
var TokenBucketSchema = external_exports.looseObject({
|
|
21739
21740
|
model: external_exports.string().min(1).max(BUCKET_MODEL_MAX_LENGTH),
|
|
@@ -21950,7 +21951,12 @@ var AgentSessionSchema = external_exports.looseObject({
|
|
|
21950
21951
|
/** Token counts so far, per model, speed and input band. On a chunk part
|
|
21951
21952
|
* or a streamed piece these cover the whole session so far, never just
|
|
21952
21953
|
* the turns that payload carries. Absent from older writers. */
|
|
21953
|
-
buckets: external_exports.array(TokenBucketSchema).max(TOKEN_BUCKETS_MAX).optional()
|
|
21954
|
+
buckets: external_exports.array(TokenBucketSchema).max(TOKEN_BUCKETS_MAX).optional(),
|
|
21955
|
+
/** The input band boundaries `buckets` were grouped by. A price tier whose
|
|
21956
|
+
* threshold falls inside one of these bands cannot be applied from the
|
|
21957
|
+
* buckets alone. Absent from older writers, which used
|
|
21958
|
+
* {@link UNRECORDED_INPUT_BAND_BOUNDARIES}. */
|
|
21959
|
+
bandBoundaries: external_exports.array(count).max(BAND_BOUNDARIES_MAX).optional()
|
|
21954
21960
|
}),
|
|
21955
21961
|
/** Filled natively (`pr-link` lines, `git commit` tool results) or by later
|
|
21956
21962
|
* joins. A session can link MANY pull requests (stacked PRs, long-lived seat
|
|
@@ -22273,7 +22279,7 @@ var ArtifactTombstoneRecordSchema = external_exports.looseObject({
|
|
|
22273
22279
|
});
|
|
22274
22280
|
external_exports.union([ArtifactSpoolRecordSchema, ArtifactTombstoneRecordSchema]);
|
|
22275
22281
|
var EMITTED_RESULTS = ["pass", "fail"];
|
|
22276
|
-
var RESERVED_EMIT_NAMES = ["artifact", "criteria", "finding", "findings"];
|
|
22282
|
+
var RESERVED_EMIT_NAMES = ["artifact", "criteria", "finding", "findings", "step"];
|
|
22277
22283
|
var EmittedNameSchema = external_exports.string().regex(/^[a-z][a-z0-9._-]{0,63}$/).superRefine((name, ctx) => {
|
|
22278
22284
|
if (RESERVED_EMIT_NAMES.includes(name)) {
|
|
22279
22285
|
ctx.addIssue({
|
|
@@ -22318,6 +22324,19 @@ external_exports.object({
|
|
|
22318
22324
|
item: external_exports.object({ number: external_exports.number().int().positive() }).optional(),
|
|
22319
22325
|
sessionId: external_exports.string().optional()
|
|
22320
22326
|
}).superRefine((request, ctx) => refuseDuplicateIds(request.criteria, ctx));
|
|
22327
|
+
var STEP_NAME_MAX = 80;
|
|
22328
|
+
var CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/;
|
|
22329
|
+
var StepNameSchema = external_exports.string().trim().min(1, "name must not be empty").max(STEP_NAME_MAX, `name must be at most ${STEP_NAME_MAX} characters`).refine((name) => !CONTROL_CHARACTER.test(name), {
|
|
22330
|
+
message: "name must be one line, with no line break or control character"
|
|
22331
|
+
});
|
|
22332
|
+
var StepBodySchema = external_exports.object({
|
|
22333
|
+
/** Minted by the CLI once per step; the same id on the same item is the same step. */
|
|
22334
|
+
clientStepId: external_exports.string().uuid(),
|
|
22335
|
+
name: StepNameSchema,
|
|
22336
|
+
item: external_exports.object({ number: external_exports.number().int().positive() }),
|
|
22337
|
+
/** When the agent started the step. The gateway clamps it to the receive time. */
|
|
22338
|
+
startedAt: external_exports.string().datetime({ offset: true })
|
|
22339
|
+
});
|
|
22321
22340
|
var FINDING_CATEGORIES = ["context", "flaky-test", "tooling", "environment", "defect", "other"];
|
|
22322
22341
|
var FINDING_RULE_RELATIONS = ["wrong", "broken", "missing"];
|
|
22323
22342
|
var FINDING_ID_MAX_LENGTH = 64;
|
|
@@ -22525,4 +22544,4 @@ xmlchars/xmlns/1.0/ed3.js:
|
|
|
22525
22544
|
*)
|
|
22526
22545
|
*/
|
|
22527
22546
|
|
|
22528
|
-
export { ARTIFACT_KINDS, ARTIFACT_MAX_CAPTION_LENGTH, ARTIFACT_MAX_FILENAME_LENGTH, ARTIFACT_MAX_REPLACES_TARGETS, ArtifactCriterionIdSchema, ArtifactSpoolRecordSchema, ArtifactTombstoneRecordSchema, BUCKET_MODEL_MAX_LENGTH, CAPTURE_TIERS, CriteriaListSchema, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, EMITTED_RESULT_MAX_LINK_LENGTH, EVENT_TYPES, EmittedNameSchema, FindingBatchSchema, FindingsResponseSchema, RESERVED_EMIT_NAMES, SAME_PROBLEM_RULES, SCHEMA_VERSION, SPEED_MAX_LENGTH, bannedPathsForTier, bindTests, downconvertSession, inferArtifactKind, inputBandOf, isHumanUserTurn, mediaTypeForArtifactPath, parseAgentSession, parseJunit, parseTestSelector, turnCountBound };
|
|
22547
|
+
export { ARTIFACT_KINDS, ARTIFACT_MAX_CAPTION_LENGTH, ARTIFACT_MAX_FILENAME_LENGTH, ARTIFACT_MAX_REPLACES_TARGETS, ArtifactCriterionIdSchema, ArtifactSpoolRecordSchema, ArtifactTombstoneRecordSchema, BUCKET_MODEL_MAX_LENGTH, CAPTURE_TIERS, CriteriaListSchema, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, EMITTED_RESULT_MAX_LINK_LENGTH, EVENT_TYPES, EmittedNameSchema, FindingBatchSchema, FindingsResponseSchema, INPUT_BAND_BOUNDARIES, RESERVED_EMIT_NAMES, SAME_PROBLEM_RULES, SCHEMA_VERSION, SPEED_MAX_LENGTH, StepBodySchema, StepNameSchema, bannedPathsForTier, bindTests, downconvertSession, inferArtifactKind, inputBandOf, isHumanUserTurn, mediaTypeForArtifactPath, parseAgentSession, parseJunit, parseTestSelector, turnCountBound };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { DEFAULT_UNIT_NAME } from './chunk-
|
|
3
|
+
import { DEFAULT_UNIT_NAME } from './chunk-QEFKA2QD.js';
|
|
4
4
|
import { parseRunnerEnv } from './chunk-6MZSX4M7.js';
|
|
5
|
-
import { RUNNER_FILE_MODE } from './chunk-
|
|
5
|
+
import { RUNNER_FILE_MODE } from './chunk-N2PXGQRL.js';
|
|
6
6
|
import { existsSync, readFileSync, writeFileSync, renameSync, rmSync } from 'fs';
|
|
7
7
|
import { join, dirname } from 'path';
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-N2PXGQRL.js';
|
|
4
4
|
import { readlinkSync, realpathSync, mkdirSync, unlinkSync, symlinkSync, renameSync, readFileSync, writeFileSync, rmSync, existsSync, readdirSync } from 'fs';
|
|
5
5
|
import { join, basename, sep, resolve } from 'path';
|
|
6
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
3
4
|
|
|
4
5
|
createRequire(import.meta.url);
|
|
5
6
|
|
|
@@ -49,6 +50,6 @@ function warnDeprecated(message) {
|
|
|
49
50
|
process.stderr.write(`${C.yellow}!${C.reset} ${message}
|
|
50
51
|
`);
|
|
51
52
|
}
|
|
52
|
-
var API_KEY_FLAG_DEPRECATION =
|
|
53
|
+
var API_KEY_FLAG_DEPRECATION = `--api-key is deprecated: a key on the command line lands in shell history and process lists. Run \`${cliInvocation()} login\` once, or set OUTERLAYER_API_KEY.`;
|
|
53
54
|
|
|
54
55
|
export { API_KEY_FLAG_DEPRECATION, C, NO_COLOR_FLAG, stripNoColor, warnDeprecated };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { revokeTokenOnDashboard } from './chunk-
|
|
4
|
-
import { C } from './chunk-
|
|
5
|
-
import { readCloudConfig, writeCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
|
|
3
|
+
import { revokeTokenOnDashboard } from './chunk-GOSFARMS.js';
|
|
4
|
+
import { C } from './chunk-ANPNT6PM.js';
|
|
6
5
|
import { findGitDirs } from './chunk-BJ3KTMDH.js';
|
|
6
|
+
import { readCloudConfig, writeCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
|
|
7
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
7
8
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
8
9
|
import { generateKeyPairSync, privateDecrypt, constants, createPrivateKey } from 'crypto';
|
|
9
10
|
import { spawn } from 'child_process';
|
|
@@ -18,7 +19,7 @@ var LoginError = class extends Error {
|
|
|
18
19
|
};
|
|
19
20
|
function runLogin(opts) {
|
|
20
21
|
const apiKey = opts.apiKey.trim();
|
|
21
|
-
if (apiKey.length === 0) throw new LoginError(
|
|
22
|
+
if (apiKey.length === 0) throw new LoginError(`no API key given \u2014 pipe it on stdin, or run ${cliInvocation()} login with no key on stdin to sign in by browser`);
|
|
22
23
|
if (/\s/.test(apiKey)) throw new LoginError("the API key must be a single token with no spaces or line breaks");
|
|
23
24
|
const url = opts.url?.trim() || void 0;
|
|
24
25
|
const appId = opts.appId?.trim() || void 0;
|
|
@@ -229,7 +230,7 @@ function decryptToken(privateKeyPem, encryptedToken) {
|
|
|
229
230
|
Buffer.from(encryptedToken, "base64")
|
|
230
231
|
).toString("utf8");
|
|
231
232
|
} catch {
|
|
232
|
-
throw new LoginError(
|
|
233
|
+
throw new LoginError(`could not decrypt the token the dashboard sent; run ${cliInvocation()} login again`);
|
|
233
234
|
}
|
|
234
235
|
}
|
|
235
236
|
function normalizeDashboard(raw) {
|
|
@@ -246,7 +247,7 @@ function approveLink(dashboard, code) {
|
|
|
246
247
|
return `${dashboard}/cli/login?code=${encodeURIComponent(code)}`;
|
|
247
248
|
}
|
|
248
249
|
function waitingDocument(link, code, id) {
|
|
249
|
-
return JSON.stringify({ status: "waiting", url: link, code, check:
|
|
250
|
+
return JSON.stringify({ status: "waiting", url: link, code, check: `${cliInvocation()} login --check ${id}` }) + "\n";
|
|
250
251
|
}
|
|
251
252
|
async function finishApproved(flags, deps, home, dashboard, approved, privateKeyPem) {
|
|
252
253
|
const accountToken = decryptToken(privateKeyPem, approved.encryptedToken);
|
|
@@ -257,7 +258,7 @@ async function finishApproved(flags, deps, home, dashboard, approved, privateKey
|
|
|
257
258
|
const revoked = await revokeTokenOnDashboard(deps.fetchImpl, dashboard, accountToken);
|
|
258
259
|
return fail(
|
|
259
260
|
deps,
|
|
260
|
-
`could not save the login: ${err instanceof Error ? err.message : String(err)}. ` + (revoked === "revoked" ?
|
|
261
|
+
`could not save the login: ${err instanceof Error ? err.message : String(err)}. ` + (revoked === "revoked" ? `The token was revoked; run ${cliInvocation()} login again.` : "The token could not be revoked; revoke it on the CLI logins list at /profile/security.")
|
|
261
262
|
);
|
|
262
263
|
}
|
|
263
264
|
if (before.accountToken && before.accountToken !== accountToken) {
|
|
@@ -279,9 +280,12 @@ async function finishApproved(flags, deps, home, dashboard, approved, privateKey
|
|
|
279
280
|
}
|
|
280
281
|
function nextAfterLogin(cwd) {
|
|
281
282
|
const dirs = findGitDirs(cwd);
|
|
282
|
-
if (dirs === void 0) return
|
|
283
|
-
|
|
284
|
-
return
|
|
283
|
+
if (dirs === void 0) return `Next: in your repository, run \`${cliInvocation()} init --factory <org>/<factory>\`.
|
|
284
|
+
`;
|
|
285
|
+
if (existsSync(join(dirs.repoRoot, ".outerlayer"))) return `Next: run \`${cliInvocation()} connect\` to choose a factory.
|
|
286
|
+
`;
|
|
287
|
+
return `Next: run \`${cliInvocation()} init --factory <org>/<factory>\` to set up this repository.
|
|
288
|
+
`;
|
|
285
289
|
}
|
|
286
290
|
function fail(deps, message) {
|
|
287
291
|
deps.stderr.write(`${C.red}\u2717${C.reset} ${message}
|
|
@@ -301,10 +305,10 @@ async function runPastedKey(flags, deps, key, home) {
|
|
|
301
305
|
}
|
|
302
306
|
async function runCheck(flags, deps, home, id) {
|
|
303
307
|
const pending = readPending(home, id);
|
|
304
|
-
if (!pending) return fail(deps, `no pending login ${id}; run
|
|
308
|
+
if (!pending) return fail(deps, `no pending login ${id}; run ${cliInvocation()} login to start one`);
|
|
305
309
|
if (Date.parse(pending.expires_at) <= deps.now().getTime()) {
|
|
306
310
|
deletePending(home, id);
|
|
307
|
-
return fail(deps,
|
|
311
|
+
return fail(deps, `the login link expired; run ${cliInvocation()} login again`);
|
|
308
312
|
}
|
|
309
313
|
const result = await pollLogin(deps, pending.dashboard, pending.id);
|
|
310
314
|
switch (result.kind) {
|
|
@@ -317,7 +321,7 @@ async function runCheck(flags, deps, home, id) {
|
|
|
317
321
|
return fail(deps, "the login was denied");
|
|
318
322
|
case "expired":
|
|
319
323
|
deletePending(home, id);
|
|
320
|
-
return fail(deps,
|
|
324
|
+
return fail(deps, `the login link expired; run ${cliInvocation()} login again`);
|
|
321
325
|
case "unavailable":
|
|
322
326
|
deps.stderr.write(`could not check the login yet: ${result.message}
|
|
323
327
|
`);
|
|
@@ -376,7 +380,7 @@ Waiting for approval...
|
|
|
376
380
|
case "denied":
|
|
377
381
|
return fail(deps, "the login was denied");
|
|
378
382
|
case "expired":
|
|
379
|
-
return fail(deps,
|
|
383
|
+
return fail(deps, `the login link expired; run ${cliInvocation()} login again`);
|
|
380
384
|
case "unavailable":
|
|
381
385
|
case "error":
|
|
382
386
|
failures += 1;
|
|
@@ -392,7 +396,7 @@ Waiting for approval...
|
|
|
392
396
|
}
|
|
393
397
|
const untilExpiryMs = Math.max(0, expiresAt - deps.now().getTime());
|
|
394
398
|
await deps.sleep(Math.min(waitS * 1e3, untilExpiryMs));
|
|
395
|
-
if (deps.now().getTime() >= expiresAt) return fail(deps,
|
|
399
|
+
if (deps.now().getTime() >= expiresAt) return fail(deps, `the login link expired; run ${cliInvocation()} login again`);
|
|
396
400
|
}
|
|
397
401
|
}
|
|
398
402
|
async function runLoginCommand(flags, deps) {
|
|
@@ -414,7 +418,7 @@ async function runLoginCommand(flags, deps) {
|
|
|
414
418
|
return EXIT_USAGE;
|
|
415
419
|
}
|
|
416
420
|
if (flags.noInput) {
|
|
417
|
-
return fail(deps,
|
|
421
|
+
return fail(deps, `no API key on stdin and --no-input forbids prompting \u2014 pipe the key: echo "$KEY" | ${cliInvocation()} login`);
|
|
418
422
|
}
|
|
419
423
|
purgeExpiredPending(home, deps.now());
|
|
420
424
|
return await runBrowserLogin(flags, deps, home);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { authorEnvironment, withHooksPath } from './chunk-BYT5O5RV.js';
|
|
4
3
|
import { existsSync, unlinkSync, chmodSync } from 'fs';
|
|
5
4
|
import { request as request$1, createServer } from 'http';
|
|
6
5
|
import { request } from 'https';
|
|
@@ -345,6 +344,61 @@ async function startBuildServices(input) {
|
|
|
345
344
|
}
|
|
346
345
|
}
|
|
347
346
|
|
|
347
|
+
// src/runner/commit-identity.ts
|
|
348
|
+
var NOREPLY_SUFFIX = "@users.noreply.github.com";
|
|
349
|
+
var MAX_LENGTH = 200;
|
|
350
|
+
function parseIdentity(value) {
|
|
351
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
352
|
+
const { name, email } = value;
|
|
353
|
+
if (typeof name !== "string" || typeof email !== "string") return void 0;
|
|
354
|
+
if (name.trim() === "" || name.length > MAX_LENGTH || /[\r\n\0<>]/.test(name)) return void 0;
|
|
355
|
+
if (email.length > MAX_LENGTH || !email.endsWith(NOREPLY_SUFFIX) || /[\s\0<>]/.test(email) || email.length === NOREPLY_SUFFIX.length) return void 0;
|
|
356
|
+
return { name, email };
|
|
357
|
+
}
|
|
358
|
+
function parseClaimIdentity(data) {
|
|
359
|
+
const author = parseIdentity(data.commitAuthor);
|
|
360
|
+
if (author === void 0) return void 0;
|
|
361
|
+
const coAuthor = parseIdentity(data.coAuthor);
|
|
362
|
+
return coAuthor === void 0 ? { author } : { author, coAuthor };
|
|
363
|
+
}
|
|
364
|
+
function authorEnvironment(identity) {
|
|
365
|
+
if (identity === void 0) return {};
|
|
366
|
+
return {
|
|
367
|
+
GIT_AUTHOR_NAME: identity.name,
|
|
368
|
+
GIT_AUTHOR_EMAIL: identity.email,
|
|
369
|
+
GIT_COMMITTER_NAME: identity.name,
|
|
370
|
+
GIT_COMMITTER_EMAIL: identity.email
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function configCount(env) {
|
|
374
|
+
const raw = String(env.GIT_CONFIG_COUNT);
|
|
375
|
+
return /^[0-9]+$/.test(raw) ? Number(raw) : 0;
|
|
376
|
+
}
|
|
377
|
+
function withGitConfig(env, key, value) {
|
|
378
|
+
const at = configCount(env);
|
|
379
|
+
return {
|
|
380
|
+
...env,
|
|
381
|
+
GIT_CONFIG_COUNT: String(at + 1),
|
|
382
|
+
[`GIT_CONFIG_KEY_${at}`]: key,
|
|
383
|
+
[`GIT_CONFIG_VALUE_${at}`]: value
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function tokenHeader(token) {
|
|
387
|
+
return `Authorization: Basic ${Buffer.from(`x-access-token:${token}`).toString("base64")}`;
|
|
388
|
+
}
|
|
389
|
+
function withTokenHeader(env, url, token) {
|
|
390
|
+
return withGitConfig(env, `http.${url}.extraHeader`, tokenHeader(token));
|
|
391
|
+
}
|
|
392
|
+
function withHooksPath(env, dir) {
|
|
393
|
+
return withGitConfig(env, "core.hooksPath", dir);
|
|
394
|
+
}
|
|
395
|
+
function commitIdentityRecord(identity) {
|
|
396
|
+
return {
|
|
397
|
+
author: identity === void 0 ? "host" : "app",
|
|
398
|
+
coAuthor: identity?.coAuthor !== void 0 && identity.hooksPath !== void 0 ? "credited" : "none"
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
348
402
|
// src/runner/repositories.ts
|
|
349
403
|
function parseClaimedRepositories(value) {
|
|
350
404
|
if (!Array.isArray(value) || value.length === 0) return void 0;
|
|
@@ -372,10 +426,19 @@ function primaryOf(repositories) {
|
|
|
372
426
|
var RELAY_PORT = 3128;
|
|
373
427
|
var JOB_MOUNT = "/outerlayer/job";
|
|
374
428
|
var EVAL_INPUT_DIR = `${JOB_MOUNT}/eval-input`;
|
|
429
|
+
var BUILD_HOME = "/build/home";
|
|
375
430
|
var CHECKOUT_DIR = "/build/work/checkout";
|
|
376
431
|
var REPOS_DIR = "/build/work/repos";
|
|
377
432
|
function checkoutPath(entry) {
|
|
378
|
-
return entry.primary ? CHECKOUT_DIR :
|
|
433
|
+
return entry.primary ? CHECKOUT_DIR : repositoryPath(entry.repository);
|
|
434
|
+
}
|
|
435
|
+
function repositoryPath(repository) {
|
|
436
|
+
return `${REPOS_DIR}/${repository.toLowerCase()}`;
|
|
437
|
+
}
|
|
438
|
+
function lifecycleWorkdir(repositories, governingRepository) {
|
|
439
|
+
const governing = governingRepository?.toLowerCase();
|
|
440
|
+
const entry = governing === void 0 ? void 0 : repositories.find((candidate) => candidate.repository.toLowerCase() === governing);
|
|
441
|
+
return entry === void 0 ? CHECKOUT_DIR : checkoutPath(entry);
|
|
379
442
|
}
|
|
380
443
|
var MAX_HOSTS = 200;
|
|
381
444
|
function tokenVariables() {
|
|
@@ -404,10 +467,16 @@ function proxyEnvironment(proxyUrl, alsoNoProxy) {
|
|
|
404
467
|
YARN_HTTP_PROXY: proxyUrl
|
|
405
468
|
};
|
|
406
469
|
}
|
|
470
|
+
var PROXY_WARNING_FLAG = "--disable-warning=UNDICI-EHPA";
|
|
471
|
+
function withProxyWarningHidden(options) {
|
|
472
|
+
const given = options?.trim() ?? "";
|
|
473
|
+
if (given.split(/\s+/).includes(PROXY_WARNING_FLAG)) return given;
|
|
474
|
+
return given === "" ? PROXY_WARNING_FLAG : `${given} ${PROXY_WARNING_FLAG}`;
|
|
475
|
+
}
|
|
407
476
|
function runnerLiterals(repository, repositories = []) {
|
|
408
477
|
return {
|
|
409
478
|
OUTERLAYER_JOB_DIR: JOB_MOUNT,
|
|
410
|
-
HOME:
|
|
479
|
+
HOME: BUILD_HOME,
|
|
411
480
|
TMPDIR: "/tmp",
|
|
412
481
|
...proxyEnvironment(PROXY_URL),
|
|
413
482
|
GIT_TERMINAL_PROMPT: "0",
|
|
@@ -466,6 +535,11 @@ function buildEnvironment(input) {
|
|
|
466
535
|
passed[name] = value;
|
|
467
536
|
variables.push(name);
|
|
468
537
|
}
|
|
538
|
+
const nodeOptions = {};
|
|
539
|
+
if (input.imageEnv !== void 0) {
|
|
540
|
+
if (passed.NODE_OPTIONS !== void 0) passed.NODE_OPTIONS = withProxyWarningHidden(passed.NODE_OPTIONS);
|
|
541
|
+
else nodeOptions.NODE_OPTIONS = withProxyWarningHidden(recipe.NODE_OPTIONS ?? input.imageEnv.NODE_OPTIONS);
|
|
542
|
+
}
|
|
469
543
|
const destinations = destinationEnvironment(input.config.build?.destinations, containerLocalAddress);
|
|
470
544
|
const builtInLiterals = builtIns ? builtInEnvironment(containerBuiltInAddress, claudeCredential(input.hostEnv)) : {};
|
|
471
545
|
const hooksPath = input.identity?.hooksPath;
|
|
@@ -483,6 +557,7 @@ function buildEnvironment(input) {
|
|
|
483
557
|
return {
|
|
484
558
|
literals: {
|
|
485
559
|
...recipe,
|
|
560
|
+
...nodeOptions,
|
|
486
561
|
...destinations,
|
|
487
562
|
...runnerLiterals(input.repository, repositoriesOf({ repositories: input.repositories, repository: input.repository, branch: input.branch })),
|
|
488
563
|
...builtInLiterals,
|
|
@@ -502,7 +577,8 @@ function checkEnvironment(input) {
|
|
|
502
577
|
repository: input.repository,
|
|
503
578
|
hostEnv: input.hostEnv,
|
|
504
579
|
containerEnv: input.containerEnv,
|
|
505
|
-
builtIns: false
|
|
580
|
+
builtIns: false,
|
|
581
|
+
imageEnv: input.imageEnv
|
|
506
582
|
});
|
|
507
583
|
const withheld = /* @__PURE__ */ new Set(["OUTERLAYER_URL", "OUTERLAYER_API_KEY", ...CLAUDE_CREDENTIAL_VARIABLES]);
|
|
508
584
|
const literals = { OUTERLAYER_EVAL_INPUT: EVAL_INPUT_DIR };
|
|
@@ -544,4 +620,4 @@ function withTunnelRecord(environment, record, onlyWhenUsed = false) {
|
|
|
544
620
|
};
|
|
545
621
|
}
|
|
546
622
|
|
|
547
|
-
export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseClaimedRepositories, parseIsolation, primaryOf, proxyEnvironment, repositoriesOf, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
|
|
623
|
+
export { AGENT_CREDENTIAL_MISSING, BUILD_HOME, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, authorEnvironment, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, commitIdentityRecord, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, lifecycleWorkdir, parseClaimIdentity, parseClaimedRepositories, parseIsolation, primaryOf, proxyEnvironment, repositoriesOf, repositoryPath, resolveDestinations, sharedUserEnvironment, startBuildServices, tokenHeader, withGitConfig, withHooksPath, withProxyWarningHidden, withTokenHeader, withTunnelRecord };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { sanitizeTerminal } from './chunk-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { resolveGatewayCredentials } from './chunk-
|
|
7
|
-
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
3
|
+
import { sanitizeTerminal } from './chunk-G3IJ3N6F.js';
|
|
4
|
+
import { DEFAULT_DASHBOARD } from './chunk-BM63HB2M.js';
|
|
5
|
+
import { remoteLookupFailed } from './chunk-QNLX477Q.js';
|
|
6
|
+
import { resolveGatewayCredentials } from './chunk-NTRCK4NH.js';
|
|
8
7
|
import { writeRepoConnection, findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
|
|
8
|
+
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
9
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
9
10
|
import { execFileSync } from 'child_process';
|
|
10
11
|
import { createInterface } from 'readline/promises';
|
|
11
12
|
|
|
@@ -53,7 +54,7 @@ function notLinkedText(factoryName, repository, url) {
|
|
|
53
54
|
Link it on the factory's Work page: ${url}
|
|
54
55
|
1. Connect GitHub repository, and grant the App access to ${name}.
|
|
55
56
|
2. Link repository, and pick ${name} and its default branch.
|
|
56
|
-
Then run
|
|
57
|
+
Then run \`${cliInvocation()} connect\` again.
|
|
57
58
|
`;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -151,7 +152,7 @@ async function fetchFactories(fetchImpl, url, token, repository) {
|
|
|
151
152
|
return { ok: false, result: result(1, "failed", message, message) };
|
|
152
153
|
}
|
|
153
154
|
if (res.status === 401) {
|
|
154
|
-
const message =
|
|
155
|
+
const message = `the gateway refused the login. Run \`${cliInvocation()} login\` to sign in again.`;
|
|
155
156
|
return { ok: false, result: result(1, "failed", message, message) };
|
|
156
157
|
}
|
|
157
158
|
if (!res.ok) {
|
|
@@ -160,7 +161,7 @@ async function fetchFactories(fetchImpl, url, token, repository) {
|
|
|
160
161
|
}
|
|
161
162
|
const factories = parseFactories(await res.json().catch(() => null));
|
|
162
163
|
if (factories === void 0) {
|
|
163
|
-
const message = `${url} answered, but the reply is not a list of factories. Check the gateway address with
|
|
164
|
+
const message = `${url} answered, but the reply is not a list of factories. Check the gateway address with \`${cliInvocation()} doctor\`, then run \`${cliInvocation()} connect\` again.`;
|
|
164
165
|
return { ok: false, result: result(1, "failed", `${url} did not answer with a factory list`, message) };
|
|
165
166
|
}
|
|
166
167
|
return { ok: true, factories };
|
|
@@ -205,7 +206,7 @@ ${listText(factories, repository)}`;
|
|
|
205
206
|
if (!deps.isTerminal) {
|
|
206
207
|
const why = linked.length > 1 ? `${repository} is linked to more than one factory you can use` : `you can use more than one factory, and none is the only one ${repository} is linked to`;
|
|
207
208
|
const message = `${why}, and there is no terminal to ask on.
|
|
208
|
-
Run
|
|
209
|
+
Run \`${cliInvocation()} connect --factory <org>/<factory>\` with one of:
|
|
209
210
|
${listText(factories, repository)}`;
|
|
210
211
|
return result(1, "failed", "more than one factory fits; pass --factory", message);
|
|
211
212
|
}
|
|
@@ -226,18 +227,18 @@ ${listText(factories, repository)}`;
|
|
|
226
227
|
}))
|
|
227
228
|
});
|
|
228
229
|
const factory = pool.find((f) => f.id === picked);
|
|
229
|
-
if (!factory) return result(1, "failed", "no factory was chosen",
|
|
230
|
+
if (!factory) return result(1, "failed", "no factory was chosen", `no factory was chosen. Run \`${cliInvocation()} connect\` again, or pass --factory <org>/<factory>.`);
|
|
230
231
|
return { factory, reason: "prompt" };
|
|
231
232
|
}
|
|
232
233
|
async function runConnect(flags, deps) {
|
|
233
234
|
const creds = resolveGatewayCredentials({ home: deps.home, env: deps.env, cwd: deps.cwd });
|
|
234
235
|
if (creds.credential === void 0) {
|
|
235
|
-
const message =
|
|
236
|
-
return { ...result(1, "skipped",
|
|
236
|
+
const message = `no saved credential. Run \`${cliInvocation()} login\` to sign in, then run \`${cliInvocation()} connect\` again.`;
|
|
237
|
+
return { ...result(1, "skipped", `no credential; run \`${cliInvocation()} login\` first`, message), next: `Run \`${cliInvocation()} login\`, then \`${cliInvocation()} init\` again.` };
|
|
237
238
|
}
|
|
238
239
|
if (creds.kind === "key") {
|
|
239
240
|
if (flags.factory !== void 0 && flags.factory !== creds.appId) {
|
|
240
|
-
const message2 = `a factory key decides the factory${creds.appId ? ` (${creds.appId})` : ""}, so --factory ${flags.factory} cannot apply. Remove --factory, or sign in with
|
|
241
|
+
const message2 = `a factory key decides the factory${creds.appId ? ` (${creds.appId})` : ""}, so --factory ${flags.factory} cannot apply. Remove --factory, or sign in with \`${cliInvocation()} login\` and unset the key.`;
|
|
241
242
|
return result(1, "failed", "--factory names a factory other than the key's", message2);
|
|
242
243
|
}
|
|
243
244
|
const message = `Your factory key decides the factory${creds.appId ? ` (${creds.appId})` : ""}, so there is nothing to connect. No file was changed.`;
|
|
@@ -248,14 +249,14 @@ async function runConnect(flags, deps) {
|
|
|
248
249
|
}
|
|
249
250
|
const repository = deps.resolveRepository(deps.cwd);
|
|
250
251
|
if (repository === void 0 && remoteLookupFailed(deps.cwd)) {
|
|
251
|
-
const message =
|
|
252
|
+
const message = `git did not answer when asked for this repository's remote, so connect cannot tell which repository it is. Run \`git remote -v\` here, then run \`${cliInvocation()} connect\` again.`;
|
|
252
253
|
return result(1, "failed", "git could not read this repository's remote", message);
|
|
253
254
|
}
|
|
254
255
|
if (repository === void 0) {
|
|
255
|
-
return result(1, "skipped", "this repository has no git remote",
|
|
256
|
+
return result(1, "skipped", "this repository has no git remote", `this repository has no git remote, so connect cannot tell which repository it is. Add one (\`git remote add origin <url>\`), then run \`${cliInvocation()} connect\` again.`);
|
|
256
257
|
}
|
|
257
258
|
if (creds.url === void 0) {
|
|
258
|
-
const message =
|
|
259
|
+
const message = `no gateway address is saved. Run \`${cliInvocation()} login\` to sign in.`;
|
|
259
260
|
return result(1, "failed", message, message);
|
|
260
261
|
}
|
|
261
262
|
const listed = await fetchFactories(deps.fetchImpl, creds.url, creds.credential, repository);
|
|
@@ -285,7 +286,7 @@ async function runConnect(flags, deps) {
|
|
|
285
286
|
const linkUrl = workPageUrl(deps.home, factory.organization.name, factory.name);
|
|
286
287
|
return { ...result(EXIT_NOT_LINKED, "done", why, connected + notLinkedText(factory.displayName, repository, linkUrl)), ...chosen, linked, linkUrl };
|
|
287
288
|
}
|
|
288
|
-
const changeIt =
|
|
289
|
+
const changeIt = `Run \`${cliInvocation()} connect --factory <org>/<factory>\` to change it.`;
|
|
289
290
|
const text = linked === null ? `${connected}Could not check whether ${sanitizeTerminal(repository)} is linked to ${factory.displayName}.
|
|
290
291
|
${changeIt}` : connected + changeIt;
|
|
291
292
|
return { ...result(0, "done", why, text), ...chosen, linked };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
4
|
+
import { join, basename } from 'path';
|
|
5
|
+
|
|
6
|
+
createRequire(import.meta.url);
|
|
7
|
+
var BEGIN = "# BEGIN outerlayer claude";
|
|
8
|
+
var END = "# END outerlayer claude";
|
|
9
|
+
var SHELL_FUNCTION_LINE = 'claude() { outerlayer claude "$@"; }';
|
|
10
|
+
var STARTUP_FILES = { zsh: ".zshrc", bash: ".bashrc" };
|
|
11
|
+
function startupFileFor(home, shellPath) {
|
|
12
|
+
const name = STARTUP_FILES[basename(shellPath ?? "")];
|
|
13
|
+
return name === void 0 ? void 0 : join(home, name);
|
|
14
|
+
}
|
|
15
|
+
function blockLines() {
|
|
16
|
+
return [BEGIN, "# Added by `outerlayer init`. Remove this block, or run `outerlayer init --no-shell-function`, to undo it.", SHELL_FUNCTION_LINE, END];
|
|
17
|
+
}
|
|
18
|
+
function find(lines) {
|
|
19
|
+
let begin = -1;
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
if (lines[i] === BEGIN) begin = i;
|
|
22
|
+
else if (lines[i] === END && begin >= 0) return { begin, end: i };
|
|
23
|
+
}
|
|
24
|
+
return void 0;
|
|
25
|
+
}
|
|
26
|
+
function installShellFunction(input) {
|
|
27
|
+
const file = startupFileFor(input.home, input.shellPath);
|
|
28
|
+
if (file === void 0) return { status: "unsupported" };
|
|
29
|
+
const text = existsSync(file) ? readFileSync(file, "utf8") : "";
|
|
30
|
+
if (find(text.split("\n")) !== void 0) return { status: "unchanged", file };
|
|
31
|
+
const endsLine = text === "" || text.endsWith("\n");
|
|
32
|
+
writeFileSync(file, `${text}${endsLine ? "" : "\n"}
|
|
33
|
+
${blockLines().join("\n")}${endsLine ? "\n" : ""}`);
|
|
34
|
+
return { status: "added", file };
|
|
35
|
+
}
|
|
36
|
+
function removeShellFunction(input) {
|
|
37
|
+
const changed = [];
|
|
38
|
+
for (const name of Object.values(STARTUP_FILES)) {
|
|
39
|
+
const file = join(input.home, name);
|
|
40
|
+
if (!existsSync(file)) continue;
|
|
41
|
+
const lines = readFileSync(file, "utf8").split("\n");
|
|
42
|
+
const found = find(lines);
|
|
43
|
+
if (found === void 0) continue;
|
|
44
|
+
const from = found.begin > 0 && lines[found.begin - 1] === "" ? found.begin - 1 : found.begin;
|
|
45
|
+
lines.splice(from, found.end - from + 1);
|
|
46
|
+
writeFileSync(file, lines.join("\n"));
|
|
47
|
+
changed.push(file);
|
|
48
|
+
}
|
|
49
|
+
return changed;
|
|
50
|
+
}
|
|
51
|
+
function shellFunctionInstalled(input) {
|
|
52
|
+
const file = startupFileFor(input.home, input.shellPath);
|
|
53
|
+
return file !== void 0 && existsSync(file) && find(readFileSync(file, "utf8").split("\n")) !== void 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { SHELL_FUNCTION_LINE, installShellFunction, removeShellFunction, shellFunctionInstalled };
|