@autumnsgrove/groveengine 0.3.3 → 0.4.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 (270) hide show
  1. package/dist/auth/index.d.ts +2 -0
  2. package/dist/auth/index.js +5 -0
  3. package/dist/components/admin/GutterManager.svelte +4 -4
  4. package/dist/components/admin/MarkdownEditor.svelte +381 -1311
  5. package/dist/components/admin/MarkdownEditor.svelte.d.ts +2 -8
  6. package/dist/components/admin/composables/index.d.ts +7 -0
  7. package/dist/components/admin/composables/index.js +12 -0
  8. package/dist/components/admin/composables/useAmbientSounds.svelte.d.ts +53 -0
  9. package/dist/components/admin/composables/useAmbientSounds.svelte.js +192 -0
  10. package/dist/components/admin/composables/useCommandPalette.svelte.d.ts +17 -0
  11. package/dist/components/admin/composables/useCommandPalette.svelte.js +118 -0
  12. package/dist/components/admin/composables/useDraftManager.svelte.d.ts +17 -0
  13. package/dist/components/admin/composables/useDraftManager.svelte.js +154 -0
  14. package/dist/components/admin/composables/useEditorTheme.svelte.d.ts +195 -0
  15. package/dist/components/admin/composables/useEditorTheme.svelte.js +182 -0
  16. package/dist/components/admin/composables/useSlashCommands.svelte.d.ts +32 -0
  17. package/dist/components/admin/composables/useSlashCommands.svelte.js +166 -0
  18. package/dist/components/admin/composables/useSnippets.svelte.d.ts +5 -0
  19. package/dist/components/admin/composables/useSnippets.svelte.js +122 -0
  20. package/dist/components/admin/composables/useWritingSession.svelte.d.ts +13 -0
  21. package/dist/components/admin/composables/useWritingSession.svelte.js +100 -0
  22. package/dist/components/custom/ContentWithGutter.svelte +1 -1
  23. package/dist/components/custom/GutterItem.svelte +2 -2
  24. package/dist/config/ai-models.d.ts +25 -0
  25. package/dist/config/ai-models.js +50 -0
  26. package/dist/config/index.d.ts +1 -0
  27. package/dist/config/index.js +4 -0
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.js +6 -6
  30. package/dist/server/index.d.ts +1 -0
  31. package/dist/server/index.js +4 -0
  32. package/dist/ui/components/charts/ActivityOverview.svelte +293 -0
  33. package/dist/ui/components/charts/ActivityOverview.svelte.d.ts +12 -0
  34. package/dist/ui/components/charts/LOCBar.svelte +129 -0
  35. package/dist/ui/components/charts/LOCBar.svelte.d.ts +21 -0
  36. package/dist/ui/components/charts/RepoBreakdown.svelte +136 -0
  37. package/dist/ui/components/charts/RepoBreakdown.svelte.d.ts +16 -0
  38. package/dist/ui/components/charts/Sparkline.svelte +139 -0
  39. package/dist/ui/components/charts/Sparkline.svelte.d.ts +6 -0
  40. package/dist/ui/components/charts/index.d.ts +5 -0
  41. package/dist/ui/components/charts/index.js +11 -0
  42. package/dist/ui/components/content/PlanCard.svelte +91 -0
  43. package/dist/ui/components/content/PlanCard.svelte.d.ts +13 -0
  44. package/dist/ui/components/content/ProductCard.svelte +125 -0
  45. package/dist/ui/components/content/ProductCard.svelte.d.ts +14 -0
  46. package/dist/ui/components/content/SearchCard.svelte +60 -0
  47. package/dist/ui/components/content/SearchCard.svelte.d.ts +10 -0
  48. package/dist/ui/components/content/index.d.ts +4 -0
  49. package/dist/ui/components/content/index.js +10 -0
  50. package/dist/ui/components/forms/SearchInput.svelte +89 -0
  51. package/dist/ui/components/forms/SearchInput.svelte.d.ts +11 -0
  52. package/dist/ui/components/forms/index.d.ts +2 -0
  53. package/dist/ui/components/forms/index.js +8 -0
  54. package/dist/ui/components/gallery/index.d.ts +5 -0
  55. package/dist/ui/components/gallery/index.js +13 -0
  56. package/dist/ui/components/icons/IconLegend.svelte +83 -0
  57. package/dist/ui/components/icons/IconLegend.svelte.d.ts +11 -0
  58. package/dist/ui/components/icons/Icons.svelte +115 -0
  59. package/dist/ui/components/icons/Icons.svelte.d.ts +8 -0
  60. package/dist/ui/components/icons/index.d.ts +3 -0
  61. package/dist/ui/components/icons/index.js +9 -0
  62. package/dist/ui/components/indicators/CreditBalance.svelte +67 -0
  63. package/dist/ui/components/indicators/CreditBalance.svelte.d.ts +9 -0
  64. package/dist/ui/components/indicators/ScoreBar.svelte +63 -0
  65. package/dist/ui/components/indicators/ScoreBar.svelte.d.ts +9 -0
  66. package/dist/ui/components/indicators/StatusBadge.svelte +46 -0
  67. package/dist/ui/components/indicators/StatusBadge.svelte.d.ts +7 -0
  68. package/dist/ui/components/indicators/index.d.ts +4 -0
  69. package/dist/ui/components/indicators/index.js +10 -0
  70. package/dist/{components/ui → ui/components/primitives}/accordion/accordion-content.svelte +1 -1
  71. package/dist/{components/ui → ui/components/primitives}/accordion/accordion-item.svelte +1 -1
  72. package/dist/{components/ui → ui/components/primitives}/accordion/accordion-trigger.svelte +1 -1
  73. package/dist/ui/components/primitives/badge/badge.svelte +50 -0
  74. package/dist/ui/components/primitives/badge/badge.svelte.d.ts +60 -0
  75. package/dist/ui/components/primitives/badge/index.d.ts +2 -0
  76. package/dist/ui/components/primitives/badge/index.js +2 -0
  77. package/dist/ui/components/primitives/button/button.svelte +82 -0
  78. package/dist/ui/components/primitives/button/button.svelte.d.ts +132 -0
  79. package/dist/ui/components/primitives/button/index.d.ts +2 -0
  80. package/dist/ui/components/primitives/button/index.js +4 -0
  81. package/dist/ui/components/primitives/card/card-content.svelte +16 -0
  82. package/dist/ui/components/primitives/card/card-content.svelte.d.ts +5 -0
  83. package/dist/ui/components/primitives/card/card-description.svelte +16 -0
  84. package/dist/ui/components/primitives/card/card-description.svelte.d.ts +5 -0
  85. package/dist/ui/components/primitives/card/card-footer.svelte +16 -0
  86. package/dist/ui/components/primitives/card/card-footer.svelte.d.ts +5 -0
  87. package/dist/ui/components/primitives/card/card-header.svelte +16 -0
  88. package/dist/ui/components/primitives/card/card-header.svelte.d.ts +5 -0
  89. package/dist/ui/components/primitives/card/card-title.svelte +25 -0
  90. package/dist/ui/components/primitives/card/card-title.svelte.d.ts +8 -0
  91. package/dist/ui/components/primitives/card/card.svelte +20 -0
  92. package/dist/ui/components/primitives/card/card.svelte.d.ts +5 -0
  93. package/dist/ui/components/primitives/card/index.d.ts +7 -0
  94. package/dist/ui/components/primitives/card/index.js +9 -0
  95. package/dist/{components/ui → ui/components/primitives}/dialog/dialog-content.svelte +1 -1
  96. package/dist/{components/ui → ui/components/primitives}/dialog/dialog-description.svelte +1 -1
  97. package/dist/{components/ui → ui/components/primitives}/dialog/dialog-footer.svelte +1 -1
  98. package/dist/{components/ui → ui/components/primitives}/dialog/dialog-header.svelte +1 -1
  99. package/dist/{components/ui → ui/components/primitives}/dialog/dialog-overlay.svelte +1 -1
  100. package/dist/{components/ui → ui/components/primitives}/dialog/dialog-title.svelte +1 -1
  101. package/dist/ui/components/primitives/input/index.d.ts +2 -0
  102. package/dist/ui/components/primitives/input/index.js +4 -0
  103. package/dist/ui/components/primitives/input/input.svelte +46 -0
  104. package/dist/ui/components/primitives/input/input.svelte.d.ts +13 -0
  105. package/dist/{components/ui → ui/components/primitives}/select/select-content.svelte +1 -1
  106. package/dist/{components/ui → ui/components/primitives}/select/select-group-heading.svelte +1 -1
  107. package/dist/{components/ui → ui/components/primitives}/select/select-item.svelte +1 -1
  108. package/dist/{components/ui → ui/components/primitives}/select/select-scroll-down-button.svelte +1 -1
  109. package/dist/{components/ui → ui/components/primitives}/select/select-scroll-up-button.svelte +1 -1
  110. package/dist/{components/ui → ui/components/primitives}/select/select-separator.svelte +1 -1
  111. package/dist/{components/ui → ui/components/primitives}/select/select-trigger.svelte +1 -1
  112. package/dist/ui/components/primitives/separator/index.d.ts +2 -0
  113. package/dist/ui/components/primitives/separator/index.js +4 -0
  114. package/dist/ui/components/primitives/separator/separator.svelte +22 -0
  115. package/dist/ui/components/primitives/separator/separator.svelte.d.ts +4 -0
  116. package/dist/{components/ui → ui/components/primitives}/sheet/sheet-content.svelte +1 -1
  117. package/dist/{components/ui → ui/components/primitives}/sheet/sheet-description.svelte +1 -1
  118. package/dist/{components/ui → ui/components/primitives}/sheet/sheet-footer.svelte +1 -1
  119. package/dist/{components/ui → ui/components/primitives}/sheet/sheet-header.svelte +1 -1
  120. package/dist/{components/ui → ui/components/primitives}/sheet/sheet-overlay.svelte +1 -1
  121. package/dist/{components/ui → ui/components/primitives}/sheet/sheet-title.svelte +1 -1
  122. package/dist/ui/components/primitives/skeleton/index.d.ts +2 -0
  123. package/dist/ui/components/primitives/skeleton/index.js +4 -0
  124. package/dist/ui/components/primitives/skeleton/skeleton.svelte +17 -0
  125. package/dist/ui/components/primitives/skeleton/skeleton.svelte.d.ts +5 -0
  126. package/dist/{components/ui → ui/components/primitives}/table/table-body.svelte +1 -1
  127. package/dist/{components/ui → ui/components/primitives}/table/table-caption.svelte +1 -1
  128. package/dist/{components/ui → ui/components/primitives}/table/table-cell.svelte +1 -1
  129. package/dist/{components/ui → ui/components/primitives}/table/table-footer.svelte +1 -1
  130. package/dist/{components/ui → ui/components/primitives}/table/table-head.svelte +1 -1
  131. package/dist/{components/ui → ui/components/primitives}/table/table-header.svelte +1 -1
  132. package/dist/{components/ui → ui/components/primitives}/table/table-row.svelte +1 -1
  133. package/dist/{components/ui → ui/components/primitives}/table/table.svelte +1 -1
  134. package/dist/{components/ui → ui/components/primitives}/tabs/tabs-content.svelte +1 -1
  135. package/dist/{components/ui → ui/components/primitives}/tabs/tabs-list.svelte +1 -1
  136. package/dist/{components/ui → ui/components/primitives}/tabs/tabs-trigger.svelte +1 -1
  137. package/dist/ui/components/primitives/textarea/index.d.ts +2 -0
  138. package/dist/ui/components/primitives/textarea/index.js +4 -0
  139. package/dist/ui/components/primitives/textarea/textarea.svelte +24 -0
  140. package/dist/ui/components/primitives/textarea/textarea.svelte.d.ts +6 -0
  141. package/dist/ui/components/states/EmptyState.svelte +28 -0
  142. package/dist/ui/components/states/EmptyState.svelte.d.ts +10 -0
  143. package/dist/ui/components/states/Loading.svelte +62 -0
  144. package/dist/ui/components/states/Loading.svelte.d.ts +7 -0
  145. package/dist/ui/components/states/LoadingSkeleton.svelte +46 -0
  146. package/dist/ui/components/states/LoadingSkeleton.svelte.d.ts +8 -0
  147. package/dist/ui/components/states/ThemeToggle.svelte +138 -0
  148. package/dist/ui/components/states/ThemeToggle.svelte.d.ts +6 -0
  149. package/dist/ui/components/states/index.d.ts +5 -0
  150. package/dist/ui/components/states/index.js +11 -0
  151. package/dist/{components → ui/components}/ui/Accordion.svelte +1 -1
  152. package/dist/ui/components/ui/Badge.svelte +52 -0
  153. package/dist/ui/components/ui/Badge.svelte.d.ts +28 -0
  154. package/dist/ui/components/ui/Button.svelte +77 -0
  155. package/dist/ui/components/ui/Button.svelte.d.ts +34 -0
  156. package/dist/ui/components/ui/Card.svelte +102 -0
  157. package/dist/ui/components/ui/Card.svelte.d.ts +46 -0
  158. package/dist/ui/components/ui/CollapsibleSection.svelte +65 -0
  159. package/dist/ui/components/ui/CollapsibleSection.svelte.d.ts +10 -0
  160. package/dist/{components → ui/components}/ui/Dialog.svelte +1 -1
  161. package/dist/ui/components/ui/Input.svelte +81 -0
  162. package/dist/ui/components/ui/Input.svelte.d.ts +35 -0
  163. package/dist/{components → ui/components}/ui/Select.svelte +1 -1
  164. package/dist/{components → ui/components}/ui/Sheet.svelte +1 -1
  165. package/dist/ui/components/ui/Skeleton.svelte +31 -0
  166. package/dist/ui/components/ui/Skeleton.svelte.d.ts +26 -0
  167. package/dist/ui/components/ui/Spinner.svelte +45 -0
  168. package/dist/ui/components/ui/Spinner.svelte.d.ts +15 -0
  169. package/dist/{components → ui/components}/ui/Table.svelte +2 -2
  170. package/dist/{components → ui/components}/ui/Table.svelte.d.ts +1 -1
  171. package/dist/{components → ui/components}/ui/Tabs.svelte +2 -2
  172. package/dist/ui/components/ui/Textarea.svelte +81 -0
  173. package/dist/ui/components/ui/Textarea.svelte.d.ts +35 -0
  174. package/dist/{components → ui/components}/ui/Toast.svelte +1 -1
  175. package/dist/ui/components/ui/index.d.ts +18 -0
  176. package/dist/ui/components/ui/index.js +28 -0
  177. package/dist/{components → ui/components}/ui/toast.d.ts +1 -1
  178. package/dist/{components → ui/components}/ui/toast.js +2 -2
  179. package/dist/ui/index.d.ts +10 -0
  180. package/dist/ui/index.js +22 -0
  181. package/dist/ui/stores/theme.d.ts +12 -0
  182. package/dist/ui/stores/theme.js +52 -0
  183. package/dist/ui/styles/content.css +514 -0
  184. package/dist/ui/styles/grove.css +715 -0
  185. package/dist/ui/styles/tokens.css +429 -0
  186. package/dist/ui/tailwind.preset.d.ts +340 -0
  187. package/dist/ui/tailwind.preset.js +441 -0
  188. package/dist/ui/tokens/animation.d.ts +417 -0
  189. package/dist/ui/tokens/animation.js +139 -0
  190. package/dist/ui/tokens/colors.d.ts +183 -0
  191. package/dist/ui/tokens/colors.js +97 -0
  192. package/dist/ui/tokens/effects.d.ts +111 -0
  193. package/dist/ui/tokens/effects.js +61 -0
  194. package/dist/ui/tokens/index.d.ts +6 -0
  195. package/dist/ui/tokens/index.js +19 -0
  196. package/dist/ui/tokens/spacing.d.ts +89 -0
  197. package/dist/ui/tokens/spacing.js +49 -0
  198. package/dist/ui/tokens/typography.d.ts +85 -0
  199. package/dist/ui/tokens/typography.js +68 -0
  200. package/dist/ui/utils/cn.d.ts +13 -0
  201. package/dist/ui/utils/cn.js +24 -0
  202. package/dist/ui/utils/index.d.ts +2 -0
  203. package/dist/ui/utils/index.js +8 -0
  204. package/dist/utils/index.d.ts +11 -0
  205. package/dist/utils/index.js +14 -0
  206. package/dist/utils/markdown.d.ts +11 -0
  207. package/dist/utils/markdown.js +25 -0
  208. package/dist/utils/sanitize.js +2 -3
  209. package/package.json +73 -10
  210. package/dist/components/ui/index.d.ts +0 -14
  211. package/dist/components/ui/index.js +0 -18
  212. /package/dist/{components → ui/components}/gallery/ImageGallery.svelte +0 -0
  213. /package/dist/{components → ui/components}/gallery/ImageGallery.svelte.d.ts +0 -0
  214. /package/dist/{components → ui/components}/gallery/Lightbox.svelte +0 -0
  215. /package/dist/{components → ui/components}/gallery/Lightbox.svelte.d.ts +0 -0
  216. /package/dist/{components → ui/components}/gallery/LightboxCaption.svelte +0 -0
  217. /package/dist/{components → ui/components}/gallery/LightboxCaption.svelte.d.ts +0 -0
  218. /package/dist/{components → ui/components}/gallery/ZoomableImage.svelte +0 -0
  219. /package/dist/{components → ui/components}/gallery/ZoomableImage.svelte.d.ts +0 -0
  220. /package/dist/{components/ui → ui/components/primitives}/accordion/accordion-content.svelte.d.ts +0 -0
  221. /package/dist/{components/ui → ui/components/primitives}/accordion/accordion-item.svelte.d.ts +0 -0
  222. /package/dist/{components/ui → ui/components/primitives}/accordion/accordion-trigger.svelte.d.ts +0 -0
  223. /package/dist/{components/ui → ui/components/primitives}/accordion/index.d.ts +0 -0
  224. /package/dist/{components/ui → ui/components/primitives}/accordion/index.js +0 -0
  225. /package/dist/{components/ui → ui/components/primitives}/dialog/dialog-content.svelte.d.ts +0 -0
  226. /package/dist/{components/ui → ui/components/primitives}/dialog/dialog-description.svelte.d.ts +0 -0
  227. /package/dist/{components/ui → ui/components/primitives}/dialog/dialog-footer.svelte.d.ts +0 -0
  228. /package/dist/{components/ui → ui/components/primitives}/dialog/dialog-header.svelte.d.ts +0 -0
  229. /package/dist/{components/ui → ui/components/primitives}/dialog/dialog-overlay.svelte.d.ts +0 -0
  230. /package/dist/{components/ui → ui/components/primitives}/dialog/dialog-title.svelte.d.ts +0 -0
  231. /package/dist/{components/ui → ui/components/primitives}/dialog/index.d.ts +0 -0
  232. /package/dist/{components/ui → ui/components/primitives}/dialog/index.js +0 -0
  233. /package/dist/{components/ui → ui/components/primitives}/select/index.d.ts +0 -0
  234. /package/dist/{components/ui → ui/components/primitives}/select/index.js +0 -0
  235. /package/dist/{components/ui → ui/components/primitives}/select/select-content.svelte.d.ts +0 -0
  236. /package/dist/{components/ui → ui/components/primitives}/select/select-group-heading.svelte.d.ts +0 -0
  237. /package/dist/{components/ui → ui/components/primitives}/select/select-item.svelte.d.ts +0 -0
  238. /package/dist/{components/ui → ui/components/primitives}/select/select-scroll-down-button.svelte.d.ts +0 -0
  239. /package/dist/{components/ui → ui/components/primitives}/select/select-scroll-up-button.svelte.d.ts +0 -0
  240. /package/dist/{components/ui → ui/components/primitives}/select/select-separator.svelte.d.ts +0 -0
  241. /package/dist/{components/ui → ui/components/primitives}/select/select-trigger.svelte.d.ts +0 -0
  242. /package/dist/{components/ui → ui/components/primitives}/sheet/index.d.ts +0 -0
  243. /package/dist/{components/ui → ui/components/primitives}/sheet/index.js +0 -0
  244. /package/dist/{components/ui → ui/components/primitives}/sheet/sheet-content.svelte.d.ts +0 -0
  245. /package/dist/{components/ui → ui/components/primitives}/sheet/sheet-description.svelte.d.ts +0 -0
  246. /package/dist/{components/ui → ui/components/primitives}/sheet/sheet-footer.svelte.d.ts +0 -0
  247. /package/dist/{components/ui → ui/components/primitives}/sheet/sheet-header.svelte.d.ts +0 -0
  248. /package/dist/{components/ui → ui/components/primitives}/sheet/sheet-overlay.svelte.d.ts +0 -0
  249. /package/dist/{components/ui → ui/components/primitives}/sheet/sheet-title.svelte.d.ts +0 -0
  250. /package/dist/{components/ui → ui/components/primitives}/table/index.d.ts +0 -0
  251. /package/dist/{components/ui → ui/components/primitives}/table/index.js +0 -0
  252. /package/dist/{components/ui → ui/components/primitives}/table/table-body.svelte.d.ts +0 -0
  253. /package/dist/{components/ui → ui/components/primitives}/table/table-caption.svelte.d.ts +0 -0
  254. /package/dist/{components/ui → ui/components/primitives}/table/table-cell.svelte.d.ts +0 -0
  255. /package/dist/{components/ui → ui/components/primitives}/table/table-footer.svelte.d.ts +0 -0
  256. /package/dist/{components/ui → ui/components/primitives}/table/table-head.svelte.d.ts +0 -0
  257. /package/dist/{components/ui → ui/components/primitives}/table/table-header.svelte.d.ts +0 -0
  258. /package/dist/{components/ui → ui/components/primitives}/table/table-row.svelte.d.ts +0 -0
  259. /package/dist/{components/ui → ui/components/primitives}/table/table.svelte.d.ts +0 -0
  260. /package/dist/{components/ui → ui/components/primitives}/tabs/index.d.ts +0 -0
  261. /package/dist/{components/ui → ui/components/primitives}/tabs/index.js +0 -0
  262. /package/dist/{components/ui → ui/components/primitives}/tabs/tabs-content.svelte.d.ts +0 -0
  263. /package/dist/{components/ui → ui/components/primitives}/tabs/tabs-list.svelte.d.ts +0 -0
  264. /package/dist/{components/ui → ui/components/primitives}/tabs/tabs-trigger.svelte.d.ts +0 -0
  265. /package/dist/{components → ui/components}/ui/Accordion.svelte.d.ts +0 -0
  266. /package/dist/{components → ui/components}/ui/Dialog.svelte.d.ts +0 -0
  267. /package/dist/{components → ui/components}/ui/Select.svelte.d.ts +0 -0
  268. /package/dist/{components → ui/components}/ui/Sheet.svelte.d.ts +0 -0
  269. /package/dist/{components → ui/components}/ui/Tabs.svelte.d.ts +0 -0
  270. /package/dist/{components → ui/components}/ui/Toast.svelte.d.ts +0 -0
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Writing Session Composable
3
+ * Manages campfire sessions and writing goals
4
+ */
5
+ /**
6
+ * Creates a writing session manager with Svelte 5 runes
7
+ * @param {object} options - Configuration options
8
+ * @param {Function} options.getWordCount - Function to get current word count
9
+ * @returns {object} Session state and controls
10
+ */
11
+ export function useWritingSession(options?: {
12
+ getWordCount: Function;
13
+ }): object;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Writing Session Composable
3
+ * Manages campfire sessions and writing goals
4
+ */
5
+
6
+ /**
7
+ * Creates a writing session manager with Svelte 5 runes
8
+ * @param {object} options - Configuration options
9
+ * @param {Function} options.getWordCount - Function to get current word count
10
+ * @returns {object} Session state and controls
11
+ */
12
+ export function useWritingSession(options = {}) {
13
+ const { getWordCount } = options;
14
+
15
+ // Campfire session state
16
+ let campfire = $state({
17
+ active: false,
18
+ startTime: null,
19
+ targetMinutes: 25,
20
+ startWordCount: 0,
21
+ });
22
+
23
+ // Writing goals state
24
+ let goal = $state({
25
+ enabled: false,
26
+ targetWords: 500,
27
+ sessionWords: 0,
28
+ });
29
+
30
+ // Campfire elapsed time (needs to be computed with current time)
31
+ function getCampfireElapsed() {
32
+ if (!campfire.active || !campfire.startTime) return "0:00";
33
+ const now = Date.now();
34
+ const elapsed = Math.floor((now - campfire.startTime) / 1000);
35
+ const mins = Math.floor(elapsed / 60);
36
+ const secs = elapsed % 60;
37
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
38
+ }
39
+
40
+ // Writing goal progress
41
+ function getGoalProgress(currentWordCount) {
42
+ if (!goal.enabled) return 0;
43
+ const wordsWritten = currentWordCount - goal.sessionWords;
44
+ return Math.min(100, Math.round((wordsWritten / goal.targetWords) * 100));
45
+ }
46
+
47
+ // Words written in campfire session
48
+ function getCampfireWords(currentWordCount) {
49
+ return currentWordCount - campfire.startWordCount;
50
+ }
51
+
52
+ function startCampfire() {
53
+ const currentWords = getWordCount ? getWordCount() : 0;
54
+ campfire.active = true;
55
+ campfire.startTime = Date.now();
56
+ campfire.startWordCount = currentWords;
57
+ }
58
+
59
+ function endCampfire() {
60
+ // Could show a summary modal here in the future
61
+ campfire.active = false;
62
+ campfire.startTime = null;
63
+ }
64
+
65
+ function promptWritingGoal() {
66
+ const target = prompt("Set your word goal for this session:", "500");
67
+ if (target && !isNaN(parseInt(target))) {
68
+ const currentWords = getWordCount ? getWordCount() : 0;
69
+ goal.enabled = true;
70
+ goal.targetWords = parseInt(target);
71
+ goal.sessionWords = currentWords;
72
+ }
73
+ }
74
+
75
+ function disableGoal() {
76
+ goal.enabled = false;
77
+ }
78
+
79
+ return {
80
+ get campfire() {
81
+ return campfire;
82
+ },
83
+ get goal() {
84
+ return goal;
85
+ },
86
+ get isCampfireActive() {
87
+ return campfire.active;
88
+ },
89
+ get isGoalEnabled() {
90
+ return goal.enabled;
91
+ },
92
+ getCampfireElapsed,
93
+ getGoalProgress,
94
+ getCampfireWords,
95
+ startCampfire,
96
+ endCampfire,
97
+ promptWritingGoal,
98
+ disableGoal,
99
+ };
100
+ }
@@ -397,7 +397,7 @@
397
397
  // Load DOMPurify only in browser
