sourcey 3.3.10 → 3.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 (41) hide show
  1. package/README.md +19 -3
  2. package/dist/client/scroll-tracker.js +8 -1
  3. package/dist/components/layout/Head.d.ts.map +1 -1
  4. package/dist/components/layout/Head.js +1 -1
  5. package/dist/components/layout/Page.d.ts.map +1 -1
  6. package/dist/components/layout/Page.js +2 -1
  7. package/dist/components/layout/Sidebar.d.ts.map +1 -1
  8. package/dist/components/layout/Sidebar.js +6 -1
  9. package/dist/components/layout/TableOfContents.js +1 -1
  10. package/dist/components/mcp/AnnotationBadges.d.ts +15 -0
  11. package/dist/components/mcp/AnnotationBadges.d.ts.map +1 -0
  12. package/dist/components/mcp/AnnotationBadges.js +10 -0
  13. package/dist/components/mcp/McpConnection.d.ts +10 -0
  14. package/dist/components/mcp/McpConnection.d.ts.map +1 -0
  15. package/dist/components/mcp/McpConnection.js +32 -0
  16. package/dist/components/mcp/McpEndpointBar.d.ts +8 -0
  17. package/dist/components/mcp/McpEndpointBar.d.ts.map +1 -0
  18. package/dist/components/mcp/McpEndpointBar.js +16 -0
  19. package/dist/components/mcp/McpReturns.d.ts +18 -0
  20. package/dist/components/mcp/McpReturns.d.ts.map +1 -0
  21. package/dist/components/mcp/McpReturns.js +33 -0
  22. package/dist/components/openapi/Operation.d.ts.map +1 -1
  23. package/dist/components/openapi/Operation.js +5 -1
  24. package/dist/config.d.ts +3 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +8 -3
  27. package/dist/core/mcp-normalizer.d.ts +11 -0
  28. package/dist/core/mcp-normalizer.d.ts.map +1 -0
  29. package/dist/core/mcp-normalizer.js +382 -0
  30. package/dist/core/types.d.ts +26 -2
  31. package/dist/core/types.d.ts.map +1 -1
  32. package/dist/dev-server.d.ts.map +1 -1
  33. package/dist/dev-server.js +46 -8
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +16 -9
  36. package/dist/renderer/html-builder.d.ts.map +1 -1
  37. package/dist/renderer/html-builder.js +9 -0
  38. package/dist/themes/default/sourcey.css +36 -8
  39. package/dist/utils/markdown.d.ts.map +1 -1
  40. package/dist/utils/markdown.js +50 -1
  41. package/package.json +6 -2
@@ -55,6 +55,25 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
55
55
  -webkit-overflow-scrolling: touch;
56
56
  }
57
57
 
58
+ /* ── Prose Video (::video directive) ──────────────────────────────── */
59
+
60
+ #sourcey .prose-video {
61
+ position: relative;
62
+ width: 100%;
63
+ padding-bottom: 56.25%; /* 16:9 */
64
+ margin: 1.5rem 0;
65
+ border-radius: var(--radius);
66
+ overflow: hidden;
67
+ }
68
+ #sourcey .prose-video iframe,
69
+ #sourcey .prose-video video {
70
+ position: absolute;
71
+ top: 0;
72
+ left: 0;
73
+ width: 100%;
74
+ height: 100%;
75
+ }
76
+
58
77
  /* ── Prose Code Block (fenced code in markdown pages) ─────────────── */
59
78
 
60
79
  #sourcey .prose-code-block {
@@ -159,39 +178,49 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
159
178
  text-align: left;
160
179
  overflow-wrap: break-word;
161
180
  hyphens: auto;
162
- border-left: 2px solid transparent;
181
+ border-radius: 0.375rem;
163
182
  width: 100%;
164
183
  color: rgb(var(--color-gray-700));
165
- transition: color 0.15s, border-color 0.15s;
184
+ transition: color 0.15s, background-color 0.15s;
166
185
  }
167
186
  .dark #sourcey .nav-link {
168
187
  color: rgb(var(--color-gray-400));
169
188
  }
170
189
  #sourcey .nav-link:hover {
171
190
  color: rgb(var(--color-gray-900));
172
- border-left-color: rgb(var(--color-gray-300));
191
+ background: rgb(var(--color-gray-100) / 0.6);
173
192
  }
174
193
  .dark #sourcey .nav-link:hover {
175
194
  color: rgb(var(--color-gray-300));
176
- border-left-color: rgb(var(--color-gray-600));
195
+ background: rgb(var(--color-gray-800) / 0.4);
177
196
  }
178
197
  #sourcey .nav-link.active {
179
198
  color: rgb(var(--color-primary));
180
- border-left-color: rgb(var(--color-primary));
199
+ background: rgb(var(--color-primary) / 0.08);
181
200
  font-weight: 500;
182
201
  }
183
202
  .dark #sourcey .nav-link.active {
184
203
  color: rgb(var(--color-primary-light));
185
- border-left-color: rgb(var(--color-primary-light));
204
+ background: rgb(var(--color-primary-light) / 0.08);
186
205
  }
187
206
 
188
207
  /* ── TOC Active State ─────────────────────────────────────────────── */
189
208
 
