@supersoniks/concorde 5.1.1 → 5.1.3

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 (494) hide show
  1. package/.agents/skills/concorde-docs/SKILL.md +153 -0
  2. package/.agents/skills/{concorde-component-docs/template.md → concorde-docs/templates/component.md} +6 -2
  3. package/.agents/skills/concorde-docs/templates/decorator.md +43 -0
  4. package/.agents/skills/concorde-docs/templates/guide.md +25 -0
  5. package/PLAN-DOCS-AGENTS.md +80 -0
  6. package/README.md +4 -4
  7. package/ai/README.md +29 -41
  8. package/ai/skills/concorde/SKILL.md +54 -324
  9. package/ai/skills/concorde/rules/composition.md +32 -0
  10. package/ai/skills/concorde/rules/data.md +47 -0
  11. package/ai/skills/concorde/rules/http.md +25 -0
  12. package/ai/skills/concorde/rules/lists-forms.md +35 -0
  13. package/ai/skills/concorde/rules/styling.md +46 -0
  14. package/ai/skills/concorde/rules/troubleshooting.md +45 -0
  15. package/build-infos.json +1 -1
  16. package/concorde-core.bundle.js +21 -21
  17. package/concorde-core.es.js +977 -980
  18. package/custom-elements-manifest.public.config.mjs +8 -0
  19. package/{.tmp-cem/custom-elements.json → custom-elements.json} +11758 -8904
  20. package/dist/concorde-core.bundle.js +21 -21
  21. package/dist/concorde-core.es.js +977 -980
  22. package/dist/docs-mock-api-sw.js +58 -223
  23. package/dist/docs-mock-api-sw.js.map +4 -4
  24. package/dist/img/concorde/plane_01.jpg +0 -0
  25. package/dist/img/concorde/plane_02.jpg +0 -0
  26. package/dist/img/concorde/plane_03.jpg +0 -0
  27. package/dist/img/concorde/plane_04.jpg +0 -0
  28. package/dist/img/concorde/plane_05.jpg +0 -0
  29. package/dist/img/concorde/plane_06.jpg +0 -0
  30. package/dist/img/concorde/plane_07.jpg +0 -0
  31. package/dist/img/concorde/plane_08.jpg +0 -0
  32. package/dist/img/concorde/plane_09.jpg +0 -0
  33. package/dist/img/concorde/plane_10.jpg +0 -0
  34. package/dist/img/concorde/plane_11.jpg +0 -0
  35. package/dist/img/concorde/plane_12.jpg +0 -0
  36. package/dist/img/concorde/plane_13.jpg +0 -0
  37. package/dist/img/og-concorde.jpg +0 -0
  38. package/dist/robots.txt +11 -10
  39. package/docs/.htaccess +82 -0
  40. package/docs/404.html +15 -0
  41. package/docs/404.md +5 -0
  42. package/docs/about.html +111 -0
  43. package/docs/about.md +22 -0
  44. package/docs/assets/{index-Bb-_LRyY.js → index-6sS76xWj.js} +2625 -3158
  45. package/docs/assets/index-DkdPbH0F.css +1 -0
  46. package/docs/core/components/functional/date/date.html +211 -0
  47. package/docs/core/components/functional/date/date.md +150 -0
  48. package/docs/core/components/functional/fetch/fetch.html +180 -0
  49. package/docs/core/components/functional/fetch/fetch.md +108 -0
  50. package/docs/core/components/functional/if/if.html +65 -0
  51. package/docs/core/components/functional/if/if.md +34 -0
  52. package/docs/core/components/functional/jsonata/jsonata.html +110 -0
  53. package/docs/core/components/functional/jsonata/jsonata.md +61 -0
  54. package/docs/core/components/functional/list/list.html +200 -0
  55. package/docs/core/components/functional/list/list.md +125 -0
  56. package/docs/core/components/functional/mix/mix.html +78 -0
  57. package/docs/core/components/functional/mix/mix.md +46 -0
  58. package/docs/core/components/functional/queue/queue.html +155 -0
  59. package/docs/core/components/functional/queue/queue.md +51 -0
  60. package/docs/core/components/functional/router/router.html +154 -0
  61. package/docs/core/components/functional/router/router.md +93 -0
  62. package/docs/core/components/functional/sdui/sdui-extension-points.html +127 -0
  63. package/docs/core/components/functional/sdui/sdui-extension-points.md +94 -0
  64. package/docs/core/components/functional/sdui/sdui.html +397 -0
  65. package/docs/core/components/functional/sdui/sdui.md +307 -0
  66. package/docs/core/components/functional/states/states.html +141 -0
  67. package/docs/core/components/functional/states/states.md +112 -0
  68. package/docs/core/components/functional/submit/submit.html +178 -0
  69. package/docs/core/components/functional/submit/submit.md +106 -0
  70. package/docs/core/components/functional/subscriber/subscriber.html +68 -0
  71. package/docs/core/components/functional/subscriber/subscriber.md +91 -0
  72. package/docs/core/components/functional/translation/translation.html +60 -0
  73. package/docs/core/components/functional/translation/translation.md +38 -0
  74. package/docs/core/components/functional/value/value.html +81 -0
  75. package/docs/core/components/functional/value/value.md +47 -0
  76. package/docs/core/components/ui/alert/alert.html +201 -0
  77. package/docs/core/components/ui/alert/alert.md +186 -0
  78. package/docs/core/components/ui/alert-messages/alert-messages.html +132 -0
  79. package/docs/core/components/ui/alert-messages/alert-messages.md +85 -0
  80. package/docs/core/components/ui/badge/badge.html +197 -0
  81. package/docs/core/components/ui/badge/badge.md +181 -0
  82. package/docs/core/components/ui/button/button.html +309 -0
  83. package/docs/core/components/ui/button/button.md +216 -0
  84. package/docs/core/components/ui/captcha/captcha.html +80 -0
  85. package/docs/core/components/ui/captcha/captcha.md +56 -0
  86. package/docs/core/components/ui/card/card.html +254 -0
  87. package/docs/core/components/ui/card/card.md +215 -0
  88. package/docs/core/components/ui/divider/divider.html +144 -0
  89. package/docs/core/components/ui/divider/divider.md +126 -0
  90. package/docs/core/components/ui/form/checkbox/checkbox.html +200 -0
  91. package/docs/core/components/ui/form/checkbox/checkbox.md +125 -0
  92. package/docs/core/components/ui/form/fieldset/fieldset.html +238 -0
  93. package/docs/core/components/ui/form/fieldset/fieldset.md +161 -0
  94. package/docs/core/components/ui/form/form-actions/form-actions.html +122 -0
  95. package/docs/core/components/ui/form/form-actions/form-actions.md +98 -0
  96. package/docs/core/components/ui/form/form-layout/form-layout.html +115 -0
  97. package/docs/core/components/ui/form/form-layout/form-layout.md +109 -0
  98. package/docs/core/components/ui/form/input/input.html +235 -0
  99. package/docs/core/components/ui/form/input/input.md +142 -0
  100. package/docs/core/components/ui/form/radio/radio.html +144 -0
  101. package/docs/core/components/ui/form/radio/radio.md +78 -0
  102. package/docs/core/components/ui/form/select/select.html +178 -0
  103. package/docs/core/components/ui/form/select/select.md +86 -0
  104. package/docs/core/components/ui/form/switch/switch.html +146 -0
  105. package/docs/core/components/ui/form/switch/switch.md +80 -0
  106. package/docs/core/components/ui/form/textarea/textarea.html +162 -0
  107. package/docs/core/components/ui/form/textarea/textarea.md +82 -0
  108. package/docs/core/components/ui/group/group.html +113 -0
  109. package/docs/core/components/ui/group/group.md +77 -0
  110. package/docs/core/components/ui/icon/icon.html +223 -0
  111. package/docs/core/components/ui/icon/icon.md +214 -0
  112. package/docs/core/components/ui/image/image.html +194 -0
  113. package/docs/core/components/ui/image/image.md +167 -0
  114. package/docs/core/components/ui/link/link.html +101 -0
  115. package/docs/core/components/ui/link/link.md +81 -0
  116. package/docs/core/components/ui/loader/loader.html +114 -0
  117. package/docs/core/components/ui/loader/loader.md +87 -0
  118. package/docs/core/components/ui/menu/menu.html +395 -0
  119. package/docs/core/components/ui/menu/menu.md +370 -0
  120. package/docs/core/components/ui/modal/modal.html +324 -0
  121. package/docs/core/components/ui/modal/modal.md +211 -0
  122. package/docs/core/components/ui/pop/pop.html +250 -0
  123. package/docs/core/components/ui/pop/pop.md +216 -0
  124. package/docs/core/components/ui/progress/progress.html +132 -0
  125. package/docs/core/components/ui/progress/progress.md +109 -0
  126. package/docs/core/components/ui/table/table.html +333 -0
  127. package/docs/core/components/ui/table/table.md +267 -0
  128. package/docs/core/components/ui/theme/theme.html +116 -0
  129. package/docs/core/components/ui/theme/theme.md +97 -0
  130. package/docs/core/components/ui/toast/toast.html +185 -0
  131. package/docs/core/components/ui/toast/toast.md +147 -0
  132. package/docs/core/components/ui/tooltip/tooltip.html +112 -0
  133. package/docs/core/components/ui/tooltip/tooltip.md +89 -0
  134. package/docs/custom-elements.json +16559 -0
  135. package/docs/docs/decorators/ancestor-attribute.html +71 -0
  136. package/docs/docs/decorators/ancestor-attribute.md +59 -0
  137. package/docs/docs/decorators/auto-subscribe.html +61 -0
  138. package/docs/docs/decorators/auto-subscribe.md +40 -0
  139. package/docs/docs/decorators/bind.html +87 -0
  140. package/docs/docs/decorators/bind.md +76 -0
  141. package/docs/docs/decorators/get.html +166 -0
  142. package/docs/docs/decorators/get.md +160 -0
  143. package/docs/docs/decorators/handle.html +139 -0
  144. package/docs/docs/decorators/handle.md +119 -0
  145. package/docs/docs/decorators/on-assign.html +72 -0
  146. package/docs/docs/decorators/on-assign.md +63 -0
  147. package/docs/docs/decorators/patch.html +76 -0
  148. package/docs/docs/decorators/patch.md +44 -0
  149. package/docs/docs/decorators/post.html +150 -0
  150. package/docs/docs/decorators/post.md +134 -0
  151. package/docs/docs/decorators/publish.html +74 -0
  152. package/docs/docs/decorators/publish.md +56 -0
  153. package/docs/docs/decorators/put.html +83 -0
  154. package/docs/docs/decorators/put.md +51 -0
  155. package/docs/docs/decorators/subscribe.html +91 -0
  156. package/docs/docs/decorators/subscribe.md +87 -0
  157. package/docs/docs/decorators/wait-for-ancestors.html +82 -0
  158. package/docs/docs/decorators/wait-for-ancestors.md +76 -0
  159. package/docs/docs/directives/sub.html +79 -0
  160. package/docs/docs/directives/sub.md +75 -0
  161. package/docs/docs/directives/t.html +91 -0
  162. package/docs/docs/directives/t.md +73 -0
  163. package/docs/docs/getting-started/ai-agents.html +130 -0
  164. package/docs/docs/getting-started/ai-agents.md +50 -0
  165. package/docs/docs/getting-started/components.html +27 -0
  166. package/docs/docs/getting-started/create-a-component.html +108 -0
  167. package/{src/docs/_getting-started → docs/docs/getting-started}/create-a-component.md +3 -6
  168. package/docs/docs/getting-started/dataFlow.html +174 -0
  169. package/{src/docs/_core-concept → docs/docs/getting-started}/dataFlow.md +18 -19
  170. package/docs/docs/getting-started/installation.html +69 -0
  171. package/docs/docs/getting-started/installation.md +36 -0
  172. package/docs/docs/getting-started/my-first-component.html +180 -0
  173. package/{src/docs/_getting-started → docs/docs/getting-started}/my-first-component.md +5 -14
  174. package/docs/docs/getting-started/start.html +47 -0
  175. package/{src/docs/_getting-started → docs/docs/getting-started}/start.md +1 -13
  176. package/docs/docs/getting-started/theming.html +334 -0
  177. package/docs/docs/index.html +99 -0
  178. package/docs/docs/misc/api-configuration.html +149 -0
  179. package/{src/docs/_misc → docs/docs/misc}/api-configuration.md +10 -12
  180. package/docs/docs/misc/dataProviderKey.html +136 -0
  181. package/{src/docs/_misc → docs/docs/misc}/dataProviderKey.md +4 -4
  182. package/docs/docs/misc/docs-mock-api.html +155 -0
  183. package/{src/docs/_misc → docs/docs/misc}/docs-mock-api.md +12 -13
  184. package/docs/docs/misc/dynamic-path.html +181 -0
  185. package/{src/docs/_misc → docs/docs/misc}/dynamic-path.md +8 -8
  186. package/docs/docs/misc/endpoint.html +51 -0
  187. package/{src/docs/_misc → docs/docs/misc}/endpoint.md +8 -8
  188. package/docs/docs/misc/html-integration.html +45 -0
  189. package/{src/docs/_misc → docs/docs/misc}/html-integration.md +4 -5
  190. package/docs/docs-mock-api-sw.js +58 -223
  191. package/docs/docs-mock-api-sw.js.map +4 -4
  192. package/docs/hubs/decorators.html +438 -0
  193. package/docs/hubs/form-components.html +404 -0
  194. package/docs/hubs/remote-data.html +367 -0
  195. package/docs/img/archive/concorde-001-2cv.webp +0 -0
  196. package/docs/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  197. package/docs/img/archive/concorde-red-arrows-2002.webm +0 -0
  198. package/docs/img/archive/credits.json +28 -0
  199. package/docs/img/concorde/plane_01.jpg +0 -0
  200. package/docs/img/concorde/plane_02.jpg +0 -0
  201. package/docs/img/concorde/plane_03.jpg +0 -0
  202. package/docs/img/concorde/plane_04.jpg +0 -0
  203. package/docs/img/concorde/plane_05.jpg +0 -0
  204. package/docs/img/concorde/plane_06.jpg +0 -0
  205. package/docs/img/concorde/plane_07.jpg +0 -0
  206. package/docs/img/concorde/plane_08.jpg +0 -0
  207. package/docs/img/concorde/plane_09.jpg +0 -0
  208. package/docs/img/concorde/plane_10.jpg +0 -0
  209. package/docs/img/concorde/plane_11.jpg +0 -0
  210. package/docs/img/concorde/plane_12.jpg +0 -0
  211. package/docs/img/concorde/plane_13.jpg +0 -0
  212. package/docs/img/og-concorde.jpg +0 -0
  213. package/docs/index.html +184 -68
  214. package/docs/index.md +22 -0
  215. package/docs/llms-full.txt +5779 -0
  216. package/docs/llms.txt +108 -0
  217. package/docs/privacy.html +122 -0
  218. package/docs/privacy.md +32 -0
  219. package/docs/robots.txt +11 -10
  220. package/docs/sitemap.xml +243 -0
  221. package/docs/src/core/components/functional/date/date.md +150 -0
  222. package/docs/src/core/components/functional/fetch/fetch.md +108 -0
  223. package/docs/src/core/components/functional/if/if.md +34 -0
  224. package/docs/src/core/components/functional/jsonata/jsonata.md +61 -0
  225. package/docs/src/core/components/functional/list/list.md +125 -0
  226. package/docs/src/core/components/functional/mix/mix.md +46 -0
  227. package/docs/src/core/components/functional/queue/queue.md +51 -0
  228. package/docs/src/core/components/functional/router/router.md +93 -0
  229. package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
  230. package/docs/src/core/components/functional/sdui/component-catalog.json +3103 -0
  231. package/docs/src/core/components/functional/sdui/default-library.json +108 -0
  232. package/docs/src/core/components/functional/sdui/example.json +32 -0
  233. package/docs/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
  234. package/docs/src/core/components/functional/sdui/sdui.md +307 -0
  235. package/docs/src/core/components/functional/states/states.md +112 -0
  236. package/docs/src/core/components/functional/submit/submit.md +106 -0
  237. package/docs/src/core/components/functional/subscriber/subscriber.md +91 -0
  238. package/docs/src/core/components/functional/translation/translation.md +38 -0
  239. package/docs/src/core/components/functional/value/value.md +47 -0
  240. package/docs/src/core/components/ui/alert/alert.md +186 -0
  241. package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  242. package/docs/src/core/components/ui/badge/badge.md +181 -0
  243. package/docs/src/core/components/ui/button/button.md +216 -0
  244. package/docs/src/core/components/ui/captcha/captcha.md +56 -0
  245. package/docs/src/core/components/ui/card/card.md +215 -0
  246. package/docs/src/core/components/ui/divider/divider.md +126 -0
  247. package/docs/src/core/components/ui/form/checkbox/checkbox.md +125 -0
  248. package/docs/src/core/components/ui/form/fieldset/fieldset.md +161 -0
  249. package/docs/src/core/components/ui/form/form-actions/form-actions.md +98 -0
  250. package/docs/src/core/components/ui/form/form-layout/form-layout.md +109 -0
  251. package/docs/src/core/components/ui/form/input/input.md +142 -0
  252. package/docs/src/core/components/ui/form/radio/radio.md +78 -0
  253. package/docs/src/core/components/ui/form/select/select.md +86 -0
  254. package/docs/src/core/components/ui/form/switch/switch.md +80 -0
  255. package/docs/src/core/components/ui/form/textarea/textarea.md +82 -0
  256. package/docs/src/core/components/ui/group/group.md +77 -0
  257. package/docs/src/core/components/ui/icon/icon.md +214 -0
  258. package/docs/src/core/components/ui/icon/icons.json +1 -0
  259. package/docs/src/core/components/ui/image/image.md +167 -0
  260. package/docs/src/core/components/ui/link/link.md +81 -0
  261. package/docs/src/core/components/ui/loader/loader.md +87 -0
  262. package/docs/src/core/components/ui/menu/menu.md +370 -0
  263. package/docs/src/core/components/ui/modal/modal.md +211 -0
  264. package/docs/src/core/components/ui/pop/pop.md +216 -0
  265. package/docs/src/core/components/ui/progress/progress.md +109 -0
  266. package/docs/src/core/components/ui/table/table.md +267 -0
  267. package/docs/src/core/components/ui/theme/theme.md +97 -0
  268. package/docs/src/core/components/ui/toast/toast.md +147 -0
  269. package/docs/src/core/components/ui/tooltip/tooltip.md +89 -0
  270. package/docs/src/docs/decorators/ancestor-attribute.md +59 -0
  271. package/docs/src/docs/decorators/auto-subscribe.md +40 -0
  272. package/docs/src/docs/decorators/bind.md +76 -0
  273. package/docs/src/docs/decorators/get.md +160 -0
  274. package/docs/src/docs/decorators/handle.md +119 -0
  275. package/docs/src/docs/decorators/on-assign.md +63 -0
  276. package/docs/src/docs/decorators/patch.md +44 -0
  277. package/docs/src/docs/decorators/post.md +134 -0
  278. package/docs/src/docs/decorators/publish.md +56 -0
  279. package/docs/src/docs/decorators/put.md +51 -0
  280. package/docs/src/docs/decorators/subscribe.md +87 -0
  281. package/docs/src/docs/decorators/wait-for-ancestors.md +76 -0
  282. package/docs/src/docs/directives/sub.md +75 -0
  283. package/docs/src/docs/directives/t.md +73 -0
  284. package/docs/src/docs/getting-started/ai-agents.md +50 -0
  285. package/docs/src/docs/getting-started/components.md +5 -0
  286. package/docs/src/docs/getting-started/create-a-component.md +136 -0
  287. package/docs/src/docs/getting-started/dataFlow.md +87 -0
  288. package/docs/src/docs/getting-started/installation.md +36 -0
  289. package/docs/src/docs/getting-started/my-first-component.md +227 -0
  290. package/docs/src/docs/getting-started/start.md +35 -0
  291. package/docs/src/docs/getting-started/theming.md +253 -0
  292. package/docs/src/docs/misc/api-configuration.md +79 -0
  293. package/docs/src/docs/misc/dataProviderKey.md +168 -0
  294. package/docs/src/docs/misc/docs-mock-api.md +62 -0
  295. package/docs/src/docs/misc/dynamic-path.md +71 -0
  296. package/docs/src/docs/misc/endpoint.md +45 -0
  297. package/docs/src/docs/misc/html-integration.md +14 -0
  298. package/docs/src/docs/search/docs-search.json +10332 -0
  299. package/docs/src/tag-list.json +1 -0
  300. package/docs/src/tsconfig-model.json +23 -0
  301. package/docs/src/tsconfig.json +1359 -0
  302. package/index.html +157 -5
  303. package/package.json +8 -4
  304. package/public/docs-mock-api-sw.js +58 -223
  305. package/public/docs-mock-api-sw.js.map +4 -4
  306. package/public/img/concorde/plane_01.jpg +0 -0
  307. package/public/img/concorde/plane_02.jpg +0 -0
  308. package/public/img/concorde/plane_03.jpg +0 -0
  309. package/public/img/concorde/plane_04.jpg +0 -0
  310. package/public/img/concorde/plane_05.jpg +0 -0
  311. package/public/img/concorde/plane_06.jpg +0 -0
  312. package/public/img/concorde/plane_07.jpg +0 -0
  313. package/public/img/concorde/plane_08.jpg +0 -0
  314. package/public/img/concorde/plane_09.jpg +0 -0
  315. package/public/img/concorde/plane_10.jpg +0 -0
  316. package/public/img/concorde/plane_11.jpg +0 -0
  317. package/public/img/concorde/plane_12.jpg +0 -0
  318. package/public/img/concorde/plane_13.jpg +0 -0
  319. package/public/img/og-concorde.jpg +0 -0
  320. package/public/robots.txt +11 -10
  321. package/scripts/ai-init.mjs +104 -379
  322. package/scripts/ai-init.test.mjs +81 -239
  323. package/scripts/docs-markdown-vite-plugin.ts +43 -0
  324. package/scripts/docs-public-url.mjs +56 -0
  325. package/scripts/docs.htaccess +82 -0
  326. package/scripts/generate-cem.mjs +244 -0
  327. package/scripts/generate-cem.test.mjs +122 -0
  328. package/scripts/generate-crawl-docs.mjs +233 -118
  329. package/scripts/generate-crawl-docs.test.mjs +124 -0
  330. package/scripts/generate-sdui-catalog.mjs +11 -10
  331. package/scripts/post-build-docs.js +37 -50
  332. package/scripts/pre-publish.mjs +2 -1
  333. package/scripts/site-pages.mjs +212 -0
  334. package/scripts/site-pages.test.mjs +116 -0
  335. package/site-pages/about.md +22 -0
  336. package/site-pages/privacy.md +32 -0
  337. package/src/core/components/functional/date/date.md +91 -231
  338. package/src/core/components/functional/fetch/fetch.md +66 -83
  339. package/src/core/components/functional/if/if.md +28 -3
  340. package/src/core/components/functional/jsonata/jsonata.md +42 -37
  341. package/src/core/components/functional/list/list.md +103 -43
  342. package/src/core/components/functional/mix/mix.md +31 -26
  343. package/src/core/components/functional/queue/queue.demo.ts +10 -7
  344. package/src/core/components/functional/queue/queue.md +40 -61
  345. package/src/core/components/functional/router/router.demo.ts +16 -16
  346. package/src/core/components/functional/router/router.md +64 -65
  347. package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  348. package/src/core/components/functional/sdui/component-catalog.json +1 -1
  349. package/src/core/components/functional/sdui/example.json +19 -86
  350. package/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
  351. package/src/core/components/functional/sdui/sdui.md +187 -358
  352. package/src/core/components/functional/states/states.demo.ts +21 -22
  353. package/src/core/components/functional/states/states.md +86 -61
  354. package/src/core/components/functional/states/states.ts +1 -1
  355. package/src/core/components/functional/submit/submit.md +64 -72
  356. package/src/core/components/functional/translation/translation.md +38 -0
  357. package/src/core/components/functional/value/value.md +34 -22
  358. package/src/core/components/ui/alert/alert.md +48 -58
  359. package/src/core/components/ui/badge/badge.md +27 -34
  360. package/src/core/components/ui/button/button.md +139 -106
  361. package/src/core/components/ui/captcha/captcha.md +17 -32
  362. package/src/core/components/ui/card/card.md +6 -6
  363. package/src/core/components/ui/divider/divider.md +8 -11
  364. package/src/core/components/ui/form/checkbox/checkbox.md +90 -42
  365. package/src/core/components/ui/form/fieldset/fieldset.md +31 -75
  366. package/src/core/components/ui/form/form-actions/form-actions.md +14 -16
  367. package/src/core/components/ui/form/form-layout/form-layout.md +19 -29
  368. package/src/core/components/ui/form/input/input.md +95 -95
  369. package/src/core/components/ui/form/radio/radio.md +55 -34
  370. package/src/core/components/ui/form/select/select.md +60 -45
  371. package/src/core/components/ui/form/switch/switch.md +57 -34
  372. package/src/core/components/ui/form/textarea/textarea.md +55 -38
  373. package/src/core/components/ui/group/group.md +35 -33
  374. package/src/core/components/ui/icon/icon.md +4 -4
  375. package/src/core/components/ui/image/image.md +41 -107
  376. package/src/core/components/ui/link/link.md +6 -6
  377. package/src/core/components/ui/loader/loader.md +30 -55
  378. package/src/core/components/ui/menu/menu.md +27 -27
  379. package/src/core/components/ui/modal/modal.md +72 -96
  380. package/src/core/components/ui/pop/pop.md +80 -158
  381. package/src/core/components/ui/progress/progress.md +2 -2
  382. package/src/core/components/ui/table/table.md +91 -255
  383. package/src/core/components/ui/theme/theme.md +11 -36
  384. package/src/core/components/ui/toast/toast.md +48 -117
  385. package/src/core/components/ui/tooltip/tooltip.md +27 -62
  386. package/src/core/decorators/subscriber/bind.ts +9 -14
  387. package/src/core/utils/LocationHandler.spec.ts +80 -0
  388. package/src/core/utils/LocationHandler.ts +5 -9
  389. package/src/docs/components/docs-demo-sources.ts +55 -140
  390. package/src/docs/components/docs-lit-demo.ts +1 -3
  391. package/src/docs/components/docs-source-link.ts +0 -82
  392. package/src/docs/decorators/ancestor-attribute.md +59 -0
  393. package/src/docs/decorators/auto-subscribe.md +40 -0
  394. package/src/docs/decorators/bind.md +76 -0
  395. package/src/docs/decorators/get.md +160 -0
  396. package/src/docs/decorators/handle.md +119 -0
  397. package/src/docs/decorators/on-assign.md +63 -0
  398. package/src/docs/decorators/patch.md +44 -0
  399. package/src/docs/decorators/post.md +134 -0
  400. package/src/docs/decorators/publish.md +56 -0
  401. package/src/docs/decorators/put.md +51 -0
  402. package/src/docs/decorators/subscribe.md +87 -0
  403. package/src/docs/decorators/wait-for-ancestors.md +76 -0
  404. package/src/docs/directives/sub.md +75 -0
  405. package/src/docs/directives/t.md +73 -0
  406. package/src/docs/docs-location.spec.ts +56 -0
  407. package/src/docs/docs-location.ts +133 -32
  408. package/src/docs/docs.ts +1 -2
  409. package/src/docs/example/decorators-demo-bind-demos.ts +83 -135
  410. package/src/docs/example/decorators-demo-geo.ts +30 -19
  411. package/src/docs/example/decorators-demo-post.ts +88 -186
  412. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +165 -268
  413. package/src/docs/example/decorators-demo.ts +85 -98
  414. package/src/docs/example/docs-api-config-demos.ts +19 -20
  415. package/src/docs/example/docs-flight-demos.ts +147 -0
  416. package/src/docs/example/docs-jsonata-demos.ts +52 -52
  417. package/src/docs/example/docs-list-demos.ts +43 -123
  418. package/src/docs/example/docs-provider-keys.ts +21 -28
  419. package/src/docs/example/docs-queue-demos.ts +37 -77
  420. package/src/docs/example/docs-router-demos.ts +20 -25
  421. package/src/docs/example/docs-submit-demos.ts +48 -48
  422. package/src/docs/example/docs-toggle-demos.ts +4 -3
  423. package/src/docs/getting-started/ai-agents.md +50 -0
  424. package/src/docs/getting-started/components.md +5 -0
  425. package/src/docs/getting-started/create-a-component.md +136 -0
  426. package/src/docs/getting-started/dataFlow.md +87 -0
  427. package/src/docs/getting-started/installation.md +36 -0
  428. package/src/docs/getting-started/my-first-component.md +227 -0
  429. package/src/docs/getting-started/start.md +35 -0
  430. package/src/docs/getting-started/theming.md +253 -0
  431. package/src/docs/header/header.ts +11 -6
  432. package/src/docs/home/catalog.ts +1 -1
  433. package/src/docs/home/home.ts +20 -11
  434. package/src/docs/layout.ts +12 -13
  435. package/src/docs/misc/api-configuration.md +79 -0
  436. package/src/docs/misc/dataProviderKey.md +168 -0
  437. package/src/docs/misc/docs-mock-api.md +62 -0
  438. package/src/docs/misc/dynamic-path.md +71 -0
  439. package/src/docs/misc/endpoint.md +45 -0
  440. package/src/docs/misc/html-integration.md +14 -0
  441. package/src/docs/mock-api/api-config-mock.ts +5 -0
  442. package/src/docs/mock-api/fixtures.ts +0 -278
  443. package/src/docs/mock-api/flights.ts +89 -0
  444. package/src/docs/mock-api/router.ts +3 -4
  445. package/src/docs/mock-api/urls.ts +1 -2
  446. package/src/docs/navigation/navigation.ts +82 -103
  447. package/src/docs/navigation/toc.ts +7 -4
  448. package/src/docs/search/docs-search.json +2804 -5024
  449. package/src/docs/search/markdown-renderer.ts +31 -8
  450. package/src/docs/search/page.ts +9 -6
  451. package/src/docs/search/search.ts +154 -122
  452. package/src/docs/tailwind/css/docs/content.css +4 -5
  453. package/src/tsconfig.json +11 -5
  454. package/src/tsconfig.tsbuildinfo +1 -1
  455. package/vite.config.mts +11 -2
  456. package/.agents/skills/concorde-component-docs/SKILL.md +0 -194
  457. package/ai/AGENTS.md +0 -56
  458. package/ai/cursor/rules/concorde-menu.mdc +0 -15
  459. package/ai/cursor/rules/concorde-scope.mdc +0 -14
  460. package/ai/cursor/rules/concorde-theme.mdc +0 -13
  461. package/ai/cursor/rules/concorde.mdc +0 -66
  462. package/ai/jetbrains/rules/concorde.md +0 -53
  463. package/ai/skills/concorde-get-set-dp/SKILL.md +0 -194
  464. package/ai/skills/concorde-imports/SKILL.md +0 -78
  465. package/ai/skills/concorde-menu/SKILL.md +0 -74
  466. package/ai/skills/concorde-scope/SKILL.md +0 -70
  467. package/ai/skills/concorde-theme/SKILL.md +0 -57
  468. package/docs/assets/index-CD4WyL6o.css +0 -1
  469. package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -29
  470. package/src/docs/_core-concept/overview.md +0 -57
  471. package/src/docs/_core-concept/subscriber.md +0 -75
  472. package/src/docs/_decorators/ancestor-attribute.md +0 -128
  473. package/src/docs/_decorators/auto-subscribe.md +0 -202
  474. package/src/docs/_decorators/bind.md +0 -167
  475. package/src/docs/_decorators/get.md +0 -162
  476. package/src/docs/_decorators/handle.md +0 -175
  477. package/src/docs/_decorators/on-assign.md +0 -390
  478. package/src/docs/_decorators/patch.md +0 -70
  479. package/src/docs/_decorators/post.md +0 -146
  480. package/src/docs/_decorators/publish.md +0 -55
  481. package/src/docs/_decorators/put.md +0 -70
  482. package/src/docs/_decorators/subscribe.md +0 -100
  483. package/src/docs/_decorators/wait-for-ancestors.md +0 -163
  484. package/src/docs/_directives/sub.md +0 -91
  485. package/src/docs/_getting-started/ai-agents.md +0 -76
  486. package/src/docs/_getting-started/concorde-manual-install.md +0 -133
  487. package/src/docs/_getting-started/concorde-outside.md +0 -33
  488. package/src/docs/_getting-started/my-first-subscriber.md +0 -120
  489. package/src/docs/_getting-started/pubsub.md +0 -37
  490. package/src/docs/_misc/formelement-subscriber-removal.md +0 -115
  491. package/src/docs/example/docs-input-autocomplete-demos.ts +0 -110
  492. package/src/docs/example/docs-joke-demos.ts +0 -297
  493. /package/{src/docs/_getting-started → docs/docs/getting-started}/components.md +0 -0
  494. /package/{src/docs/_getting-started → docs/docs/getting-started}/theming.md +0 -0
