@adkinn/astro-ai-readiness 0.0.7

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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +285 -0
  3. package/dist/chunk-36CGBNB5.js +104 -0
  4. package/dist/chunk-BDGAXJOB.js +42 -0
  5. package/dist/chunk-CADNETPK.js +48 -0
  6. package/dist/chunk-CO2DB4IE.js +141 -0
  7. package/dist/chunk-THSVWYUX.js +42 -0
  8. package/dist/chunk-V22PCH7G.js +26 -0
  9. package/dist/chunk-WP6D4L7O.js +48 -0
  10. package/dist/components/BreadcrumbSchema.astro +22 -0
  11. package/dist/components/CollectionSchema.astro +24 -0
  12. package/dist/components/FAQPageSchema.astro +24 -0
  13. package/dist/components/OrganizationSchema.astro +33 -0
  14. package/dist/components/TechArticleSchema.astro +88 -0
  15. package/dist/components/WebSiteSchema.astro +16 -0
  16. package/dist/components/index.d.ts +7 -0
  17. package/dist/components/index.js +15 -0
  18. package/dist/components/types.d.ts +55 -0
  19. package/dist/components/types.js +0 -0
  20. package/dist/config.d.ts +1044 -0
  21. package/dist/config.js +6 -0
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.js +103 -0
  24. package/dist/outputs/agents-md.d.ts +19 -0
  25. package/dist/outputs/agents-md.js +9 -0
  26. package/dist/outputs/llms-full.d.ts +18 -0
  27. package/dist/outputs/llms-full.js +9 -0
  28. package/dist/outputs/llms-txt.d.ts +19 -0
  29. package/dist/outputs/llms-txt.js +9 -0
  30. package/dist/outputs/mcp-json.d.ts +21 -0
  31. package/dist/outputs/mcp-json.js +9 -0
  32. package/dist/outputs/robots-txt.d.ts +20 -0
  33. package/dist/outputs/robots-txt.js +9 -0
  34. package/dist/utils/json-ld.d.ts +26 -0
  35. package/dist/utils/json-ld.js +7 -0
  36. package/package.json +76 -0
  37. package/schemas/mcp/v1.json +63 -0
