@agent-scope/cli 1.15.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1107,9 +1107,9 @@ function createRL() {
1107
1107
  });
1108
1108
  }
1109
1109
  async function ask(rl, question) {
1110
- return new Promise((resolve15) => {
1110
+ return new Promise((resolve16) => {
1111
1111
  rl.question(question, (answer) => {
1112
- resolve15(answer.trim());
1112
+ resolve16(answer.trim());
1113
1113
  });
1114
1114
  });
1115
1115
  }
@@ -2389,8 +2389,8 @@ Available: ${available}`
2389
2389
  wastedRenders: opts.wastedRenders
2390
2390
  });
2391
2391
  await shutdownPool2();
2392
- const fmt = resolveFormat2(opts.format);
2393
- if (fmt === "json") {
2392
+ const fmt2 = resolveFormat2(opts.format);
2393
+ if (fmt2 === "json") {
2394
2394
  process.stdout.write(`${JSON.stringify(instrumentRoot, null, 2)}
2395
2395
  `);
2396
2396
  } else {
@@ -3109,12 +3109,12 @@ Available: ${available}`
3109
3109
  );
3110
3110
  return;
3111
3111
  }
3112
- const fmt = resolveSingleFormat(opts.format);
3113
- if (fmt === "json") {
3112
+ const fmt2 = resolveSingleFormat(opts.format);
3113
+ if (fmt2 === "json") {
3114
3114
  const json = formatRenderJson(componentName, props, result);
3115
3115
  process.stdout.write(`${JSON.stringify(json, null, 2)}
3116
3116
  `);
3117
- } else if (fmt === "file") {
3117
+ } else if (fmt2 === "file") {
3118
3118
  const dir = resolve(process.cwd(), DEFAULT_OUTPUT_DIR);
3119
3119
  mkdirSync(dir, { recursive: true });
3120
3120
  const outPath = resolve(dir, `${componentName}.png`);
@@ -3235,8 +3235,8 @@ Available: ${available}`
3235
3235
  process.stderr.write(`Sprite sheet saved to ${spritePath}
3236
3236
  `);
3237
3237
  }
3238
- const fmt = resolveMatrixFormat(opts.format, opts.sprite !== void 0);
3239
- if (fmt === "file") {
3238
+ const fmt2 = resolveMatrixFormat(opts.format, opts.sprite !== void 0);
3239
+ if (fmt2 === "file") {
3240
3240
  const { SpriteSheetGenerator: SpriteSheetGenerator2 } = await import('@agent-scope/render');
3241
3241
  const gen = new SpriteSheetGenerator2();
3242
3242
  const sheet = await gen.generate(result);
@@ -3249,10 +3249,10 @@ Available: ${available}`
3249
3249
  `\u2713 ${componentName} matrix (${result.stats.totalCells} cells) \u2192 ${relPath} (${result.stats.wallClockTimeMs.toFixed(0)}ms total)
3250
3250
  `
3251
3251
  );
3252
- } else if (fmt === "json") {
3252
+ } else if (fmt2 === "json") {
3253
3253
  process.stdout.write(`${JSON.stringify(formatMatrixJson(result), null, 2)}
3254
3254
  `);
3255
- } else if (fmt === "png") {
3255
+ } else if (fmt2 === "png") {
3256
3256
  if (opts.sprite !== void 0) {
3257
3257
  } else {
3258
3258
  const { SpriteSheetGenerator: SpriteSheetGenerator2 } = await import('@agent-scope/render');
@@ -3260,9 +3260,9 @@ Available: ${available}`
3260
3260
  const sheet = await gen.generate(result);
3261
3261
  process.stdout.write(sheet.png);
3262
3262
  }
3263
- } else if (fmt === "html") {
3263
+ } else if (fmt2 === "html") {
3264
3264
  process.stdout.write(formatMatrixHtml(componentName, result));
3265
- } else if (fmt === "csv") {
3265
+ } else if (fmt2 === "csv") {
3266
3266
  process.stdout.write(formatMatrixCsv(componentName, result));
3267
3267
  }
3268
3268
  } catch (err) {
@@ -3563,12 +3563,12 @@ async function runBaseline(options = {}) {
3563
3563
  mkdirSync(rendersDir, { recursive: true });
3564
3564
  let manifest;
3565
3565
  if (manifestPath !== void 0) {
3566
- const { readFileSync: readFileSync11 } = await import('fs');
3566
+ const { readFileSync: readFileSync12 } = await import('fs');
3567
3567
  const absPath = resolve(rootDir, manifestPath);
3568
3568
  if (!existsSync(absPath)) {
3569
3569
  throw new Error(`Manifest not found at ${absPath}.`);
3570
3570
  }
3571
- manifest = JSON.parse(readFileSync11(absPath, "utf-8"));
3571
+ manifest = JSON.parse(readFileSync12(absPath, "utf-8"));
3572
3572
  process.stderr.write(`Loaded manifest from ${manifestPath}
3573
3573
  `);
3574
3574
  } else {
@@ -4202,6 +4202,135 @@ function registerDiffSubCommand(reportCmd) {
4202
4202
  }
4203
4203
  );
4204
4204
  }
4205
+ var STATUS_BADGE = {
4206
+ added: "\u2705 added",
4207
+ removed: "\u{1F5D1}\uFE0F removed",
4208
+ unchanged: "\u2014 unchanged",
4209
+ compliance_regressed: "\u274C regressed",
4210
+ compliance_improved: "\u{1F4C8} improved",
4211
+ size_changed: "\u{1F4D0} resized"
4212
+ };
4213
+ function fmt(n) {
4214
+ return `${(n * 100).toFixed(1)}%`;
4215
+ }
4216
+ function fmtDelta(delta) {
4217
+ if (delta === null) return "\u2014";
4218
+ const sign = delta >= 0 ? "+" : "";
4219
+ return `${sign}${(delta * 100).toFixed(1)}%`;
4220
+ }
4221
+ function fmtDimensions(d) {
4222
+ if (d === null) return "\u2014";
4223
+ return `${d.width} \xD7 ${d.height}`;
4224
+ }
4225
+ function complianceDeltaArrow(diff) {
4226
+ const delta = diff.currentAggregateCompliance - diff.baselineAggregateCompliance;
4227
+ if (Math.abs(delta) < 5e-4) return `\u2192 ${fmt(diff.currentAggregateCompliance)} (no change)`;
4228
+ const arrow = delta > 0 ? "\u2191" : "\u2193";
4229
+ return `${arrow} ${fmtDelta(delta)}`;
4230
+ }
4231
+ function formatPrComment(diff) {
4232
+ const { summary, components } = diff;
4233
+ const lines = [];
4234
+ const hasRegressions = diff.hasRegressions;
4235
+ const headerEmoji = hasRegressions ? "\u26A0\uFE0F" : "\u2705";
4236
+ lines.push(`## ${headerEmoji} Scope Report`);
4237
+ lines.push("");
4238
+ lines.push("| Metric | Value |");
4239
+ lines.push("|---|---|");
4240
+ lines.push(`| Baseline compliance | ${fmt(diff.baselineAggregateCompliance)} |`);
4241
+ lines.push(`| Current compliance | ${fmt(diff.currentAggregateCompliance)} |`);
4242
+ lines.push(`| Delta | ${complianceDeltaArrow(diff)} |`);
4243
+ lines.push(
4244
+ `| Components | ${summary.total} total \xB7 ${summary.added} added \xB7 ${summary.removed} removed \xB7 ${summary.complianceRegressed} regressed |`
4245
+ );
4246
+ if (summary.renderFailed > 0) {
4247
+ lines.push(`| Render failures | ${summary.renderFailed} |`);
4248
+ }
4249
+ lines.push("");
4250
+ const changed = components.filter((c) => c.status !== "unchanged");
4251
+ const unchanged = components.filter((c) => c.status === "unchanged");
4252
+ if (changed.length > 0) {
4253
+ lines.push("### Changes");
4254
+ lines.push("");
4255
+ lines.push("| Component | Status | Compliance \u0394 | Dimensions |");
4256
+ lines.push("|---|---|---|---|");
4257
+ for (const c of changed) {
4258
+ const badge = STATUS_BADGE[c.status];
4259
+ const delta = fmtDelta(c.complianceDelta);
4260
+ const dims = fmtDimensions(c.currentDimensions ?? c.baselineDimensions);
4261
+ lines.push(`| \`${c.name}\` | ${badge} | ${delta} | ${dims} |`);
4262
+ }
4263
+ lines.push("");
4264
+ }
4265
+ if (unchanged.length > 0) {
4266
+ lines.push(
4267
+ `<details><summary>${unchanged.length} unchanged component${unchanged.length === 1 ? "" : "s"}</summary>`
4268
+ );
4269
+ lines.push("");
4270
+ lines.push("| Component | Compliance |");
4271
+ lines.push("|---|---|");
4272
+ for (const c of unchanged) {
4273
+ lines.push(
4274
+ `| \`${c.name}\` | ${c.currentCompliance !== null ? fmt(c.currentCompliance) : "\u2014"} |`
4275
+ );
4276
+ }
4277
+ lines.push("");
4278
+ lines.push("</details>");
4279
+ lines.push("");
4280
+ }
4281
+ lines.push(
4282
+ `> Generated by [Scope](https://github.com/FlatFilers/Scope) \xB7 diffed at ${diff.diffedAt}`
4283
+ );
4284
+ return lines.join("\n");
4285
+ }
4286
+ function loadDiffResult(filePath) {
4287
+ const abs = resolve(filePath);
4288
+ if (!existsSync(abs)) {
4289
+ throw new Error(`DiffResult file not found: ${abs}`);
4290
+ }
4291
+ let raw;
4292
+ try {
4293
+ raw = readFileSync(abs, "utf-8");
4294
+ } catch (err) {
4295
+ throw new Error(
4296
+ `Failed to read DiffResult file: ${err instanceof Error ? err.message : String(err)}`
4297
+ );
4298
+ }
4299
+ let parsed;
4300
+ try {
4301
+ parsed = JSON.parse(raw);
4302
+ } catch {
4303
+ throw new Error(`DiffResult file is not valid JSON: ${abs}`);
4304
+ }
4305
+ if (typeof parsed !== "object" || parsed === null || !("diffedAt" in parsed) || !("components" in parsed) || !("summary" in parsed)) {
4306
+ throw new Error(
4307
+ `DiffResult file does not match expected shape (missing diffedAt/components/summary): ${abs}`
4308
+ );
4309
+ }
4310
+ return parsed;
4311
+ }
4312
+ function registerPrCommentSubCommand(reportCmd) {
4313
+ reportCmd.command("pr-comment").description(
4314
+ "Format a DiffResult JSON file as a GitHub PR comment (Markdown, written to stdout)"
4315
+ ).requiredOption("-i, --input <path>", "Path to DiffResult JSON (from scope report diff --json)").option("-o, --output <path>", "Write comment to file instead of stdout").action(async (opts) => {
4316
+ try {
4317
+ const diff = loadDiffResult(opts.input);
4318
+ const comment = formatPrComment(diff);
4319
+ if (opts.output !== void 0) {
4320
+ writeFileSync(resolve(opts.output), comment, "utf-8");
4321
+ process.stderr.write(`PR comment written to ${opts.output}
4322
+ `);
4323
+ } else {
4324
+ process.stdout.write(`${comment}
4325
+ `);
4326
+ }
4327
+ } catch (err) {
4328
+ process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
4329
+ `);
4330
+ process.exit(1);
4331
+ }
4332
+ });
4333
+ }
4205
4334
 
4206
4335
  // src/tree-formatter.ts
4207
4336
  var BRANCH2 = "\u251C\u2500\u2500 ";
@@ -5497,6 +5626,7 @@ function createProgram(options = {}) {
5497
5626
  if (existingReportCmd !== void 0) {
5498
5627
  registerBaselineSubCommand(existingReportCmd);
5499
5628
  registerDiffSubCommand(existingReportCmd);
5629
+ registerPrCommentSubCommand(existingReportCmd);
5500
5630
  }
5501
5631
  return program;
5502
5632
  }