@3sln/deck 0.0.11 → 0.0.12

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/bin/build.js CHANGED
@@ -6,6 +6,7 @@ import path from 'path';
6
6
  import {createRequire} from 'module';
7
7
  import { sha256, loadDeckConfig, getProjectFiles, getCardFiles, getHtmlTemplate } from '../src/config.js';
8
8
 
9
+ import {marked} from 'marked';
9
10
  const require = createRequire(import.meta.url);
10
11
 
11
12
  // --- Path Resolution ---
@@ -78,10 +79,25 @@ async function build() {
78
79
  const initialCardsData = await Promise.all(cardFiles.map(async (file) => {
79
80
  const content = await fs.readFile(path.resolve(outDir, file), 'utf-8');
80
81
  const hash = await sha256(content);
81
- return { path: `/${file}`, hash };
82
+
83
+ // Extract title for agents.md
84
+ const tokens = marked.lexer(content);
85
+ const heading = tokens.find(t => t.type === 'heading' && t.depth === 1);
86
+ const title = heading ? heading.text : path.basename(file, path.extname(file));
87
+
88
+ return { path: `/${file}`, hash, title };
82
89
  }));
83
90
  console.log(`Found and processed ${initialCardsData.length} cards.`);
84
91
 
92
+ // Generate agents.md
93
+ console.log('Generating agents.md...');
94
+ let agentsMd = "# Agents Index\n\nThis file is meant to help LLMs find documentation. Below is a list of available cards.\n\n";
95
+ for (const card of initialCardsData) {
96
+ agentsMd += `- [${card.title}](${card.path})\n`;
97
+ }
98
+ await fs.writeFile(path.resolve(outDir, 'agents.md'), agentsMd);
99
+ console.log('agents.md generated.');
100
+
85
101
  // Generate asset manifest for service worker
86
102
  console.log('Generating asset manifest...');
87
103
  const manifest = await fs.readJson(path.resolve(assetsDir, '.vite/manifest.json'));
@@ -111,6 +127,9 @@ async function build() {
111
127
  pinnedCardPaths: buildConfig.pinned,
112
128
  entryFile: `/assets/${entryFile}`,
113
129
  cssFiles,
130
+ favicon: buildConfig.favicon,
131
+ scripts: buildConfig.scripts,
132
+ stylesheets: buildConfig.stylesheets,
114
133
  });
115
134
 
116
135
  await fs.writeFile(path.resolve(outDir, 'index.html'), html);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3sln/deck",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "A Vite plugin for building scalable, zero-config, Markdown-based component playgrounds and documentation sites.",
5
5
  "type": "module",
6
6
  "author": "Ray Stubbs",
package/src/config.js CHANGED
@@ -17,6 +17,9 @@ export async function loadDeckConfig(root) {
17
17
 
18
18
  const defaultConfig = {
19
19
  title: 'Deck',
20
+ favicon: null,
21
+ scripts: [],
22
+ stylesheets: [],
20
23
  pinned: [],
21
24
  pick: {},
22
25
  include: ['**/*'],
@@ -58,7 +61,25 @@ export function getCardFiles(root, config) {
58
61
  }).filter(s => s.endsWith('.md') || s.endsWith('.html'));
59
62
  }
60
63
 
61
- export function getHtmlTemplate({ title, importMap, initialCardsData, pinnedCardPaths, entryFile, cssFiles = [] }) {
64
+ export function getHtmlTemplate({ title, importMap, initialCardsData, pinnedCardPaths, entryFile, cssFiles = [], favicon, scripts = [], stylesheets = [] }) {
65
+ const scriptTags = scripts.map(s => {
66
+ if (typeof s === 'string') return `<script src="${s}"></script>`;
67
+ const attrs = Object.entries(s).map(([k, v]) => {
68
+ if (v === true) return k;
69
+ return `${k}="${v}"`;
70
+ }).join(' ');
71
+ return `<script ${attrs}></script>`;
72
+ }).join('\n');
73
+
74
+ const styleTags = stylesheets.map(s => {
75
+ if (typeof s === 'string') return `<link rel="stylesheet" href="${s}">`;
76
+ const attrs = Object.entries(s).map(([k, v]) => {
77
+ if (v === true) return k;
78
+ return `${k}="${v}"`;
79
+ }).join(' ');
80
+ return `<link rel="stylesheet" ${attrs}>`;
81
+ }).join('\n');
82
+
62
83
  return `
63
84
  <!doctype html>
64
85
  <html lang="en">
@@ -66,6 +87,8 @@ export function getHtmlTemplate({ title, importMap, initialCardsData, pinnedCard
66
87
  <meta charset="utf-8">
67
88
  <meta name="viewport" content="width=device-width, initial-scale=1">
68
89
  <title>${title}</title>
90
+ ${favicon ? `<link rel="icon" href="${favicon}">` : ''}
91
+ ${styleTags}
69
92
  ${importMap ? `<script type="importmap">${JSON.stringify(importMap)}</script>` : ''}
70
93
  <script>
71
94
  window.__INITIAL_CARDS_DATA__ = ${JSON.stringify(initialCardsData)};
@@ -88,9 +111,13 @@ export function getHtmlTemplate({ title, importMap, initialCardsData, pinnedCard
88
111
  }
89
112
  </style>
90
113
  ${cssFiles.map(file => `<link rel="stylesheet" href="/assets/${file}">`).join('\n')}
114
+ ${scriptTags}
91
115
  </head>
92
116
  <body>
93
117
  <div id="root"></div>
118
+ <div style="display: none;" aria-hidden="true">
119
+ This is a Single Page Application. Agents should look at the <a href="/agents.md">agents.md</a> file for documentation they can read easily.
120
+ </div>
94
121
  <script type="module">
95
122
  import { renderDeck } from '${entryFile}';
96
123
  renderDeck({
package/vite-plugin.js CHANGED
@@ -151,7 +151,10 @@ export default function deckPlugin() {
151
151
  importMap: devConfig.importMap,
152
152
  initialCardsData,
153
153
  pinnedCardPaths: devConfig.pinned,
154
- entryFile: '@3sln/deck'
154
+ entryFile: '@3sln/deck',
155
+ favicon: devConfig.favicon,
156
+ scripts: devConfig.scripts,
157
+ stylesheets: devConfig.stylesheets,
155
158
  });
156
159
  const html = await server.transformIndexHtml(req.url, template);
157
160
  res.end(html);