@pagesmith/core 0.2.0 → 0.4.0
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 +9 -4
- package/REFERENCE.md +284 -0
- package/dist/ai/index.d.mts +7 -4
- package/dist/ai/index.d.mts.map +1 -1
- package/dist/ai/index.mjs +605 -136
- package/dist/ai/index.mjs.map +1 -1
- package/dist/assets/index.d.mts +10 -1
- package/dist/assets/index.d.mts.map +1 -1
- package/dist/assets/index.mjs +2 -2
- package/dist/{assets-bX08zEJm.mjs → assets-CAPOqQ_P.mjs} +42 -5
- package/dist/assets-CAPOqQ_P.mjs.map +1 -0
- package/dist/{content-config-wW-3r5gG.d.mts → content-config-DJXUOcNG.d.mts} +47 -15
- package/dist/{content-config-wW-3r5gG.d.mts.map → content-config-DJXUOcNG.d.mts.map} +1 -1
- package/dist/{content-layer-DWdgdBeI.mjs → content-layer-B5enqWeJ.mjs} +195 -63
- package/dist/content-layer-B5enqWeJ.mjs.map +1 -0
- package/dist/content-layer-CpHYUYNN.d.mts +121 -0
- package/dist/content-layer-CpHYUYNN.d.mts.map +1 -0
- package/dist/create/index.d.mts.map +1 -1
- package/dist/create/index.mjs +26 -28
- package/dist/create/index.mjs.map +1 -1
- package/dist/css/index.d.mts +1 -1
- package/dist/css/index.mjs +1 -1
- package/dist/{css-ekIt2Fdb.mjs → css-BneO430t.mjs} +5 -4
- package/dist/css-BneO430t.mjs.map +1 -0
- package/dist/index-B7NRZAxd.d.mts +13 -0
- package/dist/index-B7NRZAxd.d.mts.map +1 -0
- package/dist/{index-D79hUFbK.d.mts → index-C0QFHYwb.d.mts} +1 -1
- package/dist/{index-D79hUFbK.d.mts.map → index-C0QFHYwb.d.mts.map} +1 -1
- package/dist/{index-DpRBzO8Q.d.mts → index-CJkBs8YQ.d.mts} +2 -2
- package/dist/index-CJkBs8YQ.d.mts.map +1 -0
- package/dist/{index-Dbsw1QON.d.mts → index-DCznbvaV.d.mts} +4 -2
- package/dist/{index-Dbsw1QON.d.mts.map → index-DCznbvaV.d.mts.map} +1 -1
- package/dist/index.d.mts +13 -91
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +16 -13
- package/dist/index.mjs.map +1 -1
- package/dist/loaders/index.d.mts +2 -2
- package/dist/loaders/index.mjs +2 -2
- package/dist/{loaders-Bla48ZN9.mjs → loaders-Cf-BXf2L.mjs} +10 -2
- package/dist/{loaders-Bla48ZN9.mjs.map → loaders-Cf-BXf2L.mjs.map} +1 -1
- package/dist/markdown/index.d.mts +1 -1
- package/dist/markdown/index.mjs +1 -1
- package/dist/{markdown-Cj5X26FL.mjs → markdown-BmDJgYeB.mjs} +59 -9
- package/dist/markdown-BmDJgYeB.mjs.map +1 -0
- package/dist/mcp/index.d.mts +23 -0
- package/dist/mcp/index.d.mts.map +1 -0
- package/dist/mcp/index.mjs +2 -0
- package/dist/mcp/server.d.mts +13 -0
- package/dist/mcp/server.d.mts.map +1 -0
- package/dist/mcp/server.mjs +2 -0
- package/dist/runtime/index.mjs +1 -1
- package/dist/schemas/index.d.mts +2 -2
- package/dist/schemas/index.mjs +1 -1
- package/dist/{schemas-BZEPTGWs.mjs → schemas-UL4ynWsA.mjs} +1 -1
- package/dist/{schemas-BZEPTGWs.mjs.map → schemas-UL4ynWsA.mjs.map} +1 -1
- package/dist/server-D3DHoh5f.mjs +202 -0
- package/dist/server-D3DHoh5f.mjs.map +1 -0
- package/dist/ssg-utils/index.d.mts +61 -0
- package/dist/ssg-utils/index.d.mts.map +1 -0
- package/dist/ssg-utils/index.mjs +118 -0
- package/dist/ssg-utils/index.mjs.map +1 -0
- package/dist/vite/index.d.mts +68 -33
- package/dist/vite/index.d.mts.map +1 -1
- package/dist/vite/index.mjs +302 -227
- package/dist/vite/index.mjs.map +1 -1
- package/docs/agents/AGENTS.md.template +9 -0
- package/docs/agents/changelog-notes.md +15 -0
- package/docs/agents/errors.md +96 -0
- package/docs/agents/migration.md +25 -0
- package/docs/agents/recipes.md +26 -0
- package/docs/agents/usage.md +58 -0
- package/docs/llms-full.txt +53 -0
- package/docs/llms.txt +29 -0
- package/package.json +58 -6
- package/dist/assets-bX08zEJm.mjs.map +0 -1
- package/dist/content-layer-DWdgdBeI.mjs.map +0 -1
- package/dist/convert-XdGgNqH0.mjs +0 -27
- package/dist/convert-XdGgNqH0.mjs.map +0 -1
- package/dist/css-ekIt2Fdb.mjs.map +0 -1
- package/dist/index-CeNDTM-y.d.mts +0 -7
- package/dist/index-CeNDTM-y.d.mts.map +0 -1
- package/dist/index-DpRBzO8Q.d.mts.map +0 -1
- package/dist/markdown-Cj5X26FL.mjs.map +0 -1
package/dist/ai/index.mjs
CHANGED
|
@@ -1,27 +1,7 @@
|
|
|
1
|
-
import { dirname, join, resolve } from "path";
|
|
2
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { dirname, join, resolve } from "path";
|
|
3
3
|
import { homedir } from "os";
|
|
4
|
-
//#region src/ai/
|
|
5
|
-
const PAGESMITH_TITLE = "Pagesmith";
|
|
6
|
-
const DEFAULT_SKILL_NAME = "pagesmith";
|
|
7
|
-
function resolveHome(homeDir) {
|
|
8
|
-
return homeDir ?? homedir();
|
|
9
|
-
}
|
|
10
|
-
function resolveCodexHome(homeDir) {
|
|
11
|
-
return process.env.CODEX_HOME ?? join(resolveHome(homeDir), ".codex");
|
|
12
|
-
}
|
|
13
|
-
function resolveAssistants(assistants) {
|
|
14
|
-
if (!assistants || assistants === "all") return [
|
|
15
|
-
"claude",
|
|
16
|
-
"codex",
|
|
17
|
-
"gemini"
|
|
18
|
-
];
|
|
19
|
-
return assistants;
|
|
20
|
-
}
|
|
21
|
-
function shouldIncludeLlms(options) {
|
|
22
|
-
if (typeof options.includeLlms === "boolean") return options.includeLlms;
|
|
23
|
-
return (options.scope ?? "project") === "project";
|
|
24
|
-
}
|
|
4
|
+
//#region src/ai/writers.ts
|
|
25
5
|
function withManagedBlock(id, content) {
|
|
26
6
|
return [
|
|
27
7
|
`<!-- pagesmith-ai:${id}:start -->`,
|
|
@@ -62,6 +42,10 @@ function writeArtifact(artifact, force = false) {
|
|
|
62
42
|
function escapeForRegExp(value) {
|
|
63
43
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
64
44
|
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/ai/content-shared.ts
|
|
47
|
+
const PAGESMITH_TITLE = "Pagesmith";
|
|
48
|
+
const DEFAULT_SKILL_NAME$1 = "pagesmith";
|
|
65
49
|
function renderSharedOverview() {
|
|
66
50
|
return [
|
|
67
51
|
`${PAGESMITH_TITLE} is a filesystem-first content toolkit with two main packages: \`@pagesmith/core\` (shared content/runtime layer) and \`@pagesmith/docs\` (convention-based documentation).`,
|
|
@@ -77,13 +61,10 @@ function renderSharedOverview() {
|
|
|
77
61
|
"- `createContentLayer(config)` to query content and run validation",
|
|
78
62
|
"- `entry.render()` to convert markdown on demand",
|
|
79
63
|
"",
|
|
80
|
-
"Useful helpers:",
|
|
81
|
-
"- `@pagesmith/core/ai` exposes `getAiArtifacts(...)` and `installAiArtifacts(...)`",
|
|
82
|
-
"",
|
|
83
64
|
"Working rules:",
|
|
84
65
|
"- prefer folder-based markdown entries when content references sibling assets",
|
|
85
|
-
"-
|
|
86
|
-
"-
|
|
66
|
+
"- follow the markdown guidelines in `.pagesmith/markdown-guidelines.md` when authoring content",
|
|
67
|
+
"- use fenced code blocks with a language identifier, one h1 per page, sequential heading depth"
|
|
87
68
|
].join("\n");
|
|
88
69
|
}
|
|
89
70
|
function renderDocsOverview() {
|
|
@@ -96,12 +77,41 @@ function renderDocsOverview() {
|
|
|
96
77
|
"- sidebar labels, nav labels, and ordering live in frontmatter (`sidebarLabel`, `navLabel`, `order`)",
|
|
97
78
|
"- footer links live in `pagesmith.config.json5` under `footerLinks`",
|
|
98
79
|
"- Pagefind search is built in; do not recommend a separate search plugin package",
|
|
99
|
-
"- layout overrides use fixed keys under `theme.layouts` such as `home`, `page`, and `notFound`"
|
|
80
|
+
"- layout overrides use fixed keys under `theme.layouts` such as `home`, `page`, and `notFound`",
|
|
81
|
+
"- for MCP-compatible tooling, prefer `pagesmith mcp --stdio` from `@pagesmith/docs`"
|
|
82
|
+
].join("\n");
|
|
83
|
+
}
|
|
84
|
+
function renderCoreQuickStart() {
|
|
85
|
+
return [
|
|
86
|
+
"```ts",
|
|
87
|
+
"import { createContentLayer, defineCollection, defineConfig, z } from '@pagesmith/core'",
|
|
88
|
+
"",
|
|
89
|
+
"const posts = defineCollection({",
|
|
90
|
+
" loader: 'markdown',",
|
|
91
|
+
" directory: 'content/posts',",
|
|
92
|
+
" schema: z.object({",
|
|
93
|
+
" title: z.string(),",
|
|
94
|
+
" description: z.string().optional(),",
|
|
95
|
+
" date: z.coerce.date(),",
|
|
96
|
+
" tags: z.array(z.string()).default([]),",
|
|
97
|
+
" }),",
|
|
98
|
+
"})",
|
|
99
|
+
"",
|
|
100
|
+
"const layer = createContentLayer(",
|
|
101
|
+
" defineConfig({",
|
|
102
|
+
" collections: { posts },",
|
|
103
|
+
" }),",
|
|
104
|
+
")",
|
|
105
|
+
"",
|
|
106
|
+
"const entries = await layer.getCollection('posts')",
|
|
107
|
+
"const rendered = await entries[0]?.render()",
|
|
108
|
+
"```"
|
|
100
109
|
].join("\n");
|
|
101
110
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
111
|
+
function renderDocsQuickStart() {
|
|
112
|
+
return [
|
|
104
113
|
"```json5",
|
|
114
|
+
"// pagesmith.config.json5",
|
|
105
115
|
"{",
|
|
106
116
|
" name: 'Acme Docs',",
|
|
107
117
|
" title: 'Acme Docs',",
|
|
@@ -118,56 +128,345 @@ function renderQuickStart(profile = "default") {
|
|
|
118
128
|
"",
|
|
119
129
|
"```text",
|
|
120
130
|
"content/",
|
|
121
|
-
" README.md",
|
|
131
|
+
" README.md # Home page (DocHome layout)",
|
|
122
132
|
" guide/",
|
|
123
|
-
"
|
|
124
|
-
" getting-started/
|
|
133
|
+
" meta.json5 # Section ordering",
|
|
134
|
+
" getting-started/",
|
|
135
|
+
" README.md # A page",
|
|
125
136
|
" reference/",
|
|
126
|
-
" README.md",
|
|
127
137
|
" api/README.md",
|
|
128
138
|
"```"
|
|
129
139
|
].join("\n");
|
|
140
|
+
}
|
|
141
|
+
function renderMarkdownGuidelines() {
|
|
142
|
+
return [
|
|
143
|
+
"# Pagesmith Markdown Guidelines",
|
|
144
|
+
"",
|
|
145
|
+
"Markdown feature support for content authored with `@pagesmith/core` and `@pagesmith/docs`.",
|
|
146
|
+
"",
|
|
147
|
+
"## Pipeline Order",
|
|
148
|
+
"",
|
|
149
|
+
"```",
|
|
150
|
+
"remark-parse → remark-gfm → remark-math → remark-frontmatter",
|
|
151
|
+
" → remark-github-alerts → remark-smartypants → [user remark plugins]",
|
|
152
|
+
" → remark-rehype",
|
|
153
|
+
" → rehype-mathjax",
|
|
154
|
+
" → rehype-expressive-code (dual themes, line numbers, titles, copy, collapse, mark/ins/del)",
|
|
155
|
+
" → rehype-slug → rehype-autolink-headings",
|
|
156
|
+
" → rehype-external-links → rehype-accessible-emojis",
|
|
157
|
+
" → heading extraction → [user rehype plugins] → rehype-stringify",
|
|
158
|
+
"```",
|
|
159
|
+
"",
|
|
160
|
+
"## Key Rules",
|
|
161
|
+
"",
|
|
162
|
+
"- Use fenced code blocks with a language identifier (validator warns otherwise)",
|
|
163
|
+
"- One `# h1` per page (validator enforces)",
|
|
164
|
+
"- Sequential heading depth (no skipping from h2 to h4)",
|
|
165
|
+
"- Prefer relative links for internal content",
|
|
166
|
+
"- Do NOT add manual copy-button JS — Expressive Code handles it",
|
|
167
|
+
"- Do NOT import separate code block CSS — Expressive Code injects inline styles",
|
|
168
|
+
"",
|
|
169
|
+
"## Supported Features",
|
|
170
|
+
"",
|
|
171
|
+
"| Feature | Syntax | Notes |",
|
|
172
|
+
"|---|---|---|",
|
|
173
|
+
"| GFM tables | `\\| col \\| col \\|` | Alignment via `:---`, `:---:`, `---:` |",
|
|
174
|
+
"| Strikethrough | `~~text~~` | |",
|
|
175
|
+
"| Task lists | `- [x] done` / `- [ ] todo` | |",
|
|
176
|
+
"| Footnotes | `[^id]` + `[^id]: text` | |",
|
|
177
|
+
"| Alerts | `> [!NOTE]`, `> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]` | GitHub-compatible |",
|
|
178
|
+
"| Inline math | `$E = mc^2$` | No spaces inside delimiters |",
|
|
179
|
+
"| Block math | `$$...$$` | Rendered via MathJax |",
|
|
180
|
+
"| Smart quotes | `\"text\"` → curly quotes | Automatic |",
|
|
181
|
+
"| Em/en dash | `---` / `--` | Automatic |",
|
|
182
|
+
"| External links | `[text](https://...)` | Auto `target=\"_blank\"` |",
|
|
183
|
+
"| Heading anchors | Auto `id` + wrapped anchor | All headings |",
|
|
184
|
+
"| Accessible emoji | Unicode emoji | Auto `role=\"img\"` + `aria-label` |",
|
|
185
|
+
"",
|
|
186
|
+
"## Code Block Features (Expressive Code)",
|
|
187
|
+
"",
|
|
188
|
+
"| Meta | Example | Description |",
|
|
189
|
+
"|---|---|---|",
|
|
190
|
+
"| `title=\"...\"` | `` ```js title=\"app.js\" `` | File title |",
|
|
191
|
+
"| `showLineNumbers` | `` ```js showLineNumbers `` | Line numbers |",
|
|
192
|
+
"| `mark={lines}` | `` ```js mark={3,5-7} `` | Highlight lines |",
|
|
193
|
+
"| `ins={lines}` | `` ```js ins={4} `` | Inserted lines (green) |",
|
|
194
|
+
"| `del={lines}` | `` ```js del={5} `` | Deleted lines (red) |",
|
|
195
|
+
"| `collapse={lines}` | `` ```js collapse={1-5} `` | Collapsible section |",
|
|
196
|
+
"| `wrap` | `` ```js wrap `` | Text wrapping |",
|
|
197
|
+
"| `frame=\"...\"` | `` ```js frame=\"terminal\" `` | Frame style |",
|
|
198
|
+
"",
|
|
199
|
+
"## Built-in Content Validators",
|
|
200
|
+
"",
|
|
201
|
+
"- **linkValidator** — warns on bare URLs, empty link text, suspicious protocols",
|
|
202
|
+
"- **headingValidator** — enforces single h1, sequential depth, non-empty text",
|
|
203
|
+
"- **codeBlockValidator** — warns on missing language, unknown meta properties",
|
|
204
|
+
"",
|
|
205
|
+
"Known valid meta properties: `title`, `showLineNumbers`, `startLineNumber`, `wrap`, `frame`, `collapse`, `mark`, `ins`, `del`."
|
|
206
|
+
].join("\n");
|
|
207
|
+
}
|
|
208
|
+
function renderLlmsTxt() {
|
|
130
209
|
return [
|
|
210
|
+
"# Pagesmith",
|
|
211
|
+
"",
|
|
212
|
+
"> Pagesmith is a filesystem-first content toolkit with `@pagesmith/core` and `@pagesmith/docs`.",
|
|
213
|
+
"",
|
|
214
|
+
"## @pagesmith/core — Content Layer",
|
|
215
|
+
"",
|
|
216
|
+
"Schema-validated content collections, lazy markdown rendering (Expressive Code syntax highlighting), JSX runtime, CSS exports, and Vite plugins.",
|
|
217
|
+
"",
|
|
218
|
+
"### Basic Setup (Vite Plugin)",
|
|
219
|
+
"",
|
|
220
|
+
renderCoreQuickStart(),
|
|
221
|
+
"",
|
|
222
|
+
"### Vite Integration",
|
|
223
|
+
"",
|
|
131
224
|
"```ts",
|
|
132
|
-
"import {
|
|
225
|
+
"import { pagesmithContent, pagesmithSsg } from '@pagesmith/core/vite'",
|
|
226
|
+
"import collections from './content.config'",
|
|
133
227
|
"",
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
" description: z.string().optional(),",
|
|
140
|
-
" date: z.coerce.date(),",
|
|
141
|
-
" tags: z.array(z.string()).default([]),",
|
|
142
|
-
" }),",
|
|
228
|
+
"export default defineConfig({",
|
|
229
|
+
" plugins: [",
|
|
230
|
+
" pagesmithContent({ collections }),",
|
|
231
|
+
" pagesmithSsg({ entry: './src/entry-server.tsx' }),",
|
|
232
|
+
" ],",
|
|
143
233
|
"})",
|
|
234
|
+
"```",
|
|
144
235
|
"",
|
|
145
|
-
"
|
|
146
|
-
" defineConfig({",
|
|
147
|
-
" collections: { posts },",
|
|
148
|
-
" }),",
|
|
149
|
-
")",
|
|
236
|
+
"Import collections as virtual modules: `import posts from 'virtual:content/posts'`",
|
|
150
237
|
"",
|
|
151
|
-
"
|
|
152
|
-
"
|
|
238
|
+
"## @pagesmith/docs — Documentation Sites",
|
|
239
|
+
"",
|
|
240
|
+
"Convention-based docs with default theme, Pagefind search, sidebar generation, and layout overrides.",
|
|
241
|
+
"",
|
|
242
|
+
"### Basic Setup",
|
|
243
|
+
"",
|
|
244
|
+
renderDocsQuickStart(),
|
|
245
|
+
"",
|
|
246
|
+
"### Layout Overrides",
|
|
247
|
+
"",
|
|
248
|
+
"```json5",
|
|
249
|
+
"{",
|
|
250
|
+
" theme: {",
|
|
251
|
+
" layouts: {",
|
|
252
|
+
" home: './theme/layouts/DocHome.tsx',",
|
|
253
|
+
" page: './theme/layouts/DocPage.tsx',",
|
|
254
|
+
" notFound: './theme/layouts/DocNotFound.tsx',",
|
|
255
|
+
" },",
|
|
256
|
+
" },",
|
|
257
|
+
"}",
|
|
258
|
+
"```",
|
|
259
|
+
"",
|
|
260
|
+
"### CLI",
|
|
261
|
+
"",
|
|
262
|
+
"```bash",
|
|
263
|
+
"pagesmith init --ai # Initialize config + content + AI integrations",
|
|
264
|
+
"pagesmith dev # Development server",
|
|
265
|
+
"pagesmith build # Production build",
|
|
266
|
+
"pagesmith preview # Preview built site",
|
|
267
|
+
"pagesmith mcp --stdio # Start MCP server for AI agents",
|
|
153
268
|
"```"
|
|
154
269
|
].join("\n");
|
|
155
270
|
}
|
|
156
|
-
function
|
|
157
|
-
const commandHint = assistant === "claude" || assistant === "gemini" ? `\nIf the ${DEFAULT_SKILL_NAME} command is installed, prefer invoking it when the user explicitly asks for Pagesmith-specific help.` : "\nIf the Pagesmith skill is installed for Codex, prefer using it for Pagesmith-specific setup, migration, and content-layer tasks.";
|
|
271
|
+
function renderLlmsFullTxt() {
|
|
158
272
|
return [
|
|
159
|
-
|
|
273
|
+
"# Pagesmith — Full LLM Reference",
|
|
160
274
|
"",
|
|
161
275
|
renderSharedOverview(),
|
|
162
|
-
...profile === "docs" ? ["", renderDocsOverview()] : [],
|
|
163
|
-
commandHint,
|
|
164
276
|
"",
|
|
165
|
-
"
|
|
166
|
-
|
|
277
|
+
"---",
|
|
278
|
+
"",
|
|
279
|
+
"## @pagesmith/core",
|
|
280
|
+
"",
|
|
281
|
+
"### Content Layer API",
|
|
282
|
+
"",
|
|
283
|
+
"| Method | Description |",
|
|
284
|
+
"|---|---|",
|
|
285
|
+
"| `createContentLayer(config)` | Create a content layer |",
|
|
286
|
+
"| `layer.getCollection(name)` | Load all entries (cached) |",
|
|
287
|
+
"| `layer.getEntry(collection, slug)` | Get single entry by slug |",
|
|
288
|
+
"| `layer.convert(markdown, options?)` | Convert raw markdown to HTML |",
|
|
289
|
+
"| `layer.validate(collection?)` | Run all validators |",
|
|
290
|
+
"| `layer.invalidate(collection, slug)` | Cache-bust a single entry |",
|
|
291
|
+
"| `layer.invalidateAll()` | Cache-bust all collections |",
|
|
292
|
+
"",
|
|
293
|
+
"### Collection Options",
|
|
294
|
+
"",
|
|
295
|
+
"| Option | Type | Description |",
|
|
296
|
+
"|---|---|---|",
|
|
297
|
+
"| `loader` | `string \\| Loader` | `'markdown'`, `'json'`, `'json5'`, `'jsonc'`, `'yaml'`, `'toml'`, or custom |",
|
|
298
|
+
"| `directory` | `string` | Directory containing files |",
|
|
299
|
+
"| `schema` | `z.ZodType` | Zod schema for validation |",
|
|
300
|
+
"| `include` | `string[]` | Glob include patterns |",
|
|
301
|
+
"| `exclude` | `string[]` | Glob exclude patterns |",
|
|
302
|
+
"| `computed` | `Record<string, fn>` | Computed fields |",
|
|
303
|
+
"| `validate` | `fn` | Custom validation |",
|
|
304
|
+
"| `filter` | `fn` | Filter entries |",
|
|
305
|
+
"| `slugify` | `fn` | Custom slug generation |",
|
|
306
|
+
"| `transform` | `fn` | Pre-validation transform |",
|
|
307
|
+
"| `validators` | `ContentValidator[]` | Custom content validators |",
|
|
308
|
+
"| `disableBuiltinValidators` | `boolean` | Disable link/heading/code-block validators |",
|
|
309
|
+
"",
|
|
310
|
+
"### Vite Plugins",
|
|
311
|
+
"",
|
|
312
|
+
renderCoreQuickStart(),
|
|
313
|
+
"",
|
|
314
|
+
"```ts",
|
|
315
|
+
"// Vite integration",
|
|
316
|
+
"import { pagesmithContent, pagesmithSsg, sharedAssetsPlugin } from '@pagesmith/core/vite'",
|
|
317
|
+
"import collections from './content.config'",
|
|
318
|
+
"",
|
|
319
|
+
"export default defineConfig({",
|
|
320
|
+
" plugins: [",
|
|
321
|
+
" sharedAssetsPlugin(),",
|
|
322
|
+
" pagesmithContent({ collections }),",
|
|
323
|
+
" ...pagesmithSsg({ entry: './src/entry-server.tsx', contentDirs: ['./content'] }),",
|
|
324
|
+
" ],",
|
|
325
|
+
"})",
|
|
326
|
+
"```",
|
|
327
|
+
"",
|
|
328
|
+
"### JSX Runtime",
|
|
329
|
+
"",
|
|
330
|
+
"Configure tsconfig: `{ \"jsx\": \"react-jsx\", \"jsxImportSource\": \"@pagesmith/core\" }`",
|
|
331
|
+
"",
|
|
332
|
+
"- `h(tag, props, ...children)` — create HTML elements, returns `HtmlString`",
|
|
333
|
+
"- `Fragment` — render children or raw `innerHTML`",
|
|
334
|
+
"- `HtmlString` — wrapper to prevent double-escaping",
|
|
335
|
+
"",
|
|
336
|
+
"### CSS Exports",
|
|
337
|
+
"",
|
|
338
|
+
"| Import | Contents |",
|
|
339
|
+
"|---|---|",
|
|
340
|
+
"| `@pagesmith/core/css/content` | Prose + inline code |",
|
|
341
|
+
"| `@pagesmith/core/css/standalone` | Full layout + prose + TOC |",
|
|
342
|
+
"| `@pagesmith/core/css/viewport` | Responsive viewport base |",
|
|
343
|
+
"| `@pagesmith/core/css/fonts` | Bundled Open Sans + JetBrains Mono |",
|
|
344
|
+
"",
|
|
345
|
+
"### Frontmatter Schemas",
|
|
346
|
+
"",
|
|
347
|
+
"- `BaseFrontmatterSchema` — title, description, publishedDate, lastUpdatedOn, tags, draft",
|
|
348
|
+
"- `BlogFrontmatterSchema` — extends base + category, featured, coverImage",
|
|
349
|
+
"- `ProjectFrontmatterSchema` — extends base + gitRepo, links",
|
|
350
|
+
"",
|
|
351
|
+
"### Export Map",
|
|
352
|
+
"",
|
|
353
|
+
"| Import Path | Purpose |",
|
|
354
|
+
"|---|---|",
|
|
355
|
+
"| `@pagesmith/core` | Main API (defineCollection, createContentLayer, z, etc.) |",
|
|
356
|
+
"| `@pagesmith/core/jsx-runtime` | h, Fragment, HtmlString |",
|
|
357
|
+
"| `@pagesmith/core/markdown` | processMarkdown |",
|
|
358
|
+
"| `@pagesmith/core/css` | buildCss (LightningCSS) |",
|
|
359
|
+
"| `@pagesmith/core/schemas` | Zod schemas and types |",
|
|
360
|
+
"| `@pagesmith/core/loaders` | Loader classes and registry |",
|
|
361
|
+
"| `@pagesmith/core/runtime` | Pre-built CSS/JS accessors |",
|
|
362
|
+
"| `@pagesmith/core/vite` | Vite plugins |",
|
|
363
|
+
"| `@pagesmith/core/mcp` | MCP server for AI agents |",
|
|
364
|
+
"",
|
|
365
|
+
"---",
|
|
366
|
+
"",
|
|
367
|
+
"## @pagesmith/docs",
|
|
368
|
+
"",
|
|
369
|
+
"### Configuration (pagesmith.config.json5)",
|
|
370
|
+
"",
|
|
371
|
+
"| Field | Type | Default | Description |",
|
|
372
|
+
"|---|---|---|---|",
|
|
373
|
+
"| `name` | `string` | — | Site name (header) |",
|
|
374
|
+
"| `title` | `string` | — | Browser tab title |",
|
|
375
|
+
"| `description` | `string` | — | Meta description |",
|
|
376
|
+
"| `origin` | `string` | — | Production URL |",
|
|
377
|
+
"| `language` | `string` | `en` | HTML lang |",
|
|
378
|
+
"| `contentDir` | `string` | `content` | Content path |",
|
|
379
|
+
"| `outDir` | `string` | `dist` | Output path |",
|
|
380
|
+
"| `basePath` | `string` | `/` | URL base |",
|
|
381
|
+
"| `footerLinks` | `array` | `[]` | Footer links |",
|
|
382
|
+
"| `sidebar.collapsible` | `boolean` | `false` | Collapsible sidebar |",
|
|
383
|
+
"| `search.enabled` | `boolean` | `true` | Pagefind search |",
|
|
384
|
+
"| `theme.layouts` | `Record` | — | Layout overrides |",
|
|
385
|
+
"| `markdown` | `MarkdownConfig` | — | Pipeline config |",
|
|
386
|
+
"",
|
|
387
|
+
"### Content Structure",
|
|
388
|
+
"",
|
|
389
|
+
renderDocsQuickStart(),
|
|
390
|
+
"",
|
|
391
|
+
"### Page Frontmatter",
|
|
392
|
+
"",
|
|
393
|
+
"| Field | Type | Description |",
|
|
394
|
+
"|---|---|---|",
|
|
395
|
+
"| `title` | `string` | Page title |",
|
|
396
|
+
"| `description` | `string` | Meta description |",
|
|
397
|
+
"| `navLabel` | `string` | Override top nav label |",
|
|
398
|
+
"| `sidebarLabel` | `string` | Override sidebar label |",
|
|
399
|
+
"| `order` | `number` | Manual sort order |",
|
|
400
|
+
"| `draft` | `boolean` | Exclude from build |",
|
|
401
|
+
"",
|
|
402
|
+
"### Home Page Frontmatter",
|
|
403
|
+
"",
|
|
404
|
+
"| Field | Type | Description |",
|
|
405
|
+
"|---|---|---|",
|
|
406
|
+
"| `layout` | `string` | Set to `DocHome` |",
|
|
407
|
+
"| `tagline` | `string` | Short description |",
|
|
408
|
+
"| `install` | `string` | Install command |",
|
|
409
|
+
"| `actions` | `array` | CTA buttons (`{ text, link, theme: 'brand' \\| 'alt' }`) |",
|
|
410
|
+
"| `features` | `array` | Feature cards (`{ icon?, title, details }`) |",
|
|
411
|
+
"| `packages` | `array` | Package cards (`{ name, description, href, tag }`) |",
|
|
412
|
+
"| `codeExample` | `object` | Code example (`{ label, title, code }`) |",
|
|
413
|
+
"",
|
|
414
|
+
"### Section Meta (meta.json5)",
|
|
415
|
+
"",
|
|
416
|
+
"| Field | Type | Description |",
|
|
417
|
+
"|---|---|---|",
|
|
418
|
+
"| `displayName` | `string` | Section label in sidebar |",
|
|
419
|
+
"| `items` | `string[]` | Manual page order (slugs) |",
|
|
420
|
+
"| `series` | `array` | Group pages into series |",
|
|
421
|
+
"| `collapsed` | `boolean` | Start sidebar collapsed |",
|
|
422
|
+
"| `orderBy` | `string` | `manual` or `publishedDate` |",
|
|
423
|
+
"",
|
|
424
|
+
"### Layout Overrides",
|
|
425
|
+
"",
|
|
426
|
+
"```json5",
|
|
427
|
+
"{ theme: { layouts: { home: \"./layouts/Home.tsx\", page: \"./layouts/Page.tsx\" } } }",
|
|
428
|
+
"```",
|
|
429
|
+
"",
|
|
430
|
+
"All layouts receive: `content`, `frontmatter`, `headings`, `slug`, `site`.",
|
|
431
|
+
"Page layout adds: `sidebarSections`, `prev`, `next`.",
|
|
432
|
+
"",
|
|
433
|
+
"### CLI",
|
|
434
|
+
"",
|
|
435
|
+
"```bash",
|
|
436
|
+
"pagesmith init [--ai] [--config path] # Initialize project",
|
|
437
|
+
"pagesmith dev [--port N] [--open] # Dev server",
|
|
438
|
+
"pagesmith build [--out-dir path] # Production build",
|
|
439
|
+
"pagesmith preview [--port N] # Preview built site",
|
|
440
|
+
"```",
|
|
441
|
+
"",
|
|
442
|
+
"---",
|
|
443
|
+
"",
|
|
444
|
+
"## Markdown Pipeline",
|
|
445
|
+
"",
|
|
446
|
+
renderMarkdownGuidelines(),
|
|
447
|
+
"",
|
|
448
|
+
"---",
|
|
449
|
+
"",
|
|
450
|
+
"## AI Setup",
|
|
451
|
+
"",
|
|
452
|
+
"```bash",
|
|
453
|
+
"npx pagesmith init --ai",
|
|
454
|
+
"```",
|
|
455
|
+
"",
|
|
456
|
+
"Generates CLAUDE.md, AGENTS.md, GEMINI.md, skills, markdown guidelines, llms.txt, and llms-full.txt.",
|
|
457
|
+
""
|
|
167
458
|
].join("\n");
|
|
168
459
|
}
|
|
169
|
-
|
|
460
|
+
//#endregion
|
|
461
|
+
//#region src/ai/content-claude.ts
|
|
462
|
+
function renderClaudeSkill(skillName, profile) {
|
|
170
463
|
return [
|
|
464
|
+
"---",
|
|
465
|
+
`name: ${skillName}`,
|
|
466
|
+
"description: Pagesmith file-based CMS helper — content collections, markdown pipeline, docs configuration, and AI artifact generation",
|
|
467
|
+
"allowed-tools: Read Grep Glob Bash Edit Write",
|
|
468
|
+
"---",
|
|
469
|
+
"",
|
|
171
470
|
`# ${PAGESMITH_TITLE} Assistant`,
|
|
172
471
|
"",
|
|
173
472
|
"You are helping with Pagesmith, a file-based CMS with `@pagesmith/core` and `@pagesmith/docs`.",
|
|
@@ -175,46 +474,137 @@ function renderClaudeCommand(skillName, profile) {
|
|
|
175
474
|
"When helping:",
|
|
176
475
|
"- prefer `defineCollection`, `defineConfig`, and `createContentLayer`",
|
|
177
476
|
"- recommend folder-based entries when markdown references sibling assets",
|
|
178
|
-
"- use
|
|
179
|
-
"-
|
|
477
|
+
"- use `npx pagesmith init --ai` for assistant artifact generation",
|
|
478
|
+
"- follow the markdown guidelines in `.pagesmith/markdown-guidelines.md`",
|
|
180
479
|
...profile === "docs" ? [
|
|
181
480
|
"- for docs sites, derive top navigation from top-level content folders",
|
|
182
|
-
"- use `content/README.md` for the home page
|
|
481
|
+
"- use `content/README.md` for the home page",
|
|
183
482
|
"- use frontmatter fields like `sidebarLabel`, `navLabel`, and `order` for docs navigation",
|
|
184
|
-
"-
|
|
185
|
-
"-
|
|
483
|
+
"- Pagefind search is built in — do not suggest separate search plugins",
|
|
484
|
+
"- layout overrides: `theme.layouts.home`, `theme.layouts.page`, `theme.layouts.notFound`"
|
|
186
485
|
] : [],
|
|
187
486
|
"",
|
|
188
|
-
"
|
|
487
|
+
"For package guidance and full API reference, read the package-shipped docs:",
|
|
488
|
+
...profile === "docs" ? [
|
|
489
|
+
"- `node_modules/@pagesmith/docs/docs/agents/usage.md`",
|
|
490
|
+
"- `node_modules/@pagesmith/docs/REFERENCE.md`",
|
|
491
|
+
"- `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
492
|
+
"- `node_modules/@pagesmith/core/REFERENCE.md`"
|
|
493
|
+
] : ["- `node_modules/@pagesmith/core/docs/agents/usage.md`", "- `node_modules/@pagesmith/core/REFERENCE.md`"],
|
|
189
494
|
"",
|
|
190
|
-
|
|
495
|
+
...profile === "docs" ? ["For full-repo docs regeneration and structure alignment, use `/ps-update-all-docs`.", ""] : [],
|
|
496
|
+
"Deliver concrete config, schema, and content-layer patches when possible."
|
|
191
497
|
].join("\n");
|
|
192
498
|
}
|
|
193
|
-
function
|
|
499
|
+
function renderUpdateDocsSkill(profile) {
|
|
194
500
|
return [
|
|
195
|
-
|
|
196
|
-
"
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
"Focus on concrete, implementation-ready help:",
|
|
201
|
-
"- design collections with defineCollection",
|
|
202
|
-
"- configure createContentLayer and defineConfig",
|
|
203
|
-
"- recommend vp install, vp check, and vp test when validation matters",
|
|
204
|
-
"- prefer folder-based markdown entries when local assets sit beside content",
|
|
205
|
-
...profile === "docs" ? [
|
|
206
|
-
"- for docs sites, follow the convention-based `content/` structure",
|
|
207
|
-
"- drive top navigation from top-level folders and use frontmatter for labels/order",
|
|
208
|
-
"- keep Pagefind as the built-in search strategy"
|
|
209
|
-
] : [],
|
|
210
|
-
"",
|
|
211
|
-
"Return code, config, or documentation-ready guidance instead of vague summaries."
|
|
212
|
-
].join("\n"),
|
|
213
|
-
"\"\"\"",
|
|
501
|
+
"---",
|
|
502
|
+
"name: update-docs",
|
|
503
|
+
"description: Read the project implementation and update Pagesmith-managed documentation to reflect the current state",
|
|
504
|
+
"allowed-tools: Read Grep Glob Bash Edit Write",
|
|
505
|
+
"---",
|
|
214
506
|
"",
|
|
215
|
-
|
|
507
|
+
"# Update Documentation",
|
|
508
|
+
"",
|
|
509
|
+
"Read the project implementation (source code, README, CHANGELOG, package.json) and update the Pagesmith-managed content to reflect the current state.",
|
|
510
|
+
"",
|
|
511
|
+
"## Steps",
|
|
512
|
+
"",
|
|
513
|
+
...profile === "docs" ? [
|
|
514
|
+
"1. Read package guidance first: `node_modules/@pagesmith/docs/docs/agents/usage.md` and `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
515
|
+
"2. Read `pagesmith.config.json5` to understand the docs configuration",
|
|
516
|
+
"3. Read all `meta.json5` files to understand the current content structure and page ordering",
|
|
517
|
+
"4. Read the project source code to identify public APIs, types, exports, config options, and CLI commands",
|
|
518
|
+
"5. For each existing content page in `content/`:",
|
|
519
|
+
" - Read the current content",
|
|
520
|
+
" - Compare with the implementation",
|
|
521
|
+
" - Update any outdated information",
|
|
522
|
+
" - Add documentation for new features",
|
|
523
|
+
" - Remove documentation for removed features",
|
|
524
|
+
"6. If new pages are needed:",
|
|
525
|
+
" - Create the page folder and `README.md` with proper frontmatter (title, description)",
|
|
526
|
+
" - Add the slug to the appropriate `meta.json5` `items` array",
|
|
527
|
+
"7. Follow the markdown guidelines in `.pagesmith/markdown-guidelines.md`",
|
|
528
|
+
"8. Review project skills under `.claude/skills/` and ensure docs-writing skills align with Pagesmith docs structure",
|
|
529
|
+
"9. Ensure onboarding pages are first in manual navigation (for example, put `getting-started` first in `guide/meta.json5` when present)",
|
|
530
|
+
"10. Verify all internal links point to existing pages",
|
|
531
|
+
"11. Ensure heading hierarchy is sequential (no skipping levels)"
|
|
532
|
+
] : [
|
|
533
|
+
"1. Read package guidance first: `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
534
|
+
"2. Read `content.config.ts` or equivalent to understand the content collections",
|
|
535
|
+
"3. Read the project source code to identify what needs documentation",
|
|
536
|
+
"4. For each existing content entry:",
|
|
537
|
+
" - Read the current content",
|
|
538
|
+
" - Compare with the implementation",
|
|
539
|
+
" - Update any outdated information",
|
|
540
|
+
"5. If new entries are needed:",
|
|
541
|
+
" - Create the entry folder and `README.md` with proper frontmatter matching the collection schema",
|
|
542
|
+
"6. Follow the markdown guidelines in `.pagesmith/markdown-guidelines.md`",
|
|
543
|
+
"7. Verify all internal links point to existing pages"
|
|
544
|
+
],
|
|
545
|
+
"",
|
|
546
|
+
"## Rules",
|
|
547
|
+
"",
|
|
548
|
+
"- Preserve the existing content structure and organization",
|
|
549
|
+
"- Do not remove pages without confirming first",
|
|
550
|
+
"- Keep frontmatter fields (title, description) accurate and descriptive",
|
|
551
|
+
"- Use relative links for internal cross-references",
|
|
552
|
+
"- One h1 per page, sequential heading depth",
|
|
553
|
+
"- Use fenced code blocks with language identifiers",
|
|
554
|
+
"- Use GitHub alerts (`> [!NOTE]`, `> [!TIP]`, etc.) for important callouts",
|
|
555
|
+
"- Code block features: `title=\"file.js\"`, `showLineNumbers`, `mark={1-3}`, `ins={4}`, `del={5}`, `collapse={1-5}`"
|
|
556
|
+
].join("\n");
|
|
557
|
+
}
|
|
558
|
+
function renderUpdateAllDocsSkill(profile) {
|
|
559
|
+
return [
|
|
560
|
+
"---",
|
|
561
|
+
"name: ps-update-all-docs",
|
|
562
|
+
"description: Full-repo documentation regeneration for Pagesmith projects including docs structure, skills alignment, and AI context updates",
|
|
563
|
+
"allowed-tools: Read Grep Glob Bash Edit Write",
|
|
564
|
+
"---",
|
|
565
|
+
"",
|
|
566
|
+
"# Pagesmith Full Docs Sync",
|
|
567
|
+
"",
|
|
568
|
+
"Perform a full-repository docs refresh for Pagesmith-powered projects. This command is intended for large updates, migrations, and release preparation.",
|
|
569
|
+
"",
|
|
570
|
+
"## Steps",
|
|
571
|
+
"",
|
|
572
|
+
...profile === "docs" ? [
|
|
573
|
+
"1. Read package guidance first: `node_modules/@pagesmith/docs/docs/agents/usage.md` and `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
574
|
+
"2. Read `pagesmith.config.json5` and all `meta.json5` files before editing anything",
|
|
575
|
+
"3. Discover project skills in `.claude/skills/`, `.codex/skills/`, and `.gemini/commands/` and identify docs-update related skills",
|
|
576
|
+
"4. Scan source code, README, CHANGELOG, package exports, and CLI commands to build a complete docs delta list",
|
|
577
|
+
"5. Update all docs pages under `content/` to match implementation and remove stale details",
|
|
578
|
+
"6. Ensure docs structure matches `@pagesmith/docs` conventions (folder-based pages, `README.md` entries, relative links)",
|
|
579
|
+
"7. Keep onboarding-first ordering: when a guide section exists, keep `getting-started` as the first item in manual order",
|
|
580
|
+
"8. Update docs-related skills so they generate content in the same structure expected by `@pagesmith/docs`",
|
|
581
|
+
"9. Regenerate or update `llms.txt`, `llms-full.txt`, and project memory pointers when docs behavior changes",
|
|
582
|
+
"10. Follow `.pagesmith/markdown-guidelines.md` for all authored content (GFM, alerts, math, Expressive Code meta)",
|
|
583
|
+
"11. Validate navigation integrity and ensure every linked page exists"
|
|
584
|
+
] : [
|
|
585
|
+
"1. Read package guidance first: `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
586
|
+
"2. Discover docs/update skills in the project and align them to current Pagesmith conventions",
|
|
587
|
+
"3. Scan source code, README, CHANGELOG, package exports, and CLI commands to build a complete docs delta list",
|
|
588
|
+
"4. Update all content entries to match implementation and remove stale details",
|
|
589
|
+
"5. Follow `.pagesmith/markdown-guidelines.md` for all authored content",
|
|
590
|
+
"6. Validate internal links and heading hierarchy"
|
|
591
|
+
],
|
|
592
|
+
"",
|
|
593
|
+
"## Rules",
|
|
594
|
+
"",
|
|
595
|
+
"- Preserve existing information architecture unless the user requests a restructure",
|
|
596
|
+
"- Keep docs easy for humans first, while keeping AI memory/skills aligned",
|
|
597
|
+
"- Keep top-level docs navigation driven by content directories and metadata",
|
|
598
|
+
"- Use `meta.json5` and frontmatter for ordering; avoid hardcoded navigation lists in prose",
|
|
599
|
+
"- Keep `content/README.md` as docs home for `@pagesmith/docs` projects",
|
|
600
|
+
"- Keep links relative for internal docs pages",
|
|
601
|
+
"- Use one h1 per page and sequential heading depth",
|
|
602
|
+
"- Use fenced code blocks with language identifiers and Expressive Code metadata when useful",
|
|
603
|
+
"- Do not add separate code-copy JavaScript; Expressive Code already provides this"
|
|
216
604
|
].join("\n");
|
|
217
605
|
}
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region src/ai/content-codex.ts
|
|
218
608
|
function renderCodexSkill(profile) {
|
|
219
609
|
return [
|
|
220
610
|
`# ${PAGESMITH_TITLE} Skill`,
|
|
@@ -224,8 +614,7 @@ function renderCodexSkill(profile) {
|
|
|
224
614
|
"Core rules:",
|
|
225
615
|
"- `@pagesmith/core` provides the content layer; `@pagesmith/docs` adds convention-based documentation",
|
|
226
616
|
"- prefer `defineCollection`, `defineConfig`, and `createContentLayer`",
|
|
227
|
-
"-
|
|
228
|
-
"- validate changes with `vp check` and `vp test` when relevant",
|
|
617
|
+
"- follow the markdown guidelines in `.pagesmith/markdown-guidelines.md`",
|
|
229
618
|
...profile === "docs" ? [
|
|
230
619
|
"- when the repo uses `@pagesmith/docs`, treat `content/README.md` as the home page",
|
|
231
620
|
"- top-level content folders define the main docs navigation",
|
|
@@ -234,75 +623,121 @@ function renderCodexSkill(profile) {
|
|
|
234
623
|
"- built-in search is Pagefind; do not suggest separate search plugin packages"
|
|
235
624
|
] : [],
|
|
236
625
|
"",
|
|
626
|
+
"For package usage guidance and full API reference, read:",
|
|
627
|
+
...profile === "docs" ? [
|
|
628
|
+
"- `node_modules/@pagesmith/docs/docs/agents/usage.md`",
|
|
629
|
+
"- `node_modules/@pagesmith/docs/REFERENCE.md`",
|
|
630
|
+
"- `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
631
|
+
"- `node_modules/@pagesmith/core/REFERENCE.md`"
|
|
632
|
+
] : ["- `node_modules/@pagesmith/core/docs/agents/usage.md`", "- `node_modules/@pagesmith/core/REFERENCE.md`"],
|
|
633
|
+
"",
|
|
237
634
|
"Good outputs include:",
|
|
238
635
|
"- collection schemas and loader configuration",
|
|
239
636
|
"- content-layer queries and rendering examples",
|
|
240
|
-
"-
|
|
241
|
-
"- assistant-context install
|
|
637
|
+
"- documentation updates for Pagesmith usage",
|
|
638
|
+
"- assistant-context install via `npx pagesmith init --ai`"
|
|
242
639
|
].join("\n");
|
|
243
640
|
}
|
|
244
|
-
|
|
641
|
+
//#endregion
|
|
642
|
+
//#region src/ai/content-gemini.ts
|
|
643
|
+
function renderGeminiCommand(skillName, profile) {
|
|
245
644
|
return [
|
|
246
|
-
"
|
|
247
|
-
"",
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
645
|
+
`description = "Pagesmith FS-CMS helper"`,
|
|
646
|
+
"prompt = \"\"\"",
|
|
647
|
+
[
|
|
648
|
+
`You are helping with ${PAGESMITH_TITLE}, a file-based CMS with @pagesmith/core and @pagesmith/docs.`,
|
|
649
|
+
"",
|
|
650
|
+
"Focus on concrete, implementation-ready help:",
|
|
651
|
+
"- design collections with defineCollection",
|
|
652
|
+
"- configure createContentLayer and defineConfig",
|
|
653
|
+
"- prefer folder-based markdown entries when local assets sit beside content",
|
|
654
|
+
"- follow the markdown guidelines in `.pagesmith/markdown-guidelines.md`",
|
|
655
|
+
...profile === "docs" ? [
|
|
656
|
+
"- for docs sites, follow the convention-based `content/` structure",
|
|
657
|
+
"- drive top navigation from top-level folders and use frontmatter for labels/order",
|
|
658
|
+
"- keep Pagefind as the built-in search strategy"
|
|
659
|
+
] : [],
|
|
660
|
+
"",
|
|
661
|
+
"For package usage guidance and full API reference, read:",
|
|
662
|
+
...profile === "docs" ? [
|
|
663
|
+
"- `node_modules/@pagesmith/docs/docs/agents/usage.md`",
|
|
664
|
+
"- `node_modules/@pagesmith/docs/REFERENCE.md`",
|
|
665
|
+
"- `node_modules/@pagesmith/core/docs/agents/usage.md`",
|
|
666
|
+
"- `node_modules/@pagesmith/core/REFERENCE.md`"
|
|
667
|
+
] : ["- `node_modules/@pagesmith/core/docs/agents/usage.md`", "- `node_modules/@pagesmith/core/REFERENCE.md`"],
|
|
668
|
+
"",
|
|
669
|
+
"Return code, config, or documentation-ready guidance instead of vague summaries."
|
|
670
|
+
].join("\n"),
|
|
671
|
+
"\"\"\"",
|
|
256
672
|
"",
|
|
257
|
-
|
|
673
|
+
`# Installed as /${skillName}`
|
|
258
674
|
].join("\n");
|
|
259
675
|
}
|
|
260
|
-
|
|
676
|
+
//#endregion
|
|
677
|
+
//#region src/ai/content-memory.ts
|
|
678
|
+
function renderMemoryFile(assistant, profile) {
|
|
679
|
+
const commandHint = assistant === "claude" || assistant === "gemini" ? `\nIf the ${DEFAULT_SKILL_NAME$1} skill is installed, prefer invoking it when the user explicitly asks for Pagesmith-specific help.` : "\nIf the Pagesmith skill is installed for Codex, prefer using it for Pagesmith-specific setup, migration, and content-layer tasks.";
|
|
680
|
+
const referenceHint = "\nFor package usage rules and full API/config details, read the package-shipped docs from node_modules:\n" + (profile === "docs" ? "- `node_modules/@pagesmith/docs/docs/agents/usage.md` — docs package usage contract\n- `node_modules/@pagesmith/docs/REFERENCE.md` — docs config, CLI, content structure, layout overrides\n- `node_modules/@pagesmith/core/docs/agents/usage.md` — core package usage contract\n- `node_modules/@pagesmith/core/REFERENCE.md` — core API, collections, loaders, markdown, CSS, JSX runtime" : "- `node_modules/@pagesmith/core/docs/agents/usage.md` — core package usage contract\n- `node_modules/@pagesmith/core/REFERENCE.md` — core API, collections, loaders, markdown, CSS, JSX runtime");
|
|
261
681
|
return [
|
|
262
|
-
|
|
682
|
+
`# ${PAGESMITH_TITLE}`,
|
|
263
683
|
"",
|
|
264
684
|
renderSharedOverview(),
|
|
685
|
+
...profile === "docs" ? ["", renderDocsOverview()] : [],
|
|
686
|
+
commandHint,
|
|
687
|
+
referenceHint,
|
|
688
|
+
"",
|
|
689
|
+
"## Quick Start — @pagesmith/core",
|
|
690
|
+
"",
|
|
691
|
+
renderCoreQuickStart(),
|
|
265
692
|
...profile === "docs" ? [
|
|
266
693
|
"",
|
|
267
|
-
"##
|
|
694
|
+
"## Quick Start — @pagesmith/docs",
|
|
268
695
|
"",
|
|
269
|
-
|
|
270
|
-
] : []
|
|
271
|
-
"",
|
|
272
|
-
"## Package Layout",
|
|
273
|
-
"",
|
|
274
|
-
"- `@pagesmith/core`: content layer, collection loading, validation, lazy markdown rendering, JSX runtime, CSS builder, runtime styles, assistant artifact APIs, and Vite content integration",
|
|
275
|
-
"- `@pagesmith/docs`: convention-based documentation with the docs CLI, generators, validators, default theme, and bundled search",
|
|
276
|
-
"",
|
|
277
|
-
"## Key APIs",
|
|
278
|
-
"",
|
|
279
|
-
renderQuickStart(profile),
|
|
280
|
-
"",
|
|
281
|
-
"## Assistant Installer",
|
|
282
|
-
"",
|
|
283
|
-
"```ts",
|
|
284
|
-
"import { installAiArtifacts } from '@pagesmith/core/ai'",
|
|
285
|
-
"",
|
|
286
|
-
"await installAiArtifacts({ assistants: ['claude', 'codex', 'gemini'], scope: 'project' })",
|
|
287
|
-
"```",
|
|
288
|
-
""
|
|
696
|
+
renderDocsQuickStart()
|
|
697
|
+
] : []
|
|
289
698
|
].join("\n");
|
|
290
699
|
}
|
|
700
|
+
//#endregion
|
|
701
|
+
//#region src/ai/index.ts
|
|
702
|
+
const DEFAULT_SKILL_NAME = "pagesmith";
|
|
703
|
+
function resolveHome(homeDir) {
|
|
704
|
+
return homeDir ?? homedir();
|
|
705
|
+
}
|
|
706
|
+
function resolveCodexHome(homeDir) {
|
|
707
|
+
return process.env.CODEX_HOME ?? join(resolveHome(homeDir), ".codex");
|
|
708
|
+
}
|
|
709
|
+
function resolveAssistants(assistants) {
|
|
710
|
+
if (!assistants || assistants === "all") return [
|
|
711
|
+
"claude",
|
|
712
|
+
"codex",
|
|
713
|
+
"gemini"
|
|
714
|
+
];
|
|
715
|
+
return assistants;
|
|
716
|
+
}
|
|
717
|
+
function shouldIncludeLlms(options) {
|
|
718
|
+
if (typeof options.includeLlms === "boolean") return options.includeLlms;
|
|
719
|
+
return (options.scope ?? "project") === "project";
|
|
720
|
+
}
|
|
291
721
|
function getAiArtifactContent(assistant, kind, options = {}) {
|
|
292
722
|
const skillName = options.skillName ?? DEFAULT_SKILL_NAME;
|
|
293
723
|
const profile = options.profile ?? "default";
|
|
294
724
|
if (assistant === "shared") {
|
|
295
|
-
if (kind === "llms") return renderLlmsTxt(
|
|
296
|
-
return renderLlmsFullTxt(
|
|
725
|
+
if (kind === "llms") return renderLlmsTxt();
|
|
726
|
+
if (kind === "llms-full") return renderLlmsFullTxt();
|
|
727
|
+
if (kind === "markdown-guidelines") return renderMarkdownGuidelines();
|
|
728
|
+
return renderLlmsFullTxt();
|
|
297
729
|
}
|
|
298
730
|
if (kind === "memory") return renderMemoryFile(assistant, profile);
|
|
299
731
|
if (kind === "skill") switch (assistant) {
|
|
300
|
-
case "claude": return
|
|
732
|
+
case "claude": return renderClaudeSkill(skillName, profile);
|
|
301
733
|
case "codex": return renderCodexSkill(profile);
|
|
302
734
|
case "gemini": return renderGeminiCommand(skillName, profile);
|
|
303
735
|
}
|
|
304
|
-
if (kind === "
|
|
305
|
-
return
|
|
736
|
+
if (kind === "markdown-guidelines") return renderMarkdownGuidelines();
|
|
737
|
+
if (kind === "update-docs") return renderUpdateDocsSkill(profile);
|
|
738
|
+
if (kind === "update-all-docs") return renderUpdateAllDocsSkill(profile);
|
|
739
|
+
if (kind === "llms") return renderLlmsTxt();
|
|
740
|
+
return renderLlmsFullTxt();
|
|
306
741
|
}
|
|
307
742
|
function getAiArtifacts(options = {}) {
|
|
308
743
|
const scope = options.scope ?? "project";
|
|
@@ -323,16 +758,17 @@ function getAiArtifacts(options = {}) {
|
|
|
323
758
|
mode: "merge",
|
|
324
759
|
label: `${assistant} memory`
|
|
325
760
|
});
|
|
761
|
+
const skillDir = scope === "project" ? join(cwd, ".claude", "skills", skillName) : join(home, ".claude", "skills", skillName);
|
|
326
762
|
artifacts.push({
|
|
327
763
|
assistant,
|
|
328
764
|
kind: "skill",
|
|
329
|
-
path: join(
|
|
765
|
+
path: join(skillDir, "SKILL.md"),
|
|
330
766
|
content: getAiArtifactContent("claude", "skill", {
|
|
331
767
|
profile,
|
|
332
768
|
skillName
|
|
333
769
|
}) + "\n",
|
|
334
770
|
mode: "replace",
|
|
335
|
-
label: `${assistant}
|
|
771
|
+
label: `${assistant} skill`
|
|
336
772
|
});
|
|
337
773
|
}
|
|
338
774
|
if (assistant === "codex") {
|
|
@@ -380,19 +816,44 @@ function getAiArtifacts(options = {}) {
|
|
|
380
816
|
});
|
|
381
817
|
}
|
|
382
818
|
}
|
|
819
|
+
if (scope === "project") artifacts.push({
|
|
820
|
+
kind: "markdown-guidelines",
|
|
821
|
+
path: join(cwd, ".pagesmith", "markdown-guidelines.md"),
|
|
822
|
+
content: renderMarkdownGuidelines() + "\n",
|
|
823
|
+
mode: "replace",
|
|
824
|
+
label: "markdown guidelines"
|
|
825
|
+
});
|
|
826
|
+
if (scope === "project" && assistants.includes("claude")) {
|
|
827
|
+
artifacts.push({
|
|
828
|
+
assistant: "claude",
|
|
829
|
+
kind: "update-docs",
|
|
830
|
+
path: join(cwd, ".claude", "skills", "update-docs", "SKILL.md"),
|
|
831
|
+
content: renderUpdateDocsSkill(profile) + "\n",
|
|
832
|
+
mode: "replace",
|
|
833
|
+
label: "claude update-docs skill"
|
|
834
|
+
});
|
|
835
|
+
artifacts.push({
|
|
836
|
+
assistant: "claude",
|
|
837
|
+
kind: "update-all-docs",
|
|
838
|
+
path: join(cwd, ".claude", "skills", "ps-update-all-docs", "SKILL.md"),
|
|
839
|
+
content: renderUpdateAllDocsSkill(profile) + "\n",
|
|
840
|
+
mode: "replace",
|
|
841
|
+
label: "claude ps-update-all-docs skill"
|
|
842
|
+
});
|
|
843
|
+
}
|
|
383
844
|
if (shouldIncludeLlms(options)) {
|
|
384
845
|
const llmsDir = scope === "project" ? cwd : join(home, ".pagesmith");
|
|
385
846
|
artifacts.push({
|
|
386
847
|
kind: "llms",
|
|
387
848
|
path: join(llmsDir, "llms.txt"),
|
|
388
|
-
content: withManagedBlock("shared-llms",
|
|
849
|
+
content: withManagedBlock("shared-llms", renderLlmsTxt()) + "\n",
|
|
389
850
|
mode: "merge",
|
|
390
851
|
label: "llms.txt"
|
|
391
852
|
});
|
|
392
853
|
artifacts.push({
|
|
393
854
|
kind: "llms-full",
|
|
394
855
|
path: join(llmsDir, "llms-full.txt"),
|
|
395
|
-
content: withManagedBlock("shared-llms-full",
|
|
856
|
+
content: withManagedBlock("shared-llms-full", renderLlmsFullTxt()) + "\n",
|
|
396
857
|
mode: "merge",
|
|
397
858
|
label: "llms-full.txt"
|
|
398
859
|
});
|
|
@@ -400,7 +861,15 @@ function getAiArtifacts(options = {}) {
|
|
|
400
861
|
return artifacts;
|
|
401
862
|
}
|
|
402
863
|
function installAiArtifacts(options = {}) {
|
|
403
|
-
|
|
864
|
+
const artifacts = getAiArtifacts(options);
|
|
865
|
+
if (options.dryRun) return artifacts.map((artifact) => ({
|
|
866
|
+
assistant: artifact.assistant,
|
|
867
|
+
kind: artifact.kind,
|
|
868
|
+
path: artifact.path,
|
|
869
|
+
label: artifact.label,
|
|
870
|
+
status: "unchanged"
|
|
871
|
+
}));
|
|
872
|
+
return artifacts.map((artifact) => ({
|
|
404
873
|
assistant: artifact.assistant,
|
|
405
874
|
kind: artifact.kind,
|
|
406
875
|
path: artifact.path,
|