MarsDawn

和你的 agent 一起做主題

給製作 MarsDawn 預覽主題的 AI agent 的參考。agent 寫出一個 theme.json,用 marsdawn 命令列工具檢查並渲染,再把連結交給你。你在打造一個主題頁面用眼睛調整,然後投稿。下面的欄位表直接讀自 kit 的原始碼,並有檢查確保兩者一致。

寫出一個 theme.json,反覆執行 marsdawn theme validate theme.json --require-complete --json 直到結束代碼為 0,用 marsdawn theme preview 分別渲染淺色與深色,再把連結交給使用者。主題只有參數,不含任何 CSS。

主題是什麼

不在下面表格裡的鍵是錯誤,同一個鍵寫兩次也是。檔案最大 16,384 位元組。

檢查與渲染

在放有 theme.json 的資料夾裡執行這些指令。需要 marsdawn 工具:見給 AI agent 的 marsdawn 參考。

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

從內建主題開始

複製四個內建主題之一再修改。每一個都是完整且有效的檔案:

範例:Dawn

這是 dawn.json,一個位元組都沒改。它唯一的樣式選項是 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 } }
  }
}

欄位

下面每個物件都用同樣的方式讀取。required 表示這個鍵必須存在,沒有列出的鍵都是錯誤。

型別:string、integer、number、boolean、map(語言標籤對應文字)、enum(列出的值之一)、role(色盤角色)和 object(連到它的表格)。型別後面的 [] 表示清單。

theme.json

欄位型別必填與否值與備註
schemaVersionintegerrequired固定是 1。
idstringrequired1 到 32 個字元:小寫字母與數字,以單一連字號連接成段,例如 calm-green。
versionstringrequiredMAJOR.MINOR.PATCH,例如 1.0.0。
namemaprequired語言標籤對應文字。en 必填,其他鍵是像 zh-Hant 的語言標籤。每段文字最多 48 個字元,不可含連結或換行。
summarymaprequired和 name 的形式相同,每段文字最多 120 個字元。
fontDesignenumrequiredsans, serif, rounded
scenariosenum[]requiredagent-review, technical-docs, formal-output, notes-sharing — 一個或兩個,不可重複。它們決定主題必須達到多高的對比。
authorobjectoptionalauthor
licensestringoptionalSPDX 識別碼,例如 Apache-2.0。投稿的主題以 Apache-2.0 釋出。
lightobjectrequiredlight, dark
darkobjectrequiredlight, dark
styleobjectoptionalstyle

author

欄位型別必填與否值與備註
namestringrequired最多 64 個字元,不可含連結。
githubstringoptionalGitHub 帳號。投稿時請填投稿者自己的帳號。

light, dark

欄位型別必填與否值與備註
backgroundstringrequired# 加六個十六進位數字,例如 #1C1C1C。
surfacestringrequired# 加六個十六進位數字,例如 #1C1C1C。
textstringrequired# 加六個十六進位數字,例如 #1C1C1C。
mutedstringrequired# 加六個十六進位數字,例如 #1C1C1C。
borderstringrequired# 加六個十六進位數字,例如 #1C1C1C。
headingstringrequired# 加六個十六進位數字,例如 #1C1C1C。
accentstringrequired# 加六個十六進位數字,例如 #1C1C1C。
linkstringrequired# 加六個十六進位數字,例如 #1C1C1C。
quotestringrequired# 加六個十六進位數字,例如 #1C1C1C。
syntaxobjectoptional (發布時必填,用 --require-complete 檢查)syntax
diagramobjectoptional (發布時必填,用 --require-complete 檢查)diagram

syntax

欄位型別必填與否值與備註
keywordstringrequired# 加六個十六進位數字,例如 #1C1C1C。
stringstringrequired# 加六個十六進位數字,例如 #1C1C1C。
commentstringrequired# 加六個十六進位數字,例如 #1C1C1C。
numberstringrequired# 加六個十六進位數字,例如 #1C1C1C。
functionstringrequired# 加六個十六進位數字,例如 #1C1C1C。
typestringrequired# 加六個十六進位數字,例如 #1C1C1C。

