mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:41:09 +02:00
docs: add Mana Bundle Format plan
Cross-app data bundle format (.mana / .manapkg) for onboarding flows, templates, and sequential content release. Implementation deferred. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f79ad1773a
commit
5871283d60
1 changed files with 240 additions and 0 deletions
240
.claude/plans/mana-bundle-format.md
Normal file
240
.claude/plans/mana-bundle-format.md
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
# Mana Bundle Format
|
||||
|
||||
**Status:** Planned (not started)
|
||||
**Priority:** Low — implement after local-first migration is complete
|
||||
**Scope:** New `@manacore/bundle` package + ManaCore import UI + optional `.manapkg` tooling
|
||||
|
||||
---
|
||||
|
||||
## Vision
|
||||
|
||||
A portable, shareable file format (`.mana` / `.manapkg`) that can be opened in ManaCore and:
|
||||
|
||||
- Creates data across multiple apps (Todo, Calendar, Contacts, Storage, ...)
|
||||
- Configures dashboard layouts
|
||||
- Optionally releases content sequentially (day-by-day courses, onboarding flows)
|
||||
|
||||
Primary use cases:
|
||||
|
||||
- Onboarding courses (e.g. GTD setup, productivity starter kit)
|
||||
- Cross-app templates shared between users
|
||||
- App-internal onboarding when a user first activates an app
|
||||
- Future: third-party ecosystem (coaches, companies publishing setups)
|
||||
|
||||
---
|
||||
|
||||
## File Format
|
||||
|
||||
### Simple: `.mana` (JSON)
|
||||
|
||||
For small bundles without binary assets.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"type": "blueprint",
|
||||
"meta": {
|
||||
"name": "GTD Onboarding",
|
||||
"description": "Startet dich mit Todo, Kalender & Kontakten",
|
||||
"author": "mana.how",
|
||||
"createdAt": "2026-03-31"
|
||||
},
|
||||
"variables": {
|
||||
"userName": { "type": "string", "prompt": "Wie heißt du?" },
|
||||
"startDate": { "type": "date", "default": "today" }
|
||||
},
|
||||
"steps": [ ... ],
|
||||
"dashboard": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
### Rich: `.manapkg` (ZIP archive)
|
||||
|
||||
For bundles with images, PDFs, audio files.
|
||||
|
||||
```
|
||||
onboarding.manapkg
|
||||
├── manifest.json # name, version, author, asset index
|
||||
├── blueprint.json # full step/data definition
|
||||
└── assets/
|
||||
├── avatar.png
|
||||
├── cheatsheet.pdf
|
||||
└── day1-banner.jpg
|
||||
```
|
||||
|
||||
Assets referenced in blueprint as `asset://avatar.png` → resolved to MinIO URLs on import.
|
||||
|
||||
---
|
||||
|
||||
## Data Model
|
||||
|
||||
### Step Structure
|
||||
|
||||
Each step defines what data to create and when to release it:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "day-1",
|
||||
"label": "Tag 1: Grundlagen",
|
||||
"releaseOn": "import",
|
||||
"data": {
|
||||
"todo": {
|
||||
"projects": [{ "id": "onboarding", "name": "Onboarding" }],
|
||||
"tasks": [{ "title": "App-Tour abschließen", "projectId": "onboarding", "dueDate": "+0d" }]
|
||||
},
|
||||
"calendar": {
|
||||
"events": [{ "title": "Kick-off", "startDate": "+0d" }]
|
||||
},
|
||||
"contacts": {
|
||||
"contacts": [
|
||||
{ "name": "Mana Support", "email": "hi@mana.how", "photoAsset": "asset://avatar.png" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Release Triggers
|
||||
|
||||
Three modes, combinable via `any` / `all`:
|
||||
|
||||
```json
|
||||
// Time-based (relative to importDate)
|
||||
"releaseOn": { "trigger": "time", "after": "+1d" }
|
||||
|
||||
// Completion-based (task done, event attended, etc.)
|
||||
"releaseOn": { "trigger": "task:completed", "taskId": "$day-1.todo.tasks[0].id" }
|
||||
|
||||
// Combination (whichever comes first)
|
||||
"releaseOn": {
|
||||
"any": [
|
||||
{ "trigger": "time", "after": "+1d" },
|
||||
{ "trigger": "step-completed", "stepId": "day-1" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Supported trigger types (initial set):
|
||||
|
||||
- `"import"` — immediately on bundle import
|
||||
- `"time"` + `after: "+Nd"` — N days after import
|
||||
- `"step-completed"` + `stepId` — after another step's data has been applied
|
||||
- `"task:completed"` + `taskId` — when a specific task is checked off
|
||||
|
||||
### Dashboard Configuration
|
||||
|
||||
```json
|
||||
"dashboard": {
|
||||
"layout": [
|
||||
{ "type": "tasks-today", "size": "medium", "position": { "x": 0, "y": 0 } },
|
||||
{ "type": "calendar-upcoming", "size": "medium", "position": { "x": 4, "y": 0 } },
|
||||
{ "type": "bundle-progress", "size": "small", "position": { "x": 8, "y": 0 } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Binary / Asset Handling
|
||||
|
||||
| Asset size | Strategy |
|
||||
| --------------- | -------------------------------------------------- |
|
||||
| Small (< 50 KB) | Base64 inline in blueprint.json |
|
||||
| Medium / Large | `.manapkg` ZIP with `assets/` folder |
|
||||
| Hosted assets | External URL (`https://...`), downloaded on import |
|
||||
|
||||
On import: assets are uploaded to MinIO → URL stored in record. Bundle stays self-contained if `.manapkg`.
|
||||
|
||||
---
|
||||
|
||||
## ManaCore State: `bundles` Collection
|
||||
|
||||
A new collection in the ManaCore local-store tracks installed bundles and their progress:
|
||||
|
||||
```typescript
|
||||
interface BundleRecord {
|
||||
id: string;
|
||||
name: string;
|
||||
importedAt: string; // ISO date
|
||||
anchor: string; // = importedAt, base for relative dates
|
||||
status: 'active' | 'completed' | 'paused';
|
||||
appliedSteps: string[]; // step IDs already applied
|
||||
pendingSteps: PendingStep[];
|
||||
}
|
||||
|
||||
interface PendingStep {
|
||||
stepId: string;
|
||||
label: string;
|
||||
releaseAt?: string; // resolved ISO datetime (for time-triggers)
|
||||
trigger?: object; // original trigger definition (for reactive triggers)
|
||||
applied: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Core Format + Import (MVP)
|
||||
|
||||
1. **`packages/bundle/`** — new package `@manacore/bundle`
|
||||
- `schema.ts` — TypeScript types for `.mana` format (Blueprint, Step, Trigger, DashboardConfig)
|
||||
- `parser.ts` — parse & validate `.mana` JSON or `.manapkg` ZIP
|
||||
- `resolver.ts` — resolve variables, relative dates (`+Nd`), asset references
|
||||
- `importer.ts` — write data into app collections via cross-app-stores write API
|
||||
|
||||
2. **ManaCore: `bundles` collection** — add to `manacore-store.ts`
|
||||
|
||||
3. **ManaCore: Import UI**
|
||||
- Drag & drop or file picker on dashboard or settings page
|
||||
- Variable prompt dialog (if `variables` defined)
|
||||
- Preview: shows what will be created across which apps
|
||||
- Confirmation → apply step `releaseOn: "import"` immediately
|
||||
|
||||
4. **ManaCore: `bundle-progress` Dashboard Widget**
|
||||
- Shows bundle name, progress bar, current/next step label
|
||||
- Lists completed ✅ / active ▶ / locked 🔒 steps
|
||||
|
||||
### Phase 2: Sequential Release
|
||||
|
||||
5. **Bundle Runner** — background check on app start
|
||||
- Query `bundles` collection for `status: 'active'`
|
||||
- For each pending step: check if `releaseAt <= now` → apply & mark applied
|
||||
- Uses existing `cross-app-stores` write path
|
||||
|
||||
6. **Reactive Triggers** (task:completed, step-completed)
|
||||
- Subscribe via `liveQuery` on relevant collections
|
||||
- Trigger condition check → apply next step
|
||||
|
||||
### Phase 3: Asset Support
|
||||
|
||||
7. **`.manapkg` ZIP parsing** — use a lightweight JS ZIP lib (e.g. `fflate`)
|
||||
8. **Asset upload to MinIO** on import via `@manacore/shared-storage`
|
||||
9. **External URL download** with offline fallback (queue for later)
|
||||
|
||||
### Phase 4: Tooling (optional, later)
|
||||
|
||||
10. **Bundle authoring CLI** — `mana-bundle create`, `mana-bundle validate`, `mana-bundle pack`
|
||||
11. **`manacore://` deep link + QR** — open bundle from URL, encode small bundles in QR
|
||||
|
||||
---
|
||||
|
||||
## Key Files (when implementing)
|
||||
|
||||
| File | Purpose |
|
||||
| ------------------------------------------------------------------------- | ------------------------------- |
|
||||
| `packages/bundle/src/schema.ts` | TypeScript types for the format |
|
||||
| `packages/bundle/src/importer.ts` | Write data into app collections |
|
||||
| `apps/manacore/apps/web/src/lib/data/manacore-store.ts` | Add `bundles` collection |
|
||||
| `apps/manacore/apps/web/src/lib/data/cross-app-stores.ts` | Extend write API if needed |
|
||||
| `apps/manacore/apps/web/src/routes/(app)/+page.svelte` | Import UI entry point |
|
||||
| `apps/manacore/apps/web/src/lib/components/widgets/BundleProgress.svelte` | Dashboard widget |
|
||||
|
||||
---
|
||||
|
||||
## Open Questions (resolve when starting)
|
||||
|
||||
- Should bundles be synced via mana-sync so they appear on all devices? (probably yes)
|
||||
- Max asset size limit for `.manapkg`?
|
||||
- Should there be a way to "uninstall" a bundle (delete created data)?
|
||||
- Do we need bundle signing/trust for third-party bundles?
|
||||
Loading…
Add table
Add a link
Reference in a new issue