@glubean/cli 0.8.2 → 0.8.4

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.
@@ -0,0 +1,297 @@
1
+ import { resolve } from "node:path";
2
+ import { stat } from "node:fs/promises";
3
+ import { loadProjectEnv } from "@glubean/runner";
4
+ import { buildProjections } from "./dry-run.js";
5
+ import { findProjectConfig } from "./run.js";
6
+ import { resolveToken, resolveProjectId, resolveApiUrl } from "../lib/auth.js";
7
+ import { resolveEnvFileName } from "../lib/active_env.js";
8
+ const colors = {
9
+ reset: "\x1b[0m",
10
+ bold: "\x1b[1m",
11
+ dim: "\x1b[2m",
12
+ green: "\x1b[32m",
13
+ yellow: "\x1b[33m",
14
+ blue: "\x1b[34m",
15
+ red: "\x1b[31m",
16
+ };
17
+ /** Strip credential-bearing URL parts (query / fragment / userinfo) before a URL
18
+ * leaves the machine — mirrors the cloud's server-side sanitizer (defense in
19
+ * depth: the dry-run projector already placeholders ctx.secrets to `<KEY>`). */
20
+ function sanitizeUrl(url) {
21
+ try {
22
+ const u = new URL(url);
23
+ u.username = "";
24
+ u.password = "";
25
+ u.search = "";
26
+ u.hash = "";
27
+ return u.toString();
28
+ }
29
+ catch {
30
+ return url.split("#")[0].split("?")[0].replace(/(\/\/)[^/@]*@/, "$1");
31
+ }
32
+ }
33
+ /**
34
+ * `glubean sync` — sync the repo's test-definition projections (declared
35
+ * metadata + dry-run shape) to Glubean Cloud for team review. PROJECT-scoped:
36
+ * the projection is generated from SOURCE CODE, so it's one set per codebase
37
+ * regardless of how many targets it runs against. The upload is the COMPLETE
38
+ * source snapshot — the server replaces the project's projections with it
39
+ * (removed tests are deleted). Distinct from `glubean run --upload` (run
40
+ * evidence).
41
+ */
42
+ export async function syncCommand(options = {}) {
43
+ const dir = options.dir ? resolve(options.dir) : process.cwd();
44
+ // Resolve auth/env from the PROJECT ROOT (so root .env.* / .glubean/active-env
45
+ // are honored even when --dir points at a nested scan dir) — parity with run.
46
+ const { rootDir } = await findProjectConfig(dir);
47
+ console.log(`\n${colors.bold}${colors.blue}🔄 Glubean Sync (test-definition projection)${colors.reset}\n`);
48
+ // Validate an EXPLICIT --env-file FIRST — before the (expensive, user-code-
49
+ // running) projection — so a typo fails fast. A missing explicit env file
50
+ // would otherwise load empty and let global/process credentials upload to the
51
+ // WRONG project (parity with run/load). Default: the active env (or .env).
52
+ const userSpecifiedEnvFile = !!options.envFile;
53
+ const envFileName = options.envFile ?? (await resolveEnvFileName(rootDir));
54
+ if (userSpecifiedEnvFile) {
55
+ try {
56
+ await stat(resolve(rootDir, envFileName));
57
+ }
58
+ catch {
59
+ console.error(`${colors.red}Sync failed: env file '${envFileName}' not found in ${rootDir}${colors.reset}`);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ // ALWAYS project the WHOLE project (rootDir), never just --dir: the upload is a
64
+ // complete snapshot the server replaces, so scanning a subdirectory would make
65
+ // the server delete every test outside it. --dir only locates the project root.
66
+ const { projected, errors, warnings, emptyTestFiles, contracts, workflows, openapi, openapiFailed } = await buildProjections(rootDir);
67
+ // A file that failed to import / timed out has NO projection. Since sync is a
68
+ // full-snapshot replace, publishing now would DELETE the broken file's tests'
69
+ // projections (treating them as removed) — so abort and let the user fix +
70
+ // re-sync the complete set.
71
+ if (errors.length) {
72
+ console.error(`${colors.red}Sync aborted: ${errors.length} file(s) failed to project.${colors.reset}`);
73
+ for (const e of errors)
74
+ console.error(` ${colors.red}✗ ${e.file}: ${e.message}${colors.reset}`);
75
+ console.error(`${colors.dim}Fix these files and re-run — syncing now would drop their tests' projections.${colors.reset}`);
76
+ process.exit(1);
77
+ }
78
+ // A file the SCANNER couldn't turn into a projection is dropped BEFORE upload
79
+ // (it never shows in `errors`), yet its tests/contracts/workflows would vanish
80
+ // from this full snapshot and be DELETED on replace. All fatal: test extraction
81
+ // THREW ("Failed to extract metadata from"), a test file yielded ZERO exports
82
+ // (emptyTestFiles), or a contract/workflow file failed to import ("Contract
83
+ // import failed" / "Flow import failed" — leaves contractsProjection/workflows
84
+ // missing that file, so a full-replace would wipe its prior Cloud projection).
85
+ const dropped = [
86
+ ...warnings.filter((w) => w.startsWith("Failed to extract metadata from") ||
87
+ w.startsWith("Contract import failed") ||
88
+ w.startsWith("Flow import failed")),
89
+ ...emptyTestFiles.map((f) => `${f} — a Glubean test file with no extractable tests (syntax error, or tests removed/unrecognized?)`),
90
+ ];
91
+ if (dropped.length) {
92
+ console.error(`${colors.red}Sync aborted: ${dropped.length} file(s) would be dropped from the snapshot.${colors.reset}`);
93
+ for (const w of dropped)
94
+ console.error(` ${colors.red}✗ ${w}${colors.reset}`);
95
+ console.error(`${colors.dim}Fix these files and re-run — syncing now would delete their projections from Cloud.${colors.reset}`);
96
+ process.exit(1);
97
+ }
98
+ // Empty snapshot would CLEAR the project's projections — guard against an
99
+ // accidental run in the wrong/empty dir; require --allow-empty to actually wipe.
100
+ // "Empty" means NO specs of ANY kind (test + contract + workflow).
101
+ if (projected.length === 0 && contracts.length === 0 && workflows.length === 0 && !options.allowEmpty) {
102
+ console.log(`${colors.yellow}No tests, contracts, or workflows found.${colors.reset} ${colors.dim}Pass --allow-empty to clear the project's projections, or check the directory.${colors.reset}\n`);
103
+ return;
104
+ }
105
+ // Resolve cloud auth — PROJECT-scoped (no target: the projection is repo-level).
106
+ const { vars, secrets } = await loadProjectEnv(rootDir, envFileName);
107
+ const authOpts = { token: options.token, project: options.project, apiUrl: options.apiUrl };
108
+ const sources = { envFileVars: { ...vars, ...secrets } };
109
+ const token = await resolveToken(authOpts, sources, options.tokenEnv);
110
+ const projectId = await resolveProjectId(authOpts, sources);
111
+ const apiUrl = await resolveApiUrl(authOpts, sources);
112
+ if (!token) {
113
+ console.error(`${colors.red}Sync failed: no auth token.${colors.reset}\n` +
114
+ `${colors.dim}Create a project token (glb_…) in the dashboard (Project → Tokens), then run 'glubean login', set GLUBEAN_TOKEN / --token, or add it to .env.secrets.${colors.reset}`);
115
+ process.exit(1);
116
+ }
117
+ if (!projectId) {
118
+ console.error(`${colors.red}Sync failed: no project ID.${colors.reset}\n` +
119
+ `${colors.dim}Set --project / GLUBEAN_PROJECT_ID, or run 'glubean login'.${colors.reset}`);
120
+ process.exit(1);
121
+ }
122
+ if (!apiUrl) {
123
+ console.error(`${colors.red}Sync failed: no API URL (set --api-url / GLUBEAN_API_URL).${colors.reset}`);
124
+ process.exit(1);
125
+ }
126
+ const tests = projected.map((p) => ({
127
+ testId: p.testId,
128
+ description: p.description ?? null,
129
+ deprecated: p.deprecated ?? null,
130
+ requires: p.requires ?? null,
131
+ defaultRun: p.defaultRun ?? null,
132
+ tags: p.tags ?? [],
133
+ assertions: p.assertions,
134
+ endpoints: p.endpoints.map((e) => ({ ...e, url: sanitizeUrl(e.url) })),
135
+ assertionCount: p.assertionCount,
136
+ projectionComplete: p.projectionComplete,
137
+ incompleteReason: p.incompleteReason ?? null,
138
+ skipped: p.skipped ?? false,
139
+ }));
140
+ // Redact outbound data before it leaves the machine (parity with run/load):
141
+ // a hardcoded credential in an assertion message / endpoint is masked (URL
142
+ // query/userinfo/fragment is already stripped above). Honor the PROJECT's
143
+ // redaction rules (glubean.yaml `defaults.redaction` — custom sensitiveKeys /
144
+ // customPatterns), not just the built-in defaults; FAIL CLOSED on invalid config.
145
+ const { redactValue, BUILTIN_SCOPES } = await import("@glubean/redaction");
146
+ const { loadProjectConfigV1, resolveRedactionConfig } = await import("../lib/config.js");
147
+ let redaction = resolveRedactionConfig(undefined); // built-in defaults
148
+ let hasConfig = false;
149
+ try {
150
+ await stat(resolve(rootDir, "glubean.yaml"));
151
+ hasConfig = true;
152
+ }
153
+ catch {
154
+ /* no glubean.yaml → built-in default redaction */
155
+ }
156
+ if (hasConfig) {
157
+ try {
158
+ const { config } = await loadProjectConfigV1(rootDir);
159
+ redaction = resolveRedactionConfig(config.defaults?.redaction);
160
+ }
161
+ catch (err) {
162
+ console.error(`${colors.red}Sync failed: invalid glubean.yaml redaction config — ${err?.message ?? String(err)}${colors.reset}`);
163
+ process.exit(1);
164
+ }
165
+ }
166
+ // The projection is a static blob with NO request/response scope to bind to, so
167
+ // fold the builtin SCOPE sensitive keys (cookie / set-cookie / authorization /
168
+ // token / …) into the global keys — otherwise header/query examples carried in a
169
+ // contract/workflow projection would upload in cleartext (run/load apply these
170
+ // per-scope; here there's no scope, so apply them everywhere).
171
+ const scopeKeys = [...new Set(BUILTIN_SCOPES.flatMap((s) => s.rules?.sensitiveKeys ?? []))];
172
+ const globalRules = {
173
+ ...redaction.globalRules,
174
+ sensitiveKeys: [...new Set([...(redaction.globalRules.sensitiveKeys ?? []), ...scopeKeys])],
175
+ };
176
+ const redactField = (v) => redactValue(v, {
177
+ globalRules,
178
+ replacementFormat: redaction.replacementFormat,
179
+ maxDepth: 64,
180
+ });
181
+ // The normalized contract/workflow `projection` is a TYPE/STRUCTURE blob (JSON
182
+ // schemas, node trees) — its object KEYS are field names (e.g. a schema property
183
+ // literally named `password`/`token`), NOT secrets. Key-based redaction would
184
+ // MASK those field names and destroy the schema projection — the most important
185
+ // part of a contract. So redact the projection with PATTERN rules ONLY (still
186
+ // catches secret-LOOKING literal values, e.g. a hardcoded `sk-…` default), never
187
+ // sensitiveKeys.
188
+ const structureRules = { ...redaction.globalRules, sensitiveKeys: [] };
189
+ const redactStructure = (v) => redactValue(v, {
190
+ globalRules: structureRules,
191
+ replacementFormat: redaction.replacementFormat,
192
+ maxDepth: 64,
193
+ });
194
+ // Redact ONLY the secret-bearing/free-text fields — NEVER `testId` (the stable
195
+ // join key with run evidence; redacting an id that matches a built-in pattern
196
+ // would break correlation and collapse distinct ids) or structural fields
197
+ // (requires/defaultRun/counts/flags).
198
+ const safeTests = tests.map((t) => ({
199
+ ...t,
200
+ description: t.description == null ? t.description : redactField(t.description),
201
+ deprecated: t.deprecated == null ? t.deprecated : redactField(t.deprecated),
202
+ incompleteReason: t.incompleteReason == null ? t.incompleteReason : redactField(t.incompleteReason),
203
+ assertions: redactField(t.assertions),
204
+ endpoints: redactField(t.endpoints),
205
+ }));
206
+ // Contracts/workflows: redact the free-text + the normalized `projection` body
207
+ // (schemas/descriptions/notes), preserve identity/structural fields.
208
+ const safeContracts = contracts.map((c) => ({
209
+ contractId: c.contractId,
210
+ protocol: c.protocol,
211
+ target: c.target ?? null,
212
+ description: c.description == null ? null : redactField(c.description),
213
+ deprecated: c.deprecated == null ? null : redactField(c.deprecated),
214
+ tags: c.tags ?? [],
215
+ caseCount: c.caseCount,
216
+ projection: redactStructure(c.projection),
217
+ projectionComplete: c.projectionComplete,
218
+ incompleteReason: c.incompleteReason ?? null,
219
+ }));
220
+ const safeWorkflows = workflows.map((w) => ({
221
+ workflowId: w.workflowId,
222
+ name: w.name ?? null,
223
+ description: w.description == null ? null : redactField(w.description),
224
+ tags: w.tags ?? [],
225
+ nodeCount: w.nodeCount,
226
+ projection: redactStructure(w.projection),
227
+ projectionComplete: w.projectionComplete,
228
+ incompleteReason: w.incompleteReason ?? null,
229
+ }));
230
+ // The OpenAPI doc is purely structural (paths + schemas). Redact it pattern-ONLY
231
+ // (same as the normalized projection): mask secret-LOOKING example/default values
232
+ // but PRESERVE schema field names — masking a `password`/`token` field name (a
233
+ // type, not a secret) would corrupt the schema. `null` when there are no HTTP
234
+ // contracts, so a full-replace clears any stale doc.
235
+ const safeOpenapi = openapi ? redactStructure(openapi) : null;
236
+ const base = `${apiUrl.replace(/\/+$/, "")}/v1/projects/${projectId}/projections`;
237
+ // Each kind is its OWN full-snapshot replace (an empty kind clears that kind's
238
+ // stale projections). POST all three; a failure on any aborts.
239
+ const post = async (kind, body, opts) => {
240
+ let res;
241
+ try {
242
+ res = await fetch(`${base}/${kind}`, {
243
+ method: "POST",
244
+ headers: { "content-type": "application/json", authorization: `Bearer ${token}` },
245
+ body: JSON.stringify(body),
246
+ });
247
+ }
248
+ catch (err) {
249
+ console.error(`${colors.red}Sync failed (${kind}): ${err?.message ?? String(err)}${colors.reset}`);
250
+ process.exit(1);
251
+ }
252
+ if (!res.ok) {
253
+ // A server that predates this projection kind answers 404 — tolerate it (skip
254
+ // this kind) instead of failing a sync that already replaced the OTHER kinds, so
255
+ // a newer CLI keeps working against a not-yet-upgraded / self-hosted server.
256
+ if (opts?.tolerateMissingRoute && res.status === 404)
257
+ return { skipped: true };
258
+ const text = await res.text().catch(() => "");
259
+ console.error(`${colors.red}Sync failed (${kind}): ${res.status} ${text}${colors.reset}`);
260
+ if (res.status === 401 || res.status === 403) {
261
+ console.error(`${colors.dim}The token is invalid/expired or lacks runs:write. Create a project token in the dashboard and 'glubean login' (or set GLUBEAN_TOKEN).${colors.reset}`);
262
+ }
263
+ process.exit(1);
264
+ }
265
+ return (await res.json().catch(() => ({})));
266
+ };
267
+ const testRes = await post("test", { tests: safeTests });
268
+ const contractRes = await post("contract", { contracts: safeContracts });
269
+ const workflowRes = await post("workflow", { workflows: safeWorkflows });
270
+ // The OpenAPI doc is a project-level single snapshot (not a per-id replace) — one
271
+ // doc rendered from all HTTP contracts. POST it last; `null` clears a stale doc. Two
272
+ // ways it skips (best-effort, never aborts the whole sync): render FAILED (don't wipe
273
+ // a prior doc on a transient error), or the server predates the route (404 tolerated,
274
+ // so a newer CLI doesn't break sync against a not-yet-upgraded server).
275
+ const openapiRes = openapiFailed
276
+ ? { skipped: true }
277
+ : await post("openapi", { openapi: safeOpenapi }, { tolerateMissingRoute: true });
278
+ const line = (label, r, n) => {
279
+ const removed = r.deleted ? `${colors.dim} (${r.deleted} removed)${colors.reset}` : "";
280
+ return `${colors.green}✓ ${r.upserted ?? n} ${label}${colors.reset}${removed}`;
281
+ };
282
+ const pathCount = safeOpenapi ? Object.keys(safeOpenapi.paths ?? {}).length : 0;
283
+ const openapiLine = openapiFailed
284
+ ? `${colors.yellow}⚠ openapi skipped (render failed; kept previous)${colors.reset}`
285
+ : openapiRes?.skipped
286
+ ? `${colors.dim}· openapi not supported by this server (skipped)${colors.reset}`
287
+ : `${colors.green}✓ openapi${colors.reset}${colors.dim} (${pathCount} path${pathCount === 1 ? "" : "s"})${colors.reset}`;
288
+ console.log(`${line("test", testRes, safeTests.length)} ${line("contract", contractRes, safeContracts.length)} ${line("workflow", workflowRes, safeWorkflows.length)} ${openapiLine} ${colors.dim}→ project ${projectId}${colors.reset}`);
289
+ const partial = projected.filter((p) => !p.projectionComplete).length +
290
+ contracts.filter((c) => !c.projectionComplete).length +
291
+ workflows.filter((w) => !w.projectionComplete).length;
292
+ if (partial > 0) {
293
+ console.log(`${colors.yellow} ◐ ${partial} partial — use ctx.when()/switch()/while() (tests) or resolve opaque nodes/unprojectable schemas (workflows/contracts) for full projection${colors.reset}`);
294
+ }
295
+ console.log();
296
+ }
297
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * only-selectors.ts — pure, unit-testable builders for the B2 M3 `{id, rowIndex}`
3
+ * "only" selector protocol at the CLI surface.
4
+ *
5
+ * Two entry points:
6
+ * - `buildOnlySelectorsFromFlags` — the single validation gate for the
7
+ * `--only-id` / `--row` / `--rerun-failed` flag combination. Returns the
8
+ * selector set for the explicit (`--only-id`/`--row`) path, or a clear error.
9
+ * - `deriveRerunSelectors` — turns a prior `last-run.result.json` into the
10
+ * failed-subset selectors + the distinct files those failures live in.
11
+ *
12
+ * The protocol shape (`OnlySelector`) and matching/collection semantics
13
+ * (`collectFailedSelectors`) are reused from `@glubean/runner` so the CLI, the
14
+ * SDK runner, and the cloud harness all speak ONE protocol.
15
+ */
16
+ import { type OnlySelector } from "@glubean/runner";
17
+ export interface OnlyFlags {
18
+ onlyId?: string[];
19
+ row?: number;
20
+ rerunFailed?: boolean;
21
+ }
22
+ export type BuildSelectorsResult = {
23
+ ok: true;
24
+ selectors: OnlySelector[];
25
+ } | {
26
+ ok: false;
27
+ error: string;
28
+ };
29
+ /**
30
+ * Validate the flag combination and build selectors for the explicit
31
+ * `--only-id` / `--row` path.
32
+ *
33
+ * Validation:
34
+ * - `--rerun-failed` is mutually exclusive with `--only-id` / `--row`.
35
+ * - `--row` requires EXACTLY one `--only-id` (it pins a single `.each` row).
36
+ *
37
+ * Returns `{ selectors: [] }` for the conflict-free `--rerun-failed` case — the
38
+ * caller sources the actual selectors from the last run via `deriveRerunSelectors`.
39
+ */
40
+ export declare function buildOnlySelectorsFromFlags(opts: OnlyFlags): BuildSelectorsResult;
41
+ /**
42
+ * Derive the `--rerun-failed` selector set + the distinct files those failures
43
+ * came from, off a prior run's `last-run.result.json` `tests` array.
44
+ *
45
+ * `selectors` reuses `collectFailedSelectors` (failed records with an id → bare
46
+ * `{id}` or row-pinned `{id, rowIndex}`). `files` is the de-duplicated list of
47
+ * `filePath`s of failed records (declaration order preserved) so the caller can
48
+ * narrow discovery to only the files that actually contained a failure.
49
+ */
50
+ export declare function deriveRerunSelectors(lastRun: {
51
+ tests: Array<{
52
+ testId?: string;
53
+ rowIndex?: number;
54
+ filePath?: string;
55
+ success: boolean;
56
+ }>;
57
+ }): {
58
+ selectors: OnlySelector[];
59
+ files: string[];
60
+ };
61
+ //# sourceMappingURL=only-selectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"only-selectors.d.ts","sourceRoot":"","sources":["../../src/lib/only-selectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE5E,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,YAAY,EAAE,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,GAAG,oBAAoB,CAiCjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC3F,GAAG;IAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAcjD"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * only-selectors.ts — pure, unit-testable builders for the B2 M3 `{id, rowIndex}`
3
+ * "only" selector protocol at the CLI surface.
4
+ *
5
+ * Two entry points:
6
+ * - `buildOnlySelectorsFromFlags` — the single validation gate for the
7
+ * `--only-id` / `--row` / `--rerun-failed` flag combination. Returns the
8
+ * selector set for the explicit (`--only-id`/`--row`) path, or a clear error.
9
+ * - `deriveRerunSelectors` — turns a prior `last-run.result.json` into the
10
+ * failed-subset selectors + the distinct files those failures live in.
11
+ *
12
+ * The protocol shape (`OnlySelector`) and matching/collection semantics
13
+ * (`collectFailedSelectors`) are reused from `@glubean/runner` so the CLI, the
14
+ * SDK runner, and the cloud harness all speak ONE protocol.
15
+ */
16
+ import { collectFailedSelectors } from "@glubean/runner";
17
+ /**
18
+ * Validate the flag combination and build selectors for the explicit
19
+ * `--only-id` / `--row` path.
20
+ *
21
+ * Validation:
22
+ * - `--rerun-failed` is mutually exclusive with `--only-id` / `--row`.
23
+ * - `--row` requires EXACTLY one `--only-id` (it pins a single `.each` row).
24
+ *
25
+ * Returns `{ selectors: [] }` for the conflict-free `--rerun-failed` case — the
26
+ * caller sources the actual selectors from the last run via `deriveRerunSelectors`.
27
+ */
28
+ export function buildOnlySelectorsFromFlags(opts) {
29
+ const onlyId = opts.onlyId ?? [];
30
+ const hasRow = opts.row !== undefined;
31
+ const rerun = !!opts.rerunFailed;
32
+ // --rerun-failed reuses the last run's failed set; it can't be combined with
33
+ // an explicit --only-id / --row target.
34
+ if (rerun && (onlyId.length > 0 || hasRow)) {
35
+ return {
36
+ ok: false,
37
+ error: "--rerun-failed cannot be combined with --only-id or --row (it reuses the last run's failed set).",
38
+ };
39
+ }
40
+ // --row pins a single .each row, so it needs exactly one --only-id to attach to.
41
+ if (hasRow && onlyId.length !== 1) {
42
+ return {
43
+ ok: false,
44
+ error: onlyId.length === 0
45
+ ? "--row requires --only-id (the id whose .each row you want to isolate)."
46
+ : `--row requires exactly one --only-id (got ${onlyId.length}). Drop --row to run multiple ids.`,
47
+ };
48
+ }
49
+ // Conflict-free rerun mode: no flag-derived selectors — they come from the file.
50
+ if (rerun)
51
+ return { ok: true, selectors: [] };
52
+ if (hasRow) {
53
+ return { ok: true, selectors: [{ id: onlyId[0], rowIndex: opts.row }] };
54
+ }
55
+ return { ok: true, selectors: onlyId.map((id) => ({ id })) };
56
+ }
57
+ /**
58
+ * Derive the `--rerun-failed` selector set + the distinct files those failures
59
+ * came from, off a prior run's `last-run.result.json` `tests` array.
60
+ *
61
+ * `selectors` reuses `collectFailedSelectors` (failed records with an id → bare
62
+ * `{id}` or row-pinned `{id, rowIndex}`). `files` is the de-duplicated list of
63
+ * `filePath`s of failed records (declaration order preserved) so the caller can
64
+ * narrow discovery to only the files that actually contained a failure.
65
+ */
66
+ export function deriveRerunSelectors(lastRun) {
67
+ const tests = lastRun.tests ?? [];
68
+ const selectors = collectFailedSelectors(tests.map((t) => ({ id: t.testId, rowIndex: t.rowIndex, success: t.success })));
69
+ const files = [];
70
+ const seen = new Set();
71
+ for (const t of tests) {
72
+ if (t.success === false && t.filePath && !seen.has(t.filePath)) {
73
+ seen.add(t.filePath);
74
+ files.push(t.filePath);
75
+ }
76
+ }
77
+ return { selectors, files };
78
+ }
79
+ //# sourceMappingURL=only-selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"only-selectors.js","sourceRoot":"","sources":["../../src/lib/only-selectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,sBAAsB,EAAqB,MAAM,iBAAiB,CAAC;AAY5E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAe;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;IAEjC,6EAA6E;IAC7E,wCAAwC;IACxC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC;QAC3C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EACH,kGAAkG;SACrG,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EACH,MAAM,CAAC,MAAM,KAAK,CAAC;gBACjB,CAAC,CAAC,wEAAwE;gBAC1E,CAAC,CAAC,6CAA6C,MAAM,CAAC,MAAM,oCAAoC;SACrG,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,IAAI,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAE9C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAI,EAAE,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAEpC;IACC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,sBAAsB,CACtC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAC/E,CAAC;IACF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC"}
@@ -169,6 +169,28 @@ export interface UploadOptions {
169
169
  * runs set this — those dirs hold TEST artifacts (the LoadArtifact is already
170
170
  * the `result` blob), so attaching them would misattribute stale files. */
171
171
  skipArtifacts?: boolean;
172
+ /** This run's exact screenshot file paths (absolute), extracted from the
173
+ * `browser:screenshot` event stream. When provided, the `.glubean/screenshots`
174
+ * portion uploads ONLY these files instead of walking the whole dir — the dir
175
+ * accumulates screenshots across runs, so a plain walk misattributes stale
176
+ * files from previous runs to this run (ART1). Each path is realpath-checked
177
+ * to be inside `.glubean/screenshots`; escapees are dropped. When omitted, the
178
+ * screenshots dir is walked as before (backward compatible). Does NOT affect
179
+ * the `.glubean/artifacts` scan, which always walks. */
180
+ screenshotPaths?: string[];
181
+ }
182
+ /** A file the server confirmed receiving, with the stat identity it had when
183
+ * its bytes were read into the upload form. Cleanup (ART1-B) re-checks this
184
+ * identity immediately before unlinking so it never deletes a file that was
185
+ * recreated at the same path after the upload (different content the server
186
+ * never saw). */
187
+ export interface UploadedArtifactFile {
188
+ /** Absolute (realpath'd for whitelist screenshots) path of the posted file. */
189
+ path: string;
190
+ size: number;
191
+ mtimeMs: number;
192
+ ino: number;
193
+ dev: number;
172
194
  }
173
195
  export interface UploadReceipt {
174
196
  schemaVersion: "glubean.upload-receipt.v1";
@@ -194,8 +216,39 @@ export interface UploadReceipt {
194
216
  sizeBytes?: number;
195
217
  statusCode?: number;
196
218
  error?: string;
219
+ /** The files that actually entered the multipart form (absolute path +
220
+ * stat identity captured at upload time), set only when the server
221
+ * confirmed the batch (`status: "uploaded"`). Excludes over-cap skips.
222
+ * Mixed set: `.glubean/artifacts` walk entries AND whitelist screenshots
223
+ * — a caller cleaning up local screenshots must intersect with its own
224
+ * run's screenshot list (ART1-B), never delete this list wholesale. The
225
+ * identity lets cleanup verify the on-disk file is still the exact file
226
+ * the server received (a concurrent run may have recreated the path). */
227
+ uploadedFiles?: UploadedArtifactFile[];
197
228
  };
198
229
  }
230
+ /**
231
+ * ART1-B — delete this run's screenshots locally once the Cloud confirmed it
232
+ * received them. Deletes ONLY the intersection of:
233
+ * - `screenshotPaths`: this run's screenshot list (from the event stream), and
234
+ * - `uploadedFiles`: what `uploadToCloud` actually posted in a server-confirmed
235
+ * batch (`receipt.artifactUpload.uploadedFiles`).
236
+ * plus the same realpath containment guard as the upload whitelist: a path is
237
+ * only unlinked when it resolves strictly inside `.glubean/screenshots`. On top
238
+ * of path membership, the file's stat identity (dev/ino/size/mtimeMs) must still
239
+ * match what was uploaded — a concurrent run that recreated the same path put
240
+ * bytes there the server never received, and those must survive. (The check is
241
+ * re-done immediately before each unlink; POSIX offers no unlink-by-fd, so a
242
+ * recreation landing in the sub-ms window between lstat and unlink is the one
243
+ * residual race — codex r2 P3, accepted.) So a partial
244
+ * upload (over-cap skip) keeps its file, a failed batch keeps everything, and
245
+ * nothing outside the screenshots dir (e.g. `.glubean/artifacts`, or an escapee
246
+ * event path) is ever touched. Idempotent: already-missing files are skipped
247
+ * silently. Returns how many files were removed.
248
+ */
249
+ export declare function removeUploadedScreenshots(rootDir: string, screenshotPaths: string[], uploadedFiles: UploadedArtifactFile[]): Promise<{
250
+ removed: number;
251
+ }>;
199
252
  /**
200
253
  * Upload a run (test or load) + optionally its artifacts to Glubean Cloud under
201
254
  * a target (ADR 0007). The caller assembles the run-level `UploadRunInput` from
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/lib/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/lib/upload.ts"],"names":[],"mappings":"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"}