398
398
  onMount(async () => {
399
399
  if (browser) {
400
- const module = await import('dompurify');
400
+ const module = await import('isomorphic-dompurify');
401
401
  DOMPurify = module.default;
402
402
  }
403
403
  });
@@ -1,6 +1,6 @@
1
1
  <script>
2
- import Lightbox from '../gallery/Lightbox.svelte';
3
- import ImageGallery from '../gallery/ImageGallery.svelte';
2
+ import Lightbox from '../../ui/components/gallery/Lightbox.svelte';
3
+ import ImageGallery from '../../ui/components/gallery/ImageGallery.svelte';
4
4
  import { sanitizeHTML } from '../../utils/sanitize.js';
5
5
 
6
6
  let { item = {} } = $props();
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Calculate estimated cost for AI analysis
3
+ * @param {string} content - The content to analyze
4
+ * @param {string} model - The model to use ('haiku' or 'sonnet')
5
+ * @returns {{ inputTokens: number, outputTokens: number, cost: number }}
6
+ */
7
+ export function calculateCost(content: string, model?: string): {
8
+ inputTokens: number;
9
+ outputTokens: number;
10
+ cost: number;
11
+ };
12
+ /**
13
+ * Get available AI models
14
+ * @returns {Array<{ id: string, name: string, description: string }>}
15
+ */
16
+ export function getAvailableModels(): Array<{
17
+ id: string;
18
+ name: string;
19
+ description: string;
20
+ }>;
21
+ /**
22
+ * AI Model Configuration
23
+ * Constants and utilities for AI-powered features like writing assistance
24
+ */
25
+ export const MAX_CONTENT_LENGTH: 100000;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * AI Model Configuration
3
+ * Constants and utilities for AI-powered features like writing assistance
4
+ */
5
+
6
+ // Maximum content length for AI analysis (in characters)
7
+ // Based on typical API token limits (~100k tokens ≈ 400k chars, with safety margin)
8
+ export const MAX_CONTENT_LENGTH = 100000;
9
+
10
+ // Model pricing (per 1M tokens) - for cost estimation
11
+ const MODEL_PRICING = {
12
+ haiku: { input: 0.25, output: 1.25 },
13
+ sonnet: { input: 3.0, output: 15.0 }
14
+ };
15
+
16
+ // Average characters per token (rough estimate)
17
+ const CHARS_PER_TOKEN = 4;
18
+
19
+ /**
20
+ * Calculate estimated cost for AI analysis
21
+ * @param {string} content - The content to analyze
22
+ * @param {string} model - The model to use ('haiku' or 'sonnet')
23
+ * @returns {{ inputTokens: number, outputTokens: number, cost: number }}
24
+ */
25
+ export function calculateCost(content, model = 'haiku') {
26
+ const pricing = MODEL_PRICING[model] || MODEL_PRICING.haiku;
27
+ const inputTokens = Math.ceil(content.length / CHARS_PER_TOKEN);
28
+ // Estimate output tokens as ~10% of input for analysis tasks
29
+ const outputTokens = Math.ceil(inputTokens * 0.1);
30
+
31
+ const inputCost = (inputTokens / 1_000_000) * pricing.input;
32
+ const outputCost = (outputTokens / 1_000_000) * pricing.output;
33
+
34
+ return {
35
+ inputTokens,
36
+ outputTokens,
37
+ cost: inputCost + outputCost
38
+ };
39
+ }
40
+
41
+ /**
42
+ * Get available AI models
43
+ * @returns {Array<{ id: string, name: string, description: string }>}
44
+ */
45
+ export function getAvailableModels() {
46
+ return [
47
+ { id: 'haiku', name: 'Haiku', description: 'Fast and cost-effective' },
48
+ { id: 'sonnet', name: 'Sonnet', description: 'More thorough analysis' }
49
+ ];
50
+ }
@@ -0,0 +1 @@
1
+ export * from "./ai-models.js";
@@ -0,0 +1,4 @@
1
+ // Config barrel export
2
+ // Re-exports all configuration constants and utilities
3
+
4
+ export * from './ai-models.js';
package/dist/index.d.ts CHANGED
@@ -6,9 +6,9 @@ export { default as MobileTOC } from './components/custom/MobileTOC.svelte';
6
6
  export { default as CollapsibleSection } from './components/custom/CollapsibleSection.svelte';
