mosage 0.1.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +16 -217
  3. package/bin.js +2 -0
  4. package/dist/build-C7NW_3Pk.js +14 -0
  5. package/dist/check-CP4873Wx.js +41 -0
  6. package/dist/cli/bin.d.ts +1 -0
  7. package/dist/cli/bin.js +228 -0
  8. package/dist/config-DPm1BBAb.js +2619 -0
  9. package/dist/config-TlTe7Ona.d.ts +24 -0
  10. package/dist/context-BqsdSrAQ.js +1084 -0
  11. package/dist/dev-Biz42qlu.js +17 -0
  12. package/dist/diagram-xlVDekYk.js +763 -0
  13. package/dist/export-Bi6nuxjT.js +31 -0
  14. package/dist/import-D2jNB07F.js +25 -0
  15. package/dist/index.d.ts +455 -0
  16. package/dist/index.js +693 -0
  17. package/dist/init-Bbtj2pxF.js +262 -0
  18. package/dist/preview-CLm51aRt.js +19 -0
  19. package/dist/sdk-DjpX6mCv.js +51 -0
  20. package/dist/vite/index.d.ts +25 -0
  21. package/dist/vite/index.js +2 -0
  22. package/env.d.ts +83 -0
  23. package/package.json +84 -64
  24. package/skills/apply-comments/SKILL.md +43 -56
  25. package/skills/create-doc/SKILL.md +106 -0
  26. package/skills/create-theme/SKILL.md +184 -0
  27. package/skills/current-doc/SKILL.md +120 -0
  28. package/skills/doc-authoring/SKILL.md +434 -0
  29. package/skills/doc-authoring/references/assets.md +47 -0
  30. package/skills/doc-authoring/references/design-system.md +81 -0
  31. package/skills/doc-authoring/references/long-form.md +131 -0
  32. package/skills/doc-authoring/references/pagination.md +118 -0
  33. package/skills/doc-authoring/references/tables-and-charts.md +161 -0
  34. package/src/app/app.tsx +42 -0
  35. package/src/app/components/data-table.tsx +196 -0
  36. package/src/app/components/design-panel/design-panel.tsx +318 -0
  37. package/src/app/components/design-panel/design-provider.tsx +121 -0
  38. package/src/app/components/design-panel/use-design.ts +85 -0
  39. package/src/app/components/diagram.tsx +76 -0
  40. package/src/app/components/doc-assets.tsx +129 -0
  41. package/src/app/components/doc-search.tsx +248 -0
  42. package/src/app/components/doc-sidebar.tsx +162 -0
  43. package/src/app/components/flow-page.tsx +93 -0
  44. package/src/app/components/footnote.tsx +204 -0
  45. package/src/app/components/image-placeholder.tsx +50 -0
  46. package/src/app/components/inspector/inspector.tsx +518 -0
  47. package/src/app/components/numbering.tsx +224 -0
  48. package/src/app/components/page-frame.tsx +70 -0
  49. package/src/app/components/sidebar/folder-item.tsx +212 -0
  50. package/src/app/components/sidebar/icon-picker.tsx +99 -0
  51. package/src/app/components/sidebar/sidebar.tsx +252 -0
  52. package/src/app/components/table-of-contents.tsx +93 -0
  53. package/src/app/components/theme-toggle.tsx +50 -0
  54. package/src/app/components/themes/markdown.tsx +249 -0
  55. package/src/app/components/themes/theme-preview.tsx +74 -0
  56. package/src/app/components/ui/menu.tsx +143 -0
  57. package/src/app/index.html +12 -0
  58. package/src/app/lib/agent-bridge.ts +140 -0
  59. package/src/app/lib/assets.ts +151 -0
  60. package/src/app/lib/design-presets.ts +109 -0
  61. package/src/app/lib/design.ts +88 -0
  62. package/src/app/lib/diagnostics.ts +282 -0
  63. package/src/app/lib/doc-preview.tsx +29 -0
  64. package/src/app/lib/docs.ts +26 -0
  65. package/src/app/lib/docx/extract.ts +1623 -0
  66. package/src/app/lib/docx/fonts.test.ts +136 -0
  67. package/src/app/lib/docx/fonts.ts +166 -0
  68. package/src/app/lib/docx/media.ts +102 -0
  69. package/src/app/lib/docx/model.ts +206 -0
  70. package/src/app/lib/docx/paragraph.test.ts +92 -0
  71. package/src/app/lib/docx/paragraph.ts +107 -0
  72. package/src/app/lib/docx/props.ts +187 -0
  73. package/src/app/lib/docx/styles.ts +306 -0
  74. package/src/app/lib/docx/units.ts +35 -0
  75. package/src/app/lib/docx/write.test.ts +507 -0
  76. package/src/app/lib/docx/write.ts +581 -0
  77. package/src/app/lib/docx/xml.ts +39 -0
  78. package/src/app/lib/export-docx.ts +289 -0
  79. package/src/app/lib/export-dom.ts +318 -0
  80. package/src/app/lib/export-html.ts +156 -0
  81. package/src/app/lib/export-image.ts +70 -0
  82. package/src/app/lib/export-pdf.ts +165 -0
  83. package/src/app/lib/flow-measure.test.ts +31 -0
  84. package/src/app/lib/flow-measure.ts +183 -0
  85. package/src/app/lib/flow.test.ts +110 -0
  86. package/src/app/lib/flow.ts +136 -0
  87. package/src/app/lib/folders.ts +192 -0
  88. package/src/app/lib/footnotes.test.tsx +102 -0
  89. package/src/app/lib/footnotes.ts +94 -0
  90. package/src/app/lib/inspector/fiber.ts +99 -0
  91. package/src/app/lib/labels.test.ts +18 -0
  92. package/src/app/lib/labels.ts +181 -0
  93. package/src/app/lib/outline.ts +118 -0
  94. package/src/app/lib/page-context.tsx +43 -0
  95. package/src/app/lib/page-range.test.ts +95 -0
  96. package/src/app/lib/page-range.ts +90 -0
  97. package/src/app/lib/print-ready.ts +69 -0
  98. package/src/app/lib/rasterize.ts +173 -0
  99. package/src/app/lib/scan.ts +26 -0
  100. package/src/app/lib/sdk.test.ts +32 -0
  101. package/src/app/lib/sdk.ts +115 -0
  102. package/src/app/lib/themes.ts +31 -0
  103. package/src/app/lib/use-doc-module.ts +53 -0
  104. package/src/app/lib/use-doc-pages.ts +147 -0
  105. package/src/app/lib/utils.ts +6 -0
  106. package/src/app/lib/view-mode.test.ts +91 -0
  107. package/src/app/lib/view-mode.ts +104 -0
  108. package/src/app/main.tsx +14 -0
  109. package/src/app/routes/assets.tsx +257 -0
  110. package/src/app/routes/doc.tsx +877 -0
  111. package/src/app/routes/home-shell.tsx +203 -0
  112. package/src/app/routes/home.tsx +269 -0
  113. package/src/app/routes/themes.tsx +121 -0
  114. package/src/app/styles.css +97 -0
  115. package/src/app/virtual.d.ts +30 -0
  116. package/template/AGENTS.md +27 -0
  117. package/template/README.md +39 -0
  118. package/template/docs/getting-started/index.tsx +230 -0
  119. package/template/mosage.config.ts +5 -0
  120. package/template/package.json +24 -0
  121. package/template/tsconfig.json +17 -0
  122. package/README.en.md +0 -57
  123. package/dist/cli.js +0 -4545
  124. package/dist/web/assets/index-Czg2WeHe.js +0 -182
  125. package/dist/web/assets/index-DKAyt92W.css +0 -1
  126. package/dist/web/index.html +0 -15
  127. package/skills/current-position/SKILL.md +0 -65
  128. package/skills/kickoff/SKILL.md +0 -105
  129. package/skills/mosage-reference/SKILL.md +0 -164
  130. package/skills/outline/SKILL.md +0 -79
  131. package/skills/review/SKILL.md +0 -64
  132. package/skills/write-chapter/SKILL.md +0 -58
  133. package/template/book/STYLE.md +0 -6
  134. package/template/book/assets/.gitkeep +0 -0
  135. package/template/book/book.yaml +0 -42
  136. package/template/book/brief.md +0 -6
  137. package/template/book/chapters/.gitkeep +0 -0
  138. package/template/book/notes/README.md +0 -7
  139. package/template/project/AGENTS.md +0 -82
  140. package/template/project/CLAUDE.md +0 -1
  141. package/template/project/README.md +0 -48
  142. package/template/project/books/.gitkeep +0 -0
  143. package/template/project/gitignore +0 -5
  144. package/template/project/mosage.yaml +0 -23
  145. package/template/project/notes/README.md +0 -8
  146. package/template/project/package.json +0 -14
