@ascribed/astro 0.2.1-next.11 → 0.2.1-next.13
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 +3 -1
- package/dist/dev.js +9 -0
- package/dist/dev.js.map +1 -1
- package/dist/files.d.ts +8 -2
- package/dist/files.js +21 -5
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +44 -10
- package/dist/index.js.map +1 -1
- package/dist/names.d.ts +5 -0
- package/dist/names.js +5 -0
- package/dist/names.js.map +1 -1
- package/dist/permalinks.d.ts +54 -0
- package/dist/permalinks.js +72 -0
- package/dist/permalinks.js.map +1 -0
- package/dist/project.d.ts +10 -0
- package/dist/project.js +11 -0
- package/dist/project.js.map +1 -1
- package/dist/review/diff.d.ts +13 -0
- package/dist/review/diff.js +34 -1
- package/dist/review/diff.js.map +1 -1
- package/dist/review/server.d.ts +13 -0
- package/dist/review/server.js +44 -0
- package/dist/review/server.js.map +1 -1
- package/dist/run.d.ts +5 -4
- package/dist/run.js +12 -5
- package/dist/run.js.map +1 -1
- package/dist/shapes.d.ts +8 -1
- package/dist/shapes.js.map +1 -1
- package/dist/toolbar/app.js +98 -0
- package/dist/toolbar/app.js.map +1 -1
- package/package.json +15 -8
- package/src/MissingPermalink.astro +56 -0
- package/src/Permalink.astro +77 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The [Astro](https://astro.build) integration for [Ascribe](https://github.com/ascribed-dev/ascribe), for Astro 7.3.5 and later 7.x releases.
|
|
4
4
|
|
|
5
|
-
It runs `ascribe build --emit site` before Astro loads content, gives you a content collection over the output with a schema generated from `ascribe.toml`, applies heading ids and image attributes in Astro's own Markdown pipeline (so Astro keeps its heading, table-of-contents, and image handling), loads the element library,
|
|
5
|
+
It runs `ascribe build --emit site` before Astro loads content, gives you a content collection over the output with a schema generated from `ascribe.toml`, applies heading ids and image attributes in Astro's own Markdown pipeline (so Astro keeps its heading, table-of-contents, and image handling), loads the element library, serves the files pages link to, and gives each permalink an address that forwards to its heading. In `astro dev`, it rebuilds as you edit.
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
npm install @ascribed/astro
|
|
@@ -70,6 +70,8 @@ The [Astro guide](https://ascribed-dev.com/guides/astro/) walks through a site:
|
|
|
70
70
|
| `src/Elements.astro` | Loads `@ascribed/elements` (stylesheet and script) |
|
|
71
71
|
| `src/Availability.astro` | A page's availability as the element library's badge |
|
|
72
72
|
| `src/code-titles.ts` | The Shiki transformer that shows code block titles |
|
|
73
|
+
| `src/Permalink.astro`, `src/permalinks.ts` | The route at each permalink's address, and its pages, from the site output's `_ascribe/permalinks.json` |
|
|
74
|
+
| `src/MissingPermalink.astro` | The explanation on a site's 404 page for an address under the permalinks' path that matches nothing |
|
|
73
75
|
| `src/schema.ts` | Copies the generated schema inside the Astro root |
|
|
74
76
|
| `src/attributes.ts` | The attribute-marker and source-anchor rules, on a hast tree |
|
|
75
77
|
| `src/rehype.ts`, `src/satteri.ts` | The rules applied in each of Astro's Markdown processors |
|
package/dist/dev.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { permalinksText } from "./permalinks.js";
|
|
3
4
|
import { consumerMismatches, readProject } from "./project.js";
|
|
4
5
|
/**
|
|
5
6
|
* The assets a build copied from outside the content root, as absolute paths,
|
|
@@ -97,6 +98,7 @@ export function watchDev(options) {
|
|
|
97
98
|
running = true;
|
|
98
99
|
const previousProject = project;
|
|
99
100
|
const previousSiteRoot = previousProject.siteRoot(options.build);
|
|
101
|
+
const previousPermalinks = permalinksText(previousSiteRoot);
|
|
100
102
|
while (dirty) {
|
|
101
103
|
dirty = false;
|
|
102
104
|
try {
|
|
@@ -124,6 +126,13 @@ export function watchDev(options) {
|
|
|
124
126
|
server.watcher.add(project.configPath);
|
|
125
127
|
watchAssets();
|
|
126
128
|
await refreshContent();
|
|
129
|
+
// Astro keeps each route's `getStaticPaths` until content changes, and adding or removing a
|
|
130
|
+
// permalink may change no page: clear it, as Astro does, so the addresses follow the list.
|
|
131
|
+
if (permalinksText(previousSiteRoot) !== previousPermalinks) {
|
|
132
|
+
for (const name of ["ssr", "prerender"]) {
|
|
133
|
+
server.environments[name]?.hot.send("astro:content-changed", {});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
127
136
|
server.ws.send({ type: "full-reload" });
|
|
128
137
|
}
|
|
129
138
|
catch (error) {
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { AstroIntegration } from \"astro\";\nimport { consumerMismatches, readProject, type ProjectInfo } from \"./project.js\";\n\ntype ServerOptions = Parameters<NonNullable<AstroIntegration[\"hooks\"][\"astro:server:setup\"]>>[0];\n\n/**\n * The assets a build copied from outside the content root, as absolute paths,\n * read from the site output's manifest. Watching the content root doesn't\n * cover them. A manifest that's missing or unreadable gives none: the next\n * successful build writes one.\n */\nexport function outsideAssets(project: ProjectInfo, build: string): string[] {\n const manifest = path.join(path.dirname(project.siteRoot(build)), \"site.manifest.json\");\n let files: unknown;\n try {\n files = (JSON.parse(readFileSync(manifest, \"utf8\")) as { files?: unknown }).files;\n } catch {\n return [];\n }\n if (!Array.isArray(files)) return [];\n const assets = new Set<string>();\n for (const entry of files as { kind?: unknown; source?: unknown }[]) {\n if (entry.kind !== \"asset\" || typeof entry.source !== \"string\") continue;\n const absolute = path.resolve(project.contentRoot, entry.source);\n if (!absolute.startsWith(project.contentRoot + path.sep)) assets.add(absolute);\n }\n return [...assets].sort();\n}\n\n/**\n * Each watched file's size and modification time, as last seen. A watcher\n * can report an edit late, after a build already read it: macOS delivers\n * edits made just before the dev server started some seconds after it\n * started. An event that changes neither is no edit, and rebuilding for it\n * would reload the page under the reader.\n */\nexport class SeenFiles {\n private readonly stamps = new Map<string, string>();\n\n /** Records the files under `paths` (files or folders) as they are now. */\n prime(paths: readonly string[]): void {\n for (const at of paths) {\n let entries: string[];\n try {\n entries = statSync(at).isDirectory()\n ? readdirSync(at, { recursive: true, encoding: \"utf8\" }).map((f) => path.join(at, f))\n : [at];\n } catch {\n continue;\n }\n for (const file of entries) {\n const stamp = stampOf(file);\n if (stamp !== undefined && !this.stamps.has(file)) this.stamps.set(file, stamp);\n }\n }\n }\n\n /** Whether `file` differs from when it was last seen (or wasn't seen), and records it. */\n changed(file: string): boolean {\n const stamp = stampOf(file);\n const before = this.stamps.get(file);\n if (stamp === undefined) this.stamps.delete(file);\n else this.stamps.set(file, stamp);\n return stamp === undefined || stamp !== before;\n }\n}\n\nfunction stampOf(file: string): string | undefined {\n try {\n const stat = statSync(file);\n return stat.isFile() ? `${stat.size}:${stat.mtimeMs}` : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What `watchDev` gives back. */\nexport interface DevBuilds {\n /** Runs `task` in turn with the compiler runs, never during one. */\n inTurn(task: () => Promise<void>): Promise<void>;\n}\n\n/** Watch source files, serialize compiler runs, and refresh Astro after successful output. */\nexport function watchDev(options: {\n server: ServerOptions[\"server\"];\n refreshContent: () => Promise<void>;\n logger: ServerOptions[\"logger\"];\n project: ProjectInfo;\n astro: { base: string; trailingSlash: string; site: string | undefined };\n build: string;\n rebuild: () => Promise<void>;\n /** Called after each successful rebuild, before Astro reloads the page. */\n onBuilt?: () => void;\n /** The sources as the first build read them. */\n seen?: SeenFiles;\n}): DevBuilds {\n const { server, refreshContent, logger, rebuild } = options;\n let project = options.project;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let pending: Promise<void> = Promise.resolve();\n let dirty = false;\n let running = false;\n let failed = false;\n let assets = new Set<string>();\n const seen = options.seen ?? new SeenFiles();\n const watchAssets = () => {\n assets = new Set(outsideAssets(project, options.build));\n if (assets.size > 0) server.watcher.add([...assets]);\n seen.prime([...assets]);\n };\n\n const drain = async () => {\n running = true;\n const previousProject = project;\n const previousSiteRoot = previousProject.siteRoot(options.build);\n while (dirty) {\n dirty = false;\n try {\n await rebuild();\n failed = false;\n } catch (error) {\n failed = true;\n logger.error(error instanceof Error ? error.message : String(error));\n }\n }\n if (!failed) {\n options.onBuilt?.();\n try {\n const reloaded = readProject(project.dir);\n if (reloaded.siteRoot(options.build) !== previousSiteRoot) {\n throw new Error(\n \"ascribe.toml changed output-dir; restart astro dev to reload the collection.\",\n );\n }\n const mismatches = consumerMismatches(reloaded, options.astro);\n if (mismatches.length > 0) {\n throw new Error(\n `@ascribed/astro: ascribe.toml and astro.config disagree:\\n- ${mismatches.join(\"\\n- \")}`,\n );\n }\n project = reloaded;\n server.watcher.add(project.contentRoot);\n server.watcher.add(project.configPath);\n watchAssets();\n await refreshContent();\n server.ws.send({ type: \"full-reload\" });\n } catch (error) {\n failed = true;\n logger.error(\n `could not refresh Ascribe content: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n running = false;\n };\n const schedule = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n pending = pending.then(drain);\n }, 50);\n };\n const onChange = (event: string, file: string) => {\n if (![\"add\", \"change\", \"unlink\"].includes(event)) return;\n const absolute = path.resolve(file);\n const source =\n absolute === project.configPath ||\n assets.has(absolute) ||\n (absolute.startsWith(project.contentRoot + path.sep) &&\n !absolute.startsWith(project.outputRoot + path.sep));\n if (!source) return;\n // A late report of an edit the last build already had.\n if (event !== \"unlink\" && !seen.changed(absolute)) return;\n dirty = true;\n schedule();\n };\n server.watcher.add(project.contentRoot);\n server.watcher.add(project.configPath);\n seen.prime([project.contentRoot, project.configPath]);\n watchAssets();\n server.watcher.on(\"all\", onChange);\n server.httpServer?.once(\"close\", () => {\n if (timer) clearTimeout(timer);\n server.watcher.off(\"all\", onChange);\n });\n server.middlewares.use((_req, res, next) => {\n if (!dirty && !running && !failed) return next();\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n pending = pending.then(drain);\n }\n void pending.then(() => {\n if (failed) {\n res.statusCode = 503;\n res.end(\"Ascribe build failed; fix the source and save to retry.\");\n } else next();\n });\n });\n return {\n inTurn: (task) => {\n const run = pending.then(task);\n pending = run.catch(() => undefined);\n return run;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { AstroIntegration } from \"astro\";\nimport { permalinksText } from \"./permalinks.js\";\nimport { consumerMismatches, readProject, type ProjectInfo } from \"./project.js\";\n\ntype ServerOptions = Parameters<NonNullable<AstroIntegration[\"hooks\"][\"astro:server:setup\"]>>[0];\n\n/**\n * The assets a build copied from outside the content root, as absolute paths,\n * read from the site output's manifest. Watching the content root doesn't\n * cover them. A manifest that's missing or unreadable gives none: the next\n * successful build writes one.\n */\nexport function outsideAssets(project: ProjectInfo, build: string): string[] {\n const manifest = path.join(path.dirname(project.siteRoot(build)), \"site.manifest.json\");\n let files: unknown;\n try {\n files = (JSON.parse(readFileSync(manifest, \"utf8\")) as { files?: unknown }).files;\n } catch {\n return [];\n }\n if (!Array.isArray(files)) return [];\n const assets = new Set<string>();\n for (const entry of files as { kind?: unknown; source?: unknown }[]) {\n if (entry.kind !== \"asset\" || typeof entry.source !== \"string\") continue;\n const absolute = path.resolve(project.contentRoot, entry.source);\n if (!absolute.startsWith(project.contentRoot + path.sep)) assets.add(absolute);\n }\n return [...assets].sort();\n}\n\n/**\n * Each watched file's size and modification time, as last seen. A watcher\n * can report an edit late, after a build already read it: macOS delivers\n * edits made just before the dev server started some seconds after it\n * started. An event that changes neither is no edit, and rebuilding for it\n * would reload the page under the reader.\n */\nexport class SeenFiles {\n private readonly stamps = new Map<string, string>();\n\n /** Records the files under `paths` (files or folders) as they are now. */\n prime(paths: readonly string[]): void {\n for (const at of paths) {\n let entries: string[];\n try {\n entries = statSync(at).isDirectory()\n ? readdirSync(at, { recursive: true, encoding: \"utf8\" }).map((f) => path.join(at, f))\n : [at];\n } catch {\n continue;\n }\n for (const file of entries) {\n const stamp = stampOf(file);\n if (stamp !== undefined && !this.stamps.has(file)) this.stamps.set(file, stamp);\n }\n }\n }\n\n /** Whether `file` differs from when it was last seen (or wasn't seen), and records it. */\n changed(file: string): boolean {\n const stamp = stampOf(file);\n const before = this.stamps.get(file);\n if (stamp === undefined) this.stamps.delete(file);\n else this.stamps.set(file, stamp);\n return stamp === undefined || stamp !== before;\n }\n}\n\nfunction stampOf(file: string): string | undefined {\n try {\n const stat = statSync(file);\n return stat.isFile() ? `${stat.size}:${stat.mtimeMs}` : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What `watchDev` gives back. */\nexport interface DevBuilds {\n /** Runs `task` in turn with the compiler runs, never during one. */\n inTurn(task: () => Promise<void>): Promise<void>;\n}\n\n/** Watch source files, serialize compiler runs, and refresh Astro after successful output. */\nexport function watchDev(options: {\n server: ServerOptions[\"server\"];\n refreshContent: () => Promise<void>;\n logger: ServerOptions[\"logger\"];\n project: ProjectInfo;\n astro: { base: string; trailingSlash: string; site: string | undefined };\n build: string;\n rebuild: () => Promise<void>;\n /** Called after each successful rebuild, before Astro reloads the page. */\n onBuilt?: () => void;\n /** The sources as the first build read them. */\n seen?: SeenFiles;\n}): DevBuilds {\n const { server, refreshContent, logger, rebuild } = options;\n let project = options.project;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let pending: Promise<void> = Promise.resolve();\n let dirty = false;\n let running = false;\n let failed = false;\n let assets = new Set<string>();\n const seen = options.seen ?? new SeenFiles();\n const watchAssets = () => {\n assets = new Set(outsideAssets(project, options.build));\n if (assets.size > 0) server.watcher.add([...assets]);\n seen.prime([...assets]);\n };\n\n const drain = async () => {\n running = true;\n const previousProject = project;\n const previousSiteRoot = previousProject.siteRoot(options.build);\n const previousPermalinks = permalinksText(previousSiteRoot);\n while (dirty) {\n dirty = false;\n try {\n await rebuild();\n failed = false;\n } catch (error) {\n failed = true;\n logger.error(error instanceof Error ? error.message : String(error));\n }\n }\n if (!failed) {\n options.onBuilt?.();\n try {\n const reloaded = readProject(project.dir);\n if (reloaded.siteRoot(options.build) !== previousSiteRoot) {\n throw new Error(\n \"ascribe.toml changed output-dir; restart astro dev to reload the collection.\",\n );\n }\n const mismatches = consumerMismatches(reloaded, options.astro);\n if (mismatches.length > 0) {\n throw new Error(\n `@ascribed/astro: ascribe.toml and astro.config disagree:\\n- ${mismatches.join(\"\\n- \")}`,\n );\n }\n project = reloaded;\n server.watcher.add(project.contentRoot);\n server.watcher.add(project.configPath);\n watchAssets();\n await refreshContent();\n // Astro keeps each route's `getStaticPaths` until content changes, and adding or removing a\n // permalink may change no page: clear it, as Astro does, so the addresses follow the list.\n if (permalinksText(previousSiteRoot) !== previousPermalinks) {\n for (const name of [\"ssr\", \"prerender\"]) {\n server.environments[name]?.hot.send(\"astro:content-changed\", {});\n }\n }\n server.ws.send({ type: \"full-reload\" });\n } catch (error) {\n failed = true;\n logger.error(\n `could not refresh Ascribe content: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n running = false;\n };\n const schedule = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n pending = pending.then(drain);\n }, 50);\n };\n const onChange = (event: string, file: string) => {\n if (![\"add\", \"change\", \"unlink\"].includes(event)) return;\n const absolute = path.resolve(file);\n const source =\n absolute === project.configPath ||\n assets.has(absolute) ||\n (absolute.startsWith(project.contentRoot + path.sep) &&\n !absolute.startsWith(project.outputRoot + path.sep));\n if (!source) return;\n // A late report of an edit the last build already had.\n if (event !== \"unlink\" && !seen.changed(absolute)) return;\n dirty = true;\n schedule();\n };\n server.watcher.add(project.contentRoot);\n server.watcher.add(project.configPath);\n seen.prime([project.contentRoot, project.configPath]);\n watchAssets();\n server.watcher.on(\"all\", onChange);\n server.httpServer?.once(\"close\", () => {\n if (timer) clearTimeout(timer);\n server.watcher.off(\"all\", onChange);\n });\n server.middlewares.use((_req, res, next) => {\n if (!dirty && !running && !failed) return next();\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n pending = pending.then(drain);\n }\n void pending.then(() => {\n if (failed) {\n res.statusCode = 503;\n res.end(\"Ascribe build failed; fix the source and save to retry.\");\n } else next();\n });\n });\n return {\n inTurn: (task) => {\n const run = pending.then(task);\n pending = run.catch(() => undefined);\n return run;\n },\n };\n}\n"]}
|
package/dist/files.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
-
/** Copies the published files to `<outDir>/_ascribe/files/`. Returns
|
|
2
|
+
/** Copies the published files to `<outDir>/_ascribe/files/`. Returns whether there were any. */
|
|
3
3
|
export declare function copyPublishedFiles(siteRoot: string, outDir: URL): Promise<boolean>;
|
|
4
|
+
/** Copies the plain output for agents to the build output's root, the base path. Returns whether there was one. */
|
|
5
|
+
export declare function copyAgentFiles(plainRoot: string, outDir: URL): Promise<boolean>;
|
|
6
|
+
type Middleware = (req: IncomingMessage, res: ServerResponse, next: () => void) => void;
|
|
4
7
|
/** A dev-server middleware serving the published files at `<base>_ascribe/files/`. */
|
|
5
|
-
export declare function filesMiddleware(siteRoot: string, base: string):
|
|
8
|
+
export declare function filesMiddleware(siteRoot: string, base: string): Middleware;
|
|
9
|
+
/** A dev-server middleware serving the plain output for agents at `<base>`: `llms.txt`, each page's `.md`, and their files. */
|
|
10
|
+
export declare function agentsMiddleware(plainRoot: string, base: string): Middleware;
|
|
11
|
+
export {};
|
package/dist/files.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
// images. Astro doesn't copy them, so the integration
|
|
3
3
|
// does: into the build's output directory, and in dev through a middleware.
|
|
4
4
|
// Both put them at `<base>_ascribe/files/`, the URL the site output links to.
|
|
5
|
+
//
|
|
6
|
+
// With `[consumer] agents = true`, the same for the plain output, which is
|
|
7
|
+
// laid out by URL: `llms.txt`, each page's Markdown, and their files, all at
|
|
8
|
+
// `<base>` and below.
|
|
5
9
|
import { createReadStream } from "node:fs";
|
|
6
10
|
import { cp, stat } from "node:fs/promises";
|
|
7
11
|
import path from "node:path";
|
|
@@ -10,12 +14,18 @@ import { fileURLToPath } from "node:url";
|
|
|
10
14
|
function publishedDir(siteRoot) {
|
|
11
15
|
return path.join(siteRoot, "_ascribe", "files");
|
|
12
16
|
}
|
|
13
|
-
/** Copies the published files to `<outDir>/_ascribe/files/`. Returns
|
|
17
|
+
/** Copies the published files to `<outDir>/_ascribe/files/`. Returns whether there were any. */
|
|
14
18
|
export async function copyPublishedFiles(siteRoot, outDir) {
|
|
15
|
-
|
|
19
|
+
return copyDirectory(publishedDir(siteRoot), path.join(fileURLToPath(outDir), "_ascribe", "files"));
|
|
20
|
+
}
|
|
21
|
+
/** Copies the plain output for agents to the build output's root, the base path. Returns whether there was one. */
|
|
22
|
+
export async function copyAgentFiles(plainRoot, outDir) {
|
|
23
|
+
return copyDirectory(plainRoot, fileURLToPath(outDir));
|
|
24
|
+
}
|
|
25
|
+
async function copyDirectory(from, to) {
|
|
16
26
|
if (!(await stat(from).then((s) => s.isDirectory(), () => false)))
|
|
17
27
|
return false;
|
|
18
|
-
await cp(from,
|
|
28
|
+
await cp(from, to, { recursive: true });
|
|
19
29
|
return true;
|
|
20
30
|
}
|
|
21
31
|
const TYPES = {
|
|
@@ -39,10 +49,16 @@ const TYPES = {
|
|
|
39
49
|
};
|
|
40
50
|
/** A dev-server middleware serving the published files at `<base>_ascribe/files/`. */
|
|
41
51
|
export function filesMiddleware(siteRoot, base) {
|
|
42
|
-
|
|
52
|
+
return directoryMiddleware(publishedDir(siteRoot), `${base}_ascribe/files/`);
|
|
53
|
+
}
|
|
54
|
+
/** A dev-server middleware serving the plain output for agents at `<base>`: `llms.txt`, each page's `.md`, and their files. */
|
|
55
|
+
export function agentsMiddleware(plainRoot, base) {
|
|
56
|
+
return directoryMiddleware(plainRoot, base);
|
|
57
|
+
}
|
|
58
|
+
/** A middleware serving the files in `root` at the URL path `prefix`, which ends in `/`. */
|
|
59
|
+
function directoryMiddleware(root, prefix) {
|
|
43
60
|
// Only under the base path, as in the build. Vite strips the base from
|
|
44
61
|
// `req.url` before a plugin's middleware runs, but connect keeps the original in `originalUrl`.
|
|
45
|
-
const prefix = `${base}_ascribe/files/`;
|
|
46
62
|
return (req, res, next) => {
|
|
47
63
|
const pathname = (req.originalUrl ?? req.url ?? "").split(/[?#]/, 1)[0] ?? "";
|
|
48
64
|
if (!pathname.startsWith(prefix) || (req.method !== "GET" && req.method !== "HEAD"))
|
package/dist/files.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sDAAsD;AACtD,4EAA4E;AAC5E,8EAA8E;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,kEAAkE;AAClE,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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","sourcesContent":["// Serving `_ascribe/files/`: the files pages link to that aren't pages or\n// images. Astro doesn't copy them, so the integration\n// does: into the build's output directory, and in dev through a middleware.\n// Both put them at `<base>_ascribe/files/`, the URL the site output links to.\n//\n// With `[consumer] agents = true`, the same for the plain output, which is\n// laid out by URL: `llms.txt`, each page's Markdown, and their files, all at\n// `<base>` and below.\nimport { createReadStream } from \"node:fs\";\nimport { cp, stat } from \"node:fs/promises\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** The directory of published files inside a site output root. */\nfunction publishedDir(siteRoot: string): string {\n return path.join(siteRoot, \"_ascribe\", \"files\");\n}\n\n/** Copies the published files to `<outDir>/_ascribe/files/`. Returns whether there were any. */\nexport async function copyPublishedFiles(siteRoot: string, outDir: URL): Promise<boolean> {\n return copyDirectory(\n publishedDir(siteRoot),\n path.join(fileURLToPath(outDir), \"_ascribe\", \"files\"),\n );\n}\n\n/** Copies the plain output for agents to the build output's root, the base path. Returns whether there was one. */\nexport async function copyAgentFiles(plainRoot: string, outDir: URL): Promise<boolean> {\n return copyDirectory(plainRoot, fileURLToPath(outDir));\n}\n\nasync function copyDirectory(from: string, to: string): Promise<boolean> {\n if (\n !(await stat(from).then(\n (s) => s.isDirectory(),\n () => false,\n ))\n )\n return false;\n await cp(from, to, { recursive: true });\n return true;\n}\n\nconst TYPES: Record<string, string> = {\n \".pdf\": \"application/pdf\",\n \".zip\": \"application/zip\",\n \".json\": \"application/json\",\n \".yaml\": \"text/yaml; charset=utf-8\",\n \".yml\": \"text/yaml; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n \".csv\": \"text/csv; charset=utf-8\",\n \".md\": \"text/markdown; charset=utf-8\",\n \".html\": \"text/html; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n};\n\ntype Middleware = (req: IncomingMessage, res: ServerResponse, next: () => void) => void;\n\n/** A dev-server middleware serving the published files at `<base>_ascribe/files/`. */\nexport function filesMiddleware(siteRoot: string, base: string): Middleware {\n return directoryMiddleware(publishedDir(siteRoot), `${base}_ascribe/files/`);\n}\n\n/** A dev-server middleware serving the plain output for agents at `<base>`: `llms.txt`, each page's `.md`, and their files. */\nexport function agentsMiddleware(plainRoot: string, base: string): Middleware {\n return directoryMiddleware(plainRoot, base);\n}\n\n/** A middleware serving the files in `root` at the URL path `prefix`, which ends in `/`. */\nfunction directoryMiddleware(root: string, prefix: string): Middleware {\n // Only under the base path, as in the build. Vite strips the base from\n // `req.url` before a plugin's middleware runs, but connect keeps the original in `originalUrl`.\n return (req, res, next) => {\n const pathname =\n ((req as { originalUrl?: string }).originalUrl ?? req.url ?? \"\").split(/[?#]/, 1)[0] ?? \"\";\n if (!pathname.startsWith(prefix) || (req.method !== \"GET\" && req.method !== \"HEAD\"))\n return next();\n let relative: string;\n try {\n relative = decodeURIComponent(pathname.slice(prefix.length));\n } catch {\n return next();\n }\n const file = path.resolve(root, relative);\n if (file !== root && !file.startsWith(root + path.sep)) return next();\n stat(file).then(\n (info) => {\n if (!info.isFile()) return next();\n res.setHeader(\n \"Content-Type\",\n TYPES[path.extname(file).toLowerCase()] ?? \"application/octet-stream\",\n );\n res.setHeader(\"Content-Length\", info.size);\n if (req.method === \"HEAD\") return void res.end();\n createReadStream(file).pipe(res);\n },\n () => next(),\n );\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -32,5 +32,9 @@ export interface AscribeOptions {
|
|
|
32
32
|
*/
|
|
33
33
|
codeTitles?: boolean;
|
|
34
34
|
}
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Runs `ascribe build`, checks the site's routing, adds the markdown plugin, adds a page for each
|
|
37
|
+
* permalink's address, and serves published files, and, with `[consumer] agents = true`, `llms.txt`
|
|
38
|
+
* and each page's Markdown.
|
|
39
|
+
*/
|
|
36
40
|
export default function ascribe(options: AscribeOptions): AstroIntegration;
|
package/dist/index.js
CHANGED
|
@@ -19,16 +19,20 @@
|
|
|
19
19
|
// // a layout
|
|
20
20
|
// import Elements from "@ascribed/astro/Elements.astro"; // <Elements /> in <head>
|
|
21
21
|
// import Availability from "@ascribed/astro/Availability.astro"; // the page's availability
|
|
22
|
+
//
|
|
23
|
+
// // src/pages/404.astro
|
|
24
|
+
// import MissingPermalink from "@ascribed/astro/MissingPermalink.astro"; // a permalink that isn't here
|
|
22
25
|
import path from "node:path";
|
|
23
26
|
import { fileURLToPath } from "node:url";
|
|
24
27
|
import { findBinary } from "./binary.js";
|
|
25
28
|
import { codeTitles } from "./code-titles.js";
|
|
26
29
|
import { SeenFiles, watchDev } from "./dev.js";
|
|
27
|
-
import { copyPublishedFiles, filesMiddleware } from "./files.js";
|
|
28
|
-
import {
|
|
30
|
+
import { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware } from "./files.js";
|
|
31
|
+
import { permalinkPattern, readPermalinks } from "./permalinks.js";
|
|
32
|
+
import { consumerMismatches, homeRoute, readProject } from "./project.js";
|
|
29
33
|
import rehypeAscribeAttributes from "./rehype.js";
|
|
30
34
|
import { removeDevFile, siteUrl, writeDevFile } from "./review/devfile.js";
|
|
31
|
-
import { runDiff } from "./review/diff.js";
|
|
35
|
+
import { runDiff, runPrompt } from "./review/diff.js";
|
|
32
36
|
import { APP_ID } from "./review/protocol.js";
|
|
33
37
|
import { readRoutes } from "./review/routes.js";
|
|
34
38
|
import { channelProblem, ReviewServer } from "./review/server.js";
|
|
@@ -41,9 +45,15 @@ export { satteriAscribeAttributes } from "./satteri.js";
|
|
|
41
45
|
const SITE_MODULE = "virtual:ascribe/site";
|
|
42
46
|
/** The toolbar app's icon: a speech bubble over a page. */
|
|
43
47
|
const ICON = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3h8l4 4v6"/><path d="M14 3v4h4"/><path d="M6 3v15"/><path d="M11 14h10v6h-6l-3 2v-2h-1z"/></svg>';
|
|
44
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Runs `ascribe build`, checks the site's routing, adds the markdown plugin, adds a page for each
|
|
50
|
+
* permalink's address, and serves published files, and, with `[consumer] agents = true`, `llms.txt`
|
|
51
|
+
* and each page's Markdown.
|
|
52
|
+
*/
|
|
45
53
|
export default function ascribe(options) {
|
|
46
54
|
let siteRoot = "";
|
|
55
|
+
/** The plain output's root, when the project publishes it for agents. */
|
|
56
|
+
let agentsRoot;
|
|
47
57
|
let devProject;
|
|
48
58
|
let devConfig;
|
|
49
59
|
let rebuild;
|
|
@@ -56,11 +66,13 @@ export default function ascribe(options) {
|
|
|
56
66
|
return {
|
|
57
67
|
name: "@ascribed/astro",
|
|
58
68
|
hooks: {
|
|
59
|
-
"astro:config:setup": async ({ config, command, logger, updateConfig, addDevToolbarApp, createCodegenDir, }) => {
|
|
69
|
+
"astro:config:setup": async ({ config, command, logger, updateConfig, addDevToolbarApp, createCodegenDir, injectRoute, }) => {
|
|
60
70
|
const root = fileURLToPath(config.root);
|
|
61
71
|
const project = readProject(path.resolve(root, options.project ?? "."));
|
|
62
72
|
// An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.
|
|
63
73
|
siteRoot = project.siteRoot(options.build);
|
|
74
|
+
if (project.consumer.agents)
|
|
75
|
+
agentsRoot = project.plainRoot(options.build);
|
|
64
76
|
// `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.
|
|
65
77
|
const problems = consumerMismatches(project, {
|
|
66
78
|
base: config.base,
|
|
@@ -110,8 +122,13 @@ export default function ascribe(options) {
|
|
|
110
122
|
build: options.build,
|
|
111
123
|
cwd: project.dir,
|
|
112
124
|
anchors: anchorsFor(options.anchors, command, reviewing),
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
outputs: [
|
|
126
|
+
"site",
|
|
127
|
+
// `llms.txt` and each page's Markdown, which agents read.
|
|
128
|
+
...(agentsRoot === undefined ? [] : ["plain"]),
|
|
129
|
+
// While review is on, the JSON output says which page is at each route.
|
|
130
|
+
...(review?.active ? ["json"] : []),
|
|
131
|
+
],
|
|
115
132
|
});
|
|
116
133
|
if (hasWarnings(result.diagnostics))
|
|
117
134
|
logger.warn(result.diagnostics);
|
|
@@ -127,8 +144,17 @@ export default function ascribe(options) {
|
|
|
127
144
|
await rebuild();
|
|
128
145
|
if (command === "dev")
|
|
129
146
|
devProject = project;
|
|
147
|
+
// Each permalink's address, a page that forwards to its heading.
|
|
148
|
+
const permalinks = readPermalinks(siteRoot);
|
|
149
|
+
if (permalinks !== undefined) {
|
|
150
|
+
injectRoute({
|
|
151
|
+
pattern: permalinkPattern(permalinks.path, config.base),
|
|
152
|
+
entrypoint: new URL("../src/Permalink.astro", import.meta.url),
|
|
153
|
+
prerender: true,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
130
156
|
}
|
|
131
|
-
// Dev serving of `_ascribe/files
|
|
157
|
+
// Dev serving of `_ascribe/files/`, and of the plain output for agents; the build copies them in `astro:build:done`.
|
|
132
158
|
updateConfig({
|
|
133
159
|
...(options.codeTitles === false
|
|
134
160
|
? {}
|
|
@@ -141,13 +167,17 @@ export default function ascribe(options) {
|
|
|
141
167
|
name: "@ascribed/astro:site",
|
|
142
168
|
resolveId: (id) => (id === SITE_MODULE ? `\0${SITE_MODULE}` : undefined),
|
|
143
169
|
load: (id) => id === `\0${SITE_MODULE}`
|
|
144
|
-
? `export const siteRoot = ${JSON.stringify(siteRoot)}
|
|
170
|
+
? `export const siteRoot = ${JSON.stringify(siteRoot)};\n` +
|
|
171
|
+
`export const home = ${JSON.stringify(homeRoute(config.base, config.trailingSlash))};`
|
|
145
172
|
: undefined,
|
|
146
173
|
},
|
|
147
174
|
{
|
|
148
175
|
name: "@ascribed/astro:files",
|
|
149
176
|
configureServer(server) {
|
|
150
|
-
|
|
177
|
+
const base = config.base.endsWith("/") ? config.base : `${config.base}/`;
|
|
178
|
+
server.middlewares.use(filesMiddleware(siteRoot, base));
|
|
179
|
+
if (agentsRoot !== undefined)
|
|
180
|
+
server.middlewares.use(agentsMiddleware(agentsRoot, base));
|
|
151
181
|
},
|
|
152
182
|
},
|
|
153
183
|
],
|
|
@@ -182,6 +212,8 @@ export default function ascribe(options) {
|
|
|
182
212
|
contentRoot: project.contentRoot,
|
|
183
213
|
channelProblem: channelProblem(server.config),
|
|
184
214
|
diff: (base) => runDiff({ ...run, build: options.build, base }),
|
|
215
|
+
prompt: (page, base) => runPrompt({ ...run, build: options.build, base, path: page }),
|
|
216
|
+
projectDir: project.dir,
|
|
185
217
|
connect: async () => (await import("./review/github.js")).connect(project.dir),
|
|
186
218
|
writeRoutes: () => builds.inTurn(async () => {
|
|
187
219
|
await runBuild({ ...run, build: options.build, outputs: ["json"] });
|
|
@@ -218,6 +250,8 @@ export default function ascribe(options) {
|
|
|
218
250
|
"astro:build:done": async ({ dir, logger }) => {
|
|
219
251
|
if (await copyPublishedFiles(siteRoot, dir))
|
|
220
252
|
logger.info("copied _ascribe/files/");
|
|
253
|
+
if (agentsRoot !== undefined && (await copyAgentFiles(agentsRoot, dir)))
|
|
254
|
+
logger.info("copied llms.txt and each page's Markdown");
|
|
221
255
|
},
|
|
222
256
|
},
|
|
223
257
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// @ascribed/astro: the Astro integration for Ascribe. Written against Astro\n// 7.3.5.\n//\n// // astro.config.mjs\n// import ascribe from \"@ascribed/astro\";\n// export default defineConfig({\n// base: \"/docs\", trailingSlash: \"never\", // as in ascribe.toml's [consumer]\n// integrations: [ascribe({ build: \"site\" })],\n// });\n//\n// // src/content.config.ts\n// import { defineCollection } from \"astro:content\";\n// import { ascribeCollection } from \"@ascribed/astro/content\";\n// // The generated schema. With the project outside the Astro root, import the\n// // copy inside it instead: \"../.astro/integrations/_ascribed_astro/schema.ts\".\n// import { schema } from \"../.ascribe/build/site/site/_ascribe/schema.ts\";\n// export const collections = { docs: defineCollection(ascribeCollection({ schema })) };\n//\n// // a layout\n// import Elements from \"@ascribed/astro/Elements.astro\"; // <Elements /> in <head>\n// import Availability from \"@ascribed/astro/Availability.astro\"; // the page's availability\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { AstroIntegration } from \"astro\";\nimport { findBinary } from \"./binary.js\";\nimport { codeTitles } from \"./code-titles.js\";\nimport { SeenFiles, watchDev } from \"./dev.js\";\nimport { copyPublishedFiles, filesMiddleware } from \"./files.js\";\nimport { consumerMismatches, readProject } from \"./project.js\";\nimport rehypeAscribeAttributes from \"./rehype.js\";\nimport { removeDevFile, siteUrl, writeDevFile } from \"./review/devfile.js\";\nimport { runDiff } from \"./review/diff.js\";\nimport { APP_ID } from \"./review/protocol.js\";\nimport { readRoutes } from \"./review/routes.js\";\nimport { channelProblem, ReviewServer, type ToolbarChannel } from \"./review/server.js\";\nimport { anchorsFor, hasWarnings, reviewFor, runBuild } from \"./run.js\";\nimport { satteriAscribeAttributes } from \"./satteri.js\";\nimport { copySchema } from \"./schema.js\";\n\nexport { default as rehypeAscribeAttributes } from \"./rehype.js\";\nexport { satteriAscribeAttributes } from \"./satteri.js\";\n\n/** The virtual module `content.ts` reads the resolved site output root from. */\nconst SITE_MODULE = \"virtual:ascribe/site\";\n\n/** Options of the integration. */\nexport interface AscribeOptions {\n /** The build whose site output is the collection (a name in `ascribe.toml`). */\n build: string;\n /** The directory holding `ascribe.toml`, relative to the Astro root. Default: the root. */\n project?: string;\n /**\n * The `ascribe` binary, relative to the Astro root. Default: `ASCRIBE_BIN`, then\n * the platform binary installed with `@ascribed/cli`.\n */\n binary?: string;\n /**\n * Mark each block of the site output with the source lines it came from\n * (source anchors), for review: `\"dev\"` in `astro dev` only, `true` always.\n * Default: `false`, though `review` has them in `astro dev`.\n */\n anchors?: boolean | \"dev\";\n /**\n * Review in the site preview: an **Ascribe review** app in `astro dev`'s\n * toolbar, which marks the page's changes and shows the pull request's\n * comments, with source anchors in `astro dev`. Default `true`; `false`\n * removes the app. `astro build` never has it.\n */\n review?: boolean;\n /**\n * Show a code block's title (`title=\"…\"` in its info string, as `@snippet`\n * writes it) above it, with a Shiki transformer that puts the block in a\n * `<figure class=\"code-title\">` with a `<figcaption>`. Default `true`.\n */\n codeTitles?: boolean;\n}\n\n/** The toolbar app's icon: a speech bubble over a page. */\nconst ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3h8l4 4v6\"/><path d=\"M14 3v4h4\"/><path d=\"M6 3v15\"/><path d=\"M11 14h10v6h-6l-3 2v-2h-1z\"/></svg>';\n\n/** Runs `ascribe build`, checks the site's routing, adds the markdown plugin, and serves published files. */\nexport default function ascribe(options: AscribeOptions): AstroIntegration {\n let siteRoot = \"\";\n let devProject: ReturnType<typeof readProject> | undefined;\n let devConfig:\n | {\n base: string;\n trailingSlash: string;\n site: string | undefined;\n }\n | undefined;\n let rebuild: (() => Promise<void>) | undefined;\n /** The dev server's sources as its first build read them. */\n const seen = new SeenFiles();\n let binary: string | undefined;\n let reviewing = false;\n let devHttps = false;\n let review: ReviewServer | undefined;\n return {\n name: \"@ascribed/astro\",\n hooks: {\n \"astro:config:setup\": async ({\n config,\n command,\n logger,\n updateConfig,\n addDevToolbarApp,\n createCodegenDir,\n }) => {\n const root = fileURLToPath(config.root);\n const project = readProject(path.resolve(root, options.project ?? \".\"));\n // An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.\n siteRoot = project.siteRoot(options.build);\n\n // `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.\n const problems = consumerMismatches(project, {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n });\n if (problems.length > 0) {\n throw new Error(\n `@ascribed/astro: ascribe.toml and astro.config disagree:\\n- ${problems.join(\"\\n- \")}`,\n );\n }\n\n // Where a markdown plugin goes depends on the processor Astro 7.3 runs.\n const processor = config.markdown.processor;\n const pluginLists = processor.options as {\n rehypePlugins?: unknown[];\n hastPlugins?: unknown[];\n };\n if (processor.name === \"satteri\" && pluginLists.hastPlugins !== undefined) {\n pluginLists.hastPlugins.push(satteriAscribeAttributes());\n } else if (processor.name === \"unified\" && pluginLists.rehypePlugins !== undefined) {\n pluginLists.rehypePlugins.push(rehypeAscribeAttributes);\n } else {\n throw new Error(\n `@ascribed/astro: the markdown processor \"${processor.name}\" is not one it can add its plugin to. ` +\n \"Use Astro's default (satteri) or unified(), or add `rehypeAscribeAttributes` to your own.\",\n );\n }\n\n devConfig = {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n };\n\n reviewing = reviewFor(options.review, command);\n if (reviewing) {\n addDevToolbarApp({\n id: APP_ID,\n name: \"Ascribe review\",\n icon: ICON,\n entrypoint: new URL(\"./toolbar/app.js\", import.meta.url),\n });\n }\n\n if (command !== \"preview\") {\n const found = findBinary({ binary: options.binary, root });\n binary = found;\n // The schema's copy inside the Astro root, for content.config.ts to import.\n const codegen = fileURLToPath(createCodegenDir());\n rebuild = async () => {\n logger.info(`running ${path.basename(found)} build for \"${options.build}\"`);\n const result = await runBuild({\n binary: found,\n configPath: project.configPath,\n build: options.build,\n cwd: project.dir,\n anchors: anchorsFor(options.anchors, command, reviewing),\n // While review is on, the JSON output says which page is at each route.\n outputs: review?.active ? [\"site\", \"json\"] : [\"site\"],\n });\n if (hasWarnings(result.diagnostics)) logger.warn(result.diagnostics);\n else if (result.diagnostics !== \"\") logger.info(result.diagnostics);\n if (result.summary !== \"\") logger.info(result.summary);\n copySchema(siteRoot, codegen);\n };\n // The sources as the first build reads them: the watcher may report their edits late.\n if (command === \"dev\") seen.prime([project.contentRoot, project.configPath]);\n await rebuild();\n if (command === \"dev\") devProject = project;\n }\n\n // Dev serving of `_ascribe/files/`; the build copies them in `astro:build:done`.\n updateConfig({\n ...(options.codeTitles === false\n ? {}\n : { markdown: { shikiConfig: { transformers: [codeTitles] } } }),\n vite: {\n // `Elements.astro` is Astro source, so Vite must compile it, not load it as a Node module.\n ssr: { noExternal: [\"@ascribed/astro\"] },\n plugins: [\n {\n name: \"@ascribed/astro:site\",\n resolveId: (id) => (id === SITE_MODULE ? `\\0${SITE_MODULE}` : undefined),\n load: (id) =>\n id === `\\0${SITE_MODULE}`\n ? `export const siteRoot = ${JSON.stringify(siteRoot)};`\n : undefined,\n },\n {\n name: \"@ascribed/astro:files\",\n configureServer(server) {\n server.middlewares.use(\n filesMiddleware(\n siteRoot,\n config.base.endsWith(\"/\") ? config.base : `${config.base}/`,\n ),\n );\n },\n },\n ],\n },\n });\n },\n \"astro:server:setup\": ({ server, refreshContent, logger, toolbar }) => {\n if (devProject && rebuild && devConfig) {\n if (!refreshContent)\n throw new Error(\"@ascribed/astro: this Astro version does not support refreshContent.\");\n const project = devProject;\n devHttps = Boolean(server.config.server.https);\n const builds = watchDev({\n server,\n seen,\n refreshContent: () => refreshContent({}),\n logger,\n project,\n astro: devConfig,\n build: options.build,\n rebuild,\n onBuilt: () => review?.rebuilt(),\n });\n if (reviewing && binary !== undefined) {\n const found = binary;\n const run = { binary: found, configPath: project.configPath, cwd: project.dir };\n const jsonRoot = path.join(path.dirname(siteRoot), \"json\");\n review = new ReviewServer({\n channel: toolbar as ToolbarChannel,\n logger,\n build: options.build,\n contentRoot: project.contentRoot,\n channelProblem: channelProblem(server.config),\n diff: (base) => runDiff({ ...run, build: options.build, base }),\n connect: async () => (await import(\"./review/github.js\")).connect(project.dir),\n writeRoutes: () =>\n builds.inTurn(async () => {\n await runBuild({ ...run, build: options.build, outputs: [\"json\"] });\n }),\n readRoutes: () => readRoutes(jsonRoot),\n });\n }\n }\n },\n \"astro:server:start\": ({ address, logger }) => {\n review?.listening(address.address);\n if (!devProject || !devConfig) return;\n const dir = devProject.dir;\n try {\n writeDevFile(dir, {\n url: siteUrl(address, { https: devHttps, base: devConfig.base }),\n build: options.build,\n pid: process.pid,\n });\n // Vite exits on a signal before `astro:server:done` runs.\n process.once(\"exit\", () => removeDevFile(dir, process.pid));\n } catch (error) {\n logger.warn(\n `couldn't write .ascribe/dev.json, which the editor's Open Site Preview reads: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n \"astro:server:done\": () => {\n review?.dispose();\n review = undefined;\n if (devProject) removeDevFile(devProject.dir, process.pid);\n },\n \"astro:build:done\": async ({ dir, logger }) => {\n if (await copyPublishedFiles(siteRoot, dir)) logger.info(\"copied _ascribe/files/\");\n },\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// @ascribed/astro: the Astro integration for Ascribe. Written against Astro\n// 7.3.5.\n//\n// // astro.config.mjs\n// import ascribe from \"@ascribed/astro\";\n// export default defineConfig({\n// base: \"/docs\", trailingSlash: \"never\", // as in ascribe.toml's [consumer]\n// integrations: [ascribe({ build: \"site\" })],\n// });\n//\n// // src/content.config.ts\n// import { defineCollection } from \"astro:content\";\n// import { ascribeCollection } from \"@ascribed/astro/content\";\n// // The generated schema. With the project outside the Astro root, import the\n// // copy inside it instead: \"../.astro/integrations/_ascribed_astro/schema.ts\".\n// import { schema } from \"../.ascribe/build/site/site/_ascribe/schema.ts\";\n// export const collections = { docs: defineCollection(ascribeCollection({ schema })) };\n//\n// // a layout\n// import Elements from \"@ascribed/astro/Elements.astro\"; // <Elements /> in <head>\n// import Availability from \"@ascribed/astro/Availability.astro\"; // the page's availability\n//\n// // src/pages/404.astro\n// import MissingPermalink from \"@ascribed/astro/MissingPermalink.astro\"; // a permalink that isn't here\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { AstroIntegration } from \"astro\";\nimport { findBinary } from \"./binary.js\";\nimport { codeTitles } from \"./code-titles.js\";\nimport { SeenFiles, watchDev } from \"./dev.js\";\nimport { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware } from \"./files.js\";\nimport { permalinkPattern, readPermalinks } from \"./permalinks.js\";\nimport { consumerMismatches, homeRoute, readProject } from \"./project.js\";\nimport rehypeAscribeAttributes from \"./rehype.js\";\nimport { removeDevFile, siteUrl, writeDevFile } from \"./review/devfile.js\";\nimport { runDiff, runPrompt } from \"./review/diff.js\";\nimport { APP_ID } from \"./review/protocol.js\";\nimport { readRoutes } from \"./review/routes.js\";\nimport { channelProblem, ReviewServer, type ToolbarChannel } from \"./review/server.js\";\nimport { anchorsFor, hasWarnings, reviewFor, runBuild } from \"./run.js\";\nimport { satteriAscribeAttributes } from \"./satteri.js\";\nimport { copySchema } from \"./schema.js\";\n\nexport { default as rehypeAscribeAttributes } from \"./rehype.js\";\nexport { satteriAscribeAttributes } from \"./satteri.js\";\n\n/** The virtual module `content.ts` reads the resolved site output root from. */\nconst SITE_MODULE = \"virtual:ascribe/site\";\n\n/** Options of the integration. */\nexport interface AscribeOptions {\n /** The build whose site output is the collection (a name in `ascribe.toml`). */\n build: string;\n /** The directory holding `ascribe.toml`, relative to the Astro root. Default: the root. */\n project?: string;\n /**\n * The `ascribe` binary, relative to the Astro root. Default: `ASCRIBE_BIN`, then\n * the platform binary installed with `@ascribed/cli`.\n */\n binary?: string;\n /**\n * Mark each block of the site output with the source lines it came from\n * (source anchors), for review: `\"dev\"` in `astro dev` only, `true` always.\n * Default: `false`, though `review` has them in `astro dev`.\n */\n anchors?: boolean | \"dev\";\n /**\n * Review in the site preview: an **Ascribe review** app in `astro dev`'s\n * toolbar, which marks the page's changes and shows the pull request's\n * comments, with source anchors in `astro dev`. Default `true`; `false`\n * removes the app. `astro build` never has it.\n */\n review?: boolean;\n /**\n * Show a code block's title (`title=\"…\"` in its info string, as `@snippet`\n * writes it) above it, with a Shiki transformer that puts the block in a\n * `<figure class=\"code-title\">` with a `<figcaption>`. Default `true`.\n */\n codeTitles?: boolean;\n}\n\n/** The toolbar app's icon: a speech bubble over a page. */\nconst ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3h8l4 4v6\"/><path d=\"M14 3v4h4\"/><path d=\"M6 3v15\"/><path d=\"M11 14h10v6h-6l-3 2v-2h-1z\"/></svg>';\n\n/**\n * Runs `ascribe build`, checks the site's routing, adds the markdown plugin, adds a page for each\n * permalink's address, and serves published files, and, with `[consumer] agents = true`, `llms.txt`\n * and each page's Markdown.\n */\nexport default function ascribe(options: AscribeOptions): AstroIntegration {\n let siteRoot = \"\";\n /** The plain output's root, when the project publishes it for agents. */\n let agentsRoot: string | undefined;\n let devProject: ReturnType<typeof readProject> | undefined;\n let devConfig:\n | {\n base: string;\n trailingSlash: string;\n site: string | undefined;\n }\n | undefined;\n let rebuild: (() => Promise<void>) | undefined;\n /** The dev server's sources as its first build read them. */\n const seen = new SeenFiles();\n let binary: string | undefined;\n let reviewing = false;\n let devHttps = false;\n let review: ReviewServer | undefined;\n return {\n name: \"@ascribed/astro\",\n hooks: {\n \"astro:config:setup\": async ({\n config,\n command,\n logger,\n updateConfig,\n addDevToolbarApp,\n createCodegenDir,\n injectRoute,\n }) => {\n const root = fileURLToPath(config.root);\n const project = readProject(path.resolve(root, options.project ?? \".\"));\n // An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.\n siteRoot = project.siteRoot(options.build);\n if (project.consumer.agents) agentsRoot = project.plainRoot(options.build);\n\n // `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.\n const problems = consumerMismatches(project, {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n });\n if (problems.length > 0) {\n throw new Error(\n `@ascribed/astro: ascribe.toml and astro.config disagree:\\n- ${problems.join(\"\\n- \")}`,\n );\n }\n\n // Where a markdown plugin goes depends on the processor Astro 7.3 runs.\n const processor = config.markdown.processor;\n const pluginLists = processor.options as {\n rehypePlugins?: unknown[];\n hastPlugins?: unknown[];\n };\n if (processor.name === \"satteri\" && pluginLists.hastPlugins !== undefined) {\n pluginLists.hastPlugins.push(satteriAscribeAttributes());\n } else if (processor.name === \"unified\" && pluginLists.rehypePlugins !== undefined) {\n pluginLists.rehypePlugins.push(rehypeAscribeAttributes);\n } else {\n throw new Error(\n `@ascribed/astro: the markdown processor \"${processor.name}\" is not one it can add its plugin to. ` +\n \"Use Astro's default (satteri) or unified(), or add `rehypeAscribeAttributes` to your own.\",\n );\n }\n\n devConfig = {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n };\n\n reviewing = reviewFor(options.review, command);\n if (reviewing) {\n addDevToolbarApp({\n id: APP_ID,\n name: \"Ascribe review\",\n icon: ICON,\n entrypoint: new URL(\"./toolbar/app.js\", import.meta.url),\n });\n }\n\n if (command !== \"preview\") {\n const found = findBinary({ binary: options.binary, root });\n binary = found;\n // The schema's copy inside the Astro root, for content.config.ts to import.\n const codegen = fileURLToPath(createCodegenDir());\n rebuild = async () => {\n logger.info(`running ${path.basename(found)} build for \"${options.build}\"`);\n const result = await runBuild({\n binary: found,\n configPath: project.configPath,\n build: options.build,\n cwd: project.dir,\n anchors: anchorsFor(options.anchors, command, reviewing),\n outputs: [\n \"site\",\n // `llms.txt` and each page's Markdown, which agents read.\n ...(agentsRoot === undefined ? [] : ([\"plain\"] as const)),\n // While review is on, the JSON output says which page is at each route.\n ...(review?.active ? ([\"json\"] as const) : []),\n ],\n });\n if (hasWarnings(result.diagnostics)) logger.warn(result.diagnostics);\n else if (result.diagnostics !== \"\") logger.info(result.diagnostics);\n if (result.summary !== \"\") logger.info(result.summary);\n copySchema(siteRoot, codegen);\n };\n // The sources as the first build reads them: the watcher may report their edits late.\n if (command === \"dev\") seen.prime([project.contentRoot, project.configPath]);\n await rebuild();\n if (command === \"dev\") devProject = project;\n\n // Each permalink's address, a page that forwards to its heading.\n const permalinks = readPermalinks(siteRoot);\n if (permalinks !== undefined) {\n injectRoute({\n pattern: permalinkPattern(permalinks.path, config.base),\n entrypoint: new URL(\"../src/Permalink.astro\", import.meta.url),\n prerender: true,\n });\n }\n }\n\n // Dev serving of `_ascribe/files/`, and of the plain output for agents; the build copies them in `astro:build:done`.\n updateConfig({\n ...(options.codeTitles === false\n ? {}\n : { markdown: { shikiConfig: { transformers: [codeTitles] } } }),\n vite: {\n // `Elements.astro` is Astro source, so Vite must compile it, not load it as a Node module.\n ssr: { noExternal: [\"@ascribed/astro\"] },\n plugins: [\n {\n name: \"@ascribed/astro:site\",\n resolveId: (id) => (id === SITE_MODULE ? `\\0${SITE_MODULE}` : undefined),\n load: (id) =>\n id === `\\0${SITE_MODULE}`\n ? `export const siteRoot = ${JSON.stringify(siteRoot)};\\n` +\n `export const home = ${JSON.stringify(homeRoute(config.base, config.trailingSlash))};`\n : undefined,\n },\n {\n name: \"@ascribed/astro:files\",\n configureServer(server) {\n const base = config.base.endsWith(\"/\") ? config.base : `${config.base}/`;\n server.middlewares.use(filesMiddleware(siteRoot, base));\n if (agentsRoot !== undefined)\n server.middlewares.use(agentsMiddleware(agentsRoot, base));\n },\n },\n ],\n },\n });\n },\n \"astro:server:setup\": ({ server, refreshContent, logger, toolbar }) => {\n if (devProject && rebuild && devConfig) {\n if (!refreshContent)\n throw new Error(\"@ascribed/astro: this Astro version does not support refreshContent.\");\n const project = devProject;\n devHttps = Boolean(server.config.server.https);\n const builds = watchDev({\n server,\n seen,\n refreshContent: () => refreshContent({}),\n logger,\n project,\n astro: devConfig,\n build: options.build,\n rebuild,\n onBuilt: () => review?.rebuilt(),\n });\n if (reviewing && binary !== undefined) {\n const found = binary;\n const run = { binary: found, configPath: project.configPath, cwd: project.dir };\n const jsonRoot = path.join(path.dirname(siteRoot), \"json\");\n review = new ReviewServer({\n channel: toolbar as ToolbarChannel,\n logger,\n build: options.build,\n contentRoot: project.contentRoot,\n channelProblem: channelProblem(server.config),\n diff: (base) => runDiff({ ...run, build: options.build, base }),\n prompt: (page, base) => runPrompt({ ...run, build: options.build, base, path: page }),\n projectDir: project.dir,\n connect: async () => (await import(\"./review/github.js\")).connect(project.dir),\n writeRoutes: () =>\n builds.inTurn(async () => {\n await runBuild({ ...run, build: options.build, outputs: [\"json\"] });\n }),\n readRoutes: () => readRoutes(jsonRoot),\n });\n }\n }\n },\n \"astro:server:start\": ({ address, logger }) => {\n review?.listening(address.address);\n if (!devProject || !devConfig) return;\n const dir = devProject.dir;\n try {\n writeDevFile(dir, {\n url: siteUrl(address, { https: devHttps, base: devConfig.base }),\n build: options.build,\n pid: process.pid,\n });\n // Vite exits on a signal before `astro:server:done` runs.\n process.once(\"exit\", () => removeDevFile(dir, process.pid));\n } catch (error) {\n logger.warn(\n `couldn't write .ascribe/dev.json, which the editor's Open Site Preview reads: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n \"astro:server:done\": () => {\n review?.dispose();\n review = undefined;\n if (devProject) removeDevFile(devProject.dir, process.pid);\n },\n \"astro:build:done\": async ({ dir, logger }) => {\n if (await copyPublishedFiles(siteRoot, dir)) logger.info(\"copied _ascribe/files/\");\n if (agentsRoot !== undefined && (await copyAgentFiles(agentsRoot, dir)))\n logger.info(\"copied llms.txt and each page's Markdown\");\n },\n },\n };\n}\n"]}
|
package/dist/names.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export declare const ELEMENT_AVAILABILITY = "ascribe-availability";
|
|
|
15
15
|
export declare const ELEMENT_AVAILABILITY_TARGET = "ascribe-availability-target";
|
|
16
16
|
/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */
|
|
17
17
|
export declare const ELEMENT_GROUP = "ascribe-group";
|
|
18
|
+
/**
|
|
19
|
+
* `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top
|
|
20
|
+
* of a page, for agents (packages/elements/CONTRACT.md §8).
|
|
21
|
+
*/
|
|
22
|
+
export declare const ELEMENT_FOR_AGENTS = "ascribe-for-agents";
|
|
18
23
|
/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */
|
|
19
24
|
export declare const ELEMENT_ATTRIBUTES = "ascribe-attributes";
|
|
20
25
|
/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */
|
package/dist/names.js
CHANGED
|
@@ -18,6 +18,11 @@ export const ELEMENT_AVAILABILITY = "ascribe-availability";
|
|
|
18
18
|
export const ELEMENT_AVAILABILITY_TARGET = "ascribe-availability-target";
|
|
19
19
|
/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */
|
|
20
20
|
export const ELEMENT_GROUP = "ascribe-group";
|
|
21
|
+
/**
|
|
22
|
+
* `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top
|
|
23
|
+
* of a page, for agents (packages/elements/CONTRACT.md §8).
|
|
24
|
+
*/
|
|
25
|
+
export const ELEMENT_FOR_AGENTS = "ascribe-for-agents";
|
|
21
26
|
/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */
|
|
22
27
|
export const ELEMENT_ATTRIBUTES = "ascribe-attributes";
|
|
23
28
|
/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */
|
package/dist/names.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"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","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/guides/astro.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"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","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/**\n * `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top\n * of a page, for agents (packages/elements/CONTRACT.md §8).\n */\nexport const ELEMENT_FOR_AGENTS = \"ascribe-for-agents\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/guides/astro.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** `_ascribe/permalinks.json`. */
|
|
2
|
+
export interface PermalinkList {
|
|
3
|
+
version: number;
|
|
4
|
+
/** Where the addresses are published, from the site's root, ending in `/`. */
|
|
5
|
+
path: string;
|
|
6
|
+
/** The content model's dimensions, each with its values: the parameters an address takes. */
|
|
7
|
+
dimensions?: Record<string, string[]>;
|
|
8
|
+
/**
|
|
9
|
+
* Each permalink's destination. An alias names the permalink it leads to,
|
|
10
|
+
* and a retired permalink that leads somewhere its reason.
|
|
11
|
+
*/
|
|
12
|
+
permalinks: Record<string, {
|
|
13
|
+
route: string;
|
|
14
|
+
fragment?: string;
|
|
15
|
+
source: string;
|
|
16
|
+
alias?: string;
|
|
17
|
+
retired?: string;
|
|
18
|
+
}>;
|
|
19
|
+
/** The retired permalinks with nowhere to lead in this build, each with why. */
|
|
20
|
+
removed?: Record<string, {
|
|
21
|
+
reason: string;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* What an address's page needs: where it sends the reader, and the
|
|
26
|
+
* parameters it takes; or, for a retired permalink with nowhere to lead,
|
|
27
|
+
* why it was removed.
|
|
28
|
+
*/
|
|
29
|
+
export type Forwarding = {
|
|
30
|
+
to: string;
|
|
31
|
+
dimensions: Record<string, string[]>;
|
|
32
|
+
} | {
|
|
33
|
+
reason: string;
|
|
34
|
+
};
|
|
35
|
+
/** The list's text in a build's site output, or `undefined` when there isn't one. */
|
|
36
|
+
export declare function permalinksText(siteRoot: string): string | undefined;
|
|
37
|
+
/** The list in a build's site output, or `undefined` when there isn't one. */
|
|
38
|
+
export declare function readPermalinks(siteRoot: string): PermalinkList | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* The route pattern for the addresses, as Astro takes it: under `base`, which
|
|
41
|
+
* Astro adds. Throws when the list's path isn't under `base`, since an Astro
|
|
42
|
+
* site serves nothing outside it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function permalinkPattern(listPath: string, base: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* `getStaticPaths` for the route: one page for each permalink in the site
|
|
47
|
+
* output's list, and one for each retired permalink it lists as removed.
|
|
48
|
+
*/
|
|
49
|
+
export declare function forwardingPaths(siteRoot: string): {
|
|
50
|
+
params: {
|
|
51
|
+
id: string;
|
|
52
|
+
};
|
|
53
|
+
props: Forwarding;
|
|
54
|
+
}[];
|