Манифест — pulsar.json
Один файл управляет конфигурацией приложения и упаковкой.
{
"id": "com.example.myapp",
"name": "my-app",
"version": "1.0.0",
"main": "main.ts",
"icons": { "linux": "assets/icon.png", "macos": "assets/icon.icns", "windows": "assets/icon.ico" },
"windows": [
{
"label": "main",
"ui": "ui/main.qml",
"width": 800,
"height": 600,
"title": "My App",
"minWidth": 400,
"minHeight": 300,
"resizable": true,
"frameless": false,
"transparent": false,
"icon": "assets/icon.png"
}
],
"permissions": [],
"osPermissions": ["camera", "microphone"],
"fileAssociations": [{ "ext": "md", "mime": "text/markdown", "name": "Markdown document" }],
"protocols": [{ "scheme": "myapp" }],
"singleInstance": true
}
| Поле | Значение |
|---|---|
id |
Reverse-DNS идентификатор; используется для каталогов data/config/cache приложения. |
name |
Отображаемое имя/имя вывода (оно же имя файла dist/<name>). |
version |
Версия приложения. |
main |
Точка входа бэкенда относительно манифеста (по умолчанию main.ts). |
icons |
Пути к иконкам по платформам (используются упаковкой). |
windows[] |
Стартовые окна: label, ui, width, height, title, minWidth, minHeight, maxWidth, maxHeight, resizable, frameless, transparent, icon. |
permissions |
Возможности, доступные приложению (см. Разрешения). Нет поля — все. |
osPermissions |
Runtime-разрешения ОС, которые попадут в манифест Android: camera, microphone, location, notifications, storage. |
protocols |
Свои URL-схемы (deep links), которые обрабатывает приложение. |
fileAssociations |
Типы файлов, которые открывает приложение: ext (без точки), mime, name. |
singleInstance |
Передавать второй запуск работающему экземпляру и выходить (по умолчанию false). |
ignore |
Дополнительные пути, не попадающие в сборку, в синтаксисе .gitignore. |
Прозрачное окно и Hyprland
"transparent": true у окна делает фон прозрачным, включает frameless и рисует
скруглённую матовую подложку. Само размытие делает композитор; для Hyprland:
windowrulev2 = opacity 0.94 0.88,class:^(pulsar-host)$
windowrulev2 = blur,class:^(pulsar-host)$
windowrulev2 = rounding 18,class:^(pulsar-host)$
Класс окна проверяется через hyprctl clients. Без blur прозрачность тоже
работает, но матовый эффект слабее.
Сборка всегда пропускает .git, node_modules, dist, build, .cache,
.pulsar, .env* и sync.db*, а также учитывает корневой .gitignore
приложения. ignore добавляет шаблоны сверх этого; строка с ! возвращает
путь, исключённый через .gitignore, но не встроенные исключения.
App берёт конфиг из первого окна манифеста; явные параметры, переданные в
new App({...}), переопределяют манифест.
Нативное меню
app.setMenu([
{
label: "Файл",
items: [
{ id: "new", label: "Новая задача", shortcut: "CmdOrCtrl+N" },
{ separator: true },
{ id: "hide", label: "Скрыть выполненные", checked: app.store.get("hideDone") === true },
],
},
])
app.on("menu", ({ id }) => {
if (id === "new") app.store.set("composing", true)
})
Меню строится нативно в глобальной строке меню macOS; Linux и Windows его пока
игнорируют. Повторный setMenu обновляет отметки checked. Пункт с items
становится подменю; выбор листа присылает событие menu с его id.
Разрешения
permissions объявляет возможности ОС, которые доступны приложению. Если поля
нет — разрешено всё; если оно есть — только перечисленное, а любой
другой вызов возможности завершается ошибкой permission denied.
{ "permissions": ["fs", "net", "dialog"] }
| Разрешение | Что даёт |
|---|---|
fs |
чтение/запись файлов, stat, rename, корзина |
net |
net.fetch, net.request, net.websocket |
paths |
стандартные каталоги приложения |
shell |
открытие URL в приложении по умолчанию |
notify |
системные уведомления |
dialog |
системные файловые/сообщающие диалоги |
screen |
список мониторов |
theme |
системная цветовая схема |
system |
локаль/язык/часовой пояс |
storage |
JSON-файл хранилища приложения |
secure |
системный keychain / хранилище секретов |
tray |
иконка и меню трея |
clipboard |
системный буфер обмена (чтение/запись) |
share |
системный share sheet |
device |
блокировка ориентации и keep-awake |
permissions |
запросы runtime-разрешений ОС |
media |
воспроизведение медиа через хост |
Управление окнами — ядро и не ограничивается. Пользовательские возможности, зарегистрированные приложением, тоже не ограничиваются.
Запросы runtime-разрешений ОС не связаны с capabilities. Перечислите, что
приложение может запрашивать, в osPermissions, и запрашивайте в рантайме:
import { permissions } from "pulsar"
if (await permissions.request("camera")) startScanner()
const granted = await permissions.check("microphone")
Имена: camera, microphone, location, notifications, storage. На
Android они попадают в манифест, а request показывает системный диалог; на
десктопе оба вызова резолвятся в true.