@frontman-ai/astro 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as Web from 'stream/web';
2
- import * as Fs3 from 'fs';
2
+ import * as Fs from 'fs';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
  import * as Nodepath from 'path';
5
5
  import { dirname, join } from 'path';
@@ -26,6 +26,97 @@ var require_lib = __commonJS({
26
26
  }
27
27
  });
28
28
 
29
+ // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_JsError.js
30
+ function panic(msg) {
31
+ throw new Error(`Panic! ` + msg);
32
+ }
33
+
34
+ // ../../node_modules/@rescript/runtime/lib/es6/Primitive_option.js
35
+ function some(x) {
36
+ if (x === void 0) {
37
+ return {
38
+ BS_PRIVATE_NESTED_SOME_NONE: 0
39
+ };
40
+ } else if (x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
41
+ return {
42
+ BS_PRIVATE_NESTED_SOME_NONE: x.BS_PRIVATE_NESTED_SOME_NONE + 1 | 0
43
+ };
44
+ } else {
45
+ return x;
46
+ }
47
+ }
48
+ function fromNullable(x) {
49
+ if (x == null) {
50
+ return;
51
+ } else {
52
+ return some(x);
53
+ }
54
+ }
55
+ function valFromOption(x) {
56
+ if (x === null || x.BS_PRIVATE_NESTED_SOME_NONE === void 0) {
57
+ return x;
58
+ }
59
+ let depth = x.BS_PRIVATE_NESTED_SOME_NONE;
60
+ if (depth === 0) {
61
+ return;
62
+ } else {
63
+ return {
64
+ BS_PRIVATE_NESTED_SOME_NONE: depth - 1 | 0
65
+ };
66
+ }
67
+ }
68
+
69
+ // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Option.js
70
+ function forEach(opt, f) {
71
+ if (opt !== void 0) {
72
+ return f(valFromOption(opt));
73
+ }
74
+ }
75
+ function getOrThrow(x, message3) {
76
+ if (x !== void 0) {
77
+ return valFromOption(x);
78
+ } else {
79
+ return panic("Option.getOrThrow called for None value");
80
+ }
81
+ }
82
+ function mapOr(opt, $$default, f) {
83
+ if (opt !== void 0) {
84
+ return f(valFromOption(opt));
85
+ } else {
86
+ return $$default;
87
+ }
88
+ }
89
+ function map(opt, f) {
90
+ if (opt !== void 0) {
91
+ return some(f(valFromOption(opt)));
92
+ }
93
+ }
94
+ function flatMap(opt, f) {
95
+ if (opt !== void 0) {
96
+ return f(valFromOption(opt));
97
+ }
98
+ }
99
+ function getOr(opt, $$default) {
100
+ if (opt !== void 0) {
101
+ return valFromOption(opt);
102
+ } else {
103
+ return $$default;
104
+ }
105
+ }
106
+ function orElse(opt, other) {
107
+ if (opt !== void 0) {
108
+ return opt;
109
+ } else {
110
+ return other;
111
+ }
112
+ }
113
+ function isSome(x) {
114
+ return x !== void 0;
115
+ }
116
+ function isNone(x) {
117
+ return x === void 0;
118
+ }
119
+
29
120
  // src/annotation-capture.mjs
30
121
  var annotationCaptureScript = `(function() {
31
122
  var PROPS_PREFIX = '__frontman_props__:';
@@ -257,75 +348,6 @@ function renderComponent(result, displayName, Component, props, slots) {
257
348
  };
258
349
  }
259
350
 
260
- // ../../node_modules/@rescript/runtime/lib/es6/Primitive_option.js
261
- function some(x) {
262
- if (x === void 0) {
263
- return {
264
- BS_PRIVATE_NESTED_SOME_NONE: 0
265
- };
266
- } else if (x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== void 0) {
267
- return {
268
- BS_PRIVATE_NESTED_SOME_NONE: x.BS_PRIVATE_NESTED_SOME_NONE + 1 | 0
269
- };
270
- } else {
271
- return x;
272
- }
273
- }
274
- function fromNullable(x) {
275
- if (x == null) {
276
- return;
277
- } else {
278
- return some(x);
279
- }
280
- }
281
- function valFromOption(x) {
282
- if (x === null || x.BS_PRIVATE_NESTED_SOME_NONE === void 0) {
283
- return x;
284
- }
285
- let depth = x.BS_PRIVATE_NESTED_SOME_NONE;
286
- if (depth === 0) {
287
- return;
288
- } else {
289
- return {
290
- BS_PRIVATE_NESTED_SOME_NONE: depth - 1 | 0
291
- };
292
- }
293
- }
294
-
295
- // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Option.js
296
- function forEach(opt, f) {
297
- if (opt !== void 0) {
298
- return f(valFromOption(opt));
299
- }
300
- }
301
- function map(opt, f) {
302
- if (opt !== void 0) {
303
- return some(f(valFromOption(opt)));
304
- }
305
- }
306
- function flatMap(opt, f) {
307
- if (opt !== void 0) {
308
- return f(valFromOption(opt));
309
- }
310
- }
311
- function getOr(opt, $$default) {
312
- if (opt !== void 0) {
313
- return valFromOption(opt);
314
- } else {
315
- return $$default;
316
- }
317
- }
318
- function orElse(opt, other) {
319
- if (opt !== void 0) {
320
- return opt;
321
- } else {
322
- return other;
323
- }
324
- }
325
- function isSome(x) {
326
- return x !== void 0;
327
- }
328
-
329
351
  // ../frontman-core/src/FrontmanCore__Hosts.res.mjs
330
352
  var apiHost = "api.frontman.sh";
331
353
  var clientJs = "https://app.frontman.sh/frontman.es.js";
@@ -344,7 +366,8 @@ function makeFromObject(rawConfig) {
344
366
  let isDev = host2 !== apiHost;
345
367
  let projectRoot = getOr(orElse(config.projectRoot, orElse(process.env["PROJECT_ROOT"], process.env["PWD"])), ".");
346
368
  let sourceRoot = getOr(config.sourceRoot, projectRoot);
347
- let basePath = getOr(config.basePath, "frontman");
369
+ let raw = getOr(config.basePath, "frontman").replace(/^\/+|\/+$/g, "");
370
+ let basePath = raw === "" ? "frontman" : raw;
348
371
  let serverName = getOr(config.serverName, "frontman-astro");
349
372
  let serverVersion = getOr(config.serverVersion, "1.0.0");
350
373
  let isLightTheme = getOr(config.isLightTheme, false);
@@ -371,7 +394,57 @@ function makeFromObject(rawConfig) {
371
394
  };
372
395
  }
373
396
 
397
+ // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Dict.js
398
+ var forEachWithKey = ((dict3, f) => {
399
+ for (var i in dict3) {
400
+ f(dict3[i], i);
401
+ }
402
+ });
403
+
404
+ // ../frontman-core/src/FrontmanCore__CORS.res.mjs
405
+ var corsHeaders = Object.fromEntries([
406
+ [
407
+ "Access-Control-Allow-Origin",
408
+ "*"
409
+ ],
410
+ [
411
+ "Access-Control-Allow-Methods",
412
+ "GET, POST, OPTIONS"
413
+ ],
414
+ [
415
+ "Access-Control-Allow-Headers",
416
+ "Content-Type"
417
+ ]
418
+ ]);
419
+ function withCors(response) {
420
+ let headers2 = response.headers;
421
+ forEachWithKey(corsHeaders, (value, key) => {
422
+ headers2.set(key, value);
423
+ });
424
+ return response;
425
+ }
426
+ function handlePreflight() {
427
+ return new Response(null, {
428
+ status: 204,
429
+ headers: some(corsHeaders)
430
+ });
431
+ }
432
+
374
433
  // ../../node_modules/@rescript/runtime/lib/es6/Primitive_int.js
434
+ function min(x, y) {
435
+ if (x < y) {
436
+ return x;
437
+ } else {
438
+ return y;
439
+ }
440
+ }
441
+ function max(x, y) {
442
+ if (x > y) {
443
+ return x;
444
+ } else {
445
+ return y;
446
+ }
447
+ }
375
448
  function div(x, y) {
376
449
  if (y === 0) {
377
450
  throw {
@@ -381,6 +454,15 @@ function div(x, y) {
381
454
  }
382
455
  return x / y | 0;
383
456
  }
457
+ function mod_(x, y) {
458
+ if (y === 0) {
459
+ throw {
460
+ RE_EXN_ID: "Division_by_zero",
461
+ Error: new Error()
462
+ };
463
+ }
464
+ return x % y;
465
+ }
384
466
 
385
467
  // ../../node_modules/@rescript/runtime/lib/es6/Primitive_exceptions.js
386
468
  function isExtension(e) {
@@ -415,22 +497,22 @@ function create(str) {
415
497
  // ../../node_modules/sury/src/Sury.res.mjs
416
498
  var immutableEmpty = {};
417
499
  var immutableEmpty$1 = [];
418
- function capitalize(string4) {
419
- return string4.slice(0, 1).toUpperCase() + string4.slice(1);
500
+ function capitalize(string3) {
501
+ return string3.slice(0, 1).toUpperCase() + string3.slice(1);
420
502
  }
421
503
  var copy = ((d2) => ({ ...d2 }));
422
- function fromString(string4) {
504
+ function fromString(string3) {
423
505
  let _idx = 0;
424
506
  while (true) {
425
507
  let idx = _idx;
426
- let match = string4[idx];
508
+ let match = string3[idx];
427
509
  if (match === void 0) {
428
- return `"` + string4 + `"`;
510
+ return `"` + string3 + `"`;
429
511
  }
430
512
  switch (match) {
431
513
  case '"':
432
514
  case "\n":
433
- return JSON.stringify(string4);
515
+ return JSON.stringify(string3);
434
516
  default:
435
517
  _idx = idx + 1 | 0;
436
518
  continue;
@@ -498,14 +580,14 @@ function stringify(unknown2) {
498
580
  return "null";
499
581
  }
500
582
  if (Array.isArray(unknown2)) {
501
- let string4 = "[";
583
+ let string3 = "[";
502
584
  for (let i = 0, i_finish = unknown2.length; i < i_finish; ++i) {
503
585
  if (i !== 0) {
504
- string4 = string4 + ", ";
586
+ string3 = string3 + ", ";
505
587
  }
506
- string4 = string4 + stringify(unknown2[i]);
588
+ string3 = string3 + stringify(unknown2[i]);
507
589
  }
508
- return string4 + "]";
590
+ return string3 + "]";
509
591
  }
510
592
  if (unknown2.constructor !== Object) {
511
593
  return Object.prototype.toString.call(unknown2);
@@ -522,9 +604,9 @@ function stringify(unknown2) {
522
604
  function toExpression(schema3) {
523
605
  let tag = schema3.type;
524
606
  let $$const = schema3.const;
525
- let name11 = schema3.name;
526
- if (name11 !== void 0) {
527
- return name11;
607
+ let name14 = schema3.name;
608
+ if (name14 !== void 0) {
609
+ return name14;
528
610
  }
529
611
  if ($$const !== void 0) {
530
612
  return stringify($$const);
@@ -1069,8 +1151,8 @@ function refinement(b, inputVar, schema3, negative) {
1069
1151
  }
1070
1152
  let additionalItems = schema3.additionalItems;
1071
1153
  let items = schema3.items;
1072
- let length2 = items.length;
1073
- let code = tag === "array" ? additionalItems === "strip" || additionalItems === "strict" ? additionalItems === "strip" ? and_ + inputVar + `.length` + gt + length2 : and_ + inputVar + `.length` + eq + length2 : "" : additionalItems === "strip" ? "" : and_ + not_ + `Array.isArray(` + inputVar + `)`;
1154
+ let length3 = items.length;
1155
+ let code = tag === "array" ? additionalItems === "strip" || additionalItems === "strict" ? additionalItems === "strip" ? and_ + inputVar + `.length` + gt + length3 : and_ + inputVar + `.length` + eq + length3 : "" : additionalItems === "strip" ? "" : and_ + not_ + `Array.isArray(` + inputVar + `)`;
1074
1156
  for (let idx = 0, idx_finish = items.length; idx < idx_finish; ++idx) {
1075
1157
  let match$3 = items[idx];
1076
1158
  let location = match$3.location;
@@ -1644,10 +1726,10 @@ function isPriority(tagFlag, byKey) {
1644
1726
  }
1645
1727
  }
1646
1728
  function isWiderUnionSchema(schemaAnyOf, inputAnyOf) {
1647
- return inputAnyOf.every((inputSchema10, idx) => {
1729
+ return inputAnyOf.every((inputSchema13, idx) => {
1648
1730
  let schema3 = schemaAnyOf[idx];
1649
- if (schema3 !== void 0 && !(flags[inputSchema10.type] & 9152) && inputSchema10.type === schema3.type) {
1650
- return inputSchema10.const === schema3.const;
1731
+ if (schema3 !== void 0 && !(flags[inputSchema13.type] & 9152) && inputSchema13.type === schema3.type) {
1732
+ return inputSchema13.const === schema3.const;
1651
1733
  } else {
1652
1734
  return false;
1653
1735
  }
@@ -2222,9 +2304,9 @@ function definitionToSchema(definition) {
2222
2304
  };
2223
2305
  }
2224
2306
  let fieldNames = Object.keys(definition);
2225
- let length2 = fieldNames.length;
2307
+ let length3 = fieldNames.length;
2226
2308
  let items = [];
2227
- for (let idx$1 = 0; idx$1 < length2; ++idx$1) {
2309
+ for (let idx$1 = 0; idx$1 < length3; ++idx$1) {
2228
2310
  let location$1 = fieldNames[idx$1];
2229
2311
  let schema$1 = definitionToSchema(definition[location$1]);
2230
2312
  let item = {
@@ -2294,9 +2376,9 @@ function internalToJSONSchema(schema3, defs) {
2294
2376
  jsonSchema.maxLength = match.length;
2295
2377
  return;
2296
2378
  case "Length":
2297
- let length2 = match.length;
2298
- jsonSchema.minLength = length2;
2299
- jsonSchema.maxLength = length2;
2379
+ let length3 = match.length;
2380
+ jsonSchema.minLength = length3;
2381
+ jsonSchema.maxLength = length3;
2300
2382
  return;
2301
2383
  case "Pattern":
2302
2384
  jsonSchema.pattern = String(match.re);
@@ -2370,9 +2452,9 @@ function internalToJSONSchema(schema3, defs) {
2370
2452
  jsonSchema.maxItems = match.length;
2371
2453
  return;
2372
2454
  case "Length":
2373
- let length2 = match.length;
2374
- jsonSchema.maxItems = length2;
2375
- jsonSchema.minItems = length2;
2455
+ let length3 = match.length;
2456
+ jsonSchema.maxItems = length3;
2457
+ jsonSchema.minItems = length3;
2376
2458
  return;
2377
2459
  }
2378
2460
  });
@@ -2514,46 +2596,6 @@ var reverseConvertToJsonOrThrow2 = reverseConvertToJsonOrThrow;
2514
2596
  var schema2 = schema;
2515
2597
  var toJSONSchema2 = toJSONSchema;
2516
2598
 
2517
- // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_JSON.js
2518
- function bool3(json3) {
2519
- if (typeof json3 === "boolean") {
2520
- return json3;
2521
- }
2522
- }
2523
- function $$null2(json3) {
2524
- if (json3 === null) {
2525
- return null;
2526
- }
2527
- }
2528
- function string3(json3) {
2529
- if (typeof json3 === "string") {
2530
- return json3;
2531
- }
2532
- }
2533
- function float3(json3) {
2534
- if (typeof json3 === "number") {
2535
- return json3;
2536
- }
2537
- }
2538
- function object2(json3) {
2539
- if (typeof json3 === "object" && json3 !== null && !Array.isArray(json3)) {
2540
- return json3;
2541
- }
2542
- }
2543
- function array3(json3) {
2544
- if (Array.isArray(json3)) {
2545
- return json3;
2546
- }
2547
- }
2548
- var Decode = {
2549
- bool: bool3,
2550
- $$null: $$null2,
2551
- string: string3,
2552
- float: float3,
2553
- object: object2,
2554
- array: array3
2555
- };
2556
-
2557
2599
  // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_JsExn.js
2558
2600
  function fromException(exn) {
2559
2601
  if (exn.RE_EXN_ID === "JsExn") {
@@ -2563,6 +2605,11 @@ function fromException(exn) {
2563
2605
  var getOrUndefined = ((fieldName) => (t) => t && typeof t[fieldName] === "string" ? t[fieldName] : void 0);
2564
2606
  var message2 = getOrUndefined("message");
2565
2607
 
2608
+ // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Promise.js
2609
+ function $$catch(promise, callback) {
2610
+ return promise.catch((err) => callback(internalToException(err)));
2611
+ }
2612
+
2566
2613
  // ../frontman-protocol/src/FrontmanProtocol__MCP.res.mjs
2567
2614
  enableJson2();
2568
2615
  var capabilitiesSchema = schema2((s2) => ({
@@ -4247,6 +4294,24 @@ async function Te(o) {
4247
4294
  }
4248
4295
 
4249
4296
  // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Array.js
4297
+ function make2(length3, x) {
4298
+ if (length3 <= 0) {
4299
+ return [];
4300
+ }
4301
+ let arr = new Array(length3);
4302
+ arr.fill(x);
4303
+ return arr;
4304
+ }
4305
+ function fromInitializer(length3, f) {
4306
+ if (length3 <= 0) {
4307
+ return [];
4308
+ }
4309
+ let arr = new Array(length3);
4310
+ for (let i = 0; i < length3; ++i) {
4311
+ arr[i] = f(i);
4312
+ }
4313
+ return arr;
4314
+ }
4250
4315
  function reduce(arr, init, f) {
4251
4316
  return arr.reduce(f, init);
4252
4317
  }
@@ -4852,67 +4917,666 @@ LIMITATIONS:
4852
4917
  - Results limited to max_results (default 20)
4853
4918
  - Binary files are automatically skipped
4854
4919
  - Hidden files (starting with '.') are skipped by default`;