7
7
  export { default as MarkdownEditor } from './components/admin/MarkdownEditor.svelte';
8
8
  export { default as GutterManager } from './components/admin/GutterManager.svelte';
9
- export { default as ImageGallery } from './components/gallery/ImageGallery.svelte';
10
- export { default as Lightbox } from './components/gallery/Lightbox.svelte';
11
- export { default as LightboxCaption } from './components/gallery/LightboxCaption.svelte';
12
- export { default as ZoomableImage } from './components/gallery/ZoomableImage.svelte';
13
- export * from './components/ui/index';
9
+ export { default as ImageGallery } from './ui/components/gallery/ImageGallery.svelte';
10
+ export { default as Lightbox } from './ui/components/gallery/Lightbox.svelte';
11
+ export { default as LightboxCaption } from './ui/components/gallery/LightboxCaption.svelte';
12
+ export { default as ZoomableImage } from './ui/components/gallery/ZoomableImage.svelte';
13
+ export * from './ui/index';
14
14
  export { cn } from './utils/cn';
package/dist/index.js CHANGED
@@ -9,12 +9,12 @@ export { default as CollapsibleSection } from './components/custom/CollapsibleSe
9
9
  // Admin components
10
10
  export { default as MarkdownEditor } from './components/admin/MarkdownEditor.svelte';
