@glubean/cli 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +24 -0
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/commands/load.d.ts +65 -0
  5. package/dist/commands/load.d.ts.map +1 -0
  6. package/dist/commands/load.js +462 -0
  7. package/dist/commands/load.js.map +1 -0
  8. package/dist/commands/login.d.ts +14 -1
  9. package/dist/commands/login.d.ts.map +1 -1
  10. package/dist/commands/login.js +110 -49
  11. package/dist/commands/login.js.map +1 -1
  12. package/dist/commands/run.d.ts +14 -2
  13. package/dist/commands/run.d.ts.map +1 -1
  14. package/dist/commands/run.js +216 -122
  15. package/dist/commands/run.js.map +1 -1
  16. package/dist/lib/auth.d.ts +57 -0
  17. package/dist/lib/auth.d.ts.map +1 -1
  18. package/dist/lib/auth.js +134 -1
  19. package/dist/lib/auth.js.map +1 -1
  20. package/dist/lib/config.d.ts +17 -6
  21. package/dist/lib/config.d.ts.map +1 -1
  22. package/dist/lib/config.js +9 -2
  23. package/dist/lib/config.js.map +1 -1
  24. package/dist/lib/constants.d.ts +6 -1
  25. package/dist/lib/constants.d.ts.map +1 -1
  26. package/dist/lib/constants.js +6 -1
  27. package/dist/lib/constants.js.map +1 -1
  28. package/dist/lib/print-plan.d.ts.map +1 -1
  29. package/dist/lib/print-plan.js +4 -0
  30. package/dist/lib/print-plan.js.map +1 -1
  31. package/dist/lib/upload.d.ts +88 -10
  32. package/dist/lib/upload.d.ts.map +1 -1
  33. package/dist/lib/upload.js +117 -188
  34. package/dist/lib/upload.js.map +1 -1
  35. package/dist/main.d.ts.map +1 -1
  36. package/dist/main.js +57 -7
  37. package/dist/main.js.map +1 -1
  38. package/package.json +6 -6
  39. package/dist/lib/env.d.ts +0 -29
  40. package/dist/lib/env.d.ts.map +0 -1
  41. package/dist/lib/env.js +0 -59
  42. package/dist/lib/env.js.map +0 -1
