@lapis-notes/lapis-plugin-docs 0.0.0-stage → 0.1.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 (196) hide show
  1. package/README.md +188 -2
  2. package/dist/docs/DocsBlockMarkdownEditor.svelte +37 -0
  3. package/dist/docs/DocsBlockMarkdownEditor.svelte.d.ts +13 -0
  4. package/dist/docs/DocsBlockRefPicker.svelte +75 -0
  5. package/dist/docs/DocsBlockRefPicker.svelte.d.ts +11 -0
  6. package/dist/docs/DocsBookEditor.svelte +141 -0
  7. package/dist/docs/DocsBookEditor.svelte.d.ts +10 -0
  8. package/dist/docs/DocsBookNavigation.svelte +838 -0
  9. package/dist/docs/DocsBookNavigation.svelte.d.ts +11 -0
  10. package/dist/docs/DocsBooksColumn.svelte +82 -0
  11. package/dist/docs/DocsBooksColumn.svelte.d.ts +10 -0
  12. package/dist/docs/DocsCardBackMatter.svelte +32 -0
  13. package/dist/docs/DocsCardBackMatter.svelte.d.ts +10 -0
  14. package/dist/docs/DocsCardBlockExtra.svelte +43 -0
  15. package/dist/docs/DocsCardBlockExtra.svelte.d.ts +9 -0
  16. package/dist/docs/DocsCardPreviewFlip.svelte +143 -0
  17. package/dist/docs/DocsCardPreviewFlip.svelte.d.ts +17 -0
  18. package/dist/docs/DocsCardPreviewStack.svelte +135 -0
  19. package/dist/docs/DocsCardPreviewStack.svelte.d.ts +13 -0
  20. package/dist/docs/DocsCardPrompt.svelte +33 -0
  21. package/dist/docs/DocsCardPrompt.svelte.d.ts +8 -0
  22. package/dist/docs/DocsCardReviewAnswer.svelte +45 -0
  23. package/dist/docs/DocsCardReviewAnswer.svelte.d.ts +8 -0
  24. package/dist/docs/DocsCardTagChips.svelte +19 -0
  25. package/dist/docs/DocsCardTagChips.svelte.d.ts +7 -0
  26. package/dist/docs/DocsCardsPanel.svelte +232 -0
  27. package/dist/docs/DocsCardsPanel.svelte.d.ts +17 -0
  28. package/dist/docs/DocsCardsReview.css +1050 -0
  29. package/dist/docs/DocsChapterFooter.svelte +248 -0
  30. package/dist/docs/DocsChapterFooter.svelte.d.ts +11 -0
  31. package/dist/docs/DocsChapterScrollRing.svelte +101 -0
  32. package/dist/docs/DocsChapterScrollRing.svelte.d.ts +6 -0
  33. package/dist/docs/DocsDisplayPanel.css +627 -0
  34. package/dist/docs/DocsDisplayPanel.svelte +78 -0
  35. package/dist/docs/DocsDisplayPanel.svelte.d.ts +16 -0
  36. package/dist/docs/DocsEditorPanel.css +325 -0
  37. package/dist/docs/DocsEditorPanel.svelte +570 -0
  38. package/dist/docs/DocsEditorPanel.svelte.d.ts +22 -0
  39. package/dist/docs/DocsFlipCard.svelte +68 -0
  40. package/dist/docs/DocsFlipCard.svelte.d.ts +8 -0
  41. package/dist/docs/DocsFolderDirectoryList.svelte +206 -0
  42. package/dist/docs/DocsFolderDirectoryList.svelte.d.ts +14 -0
  43. package/dist/docs/DocsFolderPanel.css +357 -0
  44. package/dist/docs/DocsFolderPanel.svelte +102 -0
  45. package/dist/docs/DocsFolderPanel.svelte.d.ts +17 -0
  46. package/dist/docs/DocsLinksPanel.css +61 -0
  47. package/dist/docs/DocsLinksPanel.svelte +55 -0
  48. package/dist/docs/DocsLinksPanel.svelte.d.ts +11 -0
  49. package/dist/docs/DocsMarkdownField.svelte +93 -0
  50. package/dist/docs/DocsMarkdownField.svelte.d.ts +11 -0
  51. package/dist/docs/DocsMarkdownPreview.svelte +278 -0
  52. package/dist/docs/DocsMarkdownPreview.svelte.d.ts +17 -0
  53. package/dist/docs/DocsReviewPanel.svelte +63 -0
  54. package/dist/docs/DocsReviewPanel.svelte.d.ts +11 -0
  55. package/dist/docs/DocsRichBlock.svelte +291 -0
  56. package/dist/docs/DocsRichBlock.svelte.d.ts +13 -0
  57. package/dist/docs/DocsRichDisplay.svelte +316 -0
  58. package/dist/docs/DocsRichDisplay.svelte.d.ts +14 -0
  59. package/dist/docs/DocsSlidesPreview.css +243 -0
  60. package/dist/docs/DocsSlidesPreview.svelte +206 -0
  61. package/dist/docs/DocsSlidesPreview.svelte.d.ts +10 -0
  62. package/dist/docs/DocsWorkspace.css +570 -0
  63. package/dist/docs/DocsWorkspace.svelte +831 -0
  64. package/dist/docs/DocsWorkspace.svelte.d.ts +48 -0
  65. package/dist/docs/DocsWorkspaceToolbar.svelte +211 -0
  66. package/dist/docs/DocsWorkspaceToolbar.svelte.d.ts +27 -0
  67. package/dist/docs/candidates/ChoiceMenu.svelte +114 -0
  68. package/dist/docs/candidates/ChoiceMenu.svelte.d.ts +10 -0
  69. package/dist/docs/candidates/FlipCardDeck.svelte +800 -0
  70. package/dist/docs/candidates/FlipCardDeck.svelte.d.ts +36 -0
  71. package/dist/docs/candidates/MarkdownFloatingToc.svelte +313 -0
  72. package/dist/docs/candidates/MarkdownFloatingToc.svelte.d.ts +14 -0
  73. package/dist/docs/candidates/SearchableChoicePicker.css +161 -0
  74. package/dist/docs/candidates/SearchableChoicePicker.svelte +208 -0
  75. package/dist/docs/candidates/SearchableChoicePicker.svelte.d.ts +19 -0
  76. package/dist/docs/candidates/StructuredTable.svelte +98 -0
  77. package/dist/docs/candidates/StructuredTable.svelte.d.ts +8 -0
  78. package/dist/docs/candidates/StructuredTableEditor.svelte +374 -0
  79. package/dist/docs/candidates/StructuredTableEditor.svelte.d.ts +12 -0
  80. package/dist/docs/candidates/TagEditor.svelte +31 -0
  81. package/dist/docs/candidates/TagEditor.svelte.d.ts +14 -0
  82. package/dist/docs/candidates/WorkspaceHistoryControls.svelte +112 -0
  83. package/dist/docs/candidates/WorkspaceHistoryControls.svelte.d.ts +8 -0
  84. package/dist/docs/candidates/markdown-floating-toc.css +151 -0
  85. package/dist/docs/candidates/markdown-floating-toc.d.ts +1 -0
  86. package/dist/docs/candidates/markdown-floating-toc.js +1 -0
  87. package/dist/docs/docs-anki-import.d.ts +34 -0
  88. package/dist/docs/docs-anki-import.js +516 -0
  89. package/dist/docs/docs-book-view-model.d.ts +9 -0
  90. package/dist/docs/docs-book-view-model.js +71 -0
  91. package/dist/docs/docs-card-answer-markdown.d.ts +1 -0
  92. package/dist/docs/docs-card-answer-markdown.js +63 -0
  93. package/dist/docs/docs-card-display.d.ts +10 -0
  94. package/dist/docs/docs-card-display.js +18 -0
  95. package/dist/docs/docs-display-focus.d.ts +7 -0
  96. package/dist/docs/docs-display-focus.js +42 -0
  97. package/dist/docs/docs-document-surface.d.ts +7 -0
  98. package/dist/docs/docs-document-surface.js +25 -0
  99. package/dist/docs/docs-folder-directory.d.ts +21 -0
  100. package/dist/docs/docs-folder-directory.js +56 -0
  101. package/dist/docs/docs-link-mode.d.ts +16 -0
  102. package/dist/docs/docs-link-mode.js +94 -0
  103. package/dist/docs/docs-workspace-helpers.d.ts +25 -0
  104. package/dist/docs/docs-workspace-helpers.js +195 -0
  105. package/dist/docs/docs.tokens.css +13 -0
  106. package/dist/docs/import-anki-package.d.ts +10 -0
  107. package/dist/docs/import-anki-package.js +30 -0
  108. package/dist/docs/lapis-markdown-extensions.d.ts +9 -0
  109. package/dist/docs/lapis-markdown-extensions.js +128 -0
  110. package/dist/docs/pin-reading-chrome.d.ts +4 -0
  111. package/dist/docs/pin-reading-chrome.js +32 -0
  112. package/dist/docs/sidebar/DocsFoldersSidebar.svelte +134 -0
  113. package/dist/docs/sidebar/DocsFoldersSidebar.svelte.d.ts +15 -0
  114. package/dist/docs/sidebar/DocsLinksSidebar.svelte +105 -0
  115. package/dist/docs/sidebar/DocsLinksSidebar.svelte.d.ts +11 -0
  116. package/dist/docs/sidebar/DocsSidebar.css +346 -0
  117. package/dist/docs/sidebar/DocsSidebar.svelte +430 -0
  118. package/dist/docs/sidebar/DocsSidebar.svelte.d.ts +18 -0
  119. package/dist/docs/sidebar/DocsSidebarHost.svelte +139 -0
  120. package/dist/docs/sidebar/DocsSidebarHost.svelte.d.ts +12 -0
  121. package/dist/docs/sidebar/DocsTagsSidebar.svelte +176 -0
  122. package/dist/docs/sidebar/DocsTagsSidebar.svelte.d.ts +12 -0
  123. package/dist/docs/sidebar/docs-book-note-tree.d.ts +23 -0
  124. package/dist/docs/sidebar/docs-book-note-tree.js +88 -0
  125. package/dist/docs/sidebar/docs-note-sort.d.ts +26 -0
  126. package/dist/docs/sidebar/docs-note-sort.js +54 -0
  127. package/dist/docs/sidebar/docs-sidebar-filters.d.ts +17 -0
  128. package/dist/docs/sidebar/docs-sidebar-filters.js +74 -0
  129. package/dist/docs/sidebar/docs-sidebar-ui-storage.d.ts +24 -0
  130. package/dist/docs/sidebar/docs-sidebar-ui-storage.js +87 -0
  131. package/dist/docs/sidebar/docs-source-folder-tree.d.ts +16 -0
  132. package/dist/docs/sidebar/docs-source-folder-tree.js +143 -0
  133. package/dist/docs/sidebar/docs-tag-tree.d.ts +17 -0
  134. package/dist/docs/sidebar/docs-tag-tree.js +84 -0
  135. package/dist/docs-cards-view.d.ts +18 -0
  136. package/dist/docs-cards-view.js +52 -0
  137. package/dist/docs-document-view.d.ts +24 -0
  138. package/dist/docs-document-view.js +127 -0
  139. package/dist/docs-document-workspace.svelte +215 -0
  140. package/dist/docs-document-workspace.svelte.d.ts +16 -0
  141. package/dist/docs-index.d.ts +5 -0
  142. package/dist/docs-index.js +49 -0
  143. package/dist/docs-path.d.ts +6 -0
  144. package/dist/docs-path.js +10 -0
  145. package/dist/docs-plugin.d.ts +21 -0
  146. package/dist/docs-plugin.js +140 -0
  147. package/dist/docs-repository.d.ts +15 -0
  148. package/dist/docs-repository.js +75 -0
  149. package/dist/docs-review-view.d.ts +18 -0
  150. package/dist/docs-review-view.js +52 -0
  151. package/dist/docs-settings-tab.d.ts +8 -0
  152. package/dist/docs-settings-tab.js +25 -0
  153. package/dist/docs-settings.d.ts +17 -0
  154. package/dist/docs-settings.js +38 -0
  155. package/dist/docs-view.d.ts +22 -0
  156. package/dist/docs-view.js +51 -0
  157. package/dist/docs-workspace.svelte +394 -0
  158. package/dist/docs-workspace.svelte.d.ts +15 -0
  159. package/dist/index.d.ts +12 -0
  160. package/dist/index.js +12 -0
  161. package/dist/model/book.d.ts +6 -0
  162. package/dist/model/book.js +101 -0
  163. package/dist/model/coding-runtime.d.ts +4 -0
  164. package/dist/model/coding-runtime.js +9 -0
  165. package/dist/model/docs-card-context.d.ts +32 -0
  166. package/dist/model/docs-card-context.js +89 -0
  167. package/dist/model/docs-card-preview-stack-motion.d.ts +51 -0
  168. package/dist/model/docs-card-preview-stack-motion.js +94 -0
  169. package/dist/model/docs-media-context.d.ts +9 -0
  170. package/dist/model/docs-media-context.js +18 -0
  171. package/dist/model/docs-note-list.d.ts +8 -0
  172. package/dist/model/docs-note-list.js +25 -0
  173. package/dist/model/docs-relative-media.d.ts +30 -0
  174. package/dist/model/docs-relative-media.js +116 -0
  175. package/dist/model/docs-review-constants.d.ts +4 -0
  176. package/dist/model/docs-review-constants.js +13 -0
  177. package/dist/model/fsrs.d.ts +14 -0
  178. package/dist/model/fsrs.js +153 -0
  179. package/dist/model/graph.d.ts +12 -0
  180. package/dist/model/graph.js +169 -0
  181. package/dist/model/index.d.ts +14 -0
  182. package/dist/model/index.js +14 -0
  183. package/dist/model/markdown-normalize.d.ts +11 -0
  184. package/dist/model/markdown-normalize.js +755 -0
  185. package/dist/model/markdown.d.ts +167 -0
  186. package/dist/model/markdown.js +365 -0
  187. package/dist/model/sample.d.ts +7 -0
  188. package/dist/model/sample.js +524 -0
  189. package/dist/model/types.d.ts +328 -0
  190. package/dist/model/types.js +1 -0
  191. package/dist/model/workspace.d.ts +6 -0
  192. package/dist/model/workspace.js +81 -0
  193. package/dist/storybook.css +52 -0
  194. package/dist/styles.css +1 -0
  195. package/manifest.json +11 -0
  196. package/package.json +147 -4
