@dominikcz/greg 0.9.27

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 (183) hide show
  1. package/README.md +397 -0
  2. package/bin/greg.js +241 -0
  3. package/bin/init.js +351 -0
  4. package/bin/templates/docs/getting-started.md +47 -0
  5. package/bin/templates/docs/index.md +11 -0
  6. package/bin/templates/greg.config.js +39 -0
  7. package/bin/templates/greg.config.ts +38 -0
  8. package/bin/templates/index.html +16 -0
  9. package/bin/templates/src/App.svelte +5 -0
  10. package/bin/templates/src/app.css +20 -0
  11. package/bin/templates/src/main.js +9 -0
  12. package/bin/templates/svelte.config.js +1 -0
  13. package/bin/templates/tsconfig.json +21 -0
  14. package/bin/templates/vite.config.js +23 -0
  15. package/docs/__partials/markdown/examples/basic.md +4 -0
  16. package/docs/__partials/markdown/examples/diff.md +10 -0
  17. package/docs/__partials/markdown/examples/focus.md +5 -0
  18. package/docs/__partials/markdown/examples/language-title.md +3 -0
  19. package/docs/__partials/markdown/examples/line-highlighting.md +5 -0
  20. package/docs/__partials/markdown/examples/line-numbers.md +5 -0
  21. package/docs/__partials/note.md +4 -0
  22. package/docs/guide/__shared-warning.md +4 -0
  23. package/docs/guide/asset-handling.md +88 -0
  24. package/docs/guide/deploying.md +162 -0
  25. package/docs/guide/getting-started.md +334 -0
  26. package/docs/guide/index.md +23 -0
  27. package/docs/guide/localization.md +290 -0
  28. package/docs/guide/markdown/code.md +95 -0
  29. package/docs/guide/markdown/components-and-mermaid.md +43 -0
  30. package/docs/guide/markdown/containers.md +110 -0
  31. package/docs/guide/markdown/header-anchors.md +34 -0
  32. package/docs/guide/markdown/includes.md +84 -0
  33. package/docs/guide/markdown/index.md +20 -0
  34. package/docs/guide/markdown/inline-attributes.md +21 -0
  35. package/docs/guide/markdown/links-and-toc.md +64 -0
  36. package/docs/guide/markdown/math.md +54 -0
  37. package/docs/guide/markdown/syntax-highlighting.md +75 -0
  38. package/docs/guide/routing.md +150 -0
  39. package/docs/guide/using-svelte.md +88 -0
  40. package/docs/guide/versioning.md +281 -0
  41. package/docs/incompatibilities.md +48 -0
  42. package/docs/index.md +43 -0
  43. package/docs/reference/badge.md +100 -0
  44. package/docs/reference/carbon-ads.md +46 -0
  45. package/docs/reference/code-group.md +126 -0
  46. package/docs/reference/home-page.md +232 -0
  47. package/docs/reference/index.md +18 -0
  48. package/docs/reference/markdowndocs.md +275 -0
  49. package/docs/reference/outline.md +79 -0
  50. package/docs/reference/search.md +263 -0
  51. package/docs/reference/steps.md +200 -0
  52. package/docs/reference/team-page.md +189 -0
  53. package/docs/reference/theme.md +150 -0
  54. package/fakeDocsGenerator/generate_docs.js +310 -0
  55. package/package.json +92 -0
  56. package/scripts/build-versions.js +609 -0
  57. package/scripts/generate-static.js +79 -0
  58. package/scripts/render-markdown.js +420 -0
  59. package/src/lib/MarkdownDocs/AiChat.svelte +936 -0
  60. package/src/lib/MarkdownDocs/BackToTop.svelte +68 -0
  61. package/src/lib/MarkdownDocs/Breadcrumb.svelte +68 -0
  62. package/src/lib/MarkdownDocs/DocsNavigation.svelte +149 -0
  63. package/src/lib/MarkdownDocs/DocsSiteHeader.svelte +758 -0
  64. package/src/lib/MarkdownDocs/DocsVersionSwitcher.svelte +103 -0
  65. package/src/lib/MarkdownDocs/MarkdownDocs.svelte +2115 -0
  66. package/src/lib/MarkdownDocs/MarkdownRenderer.svelte +487 -0
  67. package/src/lib/MarkdownDocs/Outline.svelte +238 -0
  68. package/src/lib/MarkdownDocs/PrevNext.svelte +115 -0
  69. package/src/lib/MarkdownDocs/SearchModal.svelte +1241 -0
  70. package/src/lib/MarkdownDocs/TreeView.svelte +32 -0
  71. package/src/lib/MarkdownDocs/TreeViewItem.svelte +219 -0
  72. package/src/lib/MarkdownDocs/VersionOutdatedNotice.svelte +72 -0
  73. package/src/lib/MarkdownDocs/__tests__/codeDirectives.test.js +54 -0
  74. package/src/lib/MarkdownDocs/__tests__/common.test.js +41 -0
  75. package/src/lib/MarkdownDocs/__tests__/docsExamplesLint.test.js +77 -0
  76. package/src/lib/MarkdownDocs/__tests__/fixtures/docs/markdown/__partial-basic.md +3 -0
  77. package/src/lib/MarkdownDocs/__tests__/fixtures/docs/markdown/snippet.js +9 -0
  78. package/src/lib/MarkdownDocs/__tests__/fixtures/includes/part.md +11 -0
  79. package/src/lib/MarkdownDocs/__tests__/fixtures/includes/wrapper.md +5 -0
  80. package/src/lib/MarkdownDocs/__tests__/fixtures/snippets/sample.js +8 -0
  81. package/src/lib/MarkdownDocs/__tests__/fixtures/snippets/sample.md +5 -0
  82. package/src/lib/MarkdownDocs/__tests__/helpers.js +67 -0
  83. package/src/lib/MarkdownDocs/__tests__/localeUtils.test.js +204 -0
  84. package/src/lib/MarkdownDocs/__tests__/markdown.test.js +704 -0
  85. package/src/lib/MarkdownDocs/__tests__/markdownRendererRuntime.test.js +65 -0
  86. package/src/lib/MarkdownDocs/__tests__/searchIndexBuilder.test.js +117 -0
  87. package/src/lib/MarkdownDocs/__tests__/sqliteStore.test.js +202 -0
  88. package/src/lib/MarkdownDocs/__tests__/useRouter.test.js +16 -0
  89. package/src/lib/MarkdownDocs/ai/adapters/customAdapter.js +14 -0
  90. package/src/lib/MarkdownDocs/ai/adapters/customAdapter.ts +43 -0
  91. package/src/lib/MarkdownDocs/ai/adapters/ollamaAdapter.js +81 -0
  92. package/src/lib/MarkdownDocs/ai/adapters/ollamaAdapter.ts +116 -0
  93. package/src/lib/MarkdownDocs/ai/adapters/openaiAdapter.js +92 -0
  94. package/src/lib/MarkdownDocs/ai/adapters/openaiAdapter.ts +137 -0
  95. package/src/lib/MarkdownDocs/ai/aiProvider.ts +31 -0
  96. package/src/lib/MarkdownDocs/ai/characters.js +52 -0
  97. package/src/lib/MarkdownDocs/ai/characters.ts +69 -0
  98. package/src/lib/MarkdownDocs/ai/chunkStore.ts +25 -0
  99. package/src/lib/MarkdownDocs/ai/chunker.js +85 -0
  100. package/src/lib/MarkdownDocs/ai/chunker.ts +135 -0
  101. package/src/lib/MarkdownDocs/ai/docLinker.js +26 -0
  102. package/src/lib/MarkdownDocs/ai/docLinker.ts +36 -0
  103. package/src/lib/MarkdownDocs/ai/promptBuilder.js +33 -0
  104. package/src/lib/MarkdownDocs/ai/promptBuilder.ts +53 -0
  105. package/src/lib/MarkdownDocs/ai/ragPipeline.js +54 -0
  106. package/src/lib/MarkdownDocs/ai/ragPipeline.ts +106 -0
  107. package/src/lib/MarkdownDocs/ai/stores/memoryStore.js +88 -0
  108. package/src/lib/MarkdownDocs/ai/stores/memoryStore.ts +112 -0
  109. package/src/lib/MarkdownDocs/ai/stores/sqliteStore.ts +372 -0
  110. package/src/lib/MarkdownDocs/ai/types.ts +71 -0
  111. package/src/lib/MarkdownDocs/aiServer.js +288 -0
  112. package/src/lib/MarkdownDocs/codeDirectives.js +191 -0
  113. package/src/lib/MarkdownDocs/codeFenceInfo.js +45 -0
  114. package/src/lib/MarkdownDocs/codeGroup.ts +46 -0
  115. package/src/lib/MarkdownDocs/common.ts +47 -0
  116. package/src/lib/MarkdownDocs/docsUtils.js +281 -0
  117. package/src/lib/MarkdownDocs/index.plugins.js +22 -0
  118. package/src/lib/MarkdownDocs/layouts/LayoutDoc.svelte +8 -0
  119. package/src/lib/MarkdownDocs/layouts/LayoutHome.svelte +58 -0
  120. package/src/lib/MarkdownDocs/layouts/LayoutPage.svelte +9 -0
  121. package/src/lib/MarkdownDocs/loadGregConfig.js +82 -0
  122. package/src/lib/MarkdownDocs/localeUtils.ts +682 -0
  123. package/src/lib/MarkdownDocs/markdownRendererRuntime.ts +314 -0
  124. package/src/lib/MarkdownDocs/mermaidThemes.js +319 -0
  125. package/src/lib/MarkdownDocs/navigationUtils.js +22 -0
  126. package/src/lib/MarkdownDocs/rehypeCodeGroup.js +326 -0
  127. package/src/lib/MarkdownDocs/rehypeCodeTitle.js +96 -0
  128. package/src/lib/MarkdownDocs/rehypeToc.js +170 -0
  129. package/src/lib/MarkdownDocs/remarkCodeMeta.js +22 -0
  130. package/src/lib/MarkdownDocs/remarkContainers.js +329 -0
  131. package/src/lib/MarkdownDocs/remarkCustomAnchors.js +42 -0
  132. package/src/lib/MarkdownDocs/remarkEscapeSvelte.js +33 -0
  133. package/src/lib/MarkdownDocs/remarkGlobalComponents.js +65 -0
  134. package/src/lib/MarkdownDocs/remarkImports.js +461 -0
  135. package/src/lib/MarkdownDocs/remarkImportsBrowser.js +349 -0
  136. package/src/lib/MarkdownDocs/remarkInlineAttrs.js +95 -0
  137. package/src/lib/MarkdownDocs/remarkMathToHtml.js +138 -0
  138. package/src/lib/MarkdownDocs/searchIndexBuilder.js +497 -0
  139. package/src/lib/MarkdownDocs/searchServer.js +263 -0
  140. package/src/lib/MarkdownDocs/treeViewTypes.ts +11 -0
  141. package/src/lib/MarkdownDocs/useRouter.svelte.ts +114 -0
  142. package/src/lib/MarkdownDocs/useSplitter.svelte.ts +33 -0
  143. package/src/lib/MarkdownDocs/versioningDefaults.js +20 -0
  144. package/src/lib/MarkdownDocs/vitePluginAiServer.js +204 -0
  145. package/src/lib/MarkdownDocs/vitePluginCopyDocs.js +153 -0
  146. package/src/lib/MarkdownDocs/vitePluginFrontmatter.js +109 -0
  147. package/src/lib/MarkdownDocs/vitePluginGregConfig.js +108 -0
  148. package/src/lib/MarkdownDocs/vitePluginSearchIndex.js +57 -0
  149. package/src/lib/MarkdownDocs/vitePluginSearchServer.js +190 -0
  150. package/src/lib/components/Badge.svelte +59 -0
  151. package/src/lib/components/Button.svelte +138 -0
  152. package/src/lib/components/CarbonAds.svelte +99 -0
  153. package/src/lib/components/CodeGroup.svelte +102 -0
  154. package/src/lib/components/Feature.svelte +209 -0
  155. package/src/lib/components/Features.svelte +123 -0
  156. package/src/lib/components/Hero.svelte +399 -0
  157. package/src/lib/components/Image.svelte +128 -0
  158. package/src/lib/components/Link.svelte +105 -0
  159. package/src/lib/components/SocialLink.svelte +84 -0
  160. package/src/lib/components/SocialLinks.svelte +33 -0
  161. package/src/lib/components/Steps.svelte +143 -0
  162. package/src/lib/components/TeamMember.svelte +273 -0
  163. package/src/lib/components/TeamMembers.svelte +81 -0
  164. package/src/lib/components/TeamPage.svelte +65 -0
  165. package/src/lib/components/TeamPageSection.svelte +108 -0
  166. package/src/lib/components/TeamPageTitle.svelte +89 -0
  167. package/src/lib/components/index.js +24 -0
  168. package/src/lib/portal/context.js +12 -0
  169. package/src/lib/portal/index.js +3 -0
  170. package/src/lib/portal/portal.svelte +14 -0
  171. package/src/lib/portal/slot.svelte +8 -0
  172. package/src/lib/scss/__code.scss +128 -0
  173. package/src/lib/scss/__containers.scss +99 -0
  174. package/src/lib/scss/__markdown.scss +447 -0
  175. package/src/lib/scss/__scrollbar.scss +60 -0
  176. package/src/lib/scss/__steps.scss +100 -0
  177. package/src/lib/scss/__theme.scss +238 -0
  178. package/src/lib/scss/__toc.scss +55 -0
  179. package/src/lib/scss/__utilities.scss +7 -0
  180. package/src/lib/scss/greg.scss +9 -0
  181. package/src/lib/spinner/spinner.svelte +42 -0
  182. package/svelte.config.js +146 -0
  183. package/types/index.d.ts +456 -0