@@ -1,87 +1,74 @@
1
1
  ---
2
2
  name: apply-comments
3
- description: 處理作者在 MoSage 介面上留給 AI 的留言。作者說「處理留言」「套用我的留言」「看一下我的意見」「我留了言」「apply comments」時使用。找出所有作者留言(mosage:comment,by=human),依 ai.editMode 以「修改建議」或直接修改的方式處理,然後移除已處理的留言標記。
3
+ description: Use this skill when the user asks to apply, process, or clear the comments they left in the MoSage inspector — phrases like "apply the comments", "apply my edits", "I left notes on the document", "process the markers", "/apply-comments". It finds every `@doc-comment` marker under `docs/`, makes the edit each one asks for, then removes the marker. Do NOT use for authoring new documents — that is `create-doc`.
4
4
  ---
5
5
 
6
- # 處理作者留言
6
+ # Apply inspector comments
7
7
 
8
- 作者在介面上選取文字、按「留言給 AI」後,留言會以 HTML 註解存進章節檔,放在它所指的區塊(段落、標題、清單、表格…)**正上方**:
8
+ The dev UI's **Inspect** mode lets the user click any element on a page and leave a note. Each note is written into the document source as a marker:
9
9
 
10
- ```markdown
11
- <!-- mosage:comment id=c-3f9a12bc by=human at=2026-09-26T08:12:03Z quote="這一段的第二句"
12
- 太生硬了,改得口語一點,並補一個例子
13
- -->
14
- 這是作者留言所指的那一段……
10
+ ```tsx
11
+ <p style={p}>
12
+ {/* @doc-comment id="c-4591fd61" ts="2026-08-15T15:40:52.644Z" text="<base64url>" */}
13
+ 從 FastMCP 開發、容器化…
14
+ </p>
15
15
  ```
16
16
 
17
- - `quote` 是作者選取的文字(可能沒有 —— 那就是針對整個區塊)。
18
- - 標記下方緊接的那個區塊就是留言的對象。
17
+ The marker is always the **first child of the element the note is about** — that is your anchor. `text` is base64url-encoded JSON: `{"note": "...", "hint": "p"}`.
19
18
 
20
- ## 1. 找出留言
19
+ ## Step 1 — Find the pending comments
21
20
 
22
21
  ```bash