@@ -0,0 +1,462 @@
1
+ /**
2
+ * `glubean load [target]` — run performance plans (M4-c).
3
+ *
4
+ * Discovers `loadRunner()` exports in `.load.ts` files, runs each through the
5
+ * closed-model orchestrator (`@glubean/runner` `runLoad`) IN A CHILD PROCESS,
6
+ * writes each finalized `LoadArtifact` to `.glubean/<runnerId>.load.result.json`,
7
+ * prints a per-plan summary, and exits non-zero if any plan's `summary.pass` is
8
+ * false (a crash or a breached threshold). This is the dedicated load path —
9
+ * separate from `glubean run` (the per-test ProjectRunner), since load's
10
+ * execution model differs.
11
+ *
12
+ * Each `.load.ts` runs via `runLoadFileInSubprocess`, which spawns the
13
+ * project-local runner harness (as `glubean run` does) so the harness and the
14
+ * user file co-resolve one `@glubean/sdk` — no split-brain when a globally
15
+ * installed CLI runs against a project with its own non-deduped sdk.
16
+ */
17
+ import { resolve, dirname } from "node:path";
18
+ import { randomUUID } from "node:crypto";
19
+ import { stat, readdir, writeFile, mkdir } from "node:fs/promises";
20
+ import { existsSync } from "node:fs";
21
+ import { glob } from "node:fs/promises";
22
+ import { loadProjectEnv, runLoadFileInSubprocess } from "@glubean/runner";
23
+ import { resolveEnvFileName } from "../lib/active_env.js";
24
+ import { findProjectConfig } from "./run.js";
25
+ const colors = {
26
+ reset: "\x1b[0m",
27
+ bold: "\x1b[1m",
28
+ dim: "\x1b[2m",
29
+ green: "\x1b[32m",
30
+ red: "\x1b[31m",
31
+ yellow: "\x1b[33m",
32
+ blue: "\x1b[34m",
33
+ cyan: "\x1b[36m",
34
+ };
35
+ // Mirror the run command's skip list (+ .glubean output) so a compiled `build/`
36
+ // dir isn't walked — otherwise a built `.load.js` could double-run a plan.
37
+ const SKIP_DIRS = new Set(["node_modules", ".git", "dist", "build", ".glubean"]);
38
+ // Directory/glob discovery matches SOURCE `.load.ts` only (like `glubean run`'s
39
+ // `.ts`-only discovery), so a compiled `.load.js`/`.mjs` alongside it isn't run
40
+ // twice. An explicit file target still runs whatever the user named.
41
+ function isLoadSourceFile(name) {
42
+ return name.endsWith(".load.ts");
43
+ }
44
+ /** A filesystem-safe result filename for a runner id. */
45
+ export function loadResultFileName(runnerId) {
46
+ const safe = runnerId.replace(/[^a-zA-Z0-9._-]/g, "_").replace(/^_+|_+$/g, "");
47
+ return `${safe || "load"}.load.result.json`;
48
+ }
49
+ /**
50
+ * Run each load file's plans in a CHILD PROCESS (`runLoadFileInSubprocess`) so the
51
+ * harness and the user file co-resolve one `@glubean/sdk`, and collect the
52
+ * artifacts. A single file's import failure (or a crash) is recorded as a per-file
53
+ * error and the rest still run — completed artifacts are never discarded because a
54
+ * LATER file is broken. The raw `{ vars, secrets }` flow to the child, which
55
+ * applies the process.env fallback. Free of fs writes / process exit / printing.
56
+ */
57
+ export async function runLoadFiles(files, opts) {
58
+ const outcomes = [];
59
+ const errors = [];
60
+ for (const file of files) {
61
+ const res = await runLoadFileInSubprocess(file, {
62
+ vars: opts.vars,
63
+ secrets: opts.secrets,
64
+ cwd: opts.cwd,
65
+ });
66
+ for (const o of res.outcomes)
67
+ outcomes.push({ file, runnerId: o.runnerId, artifact: o.artifact });
68
+ for (const e of res.errors)
69
+ errors.push({ file, message: e.message });
70
+ }
71
+ return { outcomes, errors };
72
+ }
73
+ /** Write each outcome's artifact to `<glubeanDir>/<runnerId>.load.result.json`,
74
+ * disambiguating ids that sanitize to the same filename so no artifact is lost. */
75
+ export async function writeLoadResults(outcomes, glubeanDir) {
76
+ await mkdir(glubeanDir, { recursive: true });
77
+ // Track collisions case-INSENSITIVELY: on macOS/Windows, "Checkout" and
78
+ // "checkout" are the same directory entry, so an exact-string check would let
79
+ // the second overwrite the first.
80
+ const used = new Set();
81
+ const written = [];
82
+ for (const o of outcomes) {
83
+ let name = loadResultFileName(o.runnerId);
84
+ if (used.has(name.toLowerCase())) {
85
+ // Ids collapsed to the same filename — append `-N` so both survive.
86
+ const base = name.replace(/\.load\.result\.json$/, "");
87
+ let n = 2;
88
+ while (used.has(`${base}-${n}.load.result.json`.toLowerCase()))
89
+ n += 1;
90
+ name = `${base}-${n}.load.result.json`;
91
+ }
92
+ used.add(name.toLowerCase());
93
+ const path = resolve(glubeanDir, name);
94
+ await writeFile(path, JSON.stringify(o.artifact, null, 2), "utf-8");
95
+ written.push(path);
96
+ }
97
+ return written;
98
+ }
99
+ /** Recursively collect `.load.ts` files under a directory. */
100
+ async function walkLoadFiles(dir, out) {
101
+ for (const entry of await readdir(dir, { withFileTypes: true })) {
102
+ if (entry.isDirectory()) {
103
+ if (!SKIP_DIRS.has(entry.name))
104
+ await walkLoadFiles(resolve(dir, entry.name), out);
105
+ }
106
+ else if (entry.isFile() && isLoadSourceFile(entry.name)) {
107
+ out.push(resolve(dir, entry.name));
108
+ }
109
+ }
110
+ }
111
+ /** Resolve a file / directory / glob target to a sorted, deduped `.load.ts` list. */
112
+ async function resolveLoadFiles(target) {
113
+ const abs = resolve(target);
114
+ try {
115
+ const s = await stat(abs);
116
+ if (s.isFile())
117
+ return [abs];
118
+ if (s.isDirectory()) {
119
+ const files = [];
120
+ await walkLoadFiles(abs, files);
121
+ files.sort();
122
+ return files;
123
+ }
124
+ }
125
+ catch {
126
+ // not a path — try glob below
127
+ }
128
+ const files = [];
129
+ for await (const entry of glob(target, { cwd: process.cwd() })) {
130
+ const full = resolve(process.cwd(), entry);
131
+ if (!isLoadSourceFile(full))
132
+ continue;
133
+ const s = await stat(full).catch(() => null);
134
+ if (s?.isFile())
135
+ files.push(full);
136
+ }
137
+ files.sort();
138
+ return [...new Set(files)];
139
+ }
140
+ function pct(fraction) {
141
+ return `${(fraction * 100).toFixed(2)}%`;
142
+ }
143
+ /** Print a one-plan summary line block. The top `iterations` line is the
144
+ * end-to-end (whole-transaction) view; when a scenario calls
145
+ * `ctx.report.primaryComplete()` the artifact also carries a primary/end-to-end
146
+ * phase split, surfaced as an extra line so an async-job run shows submit latency
147
+ * vs full latency. (Exported for display tests.) */
148
+ export function printOutcome(o) {
149
+ const s = o.artifact.summary;
150
+ const verdict = s.pass
151
+ ? `${colors.green}PASS${colors.reset}`
152
+ : `${colors.red}FAIL${colors.reset}`;
153
+ console.log(`${colors.bold}${o.runnerId}${colors.reset} ${verdict}`);
154
+ console.log(`${colors.dim} iterations ${s.totalIterations} (ok ${s.successfulIterations}, failed ${s.failedIterations})` +
155
+ ` errorRate ${pct(s.errorRate)} p95 ${Math.round(s.latency.p95)}ms` +
156
+ ` throughput ${s.throughputPerSec.toFixed(1)}/s${colors.reset}`);
157
+ // Phase split (M5): the line above is end-to-end; show the primary phase (up to
158
+ // the primaryComplete boundary). `completed/started` indicates primary coverage —
159
+ // when fewer iterations complete primary than started, some failed before the
160
+ // boundary (a branch/error path); precise boundary coverage lands with M6.
161
+ if (s.primary) {
162
+ console.log(`${colors.dim} primary (to boundary) p95 ${Math.round(s.primary.latency.p95)}ms` +
163
+ ` throughput ${s.primary.throughputPerSec.toFixed(1)}/s` +
164
+ ` completed ${s.primary.completed}/${s.primary.started}${colors.reset}`);
165
+ if (s.primary.completed < s.primary.started) {
166
+ console.log(`${colors.yellow} ⚠ ${s.primary.started - s.primary.completed} iteration(s) did not reach the primary boundary` +
167
+ ` (failed before it, or a branch skipped it)${colors.reset}`);
168
+ }
169
+ }
170
+ // Continuation / producer-release subsystem (M6): present once any iteration engaged
171
+ // release (released / rejected / duplicate / still pending). Show the slot model, how
172
+ // many slots were released, the backlog peak + back-pressure, then surface rejections,
173
+ // drain-timeout aborts, and coverage gaps as warnings.
174
+ const c = s.continuation;
175
+ if (c) {
176
+ console.log(`${colors.dim} continuation (${o.artifact.runtime.slotModel}) released ${c.releasedProducerSlots}` +
177
+ ` backlog max ${c.maxBacklog}` +
178
+ (c.backpressureMs ? ` backpressure p95 ${Math.round(c.backpressureMs.p95)}ms` : "") +
179
+ `${colors.reset}`);
180
+ if (c.rejectedReleaseSignals > 0) {
181
+ console.log(`${colors.yellow} ⚠ ${c.rejectedReleaseSignals} release(s) rejected (backlog full, drain bound, or run deadline)${colors.reset}`);
182
+ }
183
+ if (c.abortedByDrainTimeout > 0) {
184
+ console.log(`${colors.yellow} ⚠ ${c.abortedByDrainTimeout} continuation(s) aborted by the drain timeout` +
185
+ ` (still in flight at finalize)${colors.reset}`);
186
+ }
187
+ if (c.duplicateReleaseSignals > 0) {
188
+ console.log(`${colors.yellow} ⚠ ${c.duplicateReleaseSignals} duplicate release signal(s)` +
189
+ ` (one producer-release boundary per iteration)${colors.reset}`);
190
+ }
191
+ // Coverage gaps: only SOME iterations reached a primary boundary (a branch/error path
192
+ // skipped it), so the producer-release stats above reflect just that subset — warn,
193
+ // since `releaseCoverage` alone can read 100% while boundary coverage is partial.
194
+ if (c.primaryBoundaryCoverage < 1) {
195
+ console.log(`${colors.yellow} ⚠ only ${pct(c.primaryBoundaryCoverage)} of iterations reached a primary boundary` +
196
+ ` — producer-release stats cover that subset${colors.reset}`);
197
+ }
198
+ if (c.releaseCoverage < 1) {
199
+ console.log(`${colors.dim} release coverage ${pct(c.releaseCoverage)} of primary boundaries${colors.reset}`);
200
+ }
201
+ }
202
+ for (const t of s.thresholds) {
203
+ const mark = t.pass ? `${colors.green}✓${colors.reset}` : `${colors.red}✗${colors.reset}`;
204
+ const where = t.target ? `${t.scope}[${t.target}]` : t.scope;
205
+ console.log(`${colors.dim} ${mark} ${where}.${t.metric} ${t.expression} (actual ${t.actual})${colors.reset}`);
206
+ }
207
+ // Non-fatal run-shape advisories (M6-d), e.g. a long tail poll that held the producer
208
+ // slot with no release.
209
+ for (const a of s.advisories ?? []) {
210
+ console.log(`${colors.yellow} ⓘ ${a}${colors.reset}`);
211
+ }
212
+ }
213
+ /**
214
+ * Preflight the upload destination BEFORE running any load plan: resolve +
215
+ * validate token / project / target. On any failure this exits non-zero so a
216
+ * `--upload` typo fails fast instead of after a full (expensive) load run.
217
+ * Token format isn't pre-judged locally — the server validates it (a non-glb_
218
+ * token gets a 401 on the POST, surfaced as a failed receipt → non-zero exit).
219
+ */
220
+ async function resolveLoadUploadContext(rootDir, envFileVars, options) {
221
+ const { resolveToken, resolveProjectId, resolveApiUrl, resolveTargetId, resolveDefaultTargetId, checkUploadAuth, checkTargetInProject, } = await import("../lib/auth.js");
222
+ const { resolveRedactionConfig, loadProjectConfigV1, GlubeanConfigError } = await import("../lib/config.js");
223
+ const authOpts = {
224
+ token: options.token,
225
+ project: options.project,
226
+ target: options.target,
227
+ apiUrl: options.apiUrl,
228
+ };
229
+ const sources = { envFileVars };
230
+ const token = await resolveToken(authOpts, sources);
231
+ const projectId = await resolveProjectId(authOpts, sources);
232
+ const apiUrl = await resolveApiUrl(authOpts, sources);
233
+ if (!token) {
234
+ console.error(`${colors.red}Upload failed: no auth token found.${colors.reset}`);
235
+ console.error(`${colors.dim}Set GLUBEAN_TOKEN / --token (a glb_ project token), or add it to .env.secrets.${colors.reset}`);
236
+ process.exit(1);
237
+ }
238
+ if (!projectId) {
239
+ console.error(`${colors.red}Upload failed: no project ID.${colors.reset}`);
240
+ console.error(`${colors.dim}Use --project or set GLUBEAN_PROJECT_ID.${colors.reset}`);
241
+ process.exit(1);
242
+ }
243
+ // Validate auth/project FIRST (before the targets-read fallback) so an invalid
244
+ // token / mistyped project / unreachable server reports its real diagnostic
245
+ // instead of a misleading "could not resolve a target". 403 (least-privilege)
246
+ // proceeds; 401/404/5xx/unreachable is fatal BEFORE any load traffic.
247
+ const check = await checkUploadAuth(apiUrl, projectId, token);
248
+ if (!check.proceed) {
249
+ if (check.status === 401) {
250
+ console.error(`${colors.red}Upload failed: authentication failed (401).${colors.reset}`);
251
+ console.error(`${colors.dim}The token is invalid/expired or not a platform project token (glb_…). Create one in the dashboard (Project → Tokens).${colors.reset}`);
252
+ }
253
+ else if (check.status === 404) {
254
+ console.error(`${colors.red}Upload failed: project ${projectId} not found (404).${colors.reset}`);
255
+ console.error(`${colors.dim}Check --project / GLUBEAN_PROJECT_ID and --api-url / GLUBEAN_API_URL.${colors.reset}`);
256
+ }
257
+ else if (check.status === 403) {
258
+ console.error(`${colors.red}Upload failed: access to project ${projectId} is forbidden (403).${colors.reset}`);
259
+ console.error(`${colors.dim}The token's org has no access to this project (or its membership was revoked).${colors.reset}`);
260
+ }
261
+ else if (check.status === 0) {
262
+ console.error(`${colors.red}Upload failed: cannot reach server at ${apiUrl}.${colors.reset}`);
263
+ }
264
+ else {
265
+ console.error(`${colors.red}Upload failed: unexpected preflight response (${check.status}).${colors.reset}`);
266
+ console.error(`${colors.dim}Check that --api-url / GLUBEAN_API_URL points at the Glubean platform API.${colors.reset}`);
267
+ }
268
+ process.exit(1);
269
+ }
270
+ let targetId = await resolveTargetId(authOpts, sources);
271
+ if (targetId) {
272
+ // EXPLICIT target — validate it belongs to the project (a typo would
273
+ // otherwise 404 only on the POST, after the load plans ran).
274
+ const tcheck = await checkTargetInProject(apiUrl, projectId, targetId, token);
275
+ if (!tcheck.proceed) {
276
+ if (tcheck.status === 404) {
277
+ console.error(`${colors.red}Upload failed: target ${targetId} not found in project ${projectId} (404).${colors.reset}`);
278
+ console.error(`${colors.dim}Check GLUBEAN_TARGET_ID / --upload-target.${colors.reset}`);
279
+ }
280
+ else if (tcheck.status === 401) {
281
+ console.error(`${colors.red}Upload failed: authentication failed validating the target (401).${colors.reset}`);
282
+ }
283
+ else if (tcheck.status === 0) {
284
+ console.error(`${colors.red}Upload failed: cannot reach server at ${apiUrl}.${colors.reset}`);
285
+ }
286
+ else {
287
+ console.error(`${colors.red}Upload failed: could not validate target ${targetId} (${tcheck.status}).${colors.reset}`);
288
+ }
289
+ process.exit(1);
290
+ }
291
+ // 403 insufficient_scope (unverified) → no targets:read; can't validate, proceed.
292
+ }
293
+ else {
294
+ targetId = await resolveDefaultTargetId(apiUrl, projectId, token);
295
+ if (!targetId) {
296
+ console.error(`${colors.red}Upload failed: could not resolve a target for project ${projectId}.${colors.reset}`);
297
+ console.error(`${colors.dim}Set the target explicitly (GLUBEAN_TARGET_ID or --upload-target). Auto-resolving a non-default project's target needs a token with the targets:read scope.${colors.reset}`);
298
+ process.exit(1);
299
+ }
300
+ }
301
+ // Resolve redaction up front and FAIL CLOSED: a present-but-invalid glubean.yaml
302
+ // is fatal for upload — load artifacts (samples / failure traces) can carry
303
+ // secrets only the project's custom `defaults.redaction` rules cover, so we must
304
+ // never silently fall back to weaker baseline-only redaction. Absent glubean.yaml
305
+ // → baseline is correct (no custom rules declared).
306
+ let redaction = resolveRedactionConfig();
307
+ try {
308
+ const { config } = await loadProjectConfigV1(rootDir);
309
+ redaction = resolveRedactionConfig(config.defaults?.redaction);
310
+ }
311
+ catch (err) {
312
+ if (!(err instanceof GlubeanConfigError))
313
+ throw err;
314
+ if (!/not found/i.test(err.message)) {
315
+ console.error(`${colors.red}Upload failed: could not load glubean.yaml redaction config (${err.message.split("\n")[0]}).${colors.reset}`);
316
+ console.error(`${colors.dim}Fix glubean.yaml before --upload — load artifacts must not be uploaded with weaker baseline-only redaction.${colors.reset}`);
317
+ process.exit(1);
318
+ }
319
+ }
320
+ return { token, projectId, apiUrl, targetId, redaction };
321
+ }
322
+ async function uploadLoadOutcomes(outcomes, ctx) {
323
+ const { options } = ctx;
324
+ // Destination + redaction were resolved + validated in the preflight (before
325
+ // plans ran) — fail-fast and fail-closed; reuse them here.
326
+ const { token, projectId, apiUrl, targetId, redaction } = ctx.context;
327
+ const { uploadToCloud } = await import("../lib/upload.js");
328
+ const { redactValue } = await import("@glubean/redaction");
329
+ const receipts = [];
330
+ for (const o of outcomes) {
331
+ const a = o.artifact;
332
+ const redactedResult = redactValue(a, {
333
+ globalRules: redaction.globalRules,
334
+ replacementFormat: redaction.replacementFormat,
335
+ maxDepth: 64,
336
+ });
337
+ const input = {
338
+ kind: "load",
339
+ schemaVersion: a.schemaVersion,
340
+ // One idempotency id per load outcome (each loadRunner = its own run),
341
+ // reused across the upload retry so a lost-response retry replaces it (P1).
342
+ clientRunId: randomUUID(),
343
+ status: a.summary.pass ? "passed" : "failed",
344
+ startedAt: a.startedAt,
345
+ completedAt: new Date(Date.parse(a.startedAt) + a.durationMs).toISOString(),
346
+ durationMs: a.durationMs,
347
+ summary: {
348
+ throughputPerSec: a.summary.throughputPerSec,
349
+ errorRate: a.summary.errorRate,
350
+ },
351
+ result: redactedResult,
352
+ };
353
+ const receipt = await uploadToCloud(input, {
354
+ apiUrl,
355
+ token,
356
+ projectId,
357
+ targetId,
358
+ envFile: ctx.envFile,
359
+ rootDir: ctx.rootDir,
360
+ // The LoadArtifact is the result blob; don't attach .glubean test artifacts.
361
+ skipArtifacts: true,
362
+ });
363
+ receipts.push(receipt);
364
+ }
365
+ if (options.uploadReceiptJson) {
366
+ const receiptPath = resolve(process.cwd(), options.uploadReceiptJson);
367
+ await mkdir(dirname(receiptPath), { recursive: true });
368
+ await writeFile(receiptPath, JSON.stringify(receipts, null, 2) + "\n", "utf-8");
369
+ console.log(`${colors.dim}Upload receipt(s) written to: ${receiptPath}${colors.reset}`);
370
+ }
371
+ // A requested --upload where a plan's run POST was rejected is a failure, even
372
+ // on passing load runs — exit non-zero so CI doesn't read false-green. The
373
+ // receipts are written above first, so the failure is still recorded.
374
+ const failedUploads = receipts.filter((r) => r.resultUpload.status === "failed").length;
375
+ if (failedUploads > 0) {
376
+ console.error(`${colors.red}Upload failed: ${failedUploads} of ${receipts.length} load run(s) were not recorded in Cloud (see errors above).${colors.reset}`);
377
+ process.exit(1);
378
+ }
379
+ }
380
+ /**
381
+ * `glubean load [target]` — discover + run load plans under `target` (a file,
382
+ * directory, or glob; defaults to the cwd), write results, and exit non-zero if
383
+ * any plan fails.
384
+ */
385
+ export async function loadCommand(target, options = {}) {
386
+ console.log(`\n${colors.bold}${colors.blue}⚡ Glubean Load${colors.reset}\n`);
387
+ // --upload-receipt-json without --upload would silently write nothing — reject
388
+ // the combo up front (mirrors `glubean run`).
389
+ if (options.uploadReceiptJson && !options.upload) {
390
+ console.error(`${colors.red}Error: --upload-receipt-json requires --upload.${colors.reset}`);
391
+ process.exit(1);
392
+ }
393
+ const files = await resolveLoadFiles(target ?? process.cwd());
394
+ if (files.length === 0) {
395
+ console.log(`${colors.yellow}No .load.ts files found${target ? ` for "${target}"` : ` in ${process.cwd()}`}.${colors.reset}`);
396
+ process.exit(1);
397
+ }
398
+ // Derive the project root from the discovered file (not the shell cwd) so a
399
+ // targeted run outside cwd uses the load file's project for runner resolution /
400
+ // env / `.glubean` output.
401
+ const { rootDir } = await findProjectConfig(dirname(files[0]));
402
+ // An EXPLICIT --env-file that's missing is an error (mirrors `glubean run`) —
403
+ // silently running with empty env could send load to the wrong target / run
404
+ // without credentials. Validate the env file up front so a missing one fails
405
+ // fast. A resolved default/active env file may be absent.
406
+ const userSpecifiedEnvFile = options.envFile !== undefined;
407
+ const envFileName = userSpecifiedEnvFile ? options.envFile : await resolveEnvFileName(rootDir);
408
+ if (userSpecifiedEnvFile && !existsSync(resolve(rootDir, envFileName))) {
409
+ console.log(`${colors.red}Error: env file '${envFileName}' not found in ${rootDir}${colors.reset}`);
410
+ process.exit(1);
411
+ }
412
+ // Plugin bootstrap happens INSIDE each subprocess (the harness registers
413
+ // matchers / protocol adapters before importing the load file), so the CLI no
414
+ // longer bootstraps here.
415
+ const { vars, secrets } = await loadProjectEnv(rootDir, envFileName);
416
+ // Preflight the upload destination BEFORE running plans — a `--upload` typo
417
+ // (bad token/project/target) shouldn't first generate a full load run against
418
+ // real services and only then fail. Exits non-zero on any resolution failure.
419
+ let uploadContext;
420
+ if (options.upload) {
421
+ uploadContext = await resolveLoadUploadContext(rootDir, { ...vars, ...secrets }, options);
422
+ }
423
+ // A single file's import failure (or crash) is collected (not thrown) so
424
+ // earlier/later files still produce + persist results. Pass the raw resolved
425
+ // env — the child re-applies the process.env fallback (a Proxy can't cross the
426
+ // process boundary), so shell/CI-supplied vars/secrets still resolve.
427
+ const { outcomes, errors } = await runLoadFiles(files, { vars, secrets, cwd: rootDir });
428
+ // Persist every completed artifact FIRST — a later broken file must not discard
429
+ // an expensive successful plan's result.
430
+ const written = await writeLoadResults(outcomes, resolve(rootDir, ".glubean"));
431
+ console.log();
432
+ let anyFail = false;
433
+ for (const o of outcomes) {
434
+ printOutcome(o);
435
+ if (!o.artifact.summary.pass)
436
+ anyFail = true;
437
+ }
438
+ for (const e of errors) {
439
+ console.log(`${colors.red}✗ ${e.message}${colors.reset}`);
440
+ }
441
+ if (written.length > 0) {
442
+ console.log(`\n${colors.dim}Wrote ${written.length} result file(s) to .glubean/${colors.reset}`);
443
+ }
444
+ if (outcomes.length === 0 && errors.length === 0) {
445
+ console.log(`${colors.yellow}No loadRunner() exports found in ${files.length} file(s).${colors.reset}`);
446
+ }
447
+ // Upload completed plans (destination preflighted above). Runs upload
448
+ // regardless of pass/fail — a failed load run is still worth a durable
449
+ // performance-history record.
450
+ if (uploadContext && outcomes.length > 0) {
451
+ await uploadLoadOutcomes(outcomes, {
452
+ context: uploadContext,
453
+ rootDir,
454
+ envFile: envFileName,
455
+ options,
456
+ });
457
+ }
458
+ // Fail if any plan failed, any file errored, or nothing ran at all.
459
+ if (anyFail || errors.length > 0 || outcomes.length === 0)
460
+ process.exit(1);
461
+ }
462
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/commands/load.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,23 @@
1
1
  /**
2
- * glubean login — Authenticate with Glubean Cloud.
2
+ * glubean login — Sign the CLI in to Glubean Cloud via the device-authorization
3
+ * grant (RFC 8628). The CLI requests a code from the AUTH plane (server-hono),
4
+ * opens the browser to approve it, polls until a `glb_` token is minted, and
5
+ * saves it to ~/.glubean/credentials.json for `--upload`.
6
+ *
7
+ * Login talks to the AUTH url (server-hono); uploads talk to the platform API
8
+ * (`GLUBEAN_API_URL`) — two separate planes. The open platform is token-only and
9
+ * has no login of its own.
3
10
  */
4
11
  export interface LoginOptions {
12
+ /** Non-interactive escape hatch: save this glb_ token directly (no device flow). */
5
13
  token?: string;
6
14
  project?: string;
15
+ /** Platform/upload API URL to persist for `--upload`. */
7
16
  apiUrl?: string;
17
+ /** Auth-plane URL (server-hono) for the device grant. */
18
+ authUrl?: string;
19
+ /** Don't auto-open the browser (print the URL only). */
20
+ noBrowser?: boolean;
8
21
  }
9
22
  export declare function loginCommand(options: LoginOptions): Promise<void>;
10
23
  //# sourceMappingURL=login.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFvE"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqBH,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAgED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFvE"}