@frontman-ai/astro 0.1.7 → 0.2.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 +678 -90
- package/dist/integration.js +682 -91
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Web from 'stream/web';
|
|
2
|
-
import * as
|
|
2
|
+
import * as Fs3 from 'fs';
|
|
3
3
|
import { existsSync, readFileSync } from 'fs';
|
|
4
4
|
import * as Nodepath from 'path';
|
|
5
5
|
import { dirname, join } from 'path';
|
|
@@ -140,6 +140,267 @@ function makeFromObject(rawConfig) {
|
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
// src/annotation-capture.mjs
|
|
144
|
+
var annotationCaptureScript = `(function() {
|
|
145
|
+
var PROPS_PREFIX = '__frontman_props__:';
|
|
146
|
+
|
|
147
|
+
function parsePropsPayload(text) {
|
|
148
|
+
text = text.trim();
|
|
149
|
+
if (text.indexOf(PROPS_PREFIX) !== 0) return null;
|
|
150
|
+
try {
|
|
151
|
+
var encoded = text.slice(PROPS_PREFIX.length).trim();
|
|
152
|
+
return JSON.parse(atob(encoded));
|
|
153
|
+
} catch(e) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function captureAnnotations() {
|
|
159
|
+
var annotations = new Map();
|
|
160
|
+
var propsMap = new Map();
|
|
161
|
+
var pendingProps = [];
|
|
162
|
+
|
|
163
|
+
var walker = document.createTreeWalker(
|
|
164
|
+
document.documentElement,
|
|
165
|
+
NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT,
|
|
166
|
+
null
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
var node;
|
|
170
|
+
while (node = walker.nextNode()) {
|
|
171
|
+
if (node.nodeType === 8) {
|
|
172
|
+
var parsed = parsePropsPayload(node.textContent);
|
|
173
|
+
if (parsed) {
|
|
174
|
+
pendingProps.push(parsed);
|
|
175
|
+
}
|
|
176
|
+
} else if (node.nodeType === 1) {
|
|
177
|
+
if (pendingProps.length > 0 && node.hasAttribute('data-astro-source-file')) {
|
|
178
|
+
propsMap.set(node, pendingProps.slice());
|
|
179
|
+
pendingProps = [];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
document.querySelectorAll('[data-astro-source-file]').forEach(function(el) {
|
|
185
|
+
var sourceFile = el.getAttribute('data-astro-source-file');
|
|
186
|
+
var annotation = {
|
|
187
|
+
file: sourceFile,
|
|
188
|
+
loc: el.getAttribute('data-astro-source-loc')
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
var propsChain = propsMap.get(el);
|
|
192
|
+
|
|
193
|
+
if (!propsChain) {
|
|
194
|
+
var parent = el.parentElement;
|
|
195
|
+
var maxSteps = 30;
|
|
196
|
+
while (parent && maxSteps-- > 0) {
|
|
197
|
+
propsChain = propsMap.get(parent);
|
|
198
|
+
if (propsChain) break;
|
|
199
|
+
parent = parent.parentElement;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (propsChain && propsChain.length > 0) {
|
|
204
|
+
var match = null;
|
|
205
|
+
for (var i = 0; i < propsChain.length; i++) {
|
|
206
|
+
var entry = propsChain[i];
|
|
207
|
+
if (entry.moduleId) {
|
|
208
|
+
var entryFile = entry.moduleId.split('/').pop() || '';
|
|
209
|
+
var srcFile = sourceFile.split('/').pop() || '';
|
|
210
|
+
if (entryFile === srcFile && entryFile !== '') {
|
|
211
|
+
match = entry;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (!match) match = propsChain[0];
|
|
217
|
+
|
|
218
|
+
if (match) {
|
|
219
|
+
annotation.componentProps = match.props || null;
|
|
220
|
+
if (match.displayName) {
|
|
221
|
+
annotation.displayName = match.displayName;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
annotations.set(el, annotation);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
window.__frontman_annotations__ = {
|
|
230
|
+
_map: annotations,
|
|
231
|
+
get: function(el) { return annotations.get(el); },
|
|
232
|
+
has: function(el) { return annotations.has(el); },
|
|
233
|
+
size: function() { return annotations.size; }
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
document.addEventListener('DOMContentLoaded', captureAnnotations);
|
|
238
|
+
|
|
239
|
+
var initialLoad = true;
|
|
240
|
+
document.addEventListener('astro:page-load', function() {
|
|
241
|
+
if (initialLoad) { initialLoad = false; return; }
|
|
242
|
+
captureAnnotations();
|
|
243
|
+
});
|
|
244
|
+
})();`;
|
|
245
|
+
|
|
246
|
+
// src/vite-plugin-props-injection.mjs
|
|
247
|
+
function frontmanPropsInjectionPlugin() {
|
|
248
|
+
return {
|
|
249
|
+
name: "frontman:props-injection",
|
|
250
|
+
enforce: "pre",
|
|
251
|
+
apply: "serve",
|
|
252
|
+
// Only apply in SSR (server-side rendering) mode
|
|
253
|
+
transform(code, id, options) {
|
|
254
|
+
if (!options?.ssr) return null;
|
|
255
|
+
if (!id.includes("astro/dist/runtime/server/render/component") && !id.includes("astro/runtime/server/render/component")) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
if (!code.includes("function renderComponent(")) {
|
|
259
|
+
console.warn(
|
|
260
|
+
"[Frontman] Could not find renderComponent in Astro internals \u2014 component props injection will be disabled. This may happen after an Astro upgrade. File: " + id
|
|
261
|
+
);
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
let transformed = code.replace(
|
|
265
|
+
"function renderComponent(",
|
|
266
|
+
"function __original_renderComponent("
|
|
267
|
+
);
|
|
268
|
+
const wrapperCode = `
|
|
269
|
+
|
|
270
|
+
// --- Frontman props injection wrapper ---
|
|
271
|
+
|
|
272
|
+
function __frontman_safeSerialize(displayName, Component, props) {
|
|
273
|
+
try {
|
|
274
|
+
const clean = {};
|
|
275
|
+
for (const [key, value] of Object.entries(props || {})) {
|
|
276
|
+
// Skip internal Astro props (scoped CSS hashes)
|
|
277
|
+
if (key.startsWith('data-astro-cid-')) continue;
|
|
278
|
+
// Skip class (styling detail, not semantic)
|
|
279
|
+
if (key === 'class' || key === 'class:list') continue;
|
|
280
|
+
|
|
281
|
+
const t = typeof value;
|
|
282
|
+
if (t === 'string' || t === 'number' || t === 'boolean') {
|
|
283
|
+
clean[key] = value;
|
|
284
|
+
} else if (value === null || value === undefined) {
|
|
285
|
+
clean[key] = value;
|
|
286
|
+
} else if (Array.isArray(value)) {
|
|
287
|
+
try {
|
|
288
|
+
const serialized = JSON.stringify(value);
|
|
289
|
+
clean[key] = serialized.length < 1000 ? value : '[Array(' + value.length + ')]';
|
|
290
|
+
} catch {
|
|
291
|
+
clean[key] = '[Array]';
|
|
292
|
+
}
|
|
293
|
+
} else if (t === 'object') {
|
|
294
|
+
try {
|
|
295
|
+
const serialized = JSON.stringify(value);
|
|
296
|
+
clean[key] = serialized.length < 500 ? value : '{...}';
|
|
297
|
+
} catch {
|
|
298
|
+
clean[key] = '{...}';
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// Skip functions, symbols, etc.
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const entry = { displayName, props: clean };
|
|
305
|
+
// Include the component's moduleId (file path) if available
|
|
306
|
+
if (Component && Component.moduleId) {
|
|
307
|
+
entry.moduleId = Component.moduleId;
|
|
308
|
+
}
|
|
309
|
+
return JSON.stringify(entry);
|
|
310
|
+
} catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function __frontman_toBase64(str) {
|
|
316
|
+
if (typeof Buffer !== 'undefined') return Buffer.from(str, 'utf-8').toString('base64');
|
|
317
|
+
if (typeof btoa === 'function') return btoa(unescape(encodeURIComponent(str)));
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function __frontman_wrapInstance(renderInstance, displayName, Component, props) {
|
|
322
|
+
// If no render method (e.g. fragment), pass through
|
|
323
|
+
if (!renderInstance || typeof renderInstance.render !== 'function') {
|
|
324
|
+
return renderInstance;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const serialized = __frontman_safeSerialize(displayName, Component, props);
|
|
328
|
+
if (!serialized) return renderInstance;
|
|
329
|
+
|
|
330
|
+
const encoded = __frontman_toBase64(serialized);
|
|
331
|
+
if (!encoded) return renderInstance;
|
|
332
|
+
|
|
333
|
+
const originalRender = renderInstance.render;
|
|
334
|
+
|
|
335
|
+
renderInstance.render = function(destination) {
|
|
336
|
+
// Write the props comment BEFORE the component renders.
|
|
337
|
+
// This creates a Comment node in the DOM immediately preceding
|
|
338
|
+
// the component's first rendered element.
|
|
339
|
+
// Guard: markHTMLString is assumed to be in scope from Astro's module.
|
|
340
|
+
// If it's missing (e.g., after an Astro upgrade), skip injection gracefully.
|
|
341
|
+
if (typeof markHTMLString === 'function') {
|
|
342
|
+
destination.write(markHTMLString('<!-- __frontman_props__:' + encoded + ' -->'));
|
|
343
|
+
}
|
|
344
|
+
return originalRender.call(renderInstance, destination);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
return renderInstance;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function renderComponent(result, displayName, Component, props, slots) {
|
|
351
|
+
const renderInstance = __original_renderComponent(result, displayName, Component, props, slots);
|
|
352
|
+
|
|
353
|
+
// Handle promise (async component resolution)
|
|
354
|
+
if (renderInstance && typeof renderInstance.then === 'function') {
|
|
355
|
+
return renderInstance.then(function(resolved) {
|
|
356
|
+
return __frontman_wrapInstance(resolved, displayName, Component, props);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return __frontman_wrapInstance(renderInstance, displayName, Component, props);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// --- End Frontman props injection wrapper ---
|
|
364
|
+
`;
|
|
365
|
+
transformed += wrapperCode;
|
|
366
|
+
return {
|
|
367
|
+
code: transformed,
|
|
368
|
+
map: null
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// ../../node_modules/@rescript/runtime/lib/es6/Primitive_int.js
|
|
375
|
+
function div(x, y) {
|
|
376
|
+
if (y === 0) {
|
|
377
|
+
throw {
|
|
378
|
+
RE_EXN_ID: "Division_by_zero",
|
|
379
|
+
Error: new Error()
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
return x / y | 0;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ../../node_modules/@rescript/runtime/lib/es6/Belt_Array.js
|
|
386
|
+
function concatMany(arrs) {
|
|
387
|
+
let lenArrs = arrs.length;
|
|
388
|
+
let totalLen = 0;
|
|
389
|
+
for (let i = 0; i < lenArrs; ++i) {
|
|
390
|
+
totalLen = totalLen + arrs[i].length | 0;
|
|
391
|
+
}
|
|
392
|
+
let result = new Array(totalLen);
|
|
393
|
+
totalLen = 0;
|
|
394
|
+
for (let j2 = 0; j2 < lenArrs; ++j2) {
|
|
395
|
+
let cur = arrs[j2];
|
|
396
|
+
for (let k2 = 0, k_finish = cur.length; k2 < k_finish; ++k2) {
|
|
397
|
+
result[totalLen] = cur[k2];
|
|
398
|
+
totalLen = totalLen + 1 | 0;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
|
|
143
404
|
// ../../node_modules/@rescript/runtime/lib/es6/Primitive_exceptions.js
|
|
144
405
|
function isExtension(e) {
|
|
145
406
|
if (e == null) {
|
|
@@ -280,9 +541,9 @@ function stringify(unknown2) {
|
|
|
280
541
|
function toExpression(schema3) {
|
|
281
542
|
let tag = schema3.type;
|
|
282
543
|
let $$const = schema3.const;
|
|
283
|
-
let
|
|
284
|
-
if (
|
|
285
|
-
return
|
|
544
|
+
let name11 = schema3.name;
|
|
545
|
+
if (name11 !== void 0) {
|
|
546
|
+
return name11;
|
|
286
547
|
}
|
|
287
548
|
if ($$const !== void 0) {
|
|
288
549
|
return stringify($$const);
|
|
@@ -1402,10 +1663,10 @@ function isPriority(tagFlag, byKey) {
|
|
|
1402
1663
|
}
|
|
1403
1664
|
}
|
|
1404
1665
|
function isWiderUnionSchema(schemaAnyOf, inputAnyOf) {
|
|
1405
|
-
return inputAnyOf.every((
|
|
1666
|
+
return inputAnyOf.every((inputSchema10, idx) => {
|
|
1406
1667
|
let schema3 = schemaAnyOf[idx];
|
|
1407
|
-
if (schema3 !== void 0 && !(flags[
|
|
1408
|
-
return
|
|
1668
|
+
if (schema3 !== void 0 && !(flags[inputSchema10.type] & 9152) && inputSchema10.type === schema3.type) {
|
|
1669
|
+
return inputSchema10.const === schema3.const;
|
|
1409
1670
|
} else {
|
|
1410
1671
|
return false;
|
|
1411
1672
|
}
|
|
@@ -2259,6 +2520,7 @@ var $$Error2 = $$Error;
|
|
|
2259
2520
|
var string2 = string;
|
|
2260
2521
|
var bool2 = bool;
|
|
2261
2522
|
var int2 = int;
|
|
2523
|
+
var float2 = float;
|
|
2262
2524
|
var json2 = json;
|
|
2263
2525
|
var enableJson2 = enableJson;
|
|
2264
2526
|
var literal2 = literal;
|
|
@@ -2287,7 +2549,7 @@ function string3(json3) {
|
|
|
2287
2549
|
return json3;
|
|
2288
2550
|
}
|
|
2289
2551
|
}
|
|
2290
|
-
function
|
|
2552
|
+
function float3(json3) {
|
|
2291
2553
|
if (typeof json3 === "number") {
|
|
2292
2554
|
return json3;
|
|
2293
2555
|
}
|
|
@@ -2306,7 +2568,7 @@ var Decode = {
|
|
|
2306
2568
|
bool: bool3,
|
|
2307
2569
|
$$null: $$null2,
|
|
2308
2570
|
string: string3,
|
|
2309
|
-
float:
|
|
2571
|
+
float: float3,
|
|
2310
2572
|
object: object2,
|
|
2311
2573
|
array: array3
|
|
2312
2574
|
};
|
|
@@ -4010,6 +4272,21 @@ function reduce(arr, init, f) {
|
|
|
4010
4272
|
function reduceWithIndex(arr, init, f) {
|
|
4011
4273
|
return arr.reduce(f, init);
|
|
4012
4274
|
}
|
|
4275
|
+
function filterMap(a, f) {
|
|
4276
|
+
let l = a.length;
|
|
4277
|
+
let r = new Array(l);
|
|
4278
|
+
let j2 = 0;
|
|
4279
|
+
for (let i = 0; i < l; ++i) {
|
|
4280
|
+
let v = a[i];
|
|
4281
|
+
let v$1 = f(v);
|
|
4282
|
+
if (v$1 !== void 0) {
|
|
4283
|
+
r[j2] = valFromOption(v$1);
|
|
4284
|
+
j2 = j2 + 1 | 0;
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
r.length = j2;
|
|
4288
|
+
return r;
|
|
4289
|
+
}
|
|
4013
4290
|
|
|
4014
4291
|
// ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Int.js
|
|
4015
4292
|
function fromString2(x, radix) {
|
|
@@ -4290,7 +4567,18 @@ Hint: ` + hint;
|
|
|
4290
4567
|
}
|
|
4291
4568
|
}
|
|
4292
4569
|
|
|
4570
|
+
// ../frontman-protocol/src/FrontmanProtocol__Tool.res.mjs
|
|
4571
|
+
var ToolNames = {
|
|
4572
|
+
writeFile: "write_file",
|
|
4573
|
+
readFile: "read_file",
|
|
4574
|
+
listFiles: "list_files",
|
|
4575
|
+
searchFiles: "search_files",
|
|
4576
|
+
grep: "grep",
|
|
4577
|
+
fileExists: "file_exists",
|
|
4578
|
+
loadAgentInstructions: "load_agent_instructions"};
|
|
4579
|
+
|
|
4293
4580
|
// ../frontman-core/src/tools/FrontmanCore__Tool__Grep.res.mjs
|
|
4581
|
+
var name2 = ToolNames.grep;
|
|
4294
4582
|
var inputSchema = schema2((s2) => ({
|
|
4295
4583
|
pattern: s2.m(string2),
|
|
4296
4584
|
path: s2.m(option2(string2)),
|
|
@@ -4552,7 +4840,6 @@ async function execute(ctx2, input) {
|
|
|
4552
4840
|
return await gitGrepWithFallback();
|
|
4553
4841
|
}
|
|
4554
4842
|
}
|
|
4555
|
-
var name2 = "grep";
|
|
4556
4843
|
var description = `Fast content search tool that finds files containing specific text or patterns, returning matching lines sorted by file modification time.
|
|
4557
4844
|
|
|
4558
4845
|
WHEN TO USE THIS TOOL:
|
|
@@ -4583,6 +4870,7 @@ LIMITATIONS:
|
|
|
4583
4870
|
- Results limited to max_results (default 20)
|
|
4584
4871
|
- Binary files are automatically skipped
|
|
4585
4872
|
- Hidden files (starting with '.') are skipped by default`;
|
|
4873
|
+
var name3 = ToolNames.readFile;
|
|
4586
4874
|
var inputSchema2 = schema2((s2) => ({
|
|
4587
4875
|
path: s2.m(string2),
|
|
4588
4876
|
offset: s2.m(option2(int2)),
|
|
@@ -4611,7 +4899,7 @@ async function execute2(ctx2, input) {
|
|
|
4611
4899
|
}
|
|
4612
4900
|
let result = err._0;
|
|
4613
4901
|
try {
|
|
4614
|
-
let content = await
|
|
4902
|
+
let content = await Fs3.promises.readFile(result.resolvedPath, "utf8");
|
|
4615
4903
|
let lines = content.split("\n");
|
|
4616
4904
|
let totalLines = lines.length;
|
|
4617
4905
|
let selectedLines = lines.slice(offset, offset + limit | 0);
|
|
@@ -4639,7 +4927,6 @@ async function execute2(ctx2, input) {
|
|
|
4639
4927
|
};
|
|
4640
4928
|
}
|
|
4641
4929
|
}
|
|
4642
|
-
var name3 = "read_file";
|
|
4643
4930
|
var description2 = `Reads a file from the filesystem.
|
|
4644
4931
|
|
|
4645
4932
|
Parameters:
|
|
@@ -4663,6 +4950,7 @@ function map3(opt, f) {
|
|
|
4663
4950
|
}
|
|
4664
4951
|
|
|
4665
4952
|
// ../frontman-core/src/tools/FrontmanCore__Tool__ListFiles.res.mjs
|
|
4953
|
+
var name4 = ToolNames.listFiles;
|
|
4666
4954
|
var inputSchema3 = schema2((s2) => ({
|
|
4667
4955
|
path: s2.m(option2(string2))
|
|
4668
4956
|
}));
|
|
@@ -4738,20 +5026,20 @@ async function execute3(ctx2, input) {
|
|
|
4738
5026
|
}
|
|
4739
5027
|
try {
|
|
4740
5028
|
let fullPath = err._0.resolvedPath;
|
|
4741
|
-
let entries = await
|
|
4742
|
-
let filteredEntriesResult = map3(await getIgnoredEntries(fullPath, entries), (ignored) => entries.filter((
|
|
5029
|
+
let entries = await Fs3.promises.readdir(fullPath);
|
|
5030
|
+
let filteredEntriesResult = map3(await getIgnoredEntries(fullPath, entries), (ignored) => entries.filter((name11) => !ignored.includes(name11)));
|
|
4743
5031
|
if (filteredEntriesResult.TAG !== "Ok") {
|
|
4744
5032
|
return {
|
|
4745
5033
|
TAG: "Error",
|
|
4746
5034
|
_0: filteredEntriesResult._0
|
|
4747
5035
|
};
|
|
4748
5036
|
}
|
|
4749
|
-
let entriesWithStats = await Promise.all(filteredEntriesResult._0.map(async (
|
|
4750
|
-
let entryPath = Nodepath.join(fullPath,
|
|
4751
|
-
let stats = await
|
|
5037
|
+
let entriesWithStats = await Promise.all(filteredEntriesResult._0.map(async (name11) => {
|
|
5038
|
+
let entryPath = Nodepath.join(fullPath, name11);
|
|
5039
|
+
let stats = await Fs3.promises.stat(entryPath);
|
|
4752
5040
|
return {
|
|
4753
|
-
name:
|
|
4754
|
-
path: Nodepath.join(path,
|
|
5041
|
+
name: name11,
|
|
5042
|
+
path: Nodepath.join(path, name11),
|
|
4755
5043
|
isFile: stats.isFile(),
|
|
4756
5044
|
isDirectory: stats.isDirectory()
|
|
4757
5045
|
};
|
|
@@ -4769,16 +5057,18 @@ async function execute3(ctx2, input) {
|
|
|
4769
5057
|
};
|
|
4770
5058
|
}
|
|
4771
5059
|
}
|
|
4772
|
-
var name4 = "list_files";
|
|
4773
5060
|
var description3 = `Lists files and directories in a given path.
|
|
4774
5061
|
|
|
4775
5062
|
Parameters:
|
|
4776
5063
|
- path (optional): Path to directory - either relative to source root or absolute (must be under source root). Defaults to "." (root directory).
|
|
4777
5064
|
|
|
4778
5065
|
Returns array of entries with name, path, and type information.`;
|
|
5066
|
+
var name5 = ToolNames.writeFile;
|
|
4779
5067
|
var inputSchema4 = schema2((s2) => ({
|
|
4780
5068
|
path: s2.m(string2),
|
|
4781
|
-
content: s2.m(string2)
|
|
5069
|
+
content: s2.m(option2(string2)),
|
|
5070
|
+
image_ref: s2.m(option2(string2)),
|
|
5071
|
+
encoding: s2.m(option2(literal2("base64")))
|
|
4782
5072
|
}));
|
|
4783
5073
|
var pathContextSchema2 = schema2((s2) => ({
|
|
4784
5074
|
sourceRoot: s2.m(string2),
|
|
@@ -4788,7 +5078,35 @@ var pathContextSchema2 = schema2((s2) => ({
|
|
|
4788
5078
|
var outputSchema4 = schema2((s2) => ({
|
|
4789
5079
|
_context: s2.m(option2(pathContextSchema2))
|
|
4790
5080
|
}));
|
|
5081
|
+
function writeContent(resolvedPath, content, encoding) {
|
|
5082
|
+
if (encoding === void 0) {
|
|
5083
|
+
return Fs3.promises.writeFile(resolvedPath, content, "utf8");
|
|
5084
|
+
}
|
|
5085
|
+
let buffer = Nodebuffer.Buffer.from(content, "base64");
|
|
5086
|
+
return Fs3.promises.writeFile(resolvedPath, buffer);
|
|
5087
|
+
}
|
|
4791
5088
|
async function execute4(ctx2, input) {
|
|
5089
|
+
let match = input.content;
|
|
5090
|
+
let match$1 = input.image_ref;
|
|
5091
|
+
if (match === void 0) {
|
|
5092
|
+
if (match$1 !== void 0) {
|
|
5093
|
+
return {
|
|
5094
|
+
TAG: "Error",
|
|
5095
|
+
_0: "image_ref must be resolved to content before execution"
|
|
5096
|
+
};
|
|
5097
|
+
} else {
|
|
5098
|
+
return {
|
|
5099
|
+
TAG: "Error",
|
|
5100
|
+
_0: "Either content or image_ref must be provided"
|
|
5101
|
+
};
|
|
5102
|
+
}
|
|
5103
|
+
}
|
|
5104
|
+
if (match$1 !== void 0) {
|
|
5105
|
+
return {
|
|
5106
|
+
TAG: "Error",
|
|
5107
|
+
_0: "Provide either content or image_ref, not both"
|
|
5108
|
+
};
|
|
5109
|
+
}
|
|
4792
5110
|
let err = resolve2(ctx2.sourceRoot, input.path);
|
|
4793
5111
|
if (err.TAG !== "Ok") {
|
|
4794
5112
|
return {
|
|
@@ -4797,12 +5115,11 @@ async function execute4(ctx2, input) {
|
|
|
4797
5115
|
};
|
|
4798
5116
|
}
|
|
4799
5117
|
let result = err._0;
|
|
4800
|
-
let dirPath = dirname3(result);
|
|
4801
5118
|
try {
|
|
4802
|
-
await
|
|
5119
|
+
await Fs3.promises.mkdir(dirname3(result), {
|
|
4803
5120
|
recursive: true
|
|
4804
5121
|
});
|
|
4805
|
-
await
|
|
5122
|
+
await writeContent(result.resolvedPath, match, input.encoding);
|
|
4806
5123
|
return {
|
|
4807
5124
|
TAG: "Ok",
|
|
4808
5125
|
_0: {
|
|
@@ -4822,15 +5139,18 @@ async function execute4(ctx2, input) {
|
|
|
4822
5139
|
};
|
|
4823
5140
|
}
|
|
4824
5141
|
}
|
|
4825
|
-
var name5 = "write_file";
|
|
4826
5142
|
var description4 = `Writes content to a file.
|
|
4827
5143
|
|
|
4828
5144
|
Parameters:
|
|
4829
5145
|
- path (required): Path to file - either relative to source root or absolute (must be under source root)
|
|
4830
|
-
- content
|
|
5146
|
+
- content: Text content to write (mutually exclusive with image_ref)
|
|
5147
|
+
- image_ref: URI of a user-attached image to save (e.g., "attachment://att_abc123/photo.png"). Use this to save images the user has pasted into the chat. Mutually exclusive with content.
|
|
5148
|
+
- encoding: Set to "base64" when writing binary data (used internally when image_ref is resolved)
|
|
4831
5149
|
|
|
5150
|
+
Provide either content OR image_ref, not both.
|
|
4832
5151
|
Creates parent directories if they don't exist. Overwrites existing files.
|
|
4833
5152
|
The _context field provides path resolution details for debugging.`;
|
|
5153
|
+
var name6 = ToolNames.fileExists;
|
|
4834
5154
|
var inputSchema5 = schema2((s2) => ({
|
|
4835
5155
|
path: s2.m(string2)
|
|
4836
5156
|
}));
|
|
@@ -4843,7 +5163,7 @@ async function execute5(ctx2, input) {
|
|
|
4843
5163
|
};
|
|
4844
5164
|
}
|
|
4845
5165
|
try {
|
|
4846
|
-
await
|
|
5166
|
+
await Fs3.promises.access(toString(msg._0));
|
|
4847
5167
|
return {
|
|
4848
5168
|
TAG: "Ok",
|
|
4849
5169
|
_0: true
|
|
@@ -4855,7 +5175,6 @@ async function execute5(ctx2, input) {
|
|
|
4855
5175
|
};
|
|
4856
5176
|
}
|
|
4857
5177
|
}
|
|
4858
|
-
var name6 = "file_exists";
|
|
4859
5178
|
var description5 = `Checks if a file or directory exists.
|
|
4860
5179
|
|
|
4861
5180
|
Parameters:
|
|
@@ -4863,12 +5182,294 @@ Parameters:
|
|
|
4863
5182
|
|
|
4864
5183
|
Returns true if the path exists, false otherwise.`;
|
|
4865
5184
|
var outputSchema5 = bool2;
|
|
5185
|
+
|
|
5186
|
+
// ../bindings/src/Lighthouse.res.mjs
|
|
5187
|
+
var run = ((url2, flags2) => import('module').then(({ createRequire }) => {
|
|
5188
|
+
const req = createRequire(import.meta.url);
|
|
5189
|
+
try {
|
|
5190
|
+
const mod = req("lighthouse");
|
|
5191
|
+
const lighthouse = mod.default ?? mod;
|
|
5192
|
+
return lighthouse(url2, flags2);
|
|
5193
|
+
} catch (e) {
|
|
5194
|
+
if (e.code === "MODULE_NOT_FOUND") {
|
|
5195
|
+
throw new Error("lighthouse is not installed. Run: npm install lighthouse");
|
|
5196
|
+
}
|
|
5197
|
+
throw e;
|
|
5198
|
+
}
|
|
5199
|
+
}));
|
|
5200
|
+
|
|
5201
|
+
// ../bindings/src/ChromeLauncher.res.mjs
|
|
5202
|
+
var launch = ((options) => import('module').then(({ createRequire }) => {
|
|
5203
|
+
const req = createRequire(import.meta.url);
|
|
5204
|
+
try {
|
|
5205
|
+
const mod = req("chrome-launcher");
|
|
5206
|
+
return mod.launch(options);
|
|
5207
|
+
} catch (e) {
|
|
5208
|
+
if (e.code === "MODULE_NOT_FOUND") {
|
|
5209
|
+
throw new Error("chrome-launcher is not installed. Run: npm install chrome-launcher");
|
|
5210
|
+
}
|
|
5211
|
+
throw e;
|
|
5212
|
+
}
|
|
5213
|
+
}));
|
|
5214
|
+
|
|
5215
|
+
// ../frontman-core/src/tools/FrontmanCore__Tool__Lighthouse.res.mjs
|
|
5216
|
+
var rewriteUrlForRuntime = ((url2) => {
|
|
5217
|
+
const override = process.env.FRONTMAN_LIGHTHOUSE_DEVPOD_LOCALHOST;
|
|
5218
|
+
const worktreeId = process.env.WORKTREE_ID;
|
|
5219
|
+
const overrideLower = typeof override === "string" ? override.toLowerCase() : "";
|
|
5220
|
+
const devpodMode = overrideLower === "1" || overrideLower === "true" || overrideLower === "yes" || overrideLower === "on" || typeof worktreeId === "string";
|
|
5221
|
+
if (!devpodMode) {
|
|
5222
|
+
return url2;
|
|
5223
|
+
}
|
|
5224
|
+
let parsed;
|
|
5225
|
+
try {
|
|
5226
|
+
parsed = new URL(url2);
|
|
5227
|
+
} catch {
|
|
5228
|
+
return url2;
|
|
5229
|
+
}
|
|
5230
|
+
const host2 = parsed.hostname;
|
|
5231
|
+
const mapToLocalhost = (port2, protocol) => {
|
|
5232
|
+
parsed.protocol = protocol;
|
|
5233
|
+
parsed.hostname = "127.0.0.1";
|
|
5234
|
+
parsed.port = String(port2);
|
|
5235
|
+
return parsed.toString();
|
|
5236
|
+
};
|
|
5237
|
+
if (host2.endsWith(".nextjs.frontman.local")) {
|
|
5238
|
+
return mapToLocalhost(3e3, "http:");
|
|
5239
|
+
}
|
|
5240
|
+
if (host2.endsWith(".vite.frontman.local")) {
|
|
5241
|
+
return mapToLocalhost(5173, "http:");
|
|
5242
|
+
}
|
|
5243
|
+
if (host2.endsWith(".api.frontman.local")) {
|
|
5244
|
+
return mapToLocalhost(4e3, "https:");
|
|
5245
|
+
}
|
|
5246
|
+
return url2;
|
|
5247
|
+
});
|
|
4866
5248
|
var inputSchema6 = schema2((s2) => ({
|
|
5249
|
+
url: s2.m(string2),
|
|
5250
|
+
preset: s2.m(option2(string2))
|
|
5251
|
+
}));
|
|
5252
|
+
var auditIssueSchema = schema2((s2) => ({
|
|
5253
|
+
id: s2.m(string2),
|
|
5254
|
+
title: s2.m(string2),
|
|
5255
|
+
description: s2.m(string2),
|
|
5256
|
+
score: s2.m(float2),
|
|
5257
|
+
displayValue: s2.m(option2(string2))
|
|
5258
|
+
}));
|
|
5259
|
+
var categoryResultSchema = schema2((s2) => ({
|
|
5260
|
+
id: s2.m(string2),
|
|
5261
|
+
title: s2.m(string2),
|
|
5262
|
+
score: s2.m(int2),
|
|
5263
|
+
topIssues: s2.m(array2(auditIssueSchema))
|
|
5264
|
+
}));
|
|
5265
|
+
var outputSchema6 = schema2((s2) => ({
|
|
5266
|
+
url: s2.m(string2),
|
|
5267
|
+
fetchTime: s2.m(string2),
|
|
5268
|
+
categories: s2.m(array2(categoryResultSchema)),
|
|
5269
|
+
overallScore: s2.m(int2),
|
|
5270
|
+
warnings: s2.m(array2(string2))
|
|
5271
|
+
}));
|
|
5272
|
+
var categoryIds = [
|
|
5273
|
+
"performance",
|
|
5274
|
+
"accessibility",
|
|
5275
|
+
"best-practices",
|
|
5276
|
+
"seo"
|
|
5277
|
+
];
|
|
5278
|
+
function getErrorMessage(exn) {
|
|
5279
|
+
let jsError = fromException(exn);
|
|
5280
|
+
if (jsError === void 0) {
|
|
5281
|
+
return String(exn);
|
|
5282
|
+
}
|
|
5283
|
+
let jsError$1 = valFromOption(jsError);
|
|
5284
|
+
let message3 = getOr(message2(jsError$1), "Unknown error");
|
|
5285
|
+
let stack2 = jsError$1.stack;
|
|
5286
|
+
if (stack2 !== void 0) {
|
|
5287
|
+
return message3 + `
|
|
5288
|
+
` + stack2;
|
|
5289
|
+
} else {
|
|
5290
|
+
return message3;
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
function getTopIssues(category, audits, maxIssues) {
|
|
5294
|
+
return filterMap(category.auditRefs, (ref) => audits[ref.id]).filter((audit) => {
|
|
5295
|
+
let score = audit.score;
|
|
5296
|
+
if (!(score == null) && (audit.scoreDisplayMode === "binary" || audit.scoreDisplayMode === "numeric" || audit.scoreDisplayMode === "metricSavings")) {
|
|
5297
|
+
return score < 1;
|
|
5298
|
+
} else {
|
|
5299
|
+
return false;
|
|
5300
|
+
}
|
|
5301
|
+
}).toSorted((a, b) => {
|
|
5302
|
+
let scoreA = getOr(fromNullable(a.score), 0);
|
|
5303
|
+
let scoreB = getOr(fromNullable(b.score), 0);
|
|
5304
|
+
return scoreA - scoreB;
|
|
5305
|
+
}).slice(0, maxIssues).map((audit) => ({
|
|
5306
|
+
id: audit.id,
|
|
5307
|
+
title: audit.title,
|
|
5308
|
+
description: audit.description,
|
|
5309
|
+
score: getOr(fromNullable(audit.score), 0),
|
|
5310
|
+
displayValue: audit.displayValue
|
|
5311
|
+
}));
|
|
5312
|
+
}
|
|
5313
|
+
function processLhr(lhr) {
|
|
5314
|
+
let categories = filterMap(categoryIds, (id) => lhr.categories[id]).map((category) => {
|
|
5315
|
+
let s2 = category.score;
|
|
5316
|
+
let score = !(s2 == null) ? Math.round(s2 * 100) | 0 : 0;
|
|
5317
|
+
let topIssues = getTopIssues(category, lhr.audits, 3);
|
|
5318
|
+
return {
|
|
5319
|
+
id: category.id,
|
|
5320
|
+
title: category.title,
|
|
5321
|
+
score,
|
|
5322
|
+
topIssues
|
|
5323
|
+
};
|
|
5324
|
+
});
|
|
5325
|
+
let totalScore = reduce(categories, 0, (acc, cat) => acc + cat.score | 0);
|
|
5326
|
+
let len = categories.length;
|
|
5327
|
+
let overallScore = len !== 0 ? div(totalScore, len) : 0;
|
|
5328
|
+
return {
|
|
5329
|
+
url: lhr.finalDisplayedUrl,
|
|
5330
|
+
fetchTime: lhr.fetchTime,
|
|
5331
|
+
categories,
|
|
5332
|
+
overallScore,
|
|
5333
|
+
warnings: lhr.runWarnings
|
|
5334
|
+
};
|
|
5335
|
+
}
|
|
5336
|
+
async function killChrome(chrome) {
|
|
5337
|
+
try {
|
|
5338
|
+
return await chrome.kill();
|
|
5339
|
+
} catch (exn) {
|
|
5340
|
+
return;
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5343
|
+
async function runLighthouse(chrome, url2, preset) {
|
|
5344
|
+
let port2 = chrome.port;
|
|
5345
|
+
let flags_port = port2;
|
|
5346
|
+
let flags_output = "json";
|
|
5347
|
+
let flags_logLevel = "error";
|
|
5348
|
+
let flags_onlyCategories = categoryIds;
|
|
5349
|
+
let flags_formFactor = preset;
|
|
5350
|
+
let flags_screenEmulation = {
|
|
5351
|
+
disabled: preset === "desktop"
|
|
5352
|
+
};
|
|
5353
|
+
let flags_throttlingMethod = "simulate";
|
|
5354
|
+
let flags2 = {
|
|
5355
|
+
port: flags_port,
|
|
5356
|
+
output: flags_output,
|
|
5357
|
+
logLevel: flags_logLevel,
|
|
5358
|
+
onlyCategories: flags_onlyCategories,
|
|
5359
|
+
formFactor: flags_formFactor,
|
|
5360
|
+
screenEmulation: flags_screenEmulation,
|
|
5361
|
+
throttlingMethod: flags_throttlingMethod
|
|
5362
|
+
};
|
|
5363
|
+
try {
|
|
5364
|
+
let runnerResult = await run(url2, flags2);
|
|
5365
|
+
await killChrome(chrome);
|
|
5366
|
+
if (runnerResult == null) {
|
|
5367
|
+
return {
|
|
5368
|
+
TAG: "Error",
|
|
5369
|
+
_0: "Lighthouse returned no results. The URL may be unreachable."
|
|
5370
|
+
};
|
|
5371
|
+
} else {
|
|
5372
|
+
return {
|
|
5373
|
+
TAG: "Ok",
|
|
5374
|
+
_0: processLhr(runnerResult.lhr)
|
|
5375
|
+
};
|
|
5376
|
+
}
|
|
5377
|
+
} catch (raw_exn) {
|
|
5378
|
+
let exn = internalToException(raw_exn);
|
|
5379
|
+
await killChrome(chrome);
|
|
5380
|
+
let msg = getErrorMessage(exn);
|
|
5381
|
+
return {
|
|
5382
|
+
TAG: "Error",
|
|
5383
|
+
_0: `Lighthouse audit failed: ` + msg
|
|
5384
|
+
};
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
async function execute6(_ctx, input) {
|
|
5388
|
+
let preset = getOr(input.preset, "desktop");
|
|
5389
|
+
let auditUrl = rewriteUrlForRuntime(input.url);
|
|
5390
|
+
switch (preset) {
|
|
5391
|
+
case "desktop":
|
|
5392
|
+
case "mobile":
|
|
5393
|
+
break;
|
|
5394
|
+
default:
|
|
5395
|
+
return {
|
|
5396
|
+
TAG: "Error",
|
|
5397
|
+
_0: `Invalid preset "` + preset + `". Must be "desktop" or "mobile".`
|
|
5398
|
+
};
|
|
5399
|
+
}
|
|
5400
|
+
try {
|
|
5401
|
+
let chrome = await launch({
|
|
5402
|
+
chromeFlags: [
|
|
5403
|
+
"--headless",
|
|
5404
|
+
"--disable-gpu",
|
|
5405
|
+
"--no-sandbox",
|
|
5406
|
+
"--disable-dev-shm-usage"
|
|
5407
|
+
]
|
|
5408
|
+
});
|
|
5409
|
+
let result = await runLighthouse(chrome, auditUrl, preset);
|
|
5410
|
+
if (result.TAG !== "Ok") {
|
|
5411
|
+
return result;
|
|
5412
|
+
}
|
|
5413
|
+
let out = result._0;
|
|
5414
|
+
if (auditUrl === input.url) {
|
|
5415
|
+
return {
|
|
5416
|
+
TAG: "Ok",
|
|
5417
|
+
_0: out
|
|
5418
|
+
};
|
|
5419
|
+
}
|
|
5420
|
+
let warning = `DevPod mode: audited local URL ` + auditUrl + ` instead of ` + input.url + `.`;
|
|
5421
|
+
return {
|
|
5422
|
+
TAG: "Ok",
|
|
5423
|
+
_0: {
|
|
5424
|
+
url: input.url,
|
|
5425
|
+
fetchTime: out.fetchTime,
|
|
5426
|
+
categories: out.categories,
|
|
5427
|
+
overallScore: out.overallScore,
|
|
5428
|
+
warnings: concatMany([
|
|
5429
|
+
[warning],
|
|
5430
|
+
out.warnings
|
|
5431
|
+
])
|
|
5432
|
+
}
|
|
5433
|
+
};
|
|
5434
|
+
} catch (raw_exn) {
|
|
5435
|
+
let exn = internalToException(raw_exn);
|
|
5436
|
+
let msg = getErrorMessage(exn);
|
|
5437
|
+
return {
|
|
5438
|
+
TAG: "Error",
|
|
5439
|
+
_0: `Failed to launch Chrome: ` + msg + `. Make sure Chrome is installed on the system.`
|
|
5440
|
+
};
|
|
5441
|
+
}
|
|
5442
|
+
}
|
|
5443
|
+
var name7 = "lighthouse";
|
|
5444
|
+
var description6 = `Runs a Lighthouse audit on a URL to analyze performance, accessibility, best practices, and SEO.
|
|
5445
|
+
|
|
5446
|
+
WHEN TO USE THIS TOOL:
|
|
5447
|
+
- After making changes that might affect page load performance
|
|
5448
|
+
- When implementing new UI components to check accessibility
|
|
5449
|
+
- Before deploying to verify web best practices
|
|
5450
|
+
- To diagnose why a page feels slow
|
|
5451
|
+
|
|
5452
|
+
PARAMETERS:
|
|
5453
|
+
- url (required): The full URL to audit (e.g., "http://localhost:3000/")
|
|
5454
|
+
- preset (optional): "desktop" (default) or "mobile" for mobile emulation
|
|
5455
|
+
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.
|
|
5456
|
+
|
|
5457
|
+
OUTPUT:
|
|
5458
|
+
Returns scores (0-100) for each category plus the top 3 issues to fix in each category.
|
|
5459
|
+
Higher scores are better. Issues include actionable descriptions.
|
|
5460
|
+
|
|
5461
|
+
LIMITATIONS:
|
|
5462
|
+
- Requires Chrome to be installed on the system
|
|
5463
|
+
- Takes 15-30 seconds to complete
|
|
5464
|
+
- Results can vary between runs (\xB15 points is normal)
|
|
5465
|
+
- URL must be accessible from the machine running the audit`;
|
|
5466
|
+
var name8 = ToolNames.searchFiles;
|
|
5467
|
+
var inputSchema7 = schema2((s2) => ({
|
|
4867
5468
|
pattern: s2.m(string2),
|
|
4868
5469
|
path: s2.m(option2(string2)),
|
|
4869
5470
|
max_results: s2.m(option2(int2))
|
|
4870
5471
|
}));
|
|
4871
|
-
var
|
|
5472
|
+
var outputSchema7 = schema2((s2) => ({
|
|
4872
5473
|
files: s2.m(array2(string2)),
|
|
4873
5474
|
totalResults: s2.m(int2),
|
|
4874
5475
|
truncated: s2.m(bool2)
|
|
@@ -4982,7 +5583,7 @@ async function executeGitLsFiles(pattern2, searchPath, maxResults) {
|
|
|
4982
5583
|
_0: `Git ls-files failed: ` + match.stderr
|
|
4983
5584
|
};
|
|
4984
5585
|
}
|
|
4985
|
-
async function
|
|
5586
|
+
async function execute7(ctx2, input) {
|
|
4986
5587
|
let searchPath = resolveSearchPath(ctx2.sourceRoot, input.path);
|
|
4987
5588
|
let maxResults = getOr(input.max_results, 20);
|
|
4988
5589
|
let rgPath = getRipgrepPath2();
|
|
@@ -4996,8 +5597,7 @@ async function execute6(ctx2, input) {
|
|
|
4996
5597
|
return await executeGitLsFiles(input.pattern, searchPath, maxResults);
|
|
4997
5598
|
}
|
|
4998
5599
|
}
|
|
4999
|
-
var
|
|
5000
|
-
var description6 = `Fast file name search tool that finds files matching a pattern.
|
|
5600
|
+
var description7 = `Fast file name search tool that finds files matching a pattern.
|
|
5001
5601
|
|
|
5002
5602
|
WHEN TO USE THIS TOOL:
|
|
5003
5603
|
- Use when you need to find files by name pattern
|
|
@@ -5025,14 +5625,15 @@ LIMITATIONS:
|
|
|
5025
5625
|
- Hidden files (starting with '.') are included
|
|
5026
5626
|
- Respects .gitignore when using git ls-files fallback
|
|
5027
5627
|
- Only finds files, not directories`;
|
|
5028
|
-
var
|
|
5628
|
+
var name9 = ToolNames.loadAgentInstructions;
|
|
5629
|
+
var inputSchema8 = schema2((s2) => ({
|
|
5029
5630
|
startPath: s2.m(option2(string2))
|
|
5030
5631
|
}));
|
|
5031
5632
|
var instructionFileSchema = schema2((s2) => ({
|
|
5032
5633
|
content: s2.m(string2),
|
|
5033
5634
|
fullPath: s2.m(string2)
|
|
5034
5635
|
}));
|
|
5035
|
-
var
|
|
5636
|
+
var outputSchema8 = array2(instructionFileSchema);
|
|
5036
5637
|
var agentsVariants = [
|
|
5037
5638
|
"Agents.md",
|
|
5038
5639
|
".claude/Agents.md",
|
|
@@ -5045,7 +5646,7 @@ var claudeVariants = [
|
|
|
5045
5646
|
];
|
|
5046
5647
|
async function findFileCaseInsensitive(dir, targetFileName) {
|
|
5047
5648
|
try {
|
|
5048
|
-
let files = await
|
|
5649
|
+
let files = await Fs3.promises.readdir(dir);
|
|
5049
5650
|
let targetLower = targetFileName.toLowerCase();
|
|
5050
5651
|
let found = files.find((file) => file.toLowerCase() === targetLower);
|
|
5051
5652
|
if (found !== void 0) {
|
|
@@ -5065,7 +5666,7 @@ async function loadIfExists(path) {
|
|
|
5065
5666
|
return;
|
|
5066
5667
|
}
|
|
5067
5668
|
try {
|
|
5068
|
-
let content = await
|
|
5669
|
+
let content = await Fs3.promises.readFile(actualPath, "utf8");
|
|
5069
5670
|
return {
|
|
5070
5671
|
content,
|
|
5071
5672
|
fullPath: actualPath
|
|
@@ -5102,7 +5703,7 @@ async function walkUpDirectories(current, acc) {
|
|
|
5102
5703
|
let newAcc = acc.concat(filesAtLevel);
|
|
5103
5704
|
return await walkUpDirectories(Nodepath.dirname(current), newAcc);
|
|
5104
5705
|
}
|
|
5105
|
-
async function
|
|
5706
|
+
async function execute8(ctx2, input) {
|
|
5106
5707
|
let inputPath = getOr(input.startPath, ".");
|
|
5107
5708
|
let msg = resolve(ctx2.sourceRoot, inputPath);
|
|
5108
5709
|
if (msg.TAG !== "Ok") {
|
|
@@ -5127,8 +5728,7 @@ async function execute7(ctx2, input) {
|
|
|
5127
5728
|
};
|
|
5128
5729
|
}
|
|
5129
5730
|
}
|
|
5130
|
-
var
|
|
5131
|
-
var description7 = `Discovers and loads agent instruction files (Agents.md or CLAUDE.md) following Claude Code's discovery algorithm.
|
|
5731
|
+
var description8 = `Discovers and loads agent instruction files (Agents.md or CLAUDE.md) following Claude Code's discovery algorithm.
|
|
5132
5732
|
|
|
5133
5733
|
Parameters:
|
|
5134
5734
|
- startPath (optional): Starting directory for discovery - must be under source root. Defaults to "." (source root).
|
|
@@ -5178,11 +5778,11 @@ function coreTools() {
|
|
|
5178
5778
|
visibleToAgent: true
|
|
5179
5779
|
},
|
|
5180
5780
|
{
|
|
5181
|
-
name:
|
|
5182
|
-
description:
|
|
5183
|
-
inputSchema:
|
|
5184
|
-
outputSchema:
|
|
5185
|
-
execute:
|
|
5781
|
+
name: name9,
|
|
5782
|
+
description: description8,
|
|
5783
|
+
inputSchema: inputSchema8,
|
|
5784
|
+
outputSchema: outputSchema8,
|
|
5785
|
+
execute: execute8,
|
|
5186
5786
|
visibleToAgent: false
|
|
5187
5787
|
},
|
|
5188
5788
|
{
|
|
@@ -5193,6 +5793,14 @@ function coreTools() {
|
|
|
5193
5793
|
execute,
|
|
5194
5794
|
visibleToAgent: true
|
|
5195
5795
|
},
|
|
5796
|
+
{
|
|
5797
|
+
name: name8,
|
|
5798
|
+
description: description7,
|
|
5799
|
+
inputSchema: inputSchema7,
|
|
5800
|
+
outputSchema: outputSchema7,
|
|
5801
|
+
execute: execute7,
|
|
5802
|
+
visibleToAgent: true
|
|
5803
|
+
},
|
|
5196
5804
|
{
|
|
5197
5805
|
name: name7,
|
|
5198
5806
|
description: description6,
|
|
@@ -5209,8 +5817,8 @@ function addTools(registry, newTools) {
|
|
|
5209
5817
|
tools: registry.tools.concat(newTools)
|
|
5210
5818
|
};
|
|
5211
5819
|
}
|
|
5212
|
-
function getToolByName(registry,
|
|
5213
|
-
return registry.tools.find((m) => m.name ===
|
|
5820
|
+
function getToolByName(registry, name11) {
|
|
5821
|
+
return registry.tools.find((m) => m.name === name11);
|
|
5214
5822
|
}
|
|
5215
5823
|
function serializeTool(m) {
|
|
5216
5824
|
return {
|
|
@@ -5243,12 +5851,12 @@ var toolCallRequestSchema = schema2((s2) => ({
|
|
|
5243
5851
|
var protocolVersion = "1.0";
|
|
5244
5852
|
|
|
5245
5853
|
// ../frontman-core/src/FrontmanCore__Server.res.mjs
|
|
5246
|
-
async function executeTool(registry, ctx2,
|
|
5247
|
-
let toolModule = getToolByName(registry,
|
|
5854
|
+
async function executeTool(registry, ctx2, name11, $$arguments) {
|
|
5855
|
+
let toolModule = getToolByName(registry, name11);
|
|
5248
5856
|
if (toolModule === void 0) {
|
|
5249
5857
|
return {
|
|
5250
5858
|
TAG: "ToolNotFound",
|
|
5251
|
-
_0:
|
|
5859
|
+
_0: name11
|
|
5252
5860
|
};
|
|
5253
5861
|
}
|
|
5254
5862
|
let toolCtx_projectRoot = ctx2.projectRoot;
|
|
@@ -5516,7 +6124,7 @@ var dynamicTypeSchema = union2([
|
|
|
5516
6124
|
literal2("rest"),
|
|
5517
6125
|
literal2("optional")
|
|
5518
6126
|
]);
|
|
5519
|
-
var
|
|
6127
|
+
var inputSchema9 = schema2((s2) => ({
|
|
5520
6128
|
placeholder: s2.m(option2(bool2))
|
|
5521
6129
|
}));
|
|
5522
6130
|
var pageSchema = schema2((s2) => ({
|
|
@@ -5525,7 +6133,7 @@ var pageSchema = schema2((s2) => ({
|
|
|
5525
6133
|
isDynamic: s2.m(bool2),
|
|
5526
6134
|
dynamicType: s2.m(dynamicTypeSchema)
|
|
5527
6135
|
}));
|
|
5528
|
-
var
|
|
6136
|
+
var outputSchema9 = array2(pageSchema);
|
|
5529
6137
|
function analyzeDynamicSegment(segment) {
|
|
5530
6138
|
if (segment.startsWith("[[") && segment.endsWith("]]")) {
|
|
5531
6139
|
return "optional";
|
|
@@ -5580,10 +6188,10 @@ function getMostSignificantDynamicType(segments) {
|
|
|
5580
6188
|
async function findPages(baseDir, currentPath, projectRoot, sourceRoot) {
|
|
5581
6189
|
let fullPath = Nodepath.join(projectRoot, baseDir, currentPath);
|
|
5582
6190
|
try {
|
|
5583
|
-
let entries = await
|
|
6191
|
+
let entries = await Fs3.promises.readdir(fullPath);
|
|
5584
6192
|
return (await Promise.all(entries.map(async (entry) => {
|
|
5585
6193
|
let entryPath = Nodepath.join(fullPath, entry);
|
|
5586
|
-
let stats = await
|
|
6194
|
+
let stats = await Fs3.promises.lstat(entryPath);
|
|
5587
6195
|
if (stats.isSymbolicLink()) {
|
|
5588
6196
|
return [];
|
|
5589
6197
|
}
|
|
@@ -5620,7 +6228,7 @@ async function findPages(baseDir, currentPath, projectRoot, sourceRoot) {
|
|
|
5620
6228
|
throw exn;
|
|
5621
6229
|
}
|
|
5622
6230
|
}
|
|
5623
|
-
async function
|
|
6231
|
+
async function execute9(ctx2, _input) {
|
|
5624
6232
|
try {
|
|
5625
6233
|
let srcPages = await findPages("src/pages", "", ctx2.projectRoot, ctx2.sourceRoot);
|
|
5626
6234
|
let rootPages = await findPages("pages", "", ctx2.projectRoot, ctx2.sourceRoot);
|
|
@@ -5638,8 +6246,8 @@ async function execute8(ctx2, _input) {
|
|
|
5638
6246
|
};
|
|
5639
6247
|
}
|
|
5640
6248
|
}
|
|
5641
|
-
var
|
|
5642
|
-
var
|
|
6249
|
+
var name10 = "get_client_pages";
|
|
6250
|
+
var description9 = `Lists Astro client pages from the pages directory.
|
|
5643
6251
|
|
|
5644
6252
|
Parameters: None
|
|
5645
6253
|
|
|
@@ -5648,11 +6256,11 @@ Excludes API routes (src/pages/api/) - focuses on renderable pages only.`;
|
|
|
5648
6256
|
|
|
5649
6257
|
// src/FrontmanAstro__ToolRegistry.res.mjs
|
|
5650
6258
|
var astroTools = [{
|
|
5651
|
-
name:
|
|
5652
|
-
description:
|
|
5653
|
-
inputSchema:
|
|
5654
|
-
outputSchema:
|
|
5655
|
-
execute:
|
|
6259
|
+
name: name10,
|
|
6260
|
+
description: description9,
|
|
6261
|
+
inputSchema: inputSchema9,
|
|
6262
|
+
outputSchema: outputSchema9,
|
|
6263
|
+
execute: execute9,
|
|
5656
6264
|
visibleToAgent: true
|
|
5657
6265
|
}];
|
|
5658
6266
|
function make2() {
|
|
@@ -5750,8 +6358,8 @@ var collectRequestBody = (async function(req) {
|
|
|
5750
6358
|
for await (const chunk of req) {
|
|
5751
6359
|
chunks.push(chunk);
|
|
5752
6360
|
}
|
|
5753
|
-
const { Buffer:
|
|
5754
|
-
return
|
|
6361
|
+
const { Buffer: Buffer4 } = await import('buffer');
|
|
6362
|
+
return Buffer4.concat(chunks);
|
|
5755
6363
|
});
|
|
5756
6364
|
|
|
5757
6365
|
// src/FrontmanAstro__ViteAdapter.res.mjs
|
|
@@ -5843,36 +6451,11 @@ function adaptToConnect(middleware, basePath) {
|
|
|
5843
6451
|
}
|
|
5844
6452
|
|
|
5845
6453
|
// src/FrontmanAstro__Integration.res.mjs
|
|
6454
|
+
var annotationCaptureScript2 = annotationCaptureScript;
|
|
5846
6455
|
var icon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3"/></svg>`;
|
|
5847
6456
|
function getToolbarAppPath() {
|
|
5848
6457
|
return new URL("./toolbar.js", import.meta.url).pathname;
|
|
5849
6458
|
}
|
|
5850
|
-
var annotationCaptureScript = `(function() {
|
|
5851
|
-
function captureAnnotations() {
|
|
5852
|
-
var annotations = new Map();
|
|
5853
|
-
document.querySelectorAll('[data-astro-source-file]').forEach(function(el) {
|
|
5854
|
-
annotations.set(el, {
|
|
5855
|
-
file: el.getAttribute('data-astro-source-file'),
|
|
5856
|
-
loc: el.getAttribute('data-astro-source-loc')
|
|
5857
|
-
});
|
|
5858
|
-
});
|
|
5859
|
-
window.__frontman_annotations__ = {
|
|
5860
|
-
_map: annotations,
|
|
5861
|
-
get: function(el) { return annotations.get(el); },
|
|
5862
|
-
has: function(el) { return annotations.has(el); },
|
|
5863
|
-
size: function() { return annotations.size; }
|
|
5864
|
-
};
|
|
5865
|
-
}
|
|
5866
|
-
// Capture once on initial DOM parse
|
|
5867
|
-
document.addEventListener('DOMContentLoaded', captureAnnotations);
|
|
5868
|
-
// Re-capture on View Transitions (SPA navigations) \u2014 skips the initial
|
|
5869
|
-
// page-load event since DOMContentLoaded already captured
|
|
5870
|
-
var initialLoad = true;
|
|
5871
|
-
document.addEventListener('astro:page-load', function() {
|
|
5872
|
-
if (initialLoad) { initialLoad = false; return; }
|
|
5873
|
-
captureAnnotations();
|
|
5874
|
-
});
|
|
5875
|
-
})();`;
|
|
5876
6459
|
function make3(configInput) {
|
|
5877
6460
|
let config = makeFromObject(configInput);
|
|
5878
6461
|
return {
|
|
@@ -5883,13 +6466,18 @@ function make3(configInput) {
|
|
|
5883
6466
|
if (!ctx2.config.devToolbar.enabled) {
|
|
5884
6467
|
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.");
|
|
5885
6468
|
}
|
|
6469
|
+
ctx2.updateConfig({
|
|
6470
|
+
vite: {
|
|
6471
|
+
plugins: [frontmanPropsInjectionPlugin()]
|
|
6472
|
+
}
|
|
6473
|
+
});
|
|
5886
6474
|
ctx2.addDevToolbarApp({
|
|
5887
6475
|
id: "frontman:toolbar",
|
|
5888
6476
|
name: "Frontman",
|
|
5889
6477
|
icon,
|
|
5890
6478
|
entrypoint: getToolbarAppPath()
|
|
5891
6479
|
});
|
|
5892
|
-
return ctx2.injectScript("head-inline",
|
|
6480
|
+
return ctx2.injectScript("head-inline", annotationCaptureScript2);
|
|
5893
6481
|
}
|
|
5894
6482
|
},
|
|
5895
6483
|
"astro:server:setup": (param) => {
|