package/bin/init.js ADDED
@@ -0,0 +1,351 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * greg init
4
+ *
5
+ * Interactive initializer — creates the minimal files needed to start a
6
+ * new documentation project with Greg.
7
+ *
8
+ * Usage:
9
+ * npx @dominikcz/greg init
10
+ * greg init
11
+ */
12
+ import * as p from '@clack/prompts';
13
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';
14
+ import { join, dirname } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { fork, spawnSync } from 'node:child_process';
17
+
18
+ const __dirname = dirname(fileURLToPath(import.meta.url));
19
+ const cliArgs = new Set(process.argv.slice(2));
20
+ const useDefaultsMode = cliArgs.has('--defaults') || cliArgs.has('--yes');
21
+
22
+ // ── ANSI helpers (used for file-creation log lines) ───────────────────────────
23
+ const g = (s) => `\x1b[32m${s}\x1b[0m`; // green
24
+ const y = (s) => `\x1b[33m${s}\x1b[0m`; // yellow
25
+ const c = (s) => `\x1b[36m${s}\x1b[0m`; // cyan
26
+ const b = (s) => `\x1b[1m${s}\x1b[0m`; // bold
27
+ const d = (s) => `\x1b[2m${s}\x1b[0m`; // dim
28
+
29
+ function orCancel(value) {
30
+ if (p.isCancel(value)) { p.cancel('Cancelled.'); process.exit(0); }
31
+ return value;
32
+ }
33
+
34
+ // ── Template loader ───────────────────────────────────────────────────────────
35
+ function tpl(relPath, vars = {}) {
36
+ const full = join(__dirname, 'templates', relPath);
37
+ let content = readFileSync(full, 'utf-8');
38
+ for (const [k, v] of Object.entries(vars)) {
39
+ content = content.split(`{{${k}}}`).join(v);
40
+ }
41
+ return content;
42
+ }
43
+
44
+ // ── File writer ───────────────────────────────────────────────────────────────
45
+ const cwd = process.cwd();
46
+
47
+ function ensure(relPath, content) {
48
+ const full = join(cwd, relPath);
49
+ if (existsSync(full)) {
50
+ console.log(` ${y('~')} ${relPath} ${d('(skipped – already exists)')}`);
51
+ return;
52
+ }
53
+ const dir = dirname(full);
54
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
55
+ writeFileSync(full, content, 'utf-8');
56
+ console.log(` ${g('+')} ${relPath}`);
57
+ }
58
+
59
+ // ── Package manager detector ────────────────────────────────────────────────
60
+ function detectPm() {
61
+ if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';
62
+ if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';
63
+ return 'npm';
64
+ }
65
+
66
+ function toFileSpec(absPath) {
67
+ return `file:${absPath.replace(/\\/g, '/')}`;
68
+ }
69
+
70
+ function toProjectRelativeFileSpec(absPath) {
71
+ const rel = absPath.replace(/\\/g, '/').split('/').pop();
72
+ return `file:./${rel}`;
73
+ }
74
+
75
+ function findNearbyTarball(version) {
76
+ const filename = `dominikcz-greg-${version}.tgz`;
77
+ const candidates = [
78
+ join(cwd, filename),
79
+ join(cwd, '..', 'greg', filename),
80
+ join(cwd, '..', '..', 'greg', filename),
81
+ join(cwd, '..', filename),
82
+ ];
83
+
84
+ const existing = candidates
85
+ .filter(candidate => existsSync(candidate))
86
+ .map(candidate => ({
87
+ path: candidate,
88
+ mtime: statSync(candidate).mtimeMs,
89
+ }))
90
+ .sort((a, b) => b.mtime - a.mtime);
91
+
92
+ return existing[0]?.path ?? null;
93
+ }
94
+
95
+ function buildLocalTarballSpec(packageRoot) {
96
+ const packed = spawnSync('npm', ['pack', '--silent'], {
97
+ cwd: packageRoot,
98
+ stdio: 'pipe',
99
+ shell: true,
100
+ encoding: 'utf8',
101
+ });
102
+ if (packed.status !== 0) return null;
103
+
104
+ const lines = String(packed.stdout ?? '').split(/\r?\n/).map(v => v.trim()).filter(Boolean);
105
+ const tarballName = lines[lines.length - 1];
106
+ if (!tarballName) return null;
107
+
108
+ const sourcePath = join(packageRoot, tarballName);
109
+ const targetPath = join(cwd, tarballName);
110
+ if (!existsSync(sourcePath)) return null;
111
+
112
+ writeFileSync(targetPath, readFileSync(sourcePath));
113
+ return toProjectRelativeFileSpec(targetPath);
114
+ }
115
+
116
+ function isTransientCacheSpec(spec) {
117
+ const value = String(spec ?? '').toLowerCase().replace(/\\/g, '/');
118
+ return value.includes('/_npx/') || value.includes('/npm-cache/');
119
+ }
120
+
121
+ function resolveGregDependencySpec(version) {
122
+ const packageRoot = join(__dirname, '..');
123
+ const npmView = spawnSync('npm', ['view', `@dominikcz/greg@${version}`, 'version'], {
124
+ stdio: 'pipe',
125
+ shell: true,
126
+ });
127
+
128
+ if (npmView.status === 0) {
129
+ return { spec: `^${version}`, source: 'registry' };
130
+ }
131
+
132
+ // Prefer a nearby local .tgz created by the developer (for local testing).
133
+ const nearbyTarball = findNearbyTarball(version);
134
+ if (nearbyTarball) {
135
+ const targetPath = join(cwd, `dominikcz-greg-${version}.tgz`);
136
+ if (nearbyTarball !== targetPath) {
137
+ writeFileSync(targetPath, readFileSync(nearbyTarball));
138
+ }
139
+ return { spec: toProjectRelativeFileSpec(targetPath), source: 'local-tarball' };
140
+ }
141
+
142
+ // Prefer a project-local tgz whenever the current version is unpublished.
143
+ // This avoids pinning dependencies to transient npm cache locations.
144
+ const tarballSpec = buildLocalTarballSpec(packageRoot);
145
+ if (tarballSpec) {
146
+ return { spec: tarballSpec, source: 'local-tarball' };
147
+ }
148
+
149
+ return { spec: toFileSpec(packageRoot), source: 'local' };
150
+ }
151
+
152
+ // ── main ──────────────────────────────────────────────────────────────────────
153
+ async function main() {
154
+ p.intro(`${b(c(' Greg '))} Documentation Setup`);
155
+
156
+ let docsPath = './docs';
157
+ let title = 'My Docs';
158
+ let desc = 'Documentation';
159
+ let useTS = true;
160
+ let addScripts = true;
161
+ let docsType = '1';
162
+
163
+ if (!useDefaultsMode) {
164
+ docsPath = orCancel(await p.text({ message: 'Docs path', initialValue: './docs' }));
165
+ title = orCancel(await p.text({ message: 'Site title', initialValue: 'My Docs' }));
166
+ desc = orCancel(await p.text({ message: 'Site description', initialValue: 'Documentation' }));
167
+ useTS = orCancel(await p.confirm({ message: 'Use TypeScript for configuration?', initialValue: true }));
168
+ addScripts = orCancel(await p.confirm({ message: 'Add greg scripts to package.json?', initialValue: true }));
169
+ docsType = orCancel(await p.select({
170
+ message: 'Documentation contents',
171
+ options: [
172
+ { value: '1', label: 'Empty project', hint: 'blank docs folder with a starter page' },
173
+ { value: '2', label: 'Sample documentation', hint: 'starter template with examples' },
174
+ { value: '3', label: 'Generated fake documentation', hint: 'random Markdown files via fakeDocsGenerator' },
175
+ ],
176
+ }));
177
+ } else {
178
+ p.log.info('Using default init options (non-interactive mode).');
179
+ }
180
+
181
+ let fakeFilesLimit = 10000;
182
+ if (docsType === '3') {
183
+ const raw = orCancel(await p.text({ message: 'Number of files to generate', initialValue: '10000' }));
184
+ fakeFilesLimit = parseInt(raw, 10) || 10000;
185
+ }
186
+
187
+ // ── Derive values ─────────────────────────────────────────────────────────
188
+ const docsDir = docsPath.replace(/^\.\//, '').replace(/\/$/, '');
189
+ const ext = useTS ? 'ts' : 'js';
190
+ const vars = { TITLE: title, DESCRIPTION: desc, DOCS_DIR: docsDir, EXT: ext };
191
+
192
+ p.log.step('Creating files…');
193
+
194
+ // ── Core scaffold ─────────────────────────────────────────────────────────
195
+ ensure('index.html', tpl('index.html', vars));
196
+ ensure(`src/main.${ext}`, tpl('src/main.js')); // same content for .js and .ts
197
+ ensure('src/App.svelte', tpl('src/App.svelte'));
198
+ ensure('src/app.css', tpl('src/app.css'));
199
+ ensure(`vite.config.${ext}`, tpl('vite.config.js', vars)); // same content for .js and .ts
200
+ ensure('svelte.config.js', tpl('svelte.config.js')); // always .js — vite-plugin-svelte requires it
201
+ ensure(`greg.config.${ext}`, tpl(useTS ? 'greg.config.ts' : 'greg.config.js', vars));
202
+
203
+ if (useTS) {
204
+ ensure('tsconfig.json', tpl('tsconfig.json'));
205
+ }
206
+
207
+ // ── Docs ──────────────────────────────────────────────────────────────────
208
+ if (docsType === '1') {
209
+ ensure(`${docsDir}/index.md`, `# Welcome to ${title}\n\nStart writing your documentation here.\n`);
210
+ } else if (docsType === '2') {
211
+ // Mini sample docs from templates
212
+ const templateDocsDir = join(__dirname, 'templates', 'docs');
213
+ copyTemplateDir(templateDocsDir, docsDir, vars);
214
+ } else {
215
+ // Fake docs via fakeDocsGenerator
216
+ const generatorScript = join(__dirname, '../fakeDocsGenerator/generate_docs.js');
217
+ if (!existsSync(generatorScript)) {
218
+ console.log(` ${y('!')} fakeDocsGenerator not found at ${generatorScript}`);
219
+ } else {
220
+ p.log.step('Running fake docs generator…');
221
+ await new Promise((resolve, reject) => {
222
+ const child = fork(generatorScript, [
223
+ '--output', join(cwd, docsDir),
224
+ '--files-limit', String(fakeFilesLimit),
225
+ ], { stdio: 'inherit' });
226
+ child.on('exit', code => code === 0 ? resolve() : reject(new Error(`Generator exited with code ${code}`)));
227
+ });
228
+ }
229
+ }
230
+
231
+ // ── package.json scripts + devDependencies ────────────────────────────────
232
+ // @dominikcz/greg is written to devDependencies directly (never via npm install)
233
+ // so that local `npm link` and future registry installs both work correctly.
234
+ const gregPkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
235
+ const gregVersion = gregPkg.version;
236
+ const gregDevDeps = gregPkg.devDependencies ?? {};
237
+ const { spec: gregDependencySpec, source: gregDependencySource } = resolveGregDependencySpec(gregVersion);
238
+ {
239
+ const pkgPath = join(cwd, 'package.json');
240
+ if (existsSync(pkgPath)) {
241
+ try {
242
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
243
+ let changed = false;
244
+ if (addScripts) {
245
+ pkg.scripts ??= {};
246
+ for (const [k, v] of [['dev', 'greg dev'], ['build', 'greg build'], ['preview', 'greg preview']]) {
247
+ if (!pkg.scripts[k]) { pkg.scripts[k] = v; changed = true; }
248
+ }
249
+ }
250
+ // Greg scaffold uses ESM config files (vite/svelte/greg), so enforce
251
+ // package type to avoid Node CJS/typeless-module config loading errors.
252
+ if (!pkg.type || pkg.type === 'commonjs') {
253
+ pkg.type = 'module';
254
+ changed = true;
255
+ }
256
+ pkg.devDependencies ??= {};
257
+ if (!pkg.devDependencies['@dominikcz/greg'] || isTransientCacheSpec(pkg.devDependencies['@dominikcz/greg'])) {
258
+ pkg.devDependencies['@dominikcz/greg'] = gregDependencySpec;
259
+ changed = true;
260
+ }
261
+ if (changed) {
262
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
263
+ p.log.success('package.json ' + d('(updated)'));
264
+ } else {
265
+ p.log.warn('package.json ' + d('(already up to date, skipped)'));
266
+ }
267
+ } catch {
268
+ p.log.warn('Could not update package.json');
269
+ }
270
+ } else {
271
+ const pkg = {
272
+ name: 'my-docs',
273
+ version: '0.0.1',
274
+ type: 'module',
275
+ ...(addScripts ? { scripts: { dev: 'greg dev', build: 'greg build', preview: 'greg preview' } } : {}),
276
+ devDependencies: { '@dominikcz/greg': gregDependencySpec },
277
+ };
278
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
279
+ console.log(` ${g('+')} package.json`);
280
+ }
281
+ }
282
+
283
+ // ── Install dependencies ──────────────────────────────────────────────────
284
+ // @dominikcz/greg is already in package.json devDependencies — install only peer deps.
285
+ const peerDepsArr = [
286
+ `@sveltejs/vite-plugin-svelte@${gregDevDeps['@sveltejs/vite-plugin-svelte'] ?? '^6'}`,
287
+ `svelte@${gregDevDeps.svelte ?? '^5'}`,
288
+ `vite@${gregDevDeps.vite ?? '^7'}`,
289
+ ...(useTS ? ['typescript'] : []),
290
+ ];
291
+ const pm = detectPm();
292
+ const installArgs = pm === 'npm'
293
+ ? ['install', '--save-dev', ...peerDepsArr]
294
+ : ['add', '-D', ...peerDepsArr];
295
+
296
+ const installNow = useDefaultsMode
297
+ ? true
298
+ : orCancel(await p.confirm({ message: 'Install dependencies now?', initialValue: true }));
299
+
300
+ if (installNow) {
301
+ if (gregDependencySource === 'local') {
302
+ p.log.warn('@dominikcz/greg is not available on npm for this version; using local package source.');
303
+ }
304
+ if (gregDependencySource === 'local-tarball') {
305
+ p.log.warn('@dominikcz/greg is not available on npm for this version; pinned to local tarball in project root.');
306
+ }
307
+ p.log.step(`Running ${pm} ${installArgs[0]}…`);
308
+ const result = spawnSync(pm, installArgs, { cwd, stdio: 'inherit', shell: true });
309
+ if (result.status !== 0) {
310
+ p.log.warn('Installation failed. Run manually:');
311
+ console.log(` ${c(`${pm} ${installArgs.join(' ')}`)}`);
312
+ }
313
+
314
+ // Try to link @dominikcz/greg for local development (fails silently when not needed)
315
+ if (!existsSync(join(cwd, 'node_modules/@dominikcz/greg'))) {
316
+ const linkResult = spawnSync('npm', ['link', '@dominikcz/greg'], { cwd, stdio: 'pipe', shell: true });
317
+ if (linkResult.status !== 0) {
318
+ p.log.warn('@dominikcz/greg not found locally. Run after publishing or linking:');
319
+ console.log(` ${c('npm link @dominikcz/greg')} ${d('(local dev)')}`);
320
+ console.log(` ${c('npm install')} ${d('(after publishing)')}`);
321
+ }
322
+ }
323
+ }
324
+
325
+ p.outro(
326
+ installNow
327
+ ? `${b(g('Done!'))} Start your project:\n\n ${c('npm run dev')}`
328
+ : `${b(g('Done!'))} Next steps:\n\n ${c(`${pm} ${installArgs.join(' ')}`)}\n ${c('npm run dev')}`
329
+ );
330
+ }
331
+
332
+ // ── Recursive template dir copy (applies variable substitution) ──────────────
333
+ function copyTemplateDir(srcDir, destRel, vars) {
334
+ for (const entry of readdirSync(srcDir)) {
335
+ const srcPath = join(srcDir, entry);
336
+ if (statSync(srcPath).isDirectory()) {
337
+ copyTemplateDir(srcPath, join(destRel, entry), vars);
338
+ } else {
339
+ let content = readFileSync(srcPath, 'utf-8');
340
+ for (const [k, v] of Object.entries(vars)) {
341
+ content = content.split(`{{${k}}}`).join(v);
342
+ }
343
+ ensure(join(destRel, entry), content);
344
+ }
345
+ }
346
+ }
347
+
348
+ main().catch((err) => {
349
+ console.error(err);
350
+ process.exit(1);
351
+ });
@@ -0,0 +1,47 @@
1
+ # Getting started
2
+
3
+ Welcome to **{{TITLE}}**!
4
+
5
+ ## Why Greg?
6
+
7
+ Greg is optimized for large documentation projects: preprocessed metadata,
8
+ predictable routing/sidebar generation, and search that scales to bigger docs.
9
+ It keeps configuration predictable, while some runtime API and platform
10
+ features intentionally differ.
11
+
12
+ ## Writing docs
13
+
14
+ Add Markdown files to this folder. Greg will automatically build a sidebar and routes from the file structure.
15
+
16
+ ```bash
17
+ {{DOCS_DIR}}/
18
+ index.md ← home page
19
+ getting-started.md
20
+ guide/
21
+ installation.md
22
+ configuration.md
23
+ reference/
24
+ api.md
25
+ ```
26
+
27
+ ## Front matter
28
+
29
+ Every page can use YAML front matter:
30
+
31
+ ```yaml
32
+ ---
33
+ title: My Page
34
+ order: 1
35
+ ---
36
+ ```
37
+
38
+ ## Math, diagrams and more
39
+
40
+ Greg supports:
41
+
42
+ - **Mermaid** diagrams
43
+ - **LaTeX** math via MathJax
44
+ - **Custom containers** (`::: tip`, `::: warning`, `::: danger`)
45
+ - **Code groups** and syntax highlighting via Shiki
46
+
47
+ Visit the [Greg documentation](https://github.com/dominikcz/greg) to learn more.
@@ -0,0 +1,11 @@
1
+ ---
2
+ layout: home
3
+ hero:
4
+ name: "{{TITLE}}"
5
+ text: "Documentation"
6
+ tagline: Welcome! Start writing your docs in this folder.
7
+ actions:
8
+ - theme: brand
9
+ text: Get Started
10
+ link: {{ROOT_PATH}}/getting-started
11
+ ---
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @type {import('@dominikcz/greg').GregConfig}
3
+ */
4
+ export default {
5
+ // VitePress-compatible build options:
6
+ // base: '/',
7
+ // outDir: 'dist',
8
+ srcDir: '{{DOCS_DIR}}',
9
+ docsBase: '',
10
+ mainTitle: '{{TITLE}}',
11
+ sidebar: 'auto',
12
+ // versioning: {
13
+ // strategy: 'branches', // default
14
+ // default: 'latest',
15
+ // aliases: {
16
+ // latest: '2.1',
17
+ // stable: '2.0',
18
+ // },
19
+ // ui: {
20
+ // versionMenuLabel: 'Version',
21
+ // manifestUnavailableText: 'Version selector unavailable',
22
+ // showManifestUnavailableStatus: false,
23
+ // outdatedVersionMessage: 'You are viewing an older version ({current}). Recommended: {default}.',
24
+ // outdatedVersionActionLabel: 'Go to latest',
25
+ // },
26
+ // locales: {
27
+ // '/': {
28
+ // ui: { versionMenuLabel: 'Version' },
29
+ // },
30
+ // '/pl/': {
31
+ // ui: { versionMenuLabel: 'Wersja' },
32
+ // },
33
+ // },
34
+ // branches: [
35
+ // { version: '2.1', branch: 'main', title: '2.1' },
36
+ // { version: '2.0', branch: 'release/2.0', title: '2.0' },
37
+ // ],
38
+ // },
39
+ }
@@ -0,0 +1,38 @@
1
+ import type { GregConfig } from '@dominikcz/greg'
2
+
3
+ export default {
4
+ // VitePress-compatible build options:
5
+ // base: '/',
6
+ // outDir: 'dist',
7
+ srcDir: '{{DOCS_DIR}}',
8
+ docsBase: '',
9
+ mainTitle: '{{TITLE}}',
10
+ sidebar: 'auto',
11
+ // versioning: {
12
+ // strategy: 'branches', // default
13
+ // default: 'latest',
14
+ // aliases: {
15
+ // latest: '2.1',
16
+ // stable: '2.0',
17
+ // },
18
+ // ui: {
19
+ // versionMenuLabel: 'Version',
20
+ // manifestUnavailableText: 'Version selector unavailable',
21
+ // showManifestUnavailableStatus: false,
22
+ // outdatedVersionMessage: 'You are viewing an older version ({current}). Recommended: {default}.',
23
+ // outdatedVersionActionLabel: 'Go to latest',
24
+ // },
25
+ // locales: {
26
+ // '/': {
27
+ // ui: { versionMenuLabel: 'Version' },
28
+ // },
29
+ // '/pl/': {
30
+ // ui: { versionMenuLabel: 'Wersja' },
31
+ // },
32
+ // },
33
+ // branches: [
34
+ // { version: '2.1', branch: 'main', title: '2.1' },
35
+ // { version: '2.0', branch: 'release/2.0', title: '2.0' },
36
+ // ],
37
+ // },
38
+ } satisfies GregConfig
@@ -0,0 +1,16 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <meta name="description" content="{{DESCRIPTION}}" />
8
+ <title>{{TITLE}}</title>
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app"></div>
13
+ <script type="module" src="/src/main.{{EXT}}"></script>
14
+ </body>
15
+
16
+ </html>
@@ -0,0 +1,5 @@
1
+ <script>
2
+ import MarkdownDocs from "@dominikcz/greg";
3
+ </script>
4
+
5
+ <MarkdownDocs />
@@ -0,0 +1,20 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ body {
8
+ margin: 0;
9
+ min-width: 320px;
10
+ min-height: 100vh;
11
+ font-family: ui-sans-serif, system-ui, sans-serif;
12
+ line-height: 1.75;
13
+ font-weight: 400;
14
+ color-scheme: light dark;
15
+ }
16
+
17
+ #app {
18
+ width: 100%;
19
+ height: 100vh;
20
+ }
@@ -0,0 +1,9 @@
1
+ import { mount } from 'svelte'
2
+ import './app.css'
3
+ import App from './App.svelte'
4
+
5
+ const app = mount(App, {
6
+ target: document.getElementById('app'),
7
+ })
8
+
9
+ export default app
@@ -0,0 +1 @@
1
+ export { default } from '@dominikcz/greg/svelte.config'
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "moduleResolution": "bundler",
8
+ "allowImportingTsExtensions": true,
9
+ "isolatedModules": true,
10
+ "noEmit": true,
11
+ "strict": true
12
+ },
13
+ "include": [
14
+ "src/**/*.ts",
15
+ "src/**/*.d.ts",
16
+ "src/**/*.svelte",
17
+ "vite.config.ts",
18
+ "svelte.config.js",
19
+ "greg.config.ts"
20
+ ]
21
+ }
@@ -0,0 +1,23 @@
1
+ import { defineConfig } from 'vite'
2
+ import { svelte } from '@sveltejs/vite-plugin-svelte'
3
+ import {
4
+ vitePluginGregConfig,
5
+ vitePluginSearchIndex,
6
+ vitePluginSearchServer,
7
+ vitePluginFrontmatter,
8
+ vitePluginCopyDocs,
9
+ } from '@dominikcz/greg/plugins'
10
+
11
+ const docsDir = process.env.GREG_DOCS_DIR || '{{DOCS_DIR}}'
12
+ const docsBase = process.env.GREG_DOCS_BASE || '{{ROOT_PATH}}'
13
+
14
+ export default defineConfig({
15
+ plugins: [
16
+ svelte(),
17
+ vitePluginGregConfig(),
18
+ vitePluginSearchIndex({ docsDir, srcDir: docsBase }),
19
+ vitePluginSearchServer({ docsDir, srcDir: docsBase }),
20
+ vitePluginFrontmatter({ docsDir, srcDir: docsBase }),
21
+ vitePluginCopyDocs({ docsDir, srcDir: docsBase }),
22
+ ],
23
+ })
@@ -0,0 +1,4 @@
1
+ ```javascript
2
+ const greeting = 'Hello, Greg!';
3
+ console.log(greeting);
4
+ ```
@@ -0,0 +1,10 @@
1
+ ```js
2
+ export default {
3
+ data () {
4
+ return {
5
+ msg: 'Removed' // [!code --]
6
+ msg: 'Added' // [!code ++]
7
+ }
8
+ }
9
+ }
10
+ ```
@@ -0,0 +1,5 @@
1
+ ```ts
2
+ const visible = true;
3
+ const important = true; // [!code focus]
4
+ const alsoImportant = true; // [!code focus]
5
+ ```
@@ -0,0 +1,3 @@
1
+ ```ts [api.ts]
2
+ export const add = (a: number, b: number) => a + b;
3
+ ```
@@ -0,0 +1,5 @@
1
+ ```ts{2}
2
+ const a = 1;
3
+ const b = 2;
4
+ console.log(a + b);
5
+ ```
@@ -0,0 +1,5 @@
1
+ ```ts:line-numbers=10 {1}
2
+ const first = 'A';
3
+ const second = 'B';
4
+ console.log(first, second);
5
+ ```
@@ -0,0 +1,4 @@
1
+ ::: info Note from partials
2
+ This content is included from `/__partials/note.md`.
3
+ The `/` prefix resolves to the `docs/` directory root.
4
+ :::
@@ -0,0 +1,4 @@
1
+ ::: warning Shared warning
2
+ This content is included from `__shared-warning.md` via the `<!--@include:-->` directive.
3
+ Partial files (names starting with `__`) are excluded from routing but can be included in other pages.
4
+ :::