@@ -0,0 +1,524 @@
1
+ const SAMPLE_CREATED_AT = "2026-07-01T09:00:00.000Z";
2
+ const SAMPLE_UPDATED_AT = "2026-07-01T09:30:00.000Z";
3
+ export const SAMPLE_DOCS_BOOK_FOLDER = "sample-docs";
4
+ export const SAMPLE_DOCS_BOOK_INDEX_ID = "sample-docs-index";
5
+ export const SAMPLE_DOCS_BOOK_TAG = `books/${SAMPLE_DOCS_BOOK_FOLDER}`;
6
+ export const SAMPLE_DOCS_NOTE_IDS = [
7
+ "sample-docs-schema-harness",
8
+ "sample-docs-coding-drill",
9
+ "sample-docs-system-design",
10
+ "sample-docs-story-bank",
11
+ "sample-docs-freeform",
12
+ "sample-docs-index",
13
+ ];
14
+ export const SAMPLE_DOCS_CHAPTER_IDS = [
15
+ "sample-docs-schema-harness",
16
+ "sample-docs-coding-drill",
17
+ "sample-docs-system-design",
18
+ "sample-docs-story-bank",
19
+ "sample-docs-freeform",
20
+ ];
21
+ function sourcePath(id) {
22
+ const filename = id === SAMPLE_DOCS_BOOK_INDEX_ID ? "index.doc.md" : `${id}.doc.md`;
23
+ return `docs/${SAMPLE_DOCS_BOOK_FOLDER}/${filename}`;
24
+ }
25
+ function reviewLog(cardId, index, rating, reviewedAt, due, state = "Review") {
26
+ return {
27
+ id: `${cardId}-review-${index}`,
28
+ rating,
29
+ reviewedAt,
30
+ state,
31
+ due,
32
+ stability: 2 + index * 1.5,
33
+ difficulty: 5.5 - index * 0.35,
34
+ elapsedDays: index,
35
+ scheduledDays: Math.max(1, index * 2),
36
+ learningSteps: 0,
37
+ };
38
+ }
39
+ function reviewedCard(card, options) {
40
+ return {
41
+ ...card,
42
+ fsrs: {
43
+ due: options.due,
44
+ stability: 4.2,
45
+ difficulty: 4.8,
46
+ elapsedDays: 2,
47
+ scheduledDays: 2,
48
+ learningSteps: 0,
49
+ reps: options.reviews.length,
50
+ lapses: options.reviews.filter((review) => review.rating === "again")
51
+ .length,
52
+ state: options.state ?? "Review",
53
+ lastReview: options.lastReview,
54
+ },
55
+ reviews: options.reviews,
56
+ };
57
+ }
58
+ function freshCard(card) {
59
+ return {
60
+ ...card,
61
+ fsrs: {
62
+ due: SAMPLE_UPDATED_AT,
63
+ stability: 0,
64
+ difficulty: 0,
65
+ elapsedDays: 0,
66
+ scheduledDays: 0,
67
+ learningSteps: 0,
68
+ reps: 0,
69
+ lapses: 0,
70
+ state: "New",
71
+ },
72
+ reviews: [],
73
+ };
74
+ }
75
+ function note(input) {
76
+ return {
77
+ ...input,
78
+ createdAt: SAMPLE_CREATED_AT,
79
+ updatedAt: SAMPLE_UPDATED_AT,
80
+ sourcePath: sourcePath(input.id),
81
+ };
82
+ }
83
+ const schemaHarnessBlocks = [
84
+ {
85
+ id: "text-overview",
86
+ type: "text",
87
+ title: "Overview",
88
+ body: "Use this note to exercise every structured docs block, Mermaid rendering, every card metadata field, wiki links, tags, and rendered display modes.",
89
+ },
90
+ {
91
+ id: "markdown-chapter-section",
92
+ type: "markdown",
93
+ title: "Markdown chapter section",
94
+ body: [
95
+ "Use **Markdown** blocks for longer chapter prose with Carta Write/Preview editing.",
96
+ "",
97
+ "- Lists and wiki links like [[sample-docs-index]] work here.",
98
+ "- Untitled markdown continuations render without a stub heading.",
99
+ "",
100
+ "```ts",
101
+ "const ready = true;",
102
+ "```",
103
+ ].join("\n"),
104
+ },
105
+ {
106
+ id: "concept-desirable-difficulty",
107
+ type: "concept",
108
+ title: "Desirable difficulty",
109
+ summary: "Revision should feel effortful enough to force retrieval without becoming noise.",
110
+ keyPoints: [
111
+ "Prompt before rereading.",
112
+ "Mix near-miss examples.",
113
+ "Review the weakest block first.",
114
+ ],
115
+ details: "The harness links cards to block ids so a reminder can point back to the exact concept, drill, story, or resource that created it.",
116
+ },
117
+ {
118
+ id: "procedure-review-loop",
119
+ type: "procedure",
120
+ title: "Review loop",
121
+ steps: [
122
+ "Open the due card.",
123
+ "Answer from memory.",
124
+ "Compare against the block summary.",
125
+ "Rate the card and update the next review.",
126
+ ],
127
+ notes: "This procedure is intentionally short so the rendered markdown and slide modes are easy to inspect.",
128
+ },
129
+ {
130
+ id: "prompt-cache-invalidation",
131
+ type: "prompt",
132
+ title: "Cache invalidation prompt",
133
+ problem: "Design a cache invalidation strategy for user profile updates served by multiple regional API workers.",
134
+ requirements: [
135
+ "Keep stale profile reads below one minute.",
136
+ "Handle regional partition recovery.",
137
+ "Expose observable invalidation lag.",
138
+ ],
139
+ approach: "Use versioned profile records, publish invalidation events, and fall back to version checks on hot reads.",
140
+ traps: [
141
+ "Relying only on TTL.",
142
+ "Invalidating by broad tenant prefix.",
143
+ "Ignoring replay after a queue outage.",
144
+ ],
145
+ tests: [
146
+ "Profile update reaches all regions.",
147
+ "Duplicate invalidation events are harmless.",
148
+ "A missed event is repaired by version comparison.",
149
+ ],
150
+ answer: "Make writes authoritative, propagate invalidations asynchronously, and keep the read path able to detect stale versions.",
151
+ },
152
+ {
153
+ id: "code-fsrs-helper",
154
+ type: "code",
155
+ title: "FSRS helper",
156
+ language: "ts",
157
+ caption: "A small deterministic card-state shape for fixture tests.",
158
+ code: [
159
+ "const state = {",
160
+ " due: '2026-07-02T09:00:00.000Z',",
161
+ " state: 'Review',",
162
+ " reps: 2",
163
+ "};",
164
+ ].join("\n"),
165
+ },
166
+ {
167
+ id: "code-mermaid-review-pipeline",
168
+ type: "code",
169
+ title: "Review pipeline diagram",
170
+ language: "mermaid",
171
+ caption: "A comprehensive Mermaid flowchart covering subgraphs, decisions, and labeled edges for display rendering.",
172
+ code: [
173
+ "flowchart TB",
174
+ " %% Docs revision and review pipeline fixture",
175
+ " classDef entry fill:#dbeafe,stroke:#2563eb,color:#0f172a",
176
+ " classDef decision fill:#fef3c7,stroke:#d97706,color:#0f172a",
177
+ " classDef process fill:#ecfdf5,stroke:#059669,color:#0f172a",
178
+ " classDef storage fill:#f3e8ff,stroke:#7c3aed,color:#0f172a",
179
+ " classDef terminal fill:#fee2e2,stroke:#dc2626,color:#0f172a",
180
+ "",
181
+ ' subgraph Authoring["Authoring surface"]',
182
+ " direction TB",
183
+ " A([Open note]):::entry --> B[Edit structured blocks]",
184
+ " B --> C[Attach cards and block refs]",
185
+ " C --> D{Valid schema?}",
186
+ " end",
187
+ "",
188
+ " D -->|No| E[Show validation errors]:::terminal",
189
+ " E --> B",
190
+ " D -->|Yes| F[Autosave note markdown]:::process",
191
+ "",
192
+ ' subgraph Rendering["Display rendering"]',
193
+ " direction LR",
194
+ " F --> G[Document markdown]",
195
+ " F --> H[Slide markdown]",
196
+ " F --> I[Mermaid diagrams]",
197
+ " G --> J[(Rendered preview)]:::storage",
198
+ " H --> J",
199
+ " I --> J",
200
+ " end",
201
+ "",
202
+ ' subgraph Review["Spaced review loop"]',
203
+ " direction TB",
204
+ " J --> K[Build due queue]",
205
+ " K --> L{Card due?}",
206
+ " L -->|No| M([Idle]):::terminal",
207
+ " L -->|Yes| N[Prompt from memory]:::process",
208
+ " N --> O[Reveal answer]",
209
+ " O --> P{Rate recall}",
210
+ " P -->|Again| Q[Reset interval]",
211
+ " P -->|Hard| R[Shorten interval]",
212
+ " P -->|Good| S[Advance interval]",
213
+ " P -->|Easy| T[Stretch interval]",
214
+ " Q --> U[(FSRS state)]:::storage",
215
+ " R --> U",
216
+ " S --> U",
217
+ " T --> U",
218
+ " U --> K",
219
+ " end",
220
+ "",
221
+ ' subgraph Recovery["Cache invalidation recovery"]',
222
+ " direction TB",
223
+ " V[Profile write]:::process --> W[Publish invalidation event]",
224
+ " W --> X{Event delivered?}",
225
+ " X -->|Yes| Y[Evict regional cache]",
226
+ " X -->|No| Z[Version check on read]:::decision",
227
+ " Z --> AA{Stale version?}",
228
+ " AA -->|Yes| Y",
229
+ " AA -->|No| AB([Serve cached profile]):::terminal",
230
+ " Y --> AC([Serve fresh profile]):::entry",
231
+ " end",
232
+ "",
233
+ " U -. informs .-> V",
234
+ " C -. links cards to blocks .-> N",
235
+ ].join("\n"),
236
+ },
237
+ {
238
+ id: "table-fields",
239
+ type: "table",
240
+ title: "Schema coverage",
241
+ columns: ["Area", "Fields exercised"],
242
+ rows: [
243
+ ["Note", "docType, summary, learningGoal, aliases, tags, body"],
244
+ [
245
+ "Block",
246
+ "text, concept, procedure, prompt, code, mermaid code, table, callout, story, resources",
247
+ ],
248
+ ["Card", "type, status, blockRefs, fsrs, reviews"],
249
+ ],
250
+ },
251
+ {
252
+ id: "callout-critical",
253
+ type: "callout",
254
+ title: "Harness reset",
255
+ tone: "critical",
256
+ body: "Seeding sample docs overwrites the bundled sample note ids with fixed fixture data.",
257
+ },
258
+ {
259
+ id: "story-star-example",
260
+ type: "story",
261
+ title: "Structured STAR story",
262
+ useFor: ["behavioral interview", "leadership", "ambiguity"],
263
+ situation: "A release had scattered ownership and unclear regression risk.",
264
+ task: "Create a repeatable readiness process without slowing the team.",
265
+ action: "Grouped risks by user path, added release checklists, and made owners annotate evidence before signoff.",
266
+ result: "The team caught two blocking regressions before release and reused the checklist later.",
267
+ metrics: ["2 regressions caught", "1 checklist reused across 3 releases"],
268
+ },
269
+ {
270
+ id: "resources-follow-up",
271
+ type: "resources",
272
+ title: "Follow-up resources",
273
+ items: [
274
+ {
275
+ title: "Marp Markdown",
276
+ url: "https://marp.app/",
277
+ kind: "slides",
278
+ notes: "Use the Display panel's slide mode output.",
279
+ },
280
+ {
281
+ title: "FSRS",
282
+ url: "https://github.com/open-spaced-repetition/fsrs4anki",
283
+ kind: "scheduling",
284
+ notes: "Review scheduling model used by the cards.",
285
+ },
286
+ ],
287
+ },
288
+ ];
289
+ function schemaHarnessNote() {
290
+ return note({
291
+ id: "sample-docs-schema-harness",
292
+ title: "Sample docs schema harness",
293
+ docType: "revision",
294
+ summary: "A deterministic note that covers every structured docs field and card review state.",
295
+ learningGoal: "Confirm structured editing, rendered markdown, Mermaid diagrams, slide output, search, links, cards, and review queues.",
296
+ aliases: ["Docs Harness", "Revision Fixture"],
297
+ tags: [
298
+ SAMPLE_DOCS_BOOK_TAG,
299
+ "sample",
300
+ "sample/docs/schema-harness",
301
+ "revision",
302
+ "learning/revision/fsrs",
303
+ "fsrs",
304
+ ],
305
+ bookId: SAMPLE_DOCS_BOOK_INDEX_ID,
306
+ blocks: schemaHarnessBlocks,
307
+ cards: [
308
+ reviewedCard({
309
+ id: "card-desirable-difficulty",
310
+ type: "basic",
311
+ status: "active",
312
+ prompt: "What makes a revision prompt a desirable difficulty?",
313
+ answer: "It forces retrieval with enough friction to expose weak memory without adding irrelevant noise.",
314
+ tags: ["sample", "learning/revision/memory", "memory"],
315
+ blockRefs: ["concept-desirable-difficulty"],
316
+ }, {
317
+ due: "2026-07-02T09:00:00.000Z",
318
+ lastReview: "2026-07-01T09:00:00.000Z",
319
+ reviews: [
320
+ reviewLog("card-desirable-difficulty", 1, "good", "2026-06-30T09:00:00.000Z", "2026-07-01T09:00:00.000Z", "Learning"),
321
+ reviewLog("card-desirable-difficulty", 2, "hard", "2026-07-01T09:00:00.000Z", "2026-07-02T09:00:00.000Z"),
322
+ ],
323
+ }),
324
+ reviewedCard({
325
+ id: "card-cache-invalidation-cloze",
326
+ type: "cloze",
327
+ status: "active",
328
+ prompt: "{{c1::Version checks}} repair missed cache invalidation events after queue recovery.",
329
+ answer: "Version checks let readers detect stale cached records even when an invalidation event was missed.",
330
+ tags: ["sample", "systems/cache/invalidation", "systems"],
331
+ blockRefs: ["prompt-cache-invalidation", "code-fsrs-helper"],
332
+ }, {
333
+ due: "2026-07-05T09:00:00.000Z",
334
+ lastReview: "2026-07-01T09:10:00.000Z",
335
+ reviews: [
336
+ reviewLog("card-cache-invalidation-cloze", 1, "easy", "2026-07-01T09:10:00.000Z", "2026-07-05T09:00:00.000Z"),
337
+ ],
338
+ }),
339
+ freshCard({
340
+ id: "card-suspended-harness",
341
+ type: "basic",
342
+ status: "suspended",
343
+ prompt: "Which sample card should stay out of the review queue?",
344
+ answer: "The suspended harness card.",
345
+ tags: ["sample", "learning/revision/suspended", "suspended"],
346
+ blockRefs: ["callout-critical"],
347
+ }),
348
+ ],
349
+ body: [
350
+ "This body tests freeform markdown after structured blocks.",
351
+ "",
352
+ "Related fixtures: [[sample-docs-coding-drill]] (metadata-only) and [[sample-docs-system-design]].",
353
+ "",
354
+ "#sample-body",
355
+ ].join("\n"),
356
+ });
357
+ }
358
+ function compactNote(id, docType, title, block, card, extraTags = []) {
359
+ return note({
360
+ id,
361
+ title,
362
+ docType,
363
+ summary: `${title} fixture for docs ${docType} rendering.`,
364
+ learningGoal: `Exercise the ${docType} document type in filters, metadata, and display output.`,
365
+ aliases: [title.replace(/^Sample docs /, "")],
366
+ tags: [
367
+ SAMPLE_DOCS_BOOK_TAG,
368
+ "sample",
369
+ `sample/docs/${docType}`,
370
+ docType,
371
+ ...extraTags,
372
+ ],
373
+ bookId: SAMPLE_DOCS_BOOK_INDEX_ID,
374
+ blocks: [block],
375
+ cards: [card],
376
+ body: `Back to [[sample-docs-schema-harness|the schema harness]].`,
377
+ });
378
+ }
379
+ const sampleDocsChapterNotes = [
380
+ schemaHarnessNote(),
381
+ compactNote("sample-docs-coding-drill", "coding-drill", "Sample docs coding drill", {
382
+ id: "coding-two-sum",
383
+ type: "prompt",
384
+ title: "Two pointer drill",
385
+ problem: "Return indices for a sorted two-sum target.",
386
+ requirements: [
387
+ "O(n) time",
388
+ "O(1) extra space",
389
+ "Explain duplicate handling",
390
+ ],
391
+ approach: "Move the low or high pointer based on the current sum.",
392
+ traps: [
393
+ "Returning values instead of indices",
394
+ "Skipping duplicate values incorrectly",
395
+ ],
396
+ tests: ["[2, 7, 11, 15], target 9", "[1, 1, 3], target 2"],
397
+ answer: "Use two pointers and preserve original index assumptions in the prompt.",
398
+ }, freshCard({
399
+ id: "card-two-sum-prompt",
400
+ type: "basic",
401
+ status: "active",
402
+ prompt: "What pointer move keeps a sorted two-sum search correct?",
403
+ answer: "Move the low or high pointer based on the current sum.",
404
+ tags: ["sample", "algorithms/two-pointer", "coding-drill"],
405
+ blockRefs: ["coding-two-sum"],
406
+ }), ["algorithms/two-pointer"]),
407
+ compactNote("sample-docs-system-design", "system-design", "Sample docs system design", {
408
+ id: "design-rate-limiter",
409
+ type: "table",
410
+ title: "Rate limiter tradeoffs",
411
+ columns: ["Design", "Good for", "Watch out"],
412
+ rows: [
413
+ ["Token bucket", "Bursty clients", "Clock drift"],
414
+ ["Sliding window", "Strict fairness", "Higher storage cost"],
415
+ ],
416
+ }, reviewedCard({
417
+ id: "card-token-bucket",
418
+ type: "basic",
419
+ status: "active",
420
+ prompt: "When is token bucket a better rate limiter than a fixed window?",
421
+ answer: "When bounded bursts are acceptable and smoother average throughput matters.",
422
+ tags: ["sample", "systems/design/rate-limiting", "system-design"],
423
+ blockRefs: ["design-rate-limiter"],
424
+ }, {
425
+ due: "2026-07-03T09:00:00.000Z",
426
+ lastReview: "2026-07-01T11:00:00.000Z",
427
+ reviews: [
428
+ reviewLog("card-token-bucket", 1, "hard", "2026-07-01T11:00:00.000Z", "2026-07-03T09:00:00.000Z"),
429
+ ],
430
+ }), ["systems/design/rate-limiting"]),
431
+ compactNote("sample-docs-story-bank", "story-bank", "Sample docs story bank", {
432
+ id: "story-conflict",
433
+ type: "story",
434
+ title: "Stakeholder conflict",
435
+ useFor: ["conflict", "ownership"],
436
+ situation: "Two teams disagreed on who should own a migration.",
437
+ task: "Find a decision path that preserved delivery momentum.",
438
+ action: "Mapped operational responsibilities, proposed ownership boundaries, and documented tradeoffs.",
439
+ result: "The migration proceeded with clearer on-call and escalation paths.",
440
+ metrics: ["1 ownership doc", "2 teams aligned"],
441
+ }, freshCard({
442
+ id: "card-story-action",
443
+ type: "basic",
444
+ status: "active",
445
+ prompt: "What action anchors the stakeholder conflict story?",
446
+ answer: "Mapping responsibilities and documenting ownership tradeoffs.",
447
+ tags: ["sample", "interview/behavioral/stories", "behavioral"],
448
+ blockRefs: ["story-conflict"],
449
+ }), ["interview/behavioral/stories"]),
450
+ compactNote("sample-docs-freeform", "freeform", "Sample docs freeform", {
451
+ id: "freeform-note",
452
+ type: "text",
453
+ title: "Freeform note",
454
+ body: "This note keeps the structured metadata but leaves most content in body markdown.",
455
+ }, freshCard({
456
+ id: "card-freeform-body",
457
+ type: "basic",
458
+ status: "active",
459
+ prompt: "Where does freeform fixture content mostly live?",
460
+ answer: "In the markdown body, while still preserving typed metadata and cards.",
461
+ tags: ["sample", "notes/freeform", "freeform"],
462
+ blockRefs: ["freeform-note"],
463
+ }), ["notes/freeform"]),
464
+ ];
465
+ function sampleDocsIndexNote() {
466
+ return note({
467
+ id: SAMPLE_DOCS_BOOK_INDEX_ID,
468
+ title: "Sample docs",
469
+ docType: "index",
470
+ summary: "Bundled sample book that exercises every docs note type, block, and card fixture.",
471
+ learningGoal: "Use these fixtures to verify editing, display, cards, review, search, and book navigation.",
472
+ aliases: ["Sample Docs Index", "Docs Fixtures"],
473
+ tags: [
474
+ SAMPLE_DOCS_BOOK_TAG,
475
+ "sample",
476
+ "sample/docs/index",
477
+ "index",
478
+ "resources/docs/index",
479
+ ],
480
+ book: {
481
+ chapters: SAMPLE_DOCS_CHAPTER_IDS.map((noteId) => ({ noteId })),
482
+ },
483
+ blocks: [
484
+ {
485
+ id: "index-links",
486
+ type: "resources",
487
+ title: "Fixture map",
488
+ items: [
489
+ {
490
+ title: "Schema harness",
491
+ url: "lapis://docs/sample-docs-schema-harness",
492
+ kind: "note",
493
+ notes: "Full schema coverage.",
494
+ },
495
+ {
496
+ title: "Coding drill",
497
+ url: "lapis://docs/sample-docs-coding-drill",
498
+ kind: "note",
499
+ notes: "Prompt block and coding-drill docType metadata.",
500
+ },
501
+ ],
502
+ },
503
+ ],
504
+ cards: [
505
+ freshCard({
506
+ id: "card-index-purpose",
507
+ type: "basic",
508
+ status: "active",
509
+ prompt: "What does the sample docs index fixture map?",
510
+ answer: "It maps sample note ids to the harness areas they exercise.",
511
+ tags: ["sample", "resources/docs/index", "index"],
512
+ blockRefs: ["index-links"],
513
+ }),
514
+ ],
515
+ body: "Open chapters from the book navigation, or jump via wiki links like [[sample-docs-schema-harness]].",
516
+ });
517
+ }
518
+ const sampleDocsNotesData = [
519
+ ...sampleDocsChapterNotes,
520
+ sampleDocsIndexNote(),
521
+ ];
522
+ export function sampleDocsNotes() {
523
+ return JSON.parse(JSON.stringify(sampleDocsNotesData));
524
+ }