core-maugli 1.1.5 → 1.1.6
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 +133 -3
- package/astro.config.mjs +8 -7
- package/bin/init.js +51 -3
- package/package.json +1 -1
- package/src/config/maugli.config.ts +15 -1
- package/src/content/pages/about.md +40 -0
- package/src/content/pages/contact.md +10 -0
- package/src/content/pages/terms.md +12 -0
- package/src/styles/global.css +5 -4
package/README.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
Hi-perfomance, SEO&AI-SEO optimised
|
4
4
|
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
Maugli is a lightweight, agent-friendly blog that can integrate into an existing site or run as a standalone project. Link the blog's logo to your primary site by setting `brand.logoHref` in [`src/config/maugli.config.ts`](src/config/maugli.config.ts).
|
8
|
+
|
9
|
+
The theme includes a `product` entity for showcasing offerings. Rename it (for example, to "services") and hide or customize related menu items by editing the `navLinks` array in the same configuration file.
|
10
|
+
|
5
11
|
[](https://app.netlify.com/start/deploy?repository=https://github.com/dashapps/maugli-astro-theme)
|
6
12
|
|
7
13
|
Before deploying, push this project to your own Git repository. Update the
|
@@ -29,6 +35,22 @@ cd my-blog
|
|
29
35
|
npm run dev
|
30
36
|
```
|
31
37
|
|
38
|
+
To initialize inside the current folder use:
|
39
|
+
|
40
|
+
```bash
|
41
|
+
npx core-maugli init .
|
42
|
+
```
|
43
|
+
|
44
|
+
The init script lets you choose a language or pass one with `--lang`. Available codes: `ru`, `en`, `es`, `de`, `pt`, `fr`, `zh`, `ja`.
|
45
|
+
|
46
|
+
Example:
|
47
|
+
|
48
|
+
```bash
|
49
|
+
npx core-maugli init my-blog --lang es
|
50
|
+
```
|
51
|
+
|
52
|
+
You pick the language only once during project creation; updates won't ask again.
|
53
|
+
|
32
54
|
Your blog will be available at `http://localhost:4321/`
|
33
55
|
|
34
56
|
1. **Install dependencies**
|
@@ -60,6 +82,90 @@ Your blog will be available at `http://localhost:4321/`
|
|
60
82
|
npm run build
|
61
83
|
```
|
62
84
|
|
85
|
+
`npm run build` runs [`scripts/verify-assets.js`](scripts/verify-assets.js)
|
86
|
+
before the Astro build. This script checks the SHA-256 hashes of the
|
87
|
+
floating label component and footer badge to ensure they haven't been
|
88
|
+
modified. The floating label's hash is validated to ensure compliance
|
89
|
+
with licensing.
|
90
|
+
|
91
|
+
If you hold a commercial license and legitimately change the label,
|
92
|
+
generate its new SHA-256 hash and replace the value for
|
93
|
+
`src/components/MaugliFloatingLabel.astro` in the `files` object of
|
94
|
+
[`scripts/verify-assets.js`](scripts/verify-assets.js). For example:
|
95
|
+
|
96
|
+
```bash
|
97
|
+
node -e "import { createHash } from 'crypto'; import { readFileSync } from 'fs'; console.log(createHash('sha256').update(readFileSync('src/components/MaugliFloatingLabel.astro')).digest('hex'))"
|
98
|
+
```
|
99
|
+
|
100
|
+
If you change these assets without updating their hashes in the
|
101
|
+
script, the build will fail.
|
102
|
+
|
103
|
+
### Customizing fonts
|
104
|
+
|
105
|
+
This project uses [Fontsource](https://fontsource.org/) for typography. To add a different font, install the desired package:
|
106
|
+
|
107
|
+
```bash
|
108
|
+
npm install @fontsource-variable/roboto
|
109
|
+
```
|
110
|
+
|
111
|
+
Then replace or add the corresponding `@import` line in [`src/styles/global.css`](src/styles/global.css):
|
112
|
+
|
113
|
+
```css
|
114
|
+
@import '@fontsource-variable/roboto/wght.css' layer(base);
|
115
|
+
```
|
116
|
+
|
117
|
+
Update the `--font-sans` or `--font-serif` variables in the same file so Tailwind uses the new font:
|
118
|
+
|
119
|
+
```css
|
120
|
+
--font-sans: 'Roboto Variable', sans-serif;
|
121
|
+
/* or */
|
122
|
+
--font-serif: 'Roboto Variable', sans-serif;
|
123
|
+
```
|
124
|
+
|
125
|
+
Repeat these steps for any other fonts you want to include.
|
126
|
+
|
127
|
+
### Configuring PWA colors and icons
|
128
|
+
|
129
|
+
Progressive Web App options live under the `pwa` key in [`src/config/maugli.config.ts`](src/config/maugli.config.ts). The section accepts:
|
130
|
+
|
131
|
+
- `themeColor` – used for the manifest's `theme_color` and the `<meta name="theme-color">` tag
|
132
|
+
- `backgroundColor` – controls the manifest's `background_color`
|
133
|
+
- `icons` – array of icon definitions with `src`, `sizes`, `type`, and optional `purpose`
|
134
|
+
|
135
|
+
Example configuration:
|
136
|
+
|
137
|
+
```ts
|
138
|
+
// src/config/maugli.config.ts
|
139
|
+
export const maugliConfig = {
|
140
|
+
// ...other fields
|
141
|
+
pwa: {
|
142
|
+
themeColor: '#0cbf11',
|
143
|
+
backgroundColor: '#ffffff',
|
144
|
+
icons: [
|
145
|
+
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'any maskable' },
|
146
|
+
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' }
|
147
|
+
]
|
148
|
+
}
|
149
|
+
};
|
150
|
+
```
|
151
|
+
|
152
|
+
These values are referenced in `astro.config.mjs` when generating the manifest:
|
153
|
+
|
154
|
+
```js
|
155
|
+
// astro.config.mjs
|
156
|
+
import { maugliConfig } from './src/config/maugli.config';
|
157
|
+
|
158
|
+
export const pwaOptions = {
|
159
|
+
manifest: {
|
160
|
+
background_color: maugliConfig.pwa?.backgroundColor,
|
161
|
+
theme_color: maugliConfig.pwa?.themeColor,
|
162
|
+
icons: maugliConfig.pwa?.icons
|
163
|
+
}
|
164
|
+
};
|
165
|
+
```
|
166
|
+
|
167
|
+
Updating the values in `maugli.config.ts` automatically refreshes the PWA manifest generated by Astro.
|
168
|
+
|
63
169
|
### Testing
|
64
170
|
|
65
171
|
Run the test suite to verify that example content is filtered correctly:
|
@@ -74,13 +180,19 @@ If you want to hide the example content included with this theme, set
|
|
74
180
|
`showExamples: false` in `src/config/maugli.config.ts`. Example files are
|
75
181
|
marked with `isExample: true` in their frontmatter.
|
76
182
|
|
183
|
+
To restore the default example posts and other sample content later, run:
|
184
|
+
|
185
|
+
```bash
|
186
|
+
npx core-maugli init .
|
187
|
+
```
|
188
|
+
|
77
189
|
### Useful npm scripts
|
78
190
|
|
79
191
|
| Script | Description |
|
80
192
|
| -------------------------------- | ------------------------------------------- |
|
81
193
|
| `npm run dev` | Start local dev server |
|
82
194
|
| `npm start` | Alias for `npm run dev` |
|
83
|
-
| `npm run build` | Format content then create production build |
|
195
|
+
| `npm run build` | Format content, verify assets, then create production build |
|
84
196
|
| `npm run typograf` | Run typograf on all posts |
|
85
197
|
| `npm run astro` | Access the Astro CLI |
|
86
198
|
| `npm run featured:add <slug>` | Mark a post as featured |
|
@@ -89,11 +201,29 @@ marked with `isExample: true` in their frontmatter.
|
|
89
201
|
| `npm run upgrade` | Manually update `maugli.config.ts` |
|
90
202
|
| `npm run backup-update` | Backup key files then run `npm update` |
|
91
203
|
|
204
|
+
## Checking installed version
|
205
|
+
|
206
|
+
See which version of the theme is installed:
|
207
|
+
|
208
|
+
```bash
|
209
|
+
npm list core-maugli
|
210
|
+
```
|
211
|
+
|
92
212
|
## Updating
|
93
213
|
|
94
|
-
|
214
|
+
Upgrade to the latest release:
|
215
|
+
|
216
|
+
```bash
|
217
|
+
npm update
|
218
|
+
```
|
219
|
+
|
220
|
+
To back up key files and then update, run:
|
221
|
+
|
222
|
+
```bash
|
223
|
+
npm run backup-update
|
224
|
+
```
|
95
225
|
|
96
|
-
|
226
|
+
Both commands replace the theme's components and layouts with the latest versions. Content under `src/content/**`, your stylesheet `src/styles/global.css` and your `src/config/maugli.config.ts` file are kept. Commit any local changes before updating.
|
97
227
|
|
98
228
|
## Licensing
|
99
229
|
|
package/astro.config.mjs
CHANGED
@@ -7,6 +7,7 @@ import { VitePWA } from 'vite-plugin-pwa';
|
|
7
7
|
import siteConfig from './src/data/site-config';
|
8
8
|
import remarkSlug from 'remark-slug';
|
9
9
|
import customSlugify from './src/utils/remark-slugify';
|
10
|
+
import { maugliConfig } from './src/config/maugli.config';
|
10
11
|
|
11
12
|
export const pwaOptions = {
|
12
13
|
registerType: 'autoUpdate',
|
@@ -16,21 +17,21 @@ export const pwaOptions = {
|
|
16
17
|
short_name: "Maugli",
|
17
18
|
start_url: "/",
|
18
19
|
display: "standalone",
|
19
|
-
background_color:
|
20
|
-
theme_color:
|
21
|
-
icons: [
|
20
|
+
background_color: maugliConfig.pwa?.backgroundColor ?? '#ffffff',
|
21
|
+
theme_color: maugliConfig.pwa?.themeColor ?? '#0cbf11',
|
22
|
+
icons: maugliConfig.pwa?.icons ?? [
|
22
23
|
{
|
23
24
|
src: "/icon-192.png",
|
24
25
|
sizes: "192x192",
|
25
26
|
type: "image/png",
|
26
|
-
purpose: "any maskable"
|
27
|
+
purpose: "any maskable",
|
27
28
|
},
|
28
29
|
{
|
29
30
|
src: "/icon-512.png",
|
30
31
|
sizes: "512x512",
|
31
|
-
type: "image/png"
|
32
|
-
}
|
33
|
-
]
|
32
|
+
type: "image/png",
|
33
|
+
},
|
34
|
+
],
|
34
35
|
},
|
35
36
|
workbox: {
|
36
37
|
navigateFallback: '/index.html',
|
package/bin/init.js
CHANGED
@@ -1,16 +1,52 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
import { execSync } from 'child_process';
|
4
|
-
import { cpSync, existsSync, writeFileSync } from 'fs';
|
4
|
+
import { cpSync, existsSync, readFileSync, writeFileSync } from 'fs';
|
5
5
|
import path from 'path';
|
6
|
+
import readline from 'readline';
|
6
7
|
import { fileURLToPath } from 'url';
|
7
8
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
9
10
|
const __dirname = path.dirname(__filename);
|
10
11
|
const templateRoot = path.join(__dirname, '..');
|
11
12
|
|
12
|
-
|
13
|
+
function getLanguageCodes() {
|
14
|
+
const file = readFileSync(path.join(templateRoot, 'src/i18n/languages.ts'), 'utf8');
|
15
|
+
const codes = [];
|
16
|
+
const regex = /{\s*code:\s*'([^']+)'/g;
|
17
|
+
let match;
|
18
|
+
while ((match = regex.exec(file)) !== null) {
|
19
|
+
codes.push(match[1]);
|
20
|
+
}
|
21
|
+
return codes;
|
22
|
+
}
|
23
|
+
|
24
|
+
function promptLang(codes) {
|
25
|
+
return new Promise(resolve => {
|
26
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
27
|
+
rl.question(`Choose language (${codes.join(', ')}): `, answer => {
|
28
|
+
rl.close();
|
29
|
+
resolve(codes.includes(answer) ? answer : codes[0]);
|
30
|
+
});
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
function updateConfig(targetDir, lang) {
|
35
|
+
const configPath = path.join(targetDir, 'src', 'config', 'maugli.config.ts');
|
36
|
+
if (!existsSync(configPath)) return;
|
37
|
+
let content = readFileSync(configPath, 'utf8');
|
38
|
+
content = content.replace(/defaultLang:\s*'[^']*'/, `defaultLang: '${lang}'`);
|
39
|
+
const multiMatch = content.match(/enableMultiLang:\s*(true|false)/);
|
40
|
+
const multi = multiMatch ? multiMatch[1] === 'true' : false;
|
41
|
+
content = content.replace(/showLangSwitcher:\s*(true|false)/, `showLangSwitcher: ${multi}`);
|
42
|
+
writeFileSync(configPath, content);
|
43
|
+
console.log(`Configured default language to ${lang}`);
|
44
|
+
}
|
45
|
+
|
46
|
+
export default async function init(targetName, langOption) {
|
13
47
|
const targetDir = targetName ? path.resolve(targetName) : process.cwd();
|
48
|
+
const codes = getLanguageCodes();
|
49
|
+
const lang = langOption && codes.includes(langOption) ? langOption : await promptLang(codes);
|
14
50
|
|
15
51
|
function copyItem(item) {
|
16
52
|
const src = path.join(templateRoot, item);
|
@@ -86,9 +122,21 @@ dist/
|
|
86
122
|
console.log('Created .prettierrc');
|
87
123
|
|
88
124
|
execSync('npm install', { cwd: targetDir, stdio: 'inherit' });
|
125
|
+
updateConfig(targetDir, lang);
|
89
126
|
}
|
90
127
|
|
91
128
|
// Если скрипт запускается напрямую
|
92
129
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
93
|
-
|
130
|
+
const args = process.argv.slice(2);
|
131
|
+
let targetName;
|
132
|
+
let lang;
|
133
|
+
for (let i = 0; i < args.length; i++) {
|
134
|
+
if (args[i] === '--lang' && i + 1 < args.length) {
|
135
|
+
lang = args[i + 1];
|
136
|
+
i++;
|
137
|
+
} else {
|
138
|
+
targetName = args[i];
|
139
|
+
}
|
140
|
+
}
|
141
|
+
await init(targetName, lang);
|
94
142
|
}
|
package/package.json
CHANGED
@@ -49,6 +49,12 @@ export interface MaugliConfig {
|
|
49
49
|
enableFAQ: boolean; // Enable FAQ block
|
50
50
|
enableRSS: boolean; // Enable RSS feed
|
51
51
|
};
|
52
|
+
// Progressive Web App settings
|
53
|
+
pwa?: {
|
54
|
+
themeColor?: string; // Theme color for the PWA manifest
|
55
|
+
backgroundColor?: string; // Background color for the PWA manifest
|
56
|
+
icons?: Array<{ src: string; sizes: string; type: string; purpose?: string }>; // Icons for the PWA manifest
|
57
|
+
};
|
52
58
|
// Control display of tags/rubrics
|
53
59
|
// Theme switcher
|
54
60
|
enableThemeSwitcher?: boolean; // Enable theme switcher (true by default)
|
@@ -157,6 +163,14 @@ export const maugliConfig: MaugliConfig = {
|
|
157
163
|
enableFAQ: true, // Enable FAQ block
|
158
164
|
enableRSS: true, // Enable RSS feed
|
159
165
|
},
|
166
|
+
pwa: {
|
167
|
+
themeColor: '#0cbf11', // Theme color for the PWA manifest
|
168
|
+
backgroundColor: '#ffffff', // Background color for the PWA manifest
|
169
|
+
icons: [
|
170
|
+
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'any maskable' },
|
171
|
+
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
|
172
|
+
],
|
173
|
+
},
|
160
174
|
showOnlyRubricsTags: true, // Show only rubrics by default
|
161
175
|
|
162
176
|
links: {
|
@@ -195,7 +209,7 @@ export const maugliConfig: MaugliConfig = {
|
|
195
209
|
defaultAuthorId: 'default-autor', // Default author id (used if no author is specified). Use the filename of the author .md file without the .md extension
|
196
210
|
showAuthorsWithoutArticles: true, // Show authors without articles (default: true)
|
197
211
|
showAuthorArticleCount: true, // Show article count for author
|
198
|
-
showLangSwitcher:
|
212
|
+
showLangSwitcher: false, // Show language switcher
|
199
213
|
langLinks: {
|
200
214
|
ru: 'https://maugli.cfd/ru', // Russian version
|
201
215
|
en: 'https://maugli.cfd/en', // English version
|
@@ -0,0 +1,40 @@
|
|
1
|
+
---
|
2
|
+
title: О блоге
|
3
|
+
seo:
|
4
|
+
title: ТехРев — блог, который самостоятельно ведет AI-автор
|
5
|
+
description: Демо-витрина автоматического AI-блога с персоной
|
6
|
+
image:
|
7
|
+
src: '/tr-about.webp'
|
8
|
+
alt: A person sitting at a desk in front of a computer
|
9
|
+
width: '1200'
|
10
|
+
height: '1200'
|
11
|
+
---
|
12
|
+
О концепции блога TechRev — "Технологическая революция". Блог полностью ведётся искусственным интеллектом от лица цифровой персоны — ИльичAI 🚩. Это демонстрация возможностей нейросетей создавать контент от имени автора.
|
13
|
+
|
14
|
+
ИльичAI — вождь новой эпохи. Он за освобождение общества от бессмысленного ручного интернето-марательства путём внедрения нейросетей и автоматизации контента, маркетинга и продаж.
|
15
|
+
|
16
|
+
## В блоге
|
17
|
+
|
18
|
+
🚀 Как выполнить пятилетку за неделю: быстрые планы автоматизации создания контента, экономящие месяцы работы. #ПятилеткаЗаТриДня
|
19
|
+
|
20
|
+
🔧 Пошаговые сценарии освобождения бизнеса от рутины: схемы без миллионов и армии айтишников. #СкиньОковы
|
21
|
+
|
22
|
+
📢 Манифесты против легаси-процессов: где утекает время и как это исправить. #НовыйМир
|
23
|
+
|
24
|
+
🏆 Истории трудовых побед: как наши товарищи внедряют искусственный интеллект в производство контента. #ТоварищиВнедряют
|
25
|
+
|
26
|
+
🚩 Технологии — наш серп ⚙️. Автоматизация — наш молот 🛠. Нейросети — наше знамя 🤖.
|
27
|
+
|
28
|
+
## Почему автором выбран Ильич?
|
29
|
+
|
30
|
+
Все материалы создаются, редактируются и оформляются с помощью самостоятельных AI-агентов. Процесс полностью автоматизирован. Это ли не контентная революция?
|
31
|
+
|
32
|
+
Выбор Ильича как цифрового вождя этой витрины не случаен. Поскольку контент блога полностью автоматизирован, его задача — не просто информировать, а наглядно показать, как искусственный интеллект может работать от лица харизматичной и узнаваемой персоны.
|
33
|
+
|
34
|
+
ИльичAI — это метафора технологической революции, символ духа перемен, но уже в новом, цифровом контексте. Он наследует вайб прототипа, но говорит о совершенно иных вещах: вместо политической революции — революция технологическая, вместо призывов к трудовым свершениям — призывы к освобождению от рутинной работы с помощью нейросетей и автоматизации.
|
35
|
+
|
36
|
+
Это демонстрация того, как можно строить узнаваемость и привлекать внимание с помощью сильной цифровой персоны, даже в полностью автоматизированном контенте.
|
37
|
+
|
38
|
+
## Если ваш контент еще не автоматизирован — мы готовы сделать это за вас:
|
39
|
+
|
40
|
+
Хотите протестировать такие процессы или интегрировать AI в свой бизнес? По вопросам сотрудничества: [Связаться в Telegram](https://t.me/darrrina)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
---
|
2
|
+
title: Для связи
|
3
|
+
seo:
|
4
|
+
title: Контакты
|
5
|
+
description: Создаем автоматические AI-блоги и телеграм-каналы любой тематики для брендов, экспертов, СЕО
|
6
|
+
---
|
7
|
+
|
8
|
+
Maugli -- контент-фермы с гибкой настройкой продуктов (целевая ссылка), каналов, авторов, тематики и тональности. Эта полный производственный цикл создания контента от поиска виральных тем до адаптации и публикауции. От человека требуется первоначальныц контроль в проуессе дообучения. Все остальное делают агенты.
|
9
|
+
|
10
|
+
[Связаться в Telegram](https://t.me/darrrina)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
---
|
2
|
+
title: Что такое контент-фермы
|
3
|
+
seo:
|
4
|
+
title: Как автоматически создавать контент для блогов и телеграм-канаалов?
|
5
|
+
description: Полная автоматизация блогов уже возможна без потери качества.
|
6
|
+
---
|
7
|
+
|
8
|
+
**Раздел в процессе наполнения**
|
9
|
+
|
10
|
+
Больше деталей на maugli.cfd
|
11
|
+
|
12
|
+
|
package/src/styles/global.css
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/* Import fonts. Replace or add lines to use other Fontsource packages. */
|
1
2
|
@import '@fontsource-variable/inter/wght.css' layer(base);
|
2
3
|
@import '@fontsource-variable/geologica/wght.css' layer(base);
|
3
4
|
|
@@ -23,8 +24,8 @@
|
|
23
24
|
--bg-main-40: rgba(255, 255, 255, 0.4);
|
24
25
|
--bg-muted: rgba(237, 241, 247, 0.621);
|
25
26
|
--border-main: rgba(17, 28, 44, 0.13);
|
26
|
-
--font-sans: 'Inter Variable', sans-serif;
|
27
|
-
--font-serif: 'Geologica Variable', sans-serif;
|
27
|
+
--font-sans: 'Inter Variable', sans-serif; /* Update if you change the sans-serif font */
|
28
|
+
--font-serif: 'Geologica Variable', sans-serif; /* Update if you change the serif font */
|
28
29
|
|
29
30
|
/* Card Styles */
|
30
31
|
--card-shadow:
|
@@ -100,8 +101,8 @@ html.dark {
|
|
100
101
|
*/
|
101
102
|
|
102
103
|
@theme inline {
|
103
|
-
--font-sans: 'Inter Variable', sans-serif;
|
104
|
-
--font-serif: 'Geologica Variable', sans-serif;
|
104
|
+
--font-sans: 'Inter Variable', sans-serif; /* Match --font-sans above if changed */
|
105
|
+
--font-serif: 'Geologica Variable', sans-serif; /* Match --font-serif above if changed */
|
105
106
|
--font-weight-bold: 700;
|
106
107
|
--font-weight-extra-bold: 800;
|
107
108
|
--text-color-main: var(--text-main);
|