CodeNomad/packages/ui/package.json
Pascal André a5efdefc8d
feat(missions): resume recurring Missions after OpenCode restarts with native schedules (#1259)
Closes #926.

## What changes

Recurring Missions now survive OpenCode restarts (update, crash and
relaunch, reboot) without a manual **Resume**, and the scheduler offers
more than "once a day at a fixed time".

- **Native schedules.** OpenCode's own scheduler
(`experimental.schedules`, OpenCode 2.2.3+) owns the calendar; Missions
decides whether a passage may run (CAS admission, no duplicates,
Pause/Stop, errors and uncertain states stay manual). A dedicated
technical conversation with a local no-op model carries the wake, so
wakes, titles and compaction make no provider HTTP requests.
- **Richer scheduling**, in one collapsed **Scheduling** section of the
Create/Edit editor (default: once, immediately, no condition): date,
delay, interval (≥15 min), daily, chosen weekdays, up to eight times a
day, day of month, native cron; optional end date/duration and a maximum
number of launched passages; five event conditions (another schedule
succeeds, a one-time Mission completes, new local commits, a new message
in a followed conversation, explicit files change). Up to five upcoming
dates are previewed in the saved IANA zone.
- **Created paused, started with Play.** Everything is editable before
the first launch; after it, edits follow the approved matrix (future
parameters between passages, objective/notes journaled during a
passage).
- **Keep OpenCode running.** A Preferences setting supervises the shared
OpenCode service through the OS (Windows Task Scheduler with a periodic
recovery task, macOS LaunchAgent, Linux systemd user unit with
lingering, WSL from Windows). ON by default at the first Play unless OFF
was saved; OFF removes supervision without stopping OpenCode; a live
service is never killed or duplicated.
- **Existing daily schedules** keep their path and controls; no
migration.
- Help (English and nine translations) and dev-docs are updated.

## Validation

- Typechecks (4 workspaces); server Missions/host-lifetime suites; UI
unit tests 1945/1945; help 31/31 and build.
- Real isolated OpenCode services (2.2.5, minimum 2.2.3): resting
schedule resumes after service restart with no client and no Resume; 32
real passages with history/quota/phase preserved; concurrent wakes admit
once; DST and catch-up for every frequency type; forced local
auto-compaction and restart during maintenance with zero provider HTTP;
real upgrade 2.2.3 → 2.2.5.
- OS supervision on Windows, WSL, Ubuntu VM (two real reboots, healthy
before login; OFF without a session) and macOS VM (Aqua session,
crashes, OFF/adoption). On the final bundle: two real periodic Windows
recovery relaunches; WSL OFF/Retry on a live HTTP 500 service keeps the
same process.
- Windows Electron and Tauri packages run in private profiles: paused
creation, nine frequencies, preview.
- Full browser suite: 956/957 in the last tier; the failure is
`directory-browser.test.ts` (folder picker timeout), unchanged by this
branch, and that file passes 20/20 on rerun. Earlier dev-baseline runs
on the same machine also lost module loads to
`net::ERR_NO_BUFFER_SPACE`.

## Known limits (not qualified in this PR)

- macOS reboot followed by a real login, and a Windows host reboot/logon
(needs a disposable bench).
- Real screen-reader output (keyboard, ARIA and RTL checks pass).
- Linux/macOS desktop packages.
- OpenCode's background *pre*-compaction never applies to the technical
wake conversations: their local model reports zero tokens, below the
native minimum. Their automatic local compaction is qualified.

## Follow-up

Integration with native `/goal` comes in a separate PR.
2026-11-01 14:40:24 +01:00

56 lines
1.7 KiB
JSON

{
"name": "@codenomad/ui",
"version": "1.0.1",
"private": true,
"license": "MIT",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"test:browser": "node tests/browser/run.mjs",
"qualify:browser:native-mission-replay": "node --import tsx --test --test-concurrency=1 tests/browser/native-mission-integration.qualification.ts",
"qualify:browser:timeline-sync": "node --import tsx tests/browser/timeline-sync.qualification.ts",
"typecheck": "tsc --noEmit -p tsconfig.json"
},
"dependencies": {
"@git-diff-view/solid": "^0.0.8",
"@kobalte/core": "0.13.11",
"@noble/hashes": "2.4.0",
"@opencode/client": "2.2.3",
"@solidjs/router": "^0.13.0",
"@suid/material": "^0.19.0",
"@suid/system": "^0.14.0",
"@tauri-apps/api": "^2.10.1",
"@tauri-apps/plugin-dialog": "^2.6.0",
"@tauri-apps/plugin-notification": "^2.3.3",
"@thisbeyond/solid-dnd": "^0.7.5",
"ansi-sequence-parser": "^1.1.3",
"debug": "^4.4.3",
"github-markdown-css": "^5.8.1",
"katex": "^0.16.45",
"lucide-solid": "^0.300.0",
"marked": "^12.0.0",
"marked-katex-extension": "^5.1.8",
"monaco-editor": "^0.52.2",
"qrcode": "^1.5.3",
"react": "19.2.0",
"shiki": "^3.13.0",
"solid-js": "^1.8.0",
"solid-toast": "^0.5.0",
"virtua": "^0.53.5",
"yaml": "^2.4.2"
},
"devDependencies": {
"@types/debug": "^4.1.13",
"@vite-pwa/assets-generator": "^1.0.2",
"autoprefixer": "10.4.21",
"playwright": "1.63.0",
"postcss": "8.5.6",
"tailwindcss": "3",
"typescript": "^5.3.0",
"vite": "^5.0.0",
"vite-plugin-pwa": "^1.2.0",
"vite-plugin-solid": "^2.10.0"
}
}