@keepsnappy/agent 0.1.0-alpha.12 → 0.1.0-alpha.13

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.
@@ -413,7 +413,7 @@ function validateConfig(raw, opts = {}) {
413
413
  }
414
414
  const pin = strList("steps.pin", steps.pin);
415
415
  const output = section("output", ["dir"], false);
416
- const outDir = str("output.dir", output.dir, false, "perflab-out");
416
+ const outDir = str("output.dir", output.dir, false, "keepsnappy-out");
417
417
  let timeoutSeconds;
418
418
  if (raw.timeout_seconds !== undefined) {
419
419
  if (typeof raw.timeout_seconds !== "number" || raw.timeout_seconds <= 0)
@@ -519,12 +519,12 @@ import { join as join11, resolve as resolve3 } from "node:path";
519
519
 
520
520
  // apps/agent/src/data-source.ts
521
521
  import { join as join2 } from "node:path";
522
- var PERF_LAB_LOG = "Documents/perf-lab/log.txt";
522
+ var KEEPSNAPPY_LOG = "Documents/keepsnappy/log.txt";
523
523
  var SAFE_FILE = /^[\w.+:-]+$/;
524
524
  var profilePath = (fileName) => {
525
525
  if (!SAFE_FILE.test(fileName) || fileName.includes(".."))
526
526
  throw new Error(`unsafe profile file name: ${fileName}`);
527
- return `Documents/perf-lab/${fileName}`;
527
+ return `Documents/keepsnappy/${fileName}`;
528
528
  };
529
529
  function parseSimctlDevices(json, udid) {
530
530
  let data;
@@ -561,7 +561,7 @@ class IosSimulatorDataSource {
561
561
  return this.deps.fs.readFile(join2(await this.dataDir(bundleId), profilePath(fileName)));
562
562
  }
563
563
  async fetchLog(bundleId) {
564
- return this.deps.fs.readFile(join2(await this.dataDir(bundleId), PERF_LAB_LOG));
564
+ return this.deps.fs.readFile(join2(await this.dataDir(bundleId), KEEPSNAPPY_LOG));
565
565
  }
566
566
  async describeDevice() {
567
567
  const r = await this.deps.spawner.run("xcrun", ["simctl", "list", "devices", this.udid === "booted" ? "booted" : "", "-j"].filter(Boolean));
@@ -580,7 +580,7 @@ class IosDeviceDataSource {
580
580
  }
581
581
  async fetchLog(bundleId) {
582
582
  await this.deps.fs.mkdir(this.scratchDir);
583
- const dest = join2(this.scratchDir, "perf-lab.log");
583
+ const dest = join2(this.scratchDir, "keepsnappy.log");
584
584
  const r = await this.deps.spawner.run("xcrun", [
585
585
  "devicectl",
586
586
  "device",
@@ -593,7 +593,7 @@ class IosDeviceDataSource {
593
593
  "--domain-identifier",
594
594
  bundleId,
595
595
  "--source",
596
- PERF_LAB_LOG,
596
+ KEEPSNAPPY_LOG,
597
597
  "--destination",
598
598
  dest
599
599
  ]);
@@ -614,7 +614,7 @@ class IosDeviceDataSource {
614
614
  "--domain-identifier",
615
615
  bundleId,
616
616
  "--source",
617
- PERF_LAB_LOG,
617
+ KEEPSNAPPY_LOG,
618
618
  "--destination",
619
619
  dest
620
620
  ]);
@@ -651,7 +651,7 @@ class IosDeviceDataSource {
651
651
  // apps/agent/src/flows.ts
652
652
  import { basename, dirname, join as join3 } from "node:path";
653
653
  var FLOW_FILE = /\.ya?ml$/i;
654
- var NOT_FLOWS = new Set(["config.yaml", "config.yml", "keepsnappy.yml", "keepsnappy.yaml", "perflab.yml", "perflab.yaml"]);
654
+ var NOT_FLOWS = new Set(["config.yaml", "config.yml", "keepsnappy.yml", "keepsnappy.yaml", "keepsnappy.yml", "keepsnappy.yaml"]);
655
655
  var flowStem = (path) => basename(path).replace(FLOW_FILE, "");
656
656
  function flowTags(text) {
657
657
  const head = text.split(/^---\s*$/m)[0] ?? "";
@@ -1193,20 +1193,20 @@ var MEASURES = {
1193
1193
  worse: "none",
1194
1194
  at: ["screen", "launch", "press", "drag", "other"],
1195
1195
  producer: "derive",
1196
- label: "Time of the PerfLab SDK in the window",
1197
- short: "time of the PerfLab SDK",
1196
+ label: "Time of the KeepSnappy SDK in the window",
1197
+ short: "time of the KeepSnappy SDK",
1198
1198
  decimals: 1,
1199
- what: "Time the PerfLab SDK spent on the JavaScript thread after each screen update in the window (reading the update, its profile and, when on, the React export); evidence only, never decides a result. Clock time, so it also holds pauses for garbage collection or other threads while the SDK ran. Not known when the window had more updates than the SDK keeps times for"
1199
+ what: "Time the KeepSnappy SDK spent on the JavaScript thread after each screen update in the window (reading the update, its profile and, when on, the React export); evidence only, never decides a result. Clock time, so it also holds pauses for garbage collection or other threads while the SDK ran. Not known when the window had more updates than the SDK keeps times for"
1200
1200
  },
1201
1201
  sdk_hook_commits: {
1202
1202
  unit: "count",
1203
1203
  worse: "none",
1204
1204
  at: ["screen", "launch", "press", "drag", "other"],
1205
1205
  producer: "derive",
1206
- label: "Screen updates the PerfLab SDK read",
1206
+ label: "Screen updates the KeepSnappy SDK read",
1207
1207
  short: "screen updates the SDK read",
1208
1208
  decimals: 0,
1209
- what: "How many screen updates the PerfLab SDK read in the window, the ones its time is summed over"
1209
+ what: "How many screen updates the KeepSnappy SDK read in the window, the ones its time is summed over"
1210
1210
  },
1211
1211
  sdk_hook_capped: {
1212
1212
  unit: "count",
@@ -1216,17 +1216,17 @@ var MEASURES = {
1216
1216
  label: "Windows with too many updates to time the SDK",
1217
1217
  short: "windows the SDK time is not known for",
1218
1218
  decimals: 0,
1219
- what: "Windows of this place with more screen updates than the PerfLab SDK keeps times for (5000), so its time there is not given"
1219
+ what: "Windows of this place with more screen updates than the KeepSnappy SDK keeps times for (5000), so its time there is not given"
1220
1220
  },
1221
1221
  js_thread_app_ms: {
1222
1222
  unit: "ms",
1223
1223
  worse: "none",
1224
1224
  at: ["screen", "launch", "press", "drag", "other"],
1225
1225
  producer: "derive",
1226
- label: "JavaScript thread CPU time without the PerfLab SDK",
1226
+ label: "JavaScript thread CPU time without the KeepSnappy SDK",
1227
1227
  short: "JavaScript thread time without the SDK",
1228
1228
  decimals: 0,
1229
- what: "JavaScript thread CPU time in the window minus the time the PerfLab SDK spent after screen updates (not below 0); evidence only, never decides a result. Approximate either way: the thread time is CPU time in 10 ms steps on Android, the SDK time is clock time and includes pauses inside it"
1229
+ what: "JavaScript thread CPU time in the window minus the time the KeepSnappy SDK spent after screen updates (not below 0); evidence only, never decides a result. Approximate either way: the thread time is CPU time in 10 ms steps on Android, the SDK time is clock time and includes pauses inside it"
1230
1230
  },
1231
1231
  main_thread_ms: {
1232
1232
  unit: "ms",
@@ -4205,7 +4205,7 @@ function netMetrics(windows) {
4205
4205
  // packages/derive/dist/src/sampler.js
4206
4206
  var obj6 = (v) => typeof v === "object" && v !== null ? v : {};
4207
4207
  var num6 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined;
4208
- var SAMPLE_MARK = "PERF_LAB sample {";
4208
+ var SAMPLE_MARK = "KEEPSNAPPY sample {";
4209
4209
  function parseSamples(logText) {
4210
4210
  const out = [];
4211
4211
  for (const line of logText.split(`
@@ -4215,7 +4215,7 @@ function parseSamples(logText) {
4215
4215
  continue;
4216
4216
  let raw;
4217
4217
  try {
4218
- raw = JSON.parse(line.slice(sp + 1 + "PERF_LAB sample ".length));
4218
+ raw = JSON.parse(line.slice(sp + 1 + "KEEPSNAPPY sample ".length));
4219
4219
  } catch {
4220
4220
  continue;
4221
4221
  }
@@ -5184,7 +5184,7 @@ function parseMarkersNdjson(text) {
5184
5184
  return out;
5185
5185
  }
5186
5186
  // packages/derive/dist/src/window-log.js
5187
- var WINDOW_MARK = "PERF_LAB window {";
5187
+ var WINDOW_MARK = "KEEPSNAPPY window {";
5188
5188
  function parseWindows(logText) {
5189
5189
  const out = [];
5190
5190
  for (const line of logText.split(`
@@ -5197,7 +5197,7 @@ function parseWindows(logText) {
5197
5197
  continue;
5198
5198
  let raw;
5199
5199
  try {
5200
- raw = JSON.parse(line.slice(sp + 1 + "PERF_LAB window ".length));
5200
+ raw = JSON.parse(line.slice(sp + 1 + "KEEPSNAPPY window ".length));
5201
5201
  } catch {
5202
5202
  continue;
5203
5203
  }
@@ -5294,21 +5294,21 @@ async function uploadRuns(deps, outDir, runs, opts) {
5294
5294
  skipped.push({ run_id: r.run_id, why: r.invalid_reason || "invalid" });
5295
5295
  continue;
5296
5296
  }
5297
- const log = await deps.fs.readFile(join4(outDir, r.run_id, "perf-lab.log"));
5297
+ const log = await deps.fs.readFile(join4(outDir, r.run_id, "keepsnappy.log"));
5298
5298
  const windows = windowsInRun(parseWindows(log), r.t0, r.t1);
5299
5299
  if (windows.length === 0) {
5300
5300
  skipped.push({ run_id: r.run_id, why: "no-windows" });
5301
5301
  continue;
5302
5302
  }
5303
5303
  const externalId = `${opts.externalPrefix}-${r.run_id}`;
5304
- const created = await call(f, opts.ingestUrl, "/v1/runs", { "x-perflab-key": opts.key }, {
5304
+ const created = await call(f, opts.ingestUrl, "/v1/runs", { "x-keepsnappy-key": opts.key }, {
5305
5305
  external_id: externalId,
5306
5306
  started_at: r.t0,
5307
5307
  ended_at: r.t1,
5308
5308
  device: { ...opts.device?.model ? { model: opts.device.model } : {}, ...opts.device?.os ? { os: opts.device.os } : {}, ...opts.device?.id ? { id: opts.device.id } : {}, exclusive: true },
5309
5309
  meta: {
5310
5310
  arm: r.arm,
5311
- driver: opts.driver ?? "perflab-run",
5311
+ driver: opts.driver ?? "keepsnappy-run",
5312
5312
  ...opts.meta,
5313
5313
  ...r.scenario ? { scenario: r.scenario } : {},
5314
5314
  ...opts.runSetId ? { run_set_id: opts.runSetId } : {}
@@ -5318,16 +5318,16 @@ async function uploadRuns(deps, outDir, runs, opts) {
5318
5318
  const token = String(created.run_token ?? "");
5319
5319
  if (!runId || !token)
5320
5320
  throw new UploadError("POST /v1/runs: response has no run_id/run_token");
5321
- const items = windows.map((w) => `${w.endWall} PERF_LAB window ${JSON.stringify(w.raw)}`);
5321
+ const items = windows.map((w) => `${w.endWall} KEEPSNAPPY window ${JSON.stringify(w.raw)}`);
5322
5322
  for (let i = 0;i * size < items.length; i++) {
5323
- await call(f, opts.ingestUrl, "/v1/windows", { "x-perflab-key": opts.key, "x-perflab-run-token": token }, {
5323
+ await call(f, opts.ingestUrl, "/v1/windows", { "x-keepsnappy-key": opts.key, "x-keepsnappy-run-token": token }, {
5324
5324
  batch_id: `${externalId}-${String(i + 1).padStart(4, "0")}`,
5325
5325
  items: items.slice(i * size, (i + 1) * size)
5326
5326
  });
5327
5327
  }
5328
- const samples = samplesInRun(parseSamples(log), r.t0, r.t1).map((x) => `${x.wall} PERF_LAB sample ${JSON.stringify(x.raw)}`);
5328
+ const samples = samplesInRun(parseSamples(log), r.t0, r.t1).map((x) => `${x.wall} KEEPSNAPPY sample ${JSON.stringify(x.raw)}`);
5329
5329
  for (let i = 0;i * size < samples.length; i++) {
5330
- await call(f, opts.ingestUrl, "/v1/windows", { "x-perflab-key": opts.key, "x-perflab-run-token": token }, {
5330
+ await call(f, opts.ingestUrl, "/v1/windows", { "x-keepsnappy-key": opts.key, "x-keepsnappy-run-token": token }, {
5331
5331
  batch_id: `${externalId}-s${String(i + 1).padStart(4, "0")}`,
5332
5332
  items: samples.slice(i * size, (i + 1) * size)
5333
5333
  });
@@ -5339,7 +5339,7 @@ async function uploadRuns(deps, outDir, runs, opts) {
5339
5339
  for (const m of markers) {
5340
5340
  await call(f, opts.ingestUrl, "/v1/markers", { authorization: `Bearer ${token}` }, { step: m.step, phase: m.phase, t_host: m.t_host });
5341
5341
  }
5342
- await call(f, opts.ingestUrl, `/v1/runs/${runId}/finish`, { "x-perflab-key": opts.key }, {});
5342
+ await call(f, opts.ingestUrl, `/v1/runs/${runId}/finish`, { "x-keepsnappy-key": opts.key }, {});
5343
5343
  uploaded++;
5344
5344
  }
5345
5345
  return { uploaded, skipped };
@@ -5570,7 +5570,7 @@ function movedCounts(sc) {
5570
5570
  }
5571
5571
  var addCounts = (xs) => xs.reduce((a, c) => ({ worse: a.worse + c.worse, warnings: a.warnings + c.warnings, better: a.better + c.better, noChange: a.noChange + c.noChange, inconclusive: a.inconclusive + c.inconclusive }), { worse: 0, warnings: 0, better: 0, noChange: 0, inconclusive: 0 });
5572
5572
  var setupLine = (h) => h?.measured_differently?.length ? `Measured differently (${h.measured_differently.join(", ")}) — ${NOT_BLOCKING}` : null;
5573
- var keyHeader = (t) => ({ "x-perflab-key": t.key });
5573
+ var keyHeader = (t) => ({ "x-keepsnappy-key": t.key });
5574
5574
  async function createRunSet(t, body) {
5575
5575
  const r = await call(t.fetch ?? fetch, t.url, "/v1/run-sets", keyHeader(t), body);
5576
5576
  return { run_set_id: String(r.run_set_id), dashboard_url: String(r.dashboard_url) };
@@ -7628,7 +7628,7 @@ function summarizeCpuProfile(raw, sessionId, name) {
7628
7628
  };
7629
7629
  }
7630
7630
 
7631
- // packages/profile-analysis/dist/src/perflab/hermes.js
7631
+ // packages/profile-analysis/dist/src/keepsnappy/hermes.js
7632
7632
  var HERMES_ROOT = "[root]";
7633
7633
  function hermesIdleAsCdp(profile) {
7634
7634
  const hasParent = new Set;
@@ -8205,7 +8205,7 @@ function selectTaskCards(profile, durationMs, taskSet, classes) {
8205
8205
  };
8206
8206
  }
8207
8207
 
8208
- // packages/profile-analysis/dist/src/perflab/keys.js
8208
+ // packages/profile-analysis/dist/src/keepsnappy/keys.js
8209
8209
  function keyPath(path) {
8210
8210
  const normalized = path.replace(/\\/g, "/");
8211
8211
  const marker = normalized.lastIndexOf("node_modules/");
@@ -8228,9 +8228,9 @@ function functionKey(frame, options = {}) {
8228
8228
  return `${name}@${compactLocation(frame.url, frame.lineNumber, frame.columnNumber)}`;
8229
8229
  }
8230
8230
 
8231
- // packages/profile-analysis/dist/src/perflab/measuring.js
8232
- var MEASURING_NAME = "(PerfLab measuring)";
8233
- var SDK_PATH = /(?:^|\/)(?:node_modules\/)?@(?:keepsnappy|perf-labs)\/react-native\//;
8231
+ // packages/profile-analysis/dist/src/keepsnappy/measuring.js
8232
+ var MEASURING_NAME = "(KeepSnappy measuring)";
8233
+ var SDK_PATH = /(?:^|\/)(?:node_modules\/)?@keepsnappy\/react-native\//;
8234
8234
  var SDK_FUNCTION_NAMES = new Set([
8235
8235
  "recordCommit",
8236
8236
  "recordUnmount",
@@ -8263,8 +8263,8 @@ var SDK_FUNCTION_NAMES = new Set([
8263
8263
  "finalizeWindow",
8264
8264
  "windowAggregate",
8265
8265
  "perfLog",
8266
- "handlePerfLabDeepLink",
8267
- "isPerfLabUrl",
8266
+ "handleKeepSnappyDeepLink",
8267
+ "isKeepSnappyUrl",
8268
8268
  "logStartup",
8269
8269
  "addStartupSection",
8270
8270
  "extraStartupSections",
@@ -8343,7 +8343,7 @@ function foldMeasuring(profile) {
8343
8343
  return { profile: { ...profile, nodes, samples }, measuringId };
8344
8344
  }
8345
8345
 
8346
- // packages/profile-analysis/dist/src/perflab/task-cards.js
8346
+ // packages/profile-analysis/dist/src/keepsnappy/task-cards.js
8347
8347
  var REACT_INTERNALS = new Set([
8348
8348
  "propagateParentContextChanges",
8349
8349
  "lazilyPropagateParentContextChanges",
@@ -8481,7 +8481,7 @@ function finishCard(card, measuringMs, profileStartMs) {
8481
8481
  const cleaned = { ...card, boundaryFrames, culprits: keep(card.culprits) };
8482
8482
  const { title, location } = taskCardTitle(cleaned);
8483
8483
  const what = card.boundaries === "measured" ? "task" : "stretch of uninterrupted JS work";
8484
- const measuring = measuringMs >= 1 ? ` (${formatMs(measuringMs)} of it PerfLab's own measuring)` : "";
8484
+ const measuring = measuringMs >= 1 ? ` (${formatMs(measuringMs)} of it KeepSnappy's own measuring)` : "";
8485
8485
  return {
8486
8486
  ...cleaned,
8487
8487
  headline: `${title} — a ${formatMs(card.durationMs)} ${what}${measuring}`,
@@ -8693,7 +8693,7 @@ function originClassTable(frames, origins) {
8693
8693
  }
8694
8694
  // packages/profile-analysis/dist/src/tracesift/lib/card-prompt.js
8695
8695
  var DRAWABLE3 = new Set(SHOWN_CLASSES);
8696
- // packages/profile-analysis/dist/src/perflab/slice.js
8696
+ // packages/profile-analysis/dist/src/keepsnappy/slice.js
8697
8697
  function sliceCpuProfile(profile, window, options = {}) {
8698
8698
  const offsetUs = (options.clockOffsetMs ?? 0) * 1000;
8699
8699
  const t0Us = window.t0Ms * 1000 - offsetUs;
@@ -8765,10 +8765,10 @@ function pruneNodes(nodes, samples) {
8765
8765
  return out;
8766
8766
  });
8767
8767
  }
8768
- // packages/profile-analysis/dist/src/perflab/source-map.js
8768
+ // packages/profile-analysis/dist/src/keepsnappy/source-map.js
8769
8769
  var BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8770
8770
  var BASE64_VALUE = new Map([...BASE64].map((char, index) => [char, index]));
8771
- // packages/profile-analysis/dist/src/perflab/symbolicate.js
8771
+ // packages/profile-analysis/dist/src/keepsnappy/symbolicate.js
8772
8772
  var FRAMEWORK_PACKAGES = new Set([
8773
8773
  "react",
8774
8774
  "react-native",
@@ -8777,9 +8777,9 @@ var FRAMEWORK_PACKAGES = new Set([
8777
8777
  "scheduler",
8778
8778
  "metro-runtime"
8779
8779
  ]);
8780
- // packages/profile-analysis/dist/src/perflab/composition.js
8780
+ // packages/profile-analysis/dist/src/keepsnappy/composition.js
8781
8781
  var HOST_PRIMITIVES = new Set(["View", "Text", "Image", "TextInput", "ScrollView"]);
8782
- // packages/profile-analysis/dist/src/perflab/summary.js
8782
+ // packages/profile-analysis/dist/src/keepsnappy/summary.js
8783
8783
  var DEFAULT_TOP_N = 10;
8784
8784
  var NOT_WORK = new Set(["(root)", "[root]", "(idle)", "(program)"]);
8785
8785
  var MAX_CALLERS2 = 3;
@@ -9020,7 +9020,7 @@ async function extract(deps, outDir, ri, memWindow, clockOffsetMs) {
9020
9020
  let logText = "";
9021
9021
  let cpuProfiles = new Map;
9022
9022
  try {
9023
- const log = await deps.fs.readFile(join6(outDir, r.run_id, "perf-lab.log"));
9023
+ const log = await deps.fs.readFile(join6(outDir, r.run_id, "keepsnappy.log"));
9024
9024
  logText = log;
9025
9025
  cpuProfiles = await readCpuProfiles(deps, join6(outDir, r.run_id), log);
9026
9026
  windows = windowsInRun(parseWindows(log), r.t0, r.t1);
@@ -9141,7 +9141,7 @@ ${r.stderr}` : ""}`);
9141
9141
  try {
9142
9142
  const text = await source.fetchLog(opts.bundleId);
9143
9143
  logText = text;
9144
- await fs.writeFile(join7(dir, "perf-lab.log"), text);
9144
+ await fs.writeFile(join7(dir, "keepsnappy.log"), text);
9145
9145
  windows = windowsInRun(parseWindows(text), t0, t1);
9146
9146
  samples = samplesInRun(parseSamples(text), t0, t1);
9147
9147
  cpuProfiles = await pullCpuProfiles(source, opts.bundleId, text, pulled);
@@ -9150,7 +9150,7 @@ ${r.stderr}` : ""}`);
9150
9150
  await saveCpuProfiles(deps, dir, cpuProfiles);
9151
9151
  } catch (e) {
9152
9152
  if (!reason)
9153
- reason = `no-perf-lab-log: ${e.message}`;
9153
+ reason = `no-keepsnappy-log: ${e.message}`;
9154
9154
  }
9155
9155
  const markers = opts.markers?.forRun(p.runId) ?? [];
9156
9156
  if (markers.length)
@@ -9294,7 +9294,7 @@ async function writeComparisonDataset(deps, baselineDir, outDir) {
9294
9294
  `);
9295
9295
  return dir;
9296
9296
  }
9297
- async function perflabRun(deps, source, opts) {
9297
+ async function keepsnappyRun(deps, source, opts) {
9298
9298
  const { runs, rows: raw } = await measure(deps, source, undefined, {
9299
9299
  arms: [{ name: "A" }],
9300
9300
  repeat: opts.repetitions,
@@ -9321,7 +9321,7 @@ async function replayRuns(deps, sources, outDir, scenario) {
9321
9321
  const runs = [];
9322
9322
  for (const src of sources) {
9323
9323
  const text = await deps.fs.readFile(join9(src.dir, "runs.ndjson")).catch(() => {
9324
- throw new Error(`--replay ${src.dir}: no runs.ndjson (not a perflab out dir)`);
9324
+ throw new Error(`--replay ${src.dir}: no runs.ndjson (not a keepsnappy out dir)`);
9325
9325
  });
9326
9326
  for (const line of text.split(`
9327
9327
  `)) {
@@ -9332,7 +9332,7 @@ async function replayRuns(deps, sources, outDir, scenario) {
9332
9332
  continue;
9333
9333
  const id = `${String(runs.length + 1).padStart(3, "0")}-A`;
9334
9334
  await deps.fs.mkdir(join9(outDir, id));
9335
- for (const f of ["perf-lab.log", "markers.ndjson", "test.log"]) {
9335
+ for (const f of ["keepsnappy.log", "markers.ndjson", "test.log"]) {
9336
9336
  const body = await deps.fs.readFile(join9(src.dir, r.run_id, f)).catch(() => null);
9337
9337
  if (body !== null)
9338
9338
  await deps.fs.writeFile(join9(outDir, id, f), body);
@@ -9350,7 +9350,7 @@ async function replayRuns(deps, sources, outDir, scenario) {
9350
9350
  }
9351
9351
 
9352
9352
  // apps/agent/src/remote-verdict.ts
9353
- var RUN_INFO = "perflab-run.json";
9353
+ var RUN_INFO = "keepsnappy-run.json";
9354
9354
  async function remoteVerdict(deps, outDir, api, opts = {}) {
9355
9355
  let info = {};
9356
9356
  try {
@@ -9401,7 +9401,7 @@ ${output.table}`);
9401
9401
  }
9402
9402
 
9403
9403
  // apps/agent/src/defaults.ts
9404
- var DEFAULT_API_URL = "https://keepsnappy-api-864539138788.europe-west1.run.app";
9404
+ var DEFAULT_API_URL = "https://keepsnappy-api-922918702810.europe-west1.run.app";
9405
9405
 
9406
9406
  // apps/agent/src/journeys.ts
9407
9407
  import { isAbsolute, relative, resolve as resolve2, sep } from "node:path";
@@ -9579,7 +9579,7 @@ async function runCommand(deps, o, positionals, rt = { env: process.env, print:
9579
9579
  }
9580
9580
  }
9581
9581
  deps.log(`running ${flows.length} flow${flows.length === 1 ? "" : "s"} x${repeat}: ${flows.map((f) => f.name).join(", ")}`);
9582
- const outcome = await perflabRun(deps, source, {
9582
+ const outcome = await keepsnappyRun(deps, source, {
9583
9583
  config,
9584
9584
  flows,
9585
9585
  outDir: out,
@@ -9605,7 +9605,7 @@ ${outcome.summary}`);
9605
9605
  device: { ...device, ...config.device && config.device !== "booted" ? { id: config.device } : {} },
9606
9606
  meta: { device_provider: provider, ...git.commit ? { commit_sha: git.commit } : {}, ...git.branch ? { branch: git.branch } : {} },
9607
9607
  ...runSet ? { runSetId: runSet.run_set_id } : {},
9608
- driver: config.flows.runner === "maestro" && positionals.length === 0 ? "maestro" : "perflab-run",
9608
+ driver: config.flows.runner === "maestro" && positionals.length === 0 ? "maestro" : "keepsnappy-run",
9609
9609
  ...api.fetch ? { fetch: api.fetch } : {}
9610
9610
  }).catch(infra(`results are saved in ${out}, but the upload failed`));
9611
9611
  rt.print(`uploaded ${up.uploaded} runs to ${api.url}${up.skipped.length ? ` (${up.skipped.length} skipped: ${up.skipped.map((x) => `${x.run_id} ${x.why}`).join(", ")})` : ""}`);
@@ -9643,7 +9643,7 @@ var infra = (what) => (e) => {
9643
9643
  };
9644
9644
  async function writeResult(deps, out, rt, runSet, summary, branch) {
9645
9645
  const url = summary?.dashboard_url ?? runSet.dashboard_url;
9646
- await deps.fs.writeFile(join11(out, "perflab-result.json"), `${JSON.stringify({ run_set_id: runSet.run_set_id, dashboard_url: url, state: summary?.verdicts?.state ?? null, summary }, null, 2)}
9646
+ await deps.fs.writeFile(join11(out, "keepsnappy-result.json"), `${JSON.stringify({ run_set_id: runSet.run_set_id, dashboard_url: url, state: summary?.verdicts?.state ?? null, summary }, null, 2)}
9647
9647
  `);
9648
9648
  const step = rt.env.GITHUB_STEP_SUMMARY;
9649
9649
  if (step)
@@ -9770,7 +9770,7 @@ import { dirname as dirname3, join as join13, resolve as resolve5 } from "node:p
9770
9770
  // packages/appium-driver/dist/src/links.js
9771
9771
  var ALERT_POLL_MS = 250;
9772
9772
  var RUN_DEFAULTS = { ttl: 3600, profile: 1, diag: 1 };
9773
- var route = (scheme) => `${scheme}devtools/perf-lab`;
9773
+ var route = (scheme) => `${scheme}devtools/keepsnappy`;
9774
9774
  function parseSdkArgs(args) {
9775
9775
  return args.split("&").filter(Boolean).map((kv) => {
9776
9776
  const i = kv.indexOf("=");
@@ -9980,7 +9980,7 @@ class Screen {
9980
9980
  // packages/appium-driver/dist/src/platform.js
9981
9981
  var modelOf2 = (device) => device.replace(/-[^-]*$/, "");
9982
9982
  var versionOf = (device) => device.replace(/^.*-/, "");
9983
- var FLUSH_ID = "perflab.flushed";
9983
+ var FLUSH_ID = "keepsnappy.flushed";
9984
9984
  function parseBroadcastAnswer(out, n) {
9985
9985
  const data = /data="([^"]*)"/.exec(String(out ?? ""))?.[1];
9986
9986
  return data !== undefined && data.startsWith(`gc:${n} `) ? data : null;
@@ -10042,7 +10042,7 @@ var ANDROID = {
10042
10042
  uploadFields: {},
10043
10043
  async gcCommand(driver, n) {
10044
10044
  const out = await driver.execute("mobile: broadcast", {
10045
- action: `${driver.bundleId}.perflab.COMMAND`,
10045
+ action: `${driver.bundleId}.keepsnappy.COMMAND`,
10046
10046
  package: driver.bundleId,
10047
10047
  extras: [["s", "cmd", "gc"], ["i", "n", String(n)]],
10048
10048
  flags: "0x10000000"
@@ -10069,7 +10069,7 @@ import { existsSync, readFileSync, statSync } from "node:fs";
10069
10069
  import { dirname as dirname2, join as join12, relative as relative2, resolve as resolve4 } from "node:path";
10070
10070
  import { fileURLToPath } from "node:url";
10071
10071
  function driverVersion() {
10072
- const built = "0.1.0-alpha.12";
10072
+ const built = "0.1.0-alpha.13";
10073
10073
  if (built)
10074
10074
  return built;
10075
10075
  let dir = dirname2(fileURLToPath(import.meta.url));
@@ -10328,7 +10328,7 @@ function linksCommand(cmd, argv, rt) {
10328
10328
  rt.print(activationLink(o.scheme, o.token, set.join("&")));
10329
10329
  return 0;
10330
10330
  }
10331
- var maestroLinkFields = (sdkArgs = "") => ({ perflabLinkArgs: linkArgs(sdkArgs) });
10331
+ var maestroLinkFields = (sdkArgs = "") => ({ keepsnappyLinkArgs: linkArgs(sdkArgs) });
10332
10332
 
10333
10333
  // apps/agent/src/farm.ts
10334
10334
  var STATE_VERSION = 1;
@@ -10355,17 +10355,17 @@ function instrumentFlags(f) {
10355
10355
  const journey = f["journey-version"] ?? hash;
10356
10356
  return { ...driver ? { "driver-version": driver } : {}, ...journey ? { "journey-version": journey } : {} };
10357
10357
  }
10358
- var TOKENS_STUB = "// Replaced by `keepsnappy farm open` for one upload. Never commit real tokens.\noutput.perflabTokens = {};\n";
10358
+ var TOKENS_STUB = "// Replaced by `keepsnappy farm open` for one upload. Never commit real tokens.\noutput.keepsnappyTokens = {};\n";
10359
10359
  var JOURNEY = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
10360
10360
  var DEFAULT_TTL = 21600;
10361
10361
  var POLL_MS = 5000;
10362
10362
  function tokensJs(api, runSetId, tokens, links = maestroLinkFields()) {
10363
10363
  return [
10364
10364
  `// Generated by \`keepsnappy farm open\` for run set ${runSetId}. Overlaid into the suite for one upload; never commit.`,
10365
- `output.perflabApi = ${JSON.stringify(api.replace(/\/+$/, ""))};`,
10366
- `output.perflabRunSet = ${JSON.stringify(runSetId)};`,
10367
- `output.perflabTokens = ${JSON.stringify(tokens)};`,
10368
- `output.perflabLinkArgs = ${JSON.stringify(links.perflabLinkArgs)};`,
10365
+ `output.keepsnappyApi = ${JSON.stringify(api.replace(/\/+$/, ""))};`,
10366
+ `output.keepsnappyRunSet = ${JSON.stringify(runSetId)};`,
10367
+ `output.keepsnappyTokens = ${JSON.stringify(tokens)};`,
10368
+ `output.keepsnappyLinkArgs = ${JSON.stringify(links.keepsnappyLinkArgs)};`,
10369
10369
  ""
10370
10370
  ].join(`
10371
10371
  `);
@@ -10443,7 +10443,7 @@ async function farmOpen(deps, f, rt) {
10443
10443
  if (!Number.isInteger(ttl) || ttl < 60)
10444
10444
  problems.push("--ttl-seconds must be a whole number >= 60");
10445
10445
  if (!f["tokens-js"])
10446
- problems.push("--tokens-js <path> is required (the file the suite overlay puts at flows/perflab/tokens.js)");
10446
+ problems.push("--tokens-js <path> is required (the file the suite overlay puts at flows/keepsnappy/tokens.js)");
10447
10447
  if (!f.state)
10448
10448
  problems.push("--state <path> is required (read by keepsnappy farm close)");
10449
10449
  if (problems.length)
@@ -10712,7 +10712,7 @@ async function closeRunSet(deps, f, rt, state, statePath) {
10712
10712
  await deps.fs.writeFile(statePath, `${JSON.stringify(state2, null, 2)}
10713
10713
  `);
10714
10714
  await deps.fs.mkdir(out);
10715
- await deps.fs.writeFile(join13(out, "perflab-result.json"), `${JSON.stringify({ run_set_id: state.run_set_id, dashboard_url: summary.dashboard_url, state: state2.result.state, session: { status: session.status, message: session.message }, summary }, null, 2)}
10715
+ await deps.fs.writeFile(join13(out, "keepsnappy-result.json"), `${JSON.stringify({ run_set_id: state.run_set_id, dashboard_url: summary.dashboard_url, state: state2.result.state, session: { status: session.status, message: session.message }, summary }, null, 2)}
10716
10716
  `);
10717
10717
  await githubOutputs(deps, rt, { state: state2.result.state ?? "none", dashboard_url: summary.dashboard_url, run_set_id: state.run_set_id });
10718
10718
  const step = rt.env.GITHUB_STEP_SUMMARY;
@@ -10893,7 +10893,7 @@ class BrowserStack {
10893
10893
  }
10894
10894
  async runMaestro(b) {
10895
10895
  const appUrl = await this.uploadApp(b.app, b.customId);
10896
- const work = join15(this.o.tmpDir ?? "/tmp", `perflab-suite-${(this.o.uniqueId ?? randomUUID)()}`);
10896
+ const work = join15(this.o.tmpDir ?? "/tmp", `keepsnappy-suite-${(this.o.uniqueId ?? randomUUID)()}`);
10897
10897
  let suiteUrl;
10898
10898
  try {
10899
10899
  const zip = await this.zipSuite(b, work);
@@ -10911,8 +10911,8 @@ class BrowserStack {
10911
10911
  testSuite: suiteUrl,
10912
10912
  devices: [b.device],
10913
10913
  setEnvVariables: { ...b.env, RUN_ID: b.runId },
10914
- buildTag: `perflab-${b.runId}`,
10915
- customBuildName: `perflab ${b.runId} ${b.platform}`,
10914
+ buildTag: `keepsnappy-${b.runId}`,
10915
+ customBuildName: `keepsnappy ${b.runId} ${b.platform}`,
10916
10916
  execute: [b.execute],
10917
10917
  deviceLogs: true,
10918
10918
  ...b.localIdentifier ? { local: "true", localIdentifier: b.localIdentifier } : {},
@@ -11045,7 +11045,7 @@ function nodeFarmRunPorts(deps, rt) {
11045
11045
  if (!user || !key)
11046
11046
  throw new ConfigError(["BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY must be set"]);
11047
11047
  const tmp = rt.env.RUNNER_TEMP ?? rt.env.TMPDIR ?? "/tmp";
11048
- const dir = join16(tmp, "perflab-bs-local");
11048
+ const dir = join16(tmp, "keepsnappy-bs-local");
11049
11049
  return {
11050
11050
  apps: new DefaultAppResolver(deps, rt.env),
11051
11051
  provider: new BrowserStack(deps, { credentials: { user, key }, tmpDir: tmp, ...rt.fetch ? { fetch: rt.fetch } : {}, ...rt.sleep ? { sleep: rt.sleep } : {}, ...rt.now ? { now: rt.now } : {} }),
@@ -11158,10 +11158,10 @@ function printPlan(p, f, rt) {
11158
11158
  line("keepsnappy farm run: dry run, no request is made and nothing is written");
11159
11159
  line(` 1. validate: ${p.journeys.join(", ")} x ${p.repeat} on ${p.device} (${p.platform}), driver ${p.driver}`);
11160
11160
  line(` 2. resolve the app: ${p.app.startsWith("eas:") ? `eas-cli build:view ${p.app.slice(4)}, download into ${p.out}` : p.app.startsWith("bs://") ? "bs:// passes through" : `${p.app} (local file)`}`);
11161
- line(` 3. farm open -> ${join16(p.out, "perflab-tokens.js")}, ${join16(p.out, "perflab-farm.json")} (POST /v1/run-sets, then POST /v1/runs x ${p.journeys.length * p.repeat})`);
11161
+ line(` 3. farm open -> ${join16(p.out, "keepsnappy-tokens.js")}, ${join16(p.out, "keepsnappy-farm.json")} (POST /v1/run-sets, then POST /v1/runs x ${p.journeys.length * p.repeat})`);
11162
11162
  line(` 4. tunnel: ${p.ports.length ? `BrowserStackLocal for bs-local.com ports ${p.ports.join(", ")}, identifier = run id` : "none (no --tunnel-for)"}`);
11163
11163
  if (p.driver === "maestro") {
11164
- line(` 5. maestro on BrowserStack: upload app, zip ${f["suite-dir"]} with the tokens at ${f["tokens-path"] ?? "flows/perflab/tokens.js"}, upload suite, POST build (execute ${f.execute}), poll`);
11164
+ line(` 5. maestro on BrowserStack: upload app, zip ${f["suite-dir"]} with the tokens at ${f["tokens-path"] ?? "flows/keepsnappy/tokens.js"}, upload suite, POST build (execute ${f.execute}), poll`);
11165
11165
  } else {
11166
11166
  line(` 5. appium: ${f["journey-module"] ? `built-in driver, journey module ${f["journey-module"]}` : `node ${f["driver-script"]}`} --platform ${p.platform} --device ... --tokens-js ... --journeys ... --repeat ${p.repeat}${p.driverArgs.length ? ` ${p.driverArgs.map((a) => substitute(a, {})).join(" ")}` : ""}`);
11167
11167
  }
@@ -11180,7 +11180,7 @@ async function runDriver2(deps, rt, f, p, ports, ctx) {
11180
11180
  app: ctx.app,
11181
11181
  ...f["custom-id"] ? { customId: f["custom-id"] } : {},
11182
11182
  suiteDir: resolve6(f["suite-dir"]),
11183
- tokensPath: f["tokens-path"] ?? "flows/perflab/tokens.js",
11183
+ tokensPath: f["tokens-path"] ?? "flows/keepsnappy/tokens.js",
11184
11184
  tokensJs: ctx.tokensJs,
11185
11185
  execute: f.execute,
11186
11186
  runId: ctx.runId,
@@ -11251,7 +11251,7 @@ async function runDriver2(deps, rt, f, p, ports, ctx) {
11251
11251
  }
11252
11252
  async function farmRun(deps, f, rt, ports) {
11253
11253
  const p = planFarmRun(f);
11254
- const statePath = join16(p.out, "perflab-farm.json");
11254
+ const statePath = join16(p.out, "keepsnappy-farm.json");
11255
11255
  if (await deps.fs.exists(statePath))
11256
11256
  throw new ConfigError([`${statePath} exists: a run set was opened here before; use another --out or remove ${p.out} (close it first with keepsnappy farm close)`]);
11257
11257
  if (f["dry-run"]) {
@@ -11259,7 +11259,7 @@ async function farmRun(deps, f, rt, ports) {
11259
11259
  return EXIT.ok;
11260
11260
  }
11261
11261
  const farm = ports ?? nodeFarmRunPorts(deps, rt);
11262
- const tokensJs = join16(p.out, "perflab-tokens.js");
11262
+ const tokensJs = join16(p.out, "keepsnappy-tokens.js");
11263
11263
  await deps.fs.mkdir(p.out);
11264
11264
  const resolved = await farm.apps.resolve(p.app, { outDir: p.out });
11265
11265
  const commit = f.commit ?? resolved.commit ?? undefined;
@@ -11287,7 +11287,7 @@ async function farmRun(deps, f, rt, ports) {
11287
11287
  return openCode;
11288
11288
  opened = true;
11289
11289
  const state = JSON.parse(await deps.fs.readFile(statePath));
11290
- const runId = f["run-id"] ?? `perflab-${p.platform}-${state.run_set_id.slice(0, 8)}`;
11290
+ const runId = f["run-id"] ?? `keepsnappy-${p.platform}-${state.run_set_id.slice(0, 8)}`;
11291
11291
  const ctx = { runId, out: p.out, tokensJs, runSetId: state.run_set_id, app: resolved.app };
11292
11292
  try {
11293
11293
  await deps.spawner.run("rm", ["-f", join16(p.out, `browserstack.${p.platform}.json`)]);
@@ -11371,7 +11371,7 @@ async function put(f, upload, body) {
11371
11371
  async function uploadSourcemaps(opts) {
11372
11372
  const f = opts.fetch ?? fetch;
11373
11373
  const read = opts.readFile ?? ((p) => readFile4(p, "utf8"));
11374
- const headers = { "x-perflab-key": opts.key };
11374
+ const headers = { "x-keepsnappy-key": opts.key };
11375
11375
  const out = [];
11376
11376
  for (const file of opts.files) {
11377
11377
  let parsed;
@@ -11625,7 +11625,7 @@ async function get(t, path, query = {}) {
11625
11625
  for (const [k, v] of Object.entries(query))
11626
11626
  if (v !== undefined && v !== "")
11627
11627
  u.searchParams.set(k, String(v));
11628
- const r = await (t.fetch ?? fetch)(u, { headers: { "x-perflab-key": t.key, accept: "application/json" } });
11628
+ const r = await (t.fetch ?? fetch)(u, { headers: { "x-keepsnappy-key": t.key, accept: "application/json" } });
11629
11629
  const text = await r.text();
11630
11630
  const body = text ? JSON.parse(text) : {};
11631
11631
  if (!r.ok) {
@@ -11767,7 +11767,7 @@ var USAGE = `keepsnappy <command>
11767
11767
  farm close --state <file> [--wait [--fail-on-worse]] [--bs-build browserstack.ios.json] [--settle-seconds 60] [--max-wait-seconds 300] [--out DIR]
11768
11768
  farm run --app <eas:ID|file.ipa|bs://ID> --journeys a,b [--repeat 5] --device "iPhone 15 Pro-17" [--platform ios|android] [--driver maestro|appium]
11769
11769
  [--tunnel-for localhost:PORT ...] [--env KEY=VALUE ...] (values may use {tunnel:PORT} {run_id} {out} {tokens_js} {run_set_id})
11770
- maestro: --suite-dir DIR --execute FLOW [--tokens-path flows/perflab/tokens.js] [--maestro-version V]
11770
+ maestro: --suite-dir DIR --execute FLOW [--tokens-path flows/keepsnappy/tokens.js] [--maestro-version V]
11771
11771
  appium: --journey-module FILE | --driver-script FILE [--driver-arg ARG ...]
11772
11772
  [--branch NAME --commit SHA] [--wait [--fail-on-worse]] [--out DIR] [--dry-run] (open + tunnel + device + close; docs/plans/54a)
11773
11773
  extract <out-dir> --ri-capture observations.ndjson [--mem-window NAME]
@@ -11899,7 +11899,7 @@ async function main2(argv) {
11899
11899
  if (platform === "ios-device" && !o.device)
11900
11900
  throw new Error("--device <udid> is required for ios-device");
11901
11901
  const arms = parseArmEnv(o["arm-env"], parseArms(o.arms));
11902
- const out = resolve7(o.out ?? `perflab-${new Date().toISOString().replace(/[:.]/g, "-")}`);
11902
+ const out = resolve7(o.out ?? `keepsnappy-${new Date().toISOString().replace(/[:.]/g, "-")}`);
11903
11903
  const udid = o.device ?? "booted";
11904
11904
  const source = platform === "ios-sim" ? new IosSimulatorDataSource(deps, udid) : new IosDeviceDataSource(deps, udid, resolve7(out, ".scratch"));
11905
11905
  const installer = platform === "ios-sim" ? new IosSimulatorInstaller(deps, udid) : new IosDeviceInstaller(deps, udid);
@@ -13,5 +13,5 @@ appId: com.gigaverse.appdev
13
13
  id: ${output.elements.home.screen}
14
14
  timeout: 30000
15
15
  # The settings come from tokens.js (`keepsnappy farm open`): the run defaults, never written by hand here (REQ-FARM-28).
16
- - openLink: gigaversedev://devtools/perf-lab?activate=1&${output.perflabLinkArgs}&runToken=${output.perflabToken}
16
+ - openLink: gigaversedev://devtools/keepsnappy?activate=1&${output.keepsnappyLinkArgs}&runToken=${output.keepsnappyToken}
17
17
  - runFlow: ../../subflows/confirm-open-link.yaml
@@ -1,16 +1,16 @@
1
1
  # End of one measured iteration: the SDK sends everything still unsent (nothing is sent while a run is active), then
2
- # shows `perflab.flushed` (ok | error | off). `activate=0` makes the next launch dormant again.
2
+ # shows `keepsnappy.flushed` (ok | error | off). `activate=0` makes the next launch dormant again.
3
3
  appId: com.gigaverse.appdev
4
4
  ---
5
5
  - runScript: send-markers.js # the iteration's step markers, recorded by step.js, sent now that it has ended
6
- - openLink: gigaversedev://devtools/perf-lab?flush=1&activate=0
6
+ - openLink: gigaversedev://devtools/keepsnappy?flush=1&activate=0
7
7
  - runFlow: ../../subflows/confirm-open-link.yaml
8
8
  - extendedWaitUntil:
9
9
  visible:
10
- id: perflab.flushed
10
+ id: keepsnappy.flushed
11
11
  timeout: 60000
12
12
  optional: true # a dormant iteration (activation failed) shows nothing; farm close marks it invalid
13
13
  - assertVisible:
14
- id: perflab.flushed
14
+ id: keepsnappy.flushed
15
15
  text: ok
16
16
  optional: true
@@ -0,0 +1,7 @@
1
+ // Hands out the run tokens of one journey in order: iteration i of JOURNEY gets output.keepsnappyTokens[JOURNEY][i].
2
+ // ES5 (Maestro runScript). An empty token (more iterations than tokens) leaves the SDK dormant: no data, no harm.
3
+ var list = (output.keepsnappyTokens || {})[JOURNEY] || [];
4
+ output.keepsnappyIdx = output.keepsnappyIdx || {};
5
+ var i = output.keepsnappyIdx[JOURNEY] || 0;
6
+ output.keepsnappyToken = list[i] || '';
7
+ output.keepsnappyIdx[JOURNEY] = i + 1;
@@ -1,4 +1,4 @@
1
- # e2e/flows/perflab/run-perflab.yaml (plan 36 D10). One BrowserStack session runs every iteration: the session is the
1
+ # e2e/flows/keepsnappy/run-keepsnappy.yaml (plan 36 D10). One BrowserStack session runs every iteration: the session is the
2
2
  # noise block. Untagged, so smoke/regression never select it; the dispatcher names it with --execute.
3
3
  # `times` must equal `keepsnappy farm open --repeat`. One begin/journey/end triple per journey listed in --journeys.
4
4
  appId: com.gigaverse.appdev