@frontman-ai/astro 0.4.1 → 0.4.2

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
@@ -1,6 +1,6 @@
1
1
  import * as Fs from 'fs';
2
2
  import { existsSync, readFileSync } from 'fs';
3
- import * as Nodepath from 'path';
3
+ import * as Nodepath4 from 'path';
4
4
  import { dirname, join } from 'path';
5
5
  import * as Nodebuffer from 'buffer';
6
6
  import * as Nodechild_process from 'child_process';
@@ -72,7 +72,7 @@ function forEach(opt, f) {
72
72
  return f(valFromOption(opt));
73
73
  }
74
74
  }
75
- function getOrThrow(x, message3) {
75
+ function getOrThrow(x, message4) {
76
76
  if (x !== void 0) {
77
77
  return valFromOption(x);
78
78
  } else {
@@ -462,22 +462,22 @@ function create(str) {
462
462
  // ../../node_modules/sury/src/Sury.res.mjs
463
463
  var immutableEmpty = {};
464
464
  var immutableEmpty$1 = [];
465
- function capitalize(string3) {
466
- return string3.slice(0, 1).toUpperCase() + string3.slice(1);
465
+ function capitalize(string4) {
466
+ return string4.slice(0, 1).toUpperCase() + string4.slice(1);
467
467
  }
468
468
  var copy = ((d2) => ({ ...d2 }));
469
- function fromString(string3) {
469
+ function fromString(string4) {
470
470
  let _idx = 0;
471
471
  while (true) {
472
472
  let idx = _idx;
473
- let match = string3[idx];
473
+ let match = string4[idx];
474
474
  if (match === void 0) {
475
- return `"` + string3 + `"`;
475
+ return `"` + string4 + `"`;
476
476
  }
477
477
  switch (match) {
478
478
  case '"':
479
479
  case "\n":
480
- return JSON.stringify(string3);
480
+ return JSON.stringify(string4);
481
481
  default:
482
482
  _idx = idx + 1 | 0;
483
483
  continue;
@@ -545,14 +545,14 @@ function stringify(unknown2) {
545
545
  return "null";
546
546
  }
547
547
  if (Array.isArray(unknown2)) {
548
- let string3 = "[";
548
+ let string4 = "[";
549
549
  for (let i = 0, i_finish = unknown2.length; i < i_finish; ++i) {
550
550
  if (i !== 0) {
551
- string3 = string3 + ", ";
551
+ string4 = string4 + ", ";
552
552
  }
553
- string3 = string3 + stringify(unknown2[i]);
553
+ string4 = string4 + stringify(unknown2[i]);
554
554
  }
555
- return string3 + "]";
555
+ return string4 + "]";
556
556
  }
557
557
  if (unknown2.constructor !== Object) {
558
558
  return Object.prototype.toString.call(unknown2);
@@ -569,9 +569,9 @@ function stringify(unknown2) {
569
569
  function toExpression(schema3) {
570
570
  let tag = schema3.type;
571
571
  let $$const = schema3.const;
572
- let name14 = schema3.name;
573
- if (name14 !== void 0) {
574
- return name14;
572
+ let name15 = schema3.name;
573
+ if (name15 !== void 0) {
574
+ return name15;
575
575
  }
576
576
  if ($$const !== void 0) {
577
577
  return stringify($$const);
@@ -732,8 +732,8 @@ var shakenTraps = {
732
732
  return target[prop];
733
733
  }
734
734
  let l$1 = valFromOption(l);
735
- let message3 = `Schema S.` + l$1 + ` is not enabled. To start using it, add S.enable` + capitalize(l$1) + `() at the project root.`;
736
- throw new Error(`[Sury] ` + message3);
735
+ let message4 = `Schema S.` + l$1 + ` is not enabled. To start using it, add S.enable` + capitalize(l$1) + `() at the project root.`;
736
+ throw new Error(`[Sury] ` + message4);
737
737
  }
738
738
  };
739
739
  function shaken(apiName) {
@@ -1691,10 +1691,10 @@ function isPriority(tagFlag, byKey) {
1691
1691
  }
1692
1692
  }
1693
1693
  function isWiderUnionSchema(schemaAnyOf, inputAnyOf) {
1694
- return inputAnyOf.every((inputSchema13, idx) => {
1694
+ return inputAnyOf.every((inputSchema14, idx) => {
1695
1695
  let schema3 = schemaAnyOf[idx];
1696
- if (schema3 !== void 0 && !(flags[inputSchema13.type] & 9152) && inputSchema13.type === schema3.type) {
1697
- return inputSchema13.const === schema3.const;
1696
+ if (schema3 !== void 0 && !(flags[inputSchema14.type] & 9152) && inputSchema14.type === schema3.type) {
1697
+ return inputSchema14.const === schema3.const;
1698
1698
  } else {
1699
1699
  return false;
1700
1700
  }
@@ -2740,8 +2740,8 @@ function argsToString(args) {
2740
2740
  function stripAnsi(str) {
2741
2741
  return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
2742
2742
  }
2743
- function addLog(state, level, message3, attributes, consoleMethod) {
2744
- let cleanMessage = stripAnsi(message3).trim();
2743
+ function addLog(state, level, message4, attributes, consoleMethod) {
2744
+ let cleanMessage = stripAnsi(message4).trim();
2745
2745
  if (cleanMessage === "") {
2746
2746
  return;
2747
2747
  }
@@ -2818,11 +2818,11 @@ var interceptConsole = (function(state) {
2818
2818
  originalDebug(...args);
2819
2819
  };
2820
2820
  });
2821
- function handleStdoutWrite(state, message3) {
2821
+ function handleStdoutWrite(state, message4) {
2822
2822
  try {
2823
- let matchesPattern2 = state.config.stdoutPatterns.some((pattern2) => message3.includes(pattern2));
2823
+ let matchesPattern2 = state.config.stdoutPatterns.some((pattern2) => message4.includes(pattern2));
2824
2824
  if (matchesPattern2) {
2825
- return addLog(state, "build", message3, void 0, void 0);
2825
+ return addLog(state, "build", message4, void 0, void 0);
2826
2826
  } else {
2827
2827
  return;
2828
2828
  }
@@ -2834,8 +2834,8 @@ function interceptStdout(_state) {
2834
2834
  (function(_state2) {
2835
2835
  const originalWrite = process.stdout.write.bind(process.stdout);
2836
2836
  process.stdout.write = (chunk, ...args) => {
2837
- const message3 = typeof chunk === "string" ? chunk : chunk.toString();
2838
- handleStdoutWrite(_state2, message3);
2837
+ const message4 = typeof chunk === "string" ? chunk : chunk.toString();
2838
+ handleStdoutWrite(_state2, message4);
2839
2839
  return originalWrite(chunk, ...args);
2840
2840
  };
2841
2841
  })(_state);
@@ -3018,10 +3018,10 @@ function endsWithSep(path) {
3018
3018
  }
3019
3019
  }
3020
3020
  function resolve(sourceRoot, inputPath) {
3021
- let normalizedRoot = Nodepath.normalize(sourceRoot);
3022
- let rootWithSep = endsWithSep(normalizedRoot) ? normalizedRoot : normalizedRoot + Nodepath.sep;
3023
- if (Nodepath.isAbsolute(inputPath)) {
3024
- let normalizedPath = Nodepath.normalize(inputPath);
3021
+ let normalizedRoot = Nodepath4.normalize(sourceRoot);
3022
+ let rootWithSep = endsWithSep(normalizedRoot) ? normalizedRoot : normalizedRoot + Nodepath4.sep;
3023
+ if (Nodepath4.isAbsolute(inputPath)) {
3024
+ let normalizedPath = Nodepath4.normalize(inputPath);
3025
3025
  if (normalizedPath === normalizedRoot || normalizedPath.startsWith(rootWithSep)) {
3026
3026
  return {
3027
3027
  TAG: "Ok",
@@ -3036,7 +3036,7 @@ function resolve(sourceRoot, inputPath) {
3036
3036
  };
3037
3037
  }
3038
3038
  }
3039
- let fullPath = Nodepath.normalize(Nodepath.join(sourceRoot, inputPath));
3039
+ let fullPath = Nodepath4.normalize(Nodepath4.join(sourceRoot, inputPath));
3040
3040
  if (fullPath === normalizedRoot || fullPath.startsWith(rootWithSep)) {
3041
3041
  return {
3042
3042
  TAG: "Ok",
@@ -3055,7 +3055,7 @@ function toString(safePath) {
3055
3055
  return safePath.path;
3056
3056
  }
3057
3057
  function dirname2(safePath) {
3058
- return Nodepath.dirname(safePath.path);
3058
+ return Nodepath4.dirname(safePath.path);
3059
3059
  }
3060
3060
 
3061
3061
  // ../frontman-core/src/FrontmanCore__PathContext.res.mjs
@@ -3067,7 +3067,7 @@ function endsWithSep2(path) {
3067
3067
  }
3068
3068
  }
3069
3069
  function toRelativePath(sourceRoot, absolutePath) {
3070
- let normalizedRoot = endsWithSep2(sourceRoot) ? sourceRoot : sourceRoot + Nodepath.sep;
3070
+ let normalizedRoot = endsWithSep2(sourceRoot) ? sourceRoot : sourceRoot + Nodepath4.sep;
3071
3071
  if (absolutePath.startsWith(normalizedRoot)) {
3072
3072
  return absolutePath.slice(normalizedRoot.length, absolutePath.length);
3073
3073
  } else if (absolutePath.startsWith(sourceRoot)) {
@@ -3080,11 +3080,11 @@ function resolveSearchPath(sourceRoot, inputPath) {
3080
3080
  if (inputPath === void 0) {
3081
3081
  return sourceRoot;
3082
3082
  }
3083
- if (!Nodepath.isAbsolute(inputPath)) {
3084
- return Nodepath.join(sourceRoot, inputPath);
3083
+ if (!Nodepath4.isAbsolute(inputPath)) {
3084
+ return Nodepath4.join(sourceRoot, inputPath);
3085
3085
  }
3086
- let normalizedPath = Nodepath.normalize(inputPath);
3087
- let normalizedRoot = Nodepath.normalize(sourceRoot);
3086
+ let normalizedPath = Nodepath4.normalize(inputPath);
3087
+ let normalizedRoot = Nodepath4.normalize(sourceRoot);
3088
3088
  if (normalizedPath.startsWith(normalizedRoot)) {
3089
3089
  return normalizedPath;
3090
3090
  } else {
@@ -3828,11 +3828,11 @@ function getMostSignificantDynamicType(segments) {
3828
3828
  });
3829
3829
  }
3830
3830
  async function findPages(baseDir, currentPath, projectRoot, sourceRoot) {
3831
- let fullPath = Nodepath.join(projectRoot, baseDir, currentPath);
3831
+ let fullPath = Nodepath4.join(projectRoot, baseDir, currentPath);
3832
3832
  try {
3833
3833
  let entries = await Fs.promises.readdir(fullPath);
3834
3834
  return (await Promise.all(entries.map(async (entry) => {
3835
- let entryPath = Nodepath.join(fullPath, entry);
3835
+ let entryPath = Nodepath4.join(fullPath, entry);
3836
3836
  let stats = await Fs.promises.lstat(entryPath);
3837
3837
  if (stats.isSymbolicLink()) {
3838
3838
  return [];
@@ -3841,13 +3841,13 @@ async function findPages(baseDir, currentPath, projectRoot, sourceRoot) {
3841
3841
  if (entry.startsWith("_") || entry === "api" || entry === "components") {
3842
3842
  return [];
3843
3843
  } else {
3844
- return await findPages(baseDir, Nodepath.join(currentPath, entry), projectRoot, sourceRoot);
3844
+ return await findPages(baseDir, Nodepath4.join(currentPath, entry), projectRoot, sourceRoot);
3845
3845
  }
3846
3846
  }
3847
3847
  if (!(entry.endsWith(".astro") || entry.endsWith(".md") || entry.endsWith(".mdx") || entry.endsWith(".html"))) {
3848
3848
  return [];
3849
3849
  }
3850
- let filePath = Nodepath.join(currentPath, entry);
3850
+ let filePath = Nodepath4.join(currentPath, entry);
3851
3851
  let routePath = fileToRoute(filePath);
3852
3852
  let filePathNoExt = filePath.replace(/\.(astro|md|mdx|html)$/, "");
3853
3853
  let segments = filePathNoExt.replaceAll("\\", "/").split("/");
@@ -4070,7 +4070,8 @@ var ToolNames = {
4070
4070
  grep: "grep",
4071
4071
  fileExists: "file_exists",
4072
4072
  loadAgentInstructions: "load_agent_instructions",
4073
- lighthouse: "lighthouse"};
4073
+ lighthouse: "lighthouse",
4074
+ listTree: "list_tree"};
4074
4075
 
4075
4076
  // ../frontman-core/src/tools/FrontmanCore__Tool__Grep.res.mjs
4076
4077
  var name6 = ToolNames.grep;
@@ -4365,8 +4366,421 @@ LIMITATIONS:
4365
4366
  - Results limited to max_results (default 20)
4366
4367
  - Binary files are automatically skipped
4367
4368
  - Hidden files (starting with '.') are skipped by default`;
4368
- var name7 = ToolNames.readFile;
4369
+
4370
+ // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_JSON.js
4371
+ function bool3(json3) {
4372
+ if (typeof json3 === "boolean") {
4373
+ return json3;
4374
+ }
4375
+ }
4376
+ function $$null2(json3) {
4377
+ if (json3 === null) {
4378
+ return null;
4379
+ }
4380
+ }
4381
+ function string3(json3) {
4382
+ if (typeof json3 === "string") {
4383
+ return json3;
4384
+ }
4385
+ }
4386
+ function float3(json3) {
4387
+ if (typeof json3 === "number") {
4388
+ return json3;
4389
+ }
4390
+ }
4391
+ function object2(json3) {
4392
+ if (typeof json3 === "object" && json3 !== null && !Array.isArray(json3)) {
4393
+ return json3;
4394
+ }
4395
+ }
4396
+ function array3(json3) {
4397
+ if (Array.isArray(json3)) {
4398
+ return json3;
4399
+ }
4400
+ }
4401
+ var Decode = {
4402
+ bool: bool3,
4403
+ $$null: $$null2,
4404
+ string: string3,
4405
+ float: float3,
4406
+ object: object2,
4407
+ array: array3
4408
+ };
4409
+
4410
+ // ../../node_modules/@rescript/runtime/lib/es6/Primitive_string.js
4411
+ function compare(s1, s2) {
4412
+ if (s1 === s2) {
4413
+ return 0;
4414
+ } else if (s1 < s2) {
4415
+ return -1;
4416
+ } else {
4417
+ return 1;
4418
+ }
4419
+ }
4420
+ async function pathExists(path) {
4421
+ try {
4422
+ await Fs.promises.access(path);
4423
+ return true;
4424
+ } catch (exn) {
4425
+ return false;
4426
+ }
4427
+ }
4428
+
4429
+ // ../frontman-core/src/tools/FrontmanCore__Tool__ListTree.res.mjs
4430
+ var name7 = ToolNames.listTree;
4369
4431
  var inputSchema6 = schema2((s2) => ({
4432
+ path: s2.m(option2(string2)),
4433
+ depth: s2.m(option2(int2))
4434
+ }));
4435
+ var workspaceSchema = schema2((s2) => ({
4436
+ name: s2.m(string2),
4437
+ path: s2.m(string2)
4438
+ }));
4439
+ var outputSchema6 = schema2((s2) => ({
4440
+ tree: s2.m(string2),
4441
+ workspaces: s2.m(array2(workspaceSchema)),
4442
+ monorepoType: s2.m(option2(string2))
4443
+ }));
4444
+ var packageJsonNameSchema = schema2((s2) => ({
4445
+ name: s2.m(option2(string2))
4446
+ }));
4447
+ var packageJsonWorkspacesObjSchema = schema2((s2) => ({
4448
+ packages: s2.m(option2(array2(string2)))
4449
+ }));
4450
+ var noiseDirs = [
4451
+ "node_modules",
4452
+ ".git",
4453
+ "dist",
4454
+ "build",
4455
+ ".next",
4456
+ "_build",
4457
+ "deps",
4458
+ ".turbo",
4459
+ ".cache",
4460
+ "coverage",
4461
+ ".svelte-kit",
4462
+ ".output",
4463
+ ".nuxt",
4464
+ ".vercel",
4465
+ "__pycache__",
4466
+ "target"
4467
+ ];
4468
+ function makeTrieNode(name15) {
4469
+ return {
4470
+ name: name15,
4471
+ children: {
4472
+ contents: {}
4473
+ },
4474
+ isFile: {
4475
+ contents: false
4476
+ }
4477
+ };
4478
+ }
4479
+ function buildTrie(files) {
4480
+ let root_children = {
4481
+ contents: {}
4482
+ };
4483
+ let root_isFile = {
4484
+ contents: false
4485
+ };
4486
+ let root = {
4487
+ name: ".",
4488
+ children: root_children,
4489
+ isFile: root_isFile
4490
+ };
4491
+ files.forEach((filePath) => {
4492
+ let parts = filePath.split("/").filter((p2) => p2 !== "");
4493
+ let current = {
4494
+ contents: root
4495
+ };
4496
+ parts.forEach((part, idx) => {
4497
+ let isLast = idx === (parts.length - 1 | 0);
4498
+ let existing = current.contents.children.contents[part];
4499
+ if (existing !== void 0) {
4500
+ if (isLast) {
4501
+ existing.isFile.contents = true;
4502
+ }
4503
+ current.contents = existing;
4504
+ return;
4505
+ }
4506
+ let node = makeTrieNode(part);
4507
+ if (isLast) {
4508
+ node.isFile.contents = true;
4509
+ }
4510
+ current.contents.children.contents[part] = node;
4511
+ current.contents = node;
4512
+ });
4513
+ });
4514
+ return root;
4515
+ }
4516
+ function getSortedChildren(node) {
4517
+ let entries = Object.entries(node.children.contents).map((param) => {
4518
+ let child = param[1];
4519
+ let hasChildren = Object.keys(child.children.contents).length !== 0;
4520
+ let isDir = hasChildren || !child.isFile.contents;
4521
+ return {
4522
+ entryName: param[0],
4523
+ node: child,
4524
+ isDir
4525
+ };
4526
+ }).filter((e) => !noiseDirs.includes(e.entryName));
4527
+ return entries.toSorted((a, b) => {
4528
+ let match = a.isDir;
4529
+ let match$1 = b.isDir;
4530
+ if (match) {
4531
+ if (!match$1) {
4532
+ return -1;
4533
+ }
4534
+ } else if (match$1) {
4535
+ return 1;
4536
+ }
4537
+ let n = compare(a.entryName, b.entryName);
4538
+ if (n < 0) {
4539
+ return -1;
4540
+ } else if (n > 0) {
4541
+ return 1;
4542
+ } else {
4543
+ return 0;
4544
+ }
4545
+ });
4546
+ }
4547
+ function renderTree(root, maxDepth, workspacePaths) {
4548
+ let lines = [];
4549
+ let walk = (node, prefix, currentDepth, parentPath) => {
4550
+ if (currentDepth > maxDepth) {
4551
+ return;
4552
+ }
4553
+ let children = getSortedChildren(node);
4554
+ let totalCount = children.length;
4555
+ let truncated = totalCount > 15;
4556
+ let visibleChildren = truncated ? children.slice(0, 10) : children;
4557
+ let visibleCount = visibleChildren.length;
4558
+ visibleChildren.forEach((entry, idx) => {
4559
+ let isLastVisible = idx === (visibleCount - 1 | 0) && !truncated;
4560
+ let connector = isLastVisible ? `\u2514\u2500\u2500 ` : `\u251C\u2500\u2500 `;
4561
+ let childPrefix = isLastVisible ? prefix + " " : prefix + `\u2502 `;
4562
+ let suffix = entry.isDir ? "/" : "";
4563
+ let entryRelPath = parentPath !== void 0 ? parentPath + "/" + entry.entryName : entry.entryName;
4564
+ let workspaceAnnotation;
4565
+ if (entry.isDir) {
4566
+ let wsName = workspacePaths[entryRelPath];
4567
+ workspaceAnnotation = wsName !== void 0 ? ` [workspace: ` + wsName + `]` : "";
4568
+ } else {
4569
+ workspaceAnnotation = "";
4570
+ }
4571
+ lines.push(prefix + connector + entry.entryName + suffix + workspaceAnnotation);
4572
+ if (entry.isDir) {
4573
+ return walk(entry.node, childPrefix, currentDepth + 1 | 0, entryRelPath);
4574
+ }
4575
+ });
4576
+ if (!truncated) {
4577
+ return;
4578
+ }
4579
+ let remaining = totalCount - 10 | 0;
4580
+ lines.push(prefix + (`\u2514\u2500\u2500 ... and ` + remaining.toString() + ` more entries`));
4581
+ };
4582
+ lines.push(".");
4583
+ walk(root, "", 1, void 0);
4584
+ return lines.join("\n");
4585
+ }
4586
+ function buildWorkspacePathLookup(workspaces) {
4587
+ let lookup = {};
4588
+ workspaces.forEach((ws) => {
4589
+ lookup[ws.path] = ws.name;
4590
+ });
4591
+ return lookup;
4592
+ }
4593
+ async function readJsonFile(path) {
4594
+ try {
4595
+ let content = await Fs.promises.readFile(path, "utf8");
4596
+ return {
4597
+ TAG: "Ok",
4598
+ _0: JSON.parse(content)
4599
+ };
4600
+ } catch (raw_exn) {
4601
+ let exn = internalToException(raw_exn);
4602
+ let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
4603
+ return {
4604
+ TAG: "Error",
4605
+ _0: `Failed to read/parse ` + path + `: ` + msg
4606
+ };
4607
+ }
4608
+ }
4609
+ async function readPackageName(dirPath) {
4610
+ let pkgPath = Nodepath4.join(dirPath, "package.json");
4611
+ let json3 = await readJsonFile(pkgPath);
4612
+ if (json3.TAG !== "Ok") {
4613
+ return;
4614
+ }
4615
+ try {
4616
+ return parseOrThrow2(json3._0, packageJsonNameSchema).name;
4617
+ } catch (exn) {
4618
+ return;
4619
+ }
4620
+ }
4621
+ function extractWorkspaceGlobs(json3) {
4622
+ let obj = Decode.object(json3);
4623
+ if (obj === void 0) {
4624
+ return;
4625
+ }
4626
+ let wsJson = obj["workspaces"];
4627
+ if (wsJson === void 0) {
4628
+ return;
4629
+ }
4630
+ try {
4631
+ return parseOrThrow2(wsJson, array2(string2));
4632
+ } catch (exn) {
4633
+ try {
4634
+ return parseOrThrow2(wsJson, packageJsonWorkspacesObjSchema).packages;
4635
+ } catch (exn$1) {
4636
+ return;
4637
+ }
4638
+ }
4639
+ }
4640
+ async function resolveWorkspaceGlobs(rootPath, globs) {
4641
+ let results = [];
4642
+ await Promise.all(globs.map(async (glob) => {
4643
+ if (glob.endsWith("/*")) {
4644
+ let parentDir = glob.slice(0, glob.length - 2 | 0);
4645
+ let fullParent = Nodepath4.join(rootPath, parentDir);
4646
+ try {
4647
+ let entries = await Fs.promises.readdir(fullParent);
4648
+ await Promise.all(entries.map(async (entry) => {
4649
+ let entryPath = Nodepath4.join(fullParent, entry);
4650
+ let stats = await Fs.promises.stat(entryPath);
4651
+ if (stats.isDirectory()) {
4652
+ results.push(parentDir + "/" + entry);
4653
+ return;
4654
+ }
4655
+ }));
4656
+ return;
4657
+ } catch (raw_exn) {
4658
+ let exn = internalToException(raw_exn);
4659
+ let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
4660
+ console.warn(`ListTree: failed to resolve workspace glob "` + glob + `": ` + msg);
4661
+ return;
4662
+ }
4663
+ } else {
4664
+ let fullPath = Nodepath4.join(rootPath, glob);
4665
+ if (await pathExists(fullPath)) {
4666
+ results.push(glob);
4667
+ return;
4668
+ } else {
4669
+ return;
4670
+ }
4671
+ }
4672
+ }));
4673
+ return results;
4674
+ }
4675
+ async function detectMonorepo(rootPath) {
4676
+ let pkgJsonResult = await readJsonFile(Nodepath4.join(rootPath, "package.json"));
4677
+ let workspaceGlobs;
4678
+ workspaceGlobs = pkgJsonResult.TAG === "Ok" ? extractWorkspaceGlobs(pkgJsonResult._0) : void 0;
4679
+ let hasTurbo = await pathExists(Nodepath4.join(rootPath, "turbo.json"));
4680
+ let hasNx = await pathExists(Nodepath4.join(rootPath, "nx.json"));
4681
+ let hasPnpmWorkspace = await pathExists(Nodepath4.join(rootPath, "pnpm-workspace.yaml"));
4682
+ let monorepoType = hasTurbo ? "turborepo" : hasNx ? "nx" : hasPnpmWorkspace ? "pnpm-workspaces" : workspaceGlobs !== void 0 ? "npm-workspaces" : void 0;
4683
+ let workspaces;
4684
+ if (workspaceGlobs !== void 0) {
4685
+ let resolvedPaths = await resolveWorkspaceGlobs(rootPath, workspaceGlobs);
4686
+ workspaces = await Promise.all(resolvedPaths.map(async (wsPath) => {
4687
+ let fullPath = Nodepath4.join(rootPath, wsPath);
4688
+ let n = await readPackageName(fullPath);
4689
+ let name15 = n !== void 0 ? n : wsPath;
4690
+ return {
4691
+ name: name15,
4692
+ path: wsPath
4693
+ };
4694
+ }));
4695
+ } else {
4696
+ workspaces = [];
4697
+ }
4698
+ return {
4699
+ monorepoType,
4700
+ workspaces
4701
+ };
4702
+ }
4703
+ async function getTrackedFiles(cwd) {
4704
+ let result = await spawnResult("git", ["ls-files"], cwd);
4705
+ if (result.TAG === "Ok") {
4706
+ let lines = result._0.stdout.trim().split("\n").filter((line) => line !== "");
4707
+ return {
4708
+ TAG: "Ok",
4709
+ _0: lines
4710
+ };
4711
+ }
4712
+ let match = result._0;
4713
+ let match$1 = match.code;
4714
+ if (match$1 === 128) {
4715
+ return {
4716
+ TAG: "Error",
4717
+ _0: `Not a git repository: ` + match.stderr
4718
+ };
4719
+ }
4720
+ return {
4721
+ TAG: "Error",
4722
+ _0: `git ls-files failed: ` + match.stderr
4723
+ };
4724
+ }
4725
+ async function execute6(ctx2, input) {
4726
+ let path = getOr(input.path, ".");
4727
+ let maxDepth = getOr(input.depth, 3);
4728
+ let err = resolve2(ctx2.sourceRoot, path);
4729
+ if (err.TAG !== "Ok") {
4730
+ return {
4731
+ TAG: "Error",
4732
+ _0: formatError(err._0)
4733
+ };
4734
+ }
4735
+ try {
4736
+ let fullPath = err._0.resolvedPath;
4737
+ let filesResult = await getTrackedFiles(fullPath);
4738
+ let files;
4739
+ if (filesResult.TAG === "Ok") {
4740
+ files = filesResult._0;
4741
+ } else {
4742
+ console.warn(`ListTree: ` + filesResult._0 + `, falling back to readdir`);
4743
+ files = await Fs.promises.readdir(fullPath);
4744
+ }
4745
+ let trie = buildTrie(files);
4746
+ let monoInfo = await detectMonorepo(fullPath);
4747
+ let workspacePaths = buildWorkspacePathLookup(monoInfo.workspaces);
4748
+ let tree = renderTree(trie, maxDepth, workspacePaths);
4749
+ return {
4750
+ TAG: "Ok",
4751
+ _0: {
4752
+ tree,
4753
+ workspaces: monoInfo.workspaces,
4754
+ monorepoType: monoInfo.monorepoType
4755
+ }
4756
+ };
4757
+ } catch (raw_exn) {
4758
+ let exn = internalToException(raw_exn);
4759
+ let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
4760
+ return {
4761
+ TAG: "Error",
4762
+ _0: `Failed to list tree for ` + path + `: ` + msg
4763
+ };
4764
+ }
4765
+ }
4766
+ var description6 = `Returns a text tree view of the project directory structure with monorepo workspace detection.
4767
+
4768
+ WHEN TO USE THIS TOOL:
4769
+ - Getting oriented in an unfamiliar codebase
4770
+ - Understanding monorepo workspace layout and boundaries
4771
+ - Exploring a specific subdirectory's structure in depth
4772
+ - Prefer this over chaining multiple list_files calls for structure discovery
4773
+
4774
+ PARAMETERS:
4775
+ - path (optional): Subdirectory to root the tree at. Defaults to "." (project root).
4776
+ - depth (optional): Maximum directory depth to display. Defaults to 3.
4777
+
4778
+ OUTPUT:
4779
+ Returns a text tree with directories and files. Directories end with /.
4780
+ Workspace roots are annotated with [workspace: name].
4781
+ Respects .gitignore. Skips node_modules, .git, dist, build, etc.`;
4782
+ var name8 = ToolNames.readFile;
4783
+ var inputSchema7 = schema2((s2) => ({
4370
4784
  path: s2.m(string2),
4371
4785
  offset: s2.m(option2(int2)),
4372
4786
  limit: s2.m(option2(int2))
@@ -4376,13 +4790,13 @@ var pathContextSchema2 = schema2((s2) => ({
4376
4790
  resolvedPath: s2.m(string2),
4377
4791
  relativePath: s2.m(string2)
4378
4792
  }));
4379
- var outputSchema6 = schema2((s2) => ({
4793
+ var outputSchema7 = schema2((s2) => ({
4380
4794
  content: s2.m(string2),
4381
4795
  totalLines: s2.m(int2),
4382
4796
  hasMore: s2.m(bool2),
4383
4797
  _context: s2.m(option2(pathContextSchema2))
4384
4798
  }));
4385
- async function execute6(ctx2, input) {
4799
+ async function execute7(ctx2, input) {
4386
4800
  let offset = getOr(input.offset, 0);
4387
4801
  let limit = getOr(input.limit, 500);
4388
4802
  let err = resolve2(ctx2.sourceRoot, input.path);
@@ -4423,7 +4837,7 @@ async function execute6(ctx2, input) {
4423
4837
  };
4424
4838
  }
4425
4839
  }
4426
- var description6 = `Reads a file from the filesystem.
4840
+ var description7 = `Reads a file from the filesystem.
4427
4841
 
4428
4842
  Parameters:
4429
4843
  - path (required): Path to file - either relative to source root or absolute (must be under source root)
@@ -4446,8 +4860,8 @@ function map3(opt, f) {
4446
4860
  }
4447
4861
 
4448
4862
  // ../frontman-core/src/tools/FrontmanCore__Tool__ListFiles.res.mjs
4449
- var name8 = ToolNames.listFiles;
4450
- var inputSchema7 = schema2((s2) => ({
4863
+ var name9 = ToolNames.listFiles;
4864
+ var inputSchema8 = schema2((s2) => ({
4451
4865
  path: s2.m(option2(string2))
4452
4866
  }));
4453
4867
  var fileEntrySchema = schema2((s2) => ({
@@ -4456,7 +4870,7 @@ var fileEntrySchema = schema2((s2) => ({
4456
4870
  isFile: s2.m(bool2),
4457
4871
  isDirectory: s2.m(bool2)
4458
4872
  }));
4459
- var outputSchema7 = array2(fileEntrySchema);
4873
+ var outputSchema8 = array2(fileEntrySchema);
4460
4874
  async function getIgnoredEntries(cwd, entries) {
4461
4875
  if (entries.length === 0) {
4462
4876
  return {
@@ -4511,7 +4925,7 @@ async function getIgnoredEntries(cwd, entries) {
4511
4925
  };
4512
4926
  }
4513
4927
  }
4514
- async function execute7(ctx2, input) {
4928
+ async function execute8(ctx2, input) {
4515
4929
  let path = getOr(input.path, ".");
4516
4930
  let err = resolve2(ctx2.sourceRoot, path);
4517
4931
  if (err.TAG !== "Ok") {
@@ -4523,19 +4937,19 @@ async function execute7(ctx2, input) {
4523
4937
  try {
4524
4938
  let fullPath = err._0.resolvedPath;
4525
4939
  let entries = await Fs.promises.readdir(fullPath);
4526
- let filteredEntriesResult = map3(await getIgnoredEntries(fullPath, entries), (ignored) => entries.filter((name14) => !ignored.includes(name14)));
4940
+ let filteredEntriesResult = map3(await getIgnoredEntries(fullPath, entries), (ignored) => entries.filter((name15) => !ignored.includes(name15)));
4527
4941
  if (filteredEntriesResult.TAG !== "Ok") {
4528
4942
  return {
4529
4943
  TAG: "Error",
4530
4944
  _0: filteredEntriesResult._0
4531
4945
  };
4532
4946
  }
4533
- let entriesWithStats = await Promise.all(filteredEntriesResult._0.map(async (name14) => {
4534
- let entryPath = Nodepath.join(fullPath, name14);
4947
+ let entriesWithStats = await Promise.all(filteredEntriesResult._0.map(async (name15) => {
4948
+ let entryPath = Nodepath4.join(fullPath, name15);
4535
4949
  let stats = await Fs.promises.stat(entryPath);
4536
4950
  return {
4537
- name: name14,
4538
- path: Nodepath.join(path, name14),
4951
+ name: name15,
4952
+ path: Nodepath4.join(path, name15),
4539
4953
  isFile: stats.isFile(),
4540
4954
  isDirectory: stats.isDirectory()
4541
4955
  };
@@ -4553,14 +4967,23 @@ async function execute7(ctx2, input) {
4553
4967
  };
4554
4968
  }
4555
4969
  }
4556
- var description7 = `Lists files and directories in a given path.
4970
+ var description8 = `Lists files and directories in a single directory.
4557
4971
 
4558
- Parameters:
4972
+ WHEN TO USE THIS TOOL:
4973
+ - Browsing one directory's immediate contents in detail (names, types)
4974
+ - Checking what files exist in a specific directory before reading or editing
4975
+ - Verifying file organization after making changes
4976
+ - Use list_tree instead when you need a multi-level project overview or monorepo layout
4977
+ - Use search_files instead when you need to find files by name pattern across the project
4978
+
4979
+ PARAMETERS:
4559
4980
  - path (optional): Path to directory - either relative to source root or absolute (must be under source root). Defaults to "." (root directory).
4560
4981
 
4561
- Returns array of entries with name, path, and type information.`;
4562
- var name9 = ToolNames.writeFile;
4563
- var inputSchema8 = schema2((s2) => ({
4982
+ OUTPUT:
4983
+ Returns array of entries with name, path, and type (file or directory) information.
4984
+ Respects .gitignore \u2014 ignored files are excluded from results.`;
4985
+ var name10 = ToolNames.writeFile;
4986
+ var inputSchema9 = schema2((s2) => ({
4564
4987
  path: s2.m(string2),
4565
4988
  content: s2.m(option2(string2)),
4566
4989
  image_ref: s2.m(option2(string2)),
@@ -4571,7 +4994,7 @@ var pathContextSchema3 = schema2((s2) => ({
4571
4994
  resolvedPath: s2.m(string2),
4572
4995
  relativePath: s2.m(string2)
4573
4996
  }));
4574
- var outputSchema8 = schema2((s2) => ({
4997
+ var outputSchema9 = schema2((s2) => ({
4575
4998
  _context: s2.m(option2(pathContextSchema3))
4576
4999
  }));
4577
5000
  function writeContent(resolvedPath, content, encoding) {
@@ -4581,7 +5004,7 @@ function writeContent(resolvedPath, content, encoding) {
4581
5004
  let buffer = Nodebuffer.Buffer.from(content, "base64");
4582
5005
  return Fs.promises.writeFile(resolvedPath, buffer);
4583
5006
  }
4584
- async function execute8(ctx2, input) {
5007
+ async function execute9(ctx2, input) {
4585
5008
  let match = input.content;
4586
5009
  let match$1 = input.image_ref;
4587
5010
  if (match === void 0) {
@@ -4635,7 +5058,7 @@ async function execute8(ctx2, input) {
4635
5058
  };
4636
5059
  }
4637
5060
  }
4638
- var description8 = `Writes content to a file.
5061
+ var description9 = `Writes content to a file.
4639
5062
 
4640
5063
  Parameters:
4641
5064
  - path (required): Path to file - either relative to source root or absolute (must be under source root)
@@ -4646,11 +5069,13 @@ Parameters:
4646
5069
  Provide either content OR image_ref, not both.
4647
5070
  Creates parent directories if they don't exist. Overwrites existing files.
4648
5071
  The _context field provides path resolution details for debugging.`;
4649
- var name10 = ToolNames.fileExists;
4650
- var inputSchema9 = schema2((s2) => ({
5072
+
5073
+ // ../frontman-core/src/tools/FrontmanCore__Tool__FileExists.res.mjs
5074
+ var name11 = ToolNames.fileExists;
5075
+ var inputSchema10 = schema2((s2) => ({
4651
5076
  path: s2.m(string2)
4652
5077
  }));
4653
- async function execute9(ctx2, input) {
5078
+ async function execute10(ctx2, input) {
4654
5079
  let msg = resolve(ctx2.sourceRoot, input.path);
4655
5080
  if (msg.TAG !== "Ok") {
4656
5081
  return {
@@ -4658,26 +5083,19 @@ async function execute9(ctx2, input) {
4658
5083
  _0: msg._0
4659
5084
  };
4660
5085
  }
4661
- try {
4662
- await Fs.promises.access(toString(msg._0));
4663
- return {
4664
- TAG: "Ok",
4665
- _0: true
4666
- };
4667
- } catch (exn) {
4668
- return {
4669
- TAG: "Ok",
4670
- _0: false
4671
- };
4672
- }
5086
+ let exists = await pathExists(toString(msg._0));
5087
+ return {
5088
+ TAG: "Ok",
5089
+ _0: exists
5090
+ };
4673
5091
  }
4674
- var description9 = `Checks if a file or directory exists.
5092
+ var description10 = `Checks if a file or directory exists.
4675
5093
 
4676
5094
  Parameters:
4677
5095
  - path (required): Path to check - either relative to source root or absolute (must be under source root)
4678
5096
 
4679
5097
  Returns true if the path exists, false otherwise.`;
4680
- var outputSchema9 = bool2;
5098
+ var outputSchema10 = bool2;
4681
5099
 
4682
5100
  // ../bindings/src/Lighthouse.res.mjs
4683
5101
  var run = ((url2, flags2) => import('module').then(({ createRequire }) => {
@@ -4718,18 +5136,43 @@ async function killSafely(chrome) {
4718
5136
  }
4719
5137
  }
4720
5138
 
5139
+ // ../frontman-core/src/FrontmanCore__ExnUtils.res.mjs
5140
+ function message3(exn) {
5141
+ return getOr(flatMap(fromException(exn), message2), "Unknown error");
5142
+ }
5143
+
4721
5144
  // ../frontman-core/src/tools/FrontmanCore__Tool__Lighthouse.res.mjs
4722
- var name11 = ToolNames.lighthouse;
4723
- var inputSchema10 = schema2((s2) => ({
5145
+ var name12 = ToolNames.lighthouse;
5146
+ var presetSchema = union2([
5147
+ literal2("desktop"),
5148
+ literal2("mobile")
5149
+ ]);
5150
+ function presetToString(preset) {
5151
+ if (preset === "desktop") {
5152
+ return "desktop";
5153
+ } else {
5154
+ return "mobile";
5155
+ }
5156
+ }
5157
+ var inputSchema11 = schema2((s2) => ({
4724
5158
  url: s2.m(string2),
4725
- preset: s2.m(option2(string2))
5159
+ preset: s2.m(option2(presetSchema))
5160
+ }));
5161
+ var elementDetailSchema = schema2((s2) => ({
5162
+ selector: s2.m(option2(string2)),
5163
+ snippet: s2.m(option2(string2)),
5164
+ nodeLabel: s2.m(option2(string2)),
5165
+ explanation: s2.m(option2(string2)),
5166
+ url: s2.m(option2(string2)),
5167
+ sourceLocation: s2.m(option2(string2))
4726
5168
  }));
4727
5169
  var auditIssueSchema = schema2((s2) => ({
4728
5170
  id: s2.m(string2),
4729
5171
  title: s2.m(string2),
4730
5172
  description: s2.m(string2),
4731
5173
  score: s2.m(float2),
4732
- displayValue: s2.m(option2(string2))
5174
+ displayValue: s2.m(option2(string2)),
5175
+ elements: s2.m(array2(elementDetailSchema))
4733
5176
  }));
4734
5177
  var categoryResultSchema = schema2((s2) => ({
4735
5178
  id: s2.m(string2),
@@ -4737,7 +5180,7 @@ var categoryResultSchema = schema2((s2) => ({
4737
5180
  score: s2.m(int2),
4738
5181
  topIssues: s2.m(array2(auditIssueSchema))
4739
5182
  }));
4740
- var outputSchema10 = schema2((s2) => ({
5183
+ var outputSchema11 = schema2((s2) => ({
4741
5184
  url: s2.m(string2),
4742
5185
  fetchTime: s2.m(string2),
4743
5186
  categories: s2.m(array2(categoryResultSchema)),
@@ -4750,30 +5193,126 @@ var categoryIds = [
4750
5193
  "best-practices",
4751
5194
  "seo"
4752
5195
  ];
5196
+ function getStr(dict3, key) {
5197
+ return flatMap(dict3[key], Decode.string);
5198
+ }
5199
+ function extractNodeDetail(itemDict) {
5200
+ let n = flatMap(itemDict["node"], Decode.object);
5201
+ let nodeDict;
5202
+ if (n !== void 0) {
5203
+ nodeDict = n;
5204
+ } else {
5205
+ let match = getStr(itemDict, "type");
5206
+ nodeDict = match === "node" ? itemDict : void 0;
5207
+ }
5208
+ if (nodeDict === void 0) {
5209
+ return;
5210
+ }
5211
+ let selector = getStr(nodeDict, "selector");
5212
+ let snippet = getStr(nodeDict, "snippet");
5213
+ let nodeLabel = getStr(nodeDict, "nodeLabel");
5214
+ let explanation = getStr(nodeDict, "explanation");
5215
+ if (selector === void 0 && snippet === void 0) {
5216
+ return;
5217
+ }
5218
+ return {
5219
+ selector,
5220
+ snippet,
5221
+ nodeLabel,
5222
+ explanation,
5223
+ url: void 0,
5224
+ sourceLocation: void 0
5225
+ };
5226
+ }
5227
+ function extractSourceLocation(itemDict) {
5228
+ let sourceDict = flatMap(itemDict["source"], Decode.object);
5229
+ if (sourceDict === void 0) {
5230
+ return;
5231
+ }
5232
+ let url2 = getStr(sourceDict, "url");
5233
+ if (url2 === void 0) {
5234
+ return;
5235
+ }
5236
+ let line = map(flatMap(sourceDict["line"], Decode.float), (prim) => prim | 0);
5237
+ let col = map(flatMap(sourceDict["column"], Decode.float), (prim) => prim | 0);
5238
+ if (line !== void 0) {
5239
+ if (col !== void 0) {
5240
+ return url2 + `:` + line.toString() + `:` + col.toString();
5241
+ } else {
5242
+ return url2 + `:` + line.toString();
5243
+ }
5244
+ } else {
5245
+ return url2;
5246
+ }
5247
+ }
5248
+ function extractResourceDetail(itemDict) {
5249
+ let url2 = getStr(itemDict, "url");
5250
+ let sourceLocation = extractSourceLocation(itemDict);
5251
+ if (url2 === void 0 && sourceLocation === void 0) {
5252
+ return;
5253
+ }
5254
+ return {
5255
+ selector: void 0,
5256
+ snippet: void 0,
5257
+ nodeLabel: void 0,
5258
+ explanation: void 0,
5259
+ url: url2,
5260
+ sourceLocation
5261
+ };
5262
+ }
5263
+ function extractElements(details) {
5264
+ let detailsDict = flatMap(details, Decode.object);
5265
+ if (detailsDict === void 0) {
5266
+ return [];
5267
+ }
5268
+ let arr = flatMap(detailsDict["items"], Decode.array);
5269
+ let items = arr !== void 0 ? arr : [];
5270
+ return filterMap(items, (item) => {
5271
+ let itemDict = Decode.object(item);
5272
+ if (itemDict === void 0) {
5273
+ return;
5274
+ }
5275
+ let result = extractNodeDetail(itemDict);
5276
+ if (result !== void 0) {
5277
+ return result;
5278
+ } else {
5279
+ return extractResourceDetail(itemDict);
5280
+ }
5281
+ }).slice(0, 3);
5282
+ }
4753
5283
  function getTopIssues(category, audits, maxIssues) {
4754
5284
  return filterMap(category.auditRefs, (ref) => audits[ref.id]).filter((audit) => {
4755
- let score = audit.score;
4756
- if (!(score == null) && (audit.scoreDisplayMode === "binary" || audit.scoreDisplayMode === "numeric" || audit.scoreDisplayMode === "metricSavings")) {
4757
- return score < 1;
4758
- } else {
5285
+ let match = audit.scoreDisplayMode;
5286
+ let match$1 = audit.score;
5287
+ switch (match) {
5288
+ case "numeric":
5289
+ case "binary":
5290
+ case "metricSavings":
5291
+ break;
5292
+ default:
5293
+ return false;
5294
+ }
5295
+ if (match$1 == null) {
4759
5296
  return false;
5297
+ } else {
5298
+ return match$1 < 1;
4760
5299
  }
4761
5300
  }).toSorted((a, b) => {
4762
- let scoreA = getOr(fromNullable(a.score), 0);
4763
- let scoreB = getOr(fromNullable(b.score), 0);
5301
+ let scoreA = getOrThrow(fromNullable(a.score));
5302
+ let scoreB = getOrThrow(fromNullable(b.score));
4764
5303
  return scoreA - scoreB;
4765
5304
  }).slice(0, maxIssues).map((audit) => ({
4766
5305
  id: audit.id,
4767
5306
  title: audit.title,
4768
5307
  description: audit.description,
4769
- score: getOr(fromNullable(audit.score), 0),
4770
- displayValue: audit.displayValue
5308
+ score: getOrThrow(fromNullable(audit.score)),
5309
+ displayValue: audit.displayValue,
5310
+ elements: extractElements(audit.details)
4771
5311
  }));
4772
5312
  }
4773
5313
  function processLhr(lhr) {
4774
5314
  let categories = filterMap(categoryIds, (id) => lhr.categories[id]).map((category) => {
4775
- let s2 = category.score;
4776
- let score = !(s2 == null) ? Math.round(s2 * 100) | 0 : 0;
5315
+ let score = Math.round(getOrThrow(fromNullable(category.score)) * 100) | 0;
4777
5316
  let topIssues = getTopIssues(category, lhr.audits, 3);
4778
5317
  return {
4779
5318
  id: category.id,
@@ -4795,13 +5334,16 @@ function processLhr(lhr) {
4795
5334
  }
4796
5335
  async function runLighthouse(chrome, url2, preset) {
4797
5336
  let port2 = chrome.port;
5337
+ let formFactor = presetToString(preset);
5338
+ let tmp;
5339
+ tmp = preset === "desktop";
4798
5340
  let flags_port = port2;
4799
5341
  let flags_output = "json";
4800
5342
  let flags_logLevel = "error";
4801
5343
  let flags_onlyCategories = categoryIds;
4802
- let flags_formFactor = preset;
5344
+ let flags_formFactor = formFactor;
4803
5345
  let flags_screenEmulation = {
4804
- disabled: preset === "desktop"
5346
+ disabled: tmp
4805
5347
  };
4806
5348
  let flags_throttlingMethod = "simulate";
4807
5349
  let flags2 = {
@@ -4813,42 +5355,28 @@ async function runLighthouse(chrome, url2, preset) {
4813
5355
  screenEmulation: flags_screenEmulation,
4814
5356
  throttlingMethod: flags_throttlingMethod
4815
5357
  };
5358
+ let result;
4816
5359
  try {
4817
5360
  let runnerResult = await run(url2, flags2);
4818
- await killSafely(chrome);
4819
- if (runnerResult == null) {
4820
- return {
4821
- TAG: "Error",
4822
- _0: "Lighthouse returned no results. The URL may be unreachable."
4823
- };
4824
- } else {
4825
- return {
4826
- TAG: "Ok",
4827
- _0: processLhr(runnerResult.lhr)
4828
- };
4829
- }
5361
+ result = runnerResult == null ? {
5362
+ TAG: "Error",
5363
+ _0: "Lighthouse returned no results. The URL may be unreachable."
5364
+ } : {
5365
+ TAG: "Ok",
5366
+ _0: processLhr(runnerResult.lhr)
5367
+ };
4830
5368
  } catch (raw_exn) {
4831
5369
  let exn = internalToException(raw_exn);
4832
- await killSafely(chrome);
4833
- let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
4834
- return {
5370
+ result = {
4835
5371
  TAG: "Error",
4836
- _0: `Lighthouse audit failed: ` + msg
5372
+ _0: `Lighthouse audit failed: ` + message3(exn)
4837
5373
  };
4838
5374
  }
5375
+ await killSafely(chrome);
5376
+ return result;
4839
5377
  }
4840
- async function execute10(_ctx, input) {
5378
+ async function execute11(_ctx, input) {
4841
5379
  let preset = getOr(input.preset, "desktop");
4842
- switch (preset) {
4843
- case "desktop":
4844
- case "mobile":
4845
- break;
4846
- default:
4847
- return {
4848
- TAG: "Error",
4849
- _0: `Invalid preset "` + preset + `". Must be "desktop" or "mobile".`
4850
- };
4851
- }
4852
5380
  try {
4853
5381
  let chrome = await launch({
4854
5382
  chromeFlags: [
@@ -4861,14 +5389,13 @@ async function execute10(_ctx, input) {
4861
5389
  return await runLighthouse(chrome, input.url, preset);
4862
5390
  } catch (raw_exn) {
4863
5391
  let exn = internalToException(raw_exn);
4864
- let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
4865
5392
  return {
4866
5393
  TAG: "Error",
4867
- _0: `Failed to launch Chrome: ` + msg + `. Make sure Chrome is installed on the system.`
5394
+ _0: `Failed to launch Chrome: ` + message3(exn) + `. Make sure Chrome is installed on the system.`
4868
5395
  };
4869
5396
  }
4870
5397
  }
4871
- var description10 = `Runs a Lighthouse audit on a URL to analyze performance, accessibility, best practices, and SEO.
5398
+ var description11 = `Runs a Lighthouse audit on a URL to analyze performance, accessibility, best practices, and SEO.
4872
5399
 
4873
5400
  WHEN TO USE THIS TOOL:
4874
5401
  - After making changes that might affect page load performance
@@ -4882,21 +5409,27 @@ PARAMETERS:
4882
5409
  IMPORTANT: Check the current_page context for device_emulation - if a mobile device is being emulated (e.g., iPhone, Pixel), use preset: "mobile" to match the user's testing context.
4883
5410
 
4884
5411
  OUTPUT:
4885
- Returns scores (0-100) for each category plus the top 3 issues to fix in each category.
4886
- Higher scores are better. Issues include actionable descriptions.
5412
+ Returns scores (0-100) for each category plus the top 3 worst issues per category.
5413
+ Higher scores are better. Each issue includes:
5414
+ - A description of the problem
5415
+ - Specific offending elements with CSS selectors, HTML snippets, and source locations when available
5416
+ Use the selectors and snippets to locate the exact elements that need fixing.
5417
+
5418
+ IMPORTANT - ITERATIVE FIXING:
5419
+ Only the 3 worst-scoring issues per category are returned. Fixing these may reveal additional issues that were previously ranked lower. After making fixes, re-run the lighthouse audit to check for newly surfaced issues and verify improvements. Repeat until scores are satisfactory.
4887
5420
 
4888
5421
  LIMITATIONS:
4889
5422
  - Requires Chrome to be installed on the system
4890
5423
  - Takes 15-30 seconds to complete
4891
5424
  - Results can vary between runs (\xB15 points is normal)
4892
5425
  - URL must be accessible from the machine running the audit`;
4893
- var name12 = ToolNames.searchFiles;
4894
- var inputSchema11 = schema2((s2) => ({
5426
+ var name13 = ToolNames.searchFiles;
5427
+ var inputSchema12 = schema2((s2) => ({
4895
5428
  pattern: s2.m(string2),
4896
5429
  path: s2.m(option2(string2)),
4897
5430
  max_results: s2.m(option2(int2))
4898
5431
  }));
4899
- var outputSchema11 = schema2((s2) => ({
5432
+ var outputSchema12 = schema2((s2) => ({
4900
5433
  files: s2.m(array2(string2)),
4901
5434
  totalResults: s2.m(int2),
4902
5435
  truncated: s2.m(bool2)
@@ -4946,7 +5479,7 @@ function matchesPattern(fileName2, patternLower) {
4946
5479
  function filterAndPaginate(lines, pattern2, maxResults) {
4947
5480
  let patternLower = pattern2.toLowerCase();
4948
5481
  let matchedFiles = lines.filter((filePath) => {
4949
- let fileName2 = Nodepath.basename(filePath);
5482
+ let fileName2 = Nodepath4.basename(filePath);
4950
5483
  return matchesPattern(fileName2, patternLower);
4951
5484
  });
4952
5485
  let truncated = matchedFiles.length > maxResults;
@@ -5010,7 +5543,7 @@ async function executeGitLsFiles(pattern2, searchPath, maxResults) {
5010
5543
  _0: `Git ls-files failed: ` + match.stderr
5011
5544
  };
5012
5545
  }
5013
- async function execute11(ctx2, input) {
5546
+ async function execute12(ctx2, input) {
5014
5547
  let searchPath = resolveSearchPath(ctx2.sourceRoot, input.path);
5015
5548
  let maxResults = getOr(input.max_results, 20);
5016
5549
  let rgPath = getRipgrepPath2();
@@ -5024,7 +5557,7 @@ async function execute11(ctx2, input) {
5024
5557
  return await executeGitLsFiles(input.pattern, searchPath, maxResults);
5025
5558
  }
5026
5559
  }
5027
- var description11 = `Fast file name search tool that finds files matching a pattern.
5560
+ var description12 = `Fast file name search tool that finds files matching a pattern.
5028
5561
 
5029
5562
  WHEN TO USE THIS TOOL:
5030
5563
  - Use when you need to find files by name pattern
@@ -5052,15 +5585,15 @@ LIMITATIONS:
5052
5585
  - Hidden files (starting with '.') are included
5053
5586
  - Respects .gitignore when using git ls-files fallback
5054
5587
  - Only finds files, not directories`;
5055
- var name13 = ToolNames.loadAgentInstructions;
5056
- var inputSchema12 = schema2((s2) => ({
5588
+ var name14 = ToolNames.loadAgentInstructions;
5589
+ var inputSchema13 = schema2((s2) => ({
5057
5590
  startPath: s2.m(option2(string2))
5058
5591
  }));
5059
5592
  var instructionFileSchema = schema2((s2) => ({
5060
5593
  content: s2.m(string2),
5061
5594
  fullPath: s2.m(string2)
5062
5595
  }));
5063
- var outputSchema12 = array2(instructionFileSchema);
5596
+ var outputSchema13 = array2(instructionFileSchema);
5064
5597
  var agentsVariants = [
5065
5598
  "Agents.md",
5066
5599
  ".claude/Agents.md",
@@ -5077,7 +5610,7 @@ async function findFileCaseInsensitive(dir, targetFileName) {
5077
5610
  let targetLower = targetFileName.toLowerCase();
5078
5611
  let found = files.find((file) => file.toLowerCase() === targetLower);
5079
5612
  if (found !== void 0) {
5080
- return Nodepath.join(dir, found);
5613
+ return Nodepath4.join(dir, found);
5081
5614
  } else {
5082
5615
  return;
5083
5616
  }
@@ -5086,8 +5619,8 @@ async function findFileCaseInsensitive(dir, targetFileName) {
5086
5619
  }
5087
5620
  }
5088
5621
  async function loadIfExists(path) {
5089
- let dir = Nodepath.dirname(path);
5090
- let fileName2 = Nodepath.basename(path);
5622
+ let dir = Nodepath4.dirname(path);
5623
+ let fileName2 = Nodepath4.basename(path);
5091
5624
  let actualPath = await findFileCaseInsensitive(dir, fileName2);
5092
5625
  if (actualPath === void 0) {
5093
5626
  return;
@@ -5106,7 +5639,7 @@ async function loadVariants(dir, variants) {
5106
5639
  let results = [];
5107
5640
  for (let i = 0, i_finish = variants.length; i < i_finish; ++i) {
5108
5641
  let variant = variants[i];
5109
- let path = Nodepath.join(dir, variant);
5642
+ let path = Nodepath4.join(dir, variant);
5110
5643
  let file = await loadIfExists(path);
5111
5644
  if (file !== void 0) {
5112
5645
  results.push(file);
@@ -5123,7 +5656,7 @@ async function findAtDirectory(dir) {
5123
5656
  }
5124
5657
  }
5125
5658
  async function walkUpDirectories(current, acc) {
5126
- let parent = Nodepath.dirname(current);
5659
+ let parent = Nodepath4.dirname(current);
5127
5660
  if (parent === current) {
5128
5661
  return acc;
5129
5662
  }
@@ -5131,7 +5664,7 @@ async function walkUpDirectories(current, acc) {
5131
5664
  let newAcc = acc.concat(filesAtLevel);
5132
5665
  return await walkUpDirectories(parent, newAcc);
5133
5666
  }
5134
- async function execute12(ctx2, input) {
5667
+ async function execute13(ctx2, input) {
5135
5668
  let inputPath = getOr(input.startPath, ".");
5136
5669
  let msg = resolve(ctx2.sourceRoot, inputPath);
5137
5670
  if (msg.TAG !== "Ok") {
@@ -5156,7 +5689,7 @@ async function execute12(ctx2, input) {
5156
5689
  };
5157
5690
  }
5158
5691
  }
5159
- var description12 = `Discovers and loads agent instruction files (Agents.md or CLAUDE.md) following Claude Code's discovery algorithm.
5692
+ var description13 = `Discovers and loads agent instruction files (Agents.md or CLAUDE.md) following Claude Code's discovery algorithm.
5160
5693
 
5161
5694
  Parameters:
5162
5695
  - startPath (optional): Starting directory for discovery - must be under source root. Defaults to "." (source root).
@@ -5173,22 +5706,6 @@ Discovery:
5173
5706
  function coreTools() {
5174
5707
  return {
5175
5708
  tools: [
5176
- {
5177
- name: name7,
5178
- description: description6,
5179
- inputSchema: inputSchema6,
5180
- outputSchema: outputSchema6,
5181
- execute: execute6,
5182
- visibleToAgent: true
5183
- },
5184
- {
5185
- name: name9,
5186
- description: description8,
5187
- inputSchema: inputSchema8,
5188
- outputSchema: outputSchema8,
5189
- execute: execute8,
5190
- visibleToAgent: true
5191
- },
5192
5709
  {
5193
5710
  name: name8,
5194
5711
  description: description7,
@@ -5206,11 +5723,27 @@ function coreTools() {
5206
5723
  visibleToAgent: true
5207
5724
  },
5208
5725
  {
5209
- name: name13,
5210
- description: description12,
5211
- inputSchema: inputSchema12,
5212
- outputSchema: outputSchema12,
5213
- execute: execute12,
5726
+ name: name9,
5727
+ description: description8,
5728
+ inputSchema: inputSchema8,
5729
+ outputSchema: outputSchema8,
5730
+ execute: execute8,
5731
+ visibleToAgent: true
5732
+ },
5733
+ {
5734
+ name: name11,
5735
+ description: description10,
5736
+ inputSchema: inputSchema10,
5737
+ outputSchema: outputSchema10,
5738
+ execute: execute10,
5739
+ visibleToAgent: true
5740
+ },
5741
+ {
5742
+ name: name14,
5743
+ description: description13,
5744
+ inputSchema: inputSchema13,
5745
+ outputSchema: outputSchema13,
5746
+ execute: execute13,
5214
5747
  visibleToAgent: false
5215
5748
  },
5216
5749
  {
@@ -5221,6 +5754,14 @@ function coreTools() {
5221
5754
  execute: execute5,
5222
5755
  visibleToAgent: true
5223
5756
  },
5757
+ {
5758
+ name: name13,
5759
+ description: description12,
5760
+ inputSchema: inputSchema12,
5761
+ outputSchema: outputSchema12,
5762
+ execute: execute12,
5763
+ visibleToAgent: true
5764
+ },
5224
5765
  {
5225
5766
  name: name12,
5226
5767
  description: description11,
@@ -5229,14 +5770,6 @@ function coreTools() {
5229
5770
  execute: execute11,
5230
5771
  visibleToAgent: true
5231
5772
  },
5232
- {
5233
- name: name11,
5234
- description: description10,
5235
- inputSchema: inputSchema10,
5236
- outputSchema: outputSchema10,
5237
- execute: execute10,
5238
- visibleToAgent: true
5239
- },
5240
5773
  {
5241
5774
  name: name3,
5242
5775
  description: description2,
@@ -5244,6 +5777,14 @@ function coreTools() {
5244
5777
  outputSchema: outputSchema2,
5245
5778
  execute: execute2,
5246
5779
  visibleToAgent: true
5780
+ },
5781
+ {
5782
+ name: name7,
5783
+ description: description6,
5784
+ inputSchema: inputSchema6,
5785
+ outputSchema: outputSchema6,
5786
+ execute: execute6,
5787
+ visibleToAgent: true
5247
5788
  }
5248
5789
  ]
5249
5790
  };
@@ -5264,8 +5805,8 @@ function replaceByName(registry, replacement) {
5264
5805
  })
5265
5806
  };
5266
5807
  }
5267
- function getToolByName(registry, name14) {
5268
- return registry.tools.find((m) => m.name === name14);
5808
+ function getToolByName(registry, name15) {
5809
+ return registry.tools.find((m) => m.name === name15);
5269
5810
  }
5270
5811
  function serializeTool(m) {
5271
5812
  return {
@@ -7127,12 +7668,12 @@ var toolCallRequestSchema = schema2((s2) => ({
7127
7668
  var protocolVersion = "1.0";
7128
7669
 
7129
7670
  // ../frontman-core/src/FrontmanCore__Server.res.mjs
7130
- async function executeTool(registry, ctx2, name14, $$arguments) {
7131
- let toolModule = getToolByName(registry, name14);
7671
+ async function executeTool(registry, ctx2, name15, $$arguments) {
7672
+ let toolModule = getToolByName(registry, name15);
7132
7673
  if (toolModule === void 0) {
7133
7674
  return {
7134
7675
  TAG: "ToolNotFound",
7135
- _0: name14
7676
+ _0: name15
7136
7677
  };
7137
7678
  }
7138
7679
  let toolCtx_projectRoot = ctx2.projectRoot;