stella-coder 3.9.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.
@@ -0,0 +1,121 @@
1
+ from pptx import Presentation
2
+ from pptx.util import Inches, Pt, Emu
3
+ from pptx.dml.color import RGBColor
4
+ from pptx.enum.text import PP_ALIGN
5
+
6
+ prs = Presentation()
7
+ prs.slide_width = Inches(13.333)
8
+ prs.slide_height = Inches(7.5)
9
+
10
+ # Цвета
11
+ ORANGE = RGBColor(0xFF, 0x8C, 0x00)
12
+ DARK = RGBColor(0x2D, 0x2D, 0x2D)
13
+ WHITE = RGBColor(0xFF, 0xFF, 0xFF)
14
+ LIGHT_BG = RGBColor(0xFF, 0xF5, 0xE6)
15
+
16
+ def set_slide_bg(slide, r, g, b):
17
+ background = slide.background
18
+ fill = background.fill
19
+ fill.solid()
20
+ fill.fore_color.rgb = RGBColor(r, g, b)
21
+
22
+ def add_text_box(slide, left, top, width, height, text, font_size=24, bold=False, color=DARK, alignment=PP_ALIGN.LEFT):
23
+ txBox = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
24
+ tf = txBox.text_frame
25
+ tf.word_wrap = True
26
+ p = tf.paragraphs[0]
27
+ p.text = text
28
+ p.font.size = Pt(font_size)
29
+ p.font.bold = bold
30
+ p.font.color.rgb = color
31
+ p.alignment = alignment
32
+ return txBox
33
+
34
+ def add_bullets(slide, left, top, width, height, items, font_size=20, color=DARK):
35
+ txBox = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
36
+ tf = txBox.text_frame
37
+ tf.word_wrap = True
38
+ for i, item in enumerate(items):
39
+ if i == 0:
40
+ p = tf.paragraphs[0]
41
+ else:
42
+ p = tf.add_paragraph()
43
+ p.text = item
44
+ p.font.size = Pt(font_size)
45
+ p.font.color.rgb = color
46
+ p.space_after = Pt(12)
47
+ p.level = 0
48
+ return txBox
49
+
50
+ # Слайд 1 — Титульный
51
+ slide = prs.slides.add_slide(prs.slide_layouts[6]) # Blank
52
+ set_slide_bg(slide, 0xFF, 0x8C, 0x00)
53
+ add_text_box(slide, 1, 1.5, 11, 2, "🐱 КОТЫ", font_size=72, bold=True, color=WHITE, alignment=PP_ALIGN.CENTER)
54
+ add_text_box(slide, 1, 3.5, 11, 1.5, "Лучшие друзья человека", font_size=36, color=WHITE, alignment=PP_ALIGN.CENTER)
55
+ add_text_box(slide, 1, 5.5, 11, 1, "🐾 🐾 🐾 🐾 🐾", font_size=36, color=WHITE, alignment=PP_ALIGN.CENTER)
56
+
57
+ # Слайд 2 — Интересные факты
58
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
59
+ set_slide_bg(slide, 0xFF, 0xF5, 0xE6)
60
+ add_text_box(slide, 0.5, 0.5, 12, 1.2, "🔍 Интересные факты о котах", font_size=40, bold=True, color=ORANGE, alignment=PP_ALIGN.CENTER)
61
+ facts = [
62
+ "😴 Коты проводят 70% своей жизни во сне",
63
+ "👃 У каждого кота уникальный рисунок носа — как отпечаток пальца",
64
+ "🔊 Коты могут издавать более 100 различных звуков",
65
+ "🏆 Самый старый кот прожил 38 лет",
66
+ "🏃 Коты бегают со скоростью до 48 км/ч",
67
+ "❤️ Коты мурлыкают на частоте 25-150 Гц — это помогает заживлению тканей",
68
+ ]
69
+ add_bullets(slide, 1.5, 2, 10, 5, facts, font_size=24, color=DARK)
70
+
71
+ # Слайд 3 — Популярные породы
72
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
73
+ set_slide_bg(slide, 0xFF, 0xF5, 0xE6)
74
+ add_text_box(slide, 0.5, 0.5, 12, 1.2, "🐈 Популярные породы", font_size=40, bold=True, color=ORANGE, alignment=PP_ALIGN.CENTER)
75
+ breeds = [
76
+ "🦁 Мейн-кун — гигант среди домашних котов (до 12 кг!)",
77
+ "👻 Сфинкс — бесшёрстная, но очень ласковая порода",
78
+ "🇬🇧 Британская короткошёрстная — классика жанра",
79
+ "🦄 Шотландская вислоухая — с милыми загнутыми ушами",
80
+ "🇹🇭 Сиамская — умная и голосистая порода",
81
+ "👑 Персидская — царственная красота и спокойный характер",
82
+ ]
83
+ add_bullets(slide, 1.5, 2, 10, 5, breeds, font_size=24, color=DARK)
84
+
85
+ # Слайд 4 — Польза для здоровья
86
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
87
+ set_slide_bg(slide, 0xFF, 0xF5, 0xE6)
88
+ add_text_box(slide, 0.5, 0.5, 12, 1.2, "💚 Польза котов для здоровья", font_size=40, bold=True, color=ORANGE, alignment=PP_ALIGN.CENTER)
89
+ health = [
90
+ "😌 Снижают уровень стресса и тревожности",
91
+ "🎵 Мурлыкание помогает заживлять кости и ткани",
92
+ "💊 Понижают давление и уровень холестерина",
93
+ "🫀 Уменьшают риск инфаркта на 40%",
94
+ "🤗 Помогают бороться с одиночеством",
95
+ "👶 Дети, растущие с котами, реже болеют аллергией",
96
+ ]
97
+ add_bullets(slide, 1.5, 2, 10, 5, health, font_size=24, color=DARK)
98
+
99
+ # Слайд 5 — Коты в культуре
100
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
101
+ set_slide_bg(slide, 0xFF, 0xF5, 0xE6)
102
+ add_text_box(slide, 0.5, 0.5, 12, 1.2, "🌍 Коты в культуре", font_size=40, bold=True, color=ORANGE, alignment=PP_ALIGN.CENTER)
103
+ culture = [
104
+ "🏛️ В Древнем Египте котов боготворили и мумифицировали",
105
+ "📱 Интернет-мемы сделали котов самыми популярными животными онлайн",
106
+ "🎨 Сальвадор Дали был известным любителем котов",
107
+ "🇯🇵 В Японии манэки-нэко (кот-привет) приносит удачу",
108
+ "🐈 Кот Боб — знаменитый рыжий уличный кот из Лондона",
109
+ "📚 Кошка Бегемот из «Мастера и Маргариты» — один из самых известных котов в литературе",
110
+ ]
111
+ add_bullets(slide, 1.5, 2, 10, 5, culture, font_size=24, color=DARK)
112
+
113
+ # Слайд 6 — Заключительный
114
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
115
+ set_slide_bg(slide, 0xFF, 0x8C, 0x00)
116
+ add_text_box(slide, 1, 2, 11, 2, "Спасибо за внимание!", font_size=60, bold=True, color=WHITE, alignment=PP_ALIGN.CENTER)
117
+ add_text_box(slide, 1, 4.2, 11, 1.5, "🐾 Возьмите кота — и ваша жизнь станет ярче! 🐾", font_size=28, color=WHITE, alignment=PP_ALIGN.CENTER)
118
+
119
+ output = r"C:\Users\user\Desktop\cats.pptx"
120
+ prs.save(output)
121
+ print(f"Презентация сохранена: {output}")
@@ -0,0 +1,16 @@
1
+ import { dirname } from "node:path"
2
+ import { fileURLToPath } from "node:url"
3
+ import { FlatCompat } from "@eslint/eslintrc"
4
+
5
+ const __filename = fileURLToPath(import.meta.url)
6
+ const __dirname = dirname(__filename)
7
+
8
+ const compat = new FlatCompat({
9
+ baseDirectory: __dirname,
10
+ })
11
+
12
+ const eslintConfig = [
13
+ ...compat.extends("next/core-web-vitals", "next/typescript"),
14
+ ]
15
+
16
+ export default eslintConfig
package/hello.py ADDED
@@ -0,0 +1,2 @@
1
+ print("Привет, мир!")
2
+ input("Нажмите Enter для закрытия...")
package/install.bat ADDED
@@ -0,0 +1,35 @@
1
+ @echo off
2
+ echo.
3
+ echo ✦ Stella Coder 3.9 — Установка
4
+ echo.
5
+
6
+ :: Check Node.js
7
+ where node >nul 2>nul
8
+ if %errorlevel% neq 0 (
9
+ echo ОШИБКА: Node.js не установлен
10
+ echo Скачайте: https://nodejs.org
11
+ pause
12
+ exit /b 1
13
+ )
14
+
15
+ :: Check npm
16
+ where npm >nul 2>nul
17
+ if %errorlevel% neq 0 (
18
+ echo ОШИБКА: npm не установлен
19
+ pause
20
+ exit /b 1
21
+ )
22
+
23
+ echo [1/3] Установка зависимостей...
24
+ call npm install
25
+
26
+ echo [2/3] Установка команд...
27
+ call npm link
28
+
29
+ echo [3/3] Проверка...
30
+ node stella-cli/index.mjs --version
31
+
32
+ echo.
33
+ echo ✓ Готово! Запуск: stella
34
+ echo.
35
+ pause
package/next-env.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ import "./.next/dev/types/routes.d.ts";
4
+
5
+ // NOTE: This file should not be edited
6
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -0,0 +1,11 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ typescript: {
4
+ ignoreBuildErrors: true,
5
+ },
6
+ images: {
7
+ unoptimized: true,
8
+ },
9
+ }
10
+
11
+ export default nextConfig
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "stella-coder",
3
+ "version": "3.9.0",
4
+ "private": false,
5
+ "description": "Stella Coder 3.9 — AI coding agent with computer control, smart home, Office automation, and antivirus",
6
+ "bin": {
7
+ "stella": "./stella-cli/index.mjs",
8
+ "stellar-av": "./antimalware/index.mjs"
9
+ },
10
+ "scripts": {
11
+ "stella": "node stella-cli/index.mjs",
12
+ "stellar-av": "node antimalware/index.mjs",
13
+ "dev": "next dev",
14
+ "build": "next build",
15
+ "build:cli": "node stella-cli/build.mjs",
16
+ "start": "next start",
17
+ "lint": "eslint .",
18
+ "publish": "node publish.mjs"
19
+ },
20
+ "keywords": ["ai", "coding", "agent", "terminal", "smart-home", "antivirus"],
21
+ "author": "codex alex",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@ai-sdk/openai": "^4.0.7",
25
+ "@ai-sdk/openai-compatible": "^3.0.5",
26
+ "@ai-sdk/react": "^4.0.16",
27
+ "@base-ui/react": "^1.5.0",
28
+ "@vercel/analytics": "1.6.1",
29
+ "ai": "^7.0.15",
30
+ "class-variance-authority": "^0.7.1",
31
+ "clsx": "^2.1.1",
32
+ "lucide-react": "^1.16.0",
33
+ "next": "16.2.6",
34
+ "react": "^19",
35
+ "react-dom": "^19",
36
+ "shadcn": "^4.8.0",
37
+ "tailwind-merge": "^3.3.1",
38
+ "tw-animate-css": "^1.4.0",
39
+ "zod": "^4.4.3"
40
+ },
41
+ "devDependencies": {
42
+ "@eslint/eslintrc": "^3.3.0",
43
+ "@tailwindcss/postcss": "^4.2.0",
44
+ "@types/node": "^24",
45
+ "@types/react": "^19",
46
+ "@types/react-dom": "^19",
47
+ "eslint": "^9.28.0",
48
+ "eslint-config-next": "^16.2.0",
49
+ "postcss": "^8.5",
50
+ "tailwindcss": "^4.2.0",
51
+ "typescript": "5.7.3"
52
+ },
53
+ "pnpm": {
54
+ "overrides": {
55
+ "hono": "4.12.25"
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,7 @@
1
+ allowBuilds:
2
+ sharp: true
3
+ unrs-resolver: true
4
+ minimumReleaseAgeExclude:
5
+ - '@ai-sdk/gateway@4.0.12'
6
+ - '@ai-sdk/react@4.0.16'
7
+ - ai@7.0.15
@@ -0,0 +1,8 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ '@tailwindcss/postcss': {},
5
+ },
6
+ }
7
+
8
+ export default config
package/publish.mjs ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ // Stella Coder — Publish to npm
3
+ import { execSync } from "node:child_process"
4
+ import fs from "node:fs"
5
+ import path from "node:path"
6
+
7
+ console.log("\n ✦ Stella Coder — Publish to npm\n")
8
+
9
+ // Check if logged in
10
+ try {
11
+ execSync("npm whoami", { stdio: "pipe" })
12
+ } catch {
13
+ console.log(" Вы не авторизованы в npm.")
14
+ console.log(" Выполните: npm login\n")
15
+ process.exit(1)
16
+ }
17
+
18
+ // Get version from package.json
19
+ const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"))
20
+ console.log(` Версия: ${pkg.version}`)
21
+ console.log(` Имя: ${pkg.name}\n`)
22
+
23
+ // Build
24
+ console.log(" [1/3] Сборка...")
25
+ try {
26
+ execSync("npm run build:cli", { stdio: "inherit" })
27
+ } catch {
28
+ console.log(" ⚠ Ошибка сборки, продолжаем...\n")
29
+ }
30
+
31
+ // Publish
32
+ console.log(" [2/3] Публикация...")
33
+ try {
34
+ execSync("npm publish --access public", { stdio: "inherit" })
35
+ console.log("\n ✓ Опубликовано!\n")
36
+ } catch (e) {
37
+ console.error("\n ✗ Ошибка публикации:", e.message)
38
+ process.exit(1)
39
+ }
40
+
41
+ // Tag
42
+ console.log(" [3/3] Создание тега...")
43
+ try {
44
+ execSync(`git tag -a v${pkg.version} -m "Release v${pkg.version}"`, { stdio: "inherit" })
45
+ execSync(`git push origin v${pkg.version}`, { stdio: "inherit" })
46
+ console.log(` ✓ Тег v${pkg.version} создан\n`)
47
+ } catch {
48
+ console.log(" ⚠ Тег не создан (нужен git репозиторий)\n")
49
+ }
50
+
51
+ console.log(" Установка для пользователей:")
52
+ console.log(` npm install -g ${pkg.name}\n`)
@@ -0,0 +1,46 @@
1
+ import { gradient, dim, violet, blue, gray, box, bold, purple } from "./theme.mjs"
2
+
3
+ const LOGO = String.raw`
4
+ ███████╗████████╗███████╗██╗ ██╗ █████╗
5
+ ██╔════╝╚══██╔══╝██╔════╝██║ ██║ ██╔══██╗
6
+ ███████╗ ██║ █████╗ ██║ ██║ ███████║
7
+ ╚════██║ ██║ ██╔══╝ ██║ ██║ ██╔══██║
8
+ ███████║ ██║ ███████╗███████╗███████╗██║ ██║
9
+ ╚══════╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝
10
+ ██████╗ ██████╗ ██████╗ ███████╗██████╗
11
+ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗
12
+ ██║ ██║ ██║██║ ██║█████╗ ██████╔╝
13
+ ██║ ██║ ██║██║ ██║██╔══╝ ██╔══██╗
14
+ ╚██████╗╚██████╔╝██████╔╝███████╗██║ ██║
15
+ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝`
16
+
17
+ export function printBanner({ model, cwd, version }) {
18
+ console.log(gradient(LOGO))
19
+ console.log()
20
+ console.log(
21
+ " " +
22
+ gradient("✦ Stella Coder") +
23
+ " " +
24
+ bold(violet(`v${version}`)) +
25
+ dim(" · powered by ") +
26
+ bold(blue("codex")) +
27
+ dim(" alex"),
28
+ )
29
+ console.log()
30
+ console.log(
31
+ box(
32
+ [
33
+ violet("✻") + " Добро пожаловать в " + bold(violet("Stella Coder 3.9")) + "!",
34
+ "",
35
+ dim(" модель: ") + blue(model),
36
+ dim(" папка: ") + gray(cwd),
37
+ "",
38
+ dim(" ") + purple("/help") + dim(" — все команды ") + purple("/model") + dim(" — сменить модель"),
39
+ dim(" ") + purple("!cmd") + dim(" — запустить shell-команду напрямую"),
40
+ dim(" ") + purple("Ctrl+C") + dim(" — прервать ответ, дважды — выход"),
41
+ ],
42
+ { title: "✦ System", padding: 2 },
43
+ ),
44
+ )
45
+ console.log()
46
+ }
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+ // Stella Coder — Build Script (SEA: Single Executable Application)
3
+ import fs from "node:fs"
4
+ import path from "node:path"
5
+ import { execSync } from "node:child_process"
6
+ import { fileURLToPath } from "node:url"
7
+
8
+ const __filename = fileURLToPath(import.meta.url)
9
+ const __dirname = path.dirname(__filename)
10
+
11
+ const DIST = path.join(__dirname, "..", "dist")
12
+ const SEA_BLOB = path.join(DIST, "sea-prep.blob")
13
+ const EXE_NAME = process.platform === "win32" ? "stella.exe" : "stella"
14
+ const OUTPUT = path.join(DIST, EXE_NAME)
15
+
16
+ console.log()
17
+ console.log("\x1b[38;2;167;139;250m ✦ Stella Coder — Build SEA Executable\x1b[0m")
18
+ console.log()
19
+
20
+ // 1. Clean dist
21
+ console.log(" [1/5] Очистка dist/...")
22
+ if (fs.existsSync(DIST)) fs.rmSync(DIST, { recursive: true })
23
+ fs.mkdirSync(DIST, { recursive: true })
24
+
25
+ // 2. Create single entry point that bundles all modules
26
+ console.log(" [2/5] Создание bundled entry point...")
27
+
28
+ const entryContent = `#!/usr/bin/env node
29
+ // Stella Coder — Bundled Single Executable
30
+ // This file bundles all CLI modules into one for SEA compilation
31
+
32
+ import { createRequire } from "node:module"
33
+ const require = createRequire(import.meta.url)
34
+
35
+ // Inline all modules
36
+ ${inlineModule("stella-cli/theme.mjs")}
37
+ ${inlineModule("stella-cli/banner.mjs")}
38
+ ${inlineModule("stella-cli/markdown.mjs")}
39
+ ${inlineModule("stella-cli/tools.mjs")}
40
+ ${inlineModule("stella-cli/security.mjs")}
41
+
42
+ // Re-export for index.mjs
43
+ export {
44
+ bold, dim, violet, purple, indigo, blue, cyan, green, red, yellow, gray, darkGray, white,
45
+ gradientLine, box, SPINNER_FRAMES, SPINNER_WORDS,
46
+ } from "./theme.mjs"
47
+
48
+ export { printBanner } from "./banner.mjs"
49
+ export { createStreamRenderer, renderMarkdown } from "./markdown.mjs"
50
+ export { createTools } from "./tools.mjs"
51
+ export {
52
+ verifyCodeIntegrity, getApiKey, saveApiKey, deleteApiKey,
53
+ getHardwareInfo, saveIntegrityHash,
54
+ } from "./security.mjs"
55
+ `
56
+
57
+ // Actually, for SEA we need a simpler approach — just copy all files to dist
58
+ console.log(" [2/5] Копирование модулей в dist/...")
59
+
60
+ const filesToCopy = [
61
+ "index.mjs",
62
+ "tools.mjs",
63
+ "banner.mjs",
64
+ "theme.mjs",
65
+ "markdown.mjs",
66
+ "security.mjs",
67
+ ]
68
+
69
+ for (const file of filesToCopy) {
70
+ const src = path.join(__dirname, file)
71
+ const dst = path.join(DIST, file)
72
+ if (fs.existsSync(src)) {
73
+ fs.copyFileSync(src, dst)
74
+ console.log(` ${file}`)
75
+ }
76
+ }
77
+
78
+ // Also copy antimalware directory
79
+ const antimalwareSrc = path.join(__dirname, "..", "antimalware")
80
+ const antimalwareDst = path.join(DIST, "antimalware")
81
+ if (fs.existsSync(antimalwareSrc)) {
82
+ fs.cpSync(antimalwareSrc, antimalwareDst, { recursive: true })
83
+ console.log(" antimalware/")
84
+ }
85
+
86
+ // 3. Create SEA blob
87
+ console.log(" [3/5] Создание SEA blob...")
88
+ const seaConfig = {
89
+ main: "index.mjs",
90
+ disableExperimentalSEAWarning: true,
91
+ }
92
+ fs.writeFileSync(path.join(DIST, "sea-config.json"), JSON.stringify(seaConfig, null, 2))
93
+
94
+ try {
95
+ execSync(`node --experimental-sea-config ${path.join(DIST, "sea-config.json")}`, {
96
+ cwd: DIST,
97
+ stdio: "inherit",
98
+ })
99
+ } catch (e) {
100
+ console.log(" ⚠ SEA config не поддерживается этой версией Node.js")
101
+ console.log(" Используйте Node.js 20+ или pkg для компиляции")
102
+ console.log()
103
+ console.log(" Альтернатива: npm install -g pkg && pkg --targets node18-win-x64 .")
104
+ console.log()
105
+ process.exit(0)
106
+ }
107
+
108
+ // 4. Copy node executable
109
+ console.log(" [4/5] Копирование Node.js executable...")
110
+ const nodeExe = process.execPath
111
+ const targetExe = path.join(DIST, EXE_NAME)
112
+ fs.copyFileSync(nodeExe, targetExe)
113
+
114
+ // 5. Inject SEA blob into executable
115
+ console.log(" [5/5] Инжектирование blob в executable...")
116
+ try {
117
+ const { execSync: exec } = await import("node:child_process")
118
+ if (process.platform === "win32") {
119
+ exec(`npx postject ${targetExe} NODE_SEA_BLOB ${SEA_BLOB} --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`, {
120
+ cwd: DIST,
121
+ stdio: "inherit",
122
+ })
123
+ } else {
124
+ exec(`npx postject ${targetExe} NODE_SEA_BLOB ${SEA_BLOB} --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`, {
125
+ cwd: DIST,
126
+ stdio: "inherit",
127
+ })
128
+ }
129
+ } catch (e) {
130
+ console.log(" ⚠ Postject не удался. Попробуйте:")
131
+ console.log(" npm install -g postject")
132
+ console.log(" postject stella.exe NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2")
133
+ }
134
+
135
+ // Cleanup
136
+ try { fs.unlinkSync(path.join(DIST, "sea-prep.blob")) } catch {}
137
+ try { fs.unlinkSync(path.join(DIST, "sea-config.json")) } catch {}
138
+
139
+ console.log()
140
+ console.log(`\x1b[38;2;0;200;100m ✓ Готово: ${OUTPUT}\x1b[0m`)
141
+ console.log(dim(` Размер: ${(fs.statSync(targetExe).size / 1024 / 1024).toFixed(1)} MB`))
142
+ console.log()
143
+
144
+ function inlineModule(relativePath) {
145
+ const fullPath = path.join(__dirname, "..", relativePath)
146
+ try {
147
+ return fs.readFileSync(fullPath, "utf8")
148
+ } catch {
149
+ return `// ${relativePath} not found`
150
+ }
151
+ }