MarsDawn

Créer un thème avec votre agent

Une référence pour un agent IA qui crée un thème d’aperçu MarsDawn. L’agent écrit un seul theme.json, le vérifie et le rend avec l’outil en ligne de commande marsdawn, puis vous remet un lien. Vous l’ajustez à l’œil sur la page Créer un thème et vous le soumettez. Les tableaux de champs ci-dessous sont lus dans le code source du kit, et une vérification les maintient identiques.

Écrivez un theme.json, lancez marsdawn theme validate theme.json --require-complete --json jusqu’à obtenir le code de sortie 0, rendez-le avec marsdawn theme preview en clair et en sombre, puis donnez un lien à la personne. Un thème n’est fait que de paramètres. Il ne contient jamais de CSS.

Ce qu’est un thème

Une clé absente des tableaux ci-dessous est une erreur, tout comme une clé écrite deux fois. Le fichier fait au plus 16 384 octets.

Vérifier et rendre

Lancez ces commandes dans le dossier qui contient theme.json. Elles demandent l’outil marsdawn : voir marsdawn pour les agents.

marsdawn theme validate theme.json --require-complete --json
marsdawn theme css theme.json --json
marsdawn theme preview theme.json --appearance light -o light.png
marsdawn theme preview theme.json --appearance dark -o dark.png

Partir d’un thème intégré

Copiez l’un des quatre thèmes intégrés et modifiez-le. Chacun est un fichier complet et valide :

Exemple : Dawn

Voici dawn.json, octet pour octet. Sa seule option de style est un fin filet de couleur d’accent pour hr.

{
  "schemaVersion": 1,
  "id": "dawn",
  "version": "1.0.0",
  "name": { "en": "Dawn" },
  "summary": { "en": "Warm Martian sunrise" },
  "fontDesign": "sans",
  "scenarios": ["agent-review"],
  "light": {
    "background": "#FFFDFB", "surface": "#F6F0EC", "text": "#26211F", "muted": "#6F6660",
    "border": "#EADFD8", "heading": "#26211F", "accent": "#C8471B", "link": "#B03C0C", "quote": "#D97A4A",
    "syntax": { "keyword": "#B03C0C", "string": "#2F6F5E", "comment": "#746B66", "number": "#9A5B00", "function": "#5B3E8C", "type": "#1F6FB2" },
    "diagram": { "node": "#FBE9E0", "nodeBorder": "#CA6C3C", "text": "#26211F", "line": "#8A6A5C", "secondary": "#E6F1EE", "tertiary": "#FFF6F1", "note": "#FFF1D6" }
  },
  "dark": {
    "background": "#1C1A1F", "surface": "#262229", "text": "#EBE4DF", "muted": "#A39992",
    "border": "#3A343A", "heading": "#F4EEEA", "accent": "#FF8A50", "link": "#FF9E6B", "quote": "#E08A5C",
    "syntax": { "keyword": "#FF9E6B", "string": "#7FD1B9", "comment": "#938A84", "number": "#F2C572", "function": "#C7A6F5", "type": "#6CB6FF" },
    "diagram": { "node": "#3A2A26", "nodeBorder": "#E08A5C", "text": "#EBE4DF", "line": "#B8A69C", "secondary": "#23332F", "tertiary": "#2B2427", "note": "#3D3322" }
  },
  "style": {
    "hr": { "style": { "type": "line", "color": "accent", "thickness": 1 } }
  }
}

Champs

Chaque objet ci-dessous est lu de la même façon. required signifie que la clé doit être présente, et une clé qui n’est pas listée est une erreur.

Types : string, integer, number, boolean, map (balise de langue vers texte), enum (l’une des valeurs listées), role (un rôle de palette) et object (le tableau vers lequel il renvoie). Un [] après un type signifie une liste.

theme.json

ChampTypePrésenceValeurs et remarques
schemaVersionintegerrequiredToujours 1.
idstringrequiredDe 1 à 32 caractères : lettres minuscules et chiffres, en blocs reliés par des tirets simples, par exemple calm-green.
versionstringrequiredMAJOR.MINOR.PATCH, par exemple 1.0.0.
namemaprequiredBalise de langue vers texte. en est obligatoire ; les autres clés sont des balises de langue comme zh-Hant. Chaque texte compte au plus 48 caractères, sans lien ni saut de ligne.
summarymaprequiredMême forme que name, au plus 120 caractères par texte.
fontDesignenumrequiredsans, serif, rounded
scenariosenum[]requiredagent-review, technical-docs, formal-output, notes-sharing — Un ou deux, sans répétition. Ils fixent le contraste que le thème doit atteindre.
authorobjectoptionalauthor
licensestringoptionalUn identifiant SPDX, par exemple Apache-2.0. Les thèmes soumis sont publiés sous Apache-2.0.
lightobjectrequiredlight, dark
darkobjectrequiredlight, dark
styleobjectoptionalstyle

author

ChampTypePrésenceValeurs et remarques
namestringrequiredAu plus 64 caractères, sans lien.
githubstringoptionalUn identifiant GitHub. Pour une soumission, indiquez celui de la personne qui soumet.

light, dark

ChampTypePrésenceValeurs et remarques
backgroundstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
surfacestringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
textstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
mutedstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
borderstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
headingstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
accentstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
linkstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
quotestringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
syntaxobjectoptional (requis pour publier, avec --require-complete)syntax
diagramobjectoptional (requis pour publier, avec --require-complete)diagram