@@ -0,0 +1,42 @@
1
+ import {
2
+ writeOutput
3
+ } from "./chunk-V22PCH7G.js";
4
+
5
+ // src/outputs/llms-full.ts
6
+ function composeLlmsFullTxt(config) {
7
+ const { llmsFull, llmsTxt, organization } = config;
8
+ const lines = [];
9
+ lines.push(`# ${llmsFull.title ?? organization.name}`);
10
+ lines.push("");
11
+ const summary = llmsFull.summary ?? llmsTxt?.summary;
12
+ if (summary) {
13
+ lines.push(`> ${summary}`);
14
+ lines.push("");
15
+ }
16
+ if (llmsFull.content) {
17
+ lines.push(llmsFull.content.trimEnd());
18
+ lines.push("");
19
+ }
20
+ if (llmsFull.sections) {
21
+ for (const section of llmsFull.sections) {
22
+ lines.push(`## ${section.title}`);
23
+ lines.push("");
24
+ lines.push(section.content.trimEnd());
25
+ lines.push("");
26
+ }
27
+ }
28
+ return lines.join("\n").replace(/\n+$/, "\n");
29
+ }
30
+ async function writeLlmsFullTxt(config, dir, logger) {
31
+ if (!config.llmsFull) return;
32
+ const content = composeLlmsFullTxt(
33
+ config
34
+ );
35
+ const target = new URL("llms-full.txt", dir);
36
+ await writeOutput(target, content, "llms-full.txt", logger);
37
+ }
38
+
39
+ export {
40
+ composeLlmsFullTxt,
41
+ writeLlmsFullTxt
42
+ };
@@ -0,0 +1,26 @@
1
+ // src/outputs/write-output.ts
2
+ import { mkdir, writeFile } from "fs/promises";
3
+ async function writeOutput(target, content, label, logger, ensureDir) {
4
+ if (ensureDir) {
5
+ await mkdir(ensureDir, { recursive: true });
6
+ }
7
+ try {
8
+ await writeFile(target, content, { encoding: "utf-8", flag: "wx" });
9
+ logger.info(`wrote ${label} (${content.length} bytes)`);
10
+ } catch (err) {
11
+ const code = err?.code;
12
+ if (code === "EEXIST") {
13
+ logger.warn(
14
+ `${label} already exists \u2014 leaving your file untouched. Delete it if you want @adkinn/astro-ai-readiness to generate ${label}.`
15
+ );
16
+ return;
17
+ }
18
+ const msg = err instanceof Error ? err.message : String(err);
19
+ logger.warn(`failed to write ${label} at ${target.pathname}: ${msg}`);
20
+ throw err;
21
+ }
22
+ }
23
+
24
+ export {
25
+ writeOutput
26
+ };
@@ -0,0 +1,48 @@
1
+ import {
2
+ writeOutput
3
+ } from "./chunk-V22PCH7G.js";
4
+
5
+ // src/outputs/llms-txt.ts
6
+ function composeLlmsTxt(config) {
7
+ const { llmsTxt, organization } = config;
8
+ const lines = [];
9
+ lines.push(`# ${organization.name}`);
10
+ lines.push("");
11
+ lines.push(`> ${llmsTxt.summary}`);
12
+ lines.push("");
13
+ if (llmsTxt.body) {
14
+ lines.push(llmsTxt.body.trimEnd());
15
+ lines.push("");
16
+ }
17
+ if (llmsTxt.sections && llmsTxt.sections.length > 0) {
18
+ for (const section of llmsTxt.sections) {
19
+ lines.push(`## ${section.title}`);
20
+ lines.push("");
21
+ for (const link of section.links) {
22
+ const desc = link.description ? `: ${link.description}` : "";
23
+ lines.push(`- [${link.title}](${link.url})${desc}`);
24
+ }
25
+ lines.push("");
26
+ }
27
+ }
28
+ if (llmsTxt.deferTo) {
29
+ lines.push("---");
30
+ lines.push("");
31
+ lines.push(`Canonical reference: [${llmsTxt.deferTo.title}](${llmsTxt.deferTo.url})`);
32
+ lines.push("");
33
+ }
34
+ return lines.join("\n").replace(/\n+$/, "\n");
35
+ }
36
+ async function writeLlmsTxt(config, dir, logger) {
37
+ if (!config.llmsTxt) return;
38
+ const content = composeLlmsTxt(
39
+ config
40
+ );
41
+ const target = new URL("llms.txt", dir);
42
+ await writeOutput(target, content, "llms.txt", logger);
43
+ }
44
+
45
+ export {
46
+ composeLlmsTxt,
47
+ writeLlmsTxt
48
+ };
@@ -0,0 +1,22 @@
1
+ ---
2
+ import { jsonLd } from '../utils/json-ld'
3
+ import type { BreadcrumbItem } from './types'
4
+
5
+ interface Props {
6
+ items: BreadcrumbItem[]
7
+ }
8
+
9
+ const { items } = Astro.props
10
+
11
+ const bl = {
12
+ '@context': 'https://schema.org',
13
+ '@type': 'BreadcrumbList',
14
+ itemListElement: items.map((item, index) => ({
15
+ '@type': 'ListItem',
16
+ position: index + 1,
17
+ name: item.name,
18
+ item: item.url,
19
+ })),
20
+ }
21
+ ---
22
+ {items.length > 0 && <script is:inline type="application/ld+json" set:html={jsonLd(bl)}></script>}
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { config } from 'virtual:ai-readiness-config'
3
+ import { jsonLd } from '../utils/json-ld'
4
+
5
+ interface Props {
6
+ name: string
7
+ url: string
8
+ description?: string
9
+ }
10
+
11
+ const { name, url, description } = Astro.props
12
+
13
+ const cp: Record<string, unknown> = {
14
+ '@context': 'https://schema.org',
15
+ '@type': 'CollectionPage',
16
+ name,
17
+ url,
18
+ isPartOf: { '@id': `${config.site}#website` },
19
+ publisher: { '@id': `${config.site}#organization` },
20
+ }
21
+
22
+ if (description) cp.description = description
23
+ ---
24
+ <script type="application/ld+json" is:inline set:html={jsonLd(cp)}></script>
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { jsonLd } from '../utils/json-ld'
3
+ import type { FAQItem } from './types'
4
+
5
+ interface Props {
6
+ items: FAQItem[]
7
+ }
8
+
9
+ const { items } = Astro.props
10
+
11
+ const fp = {
12
+ '@context': 'https://schema.org',
13
+ '@type': 'FAQPage',
14
+ mainEntity: items.map((item) => ({
15
+ '@type': 'Question',
16
+ name: item.question,
17
+ acceptedAnswer: {
18
+ '@type': 'Answer',
19
+ text: item.answer,
20
+ },
21
+ })),
22
+ }
23
+ ---
24
+ {items.length > 0 && <script is:inline type="application/ld+json" set:html={jsonLd(fp)}></script>}
@@ -0,0 +1,33 @@
1
+ ---
2
+ import { config } from 'virtual:ai-readiness-config'
3
+ import { jsonLd } from '../utils/json-ld'
4
+
5
+ const org = config.organization
6
+
7
+ type SchemaJson = Record<string, unknown>
8
+
9
+ const orgLd: SchemaJson = {
10
+ '@context': 'https://schema.org',
11
+ '@type': 'Organization',
12
+ '@id': `${config.site}#organization`,
13
+ name: org.name,
14
+ }
15
+
16
+ if (org.url) orgLd.url = org.url
17
+ if (org.logo) orgLd.logo = org.logo
18
+ if (org.foundingDate) orgLd.foundingDate = org.foundingDate
19
+ if (org.knowsAbout && org.knowsAbout.length > 0) orgLd.knowsAbout = org.knowsAbout
20
+ if (org.areaServed) orgLd.areaServed = org.areaServed
21
+
22
+ if (org.founder) {
23
+ const founder: SchemaJson = {
24
+ '@type': 'Person',
25
+ name: org.founder.name,
26
+ }
27
+ if (org.founder.jobTitle) founder.jobTitle = org.founder.jobTitle
28
+ if (org.founder.description) founder.description = org.founder.description
29
+ if (org.founder.sameAs && org.founder.sameAs.length > 0) founder.sameAs = org.founder.sameAs
30
+ orgLd.founder = founder
31
+ }
32
+ ---
33
+ <script type="application/ld+json" is:inline set:html={jsonLd(orgLd)}></script>
@@ -0,0 +1,88 @@
1
+ ---
2
+ import { config } from 'virtual:ai-readiness-config'
3
+ import { jsonLd } from '../utils/json-ld'
4
+ import type { TechArticleAuthor, TechArticleImage } from './types'
5
+
6
+ interface Props {
7
+ // Required
8
+ headline: string
9
+ description: string
10
+ datePublished: string
11
+
12
+ // Optional — common
13
+ dateModified?: string
14
+ author?: TechArticleAuthor
15
+ image?: TechArticleImage
16
+ url?: string
17
+
18
+ // Optional — Schema.org TechArticle extensions
19
+ articleSection?: string
20
+ keywords?: string[]
21
+ proficiencyLevel?: string
22
+ dependencies?: string[]
23
+ }
24
+
25
+ const {
26
+ headline,
27
+ description,
28
+ datePublished,
29
+ dateModified,
30
+ author,
31
+ image,
32
+ url,
33
+ articleSection,
34
+ keywords,
35
+ proficiencyLevel,
36
+ dependencies,
37
+ } = Astro.props
38
+
39
+ // D-21: author defaults to a Person synthesized from config.organization.founder.
40
+ // Founder-precondition guard: if author is omitted AND founder is unset, fail loudly
41
+ // at build time rather than tighten the global schema (which would break consumers
42
+ // who don't use TechArticle and don't set founder).
43
+ const founder = config.organization.founder
44
+ let resolvedAuthor: TechArticleAuthor
45
+ if (author) {
46
+ resolvedAuthor = author
47
+ } else {
48
+ if (!founder) {
49
+ throw new Error(
50
+ 'TechArticleSchema: `author` prop omitted and `config.organization.founder` ' +
51
+ 'is unset. Either pass an explicit `author` prop, or add a `founder` block to ' +
52
+ 'the `organization` config in your `aiReadiness({...})` integration call.'
53
+ )
54
+ }
55
+ resolvedAuthor = {
56
+ name: founder.name,
57
+ ...(founder.sameAs && founder.sameAs[0] && { url: founder.sameAs[0] }),
58
+ }
59
+ }
60
+
61
+ const resolvedImage =
62
+ typeof image === 'string'
63
+ ? { '@type': 'ImageObject', url: image }
64
+ : image
65
+ ? { '@type': 'ImageObject', ...image }
66
+ : undefined
67
+
68
+ const resolvedUrl = url ?? new URL(Astro.url.pathname, config.site).toString()
69
+
70
+ const ta: Record<string, unknown> = {
71
+ '@context': 'https://schema.org',
72
+ '@type': 'TechArticle',
73
+ headline,
74
+ description,
75
+ datePublished,
76
+ dateModified: dateModified ?? datePublished,
77
+ author: { '@type': 'Person', ...resolvedAuthor },
78
+ publisher: { '@id': `${config.site}#organization` },
79
+ url: resolvedUrl,
80
+ }
81
+
82
+ if (resolvedImage) ta.image = resolvedImage
83
+ if (articleSection) ta.articleSection = articleSection
84
+ if (keywords && keywords.length > 0) ta.keywords = keywords.join(', ')
85
+ if (proficiencyLevel) ta.proficiencyLevel = proficiencyLevel
86
+ if (dependencies && dependencies.length > 0) ta.dependencies = dependencies.join(', ')
87
+ ---
88
+ <script is:inline type="application/ld+json" set:html={jsonLd(ta)}></script>
@@ -0,0 +1,16 @@
1
+ ---
2
+ import { config } from 'virtual:ai-readiness-config'
3
+ import { jsonLd } from '../utils/json-ld'
4
+
5
+ const ws: Record<string, unknown> = {
6
+ '@context': 'https://schema.org',
7
+ '@type': 'WebSite',
8
+ '@id': `${config.site}#website`,
9
+ name: config.webSite?.name ?? config.organization.name,
10
+ url: config.site,
11
+ publisher: { '@id': `${config.site}#organization` },
12
+ }
13
+
14
+ if (config.webSite?.description) ws.description = config.webSite.description
15
+ ---
16
+ <script type="application/ld+json" is:inline set:html={jsonLd(ws)}></script>
@@ -0,0 +1,7 @@
1
+ export { default as OrganizationSchema } from './OrganizationSchema.astro';
2
+ export { default as WebSiteSchema } from './WebSiteSchema.astro';
3
+ export { default as CollectionSchema } from './CollectionSchema.astro';
4
+ export { default as BreadcrumbSchema } from './BreadcrumbSchema.astro';
5
+ export { default as FAQPageSchema } from './FAQPageSchema.astro';
6
+ export { default as TechArticleSchema } from './TechArticleSchema.astro';
7
+ export { BreadcrumbItem, FAQItem, TechArticleAuthor, TechArticleImage } from './types.js';
@@ -0,0 +1,15 @@
1
+ // src/components/index.ts
2
+ import { default as default2 } from "./OrganizationSchema.astro";
3
+ import { default as default3 } from "./WebSiteSchema.astro";
4
+ import { default as default4 } from "./CollectionSchema.astro";
5
+ import { default as default5 } from "./BreadcrumbSchema.astro";
6
+ import { default as default6 } from "./FAQPageSchema.astro";
7
+ import { default as default7 } from "./TechArticleSchema.astro";
8
+ export {
9
+ default5 as BreadcrumbSchema,
10
+ default4 as CollectionSchema,
11
+ default6 as FAQPageSchema,
12
+ default2 as OrganizationSchema,
13
+ default7 as TechArticleSchema,
14
+ default3 as WebSiteSchema
15
+ };
@@ -0,0 +1,55 @@
1
+ import './OrganizationSchema.astro';
2
+ import './WebSiteSchema.astro';
3
+ import './CollectionSchema.astro';
4
+ import './BreadcrumbSchema.astro';
5
+ import './FAQPageSchema.astro';
6
+ import './TechArticleSchema.astro';
7
+
8
+ /**
9
+ * Shared prop-shape types for components that need declarable interfaces
10
+ * (items-array element shapes, heavy-props nested-object shapes).
11
+ *
12
+ * @internal
13
+ * Consumers should import from the barrel:
14
+ * `import type { BreadcrumbItem, FAQItem, TechArticleAuthor, TechArticleImage } from '@adkinn/astro-ai-readiness/components'`
15
+ * The `/components/types` subpath is intentionally not exposed in
16
+ * `package.json.exports` — deep-importing
17
+ * `@adkinn/astro-ai-readiness/components/types` will fail with
18
+ * `ERR_PACKAGE_PATH_NOT_EXPORTED`. The file ships as a build artifact
19
+ * so internal relative imports (`./types`) work; the barrel is the
20
+ * public surface. Same pattern as `src/utils/json-ld.ts`.
21
+ *
22
+ * `.astro` files are externalized in `tsup.config.ts`, so their declaration
23
+ * types don't ship via tsup's `dts: true`. Interface types must live in a
24
+ * `.ts` file. This module is the single home for prop shapes — items-array
25
+ * elements (`BreadcrumbItem`, `FAQItem`) and heavy-props nested objects
26
+ * (`TechArticleAuthor`, `TechArticleImage`) — that both the component
27
+ * frontmatter and the package barrel re-export.
28
+ *
29
+ * Components import via relative path (`./types`); the barrel re-exports
30
+ * for consumer-side use.
31
+ */
32
+ interface BreadcrumbItem {
33
+ name: string;
34
+ url: string;
35
+ }
36
+ interface FAQItem {
37
+ question: string;
38
+ answer: string;
39
+ }
40
+ interface TechArticleAuthor {
41
+ name: string;
42
+ url?: string;
43
+ }
44
+ /**
45
+ * URL string is the common case; object form supports width/height/caption
46
+ * when the consumer wants the richer Schema.org ImageObject shape.
47
+ */
48
+ type TechArticleImage = string | {
49
+ url: string;
50
+ width?: number;
51
+ height?: number;
52
+ caption?: string;
53
+ };
54
+
55
+ export type { BreadcrumbItem, FAQItem, TechArticleAuthor, TechArticleImage };
File without changes