@@ -3,257 +3,99 @@ import fs from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
5
  import test from "node:test";
6
- import {
7
- buildAgentsFile,
8
- decideAgentsAction,
9
- preambleDuplicatesBase,
10
- readOverlayAgents,
11
- slimPreamble,
12
- } from "./ai-init.mjs";
6
+ import {SKILLS_DIR, linkSkills, syncSkills} from "./ai-init.mjs";
13
7
 
14
- const base = `# Agents — Concorde
8
+ async function makeSkill(dir, name, body = "x") {
9
+ await fs.mkdir(path.join(dir, name), {recursive: true});
10
+ await fs.writeFile(path.join(dir, name, "SKILL.md"), `---\nname: ${name}\n---\n${body}\n`);
11
+ }
15
12
 
16
- Guide for Concorde.
17
-
18
- ## Skills / rules
19
-
20
- | File | Role |
21
- |------|------|
22
- | \`.cursor/skills/concorde/SKILL.md\` | Patterns |
23
-
24
- ## Conventions impératives
25
-
26
- - Always **DataProvider**
27
- - No **sonic-fetch**, no **PublisherManager**
28
- - Forms: **formDataProvider**
29
- - Skill **concorde-get-set-dp**
30
- `;
31
-
32
- const overlay = `## Conventions (project)
33
-
34
- - HTTP routes: \`endpoints.*\`
35
- `;
36
-
37
- test("decideAgentsAction: missing file → create", () => {
38
- assert.equal(decideAgentsAction({existingText: ""}), "create");
39
- });
40
-
41
- test("decideAgentsAction: project-owned AGENTS.md → skip by default", () => {
42
- assert.equal(
43
- decideAgentsAction({existingText: "# Billetterie\n\nProject notes.\n"}),
44
- "skip",
45
- );
46
- });
47
-
48
- test("decideAgentsAction: --skip-agents always skips", () => {
49
- assert.equal(
50
- decideAgentsAction({existingText: "", skipAgents: true}),
51
- "skip",
52
- );
53
- });
54
-
55
- test("decideAgentsAction: --merge-agents on project-owned → merge", () => {
56
- assert.equal(
57
- decideAgentsAction({
58
- existingText: "# Billetterie\n\nNotes.\n",
59
- mergeAgents: true,
60
- }),
61
- "merge",
62
- );
63
- });
64
-
65
- test("decideAgentsAction: --force-agents on project-owned → force", () => {
66
- assert.equal(
67
- decideAgentsAction({
68
- existingText: "# Billetterie\n\nNotes.\n",
69
- forceAgents: true,
70
- }),
71
- "force",
72
- );
73
- });
74
-
75
- test("decideAgentsAction: marked file → refresh", () => {
76
- assert.equal(
77
- decideAgentsAction({
78
- existingText: "# App\n\n<!-- concorde-ai -->\n\nold\n",
79
- }),
80
- "refresh",
81
- );
82
- });
83
-
84
- test("forceAgents replaces project-owned content", () => {
85
- const {markdown} = buildAgentsFile({
86
- existing: "# Old project notes\n\nkeep me",
87
- baseContent: base,
88
- overlayContent: "",
89
- forceAgents: true,
13
+ async function withProject(fn) {
14
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-skills-"));
15
+ try {
16
+ await fn(root);
17
+ } finally {
18
+ await fs.rm(root, {recursive: true, force: true});
19
+ }
20
+ }
21
+
22
+ test("syncSkills copies a skill with its rules/ folder into .agents/skills", async () => {
23
+ await withProject(async (root) => {
24
+ const pkg = path.join(root, "pkg");
25
+ await makeSkill(pkg, "concorde");
26
+ await fs.mkdir(path.join(pkg, "concorde", "rules"));
27
+ await fs.writeFile(path.join(pkg, "concorde", "rules", "data.md"), "# Data\n");
28
+ assert.deepEqual(syncSkills(path.join(root, "app"), [pkg]), ["concorde"]);
29
+ const rule = path.join(root, "app", SKILLS_DIR, "concorde", "rules", "data.md");
30
+ assert.equal(await fs.readFile(rule, "utf8"), "# Data\n");
90
31
  });
91
- assert.equal(markdown.includes("keep me"), false);
92
- assert.equal(markdown.includes("<!-- concorde-ai -->"), false);
93
- assert.match(markdown, /^# Agents — Concorde/m);
94
32
  });
95
33
 
96
- test("without force/merge, buildAgentsFile still builds content (caller decides skip)", () => {
97
- const {markdown} = buildAgentsFile({
98
- existing: "",
99
- baseContent: base,
100
- overlayContent: "",
34
+ test("syncSkills replaces its own skill and keeps project skills", async () => {
35
+ await withProject(async (root) => {
36
+ const pkg = path.join(root, "pkg");
37
+ const app = path.join(root, "app");
38
+ const installed = path.join(app, SKILLS_DIR);
39
+ await makeSkill(pkg, "concorde");
40
+ await makeSkill(installed, "concorde", "old copy");
41
+ await makeSkill(installed, "concorde-docs", "project");
42
+ syncSkills(app, [pkg]);
43
+ assert.deepEqual((await fs.readdir(installed)).sort(), ["concorde", "concorde-docs"]);
44
+ assert.doesNotMatch(
45
+ await fs.readFile(path.join(installed, "concorde", "SKILL.md"), "utf8"),
46
+ /old copy/,
47
+ );
48
+ assert.match(
49
+ await fs.readFile(path.join(installed, "concorde-docs", "SKILL.md"), "utf8"),
50
+ /project/,
51
+ );
101
52
  });
102
- assert.match(markdown, /^# Agents — Concorde/m);
103
53
  });
104
54
 
105
- test("merge without marker keeps short unique preamble", () => {
106
- const {markdown, warnings} = buildAgentsFile({
107
- existing: "# My app\n\nOnly project notes here.\n",
108
- baseContent: base,
109
- overlayContent: "",
110
- mergeAgents: true,
55
+ test("linkSkills links each skill from .claude and .junie", async () => {
56
+ await withProject(async (root) => {
57
+ await makeSkill(path.join(root, SKILLS_DIR), "concorde");
58
+ const results = linkSkills(root, ["concorde"]);
59
+ assert.deepEqual(
60
+ results.map((r) => r.mode),
61
+ ["linked", "linked"],
62
+ );
63
+ for (const dir of [".claude/skills", ".junie/skills"]) {
64
+ const link = path.join(root, dir, "concorde");
65
+ assert.ok((await fs.lstat(link)).isSymbolicLink(), `${dir} not a symlink`);
66
+ assert.equal(await fs.readlink(link), path.join("..", "..", SKILLS_DIR, "concorde"));
67
+ assert.match(await fs.readFile(path.join(link, "SKILL.md"), "utf8"), /concorde/);
68
+ }
111
69
  });
112
- assert.match(markdown, /# My app/);
113
- assert.match(markdown, /<!-- concorde-ai -->/);
114
- assert.match(markdown, /# Agents — Concorde/);
115
- assert.equal(warnings.length, 0);
116
70
  });
117
71
 
118
- test("re-run with marker replaces managed zone only (idempotent)", () => {
119
- const first = buildAgentsFile({
120
- existing: "# My app\n\nNote.\n",
121
- baseContent: base,
122
- overlayContent: "v1 overlay",
123
- mergeAgents: true,
124
- }).markdown;
125
-
126
- const second = buildAgentsFile({
127
- existing: first.replace("v1 overlay", "STALE"),
128
- baseContent: base,
129
- overlayContent: "v2 overlay",
130
- mergeAgents: true,
131
- }).markdown;
132
-
133
- assert.equal(second.includes("STALE"), false);
134
- assert.match(second, /v2 overlay/);
135
- assert.equal(second.split("<!-- concorde-ai -->").length, 2);
136
- });
137
-
138
- test("duplicate Concorde preamble is dropped", () => {
139
- const fork = `${base}\n\nExtra copy of the same guide.\n`;
140
- assert.equal(preambleDuplicatesBase(fork, base), true);
141
-
142
- const {markdown, warnings} = buildAgentsFile({
143
- existing: `${fork}\n\n<!-- concorde-ai -->\n\nold managed\n`,
144
- baseContent: base,
145
- overlayContent: overlay,
146
- mergeAgents: true,
72
+ test("linkSkills keeps project skills and whole-folder links", async () => {
73
+ await withProject(async (root) => {
74
+ await makeSkill(path.join(root, SKILLS_DIR), "concorde");
75
+ await makeSkill(path.join(root, SKILLS_DIR), "my-skill");
76
+ // .claude/skills is already a symlink to .agents/skills (this repo's layout)
77
+ await fs.mkdir(path.join(root, ".claude"), {recursive: true});
78
+ await fs.symlink(path.join("..", SKILLS_DIR), path.join(root, ".claude/skills"));
79
+ // .junie has its own skill with the same name as an overlay skill
80
+ await makeSkill(path.join(root, ".junie/skills"), "my-skill", "junie own");
81
+
82
+ const results = linkSkills(root, ["concorde", "my-skill"], {packageNames: ["concorde"]});
83
+ assert.equal(results.find((r) => r.dir === ".claude/skills").mode, "shared");
84
+ assert.ok((await fs.lstat(path.join(root, ".claude/skills"))).isSymbolicLink());
85
+ const own = path.join(root, ".junie/skills/my-skill");
86
+ assert.ok(!(await fs.lstat(own)).isSymbolicLink());
87
+ assert.match(await fs.readFile(path.join(own, "SKILL.md"), "utf8"), /junie own/);
88
+ assert.ok((await fs.lstat(path.join(root, ".junie/skills/concorde"))).isSymbolicLink());
147
89
  });
148
-
149
- assert.equal(markdown.split("<!-- concorde-ai -->").length, 2);
150
- assert.equal(
151
- markdown.indexOf("# Agents — Concorde"),
152
- markdown.lastIndexOf("# Agents — Concorde"),
153
- );
154
- assert.match(markdown, /Conventions \(project\)/);
155
- assert.ok(warnings.some((w) => /duplicated|slimmed/i.test(w)));
156
- });
157
-
158
- test("slimPreamble keeps unique ## sections", () => {
159
- const preamble = `# Agents — Concorde (my-app)
160
-
161
- Guide.
162
-
163
- ## Skills / rules
164
-
165
- dup
166
-
167
- ## Project only
168
-
169
- - use endpoints.ts
170
- `;
171
- const slim = slimPreamble(preamble, base);
172
- assert.match(slim, /Project only/);
173
- assert.equal(slim.includes("## Skills / rules"), false);
174
- assert.match(slim, /Concorde \(my-app\)/);
175
- });
176
-
177
- test("slimPreamble drops Skills even when package title has suffix", () => {
178
- const packageBase = `# Agents — Concorde
179
-
180
- ## Skills / rules (après installation)
181
-
182
- table
183
-
184
- ## Conventions impératives
185
-
186
- - sonic-fetch
187
- - PublisherManager
188
- - formDataProvider
189
- - concorde-get-set-dp
190
- `;
191
- const preamble = `# Agents — Concorde (app)
192
-
193
- ## Skills / rules
194
-
195
- dup table
196
-
197
- ## Installation / réinstallation
198
-
199
- custom install cmd
200
-
201
- ## Project endpoints
202
-
203
- - endpoints.ts
204
- `;
205
- const slim = slimPreamble(preamble, packageBase);
206
- assert.equal(slim.includes("## Skills / rules"), false);
207
- assert.match(slim, /Project endpoints/);
208
- // Installation may stay if not in package — package has no Installation ##
209
- assert.match(slim, /Installation \/ réinstallation|Project endpoints/);
210
- });
211
-
212
- test("readOverlayAgents: prefers AGENTS.concorde.md", async () => {
213
- const dir = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-overlay-"));
214
- try {
215
- await fs.writeFile(
216
- path.join(dir, "AGENTS.concorde.md"),
217
- "# overlay preferred\n",
218
- );
219
- await fs.writeFile(
220
- path.join(dir, "AGENTS.starter.md"),
221
- "# overlay legacy\n",
222
- );
223
- const {content, warnings} = readOverlayAgents(dir);
224
- assert.match(content, /overlay preferred/);
225
- assert.equal(warnings.length, 0);
226
- } finally {
227
- await fs.rm(dir, {recursive: true, force: true});
228
- }
229
90
  });
230
91
 
231
- test("readOverlayAgents: falls back to AGENTS.starter.md with warning", async () => {
232
- const dir = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-overlay-"));
233
- try {
234
- await fs.writeFile(
235
- path.join(dir, "AGENTS.starter.md"),
236
- "# overlay legacy\n",
237
- );
238
- const {content, warnings} = readOverlayAgents(dir);
239
- assert.match(content, /overlay legacy/);
240
- assert.match(warnings[0] ?? "", /deprecated AGENTS\.starter\.md/);
241
- } finally {
242
- await fs.rm(dir, {recursive: true, force: true});
243
- }
244
- });
245
-
246
- test("readOverlayAgents: falls back to AGENTS.overlay.md with warning", async () => {
247
- const dir = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-overlay-"));
248
- try {
249
- await fs.writeFile(
250
- path.join(dir, "AGENTS.overlay.md"),
251
- "# overlay mid legacy\n",
252
- );
253
- const {content, warnings} = readOverlayAgents(dir);
254
- assert.match(content, /overlay mid legacy/);
255
- assert.match(warnings[0] ?? "", /deprecated AGENTS\.overlay\.md/);
256
- } finally {
257
- await fs.rm(dir, {recursive: true, force: true});
258
- }
92
+ test("linkSkills replaces an earlier copy of a package skill", async () => {
93
+ await withProject(async (root) => {
94
+ await makeSkill(path.join(root, SKILLS_DIR), "concorde", "new");
95
+ await makeSkill(path.join(root, ".junie/skills"), "concorde", "copied before");
96
+ linkSkills(root, ["concorde"], {packageNames: ["concorde"]});
97
+ const link = path.join(root, ".junie/skills/concorde");
98
+ assert.ok((await fs.lstat(link)).isSymbolicLink());
99
+ assert.match(await fs.readFile(path.join(link, "SKILL.md"), "utf8"), /new/);
100
+ });
259
101
  });
@@ -0,0 +1,43 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ import type { Connect, Plugin } from "vite";
5
+ import { SITE_PAGE_SLUGS, toSourceId } from "./docs-public-url.mjs";
6
+
7
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
8
+ const MD_PATH_RE = /^\/((?:docs|core)\/.+\.mdx?)(?:\?|$)/i;
9
+ const SITE_PAGE_MD_RE = new RegExp(
10
+ `^/(${SITE_PAGE_SLUGS.join("|")})\\.md(?:\\?|$)`,
11
+ );
12
+
13
+ /**
14
+ * Dev: serve public `/docs|core/…/*.md` from `src/…` (including underscore
15
+ * sections and `name/name.md` component pages), and `/about.md` & co. from
16
+ * `site-pages/`.
17
+ */
18
+ export function docsMarkdownVitePlugin(): Plugin {
19
+ return {
20
+ name: "concorde-docs-markdown",
21
+ configureServer(server) {
22
+ server.middlewares.use(((req, res, next) => {
23
+ const raw = req.url || "";
24
+ const sitePage = SITE_PAGE_MD_RE.exec(raw);
25
+ const match = MD_PATH_RE.exec(raw);
26
+ if (!match && !sitePage) {
27
+ next();
28
+ return;
29
+ }
30
+ const filePath = sitePage
31
+ ? path.join(root, "site-pages", `${sitePage[1]}.md`)
32
+ : path.join(root, "src", `${toSourceId(match![1])}.md`);
33
+ if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
34
+ next();
35
+ return;
36
+ }
37
+ res.statusCode = 200;
38
+ res.setHeader("Content-Type", "text/markdown; charset=utf-8");
39
+ fs.createReadStream(filePath).pipe(res);
40
+ }) as Connect.NextHandleFunction);
41
+ },
42
+ };
43
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Public doc URL ↔ source markdown path (under src/).
3
+ *
4
+ * Docs sections are 1:1 with the public path:
5
+ * /docs/getting-started/start ↔ docs/getting-started/start.md
6
+ *
7
+ * Components collapse the trailing duplicate folder/file name:
8
+ * /core/components/ui/button ↔ core/components/ui/button/button.md
9
+ */
10
+
11
+ /**
12
+ * Component markdown whose basename ≠ parent folder (not collapsed in public URLs).
13
+ * Keep in sync with `find src/core/components -name '*.md'` where dirname ≠ basename.
14
+ */
15
+ export const COMPONENT_MD_EXCEPTIONS = new Set([
16
+ "core/components/functional/sdui/sdui-extension-points",
17
+ ]);
18
+
19
+ /**
20
+ * Root-level site pages (`/about` ↔ `site-pages/about.md`, published as
21
+ * `/about.md`). Kept outside src/ so they stay out of doc nav and search.
22
+ */
23
+ export const SITE_PAGE_SLUGS = ["about", "privacy"];
24
+
25
+ /** Strip leading slash and optional .md/.mdx */
26
+ export function stripMd(rel) {
27
+ return rel.replace(/^\//, "").replace(/\.mdx?$/i, "");
28
+ }
29
+
30
+ /** Source-relative id (may include …/name/name for components). */
31
+ export function toSourceId(relOrPublic) {
32
+ let p = stripMd(relOrPublic);
33
+
34
+ if (p.startsWith("core/components/") && !COMPONENT_MD_EXCEPTIONS.has(p)) {
35
+ const parts = p.split("/");
36
+ const last = parts[parts.length - 1];
37
+ if (parts.length >= 2 && parts[parts.length - 2] !== last) {
38
+ p = `${p}/${last}`;
39
+ }
40
+ }
41
+
42
+ return p;
43
+ }
44
+
45
+ /** Public pathname (leading slash, no .md). */
46
+ export function toPublicPath(mdRel) {
47
+ let p = stripMd(mdRel);
48
+ // …/name/name → …/name (component index pages)
49
+ p = p.replace(/\/([^/]+)\/\1$/, "/$1");
50
+ return `/${p}`;
51
+ }
52
+
53
+ /** Public path + .md for agent / SPA fetch URL path (no leading slash). */
54
+ export function toPublicMdRel(mdRel) {
55
+ return `${toPublicPath(mdRel).slice(1)}.md`;
56
+ }
@@ -0,0 +1,82 @@
1
+ # Concorde docs — pathname SPA + agent Markdown/HTML
2
+ # Public paths match on-disk docs/… ; components collapse …/name → …/name/name.(md|html)
3
+ # See https://acceptmarkdown.com/recipes/apache (Option A, pragmatic)
4
+
5
+ DirectoryIndex index.html
6
+ # Component folders exist on disk (…/button/button.md); do not force a trailing
7
+ # slash on the pretty URL /…/button (that would break SPA + Accept negotiation).
8
+ DirectorySlash Off
9
+
10
+ RewriteEngine On
11
+
12
+ # Pretty component URLs: drop a trailing slash if the client added one
13
+ RewriteRule ^(core/components/.+)/$ /$1 [R=301,L]
14
+
15
+ # Homepage: Accept: text/markdown → index.md
16
+ RewriteCond %{HTTP:Accept} "text/markdown" [NC]
17
+ RewriteCond %{HTTP:Accept} !"text/markdown\s*;\s*q\s*=\s*0(\.0+)?(\s*,|$)" [NC]
18
+ RewriteRule ^/?$ index.md [END]
19
+
20
+ # --- Site pages: /about, /privacy (SPA shell with inline content + .md) ---
21
+ RewriteRule ^(about|privacy)/$ /$1 [R=301,L]
22
+ RewriteCond %{HTTP:Accept} "text/markdown" [NC]
23
+ RewriteCond %{HTTP:Accept} !"text/markdown\s*;\s*q\s*=\s*0(\.0+)?(\s*,|$)" [NC]
24
+ RewriteRule ^(about|privacy)$ /$1.md [END]
25
+ RewriteRule ^(about|privacy)$ /$1.html [END]
26
+
27
+ # --- Components: /…/button(.md|.html) → /…/button/button.(md|html) ---
28
+ RewriteCond %{DOCUMENT_ROOT}/$1/$2/$2.md -f
29
+ RewriteRule ^(core/components/.+)/([^/]+)\.md$ /$1/$2/$2.md [END]
30
+ RewriteCond %{DOCUMENT_ROOT}/$1/$2/$2.html -f
31
+ RewriteRule ^(core/components/.+)/([^/]+)\.html$ /$1/$2/$2.html [END]
32
+
33
+ # --- Accept: text/markdown → sibling .md (docs paths are 1:1; components collapse) ---
34
+ RewriteCond %{REQUEST_URI} !\.(mdx?|html)$ [NC]
35
+ RewriteCond %{HTTP:Accept} "text/markdown" [NC]
36
+ RewriteCond %{HTTP:Accept} !"text/markdown\s*;\s*q\s*=\s*0(\.0+)?(\s*,|$)" [NC]
37
+ RewriteCond %{DOCUMENT_ROOT}/$1/$2/$2.md -f
38
+ RewriteRule ^(core/components/.+)/([^/]+)$ /$1/$2/$2.md [END]
39
+
40
+ RewriteCond %{REQUEST_URI} !\.(mdx?|html)$ [NC]
41
+ RewriteCond %{HTTP:Accept} "text/markdown" [NC]
42
+ RewriteCond %{HTTP:Accept} !"text/markdown\s*;\s*q\s*=\s*0(\.0+)?(\s*,|$)" [NC]
43
+ RewriteCond %{DOCUMENT_ROOT}/$1.md -f
44
+ RewriteRule ^((?:docs|core)/.+)$ /$1.md [END]
45
+
46
+ # --- Known crawlers → static HTML ---
47
+ RewriteCond %{REQUEST_URI} !\.(mdx?|html)$ [NC]
48
+ RewriteCond %{HTTP_USER_AGENT} (bot|crawler|spider|slurp|GPTBot|Claude|anthropic|Bytespider|Applebot|bingbot|Googlebot|DuckDuckBot|YandexBot|Baiduspider|facebookexternalhit|LinkedInBot|Twitterbot|SemrushBot|AhrefsBot|PetalBot|CCBot|meta-externalagent|OAI-SearchBot|Perplexity|Diffbot|ia_archiver) [NC]
49
+ RewriteCond %{DOCUMENT_ROOT}/$1/$2/$2.html -f
50
+ RewriteRule ^(core/components/.+)/([^/]+)$ /$1/$2/$2.html [END]
51
+
52
+ RewriteCond %{REQUEST_URI} !\.(mdx?|html)$ [NC]
53
+ RewriteCond %{HTTP_USER_AGENT} (bot|crawler|spider|slurp|GPTBot|Claude|anthropic|Bytespider|Applebot|bingbot|Googlebot|DuckDuckBot|YandexBot|Baiduspider|facebookexternalhit|LinkedInBot|Twitterbot|SemrushBot|AhrefsBot|PetalBot|CCBot|meta-externalagent|OAI-SearchBot|Perplexity|Diffbot|ia_archiver) [NC]
54
+ RewriteCond %{DOCUMENT_ROOT}/$1.html -f
55
+ RewriteRule ^((?:docs|core)/.+)$ /$1.html [END]
56
+
57
+ # Hubs are static files only
58
+ RewriteCond %{DOCUMENT_ROOT}/hubs/$1.html -f
59
+ RewriteRule ^hubs/([^/]+)/?$ /hubs/$1.html [END]
60
+
61
+ # SPA pushState (allow when path matches an on-disk dir such as …/button/)
62
+ RewriteCond %{REQUEST_FILENAME} !-f
63
+ RewriteRule ^(?:docs|core)/ index.html [END]
64
+
65
+ RewriteCond %{REQUEST_FILENAME} !-f
66
+ RewriteCond %{HTTP:Accept} "text/markdown" [NC]
67
+ RewriteCond %{HTTP:Accept} !"text/markdown\s*;\s*q\s*=\s*0(\.0+)?(\s*,|$)" [NC]
68
+ RewriteRule ^ - [R=404,L]
69
+
70
+ ErrorDocument 404 /404.md
71
+
72
+ <IfModule mod_headers.c>
73
+ Header merge Vary Accept
74
+ </IfModule>
75
+
76
+ <FilesMatch "\.md$">
77
+ ForceType text/markdown
78
+ <IfModule mod_headers.c>
79
+ Header set Content-Type "text/markdown; charset=utf-8"
80
+ Header merge Vary Accept
81
+ </IfModule>
82
+ </FilesMatch>