diagram

欄位型別必填與否值與備註
nodestringrequired# 加六個十六進位數字,例如 #1C1C1C。
nodeBorderstringrequired# 加六個十六進位數字,例如 #1C1C1C。
textstringrequired# 加六個十六進位數字,例如 #1C1C1C。
linestringrequired# 加六個十六進位數字,例如 #1C1C1C。
secondarystringrequired# 加六個十六進位數字,例如 #1C1C1C。
tertiarystringrequired# 加六個十六進位數字,例如 #1C1C1C。
notestringrequired# 加六個十六進位數字,例如 #1C1C1C。

style

欄位型別必填與否值與備註
bodySizenumberoptional範圍
lineHeightnumberoptional範圍
headingWeightnumberoptional範圍
radiusnumberoptional範圍
maxWidthnumberoptional範圍
h1objectoptionalstyle.h1
h2objectoptionalstyle.h2
blockquoteobjectoptionalstyle.blockquote
hrobjectoptionalstyle.hr
tableobjectoptionalstyle.table
listMarkerroleoptional色盤角色
inlineCoderoleoptional色盤角色 — 只能是 text 或語法角色:keyword、string、comment、number、function 或 type。
linkobjectoptionalstyle.link
syntaxobjectoptionalstyle.syntax

style.h1

欄位型別必填與否值與備註
sizenumberoptional範圍
letterSpacingnumberoptional範圍
alignenumoptionalleft, center
decorationobjectoptionaltype

style.h2

欄位型別必填與否值與備註
letterSpacingnumberoptional範圍
decorationobjectoptionaltype
italicbooleanoptionaltrue, false

style.blockquote

欄位型別必填與否值與備註
styleobjectoptionaltype
italicbooleanoptionaltrue, false

style.hr

欄位型別必填與否值與備註
styleobjectoptionaltype

style.table

欄位型別必填與否值與備註
headerobjectoptionaltype
verticalRulesbooleanoptionaltrue, false
roundedbooleanoptionaltrue, false
欄位型別必填與否值與備註
underlinebooleanoptionaltrue, false

style.syntax

欄位型別必填與否值與備註
boldKeywordsbooleanoptionaltrue, false

帶 type 的選項

這些樣式選項是帶有 type 的物件。每個 type 只接受為它列出的欄位,其他都不行。

選項type欄位必填與否型別
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 範圍
style.blockquote.stylepanel———
style.hr.stylelinecoloroptionalrole
style.hr.stylelinethicknessoptionalnumber 範圍
style.hr.styleshortCenteredcolorrequiredrole
style.hr.stylegradientcolorsrequiredrole[] 兩個或三個角色。
style.table.headersurface———
style.table.headeraccentRulecolorrequiredrole
style.table.headerfilledbackgroundrequiredrole
style.table.headerfilledtextrequiredrole
style.table.headerfilledborderoptionalrole

色盤角色

色盤角色是下列名稱之一:

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

數字

數字會先對齊到最接近的間隔倍數,再檢查是否落在最小值與最大值之間,否則規則是 number.range。

欄位最小值最大值間隔
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

還會檢查什麼

打造一個主題頁面可以從連結開啟主題,讓人用眼睛調整。連結是該頁的網址,接著 #theme=,再接檔案位元組的 base64url(不含補位)。檔案最大 16,384 位元組。下面這一行指令在 macOS 與 Linux 的 zsh 和 bash 都能產生連結:

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

主題跟在 # 後面,瀏覽器不會把它送給網站,網站也不會把它送到任何地方。連結確實會留在你的 shell 歷史與瀏覽器歷史裡,你貼給誰,誰就能讀到這個主題。

投稿

agent 準備檔案與連結,由人來投稿。兩條路都會要求 Developer Certificate of Origin 與 Apache-2.0 授權聲明,這個聲明由人本人做出:agent 不會替他勾選方框或簽署。

投稿主題的作者名稱、名稱、摘要與 GitHub 帳號會永久公開,所以請把 author.name 設成人願意公開的名字。

已發布的主題

想看已發布的主題長什麼樣子,可以逛逛主題庫。