11
11
  export { default as GutterManager } from './components/admin/GutterManager.svelte';
12
- // Gallery components
13
- export { default as ImageGallery } from './components/gallery/ImageGallery.svelte';
14
- export { default as Lightbox } from './components/gallery/Lightbox.svelte';
15
- export { default as LightboxCaption } from './components/gallery/LightboxCaption.svelte';
16
- export { default as ZoomableImage } from './components/gallery/ZoomableImage.svelte';
12
+ // Gallery components (from UI module)
13
+ export { default as ImageGallery } from './ui/components/gallery/ImageGallery.svelte';
14
+ export { default as Lightbox } from './ui/components/gallery/Lightbox.svelte';
15
+ export { default as LightboxCaption } from './ui/components/gallery/LightboxCaption.svelte';
16
+ export { default as ZoomableImage } from './ui/components/gallery/ZoomableImage.svelte';
17
17
  // UI components - re-export all from the UI index
18
- export * from './components/ui/index';
18
+ export * from './ui/index';
19
19
  // Utilities
20
20
  export { cn } from './utils/cn';
@@ -0,0 +1 @@
1
+ export * from "./logger.js";
@@ -0,0 +1,4 @@
1
+ // Server barrel export
2
+ // Re-exports all server-side utilities
3
+
4
+ export * from './logger.js';
@@ -0,0 +1,293 @@
1
+ <script>
2
+ /**
3
+ * ActivityOverview - Weekly activity visualization
4
+ * Shows a GitHub-style contribution chart for recent days
5
+ *
6
+ * Data format: { activity_date: string, commit_count: number }[]
7
+ * (matches GitHub contributions API format)
8
+ */
9
+ import Sparkline from './Sparkline.svelte';
10
+
11
+ /**
12
+ * @type {{ activity_date: string, commit_count: number }[]}
13
+ */
14
+ let {
15
+ data = [],
16
+ locData = { additions: 0, deletions: 0 }, // LOC from separate DB fetch
17
+ days = 14
18
+ } = $props();
19
+
20
+ // Format date as YYYY-MM-DD in local timezone (not UTC!)
21
+ // This matches how GitHub attributes contributions to user's timezone
22
+ function formatDateKey(date) {
23
+ const year = date.getFullYear();
24
+ const month = String(date.getMonth() + 1).padStart(2, '0');
25
+ const day = String(date.getDate()).padStart(2, '0');
26
+ return `${year}-${month}-${day}`;
27
+ }
28
+
29
+ // Ensure we have the right number of days, using local timezone
30
+ const filledData = $derived(() => {
31
+ const result = [];
32
+ const today = new Date();
33
+
34
+ // Build activity map for quick lookup
35
+ const activityMap = {};
36
+ for (const item of data) {
37
+ activityMap[item.activity_date] = item.commit_count;
38
+ }
39
+
40
+ for (let i = days - 1; i >= 0; i--) {
41
+ const date = new Date(today);
42
+ date.setDate(date.getDate() - i);
43
+ const dateStr = formatDateKey(date); // Local timezone!
44
+
45
+ const commits = activityMap[dateStr] || 0;
46
+ result.push({
47
+ date: dateStr,
48
+ commits,
49
+ dayOfWeek: date.toLocaleDateString('en-US', { weekday: 'short' }),
50
+ isToday: i === 0
51
+ });
52
+ }
53
+
54
+ return result;
55
+ });
56
+
57
+ const commitDataArr = $derived(filledData().map(d => d.commits));
58
+
59
+ const totalCommits = $derived(filledData().reduce((sum, d) => sum + d.commits, 0));
60
+ const activeDays = $derived(filledData().filter(d => d.commits > 0).length);
61
+ const peakCommits = $derived(Math.max(...filledData().map(d => d.commits), 0));
62
+
63
+ // Get intensity level for heatmap (0-4)
64
+ function getIntensity(commits) {
65
+ if (commits === 0) return 0;
66
+ if (commits <= 2) return 1;
67
+ if (commits <= 5) return 2;
68
+ if (commits <= 10) return 3;
69
+ return 4;
70
+ }
71
+ </script>
72
+
73
+ <div class="activity-overview">
74
+ <div class="overview-header">
75
+ <h3>Recent Activity</h3>
76
+ <div class="overview-stats">
77
+ <span class="stat">
78
+ <strong>{totalCommits}</strong> commits
79
+ </span>
80
+ <span class="stat active-days">
81
+ <strong>{activeDays}</strong> of {days} days active
82
+ </span>
83
+ </div>
84
+ </div>
85
+
86
+ <div class="overview-content">
87
+ <!-- Heatmap -->
88
+ <div class="heatmap">
89
+ {#each filledData() as day}
90
+ <div
91
+ class="heatmap-cell level-{getIntensity(day.commits)}"
92
+ class:today={day.isToday}
93
+ title="{day.date}: {day.commits} commits"
94
+ >
95
+ <span class="cell-day">{day.dayOfWeek.charAt(0)}</span>
96
+ </div>
97
+ {/each}
98
+ </div>
99
+
100
+ <!-- Sparklines -->
101
+ <div class="sparklines">
102
+ <div class="sparkline-row">
103
+ <span class="sparkline-label">Commits</span>
104
+ <Sparkline
105
+ data={commitDataArr}
106
+ width={140}
107
+ height={20}
108
+ strokeColor="#5cb85f"
109
+ fillColor="rgba(92, 184, 95, 0.15)"
110
+ />
111
+ <span class="sparkline-peak" title="Peak commits in a day">↑{peakCommits}</span>
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="overview-footer">
117
+ <div class="loc-summary">
118
+ <span class="add">+{locData.additions.toLocaleString()}</span>
119
+ <span class="del">-{locData.deletions.toLocaleString()}</span>
120
+ </div>
121
+ </div>
122
+ </div>
123
+
124
+ <style>
125
+ .activity-overview {
126
+ background: white;
127
+ border-radius: 12px;
128
+ padding: 1rem;
129
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
130
+ margin-bottom: 1.5rem;
131
+ }
132
+ :global(.dark) .activity-overview {
133
+ background: var(--light-bg-tertiary);
134
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
135
+ }
136
+ .overview-header {
137
+ display: flex;
138
+ justify-content: space-between;
139
+ align-items: center;
140
+ margin-bottom: 0.75rem;
141
+ }
142
+ .overview-header h3 {
143
+ margin: 0;
144
+ font-size: 0.9rem;
145
+ color: #2c5f2d;
146
+ font-weight: 600;
147
+ }
148
+ :global(.dark) .overview-header h3 {
149
+ color: var(--accent-success);
150
+ }
151
+ .overview-stats {
152
+ display: flex;
153
+ gap: 0.75rem;
154
+ font-size: 0.8rem;
155
+ color: #666;
156
+ }
157
+ :global(.dark) .overview-stats {
158
+ color: var(--light-text-muted);
159
+ }
160
+ .overview-stats strong {
161
+ color: var(--light-border-secondary);
162
+ }
163
+ :global(.dark) .overview-stats strong {
164
+ color: var(--light-text-very-light);
165
+ }
166
+ .overview-content {
167
+ display: flex;
168
+ gap: 1.5rem;
169
+ align-items: flex-start;
170
+ }
171
+ @media (max-width: 500px) {
172
+ .overview-content {
173
+ flex-direction: column;
174
+ gap: 0.75rem;
175
+ }
176
+ }
177
+ /* Heatmap */
178
+ .heatmap {
179
+ display: flex;
180
+ gap: 3px;
181
+ flex-wrap: wrap;
182
+ max-width: 200px;
183
+ }
184
+ .heatmap-cell {
185
+ width: 12px;
186
+ height: 12px;
187
+ border-radius: 2px;
188
+ display: flex;
189
+ align-items: center;
190
+ justify-content: center;
191
+ font-size: 0;
192
+ transition: transform 0.15s ease;
193
+ }
194
+ .heatmap-cell:hover {
195
+ transform: scale(1.2);
196
+ }
197
+ .heatmap-cell.today {
198
+ outline: 1px solid var(--accent-success);
199
+ outline-offset: 1px;
200
+ }
201
+ .heatmap-cell.level-0 {
202
+ background: #ebedf0;
203
+ }
204
+ .heatmap-cell.level-1 {
205
+ background: #9be9a8;
206
+ }
207
+ .heatmap-cell.level-2 {
208
+ background: #40c463;
209
+ }
210
+ .heatmap-cell.level-3 {
211
+ background: #30a14e;
212
+ }
213
+ .heatmap-cell.level-4 {
214
+ background: #216e39;
215
+ }
216
+ :global(.dark) .heatmap-cell.level-0 {
217
+ background: #161b22;
218
+ }
219
+ :global(.dark) .heatmap-cell.level-1 {
220
+ background: #0e4429;
221
+ }
222
+ :global(.dark) .heatmap-cell.level-2 {
223
+ background: #006d32;
224
+ }
225
+ :global(.dark) .heatmap-cell.level-3 {
226
+ background: #26a641;
227
+ }
228
+ :global(.dark) .heatmap-cell.level-4 {
229
+ background: #39d353;
230
+ }
231
+ .cell-day {
232
+ display: none;
233
+ }
234
+ /* Sparklines */
235
+ .sparklines {
236
+ flex: 1;
237
+ display: flex;
238
+ flex-direction: column;
239
+ gap: 0.5rem;
240
+ }
241
+ .sparkline-row {
242
+ display: flex;
243
+ align-items: center;
244
+ gap: 0.5rem;
245
+ }
246
+ .sparkline-label {
247
+ font-size: 0.7rem;
248
+ color: var(--light-text-light);
249
+ width: 45px;
250
+ text-align: right;
251
+ }
252
+ :global(.dark) .sparkline-label {
253
+ color: #777;
254
+ }
255
+ .sparkline-peak {
256
+ font-size: 0.65rem;
257
+ color: var(--light-text-muted);
258
+ margin-left: 0.35rem;
259
+ font-variant-numeric: tabular-nums;
260
+ }
261
+ :global(.dark) .sparkline-peak {
262
+ color: #666;
263
+ }
264
+ /* Footer */
265
+ .overview-footer {
266
+ margin-top: 0.75rem;
267
+ padding-top: 0.5rem;
268
+ border-top: 1px solid var(--light-text-very-light);
269
+ display: flex;
270
+ justify-content: flex-end;
271
+ }
272
+ :global(.dark) .overview-footer {
273
+ border-top-color: var(--light-border-secondary);
274
+ }
275
+ .loc-summary {
276
+ display: flex;
277
+ gap: 0.75rem;
278
+ font-size: 0.8rem;
279
+ font-weight: 500;
280
+ }
281
+ .loc-summary .add {
282
+ color: var(--accent-success);
283
+ }
284
+ .loc-summary .del {
285
+ color: var(--accent-danger);
286
+ }
287
+ :global(.dark) .loc-summary .add {
288
+ color: var(--accent-success);
289
+ }
290
+ :global(.dark) .loc-summary .del {
291
+ color: #e57373;
292
+ }
293
+ </style>
@@ -0,0 +1,12 @@
1
+ export default ActivityOverview;
2
+ type ActivityOverview = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: ({
5
+ activity_date: string;
6
+ commit_count: number;
7
+ } | undefined)[]): void;
8
+ };
9
+ declare const ActivityOverview: import("svelte").Component<{
10
+ activity_date: string;
11
+ commit_count: number;
12
+ }[], {}, "">;