@frontman-ai/astro 0.1.4 → 0.1.6
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/README.md +65 -24
- package/dist/index.js +177 -70
- package/dist/integration.js +5815 -5
- package/index.d.ts +81 -0
- package/package.json +17 -8
- package/dist/cli.js +0 -2744
package/README.md
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
# @frontman-ai/astro
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@frontman-ai/astro)
|
|
4
|
+
[](https://astro.build)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Astro integration for [Frontman](https://frontman.sh) — AI-powered development tools that let you edit your frontend from the browser.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- [Astro](https://astro.build) 5.0+
|
|
9
|
-
- HTTP middleware integration
|
|
10
|
-
- SSE (Server-Sent Events) for streaming responses
|
|
11
|
-
|
|
12
|
-
## Features
|
|
8
|
+
## Installation
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- Streaming responses via SSE
|
|
10
|
+
```bash
|
|
11
|
+
npx astro add @frontman-ai/astro
|
|
12
|
+
```
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
Or manually:
|
|
20
15
|
|
|
21
16
|
```bash
|
|
22
17
|
npm install @frontman-ai/astro
|
|
@@ -28,26 +23,72 @@ Add the integration to your `astro.config.mjs`:
|
|
|
28
23
|
|
|
29
24
|
```javascript
|
|
30
25
|
import { defineConfig } from 'astro/config';
|
|
31
|
-
import
|
|
26
|
+
import frontman from '@frontman-ai/astro';
|
|
32
27
|
|
|
33
28
|
export default defineConfig({
|
|
34
29
|
integrations: [
|
|
35
|
-
|
|
30
|
+
frontman({ projectRoot: import.meta.dirname }),
|
|
36
31
|
],
|
|
37
32
|
});
|
|
38
33
|
```
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
Then start your dev server and open `http://localhost:4321/frontman/`.
|
|
36
|
+
|
|
37
|
+
## What it does
|
|
38
|
+
|
|
39
|
+
The integration automatically (in dev mode only):
|
|
40
|
+
|
|
41
|
+
- Registers a dev toolbar app for element selection
|
|
42
|
+
- Captures Astro source annotations so the AI knows which `.astro` file and line each element comes from
|
|
43
|
+
- Serves the Frontman UI at `/<basePath>/` (default: `/frontman/`)
|
|
44
|
+
- Exposes tool endpoints for AI interactions (file edits, screenshots, etc.)
|
|
45
|
+
|
|
46
|
+
> **Note:** Element source detection requires `devToolbar.enabled: true` (the default). Astro only emits `data-astro-source-file` / `data-astro-source-loc` annotations when the dev toolbar is enabled. If you've disabled it, Frontman will log a warning and fall back to CSS selector-based detection.
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
All options are optional with sensible defaults:
|
|
51
|
+
|
|
52
|
+
| Option | Default | Description |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `projectRoot` | `PROJECT_ROOT` env var, `PWD`, or `"."` | Path to the project root directory |
|
|
55
|
+
| `sourceRoot` | Same as `projectRoot` | Root for source file resolution (useful in monorepos) |
|
|
56
|
+
| `basePath` | `"frontman"` | URL prefix for Frontman routes |
|
|
57
|
+
| `host` | `FRONTMAN_HOST` env var or `"api.frontman.sh"` | Frontman server host for client connections |
|
|
58
|
+
| `serverName` | `"frontman-astro"` | Server name included in tool responses |
|
|
59
|
+
| `serverVersion` | `"1.0.0"` | Server version included in tool responses |
|
|
60
|
+
| `clientUrl` | Auto-generated from `host` | URL to the Frontman client bundle (must include a `host` query parameter) |
|
|
61
|
+
| `isLightTheme` | `false` | Use a light theme for the Frontman UI |
|
|
62
|
+
|
|
63
|
+
### Environment variables
|
|
64
|
+
|
|
65
|
+
| Variable | Description |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `FRONTMAN_HOST` | Override the default server host without changing config |
|
|
68
|
+
| `PROJECT_ROOT` | Override the project root path |
|
|
69
|
+
| `FRONTMAN_CLIENT_URL` | Override the client bundle URL |
|
|
70
|
+
|
|
71
|
+
## How it works
|
|
72
|
+
|
|
73
|
+
The integration uses two Astro hooks:
|
|
74
|
+
|
|
75
|
+
- **`astro:config:setup`** — Registers the dev toolbar app and injects the annotation capture script via `injectScript('head-inline', ...)`
|
|
76
|
+
- **`astro:server:setup`** — Registers Frontman API routes as Vite dev server middleware via `server.middlewares.use()`
|
|
77
|
+
|
|
78
|
+
No manual middleware file needed. No SSR adapter required. Works with static (`output: 'static'`) Astro projects.
|
|
79
|
+
|
|
80
|
+
## Requirements
|
|
41
81
|
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- `./toolbar` - Dev toolbar app component
|
|
82
|
+
- Astro ^5.0.0
|
|
83
|
+
- Node.js >= 18
|
|
45
84
|
|
|
46
|
-
##
|
|
85
|
+
## Links
|
|
47
86
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
87
|
+
- [Website](https://frontman.sh)
|
|
88
|
+
- [Documentation](https://frontman.sh/docs/astro)
|
|
89
|
+
- [Changelog](https://github.com/frontman-ai/frontman/blob/main/CHANGELOG.md)
|
|
90
|
+
- [Issues](https://github.com/frontman-ai/frontman/issues)
|
|
50
91
|
|
|
51
|
-
##
|
|
92
|
+
## License
|
|
52
93
|
|
|
53
|
-
|
|
94
|
+
[Apache-2.0](https://github.com/frontman-ai/frontman/blob/main/LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -24,11 +24,6 @@ var require_lib = __commonJS({
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
// ../../node_modules/@rescript/runtime/lib/es6/Stdlib_JsError.js
|
|
28
|
-
function throwWithMessage(str) {
|
|
29
|
-
throw new Error(str);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
27
|
// ../../node_modules/@rescript/runtime/lib/es6/Primitive_option.js
|
|
33
28
|
function some(x) {
|
|
34
29
|
if (x === void 0) {
|
|
@@ -95,25 +90,39 @@ function orElse(opt, other) {
|
|
|
95
90
|
}
|
|
96
91
|
}
|
|
97
92
|
|
|
93
|
+
// ../frontman-core/src/FrontmanCore__Hosts.res.mjs
|
|
94
|
+
var apiHost = "api.frontman.sh";
|
|
95
|
+
var clientJs = "https://app.frontman.sh/frontman.es.js";
|
|
96
|
+
var clientCss = "https://app.frontman.sh/frontman.css";
|
|
97
|
+
var devClientJs = "http://localhost:5173/src/Main.res.mjs";
|
|
98
|
+
|
|
98
99
|
// src/FrontmanAstro__Config.res.mjs
|
|
99
100
|
var host = process.env["FRONTMAN_HOST"];
|
|
100
|
-
var defaultHost = host !== void 0 ? host :
|
|
101
|
-
|
|
101
|
+
var defaultHost = host !== void 0 ? host : apiHost;
|
|
102
|
+
var ensureConfig = (function(c2) {
|
|
103
|
+
return c2 || {};
|
|
104
|
+
});
|
|
105
|
+
function makeFromObject(rawConfig) {
|
|
106
|
+
let config = ensureConfig(rawConfig);
|
|
107
|
+
let host2 = getOr(config.host, defaultHost);
|
|
108
|
+
let isDev = host2 !== apiHost;
|
|
102
109
|
let projectRoot = getOr(orElse(config.projectRoot, orElse(process.env["PROJECT_ROOT"], process.env["PWD"])), ".");
|
|
103
110
|
let sourceRoot = getOr(config.sourceRoot, projectRoot);
|
|
104
111
|
let basePath = getOr(config.basePath, "frontman");
|
|
105
112
|
let serverName = getOr(config.serverName, "frontman-astro");
|
|
106
113
|
let serverVersion = getOr(config.serverVersion, "1.0.0");
|
|
107
114
|
let isLightTheme = getOr(config.isLightTheme, false);
|
|
108
|
-
let
|
|
109
|
-
let baseUrl = getOr(process.env["FRONTMAN_CLIENT_URL"], "http://localhost:5173/src/Main.res.mjs");
|
|
115
|
+
let baseUrl = getOr(config.clientUrl, getOr(process.env["FRONTMAN_CLIENT_URL"], isDev ? devClientJs : clientJs));
|
|
110
116
|
let url2 = new URL(baseUrl);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
if (url2.searchParams.has("clientName")) ; else {
|
|
118
|
+
url2.searchParams.set("clientName", "astro");
|
|
119
|
+
}
|
|
120
|
+
if (url2.searchParams.has("host")) ; else {
|
|
121
|
+
url2.searchParams.set("host", host2);
|
|
115
122
|
}
|
|
123
|
+
let clientUrl = url2.href;
|
|
116
124
|
return {
|
|
125
|
+
isDev,
|
|
117
126
|
projectRoot,
|
|
118
127
|
sourceRoot,
|
|
119
128
|
basePath,
|
|
@@ -121,6 +130,7 @@ function makeFromObject(config) {
|
|
|
121
130
|
serverVersion,
|
|
122
131
|
host: host2,
|
|
123
132
|
clientUrl,
|
|
133
|
+
clientCssUrl: orElse(config.clientCssUrl, isDev ? void 0 : clientCss),
|
|
124
134
|
isLightTheme
|
|
125
135
|
};
|
|
126
136
|
}
|
|
@@ -699,14 +709,14 @@ function withPathPrepend(b, input, path, maybeDynamicLocationVar, appendSafe, fn
|
|
|
699
709
|
return fn(b, input, path);
|
|
700
710
|
}
|
|
701
711
|
try {
|
|
702
|
-
let $$
|
|
712
|
+
let $$catch2 = (b2, errorVar2) => {
|
|
703
713
|
b2.c = errorVar2 + `.path=` + fromString(path) + `+` + (maybeDynamicLocationVar !== void 0 ? `'["'+` + maybeDynamicLocationVar + `+'"]'+` : "") + errorVar2 + `.path`;
|
|
704
714
|
};
|
|
705
715
|
let fn$1 = (b2) => fn(b2, input, "");
|
|
706
716
|
let prevCode = b.c;
|
|
707
717
|
b.c = "";
|
|
708
718
|
let errorVar = varWithoutAllocation(b.g);
|
|
709
|
-
let maybeResolveVal = $$
|
|
719
|
+
let maybeResolveVal = $$catch2(b, errorVar);
|
|
710
720
|
let catchCode = `if(` + (errorVar + `&&` + errorVar + `.s===s`) + `){` + b.c;
|
|
711
721
|
b.c = "";
|
|
712
722
|
let bb = {
|
|
@@ -5577,42 +5587,7 @@ function make2() {
|
|
|
5577
5587
|
}
|
|
5578
5588
|
|
|
5579
5589
|
// src/FrontmanAstro__Middleware.res.mjs
|
|
5580
|
-
|
|
5581
|
-
<script>
|
|
5582
|
-
(function() {
|
|
5583
|
-
var annotations = new Map();
|
|
5584
|
-
document.querySelectorAll('[data-astro-source-file]').forEach(function(el) {
|
|
5585
|
-
annotations.set(el, {
|
|
5586
|
-
file: el.getAttribute('data-astro-source-file'),
|
|
5587
|
-
loc: el.getAttribute('data-astro-source-loc')
|
|
5588
|
-
});
|
|
5589
|
-
});
|
|
5590
|
-
window.__frontman_annotations__ = {
|
|
5591
|
-
_map: annotations,
|
|
5592
|
-
get: function(el) { return annotations.get(el); },
|
|
5593
|
-
has: function(el) { return annotations.has(el); },
|
|
5594
|
-
size: function() { return annotations.size; }
|
|
5595
|
-
};
|
|
5596
|
-
console.log('[Frontman] Captured ' + annotations.size + ' elements');
|
|
5597
|
-
})();
|
|
5598
|
-
</script>
|
|
5599
|
-
`;
|
|
5600
|
-
async function injectAnnotationScript(response) {
|
|
5601
|
-
let contentType = response.headers.get("content-type");
|
|
5602
|
-
if (contentType === null) {
|
|
5603
|
-
return response;
|
|
5604
|
-
}
|
|
5605
|
-
if (!contentType.includes("text/html")) {
|
|
5606
|
-
return response;
|
|
5607
|
-
}
|
|
5608
|
-
let html = await response.text();
|
|
5609
|
-
let injectedHtml = html.replace("</body>", annotationCaptureScript + `</body>`);
|
|
5610
|
-
return new Response(injectedHtml, {
|
|
5611
|
-
status: response.status,
|
|
5612
|
-
headers: some(response.headers)
|
|
5613
|
-
});
|
|
5614
|
-
}
|
|
5615
|
-
function uiHtml(clientUrl, isLightTheme) {
|
|
5590
|
+
function uiHtml(clientUrl, clientCssUrl, isLightTheme) {
|
|
5616
5591
|
let openrouterKey = flatMap(process.env["OPENROUTER_API_KEY"], (key) => {
|
|
5617
5592
|
if (key !== "") {
|
|
5618
5593
|
return key;
|
|
@@ -5627,12 +5602,14 @@ function uiHtml(clientUrl, isLightTheme) {
|
|
|
5627
5602
|
});
|
|
5628
5603
|
let runtimeConfig = JSON.stringify(configObj);
|
|
5629
5604
|
let themeClass = isLightTheme ? "" : "dark";
|
|
5605
|
+
let cssLink = clientCssUrl !== void 0 ? `<link rel="stylesheet" href="` + clientCssUrl + `">` : "";
|
|
5630
5606
|
return `<!DOCTYPE html>
|
|
5631
5607
|
<html lang="en" class="` + themeClass + `">
|
|
5632
5608
|
<head>
|
|
5633
5609
|
<meta charset="UTF-8">
|
|
5634
5610
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5635
5611
|
<title>Frontman</title>
|
|
5612
|
+
` + cssLink + `
|
|
5636
5613
|
<style>
|
|
5637
5614
|
html, body, #root {
|
|
5638
5615
|
margin: 0;
|
|
@@ -5650,7 +5627,7 @@ function uiHtml(clientUrl, isLightTheme) {
|
|
|
5650
5627
|
</html>`;
|
|
5651
5628
|
}
|
|
5652
5629
|
function serveUI(config) {
|
|
5653
|
-
let html = uiHtml(config.clientUrl, config.isLightTheme);
|
|
5630
|
+
let html = uiHtml(config.clientUrl, config.clientCssUrl, config.isLightTheme);
|
|
5654
5631
|
let headers2 = Object.fromEntries([[
|
|
5655
5632
|
"Content-Type",
|
|
5656
5633
|
"text/html"
|
|
@@ -5661,9 +5638,10 @@ function serveUI(config) {
|
|
|
5661
5638
|
}
|
|
5662
5639
|
function createMiddleware(config) {
|
|
5663
5640
|
let registry = make2();
|
|
5664
|
-
return async (
|
|
5665
|
-
let
|
|
5666
|
-
let
|
|
5641
|
+
return async (request) => {
|
|
5642
|
+
let url2 = new URL(request.url);
|
|
5643
|
+
let pathname = url2.pathname;
|
|
5644
|
+
let method = request.method;
|
|
5667
5645
|
let basePath = `/` + config.basePath;
|
|
5668
5646
|
if (pathname === basePath || pathname.startsWith(basePath + `/`)) {
|
|
5669
5647
|
if (method === "OPTIONS") {
|
|
@@ -5673,9 +5651,9 @@ function createMiddleware(config) {
|
|
|
5673
5651
|
} else if (pathname === basePath + `/tools` && method === "GET") {
|
|
5674
5652
|
return handleGetTools(registry, config);
|
|
5675
5653
|
} else if (pathname === basePath + `/tools/call` && method === "POST") {
|
|
5676
|
-
return await handleToolCall(registry, config,
|
|
5654
|
+
return await handleToolCall(registry, config, request);
|
|
5677
5655
|
} else if (pathname === basePath + `/resolve-source-location` && method === "POST") {
|
|
5678
|
-
return await handleResolveSourceLocation(config,
|
|
5656
|
+
return await handleResolveSourceLocation(config, request);
|
|
5679
5657
|
} else {
|
|
5680
5658
|
return Response.json(Object.fromEntries([[
|
|
5681
5659
|
"error",
|
|
@@ -5685,8 +5663,109 @@ function createMiddleware(config) {
|
|
|
5685
5663
|
});
|
|
5686
5664
|
}
|
|
5687
5665
|
}
|
|
5688
|
-
|
|
5689
|
-
|
|
5666
|
+
};
|
|
5667
|
+
}
|
|
5668
|
+
|
|
5669
|
+
// ../../node_modules/@rescript/runtime/lib/es6/Stdlib_Promise.js
|
|
5670
|
+
function $$catch(promise, callback) {
|
|
5671
|
+
return promise.catch((err) => callback(internalToException(err)));
|
|
5672
|
+
}
|
|
5673
|
+
|
|
5674
|
+
// ../bindings/src/NodeHttp.res.mjs
|
|
5675
|
+
var collectRequestBody = (async function(req) {
|
|
5676
|
+
const chunks = [];
|
|
5677
|
+
for await (const chunk of req) {
|
|
5678
|
+
chunks.push(chunk);
|
|
5679
|
+
}
|
|
5680
|
+
const { Buffer: Buffer2 } = await import('buffer');
|
|
5681
|
+
return Buffer2.concat(chunks);
|
|
5682
|
+
});
|
|
5683
|
+
|
|
5684
|
+
// src/FrontmanAstro__ViteAdapter.res.mjs
|
|
5685
|
+
var copyHeaders = (function(headers2, res) {
|
|
5686
|
+
headers2.forEach(function(value, key) {
|
|
5687
|
+
res.setHeader(key, value);
|
|
5688
|
+
});
|
|
5689
|
+
});
|
|
5690
|
+
async function toWebRequest(req) {
|
|
5691
|
+
let host2 = getOr(req.headers["host"], "localhost");
|
|
5692
|
+
let url2 = `http://` + host2 + req.url;
|
|
5693
|
+
let method = req.method;
|
|
5694
|
+
let match = method.toUpperCase();
|
|
5695
|
+
let body;
|
|
5696
|
+
switch (match) {
|
|
5697
|
+
case "PATCH":
|
|
5698
|
+
case "POST":
|
|
5699
|
+
case "PUT":
|
|
5700
|
+
body = await collectRequestBody(req);
|
|
5701
|
+
break;
|
|
5702
|
+
default:
|
|
5703
|
+
body = void 0;
|
|
5704
|
+
}
|
|
5705
|
+
let headersDict = req.headers;
|
|
5706
|
+
let init = {
|
|
5707
|
+
method,
|
|
5708
|
+
headers: some(headersDict),
|
|
5709
|
+
body: map(body, (b) => b)
|
|
5710
|
+
};
|
|
5711
|
+
if (body !== void 0) {
|
|
5712
|
+
init["duplex"] = "half";
|
|
5713
|
+
}
|
|
5714
|
+
return new Request(url2, init);
|
|
5715
|
+
}
|
|
5716
|
+
async function writeWebResponse(webResponse, res) {
|
|
5717
|
+
res.statusCode = webResponse.status;
|
|
5718
|
+
copyHeaders(webResponse.headers, res);
|
|
5719
|
+
let body = webResponse.body;
|
|
5720
|
+
if (body !== null) {
|
|
5721
|
+
let reader = body.getReader();
|
|
5722
|
+
let decoder = new TextDecoder();
|
|
5723
|
+
let reading = true;
|
|
5724
|
+
while (reading) {
|
|
5725
|
+
let result = await reader.read();
|
|
5726
|
+
if (result.done) {
|
|
5727
|
+
reading = false;
|
|
5728
|
+
} else {
|
|
5729
|
+
let chunk = result.value;
|
|
5730
|
+
if (!(chunk == null)) {
|
|
5731
|
+
let text = decoder.decode(chunk, {
|
|
5732
|
+
stream: true
|
|
5733
|
+
});
|
|
5734
|
+
res.write(text);
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
}
|
|
5738
|
+
res.end();
|
|
5739
|
+
return;
|
|
5740
|
+
}
|
|
5741
|
+
res.end();
|
|
5742
|
+
}
|
|
5743
|
+
function adaptToConnect(middleware, basePath) {
|
|
5744
|
+
let prefix = `/` + basePath;
|
|
5745
|
+
return (req, res, next) => {
|
|
5746
|
+
let reqPath = getOr(req.url.split("?")[0], req.url);
|
|
5747
|
+
if (!(reqPath === prefix || reqPath.startsWith(prefix + `/`))) {
|
|
5748
|
+
return next();
|
|
5749
|
+
}
|
|
5750
|
+
let handleRequest = async () => {
|
|
5751
|
+
let webRequest = await toWebRequest(req);
|
|
5752
|
+
let maybeResponse = await middleware(webRequest);
|
|
5753
|
+
if (maybeResponse !== void 0) {
|
|
5754
|
+
return await writeWebResponse(maybeResponse, res);
|
|
5755
|
+
} else {
|
|
5756
|
+
return next();
|
|
5757
|
+
}
|
|
5758
|
+
};
|
|
5759
|
+
$$catch(handleRequest(), (error) => {
|
|
5760
|
+
console.error("[Frontman] Middleware error:", error);
|
|
5761
|
+
if (res.headersSent) {
|
|
5762
|
+
res.end();
|
|
5763
|
+
} else {
|
|
5764
|
+
res.statusCode = 500;
|
|
5765
|
+
res.end("Internal Server Error");
|
|
5766
|
+
}
|
|
5767
|
+
return Promise.resolve();
|
|
5768
|
+
});
|
|
5690
5769
|
};
|
|
5691
5770
|
}
|
|
5692
5771
|
|
|
@@ -5695,33 +5774,61 @@ var icon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
|
|
|
5695
5774
|
function getToolbarAppPath() {
|
|
5696
5775
|
return new URL("./toolbar.js", import.meta.url).pathname;
|
|
5697
5776
|
}
|
|
5698
|
-
|
|
5777
|
+
var annotationCaptureScript = `(function() {
|
|
5778
|
+
function captureAnnotations() {
|
|
5779
|
+
var annotations = new Map();
|
|
5780
|
+
document.querySelectorAll('[data-astro-source-file]').forEach(function(el) {
|
|
5781
|
+
annotations.set(el, {
|
|
5782
|
+
file: el.getAttribute('data-astro-source-file'),
|
|
5783
|
+
loc: el.getAttribute('data-astro-source-loc')
|
|
5784
|
+
});
|
|
5785
|
+
});
|
|
5786
|
+
window.__frontman_annotations__ = {
|
|
5787
|
+
_map: annotations,
|
|
5788
|
+
get: function(el) { return annotations.get(el); },
|
|
5789
|
+
has: function(el) { return annotations.has(el); },
|
|
5790
|
+
size: function() { return annotations.size; }
|
|
5791
|
+
};
|
|
5792
|
+
}
|
|
5793
|
+
// Capture once on initial DOM parse
|
|
5794
|
+
document.addEventListener('DOMContentLoaded', captureAnnotations);
|
|
5795
|
+
// Re-capture on View Transitions (SPA navigations) \u2014 skips the initial
|
|
5796
|
+
// page-load event since DOMContentLoaded already captured
|
|
5797
|
+
var initialLoad = true;
|
|
5798
|
+
document.addEventListener('astro:page-load', function() {
|
|
5799
|
+
if (initialLoad) { initialLoad = false; return; }
|
|
5800
|
+
captureAnnotations();
|
|
5801
|
+
});
|
|
5802
|
+
})();`;
|
|
5803
|
+
function make3(configInput) {
|
|
5804
|
+
let config = makeFromObject(configInput);
|
|
5699
5805
|
return {
|
|
5700
5806
|
name: "frontman",
|
|
5701
5807
|
hooks: {
|
|
5702
5808
|
"astro:config:setup": (ctx2) => {
|
|
5703
5809
|
if (ctx2.command === "dev") {
|
|
5704
|
-
|
|
5810
|
+
if (!ctx2.config.devToolbar.enabled) {
|
|
5811
|
+
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.");
|
|
5812
|
+
}
|
|
5813
|
+
ctx2.addDevToolbarApp({
|
|
5705
5814
|
id: "frontman:toolbar",
|
|
5706
5815
|
name: "Frontman",
|
|
5707
5816
|
icon,
|
|
5708
5817
|
entrypoint: getToolbarAppPath()
|
|
5709
5818
|
});
|
|
5819
|
+
return ctx2.injectScript("head-inline", annotationCaptureScript);
|
|
5710
5820
|
}
|
|
5821
|
+
},
|
|
5822
|
+
"astro:server:setup": (param) => {
|
|
5823
|
+
let webMiddleware = createMiddleware(config);
|
|
5824
|
+
let connectMiddleware = adaptToConnect(webMiddleware, config.basePath);
|
|
5825
|
+
param.server.middlewares.use(connectMiddleware);
|
|
5711
5826
|
}
|
|
5712
5827
|
}
|
|
5713
5828
|
};
|
|
5714
5829
|
}
|
|
5715
5830
|
|
|
5716
5831
|
// src/FrontmanAstro.res.mjs
|
|
5717
|
-
var Config;
|
|
5718
|
-
var Middleware;
|
|
5719
|
-
var Server;
|
|
5720
|
-
var ToolRegistry;
|
|
5721
|
-
var Integration;
|
|
5722
|
-
var SSE;
|
|
5723
|
-
var createMiddleware2 = createMiddleware;
|
|
5724
|
-
var makeConfig = makeFromObject;
|
|
5725
5832
|
var frontmanIntegration = make3;
|
|
5726
5833
|
|
|
5727
|
-
export {
|
|
5834
|
+
export { frontmanIntegration as default, frontmanIntegration };
|