209
+ #sourcey #toc .toc-item {
210
+ border-left: 2px solid rgb(var(--color-gray-200));
211
+ padding-left: 0.75rem;
212
+ transition: color 0.15s, border-color 0.15s;
213
+ }
214
+ .dark #sourcey #toc .toc-item {
215
+ border-left-color: rgb(var(--color-gray-700));
216
+ }
190
217
  #sourcey #toc .toc-item.active {
191
218
  color: rgb(var(--color-primary));
219
+ border-left-color: rgb(var(--color-primary));
192
220
  }
193
221
  .dark #sourcey #toc .toc-item.active {
194
222
  color: rgb(var(--color-primary-light));
223
+ border-left-color: rgb(var(--color-primary-light));
195
224
  }
196
225
 
197
226
  /* ── Code Block Panels (language dropdown + response tabs) ─────────── */
@@ -1025,11 +1054,10 @@ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
1025
1054
  color: rgb(var(--color-primary-light));
1026
1055
  }
1027
1056
 
1028
- /* Drawer nav items — larger touch targets, no border indicator */
1057
+ /* Drawer nav items — larger touch targets */
1029
1058
  #sourcey .mobile-nav-dialog .nav-link,
1030
1059
  #sourcey .mobile-nav-dialog .nav-link:hover,
1031
1060
  #sourcey .mobile-nav-dialog .nav-link.active {
1032
- border-left: none;
1033
1061
  padding-top: 0.5rem;
1034
1062
  padding-bottom: 0.5rem;
1035
1063
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AA8BD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe5D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3D"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAuFD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe5D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3D"}
@@ -16,8 +16,57 @@ export function renderCodeBlock(text, lang) {
16
16
  <div class="prose-code-content">${shiki}</div>
17
17
  </div>`;
18
18
  }
19
+ function parseVideoUrl(url) {
20
+ // YouTube
21
+ let m = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]+)/);
22
+ if (m)
23
+ return { src: `https://www.youtube-nocookie.com/embed/${m[1]}`, type: "iframe" };
24
+ // Vimeo
25
+ m = url.match(/vimeo\.com\/(\d+)/);
26
+ if (m)
27
+ return { src: `https://player.vimeo.com/video/${m[1]}`, type: "iframe" };
28
+ // Raw video
29
+ const ext = url.split(".").pop()?.toLowerCase();
30
+ const mime = ext === "webm" ? "video/webm" : "video/mp4";
31
+ return { src: url, type: "video", mime };
32
+ }
33
+ const videoExtension = {
34
+ extensions: [
35
+ {
36
+ name: "video",
37
+ level: "block",
38
+ start(src) {
39
+ return src.match(/::video\[/)?.index;
40
+ },
41
+ tokenizer(src) {
42
+ const match = src.match(/^::video\[([^\]]+)\](?:\{([^}]*)\})?/);
43
+ if (!match)
44
+ return undefined;
45
+ const url = match[1];
46
+ const attrs = match[2] ?? "";
47
+ const titleMatch = attrs.match(/title="([^"]*)"/);
48
+ return { type: "video", raw: match[0], url, title: titleMatch?.[1] ?? "" };
49
+ },
50
+ renderer(token) {
51
+ const { url, title } = token;
52
+ const parsed = parseVideoUrl(url);
53
+ const safeTitle = title.replace(/"/g, "&quot;").replace(/</g, "&lt;");
54
+ if (parsed.type === "iframe") {
55
+ return `<div class="prose-video not-prose">
56
+ <iframe src="${parsed.src}" title="${safeTitle}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen loading="lazy"></iframe>
57
+ </div>\n`;
58
+ }
59
+ return `<div class="prose-video not-prose">
60
+ <video controls preload="metadata" title="${safeTitle}">
61
+ <source src="${parsed.src}" type="${parsed.mime}" />
62
+ </video>
63
+ </div>\n`;
64
+ },
65
+ },
66
+ ],
67
+ };
19
68
  /** Singleton Marked instance — code blocks get Shiki + prose wrapper, headings get IDs. */
20
- const marked = new Marked({
69
+ const marked = new Marked(videoExtension, {
21
70
  renderer: {
22
71
  code({ text, lang }) {
23
72
  return renderCodeBlock(text, lang);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sourcey",
3
- "version": "3.3.10",
3
+ "version": "3.4.0",
4
4
  "description": "Open source documentation platform. API references, guides, static output.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -21,7 +21,7 @@
21
21
  ],
22
22
  "scripts": {
23
23
  "build": "tsc && cp -r src/themes dist/ && cp src/client/*.js dist/client/",
24
- "dev": "tsc --watch",
24
+ "watch": "npm run build && tsc --watch --preserveWatchOutput",
25
25
  "test": "vitest run",
26
26
  "test:watch": "vitest",
27
27
  "lint": "eslint src/ test/",
@@ -39,6 +39,7 @@
39
39
  "jiti": "^2.6.1",
40
40
  "js-yaml": "^4.1.0",
41
41
  "marked": "^15.0.0",
42
+ "mcp-parser": "^0.2.0",
42
43
  "moxygen": "^2.1.1",
43
44
  "preact": "^10.28.4",
44
45
  "preact-render-to-string": "^6.6.6",
@@ -69,6 +70,9 @@
69
70
  "developer-documentation",
70
71
  "doxygen"
71
72
  ],
73
+ "funding": {
74
+ "url": "https://sourcey.com"
75
+ },
72
76
  "author": "Kam Low <oss@0state.com> (https://sourcey.com)",
73
77
  "license": "AGPL-3.0-only",
74
78
  "repository": {