23
- npx mosage status <書> --json # 看 notes 陣列:kind 為 comment 且 by 不是 ai 的就是作者留言
24
- grep -rn "mosage:comment" books/<書>/chapters/
22
+ grep -rn "@doc-comment" docs/
25
23
  ```
26
24
 
27
- 作者沒指定書時,處理所有書裡的作者留言(先告訴作者有幾則、在哪幾本)。沒有任何留言 → 告訴作者並結束。
25
+ If the dev server is running you can read them decoded instead, which is easier:
28
26
 
29
- ## 2. 讀懂每一則
30
-
31
- - 讀留言所在的整個區塊,以及前後各幾段(「改短一點」要看上下文才知道怎麼改)。
32
- - 依 `at` 由舊到新處理 —— 後面的留言可能修正前面的。
33
- - 先讀 `brief.md`、`STYLE.md`,修改要符合風格。
27
+ ```bash
28
+ curl -s "http://localhost:5273/__comments?docId=<id>"
29
+ ```
34
30
 
35
- ## 3. 處理
31
+ That returns `{ comments: [{ id, line, ts, note, hint }] }`. If neither turns anything up, tell the user there are no pending comments and stop.
36
32
 
37
- 先看 `ai.editMode`(`books/<書>/book.yaml` 的設定優先,否則看 `mosage.yaml`,預設 `suggest`)。
33
+ ## Step 2 — Read each one in context
38
34
 
39
- ### suggest(預設)— 提出修改建議,讓作者在介面上決定
35
+ For every marker, read the surrounding element — not just the marked line. A note like *"make this shorter"* is meaningless without the paragraph it sits in. Open the file with `Read` around the marker's line (±40 lines is usually enough) so you can see the element, its styles, and its neighbours.
40
36
 
41
- **不要改原文**。把作者的留言標記**換成**一個修改建議標記,放在同一個區塊的正上方:
37
+ Group comments by document, and handle them **oldest `ts` first** — later notes may refine earlier ones.
42
38
 
43
- ```markdown
44
- <!-- mosage:suggest by=ai note="回應留言:改得口語,加上咖啡店的例子"
45
- 改寫後的**完整段落**(整段,不是只有改的那一句)。
46
- -->
47
- 這是原本的那一段……
48
- ```
39
+ ## Step 3 — Make the edit
49
40
 
50
- - 標記內容會**整個取代**下方的區塊。只改一句也要寫出整段,其餘文字保持原樣。
51
- - 要取代**連續多個區塊**(例如把兩段合併、重寫一整個清單加一段)→ 加上 `span=2`(取代下方 2 個區塊),內容寫出全部新文字,區塊之間空一行。
52
- - 要**插入新段落**而不取代任何東西 → `span=0`,內容會插在下方區塊之前。
53
- - `note` 用一句話說明你改了什麼、為什麼;作者會在介面上看到新舊對照,按「接受」或「拒絕」。
54
- - `id` 可以省略(系統會自動產生)。
41
+ Apply what the note asks for, following the **`doc-authoring`** skill: it owns the type scale, the flow/vertical-budget rules, and the design tokens. In particular:
55
42
 
56
- ### direct — 直接修改
43
+ - Edit the element the marker is anchored to. Never reformat the whole file.
44
+ - A note about wording changes the text; a note about weight, color, or size changes the inline style — prefer `var(--od-*)` tokens over new hard-coded values.
45
+ - If the change makes a fixed page overflow, split the page or move the content into the `flow()` section (`references/pagination.md`).
46
+ - If a note is ambiguous ("fix this"), do the smallest reasonable interpretation and say what you assumed at hand-off. Don't guess at a large rewrite.
47
+ - If a note asks for something the framework can't do (per-page orientation, a splitting table), say so in the hand-off and leave the marker in place.
57
48
 
58
- 直接改寫原文,然後刪除留言標記。
49
+ ## Step 4 — Remove the marker
59
50
 
60
- ### 特殊情況
51
+ Delete the marker line for every comment you actually applied. Leave markers you deliberately skipped, and say which ones and why.
61
52
 
62
- - **留言是問題**(「這裡的數據對嗎?」)或**意思不明確** → 不要猜著大改。刪除作者的留言,在同一位置留下 AI 留言回覆:
63
- ```markdown
64
- <!-- mosage:comment by=ai quote="原本的 quote"
65
- 關於「這裡的數據對嗎?」:這個數字來自……;如果要更新,請提供新的來源。
66
- -->
67
- ```
68
- - **留言要求全書一致的修改**(「全書統一用『使用者』」)→ 找出所有相關位置,每個受影響的區塊各提一個修改建議(suggest 模式)或直接修改(direct 模式)。
69
- - **無法處理的要求**(例如需要作者提供的資料)→ 保留原留言,並在回報中說明原因。
70
-
71
- ## 4. 移除已處理的留言標記
53
+ ```bash
54
+ # with the dev server running
55
+ curl -s -X DELETE "http://localhost:5273/__comments?docId=<id>&id=<comment-id>"
56
+ ```
72
57
 
73
- 每一則處理完的作者留言,刪除整個 `<!-- mosage:comment … -->`(包含它後面的換行)。
74
- 在 suggest 模式下,你已經用修改建議標記取代了它。**沒處理的留言要保留。**
58
+ Or delete the `{/* @doc-comment … */}` line directly with `Edit`. Removing it by hand is fine — the marker is a plain JSX comment.
75
59
 
76
- 檢查:`grep -rn "mosage:comment" books/<書>/chapters/` 只剩你刻意保留的與 AI 回覆。
60
+ ## Step 5 — Verify
77
61
 
78
- ## 5. 回報
62
+ - No `@doc-comment` marker remains for an applied note: `grep -rn "@doc-comment" docs/`.
63
+ - The document still compiles: it hot-reloads in the browser; check the terminal for a Vite error.
64
+ - Run the "Self-review before finishing" checklist in `doc-authoring` for any page you touched.
79
65
 
80
- 簡短列出,每則一行:
66
+ ## Step 6 — Hand off
81
67
 
82
- - 第幾章:留言重點 → 你做了什麼(修改建議/直接修改/回覆了問題)
83
- - 跳過的留言與原因
68
+ Tell the user, in one short list:
84
69
 
85
- suggest 模式下提醒作者:
70
+ - What you changed, one line per comment.
71
+ - Anything you skipped and why.
72
+ - Any assumption you made on an ambiguous note.
86
73
 
87
- > 請到介面上逐一查看修改建議,按「接受」或「拒絕」。
74
+ Do not restate the whole document.
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: create-doc
3
+ description: Use this skill when the user wants to create, draft, author, or generate a new document, report, whitepaper, proposal, memo, or spec in this MoSage repo. Triggers on phrases like "write a report about X", "draft a proposal", "make a whitepaper", "create a document", "write up the Q3 results", or when the user asks to add content under `docs/`. Do NOT use for editing the framework itself — only for authoring content inside `docs/<id>/`.
4
+ ---
5
+
6
+ # Create a document in MoSage
7
+
8
+ This skill owns the **workflow** for drafting a new document. The technical reference — file contract, page canvas, print type scale, vertical budget, tables, TOC — lives in the **`doc-authoring`** skill. Read it before writing code; don't duplicate its rules here.
9
+
10
+ You only write files under `docs/<id>/`. Never modify `package.json`, `mosage.config.ts`, or existing documents.
11
+
12
+ **If the user already has the content written as Markdown, don't retype it into JSX.** `mosage import <file.md> --id <id>` produces a real document — `flow()` body, cover, contents, local images copied into the document's assets — which you then refine. Steps 0–2 still apply for the parts the import cannot know (theme, page size, visual direction).
13
+
14
+ ## Step 0 — Pick a theme
15
+
16
+ List files under `themes/`. If any theme markdown exists (anything other than `README.md`), call `AskUserQuestion` with each theme id as an option plus a final **"no theme — design from scratch"** option. (`AskUserQuestion` holds at most 4 options — with 4+ themes, offer the 3 most relevant plus "no theme"; the auto-added "Other" lets the user name an omitted one.)
17
+
18
+ - If the user picks a theme: read `themes/<id>.md` end-to-end. Its palette, typography, page setup, and paste-ready components are now authoritative — copy them into the document, and set `meta.theme: '<id>'` in `index.tsx`. Skip the **visual direction** question in Step 2 (the theme already commits to one) and restate the theme name so the user can correct course. Page size comes from the theme's frontmatter unless the user overrides it.
19
+ - If the user picks "no theme", or `themes/` has no theme files: continue unchanged.
20
+
21
+ ## Step 1 — Gather the substance first
22
+
23
+ A document is judged on content, not layout. Before anything else, establish:
24
+
25
+ - **Topic and purpose** — what decision or action should this document produce?
26
+ - **Audience** — executives (lead with the recommendation), engineers (lead with the mechanism), clients (lead with the outcome and the price).
27
+ - **Source material** — does the user have data, a draft, notes, a repo, an existing doc? Ask for it. **Never fabricate figures, quotes, citations, or customer names.**
28
+
29
+ If the request is thin ("write me a report"), make a **separate** `AskUserQuestion` call for topic, audience, and source material before the style questions below. If the topic is already clear, restate your reading of it in the next call so the user can correct course.
30
+
31
+ ## Step 2 — Clarify the shape (MUST ask before writing code)
32
+
33
+ Ask these in a single `AskUserQuestion` call (multi-question form). Skip a question only when the user's message already answers it unambiguously — and restate the assumption if you skip.
34
+
35
+ 1. **Document type** — propose 3 concrete types that fit *this* topic, each with what it implies structurally. Not bare labels:
36
+ - *"our Q3 infrastructure numbers"* → **internal review** (summary, metrics, incidents, actions) · **exec brief** (2 pages, recommendation-first) · **post-incident deep dive** (timeline, root cause, remediation)
37
+ - *"our new product for enterprise buyers"* → **whitepaper** (problem, approach, evidence, references) · **sales proposal** (scope, deliverables, timeline, price) · **one-pager** (positioning + proof + CTA)
38
+ Mark the best fit "(Recommended)".
39
+ 2. **Length** — offer brackets: 2–4 pages (brief), 5–10 (standard report), 11–25 (deep dive). The auto-added "Other" covers custom counts.
40
+ 3. **Page size** — A4 portrait (default) · A4 landscape (data-heavy, wide tables) · B4 or A3 (plans, posters, very wide tables). The only sizes are A4, B4 and A3, each portrait or landscape. Skip if the user already said.
41
+ 4. **Visual direction** — 3 options tailored to the audience, each naming a palette + typographic cue: e.g. **corporate neutral** (near-white, single blue accent, sans throughout) · **editorial serif** (serif headings, generous leading, hairline rules) · **technical mono-accent** (mono labels, dense tables, monochrome + one signal color).
42
+
43
+ Ask about brand colors, a logo, or required sections only if still unclear afterwards.
44
+
45
+ ## Step 3 — Pick a doc id
46
+
47
+ **kebab-case**, short, descriptive: `q3-infra-review`, `acme-proposal-2026`, `auth-migration-rfc`. Check `docs/` for collisions.
48
+
49
+ ## Step 4 — Outline before code
50
+
51
+ Write the page plan first — one line per page, with its role. Typical structures:
52
+
53
+ | Type | Page plan |
54
+ | --- | --- |
55
+ | Report | Cover · Contents · Executive summary · Method · Findings (n pages) · Risks · Recommendations · Appendix |
56
+ | Whitepaper | Cover · Abstract · Problem · Approach · Evidence · Comparison · Conclusion · References |
57
+ | Proposal | Cover · Summary · Scope · Deliverables · Timeline · Pricing · Terms · Next steps |
58
+ | RFC / spec | Summary · Motivation · Design · Alternatives · Migration · Open questions |
59
+ | Memo | Header block · Context · Recommendation · Rationale · Next steps |
60
+
61
+ Rules for the plan:
62
+
63
+ - **Page 1 is the cover**; if the doc is over ~6 pages, **page 2 is `<TableOfContents />`**. Both are fixed pages; everything after them belongs in one `flow()` section so the framework paginates the body.
64
+ - The executive summary must stand alone — a reader who reads only that page should know the conclusion and the ask.
65
+ - One section per page unless a section is genuinely two paragraphs long.
66
+ - Plan the body as a **sequence of sections**, not as a page count — `flow()` decides how many pages that becomes. Only estimate the vertical budget for the fixed pages (cover, contents, dividers); see `doc-authoring` → `references/pagination.md`.
67
+
68
+ Show the user the page plan and the estimated page count before writing the file if the document is over ~8 pages — restructuring a 20-page doc after the fact is expensive.
69
+
70
+ ## Step 5 — Commit to a visual direction
71
+
72
+ Declare a top-level `export const design: DesignSystem` and consume `var(--od-*)` everywhere. Print constraints (white background, ≥13px body, one accent) are in `references/design-system.md` — read it before choosing the palette. If a theme was picked in Step 0, copy its `design` const verbatim instead of inventing one.
73
+
74
+ Keep the const a plain object literal: the dev UI's **Design panel** parses and rewrites it, and a spread or a value read from another constant makes the document untweakable (see "Writing for the Design panel" in `doc-authoring`).
75
+
76
+ Define the shared page shell, heading styles, and the running footer **once** as local constants/components at the top of `index.tsx`, then reuse them on every page. Copy-pasted page styling is how documents drift.
77
+
78
+ ## Step 6 — Write `docs/<id>/index.tsx`
79
+
80
+ Read **`doc-authoring`** first — file contract, canvas, type scale, headings/outline, TOC, page numbers, and a starter template are all there.
81
+
82
+ While writing:
83
+
84
+ - Real `<h1>/<h2>/<h3>` for every section title, so the outline and TOC populate.
85
+ - `<TableOfContents />` for the contents page. Never hand-write one.
86
+ - `useDocPageNumber()` / `useDocPageCount()` for the footer. Never hardcode.
87
+ - Put body content in one `flow(<>…</>, { footer: Footer })` section; mark captions `data-od-keep-with-previous`. Only run budget math for fixed pages.
88
+ - Where the user must supply data, leave `<ImagePlaceholder hint="…">` or an explicit `TODO:` in the copy — never invent numbers.
89
+
90
+ ## Step 7 — Self-review
91
+
92
+ **Run `mosage check <id>` first.** You cannot see the sheets you produced; it renders them at true page size and reports clipped content, blank pages, stranded headings, and unreadable type, each with a source location. Fix every error before moving on.
93
+
94
+ Then run the checklist in `doc-authoring` ("Self-review before finishing"), and re-read the prose once as a reader: does the summary state the conclusion? Does every claim have a source?
95
+
96
+ ## Step 8 — Hand off
97
+
98
+ Tell the user:
99
+
100
+ - The doc id and file path.
101
+ - That the dev server hot-reloads — open `http://localhost:5273/d/<id>` (or refresh the home page).
102
+ - **Every placeholder and `TODO:` you left**, and what data each one needs.
103
+ - That "Export PDF" in the toolbar prints at the true page size, and "HTML" downloads a self-contained copy — or `mosage export <id>` for the same files without a browser.
104
+ - That the **Design** button live-tweaks the palette and type scale and writes the result back to the source, and that images they want to drop in go through the **Assets** page.
105
+
106
+ Don't run the dev server yourself unless asked.
@@ -0,0 +1,184 @@
1
+ ---
2
+ name: create-theme
3
+ description: Use this skill when the user wants to create, draft, author, or extract a document theme in this MoSage repo — a reusable house style for reports, proposals, or memos. Triggers on phrases like "create a theme", "make a company template", "extract a theme from <doc>", "match our brand guidelines". Produces two paired files under `themes/` — `<id>.md` (palette, typography, page setup, paste-ready Title/Footer/Table components) and `<id>.demo.tsx` (a runnable two-page demo the Themes gallery previews). Do NOT use for editing real documents — only for authoring the theme bundle.
4
+ ---
5
+
6
+ # Create a document theme
7
+
8
+ A **theme bundle** under `themes/` is two paired files describing a reusable house style:
9
+
10
+ 1. `themes/<id>.md` — agent-facing documentation: palette, typography, page setup, paste-ready components. This is what `create-doc` reads when the author picks the theme.
11
+ 2. `themes/<id>.demo.tsx` — a runnable two-page mini-document (a normal document module: `export default DocPage[]`) that shows the theme in use. The Themes gallery renders it as the live preview.
12
+
13
+ Both files share the same stem so the runtime pairs them automatically.
14
+
15
+ A theme is **distinct from a document's `design` const**:
16
+
17
+ | | What it is | Who reads it |
18
+ | --- | --- | --- |
19
+ | `themes/<id>.md` | Authoring-time direction, copied into a real document | `create-doc`, you |
20
+ | `themes/<id>.demo.tsx` | A preview, not a real document (never appears in the documents list) | The Themes gallery |
21
+ | `export const design` in `docs/<id>/index.tsx` | Runtime tokens the Design panel can live-tweak and write back | The runtime |
22
+
23
+ You only write `themes/<id>.md` and `themes/<id>.demo.tsx`. Never modify real documents or config. Read the **`doc-authoring`** skill first — the page canvas, print type scale, and vertical budget it defines are what your overrides are stated against.
24
+
25
+ ## Step 1 — Identify the input source
26
+
27
+ A theme can come from any combination of:
28
+
29
+ - **Brand material** — a style guide PDF, brand colors, a letterhead, existing reports (paths or URLs).
30
+ - **Free-text description** — prose describing palette, fonts, and feel.
31
+ - **An existing document** — `docs/<id>/index.tsx` whose look should be lifted into a reusable theme.
32
+
33
+ If the user's message already names the inputs, proceed. Otherwise call `AskUserQuestion` (multi-select) and ask follow-ups (paths, doc id, prose) only as needed.
34
+
35
+ ## Step 2 — Gather raw inputs
36
+
37
+ - **Images / PDFs**: read each path with `Read` (it accepts images and PDFs). Note hex colors, heading/body faces and weights, margin rhythm, rule weights, table styling, and any recurring chrome (letterhead, footer rule, page-number position).
38
+ - **Text**: extract explicit tokens (hex codes, font names, "20mm margins") and implicit tone ("conservative", "editorial", "technical"). Resolve vague language into concrete numbers before writing.
39
+ - **Existing document**: read `docs/<id>/index.tsx` and pull the `design` const, the shared `page`/`h1`/`h2` style objects, the running `Footer`, table cell components, and the callout style.
40
+
41
+ When inputs disagree (brand deck says navy, the sample report is black), ask which wins.
42
+
43
+ ## Step 3 — Pick a theme id
44
+
45
+ **kebab-case**, short, descriptive: `acme-corporate`, `editorial-serif`, `technical-brief`, `board-memo`. Check `themes/` for collisions.
46
+
47
+ ## Step 4 — Write `themes/<id>.md`
48
+
49
+ Keep this exact section order; adapt the bodies.
50
+
51
+ ````markdown
52
+ ---
53
+ name: <Human title, e.g. "Acme Corporate">
54
+ description: <one-line elevator pitch>
55
+ pageSize: <A4 | B4 | A3>
56
+ mode: <light | dark — light for anything that prints>
57
+ ---
58
+
59
+ # <Theme name>
60
+
61
+ ## When to use
62
+
63
+ <Two sentences: which document types this fits, and which it doesn't.>
64
+
65
+ ## Palette
66
+
67
+ | Role | Value | Notes |
68
+ | ------ | --------- | --------------------------------------- |
69
+ | bg | `#ffffff` | sheet background — keep near-white |
70
+ | text | `#16181d` | body copy |
71
+ | muted | `#6b7280` | captions, footers, secondary cells |
72
+ | accent | `#1d4ed8` | section numbers, rules, chart series |
73
+ | rule | `#e5e7eb` | table borders, hairlines, dot leaders |
74
+
75
+ Extra colors outside the `DesignSystem` shape (status green/amber/red, chart series) go in a
76
+ "Supporting colors" list below the table.
77
+
78
+ ## Typography
79
+
80
+ - Heading font: `<stack>` — weight <n>.
81
+ - Body font: `<stack>` — weight 400.
82
+ - Mono font: `<stack>` — tables of code/IDs only.
83
+ - Webfont import (omit for system stacks): `<stylesheet URL>` — load per `references/design-system.md` in `doc-authoring`.
84
+ - Type scale (px at 96dpi): title <n> · h1 <n> · h2 <n> · h3 <n> · body <n> · caption <n>.
85
+
86
+ ## Page setup
87
+
88
+ - Page size: A4 portrait (794 × 1123 px).
89
+ - Margin: <n> px on all sides (<n> mm).
90
+ - Leading: <n>.
91
+ - Running footer: <what it shows, where it sits>.
92
+ - Cover: <centered / bottom-aligned, what it carries>.
93
+
94
+ ## Design const
95
+
96
+ Paste-ready — this is what a document using the theme declares:
97
+
98
+ ```tsx
99
+ export const design: DesignSystem = {
100
+ palette: { bg: '…', text: '…', muted: '…', accent: '…', rule: '…' },
101
+ fonts: { heading: '…', body: '…', mono: '…' },
102
+ typeScale: { title: 44, h1: 28, h2: 20, h3: 16, body: 14, caption: 10 },
103
+ margin: 76,
104
+ leading: 1.55,
105
+ radius: 6,
106
+ };
107
+ ```
108
+
109
+ ## Fixed components
110
+
111
+ Paste-ready. Copy verbatim into a document using this theme.
112
+
113
+ ### Page shell + headings
114
+
115
+ ```tsx
116
+ const page = { /* … */ } as const;
117
+ const h1 = { /* … */ } as const;
118
+ const h2 = { /* … */ } as const;
119
+ ```
120
+
121
+ ### Running footer
122
+
123
+ Read the page number from `useDocPageNumber()` / `useDocPageCount()` — never hardcode it.
124
+
125
+ ```tsx
126
+ const Footer = () => { /* … */ };
127
+ ```
128
+
129
+ ### Table
130
+
131
+ ```tsx
132
+ const Th = ({ children }: { children: React.ReactNode }) => /* … */;
133
+ const Td = ({ children }: { children: React.ReactNode }) => /* … */;
134
+ ```
135
+
136
+ Include a callout and a stat component when the theme calls for them.
137
+
138
+ ## Rules
139
+
140
+ - <3–6 bullets a document must follow to stay on-theme: what never appears, how sections are numbered, whether the cover carries a logo, table style, figure captions.>
141
+ ````
142
+
143
+ ## Step 5 — Write `themes/<id>.demo.tsx`
144
+
145
+ A normal document module — **two pages**: a cover and one content page that exercises the theme's headings, body copy, a table, and the running footer.
146
+
147
+ ```tsx
148
+ import { type DesignSystem, type DocPage, useDocPageCount, useDocPageNumber } from 'mosage';
149
+
150
+ export const design: DesignSystem = { /* the same const as in the .md */ };
151
+
152
+ const Cover: DocPage = () => ( /* … */ );
153
+ const Content: DocPage = () => ( /* … */ );
154
+
155
+ export default [Cover, Content] satisfies DocPage[];
156
+ ```
157
+
158
+ Rules for the demo:
159
+
160
+ - **No `meta` export** — the demo is not a real document and must not carry `createdAt` or a title that implies it is.
161
+ - Two pages, no more. The gallery renders the first; the theme detail page renders both.
162
+ - Use placeholder copy that shows the type scale honestly (a real heading, a real paragraph, a real 4-row table) — not lorem ipsum blocks that hide how the theme handles wrapping.
163
+ - Respect the vertical budget from `doc-authoring` → `references/pagination.md`. A demo that overflows teaches the wrong lesson.
164
+ - Keep it self-contained: no asset imports, no webfont the `.md` didn't declare.
165
+
166
+ ## Step 6 — Self-review
167
+
168
+ - [ ] Both files exist and share the same stem.
169
+ - [ ] Frontmatter has `name`, `description`, `pageSize`, `mode`.
170
+ - [ ] The `design` const in the `.md` and in the demo are identical.
171
+ - [ ] The palette background is white or near-white (see `references/design-system.md` — dark documents print badly).
172
+ - [ ] Body type ≥ 13px; caption ≥ 9px.
173
+ - [ ] The footer pulls page numbers from the hooks.
174
+ - [ ] Every "paste-ready" component actually compiles as written — no `…` left in the code blocks.
175
+ - [ ] The demo fits its pages.
176
+ - [ ] Nothing outside `themes/` was written.
177
+
178
+ ## Step 7 — Hand off
179
+
180
+ Tell the user:
181
+
182
+ - The theme id and both file paths.
183
+ - That it shows up under **Themes** in the dev UI (`http://localhost:5273/themes/<id>`).
184
+ - That new documents can adopt it by setting `meta.theme: '<id>'`, which adds the back-link chip — and that `create-doc` will now offer it as a choice.
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: current-doc
3
+ description: Resolve which document, page, and (optionally) selected element the user is currently viewing in the mosage dev server. Consult this whenever the user references "this page", "this document", "this element", "the page I'm on", "the report I'm looking at", or any deictic reference to document content without naming it. Re-read `node_modules/.mosage/current.json` at the start of every such turn — the user navigates between turns, so a value you read earlier in the conversation is almost certainly stale.
4
+ ---
5
+
6
+ # Where is the user right now?
7
+
8
+ When the user says "fix this page", "tighten this heading", or "the report I'm looking at", they almost never name the document id, page number, or element — they mean wherever they are in the dev viewer. Before asking "which document?" or "which element?", check the file the dev server writes on every navigation and inspector pick.
9
+
10
+ ## Re-read on every deictic turn — never reuse a prior read
11
+
12
+ `current.json` is a live cursor, not a fact about the conversation. The user moves between documents, pages, and elements freely between your turns — including while you were doing other work. **Read the file fresh at the start of every new turn that uses a deictic reference**, even if:
13
+
14
+ - you already read it earlier in this same conversation,
15
+ - you just finished editing the document it pointed to,
16
+ - the user's new message sounds like a continuation ("now make it bigger", "also fix this one", "keep going").
17
+
18
+ A "continue editing" follow-up is exactly the case where the user has likely just scrolled to a different page or picked a different element. Trusting your last read here will silently edit the wrong sheet. Re-read, compare `docId` / `pageIndex` / `selection` against what you used last time, and act on the new values.
19
+
20
+ ## How to read it
21
+
22
+ ```
23
+ node_modules/.mosage/current.json
24
+ ```
25
+
26
+ Path is relative to the project root (the user's `cwd`, the directory that contains `docs/` and `package.json`). Use the `Read` tool. The file is JSON.
27
+
28
+ ## What you get
29
+
30
+ ```json
31
+ {
32
+ "docId": "q3-review",
33
+ "pageIndex": 2,
34
+ "pageNumber": 3,
35
+ "totalPages": 8,
36
+ "docTitle": "Q3 Review",
37
+ "pagePath": "docs/q3-review/index.tsx",
38
+ "selection": {
39
+ "line": 42,
40
+ "column": 6,
41
+ "tagName": "h2",
42
+ "text": "Availability"
43
+ },
44
+ "updatedAt": "2026-08-17T14:32:11.123Z"
45
+ }
46
+ ```
47
+
48
+ - `docId` — folder name under `docs/`. Use as-is for any `/__docs/<id>/...` API or as the URL segment (`/d/<docId>`).
49
+ - `pageIndex` — 0-based **rendered** page index.
50
+ - `pageNumber` — 1-based, for talking to the user ("page 3 of 8").
51
+ - `totalPages` — how many sheets the document currently renders to.
52
+ - `pagePath` — relative path to the document source. Hand straight to `Read` / `Edit`.
53
+ - `selection` — `null` if nothing is selected. Otherwise, the JSX element the user picked in the inspector overlay:
54
+ - `line` (1-indexed) and `column` (0-indexed) point to the JSX opening tag inside `pagePath`. This is the canonical handle — match against the source line, not the rendered DOM.
55
+ - `tagName` is the rendered DOM tag, lowercased (`"h1"`, `"p"`, `"td"`).
56
+ - `text` is a trimmed snippet (≤120 chars) of the element's `textContent`, useful to confirm you are looking at the right node.
57
+ - Selection auto-clears whenever the user moves to a different document or page.
58
+ - `updatedAt` — ISO timestamp of the last navigation or selection change. Use it to detect staleness.
59
+
60
+ ## Rendered pages are not entries in the default export
61
+
62
+ This is the one thing that differs from a slide deck, and getting it wrong means editing the wrong thing.
63
+
64
+ `export default [Cover, Contents, flow(<>…</>)]` has three *entries*, but may render to twelve *sheets* — the framework measures a `flow()` section and packs it across as many pages as it needs. So:
65
+
66
+ - **`pageIndex` indexes rendered sheets, not the array.** Do not use it to subscript the default export.
67
+ - To find what to edit, prefer `selection` (it points at real source coordinates), then the page's visible text, then the surrounding heading.
68
+ - If the user is on a flow page and there is no selection, identify the content by what they can see — read the source and match the prose — rather than counting array entries.
69
+ - A fixed `DocPage` component *is* one sheet, so for documents made only of fixed pages the index does line up. Confirm with `pagePath` before relying on that.
70
+
71
+ ## When to use this
72
+
73
+ - The user references the current document/page deictically: "this", "here", "the page I'm on", "what I'm looking at".
74
+ - The user references a specific element: "this heading", "this table", "tighten this", "make this smaller". If `selection` is non-null, that's the element they mean.
75
+ - Before asking "which document?" or "which page?" as a clarifying question — check this file first.
76
+ - Before guessing from `git log`, recently-edited files, or the newest folder under `docs/`.
77
+
78
+ ## When NOT to use this
79
+
80
+ - The user names a document explicitly ("edit `q3-review`") — use that name directly.
81
+ - The `apply-comments` workflow already finds its own targets via `@doc-comment` markers; it does not need this skill.
82
+ - For listing or discovering documents — read `docs/` directly.
83
+
84
+ ## Staleness — verify before acting
85
+
86
+ `updatedAt` is the last time the user navigated. Treat it like a cache:
87
+
88
+ - **Fresh (under ~5 minutes old)**: trust it. Open `pagePath`, do the work.
89
+ - **Older than ~5 minutes**: confirm with the user before editing. The dev server may not be running; the user may have switched contexts.
90
+ - **Hours/days old**: ignore it. Ask which document they mean.
91
+
92
+ A *newer* `updatedAt` than the one you saw last turn is the normal signal that the user has moved — switch to the new `docId` / `pageIndex` / `selection` without asking.
93
+
94
+ ## When the file is missing
95
+
96
+ - The dev server has not been opened on a document yet, or has never run. A static build never writes it.
97
+ - Don't create the file or guess. Ask which document they mean, or suggest they open it in the dev server first.
98
+
99
+ ## Example — page-level reference
100
+
101
+ User: "tighten the spacing on this page"
102
+
103
+ 1. Read `node_modules/.mosage/current.json`.
104
+ 2. Check `updatedAt` is recent.
105
+ 3. Read `pagePath` (e.g. `docs/q3-review/index.tsx`).
106
+ 4. Work out what is on `pageNumber` — by the selection, or by matching visible content, remembering that a flow section spans many sheets.
107
+ 5. Consult the `doc-authoring` skill for the spacing and vertical-budget rules, then edit in place.
108
+
109
+ If `current.json` is missing or stale, ask: "Which document and page should I tighten? The dev server hasn't published a current page recently."
110
+
111
+ ## Example — element-level reference
112
+
113
+ User: "make this bigger"
114
+
115
+ 1. Read `node_modules/.mosage/current.json`.
116
+ 2. If `selection` is non-null, that is the element. Read `pagePath`, jump to `selection.line`, and find the JSX opening tag near that line/column. Confirm against `selection.text` and `tagName`.
117
+ 3. Consult `doc-authoring` for the print type scale before editing — a size that looks fine on screen can print below the legibility floor.
118
+ 4. Edit the JSX node in place.
119
+
120
+ If `selection` is null, fall back to the page-level flow above — and consider asking "which element?", since the user used a deictic but hasn't picked one in the inspector.