4855
- var name3 = ToolNames.readFile;
4856
- var inputSchema2 = schema2((s2) => ({
4857
- path: s2.m(string2),
4858
- offset: s2.m(option2(int2)),
4859
- limit: s2.m(option2(int2))
4860
- }));
4861
- var pathContextSchema = schema2((s2) => ({
4862
- sourceRoot: s2.m(string2),
4863
- resolvedPath: s2.m(string2),
4864
- relativePath: s2.m(string2)
4865
- }));
4866
- var outputSchema2 = schema2((s2) => ({
4867
- content: s2.m(string2),
4868
- totalLines: s2.m(int2),
4869
- hasMore: s2.m(bool2),
4870
- _context: s2.m(option2(pathContextSchema))
4871
- }));
4872
- async function execute2(ctx2, input) {
4873
- let offset = getOr(input.offset, 0);
4874
- let limit = getOr(input.limit, 500);
4875
- let err = resolve2(ctx2.sourceRoot, input.path);
4876
- if (err.TAG !== "Ok") {
4877
- return {
4878
- TAG: "Error",
4879
- _0: formatError(err._0)
4880
- };
4881
- }
4882
- let result = err._0;
4883
- try {
4884
- let content = await Fs3.promises.readFile(result.resolvedPath, "utf8");
4885
- let lines = content.split("\n");
4886
- let totalLines = lines.length;
4887
- let selectedLines = lines.slice(offset, offset + limit | 0);
4888
- let selectedContent = selectedLines.join("\n");
4889
- let hasMore = (offset + limit | 0) < totalLines;
4920
+
4921
+ // ../frontman-core/src/FrontmanCore__FileTracker.res.mjs
4922
+ var readFiles = {
4923
+ contents: /* @__PURE__ */ new Set()
4924
+ };
4925
+ function recordRead(resolvedPath) {
4926
+ readFiles.contents.add(resolvedPath);
4927
+ }
4928
+ function assertReadBefore(resolvedPath) {
4929
+ if (readFiles.contents.has(resolvedPath)) {
4890
4930
  return {
4891
4931
  TAG: "Ok",
4892
- _0: {
4893
- content: selectedContent,
4894
- totalLines,
4895
- hasMore,
4896
- _context: {
4897
- sourceRoot: result.sourceRoot,
4898
- resolvedPath: result.resolvedPath,
4899
- relativePath: result.relativePath
4900
- }
4901
- }
4932
+ _0: void 0
4902
4933
  };
4903
- } catch (raw_exn) {
4904
- let exn = internalToException(raw_exn);
4905
- let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
4934
+ } else {
4906
4935
  return {
4907
4936
  TAG: "Error",
4908
- _0: `Failed to read file ` + input.path + `: ` + msg
4937
+ _0: `File must be read before editing. Use read_file on "` + resolvedPath + `" first to see its current content.`
4909
4938
  };
4910
4939
  }
4911
4940
  }
4912
- var description2 = `Reads a file from the filesystem.
4913
4941
 
4914
- Parameters:
4915
- - path (required): Path to file - either relative to source root or absolute (must be under source root)
4942
+ // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_String.js
4943
+ function indexOfOpt(s2, search) {
4944
+ let index = s2.indexOf(search);
4945
+ if (index !== -1) {
4946
+ return index;
4947
+ }
4948
+ }
4949
+
4950
+ // ../frontman-core/src/tools/FrontmanCore__Tool__EditFile__Matcher.res.mjs
4951
+ function levenshtein(a, b) {
4952
+ let match = a.length;
4953
+ let match$1 = b.length;
4954
+ if (match === 0) {
4955
+ return b.length;
4956
+ }
4957
+ if (match$1 === 0) {
4958
+ return a.length;
4959
+ }
4960
+ let matrix = fromInitializer(match + 1 | 0, (i) => fromInitializer(match$1 + 1 | 0, (j2) => {
4961
+ if (i !== 0) {
4962
+ if (j2 !== 0) {
4963
+ return 0;
4964
+ } else {
4965
+ return i;
4966
+ }
4967
+ } else {
4968
+ return j2;
4969
+ }
4970
+ }));
4971
+ for (let i = 1; i <= match; ++i) {
4972
+ for (let j2 = 1; j2 <= match$1; ++j2) {
4973
+ let cost = a.charAt(i - 1 | 0) === b.charAt(j2 - 1 | 0) ? 0 : 1;
4974
+ let del = getOrThrow(matrix[i - 1 | 0])[j2] + 1 | 0;
4975
+ let ins = getOrThrow(matrix[i])[j2 - 1 | 0] + 1 | 0;
4976
+ let sub = getOrThrow(matrix[i - 1 | 0])[j2 - 1 | 0] + cost | 0;
4977
+ getOrThrow(matrix[i])[j2] = min(del, min(ins, sub));
4978
+ }
4979
+ }
4980
+ return getOrThrow(matrix[match])[match$1];
4981
+ }
4982
+ function lineOffset(lines, lineIndex) {
4983
+ let offset = 0;
4984
+ for (let k2 = 0; k2 < lineIndex; ++k2) {
4985
+ offset = (offset + getOrThrow(lines[k2]).length | 0) + 1 | 0;
4986
+ }
4987
+ return offset;
4988
+ }
4989
+ function extractBlock(content, lines, startLine, endLine) {
4990
+ let startIdx = lineOffset(lines, startLine);
4991
+ let endIdx = lineOffset(lines, endLine) + getOrThrow(lines[endLine]).length | 0;
4992
+ return content.slice(startIdx, endIdx);
4993
+ }
4994
+ function escapeRegex(str) {
4995
+ return str.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&");
4996
+ }
4997
+ function exactMatch(content, find) {
4998
+ if (content.includes(find)) {
4999
+ return [find];
5000
+ } else {
5001
+ return [];
5002
+ }
5003
+ }
5004
+ function lineTrimMatch(content, find) {
5005
+ let contentLines = content.split("\n");
5006
+ let searchLines = find.split("\n");
5007
+ let last = searchLines[searchLines.length - 1 | 0];
5008
+ let searchLines$1 = last === "" ? searchLines.slice(0, searchLines.length - 1 | 0) : searchLines;
5009
+ let searchLen = searchLines$1.length;
5010
+ let results = [];
5011
+ for (let i = 0, i_finish = contentLines.length - searchLen | 0; i <= i_finish; ++i) {
5012
+ let matches2 = true;
5013
+ let j2 = 0;
5014
+ while (j2 < searchLen && matches2) {
5015
+ let origTrimmed = getOrThrow(contentLines[i + j2 | 0]).trim();
5016
+ let searchTrimmed = getOrThrow(searchLines$1[j2]).trim();
5017
+ if (origTrimmed === searchTrimmed) {
5018
+ j2 = j2 + 1 | 0;
5019
+ } else {
5020
+ matches2 = false;
5021
+ }
5022
+ }
5023
+ if (matches2) {
5024
+ results.push(extractBlock(content, contentLines, i, (i + searchLen | 0) - 1 | 0));
5025
+ }
5026
+ }
5027
+ return results;
5028
+ }
5029
+ function anchoredBlockMatch(content, find) {
5030
+ let contentLines = content.split("\n");
5031
+ let searchLines = find.split("\n");
5032
+ let last = searchLines[searchLines.length - 1 | 0];
5033
+ let searchLines$1 = last === "" ? searchLines.slice(0, searchLines.length - 1 | 0) : searchLines;
5034
+ if (searchLines$1.length < 3) {
5035
+ return [];
5036
+ }
5037
+ let firstLineSearch = getOrThrow(searchLines$1[0]).trim();
5038
+ let lastLineSearch = getOrThrow(searchLines$1[searchLines$1.length - 1 | 0]).trim();
5039
+ let searchBlockSize = searchLines$1.length;
5040
+ let candidates = [];
5041
+ for (let i = 0, i_finish = contentLines.length; i < i_finish; ++i) {
5042
+ if (getOrThrow(contentLines[i]).trim() === firstLineSearch) {
5043
+ let j2 = i + 2 | 0;
5044
+ while (j2 < contentLines.length) {
5045
+ if (getOrThrow(contentLines[j2]).trim() === lastLineSearch) {
5046
+ candidates.push({
5047
+ startLine: i,
5048
+ endLine: j2
5049
+ });
5050
+ j2 = j2 + 1 | 0;
5051
+ } else {
5052
+ j2 = j2 + 1 | 0;
5053
+ }
5054
+ }
5055
+ }
5056
+ }
5057
+ let match = candidates.length;
5058
+ if (match === 0) {
5059
+ return [];
5060
+ }
5061
+ if (match !== 1) {
5062
+ let bestMatch = {
5063
+ contents: void 0
5064
+ };
5065
+ let maxSim = {
5066
+ contents: -1
5067
+ };
5068
+ candidates.forEach((cand) => {
5069
+ let startLine2 = cand.startLine;
5070
+ let actualBlockSize2 = (cand.endLine - startLine2 | 0) + 1 | 0;
5071
+ let linesToCheck2 = min(searchBlockSize - 2 | 0, actualBlockSize2 - 2 | 0);
5072
+ let similarity2;
5073
+ if (linesToCheck2 > 0) {
5074
+ let sim = 0;
5075
+ for (let j2 = 1, j_finish = min(searchBlockSize - 2 | 0, actualBlockSize2 - 2 | 0); j2 <= j_finish; ++j2) {
5076
+ let origLine = getOrThrow(contentLines[startLine2 + j2 | 0]).trim();
5077
+ let searchLine = getOrThrow(searchLines$1[j2]).trim();
5078
+ let maxLen = max(origLine.length, searchLine.length);
5079
+ if (maxLen > 0) {
5080
+ let distance = levenshtein(origLine, searchLine);
5081
+ sim = sim + (1 - distance / maxLen);
5082
+ }
5083
+ }
5084
+ similarity2 = sim / linesToCheck2;
5085
+ } else {
5086
+ similarity2 = 1;
5087
+ }
5088
+ if (similarity2 > maxSim.contents) {
5089
+ maxSim.contents = similarity2;
5090
+ bestMatch.contents = cand;
5091
+ return;
5092
+ }
5093
+ });
5094
+ let match$1 = maxSim.contents >= 0.3;
5095
+ let match$2 = bestMatch.contents;
5096
+ if (match$1) {
5097
+ if (match$2 !== void 0) {
5098
+ return [extractBlock(content, contentLines, match$2.startLine, match$2.endLine)];
5099
+ } else {
5100
+ return [];
5101
+ }
5102
+ } else {
5103
+ return [];
5104
+ }
5105
+ }
5106
+ let match$3 = getOrThrow(candidates[0]);
5107
+ let endLine = match$3.endLine;
5108
+ let startLine = match$3.startLine;
5109
+ let actualBlockSize = (endLine - startLine | 0) + 1 | 0;
5110
+ let linesToCheck = min(searchBlockSize - 2 | 0, actualBlockSize - 2 | 0);
5111
+ let similarity;
5112
+ if (linesToCheck > 0) {
5113
+ let sim = 0;
5114
+ let j$1 = 1;
5115
+ while (j$1 < (searchBlockSize - 1 | 0) && j$1 < (actualBlockSize - 1 | 0)) {
5116
+ let origLine = getOrThrow(contentLines[startLine + j$1 | 0]).trim();
5117
+ let searchLine = getOrThrow(searchLines$1[j$1]).trim();
5118
+ let maxLen = max(origLine.length, searchLine.length);
5119
+ if (maxLen > 0) {
5120
+ let distance = levenshtein(origLine, searchLine);
5121
+ sim = sim + (1 - distance / maxLen) / linesToCheck;
5122
+ }
5123
+ j$1 = sim >= 0 ? searchBlockSize : j$1 + 1 | 0;
5124
+ }
5125
+ similarity = sim;
5126
+ } else {
5127
+ similarity = 1;
5128
+ }
5129
+ if (similarity >= 0) {
5130
+ return [extractBlock(content, contentLines, startLine, endLine)];
5131
+ } else {
5132
+ return [];
5133
+ }
5134
+ }
5135
+ function normalizedWhitespaceMatch(content, find) {
5136
+ let normalize3 = (text) => text.replace(/\s+/g, " ").trim();
5137
+ let normalizedFind = normalize3(find);
5138
+ let contentLines = content.split("\n");
5139
+ let results = [];
5140
+ contentLines.forEach((line) => {
5141
+ if (normalize3(line) === normalizedFind) {
5142
+ results.push(line);
5143
+ return;
5144
+ }
5145
+ let normalizedLine = normalize3(line);
5146
+ if (!normalizedLine.includes(normalizedFind)) {
5147
+ return;
5148
+ }
5149
+ let words = filterMap(find.trim().split(/\s+/), (x) => x);
5150
+ if (words.length === 0) {
5151
+ return;
5152
+ }
5153
+ let pattern2 = words.map(escapeRegex).join("\\s+");
5154
+ try {
5155
+ let regex = new RegExp(pattern2);
5156
+ let result = line.match(regex);
5157
+ if (result == null) {
5158
+ return;
5159
+ }
5160
+ let m = result[0];
5161
+ if (m.length > 0) {
5162
+ results.push(m);
5163
+ return;
5164
+ } else {
5165
+ return;
5166
+ }
5167
+ } catch (exn) {
5168
+ return;
5169
+ }
5170
+ });
5171
+ let findLines = find.split("\n");
5172
+ if (findLines.length > 1) {
5173
+ for (let i = 0, i_finish = contentLines.length - findLines.length | 0; i <= i_finish; ++i) {
5174
+ let block = contentLines.slice(i, i + findLines.length | 0).join("\n");
5175
+ if (normalize3(block) === normalizedFind) {
5176
+ results.push(block);
5177
+ }
5178
+ }
5179
+ }
5180
+ return results;
5181
+ }
5182
+ function flexibleIndentMatch(content, find) {
5183
+ let removeIndent = (text) => {
5184
+ let lines = text.split("\n");
5185
+ let nonEmptyLines = lines.filter((line) => line.trim().length > 0);
5186
+ let match = nonEmptyLines.length;
5187
+ if (match === 0) {
5188
+ return text;
5189
+ }
5190
+ let minIndent = reduce(nonEmptyLines, 999999, (acc, line) => {
5191
+ let m = line.match(/^(\s*)/);
5192
+ let indent = !(m == null) ? m[0].length : 0;
5193
+ return min(acc, indent);
5194
+ });
5195
+ return lines.map((line) => {
5196
+ let match2 = line.trim().length;
5197
+ if (match2 !== 0) {
5198
+ return line.slice(minIndent, line.length);
5199
+ } else {
5200
+ return line;
5201
+ }
5202
+ }).join("\n");
5203
+ };
5204
+ let normalizedFind = removeIndent(find);
5205
+ let contentLines = content.split("\n");
5206
+ let findLines = find.split("\n");
5207
+ let results = [];
5208
+ for (let i = 0, i_finish = contentLines.length - findLines.length | 0; i <= i_finish; ++i) {
5209
+ let block = contentLines.slice(i, i + findLines.length | 0).join("\n");
5210
+ if (removeIndent(block) === normalizedFind) {
5211
+ results.push(block);
5212
+ }
5213
+ }
5214
+ return results;
5215
+ }
5216
+ function escapeNormalizedMatch(content, find) {
5217
+ let unescape = (function(str) {
5218
+ return str.replace(/\\([ntr'"\\/$])/g, function(_m, c2) {
5219
+ if (c2 === "n") return String.fromCharCode(10);
5220
+ if (c2 === "t") return String.fromCharCode(9);
5221
+ if (c2 === "r") return String.fromCharCode(13);
5222
+ return c2;
5223
+ });
5224
+ });
5225
+ let unescapedFind = unescape(find);
5226
+ let results = [];
5227
+ if (content.includes(unescapedFind)) {
5228
+ results.push(unescapedFind);
5229
+ }
5230
+ let contentLines = content.split("\n");
5231
+ let findLines = unescapedFind.split("\n");
5232
+ for (let i = 0, i_finish = contentLines.length - findLines.length | 0; i <= i_finish; ++i) {
5233
+ let block = contentLines.slice(i, i + findLines.length | 0).join("\n");
5234
+ let unescapedBlock = unescape(block);
5235
+ if (unescapedBlock === unescapedFind && !results.includes(block)) {
5236
+ results.push(block);
5237
+ }
5238
+ }
5239
+ return results;
5240
+ }
5241
+ function trimmedBoundaryMatch(content, find) {
5242
+ let trimmedFind = find.trim();
5243
+ if (trimmedFind === find) {
5244
+ return [];
5245
+ }
5246
+ let results = [];
5247
+ if (content.includes(trimmedFind)) {
5248
+ results.push(trimmedFind);
5249
+ }
5250
+ let contentLines = content.split("\n");
5251
+ let findLines = find.split("\n");
5252
+ for (let i = 0, i_finish = contentLines.length - findLines.length | 0; i <= i_finish; ++i) {
5253
+ let block = contentLines.slice(i, i + findLines.length | 0).join("\n");
5254
+ if (block.trim() === trimmedFind && !results.includes(block)) {
5255
+ results.push(block);
5256
+ }
5257
+ }
5258
+ return results;
5259
+ }
5260
+ function contextAnchorMatch(content, find) {
5261
+ let findLines = find.split("\n");
5262
+ let last = findLines[findLines.length - 1 | 0];
5263
+ let findLines$1 = last === "" ? findLines.slice(0, findLines.length - 1 | 0) : findLines;
5264
+ if (findLines$1.length < 3) {
5265
+ return [];
5266
+ }
5267
+ let contentLines = content.split("\n");
5268
+ let firstLine = getOrThrow(findLines$1[0]).trim();
5269
+ let lastLine = getOrThrow(findLines$1[findLines$1.length - 1 | 0]).trim();
5270
+ let results = [];
5271
+ for (let i = 0, i_finish = contentLines.length; i < i_finish; ++i) {
5272
+ if (getOrThrow(contentLines[i]).trim() === firstLine) {
5273
+ let j2 = i + 2 | 0;
5274
+ while (j2 < contentLines.length) {
5275
+ if (getOrThrow(contentLines[j2]).trim() === lastLine) {
5276
+ let blockLines = contentLines.slice(i, j2 + 1 | 0);
5277
+ if (blockLines.length === findLines$1.length) {
5278
+ let matchingLines = 0;
5279
+ let totalNonEmpty = 0;
5280
+ for (let k2 = 1, k_finish = blockLines.length - 2 | 0; k2 <= k_finish; ++k2) {
5281
+ let blockLine = getOrThrow(blockLines[k2]).trim();
5282
+ let findLine = getOrThrow(findLines$1[k2]).trim();
5283
+ let match = blockLine.length > 0;
5284
+ let match$1 = findLine.length > 0;
5285
+ let exit = 0;
5286
+ if (match || match$1) {
5287
+ exit = 1;
5288
+ }
5289
+ if (exit === 1) {
5290
+ totalNonEmpty = totalNonEmpty + 1 | 0;
5291
+ if (blockLine === findLine) {
5292
+ matchingLines = matchingLines + 1 | 0;
5293
+ }
5294
+ }
5295
+ }
5296
+ let total = totalNonEmpty;
5297
+ let passes = total !== 0 ? matchingLines / total >= 0.5 : true;
5298
+ if (passes) {
5299
+ results.push(extractBlock(content, contentLines, i, j2));
5300
+ }
5301
+ }
5302
+ j2 = j2 + 1 | 0;
5303
+ } else {
5304
+ j2 = j2 + 1 | 0;
5305
+ }
5306
+ }
5307
+ }
5308
+ }
5309
+ return results;
5310
+ }
5311
+ function multiOccurrenceMatch(content, find) {
5312
+ let results = [];
5313
+ let startIndex = {
5314
+ contents: 0
5315
+ };
5316
+ let continue_ = true;
5317
+ while (continue_) {
5318
+ let searchContent = content.slice(startIndex.contents, content.length);
5319
+ let idx = map(indexOfOpt(searchContent, find), (i) => i + startIndex.contents | 0);
5320
+ if (idx !== void 0) {
5321
+ results.push(find);
5322
+ startIndex.contents = idx + find.length | 0;
5323
+ } else {
5324
+ continue_ = false;
5325
+ }
5326
+ }
5327
+ return results;
5328
+ }
5329
+ var strategies = [
5330
+ exactMatch,
5331
+ lineTrimMatch,
5332
+ anchoredBlockMatch,
5333
+ normalizedWhitespaceMatch,
5334
+ flexibleIndentMatch,
5335
+ escapeNormalizedMatch,
5336
+ trimmedBoundaryMatch,
5337
+ contextAnchorMatch,
5338
+ multiOccurrenceMatch
5339
+ ];
5340
+ function applyEdit(content, oldText, newText, replaceAllOpt) {
5341
+ let replaceAll = replaceAllOpt !== void 0 ? replaceAllOpt : false;
5342
+ let notFound = {
5343
+ contents: true
5344
+ };
5345
+ let result = {
5346
+ contents: void 0
5347
+ };
5348
+ let strategyIdx = 0;
5349
+ while (isNone(result.contents) && strategyIdx < strategies.length) {
5350
+ let strategy = getOrThrow(strategies[strategyIdx]);
5351
+ let candidates = strategy(content, oldText);
5352
+ let match = !replaceAll && candidates.length > 1;
5353
+ if (match) {
5354
+ notFound.contents = false;
5355
+ } else if (replaceAll) {
5356
+ candidates.forEach((candidate) => {
5357
+ let match2 = result.contents;
5358
+ if (match2 !== void 0) {
5359
+ return;
5360
+ }
5361
+ let idx = content.indexOf(candidate);
5362
+ if (idx >= 0) {
5363
+ notFound.contents = false;
5364
+ result.contents = {
5365
+ TAG: "Applied",
5366
+ _0: content.split(candidate).join(newText)
5367
+ };
5368
+ return;
5369
+ }
5370
+ });
5371
+ } else {
5372
+ let candidate = candidates[0];
5373
+ if (candidate !== void 0) {
5374
+ let idx = content.indexOf(candidate);
5375
+ if (idx >= 0) {
5376
+ notFound.contents = false;
5377
+ let lastIdx = content.lastIndexOf(candidate);
5378
+ if (idx === lastIdx) {
5379
+ let before = content.slice(0, idx);
5380
+ let after = content.slice(idx + candidate.length | 0, content.length);
5381
+ result.contents = {
5382
+ TAG: "Applied",
5383
+ _0: before + newText + after
5384
+ };
5385
+ }
5386
+ }
5387
+ }
5388
+ }
5389
+ strategyIdx = strategyIdx + 1 | 0;
5390
+ }
5391
+ let r = result.contents;
5392
+ if (r !== void 0) {
5393
+ return r;
5394
+ } else if (notFound.contents) {
5395
+ return "NotFound";
5396
+ } else {
5397
+ return "Ambiguous";
5398
+ }
5399
+ }
5400
+
5401
+ // ../frontman-core/src/tools/FrontmanCore__Tool__EditFile.res.mjs
5402
+ var inputSchema2 = schema2((s2) => ({
5403
+ path: s2.m(string2),
5404
+ oldText: s2.m(string2),
5405
+ newText: s2.m(string2),
5406
+ replaceAll: s2.m(option2(bool2))
5407
+ }));
5408
+ var pathContextSchema = schema2((s2) => ({
5409
+ sourceRoot: s2.m(string2),
5410
+ resolvedPath: s2.m(string2),
5411
+ relativePath: s2.m(string2)
5412
+ }));
5413
+ var outputSchema2 = schema2((s2) => ({
5414
+ message: s2.m(string2),
5415
+ _context: s2.m(option2(pathContextSchema))
5416
+ }));
5417
+ async function execute2(ctx2, input) {
5418
+ let replaceAll = getOr(input.replaceAll, false);
5419
+ if (input.oldText === input.newText) {
5420
+ return {
5421
+ TAG: "Error",
5422
+ _0: "oldText and newText must be different"
5423
+ };
5424
+ }
5425
+ let err = resolve2(ctx2.sourceRoot, input.path);
5426
+ if (err.TAG !== "Ok") {
5427
+ return {
5428
+ TAG: "Error",
5429
+ _0: formatError(err._0)
5430
+ };
5431
+ }
5432
+ let result = err._0;
5433
+ let pathCtx_sourceRoot = result.sourceRoot;
5434
+ let pathCtx_resolvedPath = result.resolvedPath;
5435
+ let pathCtx_relativePath = result.relativePath;
5436
+ let pathCtx = {
5437
+ sourceRoot: pathCtx_sourceRoot,
5438
+ resolvedPath: pathCtx_resolvedPath,
5439
+ relativePath: pathCtx_relativePath
5440
+ };
5441
+ if (input.oldText === "") {
5442
+ try {
5443
+ let dirPath = dirname3(result);
5444
+ await Fs.promises.mkdir(dirPath, {
5445
+ recursive: true
5446
+ });
5447
+ await Fs.promises.writeFile(result.resolvedPath, input.newText, "utf8");
5448
+ return {
5449
+ TAG: "Ok",
5450
+ _0: {
5451
+ message: "File created successfully.",
5452
+ _context: pathCtx
5453
+ }
5454
+ };
5455
+ } catch (raw_exn) {
5456
+ let exn = internalToException(raw_exn);
5457
+ let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
5458
+ return {
5459
+ TAG: "Error",
5460
+ _0: `Failed to create file ` + input.path + `: ` + msg
5461
+ };
5462
+ }
5463
+ } else {
5464
+ let msg$1 = assertReadBefore(result.resolvedPath);
5465
+ if (msg$1.TAG !== "Ok") {
5466
+ return {
5467
+ TAG: "Error",
5468
+ _0: msg$1._0
5469
+ };
5470
+ }
5471
+ try {
5472
+ let content = await Fs.promises.readFile(result.resolvedPath, "utf8");
5473
+ let newContent = applyEdit(content, input.oldText, input.newText, replaceAll);
5474
+ if (typeof newContent !== "object") {
5475
+ if (newContent === "NotFound") {
5476
+ return {
5477
+ TAG: "Error",
5478
+ _0: `oldText not found in file ` + input.path + `. Make sure the text matches exactly, or read the file again to see its current content.`
5479
+ };
5480
+ } else {
5481
+ return {
5482
+ TAG: "Error",
5483
+ _0: `Found multiple matches for oldText in ` + input.path + `. Provide more surrounding context to identify the correct match, or use replaceAll to replace all occurrences.`
5484
+ };
5485
+ }
5486
+ }
5487
+ await Fs.promises.writeFile(result.resolvedPath, newContent._0, "utf8");
5488
+ return {
5489
+ TAG: "Ok",
5490
+ _0: {
5491
+ message: "Edit applied successfully.",
5492
+ _context: pathCtx
5493
+ }
5494
+ };
5495
+ } catch (raw_exn$1) {
5496
+ let exn$1 = internalToException(raw_exn$1);
5497
+ let msg$2 = getOr(flatMap(fromException(exn$1), message2), "Unknown error");
5498
+ return {
5499
+ TAG: "Error",
5500
+ _0: `Failed to edit file ` + input.path + `: ` + msg$2
5501
+ };
5502
+ }
5503
+ }
5504
+ }
5505
+ var name3 = "edit_file";
5506
+ var description2 = `Edits a file by replacing text using fuzzy matching.
5507
+
5508
+ Parameters:
5509
+ - path (required): Path to file - either relative to source root or absolute (must be under source root)
5510
+ - oldText (required): The text to find and replace. An empty oldText creates a new file with newText as content.
5511
+ - newText (required): The replacement text (must differ from oldText)
5512
+ - replaceAll (optional): If true, replaces all occurrences. Default: false.
5513
+
5514
+ The tool uses multiple matching strategies (exact, line-trimmed, whitespace-normalized,
5515
+ indentation-flexible, etc.) to handle common formatting differences.
5516
+
5517
+ IMPORTANT: You must read_file before editing. The tool will reject edits on unread files.`;
5518
+ var name4 = ToolNames.readFile;
5519
+ var inputSchema3 = schema2((s2) => ({
5520
+ path: s2.m(string2),
5521
+ offset: s2.m(option2(int2)),
5522
+ limit: s2.m(option2(int2))
5523
+ }));
5524
+ var pathContextSchema2 = schema2((s2) => ({
5525
+ sourceRoot: s2.m(string2),
5526
+ resolvedPath: s2.m(string2),
5527
+ relativePath: s2.m(string2)
5528
+ }));
5529
+ var outputSchema3 = schema2((s2) => ({
5530
+ content: s2.m(string2),
5531
+ totalLines: s2.m(int2),
5532
+ hasMore: s2.m(bool2),
5533
+ _context: s2.m(option2(pathContextSchema2))
5534
+ }));
5535
+ async function execute3(ctx2, input) {
5536
+ let offset = getOr(input.offset, 0);
5537
+ let limit = getOr(input.limit, 500);
5538
+ let err = resolve2(ctx2.sourceRoot, input.path);
5539
+ if (err.TAG !== "Ok") {
5540
+ return {
5541
+ TAG: "Error",
5542
+ _0: formatError(err._0)
5543
+ };
5544
+ }
5545
+ let result = err._0;
5546
+ try {
5547
+ let content = await Fs.promises.readFile(result.resolvedPath, "utf8");
5548
+ let lines = content.split("\n");
5549
+ let totalLines = lines.length;
5550
+ let selectedLines = lines.slice(offset, offset + limit | 0);
5551
+ let selectedContent = selectedLines.join("\n");
5552
+ let hasMore = (offset + limit | 0) < totalLines;
5553
+ recordRead(result.resolvedPath);
5554
+ return {
5555
+ TAG: "Ok",
5556
+ _0: {
5557
+ content: selectedContent,
5558
+ totalLines,
5559
+ hasMore,
5560
+ _context: {
5561
+ sourceRoot: result.sourceRoot,
5562
+ resolvedPath: result.resolvedPath,
5563
+ relativePath: result.relativePath
5564
+ }
5565
+ }
5566
+ };
5567
+ } catch (raw_exn) {
5568
+ let exn = internalToException(raw_exn);
5569
+ let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
5570
+ return {
5571
+ TAG: "Error",
5572
+ _0: `Failed to read file ` + input.path + `: ` + msg
5573
+ };
5574
+ }
5575
+ }
5576
+ var description3 = `Reads a file from the filesystem.
5577
+
5578
+ Parameters:
5579
+ - path (required): Path to file - either relative to source root or absolute (must be under source root)
4916
5580
  - offset (optional): Line number to start from (0-indexed, default: 0). Pass null or 0 to start from beginning.
4917
5581
  - limit (optional): Maximum lines to read (default: 500). Pass null or 500 for default.
4918
5582
 
@@ -4932,8 +5596,8 @@ function map3(opt, f) {
4932
5596
  }
4933
5597
 
4934
5598
  // ../frontman-core/src/tools/FrontmanCore__Tool__ListFiles.res.mjs
4935
- var name4 = ToolNames.listFiles;
4936
- var inputSchema3 = schema2((s2) => ({
5599
+ var name5 = ToolNames.listFiles;
5600
+ var inputSchema4 = schema2((s2) => ({
4937
5601
  path: s2.m(option2(string2))
4938
5602
  }));
4939
5603
  var fileEntrySchema = schema2((s2) => ({
@@ -4942,7 +5606,7 @@ var fileEntrySchema = schema2((s2) => ({
4942
5606
  isFile: s2.m(bool2),
4943
5607
  isDirectory: s2.m(bool2)
4944
5608
  }));
4945
- var outputSchema3 = array2(fileEntrySchema);
5609
+ var outputSchema4 = array2(fileEntrySchema);
4946
5610
  async function getIgnoredEntries(cwd, entries) {
4947
5611
  if (entries.length === 0) {
4948
5612
  return {
@@ -4997,7 +5661,7 @@ async function getIgnoredEntries(cwd, entries) {
4997
5661
  };
4998
5662
  }
4999
5663
  }
5000
- async function execute3(ctx2, input) {
5664
+ async function execute4(ctx2, input) {
5001
5665
  let path = getOr(input.path, ".");
5002
5666
  let err = resolve2(ctx2.sourceRoot, path);
5003
5667
  if (err.TAG !== "Ok") {
@@ -5008,20 +5672,20 @@ async function execute3(ctx2, input) {
5008
5672
  }
5009
5673
  try {
5010
5674
  let fullPath = err._0.resolvedPath;
5011
- let entries = await Fs3.promises.readdir(fullPath);
5012
- let filteredEntriesResult = map3(await getIgnoredEntries(fullPath, entries), (ignored) => entries.filter((name11) => !ignored.includes(name11)));
5675
+ let entries = await Fs.promises.readdir(fullPath);
5676
+ let filteredEntriesResult = map3(await getIgnoredEntries(fullPath, entries), (ignored) => entries.filter((name14) => !ignored.includes(name14)));
5013
5677
  if (filteredEntriesResult.TAG !== "Ok") {
5014
5678
  return {
5015
5679
  TAG: "Error",
5016
5680
  _0: filteredEntriesResult._0
5017
5681
  };
5018
5682
  }
5019
- let entriesWithStats = await Promise.all(filteredEntriesResult._0.map(async (name11) => {
5020
- let entryPath = Nodepath.join(fullPath, name11);
5021
- let stats = await Fs3.promises.stat(entryPath);
5683
+ let entriesWithStats = await Promise.all(filteredEntriesResult._0.map(async (name14) => {
5684
+ let entryPath = Nodepath.join(fullPath, name14);
5685
+ let stats = await Fs.promises.stat(entryPath);
5022
5686
  return {
5023
- name: name11,
5024
- path: Nodepath.join(path, name11),
5687
+ name: name14,
5688
+ path: Nodepath.join(path, name14),
5025
5689
  isFile: stats.isFile(),
5026
5690
  isDirectory: stats.isDirectory()
5027
5691
  };
@@ -5039,35 +5703,35 @@ async function execute3(ctx2, input) {
5039
5703
  };
5040
5704
  }
5041
5705
  }
5042
- var description3 = `Lists files and directories in a given path.
5706
+ var description4 = `Lists files and directories in a given path.
5043
5707
 
5044
5708
  Parameters:
5045
5709
  - path (optional): Path to directory - either relative to source root or absolute (must be under source root). Defaults to "." (root directory).
5046
5710
 
5047
5711
  Returns array of entries with name, path, and type information.`;
5048
- var name5 = ToolNames.writeFile;
5049
- var inputSchema4 = schema2((s2) => ({
5712
+ var name6 = ToolNames.writeFile;
5713
+ var inputSchema5 = schema2((s2) => ({
5050
5714
  path: s2.m(string2),
5051
5715
  content: s2.m(option2(string2)),
5052
5716
  image_ref: s2.m(option2(string2)),
5053
5717
  encoding: s2.m(option2(literal2("base64")))
5054
5718
  }));
5055
- var pathContextSchema2 = schema2((s2) => ({
5719
+ var pathContextSchema3 = schema2((s2) => ({
5056
5720
  sourceRoot: s2.m(string2),
5057
5721
  resolvedPath: s2.m(string2),
5058
5722
  relativePath: s2.m(string2)
5059
5723
  }));
5060
- var outputSchema4 = schema2((s2) => ({
5061
- _context: s2.m(option2(pathContextSchema2))
5724
+ var outputSchema5 = schema2((s2) => ({
5725
+ _context: s2.m(option2(pathContextSchema3))
5062
5726
  }));
5063
5727
  function writeContent(resolvedPath, content, encoding) {
5064
5728
  if (encoding === void 0) {
5065
- return Fs3.promises.writeFile(resolvedPath, content, "utf8");
5729
+ return Fs.promises.writeFile(resolvedPath, content, "utf8");
5066
5730
  }
5067
5731
  let buffer = Nodebuffer.Buffer.from(content, "base64");
5068
- return Fs3.promises.writeFile(resolvedPath, buffer);
5732
+ return Fs.promises.writeFile(resolvedPath, buffer);
5069
5733
  }
5070
- async function execute4(ctx2, input) {
5734
+ async function execute5(ctx2, input) {
5071
5735
  let match = input.content;
5072
5736
  let match$1 = input.image_ref;
5073
5737
  if (match === void 0) {
@@ -5098,7 +5762,7 @@ async function execute4(ctx2, input) {
5098
5762
  }
5099
5763
  let result = err._0;
5100
5764
  try {
5101
- await Fs3.promises.mkdir(dirname3(result), {
5765
+ await Fs.promises.mkdir(dirname3(result), {
5102
5766
  recursive: true
5103
5767
  });
5104
5768
  await writeContent(result.resolvedPath, match, input.encoding);
@@ -5121,7 +5785,7 @@ async function execute4(ctx2, input) {
5121
5785
  };
5122
5786
  }
5123
5787
  }
5124
- var description4 = `Writes content to a file.
5788
+ var description5 = `Writes content to a file.
5125
5789
 
5126
5790
  Parameters:
5127
5791
  - path (required): Path to file - either relative to source root or absolute (must be under source root)
@@ -5132,11 +5796,11 @@ Parameters:
5132
5796
  Provide either content OR image_ref, not both.
5133
5797
  Creates parent directories if they don't exist. Overwrites existing files.
5134
5798
  The _context field provides path resolution details for debugging.`;
5135
- var name6 = ToolNames.fileExists;
5136
- var inputSchema5 = schema2((s2) => ({
5799
+ var name7 = ToolNames.fileExists;
5800
+ var inputSchema6 = schema2((s2) => ({
5137
5801
  path: s2.m(string2)
5138
5802
  }));
5139
- async function execute5(ctx2, input) {
5803
+ async function execute6(ctx2, input) {
5140
5804
  let msg = resolve(ctx2.sourceRoot, input.path);
5141
5805
  if (msg.TAG !== "Ok") {
5142
5806
  return {
@@ -5145,7 +5809,7 @@ async function execute5(ctx2, input) {
5145
5809
  };
5146
5810
  }
5147
5811
  try {
5148
- await Fs3.promises.access(toString(msg._0));
5812
+ await Fs.promises.access(toString(msg._0));
5149
5813
  return {
5150
5814
  TAG: "Ok",
5151
5815
  _0: true
@@ -5157,13 +5821,13 @@ async function execute5(ctx2, input) {
5157
5821
  };
5158
5822
  }
5159
5823
  }
5160
- var description5 = `Checks if a file or directory exists.
5824
+ var description6 = `Checks if a file or directory exists.
5161
5825
 
5162
5826
  Parameters:
5163
5827
  - path (required): Path to check - either relative to source root or absolute (must be under source root)
5164
5828
 
5165
5829
  Returns true if the path exists, false otherwise.`;
5166
- var outputSchema5 = bool2;
5830
+ var outputSchema6 = bool2;
5167
5831
 
5168
5832
  // ../bindings/src/Lighthouse.res.mjs
5169
5833
  var run = ((url2, flags2) => import('module').then(({ createRequire }) => {
@@ -5205,8 +5869,8 @@ async function killSafely(chrome) {
5205
5869
  }
5206
5870
 
5207
5871
  // ../frontman-core/src/tools/FrontmanCore__Tool__Lighthouse.res.mjs
5208
- var name7 = ToolNames.lighthouse;
5209
- var inputSchema6 = schema2((s2) => ({
5872
+ var name8 = ToolNames.lighthouse;
5873
+ var inputSchema7 = schema2((s2) => ({
5210
5874
  url: s2.m(string2),
5211
5875
  preset: s2.m(option2(string2))
5212
5876
  }));
@@ -5223,7 +5887,7 @@ var categoryResultSchema = schema2((s2) => ({
5223
5887
  score: s2.m(int2),
5224
5888
  topIssues: s2.m(array2(auditIssueSchema))
5225
5889
  }));
5226
- var outputSchema6 = schema2((s2) => ({
5890
+ var outputSchema7 = schema2((s2) => ({
5227
5891
  url: s2.m(string2),
5228
5892
  fetchTime: s2.m(string2),
5229
5893
  categories: s2.m(array2(categoryResultSchema)),
@@ -5323,7 +5987,7 @@ async function runLighthouse(chrome, url2, preset) {
5323
5987
  };
5324
5988
  }
5325
5989
  }
5326
- async function execute6(_ctx, input) {
5990
+ async function execute7(_ctx, input) {
5327
5991
  let preset = getOr(input.preset, "desktop");
5328
5992
  switch (preset) {
5329
5993
  case "desktop":
@@ -5354,7 +6018,7 @@ async function execute6(_ctx, input) {
5354
6018
  };
5355
6019
  }
5356
6020
  }
5357
- var description6 = `Runs a Lighthouse audit on a URL to analyze performance, accessibility, best practices, and SEO.
6021
+ var description7 = `Runs a Lighthouse audit on a URL to analyze performance, accessibility, best practices, and SEO.
5358
6022
 
5359
6023
  WHEN TO USE THIS TOOL:
5360
6024
  - After making changes that might affect page load performance
@@ -5376,13 +6040,13 @@ LIMITATIONS:
5376
6040
  - Takes 15-30 seconds to complete
5377
6041
  - Results can vary between runs (\xB15 points is normal)
5378
6042
  - URL must be accessible from the machine running the audit`;
5379
- var name8 = ToolNames.searchFiles;
5380
- var inputSchema7 = schema2((s2) => ({
6043
+ var name9 = ToolNames.searchFiles;
6044
+ var inputSchema8 = schema2((s2) => ({
5381
6045
  pattern: s2.m(string2),
5382
6046
  path: s2.m(option2(string2)),
5383
6047
  max_results: s2.m(option2(int2))
5384
6048
  }));
5385
- var outputSchema7 = schema2((s2) => ({
6049
+ var outputSchema8 = schema2((s2) => ({
5386
6050
  files: s2.m(array2(string2)),
5387
6051
  totalResults: s2.m(int2),
5388
6052
  truncated: s2.m(bool2)
@@ -5496,7 +6160,7 @@ async function executeGitLsFiles(pattern2, searchPath, maxResults) {
5496
6160
  _0: `Git ls-files failed: ` + match.stderr
5497
6161
  };
5498
6162
  }
5499
- async function execute7(ctx2, input) {
6163
+ async function execute8(ctx2, input) {
5500
6164
  let searchPath = resolveSearchPath(ctx2.sourceRoot, input.path);
5501
6165
  let maxResults = getOr(input.max_results, 20);
5502
6166
  let rgPath = getRipgrepPath2();
@@ -5510,7 +6174,7 @@ async function execute7(ctx2, input) {
5510
6174
  return await executeGitLsFiles(input.pattern, searchPath, maxResults);
5511
6175
  }
5512
6176
  }
5513
- var description7 = `Fast file name search tool that finds files matching a pattern.
6177
+ var description8 = `Fast file name search tool that finds files matching a pattern.
5514
6178
 
5515
6179
  WHEN TO USE THIS TOOL:
5516
6180
  - Use when you need to find files by name pattern
@@ -5538,15 +6202,15 @@ LIMITATIONS:
5538
6202
  - Hidden files (starting with '.') are included
5539
6203
  - Respects .gitignore when using git ls-files fallback
5540
6204
  - Only finds files, not directories`;
5541
- var name9 = ToolNames.loadAgentInstructions;
5542
- var inputSchema8 = schema2((s2) => ({
6205
+ var name10 = ToolNames.loadAgentInstructions;
6206
+ var inputSchema9 = schema2((s2) => ({
5543
6207
  startPath: s2.m(option2(string2))
5544
6208
  }));
5545
6209
  var instructionFileSchema = schema2((s2) => ({
5546
6210
  content: s2.m(string2),
5547
6211
  fullPath: s2.m(string2)
5548
6212
  }));
5549
- var outputSchema8 = array2(instructionFileSchema);
6213
+ var outputSchema9 = array2(instructionFileSchema);
5550
6214
  var agentsVariants = [
5551
6215
  "Agents.md",
5552
6216
  ".claude/Agents.md",
@@ -5559,7 +6223,7 @@ var claudeVariants = [
5559
6223
  ];
5560
6224
  async function findFileCaseInsensitive(dir, targetFileName) {
5561
6225
  try {
5562
- let files = await Fs3.promises.readdir(dir);
6226
+ let files = await Fs.promises.readdir(dir);
5563
6227
  let targetLower = targetFileName.toLowerCase();
5564
6228
  let found = files.find((file) => file.toLowerCase() === targetLower);
5565
6229
  if (found !== void 0) {
@@ -5579,7 +6243,7 @@ async function loadIfExists(path) {
5579
6243
  return;
5580
6244
  }
5581
6245
  try {
5582
- let content = await Fs3.promises.readFile(actualPath, "utf8");
6246
+ let content = await Fs.promises.readFile(actualPath, "utf8");
5583
6247
  return {
5584
6248
  content,
5585
6249
  fullPath: actualPath
@@ -5616,7 +6280,7 @@ async function walkUpDirectories(current, acc) {
5616
6280
  let newAcc = acc.concat(filesAtLevel);
5617
6281
  return await walkUpDirectories(Nodepath.dirname(current), newAcc);
5618
6282
  }
5619
- async function execute8(ctx2, input) {
6283
+ async function execute9(ctx2, input) {
5620
6284
  let inputPath = getOr(input.startPath, ".");
5621
6285
  let msg = resolve(ctx2.sourceRoot, inputPath);
5622
6286
  if (msg.TAG !== "Ok") {
@@ -5641,7 +6305,7 @@ async function execute8(ctx2, input) {
5641
6305
  };
5642
6306
  }
5643
6307
  }
5644
- var description8 = `Discovers and loads agent instruction files (Agents.md or CLAUDE.md) following Claude Code's discovery algorithm.
6308
+ var description9 = `Discovers and loads agent instruction files (Agents.md or CLAUDE.md) following Claude Code's discovery algorithm.
5645
6309
 
5646
6310
  Parameters:
5647
6311
  - startPath (optional): Starting directory for discovery - must be under source root. Defaults to "." (source root).
@@ -5658,22 +6322,6 @@ Discovery:
5658
6322
  function coreTools() {
5659
6323
  return {
5660
6324
  tools: [
5661
- {
5662
- name: name3,
5663
- description: description2,
5664
- inputSchema: inputSchema2,
5665
- outputSchema: outputSchema2,
5666
- execute: execute2,
5667
- visibleToAgent: true
5668
- },
5669
- {
5670
- name: name5,
5671
- description: description4,
5672
- inputSchema: inputSchema4,
5673
- outputSchema: outputSchema4,
5674
- execute: execute4,
5675
- visibleToAgent: true
5676
- },
5677
6325
  {
5678
6326
  name: name4,
5679
6327
  description: description3,
@@ -5691,11 +6339,27 @@ function coreTools() {
5691
6339
  visibleToAgent: true
5692
6340
  },
5693
6341
  {
5694
- name: name9,
5695
- description: description8,
5696
- inputSchema: inputSchema8,
5697
- outputSchema: outputSchema8,
5698
- execute: execute8,
6342
+ name: name5,
6343
+ description: description4,
6344
+ inputSchema: inputSchema4,
6345
+ outputSchema: outputSchema4,
6346
+ execute: execute4,
6347
+ visibleToAgent: true
6348
+ },
6349
+ {
6350
+ name: name7,
6351
+ description: description6,
6352
+ inputSchema: inputSchema6,
6353
+ outputSchema: outputSchema6,
6354
+ execute: execute6,
6355
+ visibleToAgent: true
6356
+ },
6357
+ {
6358
+ name: name10,
6359
+ description: description9,
6360
+ inputSchema: inputSchema9,
6361
+ outputSchema: outputSchema9,
6362
+ execute: execute9,
5699
6363
  visibleToAgent: false
5700
6364
  },
5701
6365
  {
@@ -5706,6 +6370,14 @@ function coreTools() {
5706
6370
  execute,
5707
6371
  visibleToAgent: true
5708
6372
  },
6373
+ {
6374
+ name: name9,
6375
+ description: description8,
6376
+ inputSchema: inputSchema8,
6377
+ outputSchema: outputSchema8,
6378
+ execute: execute8,
6379
+ visibleToAgent: true
6380
+ },
5709
6381
  {
5710
6382
  name: name8,
5711
6383
  description: description7,
@@ -5715,11 +6387,11 @@ function coreTools() {
5715
6387
  visibleToAgent: true
5716
6388
  },
5717
6389
  {
5718
- name: name7,
5719
- description: description6,
5720
- inputSchema: inputSchema6,
5721
- outputSchema: outputSchema6,
5722
- execute: execute6,
6390
+ name: name3,
6391
+ description: description2,
6392
+ inputSchema: inputSchema2,
6393
+ outputSchema: outputSchema2,
6394
+ execute: execute2,
5723
6395
  visibleToAgent: true
5724
6396
  }
5725
6397
  ]
@@ -5730,8 +6402,19 @@ function addTools(registry, newTools) {
5730
6402
  tools: registry.tools.concat(newTools)
5731
6403
  };
5732
6404
  }
5733
- function getToolByName(registry, name11) {
5734
- return registry.tools.find((m) => m.name === name11);
6405
+ function replaceByName(registry, replacement) {
6406
+ return {
6407
+ tools: registry.tools.map((m) => {
6408
+ if (m.name === replacement.name) {
6409
+ return replacement;
6410
+ } else {
6411
+ return m;
6412
+ }
6413
+ })
6414
+ };
6415
+ }
6416
+ function getToolByName(registry, name14) {
6417
+ return registry.tools.find((m) => m.name === name14);
5735
6418
  }
5736
6419
  function serializeTool(m) {
5737
6420
  return {
@@ -5764,12 +6447,12 @@ var toolCallRequestSchema = schema2((s2) => ({
5764
6447
  var protocolVersion = "1.0";
5765
6448
 
5766
6449
  // ../frontman-core/src/FrontmanCore__Server.res.mjs
5767
- async function executeTool(registry, ctx2, name11, $$arguments) {
5768
- let toolModule = getToolByName(registry, name11);
6450
+ async function executeTool(registry, ctx2, name14, $$arguments) {
6451
+ let toolModule = getToolByName(registry, name14);
5769
6452
  if (toolModule === void 0) {
5770
6453
  return {
5771
6454
  TAG: "ToolNotFound",
5772
- _0: name11
6455
+ _0: name14
5773
6456
  };
5774
6457
  }
5775
6458
  let toolCtx_projectRoot = ctx2.projectRoot;
@@ -5861,7 +6544,23 @@ function getToolsResponse(registry, serverName, serverVersion) {
5861
6544
  };
5862
6545
  }
5863
6546
 
5864
- // src/FrontmanAstro__Server.res.mjs
6547
+ // ../frontman-core/src/FrontmanCore__RequestHandlers.res.mjs
6548
+ var resolveSourceLocationRequestSchema = schema2((s2) => ({
6549
+ componentName: s2.m(string2),
6550
+ file: s2.m(string2),
6551
+ line: s2.m(int2),
6552
+ column: s2.m(int2)
6553
+ }));
6554
+ var resolveSourceLocationResponseSchema = schema2((s2) => ({
6555
+ componentName: s2.m(string2),
6556
+ file: s2.m(string2),
6557
+ line: s2.m(int2),
6558
+ column: s2.m(int2)
6559
+ }));
6560
+ var errorResponseSchema = schema2((s2) => ({
6561
+ error: s2.m(string2),
6562
+ details: s2.m(option2(string2))
6563
+ }));
5865
6564
  function handleGetTools(registry, config) {
5866
6565
  let response = getToolsResponse(registry, config.serverName, config.serverVersion);
5867
6566
  let json3 = reverseConvertToJsonOrThrow2(response, toolsResponseSchema);
@@ -5903,13 +6602,27 @@ async function handleToolCall(registry, config, req) {
5903
6602
  let encoder = new TextEncoder();
5904
6603
  let stream = new Web.ReadableStream({
5905
6604
  start: (controller) => {
5906
- resultPromise.then((result) => {
6605
+ $$catch(resultPromise.then((result) => {
5907
6606
  let mcpResult = resultToMCP(result);
5908
6607
  let match = mcpResult.isError;
5909
6608
  let eventData = match !== void 0 && match ? errorEvent(mcpResult) : resultEvent(mcpResult);
5910
6609
  controller.enqueue(encoder.encode(eventData));
5911
6610
  controller.close();
5912
6611
  return Promise.resolve();
6612
+ }), (error) => {
6613
+ let msg = getOr(flatMap(fromException(error), message2), "Unknown error");
6614
+ let errorResult_content2 = [{
6615
+ type: "text",
6616
+ text: `Tool execution failed: ` + msg
6617
+ }];
6618
+ let errorResult_isError2 = true;
6619
+ let errorResult2 = {
6620
+ content: errorResult_content2,
6621
+ isError: errorResult_isError2
6622
+ };
6623
+ controller.enqueue(encoder.encode(errorEvent(errorResult2)));
6624
+ controller.close();
6625
+ return Promise.resolve();
5913
6626
  });
5914
6627
  }
5915
6628
  });
@@ -5931,113 +6644,582 @@ async function handleToolCall(registry, config, req) {
5931
6644
  status: 400
5932
6645
  });
5933
6646
  }
5934
- function corsHeaders() {
5935
- return Object.fromEntries([
5936
- [
5937
- "Access-Control-Allow-Origin",
5938
- "*"
5939
- ],
5940
- [
5941
- "Access-Control-Allow-Methods",
5942
- "GET, POST, OPTIONS"
5943
- ],
5944
- [
5945
- "Access-Control-Allow-Headers",
5946
- "Content-Type"
5947
- ]
5948
- ]);
5949
- }
5950
- function handleCORS() {
5951
- return new Response(null, {
5952
- status: 204,
5953
- headers: some(corsHeaders())
5954
- });
5955
- }
5956
- async function handleResolveSourceLocation(config, req) {
6647
+ async function handleResolveSourceLocation(sourceRoot, req) {
5957
6648
  let body = await req.json();
5958
- let requestObj = Decode.object(body);
5959
- if (requestObj === void 0) {
5960
- return Response.json(Object.fromEntries([[
5961
- "error",
5962
- "Invalid request body"
5963
- ]]), {
5964
- status: 400
5965
- });
6649
+ let request;
6650
+ try {
6651
+ request = {
6652
+ TAG: "Ok",
6653
+ _0: parseOrThrow2(body, resolveSourceLocationRequestSchema)
6654
+ };
6655
+ } catch (raw_e) {
6656
+ let e = internalToException(raw_e);
6657
+ if (e.RE_EXN_ID === $$Error2) {
6658
+ request = {
6659
+ TAG: "Error",
6660
+ _0: e._1.message
6661
+ };
6662
+ } else {
6663
+ throw e;
6664
+ }
5966
6665
  }
5967
- let componentName = flatMap(requestObj["componentName"], Decode.string);
5968
- let file = flatMap(requestObj["file"], Decode.string);
5969
- let line = flatMap(requestObj["line"], Decode.float);
5970
- let column = flatMap(requestObj["column"], Decode.float);
5971
- if (componentName !== void 0 && file !== void 0 && line !== void 0 && column !== void 0) {
6666
+ if (request.TAG === "Ok") {
6667
+ let request$1 = request._0;
5972
6668
  try {
5973
- let sourceLocation_line = line | 0;
5974
- let sourceLocation_column = column | 0;
6669
+ let sourceLocation_componentName = request$1.componentName;
6670
+ let sourceLocation_file = request$1.file;
6671
+ let sourceLocation_line = request$1.line;
6672
+ let sourceLocation_column = request$1.column;
5975
6673
  let sourceLocation = {
5976
- componentName,
5977
- file,
6674
+ componentName: sourceLocation_componentName,
6675
+ file: sourceLocation_file,
5978
6676
  line: sourceLocation_line,
5979
6677
  column: sourceLocation_column,
5980
6678
  componentProps: void 0,
5981
6679
  parent: void 0
5982
6680
  };
5983
6681
  let resolved = await Te(sourceLocation);
5984
- let relativeFile = toRelativePath(config.sourceRoot, resolved.file);
5985
- let responseJson = Object.fromEntries([
5986
- [
5987
- "componentName",
5988
- resolved.componentName
5989
- ],
5990
- [
5991
- "file",
5992
- relativeFile
5993
- ],
5994
- [
5995
- "line",
5996
- resolved.line
5997
- ],
5998
- [
5999
- "column",
6000
- resolved.column
6001
- ]
6002
- ]);
6682
+ let relativeFile = toRelativePath(sourceRoot, resolved.file);
6683
+ let responseJson_componentName = resolved.componentName;
6684
+ let responseJson_line = resolved.line;
6685
+ let responseJson_column = resolved.column;
6686
+ let responseJson = {
6687
+ componentName: responseJson_componentName,
6688
+ file: relativeFile,
6689
+ line: responseJson_line,
6690
+ column: responseJson_column
6691
+ };
6692
+ let json3 = reverseConvertToJsonOrThrow2(responseJson, resolveSourceLocationResponseSchema);
6003
6693
  let headers2 = Object.fromEntries([[
6004
6694
  "Content-Type",
6005
6695
  "application/json"
6006
6696
  ]]);
6007
- return Response.json(responseJson, {
6697
+ return Response.json(json3, {
6008
6698
  headers: some(headers2)
6009
6699
  });
6010
6700
  } catch (raw_exn) {
6011
6701
  let exn = internalToException(raw_exn);
6012
6702
  let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
6013
- return Response.json(Object.fromEntries([
6703
+ let json$1 = reverseConvertToJsonOrThrow2({
6704
+ error: "Failed to resolve source location",
6705
+ details: msg
6706
+ }, errorResponseSchema);
6707
+ return Response.json(json$1, {
6708
+ status: 500
6709
+ });
6710
+ }
6711
+ } else {
6712
+ let json$2 = reverseConvertToJsonOrThrow2({
6713
+ error: `Invalid request: ` + request._0,
6714
+ details: void 0
6715
+ }, errorResponseSchema);
6716
+ return Response.json(json$2, {
6717
+ status: 400
6718
+ });
6719
+ }
6720
+ }
6721
+
6722
+ // src/FrontmanAstro__Server.res.mjs
6723
+ function toHandlerConfig(config) {
6724
+ return {
6725
+ projectRoot: config.projectRoot,
6726
+ sourceRoot: config.sourceRoot,
6727
+ serverName: config.serverName,
6728
+ serverVersion: config.serverVersion
6729
+ };
6730
+ }
6731
+ function handleGetTools2(registry, config) {
6732
+ return handleGetTools(registry, toHandlerConfig(config));
6733
+ }
6734
+ async function handleToolCall2(registry, config, req) {
6735
+ return await handleToolCall(registry, toHandlerConfig(config), req);
6736
+ }
6737
+ async function handleResolveSourceLocation2(config, req) {
6738
+ return await handleResolveSourceLocation(config.sourceRoot, req);
6739
+ }
6740
+
6741
+ // ../frontman-core/src/FrontmanCore__UIShell.res.mjs
6742
+ function generateHTML(config) {
6743
+ let clientCssTag = mapOr(config.clientCssUrl, "", (url2) => `<link rel="stylesheet" href="` + url2 + `">`);
6744
+ let entrypointTemplate = mapOr(config.entrypointUrl, "", (url2) => `<script type="template" id="frontman-entrypoint-url">` + url2 + `</script>`);
6745
+ let themeClass = config.isLightTheme ? "" : "dark";
6746
+ let openrouterKey = flatMap(process.env["OPENROUTER_API_KEY"], (key) => {
6747
+ if (key !== "") {
6748
+ return key;
6749
+ }
6750
+ });
6751
+ let configObj = Object.fromEntries([[
6752
+ "framework",
6753
+ config.frameworkLabel
6754
+ ]]);
6755
+ forEach(openrouterKey, (key) => {
6756
+ configObj["openrouterKeyValue"] = key;
6757
+ });
6758
+ let payload = JSON.stringify(configObj);
6759
+ let runtimeConfigScript = `<script>window.__frontmanRuntime=` + payload + `</script>`;
6760
+ return `<!DOCTYPE html>
6761
+ <html lang="en" class="` + themeClass + `">
6762
+ <head>
6763
+ <meta charset="UTF-8">
6764
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6765
+ <title>Frontman</title>
6766
+ ` + entrypointTemplate + `
6767
+ ` + clientCssTag + `
6768
+ <style>
6769
+ html, body, #root {
6770
+ margin: 0;
6771
+ padding: 0;
6772
+ height: 100%;
6773
+ width: 100%;
6774
+ }
6775
+ </style>
6776
+ </head>
6777
+ <body>
6778
+ <div id="root"></div>
6779
+ ` + runtimeConfigScript + `
6780
+ <script>if(typeof process==="undefined"){window.process={env:{NODE_ENV:"production"}}}</script>
6781
+ <script type="module" src="` + config.clientUrl + `"></script>
6782
+ </body>
6783
+ </html>`;
6784
+ }
6785
+ function serve(config) {
6786
+ let html = generateHTML(config);
6787
+ let headers2 = Object.fromEntries([[
6788
+ "Content-Type",
6789
+ "text/html"
6790
+ ]]);
6791
+ return new Response(html, {
6792
+ headers: some(headers2)
6793
+ });
6794
+ }
6795
+
6796
+ // ../frontman-core/src/FrontmanCore__CircularBuffer.res.mjs
6797
+ function make3(capacity) {
6798
+ return {
6799
+ data: make2(capacity, void 0),
6800
+ writeIndex: 0,
6801
+ count: 0,
6802
+ maxSize: capacity
6803
+ };
6804
+ }
6805
+ function push(buffer, entry) {
6806
+ buffer.data[buffer.writeIndex] = some(entry);
6807
+ return {
6808
+ data: buffer.data,
6809
+ writeIndex: mod_(buffer.writeIndex + 1 | 0, buffer.maxSize),
6810
+ count: min(buffer.count + 1 | 0, buffer.maxSize),
6811
+ maxSize: buffer.maxSize
6812
+ };
6813
+ }
6814
+ function toArray3(buffer) {
6815
+ let c2 = buffer.count;
6816
+ if (c2 === 0) {
6817
+ return [];
6818
+ }
6819
+ if (c2 < buffer.maxSize) {
6820
+ return filterMap(buffer.data.slice(0, buffer.count), (x) => x);
6821
+ }
6822
+ let tail = filterMap(buffer.data.slice(buffer.writeIndex, buffer.maxSize), (x) => x);
6823
+ let head = filterMap(buffer.data.slice(0, buffer.writeIndex), (x) => x);
6824
+ return tail.concat(head);
6825
+ }
6826
+ function length2(buffer) {
6827
+ return buffer.count;
6828
+ }
6829
+
6830
+ // ../frontman-core/src/FrontmanCore__LogCapture.res.mjs
6831
+ enableJson2();
6832
+ function isBrowser() {
6833
+ return typeof window !== "undefined";
6834
+ }
6835
+ function getPatchedFlag() {
6836
+ return globalThis.__FRONTMAN_CORE_CONSOLE_PATCHED__;
6837
+ }
6838
+ function setPatchedFlag(_value) {
6839
+ globalThis.__FRONTMAN_CORE_CONSOLE_PATCHED__ = _value;
6840
+ }
6841
+ var logLevelSchema = union2([
6842
+ literal2("console"),
6843
+ literal2("build"),
6844
+ literal2("error")
6845
+ ]);
6846
+ var consoleMethodSchema = union2([
6847
+ literal2("log"),
6848
+ literal2("info"),
6849
+ literal2("warn"),
6850
+ literal2("error"),
6851
+ literal2("debug")
6852
+ ]);
6853
+ var logEntrySchema = schema2((s2) => ({
6854
+ timestamp: s2.m(string2),
6855
+ level: s2.m(logLevelSchema),
6856
+ message: s2.m(string2),
6857
+ attributes: s2.m(option2(json2)),
6858
+ resource: s2.m(option2(json2)),
6859
+ consoleMethod: s2.m(option2(consoleMethodSchema))
6860
+ }));
6861
+ var defaultConfig_stdoutPatterns = [
6862
+ "webpack",
6863
+ "turbopack",
6864
+ "Compiled",
6865
+ "Failed",
6866
+ "vite",
6867
+ "hmr",
6868
+ "error",
6869
+ "Error",
6870
+ "astro",
6871
+ "build"
6872
+ ];
6873
+ var defaultConfig = {
6874
+ bufferCapacity: 1024,
6875
+ stdoutPatterns: defaultConfig_stdoutPatterns
6876
+ };
6877
+ function getGlobalInstanceOpt() {
6878
+ return globalThis.__FRONTMAN_CORE_INSTANCE__;
6879
+ }
6880
+ function setGlobalInstance(_state) {
6881
+ globalThis.__FRONTMAN_CORE_INSTANCE__ = _state;
6882
+ }
6883
+ function getOrCreateInstance(config) {
6884
+ let state = getGlobalInstanceOpt();
6885
+ if (state !== void 0) {
6886
+ return state;
6887
+ }
6888
+ let state_buffer = {
6889
+ contents: make3(config.bufferCapacity)
6890
+ };
6891
+ let state$1 = {
6892
+ buffer: state_buffer,
6893
+ config
6894
+ };
6895
+ setGlobalInstance(state$1);
6896
+ return state$1;
6897
+ }
6898
+ function getInstance() {
6899
+ let state = getGlobalInstanceOpt();
6900
+ if (state !== void 0) {
6901
+ return state;
6902
+ } else {
6903
+ return getOrCreateInstance(defaultConfig);
6904
+ }
6905
+ }
6906
+ function argsToString(args) {
6907
+ return args.map((arg) => {
6908
+ let match = typeof arg;
6909
+ if (match === "string") {
6910
+ return arg;
6911
+ } else if (match === "object") {
6912
+ if (arg instanceof Error) {
6913
+ return getOr(arg.stack, arg.message);
6914
+ } else {
6915
+ return getOr(JSON.stringify(arg), "null");
6916
+ }
6917
+ } else {
6918
+ return String(arg);
6919
+ }
6920
+ }).join(" ");
6921
+ }
6922
+ function stripAnsi(str) {
6923
+ return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
6924
+ }
6925
+ function addLog(state, level, message3, attributes, consoleMethod) {
6926
+ let cleanMessage = stripAnsi(message3).trim();
6927
+ if (cleanMessage === "") {
6928
+ return;
6929
+ }
6930
+ let entry_timestamp = new Date(Date.now()).toISOString();
6931
+ let entry = {
6932
+ timestamp: entry_timestamp,
6933
+ level,
6934
+ message: cleanMessage,
6935
+ attributes,
6936
+ resource: void 0,
6937
+ consoleMethod
6938
+ };
6939
+ state.buffer.contents = push(state.buffer.contents, entry);
6940
+ }
6941
+ function handleConsoleLog(state, args) {
6942
+ try {
6943
+ return addLog(state, "console", argsToString(args), void 0, "log");
6944
+ } catch (exn) {
6945
+ return;
6946
+ }
6947
+ }
6948
+ function handleConsoleWarn(state, args) {
6949
+ try {
6950
+ return addLog(state, "console", argsToString(args), void 0, "warn");
6951
+ } catch (exn) {
6952
+ return;
6953
+ }
6954
+ }
6955
+ function handleConsoleError(state, args) {
6956
+ try {
6957
+ return addLog(state, "console", argsToString(args), void 0, "error");
6958
+ } catch (exn) {
6959
+ return;
6960
+ }
6961
+ }
6962
+ function handleConsoleInfo(state, args) {
6963
+ try {
6964
+ return addLog(state, "console", argsToString(args), void 0, "info");
6965
+ } catch (exn) {
6966
+ return;
6967
+ }
6968
+ }
6969
+ function handleConsoleDebug(state, args) {
6970
+ try {
6971
+ return addLog(state, "console", argsToString(args), void 0, "debug");
6972
+ } catch (exn) {
6973
+ return;
6974
+ }
6975
+ }
6976
+ var interceptConsole = (function(state) {
6977
+ const originalLog = console.log.bind(console);
6978
+ const originalWarn = console.warn.bind(console);
6979
+ const originalError = console.error.bind(console);
6980
+ const originalInfo = console.info.bind(console);
6981
+ const originalDebug = console.debug.bind(console);
6982
+ console.log = (...args) => {
6983
+ handleConsoleLog(state, args);
6984
+ originalLog(...args);
6985
+ };
6986
+ console.warn = (...args) => {
6987
+ handleConsoleWarn(state, args);
6988
+ originalWarn(...args);
6989
+ };
6990
+ console.error = (...args) => {
6991
+ handleConsoleError(state, args);
6992
+ originalError(...args);
6993
+ };
6994
+ console.info = (...args) => {
6995
+ handleConsoleInfo(state, args);
6996
+ originalInfo(...args);
6997
+ };
6998
+ console.debug = (...args) => {
6999
+ handleConsoleDebug(state, args);
7000
+ originalDebug(...args);
7001
+ };
7002
+ });
7003
+ function handleStdoutWrite(state, message3) {
7004
+ try {
7005
+ let matchesPattern2 = state.config.stdoutPatterns.some((pattern2) => message3.includes(pattern2));
7006
+ if (matchesPattern2) {
7007
+ return addLog(state, "build", message3, void 0, void 0);
7008
+ } else {
7009
+ return;
7010
+ }
7011
+ } catch (exn) {
7012
+ return;
7013
+ }
7014
+ }
7015
+ function interceptStdout(_state) {
7016
+ (function(_state2) {
7017
+ const originalWrite = process.stdout.write.bind(process.stdout);
7018
+ process.stdout.write = (chunk, ...args) => {
7019
+ const message3 = typeof chunk === "string" ? chunk : chunk.toString();
7020
+ handleStdoutWrite(_state2, message3);
7021
+ return originalWrite(chunk, ...args);
7022
+ };
7023
+ })(_state);
7024
+ }
7025
+ function interceptUncaughtErrors(state) {
7026
+ process.on("uncaughtException", (error) => {
7027
+ try {
7028
+ let errorMessage = getOr(error.message, "Unknown error");
7029
+ let attributes = Object.fromEntries([
6014
7030
  [
6015
- "error",
6016
- "Failed to resolve source location"
7031
+ "stack",
7032
+ getOr(map(error.stack, (prim) => prim), null)
6017
7033
  ],
6018
7034
  [
6019
- "details",
6020
- msg
7035
+ "name",
7036
+ error.name
6021
7037
  ]
6022
- ]), {
6023
- status: 500
6024
- });
7038
+ ]);
7039
+ return addLog(state, "error", errorMessage, attributes, void 0);
7040
+ } catch (exn) {
7041
+ return;
7042
+ }
7043
+ });
7044
+ process.on("unhandledRejection", (reason2) => {
7045
+ try {
7046
+ let reasonMessage = getOr(reason2.message, String.toString(reason2));
7047
+ let attributes = Object.fromEntries([[
7048
+ "stack",
7049
+ getOr(map(reason2.stack, (prim) => prim), null)
7050
+ ]]);
7051
+ return addLog(state, "error", reasonMessage, attributes, void 0);
7052
+ } catch (exn) {
7053
+ return;
6025
7054
  }
7055
+ });
7056
+ }
7057
+ function initialize(configOpt, param) {
7058
+ let config = defaultConfig;
7059
+ if (isBrowser()) {
7060
+ return;
6026
7061
  }
6027
- return Response.json(Object.fromEntries([[
6028
- "error",
6029
- "Missing required fields: componentName, file, line, column"
6030
- ]]), {
6031
- status: 400
7062
+ let match = getPatchedFlag();
7063
+ if (match !== void 0 && match) {
7064
+ return;
7065
+ }
7066
+ setPatchedFlag(true);
7067
+ let state = getOrCreateInstance(config);
7068
+ interceptConsole(state);
7069
+ interceptStdout(state);
7070
+ interceptUncaughtErrors(state);
7071
+ }
7072
+ var regexCache = {
7073
+ pattern: void 0,
7074
+ regex: void 0
7075
+ };
7076
+ function getCompiledRegex(pattern2) {
7077
+ let cached = regexCache.pattern;
7078
+ if (cached !== void 0 && cached === pattern2) {
7079
+ let r = regexCache.regex;
7080
+ if (r !== void 0) {
7081
+ return r;
7082
+ }
7083
+ let regex = new RegExp(pattern2, "i");
7084
+ regexCache.regex = regex;
7085
+ return regex;
7086
+ }
7087
+ let regex$1 = new RegExp(pattern2, "i");
7088
+ regexCache.pattern = pattern2;
7089
+ regexCache.regex = regex$1;
7090
+ return regex$1;
7091
+ }
7092
+ function getLogs(pattern2, level, since, tail) {
7093
+ try {
7094
+ let state = getInstance();
7095
+ let allLogs = toArray3(state.buffer.contents);
7096
+ let logs = since !== void 0 ? allLogs.filter((entry) => new Date(entry.timestamp).getTime() >= since) : allLogs;
7097
+ let logs$1 = level !== void 0 ? logs.filter((entry) => entry.level === level) : logs;
7098
+ let logs$2;
7099
+ if (pattern2 !== void 0) {
7100
+ let regex = getCompiledRegex(pattern2);
7101
+ logs$2 = logs$1.filter((entry) => regex.test(entry.message));
7102
+ } else {
7103
+ logs$2 = logs$1;
7104
+ }
7105
+ if (tail === void 0) {
7106
+ return logs$2;
7107
+ }
7108
+ let len = logs$2.length;
7109
+ return logs$2.slice(max(0, len - tail | 0), len);
7110
+ } catch (exn) {
7111
+ return [];
7112
+ }
7113
+ }
7114
+
7115
+ // src/tools/FrontmanAstro__Tool__GetLogs.res.mjs
7116
+ var inputSchema10 = schema2((s2) => ({
7117
+ pattern: s2.m(option2(string2)),
7118
+ level: s2.m(option2(logLevelSchema)),
7119
+ since: s2.m(option2(string2)),
7120
+ tail: s2.m(option2(int2))
7121
+ }));
7122
+ var outputSchema10 = schema2((s2) => ({
7123
+ logs: s2.m(array2(logEntrySchema)),
7124
+ totalMatched: s2.m(int2),
7125
+ bufferSize: s2.m(int2),
7126
+ hasMore: s2.m(bool2)
7127
+ }));
7128
+ async function execute10(_ctx, input) {
7129
+ try {
7130
+ let sinceTimestamp = map(input.since, (isoString) => new Date(isoString).getTime());
7131
+ let allMatchedLogs = getLogs(input.pattern, input.level, sinceTimestamp, void 0);
7132
+ let totalMatched = allMatchedLogs.length;
7133
+ let n = input.tail;
7134
+ let logs = n !== void 0 ? allMatchedLogs.slice(max(0, totalMatched - n | 0), totalMatched) : allMatchedLogs;
7135
+ let n$1 = input.tail;
7136
+ let hasMore = n$1 !== void 0 ? totalMatched > n$1 : false;
7137
+ let bufferSize = length2(getInstance().buffer.contents);
7138
+ return {
7139
+ TAG: "Ok",
7140
+ _0: {
7141
+ logs,
7142
+ totalMatched,
7143
+ bufferSize,
7144
+ hasMore
7145
+ }
7146
+ };
7147
+ } catch (raw_exn) {
7148
+ let exn = internalToException(raw_exn);
7149
+ let msg = getOr(flatMap(fromException(exn), message2), "Unknown error");
7150
+ return {
7151
+ TAG: "Error",
7152
+ _0: `Failed to retrieve logs: ` + msg
7153
+ };
7154
+ }
7155
+ }
7156
+ var name11 = "get_logs";
7157
+ var description10 = `Retrieves dev server logs from rotating 1024-entry buffer.
7158
+
7159
+ Captures:
7160
+ - Console output (console.log, warn, error, info, debug)
7161
+ - Astro build logs (compilation, errors, warnings)
7162
+ - Uncaught exceptions with stack traces
7163
+
7164
+ Parameters:
7165
+ - pattern (optional): JavaScript regex pattern to filter messages (case-insensitive)
7166
+ Examples: "error", "astro.*build", "TypeError"
7167
+ - level (optional): Filter by log type: "console", "build", or "error"
7168
+ - since (optional): ISO 8601 timestamp - only return logs after this time
7169
+ Example: "2025-12-28T10:30:00.000Z"
7170
+ - tail (optional): Limit to most recent N entries
7171
+ Example: 100 (returns last 100 matching logs)
7172
+
7173
+ Returns logs in chronological order (oldest first within buffer).`;
7174
+
7175
+ // src/tools/FrontmanAstro__Tool__EditFile.res.mjs
7176
+ function sleep(ms) {
7177
+ return new Promise((resolve3, param) => {
7178
+ setTimeout(() => resolve3(), ms);
7179
+ });
7180
+ }
7181
+ async function execute11(ctx2, input) {
7182
+ let beforeTimestamp = Date.now();
7183
+ let result = await execute2(ctx2, input);
7184
+ if (result.TAG !== "Ok") {
7185
+ return result;
7186
+ }
7187
+ let output = result._0;
7188
+ await sleep(800);
7189
+ let recentLogs = getLogs(void 0, "error", beforeTimestamp, void 0);
7190
+ let errorLogs = getLogs("error|Error|failed|Failed", void 0, beforeTimestamp, void 0);
7191
+ let seen = /* @__PURE__ */ new Set();
7192
+ recentLogs.forEach((entry) => {
7193
+ seen.add(entry.timestamp + "|" + entry.message);
6032
7194
  });
7195
+ let allErrors = recentLogs.concat(errorLogs.filter((entry) => !seen.has(entry.timestamp + "|" + entry.message)));
7196
+ if (allErrors.length === 0) {
7197
+ return {
7198
+ TAG: "Ok",
7199
+ _0: output
7200
+ };
7201
+ }
7202
+ let errorMessages = allErrors.slice(0, 5).map((entry) => entry.message).join("\n");
7203
+ let newrecord = { ...output };
7204
+ return {
7205
+ TAG: "Ok",
7206
+ _0: (newrecord.message = output.message + (`
7207
+
7208
+ Warning: Dev server errors detected after edit:
7209
+ ` + errorMessages), newrecord)
7210
+ };
6033
7211
  }
7212
+ var name12 = "edit_file";
7213
+ var description11 = description2;
7214
+ var inputSchema11 = inputSchema2;
7215
+ var outputSchema11 = outputSchema2;
6034
7216
  var dynamicTypeSchema = union2([
6035
7217
  literal2("static"),
6036
7218
  literal2("single"),
6037
7219
  literal2("rest"),
6038
7220
  literal2("optional")
6039
7221
  ]);
6040
- var inputSchema9 = schema2((s2) => ({
7222
+ var inputSchema12 = schema2((s2) => ({
6041
7223
  placeholder: s2.m(option2(bool2))
6042
7224
  }));
6043
7225
  var pageSchema = schema2((s2) => ({
@@ -6046,7 +7228,7 @@ var pageSchema = schema2((s2) => ({
6046
7228
  isDynamic: s2.m(bool2),
6047
7229
  dynamicType: s2.m(dynamicTypeSchema)
6048
7230
  }));
6049
- var outputSchema9 = array2(pageSchema);
7231
+ var outputSchema12 = array2(pageSchema);
6050
7232
  function analyzeDynamicSegment(segment) {
6051
7233
  if (segment.startsWith("[[") && segment.endsWith("]]")) {
6052
7234
  return "optional";
@@ -6101,10 +7283,10 @@ function getMostSignificantDynamicType(segments) {
6101
7283
  async function findPages(baseDir, currentPath, projectRoot, sourceRoot) {
6102
7284
  let fullPath = Nodepath.join(projectRoot, baseDir, currentPath);
6103
7285
  try {
6104
- let entries = await Fs3.promises.readdir(fullPath);
7286
+ let entries = await Fs.promises.readdir(fullPath);
6105
7287
  return (await Promise.all(entries.map(async (entry) => {
6106
7288
  let entryPath = Nodepath.join(fullPath, entry);
6107
- let stats = await Fs3.promises.lstat(entryPath);
7289
+ let stats = await Fs.promises.lstat(entryPath);
6108
7290
  if (stats.isSymbolicLink()) {
6109
7291
  return [];
6110
7292
  }
@@ -6141,7 +7323,7 @@ async function findPages(baseDir, currentPath, projectRoot, sourceRoot) {
6141
7323
  throw exn;
6142
7324
  }
6143
7325
  }
6144
- async function execute9(ctx2, _input) {
7326
+ async function execute12(ctx2, _input) {
6145
7327
  try {
6146
7328
  let srcPages = await findPages("src/pages", "", ctx2.projectRoot, ctx2.sourceRoot);
6147
7329
  let rootPages = await findPages("pages", "", ctx2.projectRoot, ctx2.sourceRoot);
@@ -6159,8 +7341,8 @@ async function execute9(ctx2, _input) {
6159
7341
  };
6160
7342
  }
6161
7343
  }
6162
- var name10 = "get_client_pages";
6163
- var description9 = `Lists Astro client pages from the pages directory.
7344
+ var name13 = "get_client_pages";
7345
+ var description12 = `Lists Astro client pages from the pages directory.
6164
7346
 
6165
7347
  Parameters: None
6166
7348
 
@@ -6168,70 +7350,53 @@ Returns array of page paths based on file-system routing conventions.
6168
7350
  Excludes API routes (src/pages/api/) - focuses on renderable pages only.`;
6169
7351
 
6170
7352
  // src/FrontmanAstro__ToolRegistry.res.mjs
6171
- var astroTools = [{
6172
- name: name10,
6173
- description: description9,
6174
- inputSchema: inputSchema9,
6175
- outputSchema: outputSchema9,
6176
- execute: execute9,
6177
- visibleToAgent: true
6178
- }];
6179
- function make2() {
6180
- return addTools(coreTools(), astroTools);
7353
+ var astroTools = [
7354
+ {
7355
+ name: name13,
7356
+ description: description12,
7357
+ inputSchema: inputSchema12,
7358
+ outputSchema: outputSchema12,
7359
+ execute: execute12,
7360
+ visibleToAgent: true
7361
+ },
7362
+ {
7363
+ name: name11,
7364
+ description: description10,
7365
+ inputSchema: inputSchema10,
7366
+ outputSchema: outputSchema10,
7367
+ execute: execute10,
7368
+ visibleToAgent: true
7369
+ }
7370
+ ];
7371
+ function make4() {
7372
+ return replaceByName(addTools(coreTools(), astroTools), {
7373
+ name: name12,
7374
+ description: description11,
7375
+ inputSchema: inputSchema11,
7376
+ outputSchema: outputSchema11,
7377
+ execute: execute11,
7378
+ visibleToAgent: true
7379
+ });
6181
7380
  }
6182
7381
 
6183
7382
  // src/FrontmanAstro__Middleware.res.mjs
6184
- function uiHtml(clientUrl, clientCssUrl, isLightTheme) {
6185
- let openrouterKey = flatMap(process.env["OPENROUTER_API_KEY"], (key) => {
6186
- if (key !== "") {
6187
- return key;
6188
- }
6189
- });
6190
- let configObj = Object.fromEntries([[
6191
- "framework",
6192
- "Astro"
6193
- ]]);
6194
- forEach(openrouterKey, (key) => {
6195
- configObj["openrouterKeyValue"] = key;
6196
- });
6197
- let runtimeConfig = JSON.stringify(configObj);
6198
- let themeClass = isLightTheme ? "" : "dark";
6199
- let cssLink = clientCssUrl !== void 0 ? `<link rel="stylesheet" href="` + clientCssUrl + `">` : "";
6200
- return `<!DOCTYPE html>
6201
- <html lang="en" class="` + themeClass + `">
6202
- <head>
6203
- <meta charset="UTF-8">
6204
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6205
- <title>Frontman</title>
6206
- ` + cssLink + `
6207
- <style>
6208
- html, body, #root {
6209
- margin: 0;
6210
- padding: 0;
6211
- height: 100%;
6212
- width: 100%;
6213
- }
6214
- </style>
6215
- </head>
6216
- <body>
6217
- <div id="root"></div>
6218
- <script>window.__frontmanRuntime=` + runtimeConfig + `</script>
6219
- <script type="module" src="` + clientUrl + `"></script>
6220
- </body>
6221
- </html>`;
6222
- }
6223
- function serveUI(config) {
6224
- let html = uiHtml(config.clientUrl, config.clientCssUrl, config.isLightTheme);
6225
- let headers2 = Object.fromEntries([[
6226
- "Content-Type",
6227
- "text/html"
6228
- ]]);
6229
- return new Response(html, {
6230
- headers: some(headers2)
6231
- });
7383
+ function toMiddlewareConfig(config) {
7384
+ return {
7385
+ projectRoot: config.projectRoot,
7386
+ sourceRoot: config.sourceRoot,
7387
+ basePath: config.basePath,
7388
+ serverName: config.serverName,
7389
+ serverVersion: config.serverVersion,
7390
+ clientUrl: config.clientUrl,
7391
+ clientCssUrl: config.clientCssUrl,
7392
+ entrypointUrl: void 0,
7393
+ isLightTheme: config.isLightTheme,
7394
+ frameworkLabel: "Astro"
7395
+ };
6232
7396
  }
6233
7397
  function createMiddleware(config) {
6234
- let registry = make2();
7398
+ let registry = make4();
7399
+ let middlewareConfig = toMiddlewareConfig(config);
6235
7400
  return async (request) => {
6236
7401
  let url2 = new URL(request.url);
6237
7402
  let pathname = url2.pathname;
@@ -6239,15 +7404,15 @@ function createMiddleware(config) {
6239
7404
  let basePath = `/` + config.basePath;
6240
7405
  if (pathname === basePath || pathname.startsWith(basePath + `/`)) {
6241
7406
  if (method === "OPTIONS") {
6242
- return handleCORS();
7407
+ return handlePreflight();
6243
7408
  } else if (pathname === basePath || pathname === basePath + `/`) {
6244
- return serveUI(config);
7409
+ return withCors(serve(middlewareConfig));
6245
7410
  } else if (pathname === basePath + `/tools` && method === "GET") {
6246
- return handleGetTools(registry, config);
7411
+ return withCors(handleGetTools2(registry, config));
6247
7412
  } else if (pathname === basePath + `/tools/call` && method === "POST") {
6248
- return await handleToolCall(registry, config, request);
7413
+ return withCors(await handleToolCall2(registry, config, request));
6249
7414
  } else if (pathname === basePath + `/resolve-source-location` && method === "POST") {
6250
- return await handleResolveSourceLocation(config, request);
7415
+ return withCors(await handleResolveSourceLocation2(config, request));
6251
7416
  } else {
6252
7417
  return Response.json(Object.fromEntries([[
6253
7418
  "error",
@@ -6260,11 +7425,6 @@ function createMiddleware(config) {
6260
7425
  };
6261
7426
  }
6262
7427
 
6263
- // ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Promise.js
6264
- function $$catch(promise, callback) {
6265
- return promise.catch((err) => callback(internalToException(err)));
6266
- }
6267
-
6268
7428
  // ../bindings/src/NodeHttp.res.mjs
6269
7429
  var collectRequestBody = (async function(req) {
6270
7430
  const chunks = [];
@@ -6372,35 +7532,46 @@ var icon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
6372
7532
  function getToolbarAppPath() {
6373
7533
  return new URL("./toolbar.js", import.meta.url).pathname;
6374
7534
  }
6375
- function make3(configInput) {
7535
+ function make5(configInput) {
6376
7536
  let config = makeFromObject(configInput);
6377
7537
  return {
6378
7538
  name: "frontman",
6379
7539
  hooks: {
6380
7540
  "astro:config:setup": (ctx2) => {
6381
- let match = ctx2.command;
6382
- if (match === "dev") {
6383
- if (ctx2.config.devToolbar.enabled) ; else {
6384
- console.warn("[Frontman] Astro devToolbar is disabled \u2014 element source detection will be limited. Set `devToolbar: { enabled: true }` in your astro.config to enable full component source resolution.");
6385
- }
6386
- ctx2.updateConfig({
6387
- vite: {
6388
- plugins: [frontmanPropsInjectionPlugin()]
6389
- }
6390
- });
6391
- ctx2.addDevToolbarApp({
6392
- id: "frontman:toolbar",
6393
- name: "Frontman",
6394
- icon,
6395
- entrypoint: getToolbarAppPath()
6396
- });
6397
- return ctx2.injectScript("head-inline", annotationCaptureScript2);
7541
+ if (ctx2.command !== "dev") {
7542
+ return;
7543
+ }
7544
+ if (!ctx2.config.devToolbar.enabled) {
7545
+ console.warn("[Frontman] Astro devToolbar is disabled \u2014 element source detection will be limited. Set `devToolbar: { enabled: true }` in your astro.config to enable full component source resolution.");
6398
7546
  }
7547
+ ctx2.updateConfig({
7548
+ vite: {
7549
+ plugins: [frontmanPropsInjectionPlugin()]
7550
+ }
7551
+ });
7552
+ ctx2.addDevToolbarApp({
7553
+ id: "frontman:toolbar",
7554
+ name: "Frontman",
7555
+ icon,
7556
+ entrypoint: getToolbarAppPath()
7557
+ });
7558
+ let safeBasePath = getOr(JSON.stringify(config.basePath), `"frontman"`);
7559
+ let basePathMeta = `{
7560
+ const meta = document.createElement('meta');
7561
+ meta.name = 'frontman-base-path';
7562
+ meta.content = ` + safeBasePath + `;
7563
+ document.head.appendChild(meta);
7564
+ }`;
7565
+ ctx2.injectScript("head-inline", basePathMeta + "\n" + annotationCaptureScript2);
6399
7566
  },
6400
7567
  "astro:server:setup": (param) => {
7568
+ initialize();
6401
7569
  let webMiddleware = createMiddleware(config);
6402
7570
  let connectMiddleware = adaptToConnect(webMiddleware, config.basePath);
6403
7571
  param.server.middlewares.use(connectMiddleware);
7572
+ param.toolbar.onAppInitialized("frontman:toolbar", () => {
7573
+ console.log("[Frontman] Dev toolbar app initialized");
7574
+ });
6404
7575
  }
6405
7576
  }
6406
7577
  };
@@ -6410,4 +7581,4 @@ var Config;
6410
7581
  var Middleware;
6411
7582
  var ViteAdapter;
6412
7583
 
6413
- export { Bindings, Config, Middleware, ViteAdapter, annotationCaptureScript2 as annotationCaptureScript, frontmanPropsInjectionPlugin2 as frontmanPropsInjectionPlugin, getToolbarAppPath, icon, make3 as make };
7584
+ export { Bindings, Config, Middleware, ViteAdapter, annotationCaptureScript2 as annotationCaptureScript, frontmanPropsInjectionPlugin2 as frontmanPropsInjectionPlugin, getToolbarAppPath, icon, make5 as make };