syntax

ChampTypePrésenceValeurs et remarques
keywordstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
stringstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
commentstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
numberstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
functionstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
typestringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.

diagram

ChampTypePrésenceValeurs et remarques
nodestringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
nodeBorderstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
textstringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
linestringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
secondarystringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
tertiarystringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.
notestringrequired# suivi de six chiffres hexadécimaux, par exemple #1C1C1C.

style

ChampTypePrésenceValeurs et remarques
bodySizenumberoptionalplage
lineHeightnumberoptionalplage
headingWeightnumberoptionalplage
radiusnumberoptionalplage
maxWidthnumberoptionalplage
h1objectoptionalstyle.h1
h2objectoptionalstyle.h2
blockquoteobjectoptionalstyle.blockquote
hrobjectoptionalstyle.hr
tableobjectoptionalstyle.table
listMarkerroleoptionalun rôle de palette
inlineCoderoleoptionalun rôle de palette — Seulement text ou un rôle de syntaxe : keyword, string, comment, number, function ou type.
linkobjectoptionalstyle.link
syntaxobjectoptionalstyle.syntax

style.h1

ChampTypePrésenceValeurs et remarques
sizenumberoptionalplage
letterSpacingnumberoptionalplage
alignenumoptionalleft, center
decorationobjectoptionaltype

style.h2

ChampTypePrésenceValeurs et remarques
letterSpacingnumberoptionalplage
decorationobjectoptionaltype
italicbooleanoptionaltrue, false

style.blockquote

ChampTypePrésenceValeurs et remarques
styleobjectoptionaltype
italicbooleanoptionaltrue, false

style.hr

ChampTypePrésenceValeurs et remarques
styleobjectoptionaltype

style.table

ChampTypePrésenceValeurs et remarques
headerobjectoptionaltype
verticalRulesbooleanoptionaltrue, false
roundedbooleanoptionaltrue, false
ChampTypePrésenceValeurs et remarques
underlinebooleanoptionaltrue, false

style.syntax

ChampTypePrésenceValeurs et remarques
boldKeywordsbooleanoptionaltrue, false

Options à type

Ces options de style sont des objets avec un type. Chaque type accepte les champs listés pour lui, et aucun autre.

OptiontypeChampPrésenceType
style.h1.decorationrule———
style.h1.decorationnone———
style.h1.decorationshortRulecolorrequiredrole
style.h1.decorationgradientBarfromrequiredrole
style.h1.decorationgradientBartorequiredrole
style.h2.decorationrule———
style.h2.decorationnone———
style.h2.decorationdotcolorrequiredrole
style.blockquote.stylebarwidthoptionalnumber plage
style.blockquote.stylepanel———
style.hr.stylelinecoloroptionalrole
style.hr.stylelinethicknessoptionalnumber plage
style.hr.styleshortCenteredcolorrequiredrole
style.hr.stylegradientcolorsrequiredrole[] Deux ou trois rôles.
style.table.headersurface———
style.table.headeraccentRulecolorrequiredrole
style.table.headerfilledbackgroundrequiredrole
style.table.headerfilledtextrequiredrole
style.table.headerfilledborderoptionalrole

Rôles de palette

Un rôle de palette est l’un de ces noms :

background, surface, text, muted, border, heading, accent, link, quote, keyword, string, comment, number, function, type

Nombres

Un nombre est arrondi au multiple le plus proche de son pas, puis doit se trouver entre le min et le max. Sinon la règle est number.range.

ChampMinMaxPas
style.bodySize14181
style.lineHeight1.41.90.05
style.headingWeight40090050
style.radius0161
style.maxWidth60010001
style.h1.size1.82.40.1
style.h1.letterSpacing-0.030.030.005
style.h2.letterSpacing-0.030.030.005
style.blockquote.style.width241
style.hr.style.thickness141

Ce qui est vérifié d’autre

La page Créer un thème ouvre un thème à partir d’un lien, pour que la personne puisse l’ajuster à l’œil. Le lien est l’adresse de la page, puis #theme=, puis les octets du fichier en base64url sans remplissage. Le fichier fait au plus 16 384 octets. Cette seule ligne construit le lien sous zsh et sous bash, sur macOS et sur Linux :

printf 'https://marsdawn.southern-light.dev/fr/themes/new/#theme=%s\n' "$(base64 < theme.json | tr -d '\n=' | tr '+/' '-_')"

Le thème voyage après un #, que le navigateur n’envoie pas au site, et le site ne le transmet nulle part. Le lien reste toutefois dans l’historique de votre shell et du navigateur, et toute personne à qui vous le collez peut lire le thème.

Le soumettre

L’agent prépare le fichier et le lien. La personne soumet. Les deux voies demandent le Developer Certificate of Origin et la publication sous Apache-2.0, et c’est la personne qui fait cette attestation : l’agent ne coche pas la case et ne signe pas à sa place.

Le nom d’auteur, le nom, le résumé et l’identifiant GitHub d’un thème soumis deviennent publics de façon permanente : mettez dans author.name un nom que la personne accepte de publier.

Thèmes publiés

Pour voir à quoi ressemblent les thèmes publiés, parcourez la galerie de thèmes.