[2026-06-25] eagle: personal/projects/personal-os/eagle-dashboard.md
This commit is contained in:
@@ -162,7 +162,9 @@ PID-file-based — survives Dashboard restarts without crashing.
|
||||
- ⏸/▶ — pause/resume (toggle enabled)
|
||||
- 🗑 — удалить крон
|
||||
|
||||
|**Launchd create** — `POST /api/crons` с `source=launchd` генерирует plist. Принимает: `name` (→ Label, префикс `com.` если не указан), `schedule` (только `every Ns/m/h/d` → StartInterval в секундах), `script` (→ ProgramArguments, разбивка по пробелам), `workdir` (→ WorkingDirectory). Cron-выражения и ISO-даты для launchd **не поддерживаются** — валидатор на фронтенде их отклоняет с сообщением "Launchd: используйте every 30m / every 2h / every 1d". Поля prompt, deliver, skills, toolsets, model, provider игнорируются. Backend парсит `every N` + суффикс s/m/h/d → множитель 1/60/3600/86400.
|
||||
||**Launchd create** — `POST /api/crons` с `source=launchd` генерирует plist. Принимает: `name` (→ Label, префикс `com.` если не указан), `schedule` (только `every Ns/m/h/d` → StartInterval в секундах), `script` (→ ProgramArguments, разбивка по пробелам), `workdir` (→ WorkingDirectory), `run_at_load` (→ RunAtLoad, boolean, default false). Cron-выражения и ISO-даты для launchd **не поддерживаются** — валидатор на фронтенде их отклоняет с сообщением "Launchd: используйте every 30m / every 2h / every 1d". Поля prompt, deliver, skills, toolsets, model, provider игнорируются. Backend парсит `every N` + суффикс s/m/h/d → множитель 1/60/3600/86400.
|
||||
|
||||
**RunAtLoad** — чекбокс \"Run on load\" в модалке создания/редактирования launchd крона. Сквозь `x-show="cronModal.source === 'launchd'"` показывается только для launchd. Описание: \"запускать при логине / загрузке системы\". При открытии редактирования — читается из `c.run_at_load` (backend отдаёт `plist.get("RunAtLoad", False)`). Сохраняется как `body.run_at_load → pd["RunAtLoad"]`. По умолчанию `false`.
|
||||
|
||||
**`_list_launchd_crons()`** теперь показывает **все** plist-ы из `~/Library/LaunchAgents/`, не только с StartInterval/StartCalendarInterval. Для plist без schedule — `schedule: "none (manual)"`. Это фикс: раньше plist без schedule (например созданный с cron-выражением) не отображался в дашборде.
|
||||
|
||||
@@ -280,7 +282,7 @@ When a launchd cron is created and `launchctl print gui/<uid>/<label>` shows `la
|
||||
|
||||
## History
|
||||
|
||||
- 2026-06-25 (round 8): **Multiple bugfixes.** `_msg` timer fix — stale object reference replaced with `find` in fresh array (both cron toggle and service action). `_list_launchd_crons()` enabled fix — removed `and pid is not None` (timer-based launchd jobs always had `enabled: false`). `openAddCron()` — source-dependent default schedule (`every 30m` for launchd, `*/30 * * * *` for Hermes), `scheduleErr` init via `validateSchedule()`. `@change` on source selector replaces default if switching hermes→launchd. Backend create for launchd: only `every Ns/m/h/d` parsed (cron-parser removed). `_list_launchd_crons()` now shows ALL plists.
|
||||
|- 2026-06-25 (round 9): **RunAtLoad checkbox for launchd crons.** Added `RunAtLoad` field to launchd plist creation. Backend: `main.py` line 636 changed from `pd["RunAtLoad"] = False` to `pd["RunAtLoad"] = body.get("run_at_load", False)`. Frontend: checkbox "Run on load" in cron modal, shown only for source=launchd via `x-show`; `openAddCron()`, `openCronEdit()`, `saveCronModal()` all wired. Backend `_list_launchd_crons()` returns `run_at_load` for edit modal. **Also fixed:** `_msg` auto-dismiss bug — stale object reference after `fetchCrons()` replaced with `find` in fresh array (both crons and services).
|
||||
- 2026-06-25 (round 7): **Launchd schedule — source-dependent validation.** `validateSchedule()` now takes `source` param. For `launchd`: only `every Ns/m/h/d` accepted; cron and ISO rejected with explicit message. For Eagle/Whale: all three formats. Hints, placeholders, and `prettySchedule()` also differ by source. `Query` import added to FastAPI.
|
||||
- 2026-06-25 (round 6): **Tab URL routing.** Each tab now persists in URL via `?tab=` query-param + `history.replaceState()`. Frontend initializes `activeTab` from URL. Backend accepts `?tab=` on `GET /`. Added `setUrlTab()` to Alpine.js data.
|
||||
- 2026-06-25 (round 4): **Schedule hint final format applied.** Multiline cron reference (no `#` prefix), field labels (m/h/d/m/w), value notation (`*/N`, `N-M`, `A,B`, `N`), human format (`every 30s / 30m / 2h / 1d`), ISO date. Collapsible via `? подсказка` button. ISO line hidden for launchd. Validator also blocks Save on invalid input.
|
||||
|
||||
Reference in New Issue
Block a user