Dokumentationen / Paket
@startsidan/module-sdk
PaketStartsideportalenKontraktet mellan skalet och modulerna, plus urvalsfunktionerna skalet använder för att komponera dem.
källa: packages/module-sdk/srcuppdaterad: 2026-10-07
Ansvar
- Definiera ModuleManifest, UserContext och de typer modulerna fyller.
- Göra urvalet: filtrera på roll, sortera på order, aggregera actions.
- Äga den samlade uppgiftslistan: uppgifterFor läser alla modulers uppgifter, öppna och hanterade, med källan ifylld – vid varje anrop, utan lager.
- Låta aggregerande moduler nå registret utan att skalet skickar det som prop.
- Beskriva redaktionella sidor och deras innehåll som block, oberoende av källa.
- Bära flödestyperna tills motorn lyfts till packages/flow-engine i M4.
Filer
| Sökväg | Roll |
|---|---|
| packages/module-sdk/src/types.ts | ModuleManifest, UserContext, Widget (med label för flyttknapparna, ADR-018), ActionItem, ModuleRoute (focus, standard, full) och RouteComponent (ADR-019, ADR-025), Genvag (ADR-025), Notification och NotificationsProvider (ADR-020), FokusItem och FokusProvider (ADR-021), IntentHandler. |
| packages/module-sdk/src/select.ts | widgetsFor, actionsFor, uppgifterFor, navFor, genvagarFor, mergeNav, routeFor (med parametrar), matchaVag, suggestionsFor. |
| packages/module-sdk/src/define.ts | defineModule: typkontroll utan annotering. |
| packages/module-sdk/src/provide.ts | provideRegistry och currentRegistry (ADR-007). |
| packages/module-sdk/src/page.ts | PageManifest, PageContent, ContentBlock och Inline (ADR-016). |
| packages/module-sdk/src/pages.ts | findPage, pageTrail, pageHref, hubsInSection, articlesUnder, resolveContent, pageProblems. |
| packages/module-sdk/src/flow.ts | FlowDefinition, turkontraktets zod-schema, farSkapas. |
| packages/module-sdk/src/prompt.ts | byggSystemprompt: systemprompten ur flödesdefinitionen, inklusive blocket med redan fastställda fält (ADR-013). |
API
| Namn | Signatur | Beskrivning |
|---|---|---|
| defineModule | (manifest: ModuleManifest) => ModuleManifest | Identitetsfunktion som ger typkontroll på manifestet. |
| widgetsFor | (modules, slot, ctx) => Widget[] | Widgets i en slot som rollen ska se, i ordning. Widgetens roles är snävare än modulens. |
| actionsFor | (modules, ctx) => Promise<ActionItem[]> | Aggregatet bakom "Att agera på": de öppna uppgifterna. En modul som fallerar tar inte ned kortet. |
| uppgifterFor | (modules, ctx) => Promise<Uppgift[]> | Den samlade uppgiftslistan bakom Mina uppgifter och AI-assistentens verktyg: öppna i ordning, sedan hanterade, senast hanterade först. Varje uppgift får modul, kalla (modulens namn om modulen inte satt en) och lage (öppen om inget sattes). |
| routeFor | (modules, path, ctx) => { route, module, params } | undefined | Slår upp en modulrutt, med parametrar ur mönster som /verktyg/personal/:id. En exakt väg går före ett mönster (ADR-019). |
| fokusFor | (modules, ctx) => Promise<FokusItem[]> | Fokusytornas innehåll, nyast först. Skalet visar den första som inte är stängd (ADR-021). |
| genvagarFor | (modules, ctx) => Genvag[] | Knapparna bredvid hälsningen på startsidan, rollfiltrerade och sorterade på order (ADR-025). |
| notificationsFor | (modules, ctx) => Promise<Notification[]> | Klockans notiser från alla moduler, nyast först. En modul som fallerar tar inte ned de andras (ADR-020). |
| matchaVag | (monster: string, path: string) => Record<string, string> | undefined | Mönstermatchningen bakom routeFor. ":namn" fångar ett segment. |
| intentsFor / matchaAvsikt | (modules, ctx) => IntentHandler[] / (intents, fraga) => IntentHandler | undefined | Avsikterna rollen når, och den första vars mönster står i frågan – gemener, delsträng. AI-fältet använder dem före modellen. |
| provideRegistry / currentRegistry | (all: ModuleManifest[]) => void / () => ModuleManifest[] | Registret för aggregerande moduler (ADR-007). |
| findPage | (modules, segments: string[]) => PageManifest | undefined | Slår upp en sida på URL-segmenten under /sidor: [sektion, ingång] eller [sektion, ingång, artikel]. |
| pageTrail / pageHref | (modules, page) => PageManifest[] / (page) => string | Brödsmulorna från ingången ned till sidan, och sidans väg. |
| resolveContent | (page, ctx) => Promise<PageContent> | Statiskt innehåll eller källa – skalet behöver inte veta vilket. |
| topPagesInSection | (modules, section) => PageManifest[] | Sektionens sidor utan parent – ingångar och inramade sidor. En webbplats meny. |
| pageProblems | (modules) => string[] | Registrets invarianter: unika slugar, artikelns parent är en ingång i samma sektion. Körs i test. |
| byggSystemprompt | (flow, profil, faltHittills?) => string | Prompten ur flödet. faltHittills förankrar värdena så att modellen återger dem ordagrant i stället för att formulera om sig varje tur. |
| buildTurnSchema | (flow: FlowDefinition) => ZodObject | Turkontraktet byggt ur flödet: reply, fields, complete, create. |
| farSkapas | (flow, turCreate, varden, antalAnvandarsvar) => boolean | Tre villkor samtidigt: modellen har begärt det, allt obligatoriskt finns, och användaren har sett en sammanfattning. |
Kontrakt
Kontraktet ska hållas tunt. Ett nytt fält gör det tyngre för alla moduler och ska bäras av minst två innan det blir permanent.
Rollfiltreringens tre nivåer – den snävaste vinner
roles på modulen gäller allt modulen bidrar med
roles på widgeten snävare än modulens
roles på nav-posten snävare än modulensPageManifest och innehållsblocken (page.ts)
interface PageManifest {
slug: string; // unik i registret, blir ctx.page
section: string; // sektions-id ur skalets "Sidor"
parent?: string; // ingångens slug – bara för en artikel
layout: "hub" | "article";
title: string; lede?: string; kicker?: string;
quickLinks?: QuickLink[]; // bara ingång
article?: ArticleMeta; // bara artikel
ai?: { suggestions?: (ctx) => Suggestion[] };
content?: PageContent | ((ctx) => Promise<PageContent>);
}
type ContentBlock =
| { type: "heading"; level: 2 | 3 | 4; text: string }
| { type: "paragraph"; inlines: Inline[] }
| { type: "list"; ordered: boolean; items: Inline[][] }
| { type: "image"; src: string; alt: string; caption?: string };
// Aldrig HTML: en adapter översätter källan till block (ADR-016).
| { type: "details"; summary: string; chip?: { label; tone }; blocks: ContentBlock[] } // ADR-022
PageManifest.slots?: { main?: Widget[]; side?: Widget[] } // bara ingång: modulens egna kort
PageContent.cards?: { title: string; blocks: ContentBlock[] }[] // fler redaktionella kort
QuickLink.cta?: string // knapptext på snabbvägskortet
interface PageLink { title: string; href: string; external: boolean; children?: PageLink[] }
// layout "embed" + embed: { src } = en extern sida i ram (ADR-017). https, ingen parent.
// children = en hopfälld nivå; så blir en webbkarta en länklista, inte en sidtyp.Beroenden och beslut
Kvarstår
- IntentHandler matchas med enkla mönster (matchaAvsikt) av AI-fältet; LLM-matchning av avsikter finns inte.
- Sidor rollfiltreras inte – de är gemensamma enligt ADR-003. Behövs det, är det ett nytt fält och en ny ADR.
- Flödestyperna ligger här i väntan på M4. ADR-005 skrivs när motorn lyfts.