@supersoniks/concorde 5.1.2 → 5.1.3-immutable.1

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 (497) hide show
  1. package/.agents/skills/concorde-docs/SKILL.md +1 -1
  2. package/.claude/skills +1 -0
  3. package/.github/workflows/ci.yml +21 -0
  4. package/.github-export-ignore +30 -0
  5. package/CONTRIBUTING.md +59 -0
  6. package/DEV.md +54 -0
  7. package/LICENSE +21 -0
  8. package/OPEN_SOURCE_CHECKPOINT.md +133 -0
  9. package/README.md +1 -1
  10. package/ai/README.md +29 -41
  11. package/ai/skills/concorde/SKILL.md +54 -324
  12. package/ai/skills/concorde/rules/composition.md +32 -0
  13. package/ai/skills/concorde/rules/data.md +47 -0
  14. package/ai/skills/concorde/rules/http.md +25 -0
  15. package/ai/skills/concorde/rules/lists-forms.md +35 -0
  16. package/ai/skills/concorde/rules/styling.md +46 -0
  17. package/ai/skills/concorde/rules/troubleshooting.md +45 -0
  18. package/build-infos.json +1 -1
  19. package/concorde-core.bundle.js +177 -177
  20. package/concorde-core.es.js +4993 -4833
  21. package/custom-elements-manifest.public.config.mjs +8 -0
  22. package/{.tmp-cem/custom-elements.json → custom-elements.json} +11722 -8868
  23. package/dist/concorde-core.bundle.js +177 -177
  24. package/dist/concorde-core.es.js +4993 -4833
  25. package/dist/docs-mock-api-sw.js +58 -223
  26. package/dist/docs-mock-api-sw.js.map +4 -4
  27. package/dist/img/og-concorde.jpg +0 -0
  28. package/dist/robots.txt +11 -10
  29. package/docs/assets/index-CD4WyL6o.css +1 -0
  30. package/docs/assets/index-D_alEsng.js +12122 -0
  31. package/docs/crawl/core/components/functional/date/date.html +190 -0
  32. package/docs/crawl/core/components/functional/fetch/fetch.html +109 -0
  33. package/docs/crawl/core/components/functional/if/if.html +27 -0
  34. package/docs/crawl/core/components/functional/jsonata/jsonata.html +79 -0
  35. package/docs/crawl/core/components/functional/list/list.html +70 -0
  36. package/docs/crawl/core/components/functional/mix/mix.html +45 -0
  37. package/docs/crawl/core/components/functional/queue/queue.html +96 -0
  38. package/docs/crawl/core/components/functional/router/router.html +106 -0
  39. package/docs/{core → crawl/core}/components/functional/sdui/sdui-extension-points.html +8 -9
  40. package/docs/crawl/core/components/functional/sdui/sdui.html +368 -0
  41. package/docs/crawl/core/components/functional/states/states.html +66 -0
  42. package/docs/crawl/core/components/functional/submit/submit.html +160 -0
  43. package/docs/{core → crawl/core}/components/functional/subscriber/subscriber.html +5 -6
  44. package/docs/crawl/core/components/functional/value/value.html +51 -0
  45. package/docs/{core → crawl/core}/components/ui/alert/alert.html +63 -53
  46. package/docs/{core → crawl/core}/components/ui/alert-messages/alert-messages.html +5 -6
  47. package/docs/{core → crawl/core}/components/ui/badge/badge.html +33 -33
  48. package/docs/crawl/core/components/ui/button/button.html +150 -0
  49. package/docs/crawl/core/components/ui/captcha/captcha.html +112 -0
  50. package/docs/{core → crawl/core}/components/ui/card/card.html +11 -12
  51. package/docs/{core → crawl/core}/components/ui/divider/divider.html +14 -14
  52. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +73 -0
  53. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +266 -0
  54. package/docs/{core → crawl/core}/components/ui/form/form-actions/form-actions.html +23 -23
  55. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +121 -0
  56. package/docs/crawl/core/components/ui/form/input/input.html +109 -0
  57. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +38 -0
  58. package/docs/crawl/core/components/ui/form/radio/radio.html +56 -0
  59. package/docs/crawl/core/components/ui/form/select/select.html +73 -0
  60. package/docs/crawl/core/components/ui/form/switch/switch.html +56 -0
  61. package/docs/crawl/core/components/ui/form/textarea/textarea.html +59 -0
  62. package/docs/crawl/core/components/ui/group/group.html +104 -0
  63. package/docs/{core → crawl/core}/components/ui/icon/icon.html +9 -10
  64. package/docs/crawl/core/components/ui/image/image.html +298 -0
  65. package/docs/{core → crawl/core}/components/ui/link/link.html +11 -12
  66. package/docs/crawl/core/components/ui/loader/loader.html +124 -0
  67. package/docs/{core → crawl/core}/components/ui/menu/menu.html +33 -34
  68. package/docs/crawl/core/components/ui/modal/modal.html +342 -0
  69. package/docs/crawl/core/components/ui/pop/pop.html +296 -0
  70. package/docs/{core → crawl/core}/components/ui/progress/progress.html +7 -8
  71. package/docs/crawl/core/components/ui/table/table.html +545 -0
  72. package/docs/crawl/core/components/ui/theme/theme.html +131 -0
  73. package/docs/crawl/core/components/ui/toast/toast.html +233 -0
  74. package/docs/crawl/core/components/ui/tooltip/tooltip.html +140 -0
  75. package/docs/{docs/getting-started → crawl/docs/_core-concept}/dataFlow.html +29 -26
  76. package/docs/crawl/docs/_core-concept/overview.html +66 -0
  77. package/docs/crawl/docs/_core-concept/subscriber.html +75 -0
  78. package/docs/crawl/docs/_decorators/ancestor-attribute.html +117 -0
  79. package/docs/crawl/docs/_decorators/auto-subscribe.html +202 -0
  80. package/docs/crawl/docs/_decorators/bind.html +141 -0
  81. package/docs/crawl/docs/_decorators/get.html +149 -0
  82. package/docs/crawl/docs/_decorators/handle.html +165 -0
  83. package/docs/crawl/docs/_decorators/on-assign.html +355 -0
  84. package/docs/crawl/docs/_decorators/patch.html +78 -0
  85. package/docs/crawl/docs/_decorators/post.html +139 -0
  86. package/docs/crawl/docs/_decorators/publish.html +61 -0
  87. package/docs/crawl/docs/_decorators/put.html +78 -0
  88. package/docs/crawl/docs/_decorators/subscribe.html +109 -0
  89. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +137 -0
  90. package/docs/crawl/docs/_directives/sub.html +93 -0
  91. package/docs/{docs/getting-started → crawl/docs/_getting-started}/ai-agents.html +11 -12
  92. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +100 -0
  93. package/docs/crawl/docs/_getting-started/concorde-outside.html +58 -0
  94. package/docs/{docs/getting-started → crawl/docs/_getting-started}/create-a-component.html +14 -11
  95. package/docs/{docs/getting-started → crawl/docs/_getting-started}/my-first-component.html +22 -13
  96. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +110 -0
  97. package/docs/crawl/docs/_getting-started/pubsub.html +62 -0
  98. package/docs/crawl/docs/_getting-started/start.html +76 -0
  99. package/docs/{docs/getting-started → crawl/docs/_getting-started}/theming.html +9 -10
  100. package/docs/{docs/misc → crawl/docs/_misc}/api-configuration.html +18 -18
  101. package/docs/{docs/misc → crawl/docs/_misc}/dataProviderKey.html +11 -12
  102. package/docs/{docs/misc → crawl/docs/_misc}/docs-mock-api.html +28 -25
  103. package/docs/{docs/misc → crawl/docs/_misc}/dynamic-path.html +15 -16
  104. package/docs/{docs/misc → crawl/docs/_misc}/endpoint.html +15 -16
  105. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +138 -0
  106. package/docs/{docs/misc → crawl/docs/_misc}/html-integration.html +15 -12
  107. package/docs/crawl/hubs/decorators.html +547 -0
  108. package/docs/crawl/hubs/form-components.html +381 -0
  109. package/docs/crawl/hubs/remote-data.html +452 -0
  110. package/docs/crawl/index.html +103 -0
  111. package/docs/docs-mock-api-sw.js +223 -58
  112. package/docs/docs-mock-api-sw.js.map +4 -4
  113. package/docs/index.html +68 -95
  114. package/docs/llms-full.txt +3610 -2231
  115. package/docs/llms.txt +86 -94
  116. package/docs/robots.txt +10 -11
  117. package/docs/sitemap.xml +84 -78
  118. package/docs/src/core/components/functional/date/date.md +231 -91
  119. package/docs/src/core/components/functional/fetch/fetch.md +83 -66
  120. package/docs/src/core/components/functional/if/if.md +3 -28
  121. package/docs/src/core/components/functional/jsonata/jsonata.md +37 -42
  122. package/docs/src/core/components/functional/list/list.md +43 -99
  123. package/docs/src/core/components/functional/mix/mix.md +26 -31
  124. package/docs/src/core/components/functional/queue/queue.md +61 -40
  125. package/docs/src/core/components/functional/router/router.md +65 -64
  126. package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  127. package/docs/src/core/components/functional/sdui/component-catalog.json +1 -1
  128. package/docs/src/core/components/functional/sdui/example.json +86 -19
  129. package/docs/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
  130. package/docs/src/core/components/functional/sdui/sdui.md +358 -187
  131. package/docs/src/core/components/functional/states/states.md +61 -86
  132. package/docs/src/core/components/functional/submit/submit.md +72 -64
  133. package/docs/src/core/components/functional/value/value.md +22 -34
  134. package/docs/src/core/components/ui/alert/alert.md +58 -48
  135. package/docs/src/core/components/ui/badge/badge.md +34 -27
  136. package/docs/src/core/components/ui/button/button.md +106 -139
  137. package/docs/src/core/components/ui/captcha/captcha.md +32 -17
  138. package/docs/src/core/components/ui/card/card.md +6 -6
  139. package/docs/src/core/components/ui/divider/divider.md +11 -8
  140. package/docs/src/core/components/ui/form/checkbox/checkbox.md +42 -90
  141. package/docs/src/core/components/ui/form/fieldset/fieldset.md +75 -31
  142. package/docs/src/core/components/ui/form/form-actions/form-actions.md +16 -14
  143. package/docs/src/core/components/ui/form/form-layout/form-layout.md +29 -19
  144. package/docs/src/core/components/ui/form/input/input.md +95 -95
  145. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +29 -0
  146. package/docs/src/core/components/ui/form/radio/radio.md +34 -55
  147. package/docs/src/core/components/ui/form/select/select.md +45 -60
  148. package/docs/src/core/components/ui/form/switch/switch.md +34 -57
  149. package/docs/src/core/components/ui/form/textarea/textarea.md +38 -55
  150. package/docs/src/core/components/ui/group/group.md +33 -35
  151. package/docs/src/core/components/ui/icon/icon.md +4 -4
  152. package/docs/src/core/components/ui/image/image.md +107 -41
  153. package/docs/src/core/components/ui/link/link.md +6 -6
  154. package/docs/src/core/components/ui/loader/loader.md +55 -30
  155. package/docs/src/core/components/ui/menu/menu.md +27 -27
  156. package/docs/src/core/components/ui/modal/modal.md +96 -72
  157. package/docs/src/core/components/ui/pop/pop.md +158 -80
  158. package/docs/src/core/components/ui/progress/progress.md +2 -2
  159. package/docs/src/core/components/ui/table/table.md +255 -91
  160. package/docs/src/core/components/ui/theme/theme.md +36 -11
  161. package/docs/src/core/components/ui/toast/toast.md +117 -48
  162. package/docs/src/core/components/ui/tooltip/tooltip.md +62 -27
  163. package/docs/{docs/getting-started → src/docs/_core-concept}/dataFlow.md +18 -17
  164. package/docs/src/docs/_core-concept/overview.md +57 -0
  165. package/docs/src/docs/_core-concept/subscriber.md +75 -0
  166. package/docs/src/docs/_decorators/ancestor-attribute.md +128 -0
  167. package/docs/src/docs/_decorators/auto-subscribe.md +202 -0
  168. package/docs/src/docs/_decorators/bind.md +167 -0
  169. package/docs/src/docs/_decorators/get.md +162 -0
  170. package/docs/src/docs/_decorators/handle.md +175 -0
  171. package/docs/src/docs/_decorators/on-assign.md +390 -0
  172. package/docs/src/docs/_decorators/patch.md +70 -0
  173. package/docs/src/docs/_decorators/post.md +146 -0
  174. package/docs/src/docs/_decorators/publish.md +55 -0
  175. package/docs/src/docs/_decorators/put.md +70 -0
  176. package/docs/src/docs/_decorators/subscribe.md +100 -0
  177. package/docs/src/docs/_decorators/wait-for-ancestors.md +163 -0
  178. package/docs/src/docs/_directives/sub.md +91 -0
  179. package/docs/src/docs/{getting-started → _getting-started}/ai-agents.md +3 -3
  180. package/docs/src/docs/_getting-started/concorde-manual-install.md +133 -0
  181. package/docs/src/docs/_getting-started/concorde-outside.md +33 -0
  182. package/docs/{docs/getting-started → src/docs/_getting-started}/create-a-component.md +6 -3
  183. package/docs/src/docs/{getting-started → _getting-started}/my-first-component.md +14 -5
  184. package/docs/src/docs/_getting-started/my-first-subscriber.md +120 -0
  185. package/docs/src/docs/_getting-started/pubsub.md +37 -0
  186. package/docs/src/docs/{getting-started → _getting-started}/start.md +13 -1
  187. package/docs/src/docs/{getting-started → _getting-started}/theming.md +2 -2
  188. package/docs/src/docs/{misc → _misc}/api-configuration.md +12 -10
  189. package/docs/src/docs/{misc → _misc}/dataProviderKey.md +4 -4
  190. package/docs/{docs/misc → src/docs/_misc}/docs-mock-api.md +13 -12
  191. package/docs/{docs/misc → src/docs/_misc}/dynamic-path.md +8 -8
  192. package/docs/{docs/misc → src/docs/_misc}/endpoint.md +8 -8
  193. package/docs/src/docs/_misc/formelement-subscriber-removal.md +115 -0
  194. package/docs/{docs/misc → src/docs/_misc}/html-integration.md +5 -4
  195. package/docs/src/docs/search/docs-search.json +4375 -2420
  196. package/docs/src/tsconfig.declarations.json +22 -0
  197. package/docs/src/tsconfig.emit.json +23 -0
  198. package/docs/src/tsconfig.json +2 -23
  199. package/gitlab/job_github_mirror.sh +39 -0
  200. package/index.html +89 -0
  201. package/package.json +22 -4
  202. package/public/img/og-concorde.jpg +0 -0
  203. package/scripts/ai-init.mjs +104 -379
  204. package/scripts/ai-init.test.mjs +81 -239
  205. package/scripts/docs-markdown-vite-plugin.ts +11 -5
  206. package/scripts/docs-public-url.mjs +6 -0
  207. package/scripts/docs.htaccess +7 -0
  208. package/scripts/generate-cem.mjs +244 -0
  209. package/scripts/generate-cem.test.mjs +122 -0
  210. package/scripts/generate-crawl-docs.mjs +29 -5
  211. package/scripts/generate-sdui-catalog.mjs +11 -10
  212. package/scripts/github-export.mjs +150 -0
  213. package/scripts/post-build-docs.js +3 -0
  214. package/scripts/post-build.mjs +0 -0
  215. package/scripts/pre-publish.mjs +2 -1
  216. package/scripts/site-pages.mjs +212 -0
  217. package/scripts/site-pages.test.mjs +116 -0
  218. package/site-pages/about.md +22 -0
  219. package/site-pages/privacy.md +32 -0
  220. package/src/core/components/functional/date/date.md +1 -1
  221. package/src/core/components/functional/example/example.ts +3 -1
  222. package/src/core/components/functional/if/if.ts +0 -0
  223. package/src/core/components/functional/list/list.demo.ts +0 -0
  224. package/src/core/components/functional/list/list.md +6 -2
  225. package/src/core/components/functional/list/list.ts +17 -4
  226. package/src/core/components/functional/mix/mix.md +0 -0
  227. package/src/core/components/functional/router/router.demo.ts +0 -0
  228. package/src/core/components/functional/router/router.ts +0 -0
  229. package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +0 -0
  230. package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  231. package/src/core/components/functional/sdui/component-catalog.json +2 -2
  232. package/src/core/components/functional/sdui/example.json +0 -0
  233. package/src/core/components/functional/sdui/sdui-immutable.spec.ts +74 -0
  234. package/src/core/components/functional/sdui/sdui.ts +33 -8
  235. package/src/core/components/functional/sdui/types.ts +0 -0
  236. package/src/core/components/functional/states/states.ts +0 -0
  237. package/src/core/components/functional/submit/submit.spec.ts +60 -0
  238. package/src/core/components/functional/submit/submit.ts +6 -3
  239. package/src/core/components/functional/subscriber/subscriber.ts +0 -0
  240. package/src/core/components/functional/value/value.md +0 -0
  241. package/src/core/components/functional/value/value.ts +0 -0
  242. package/src/core/components/ui/_css/size.ts +0 -0
  243. package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
  244. package/src/core/components/ui/card/card.md +1 -1
  245. package/src/core/components/ui/form/input/input.md +19 -1
  246. package/src/core/components/ui/form/input/input.ts +8 -2
  247. package/src/core/components/ui/form/radio/radio.md +14 -0
  248. package/src/core/components/ui/image/image.md +17 -17
  249. package/src/core/components/ui/modal/modal.md +2 -2
  250. package/src/core/decorators/subscriber/bind.ts +9 -14
  251. package/src/core/decorators/subscriber/subscribe.ts +15 -9
  252. package/src/core/decorators/subscriber/subscribe.type-test.ts +14 -5
  253. package/src/core/mixins/Subscriber.ts +0 -0
  254. package/src/core/utils/DataBindObserver.ts +0 -0
  255. package/src/core/utils/Objects.ts +0 -0
  256. package/src/core/utils/PublisherProxy.ts +166 -125
  257. package/src/core/utils/deepReadonly.spec.ts +66 -0
  258. package/src/core/utils/deepReadonly.ts +71 -0
  259. package/src/core/utils/immutableValue.spec.ts +54 -0
  260. package/src/core/utils/immutableValue.ts +102 -0
  261. package/src/core/utils/nestedDotForm.spec.ts +88 -0
  262. package/src/core/utils/publisherImmutable.spec.ts +76 -0
  263. package/src/core/utils/route.ts +0 -0
  264. package/src/core/utils/strictGet.spec.ts +61 -0
  265. package/src/core/utils/strictGet.ts +102 -0
  266. package/src/css.d.ts +19 -0
  267. package/src/docs/components/docs-demo-sources.ts +3 -3
  268. package/src/docs/decorators/bind.md +23 -24
  269. package/src/docs/docs-location.spec.ts +10 -0
  270. package/src/docs/docs-location.ts +10 -0
  271. package/src/docs/example/decorators-demo-bind-demos.ts +11 -28
  272. package/src/docs/example/docs-toggle-demos.ts +1 -1
  273. package/src/docs/example/users.ts +0 -0
  274. package/src/docs/getting-started/ai-agents.md +29 -55
  275. package/src/docs/getting-started/dataFlow.md +2 -2
  276. package/src/docs/home/home.ts +3 -1
  277. package/src/docs/misc/publisher-get-immutability-docs-crawl.json +902 -0
  278. package/src/docs/misc/publisher-get-immutability-docs-recheck.json +13 -0
  279. package/src/docs/misc/publisher-get-immutability-study.md +229 -0
  280. package/src/docs/navigation/navigation.ts +5 -1
  281. package/src/docs/search/docs-search.json +358 -58
  282. package/src/docs/search/markdown-renderer.ts +6 -1
  283. package/src/docs/tailwind/css/docs/content.css +4 -5
  284. package/src/tsconfig.declarations.json +22 -0
  285. package/src/tsconfig.emit.json +23 -0
  286. package/src/tsconfig.json +53 -5
  287. package/src/tsconfig.tsbuildinfo +1 -1
  288. package/.taste-skill/after/desktop-fold.jpg +0 -0
  289. package/.taste-skill/after/desktop-page-01.jpg +0 -0
  290. package/.taste-skill/after/desktop-page-02.jpg +0 -0
  291. package/.taste-skill/after/desktop-page-03.jpg +0 -0
  292. package/.taste-skill/after/mobile-fold.jpg +0 -0
  293. package/.taste-skill/after/mobile-page-01.jpg +0 -0
  294. package/.taste-skill/after/report.json +0 -4103
  295. package/.taste-skill/after/tablet-fold.jpg +0 -0
  296. package/.taste-skill/after/tablet-page-01.jpg +0 -0
  297. package/.taste-skill/after/tablet-page-02.jpg +0 -0
  298. package/.taste-skill/before/desktop-fold.jpg +0 -0
  299. package/.taste-skill/before/desktop-page-01.jpg +0 -0
  300. package/.taste-skill/before/desktop-page-02.jpg +0 -0
  301. package/.taste-skill/before/mobile-fold.jpg +0 -0
  302. package/.taste-skill/before/mobile-page-01.jpg +0 -0
  303. package/.taste-skill/before/report.json +0 -2556
  304. package/.taste-skill/before/tablet-fold.jpg +0 -0
  305. package/.taste-skill/before/tablet-page-01.jpg +0 -0
  306. package/.taste-skill/direction.json +0 -510
  307. package/.taste-skill/notes.md +0 -84
  308. package/.taste-skill/prod/desktop-fold.jpg +0 -0
  309. package/.taste-skill/prod/desktop-page-01.jpg +0 -0
  310. package/.taste-skill/prod/desktop-page-02.jpg +0 -0
  311. package/.taste-skill/prod/desktop-page-03.jpg +0 -0
  312. package/.taste-skill/prod/mobile-fold.jpg +0 -0
  313. package/.taste-skill/prod/mobile-page-01.jpg +0 -0
  314. package/.taste-skill/prod/mobile-page-02.jpg +0 -0
  315. package/.taste-skill/prod/report.json +0 -1973
  316. package/.taste-skill/prod/tablet-fold.jpg +0 -0
  317. package/.taste-skill/prod/tablet-page-01.jpg +0 -0
  318. package/.taste-skill/prod/tablet-page-02.jpg +0 -0
  319. package/AUDIT.md +0 -228
  320. package/PLAN-AMELIORATION.md +0 -220
  321. package/PLAN-DOCS-AGENTS.md +0 -80
  322. package/ai/AGENTS.md +0 -56
  323. package/ai/cursor/rules/concorde-menu.mdc +0 -15
  324. package/ai/cursor/rules/concorde-scope.mdc +0 -14
  325. package/ai/cursor/rules/concorde-theme.mdc +0 -13
  326. package/ai/cursor/rules/concorde.mdc +0 -66
  327. package/ai/jetbrains/rules/concorde.md +0 -53
  328. package/ai/skills/concorde-get-set-dp/SKILL.md +0 -194
  329. package/ai/skills/concorde-imports/SKILL.md +0 -78
  330. package/ai/skills/concorde-menu/SKILL.md +0 -74
  331. package/ai/skills/concorde-scope/SKILL.md +0 -70
  332. package/ai/skills/concorde-theme/SKILL.md +0 -57
  333. package/docs/.htaccess +0 -75
  334. package/docs/404.html +0 -15
  335. package/docs/404.md +0 -5
  336. package/docs/assets/index-BgG6FFPt.js +0 -11765
  337. package/docs/assets/index-x89XINSG.css +0 -1
  338. package/docs/core/components/functional/date/date.html +0 -211
  339. package/docs/core/components/functional/date/date.md +0 -150
  340. package/docs/core/components/functional/fetch/fetch.html +0 -180
  341. package/docs/core/components/functional/fetch/fetch.md +0 -108
  342. package/docs/core/components/functional/if/if.html +0 -65
  343. package/docs/core/components/functional/if/if.md +0 -34
  344. package/docs/core/components/functional/jsonata/jsonata.html +0 -110
  345. package/docs/core/components/functional/jsonata/jsonata.md +0 -61
  346. package/docs/core/components/functional/list/list.html +0 -198
  347. package/docs/core/components/functional/list/list.md +0 -121
  348. package/docs/core/components/functional/mix/mix.html +0 -78
  349. package/docs/core/components/functional/mix/mix.md +0 -46
  350. package/docs/core/components/functional/queue/queue.html +0 -155
  351. package/docs/core/components/functional/queue/queue.md +0 -51
  352. package/docs/core/components/functional/router/router.html +0 -154
  353. package/docs/core/components/functional/router/router.md +0 -93
  354. package/docs/core/components/functional/sdui/sdui-extension-points.md +0 -94
  355. package/docs/core/components/functional/sdui/sdui.html +0 -397
  356. package/docs/core/components/functional/sdui/sdui.md +0 -307
  357. package/docs/core/components/functional/states/states.html +0 -141
  358. package/docs/core/components/functional/states/states.md +0 -112
  359. package/docs/core/components/functional/submit/submit.html +0 -178
  360. package/docs/core/components/functional/submit/submit.md +0 -106
  361. package/docs/core/components/functional/subscriber/subscriber.md +0 -91
  362. package/docs/core/components/functional/translation/translation.html +0 -60
  363. package/docs/core/components/functional/translation/translation.md +0 -38
  364. package/docs/core/components/functional/value/value.html +0 -81
  365. package/docs/core/components/functional/value/value.md +0 -47
  366. package/docs/core/components/ui/alert/alert.md +0 -186
  367. package/docs/core/components/ui/alert-messages/alert-messages.md +0 -85
  368. package/docs/core/components/ui/badge/badge.md +0 -181
  369. package/docs/core/components/ui/button/button.html +0 -309
  370. package/docs/core/components/ui/button/button.md +0 -216
  371. package/docs/core/components/ui/captcha/captcha.html +0 -80
  372. package/docs/core/components/ui/captcha/captcha.md +0 -56
  373. package/docs/core/components/ui/card/card.md +0 -215
  374. package/docs/core/components/ui/divider/divider.md +0 -126
  375. package/docs/core/components/ui/form/checkbox/checkbox.html +0 -200
  376. package/docs/core/components/ui/form/checkbox/checkbox.md +0 -125
  377. package/docs/core/components/ui/form/fieldset/fieldset.html +0 -238
  378. package/docs/core/components/ui/form/fieldset/fieldset.md +0 -161
  379. package/docs/core/components/ui/form/form-actions/form-actions.md +0 -98
  380. package/docs/core/components/ui/form/form-layout/form-layout.html +0 -115
  381. package/docs/core/components/ui/form/form-layout/form-layout.md +0 -109
  382. package/docs/core/components/ui/form/input/input.html +0 -235
  383. package/docs/core/components/ui/form/input/input.md +0 -142
  384. package/docs/core/components/ui/form/radio/radio.html +0 -144
  385. package/docs/core/components/ui/form/radio/radio.md +0 -78
  386. package/docs/core/components/ui/form/select/select.html +0 -178
  387. package/docs/core/components/ui/form/select/select.md +0 -86
  388. package/docs/core/components/ui/form/switch/switch.html +0 -146
  389. package/docs/core/components/ui/form/switch/switch.md +0 -80
  390. package/docs/core/components/ui/form/textarea/textarea.html +0 -162
  391. package/docs/core/components/ui/form/textarea/textarea.md +0 -82
  392. package/docs/core/components/ui/group/group.html +0 -113
  393. package/docs/core/components/ui/group/group.md +0 -77
  394. package/docs/core/components/ui/icon/icon.md +0 -214
  395. package/docs/core/components/ui/image/image.html +0 -194
  396. package/docs/core/components/ui/image/image.md +0 -167
  397. package/docs/core/components/ui/link/link.md +0 -81
  398. package/docs/core/components/ui/loader/loader.html +0 -114
  399. package/docs/core/components/ui/loader/loader.md +0 -87
  400. package/docs/core/components/ui/menu/menu.md +0 -370
  401. package/docs/core/components/ui/modal/modal.html +0 -324
  402. package/docs/core/components/ui/modal/modal.md +0 -211
  403. package/docs/core/components/ui/pop/pop.html +0 -250
  404. package/docs/core/components/ui/pop/pop.md +0 -216
  405. package/docs/core/components/ui/progress/progress.md +0 -109
  406. package/docs/core/components/ui/table/table.html +0 -333
  407. package/docs/core/components/ui/table/table.md +0 -267
  408. package/docs/core/components/ui/theme/theme.html +0 -116
  409. package/docs/core/components/ui/theme/theme.md +0 -97
  410. package/docs/core/components/ui/toast/toast.html +0 -185
  411. package/docs/core/components/ui/toast/toast.md +0 -147
  412. package/docs/core/components/ui/tooltip/tooltip.html +0 -112
  413. package/docs/core/components/ui/tooltip/tooltip.md +0 -89
  414. package/docs/docs/decorators/ancestor-attribute.html +0 -71
  415. package/docs/docs/decorators/ancestor-attribute.md +0 -59
  416. package/docs/docs/decorators/auto-subscribe.html +0 -61
  417. package/docs/docs/decorators/auto-subscribe.md +0 -40
  418. package/docs/docs/decorators/bind.html +0 -86
  419. package/docs/docs/decorators/bind.md +0 -77
  420. package/docs/docs/decorators/get.html +0 -166
  421. package/docs/docs/decorators/get.md +0 -160
  422. package/docs/docs/decorators/handle.html +0 -139
  423. package/docs/docs/decorators/handle.md +0 -119
  424. package/docs/docs/decorators/on-assign.html +0 -72
  425. package/docs/docs/decorators/on-assign.md +0 -63
  426. package/docs/docs/decorators/patch.html +0 -76
  427. package/docs/docs/decorators/patch.md +0 -44
  428. package/docs/docs/decorators/post.html +0 -150
  429. package/docs/docs/decorators/post.md +0 -134
  430. package/docs/docs/decorators/publish.html +0 -74
  431. package/docs/docs/decorators/publish.md +0 -56
  432. package/docs/docs/decorators/put.html +0 -83
  433. package/docs/docs/decorators/put.md +0 -51
  434. package/docs/docs/decorators/subscribe.html +0 -91
  435. package/docs/docs/decorators/subscribe.md +0 -87
  436. package/docs/docs/decorators/wait-for-ancestors.html +0 -82
  437. package/docs/docs/decorators/wait-for-ancestors.md +0 -76
  438. package/docs/docs/directives/sub.html +0 -79
  439. package/docs/docs/directives/sub.md +0 -75
  440. package/docs/docs/directives/t.html +0 -91
  441. package/docs/docs/directives/t.md +0 -73
  442. package/docs/docs/getting-started/ai-agents.md +0 -76
  443. package/docs/docs/getting-started/components.html +0 -27
  444. package/docs/docs/getting-started/components.md +0 -5
  445. package/docs/docs/getting-started/installation.html +0 -69
  446. package/docs/docs/getting-started/installation.md +0 -36
  447. package/docs/docs/getting-started/my-first-component.md +0 -227
  448. package/docs/docs/getting-started/start.html +0 -47
  449. package/docs/docs/getting-started/start.md +0 -35
  450. package/docs/docs/getting-started/theming.md +0 -253
  451. package/docs/docs/index.html +0 -99
  452. package/docs/docs/misc/api-configuration.md +0 -79
  453. package/docs/docs/misc/dataProviderKey.md +0 -168
  454. package/docs/hubs/decorators.html +0 -443
  455. package/docs/hubs/form-components.html +0 -404
  456. package/docs/hubs/remote-data.html +0 -371
  457. package/docs/img/archive/concorde-001-2cv.webp +0 -0
  458. package/docs/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  459. package/docs/img/archive/concorde-red-arrows-2002.webm +0 -0
  460. package/docs/img/archive/credits.json +0 -28
  461. package/docs/index.md +0 -22
  462. package/docs/src/core/components/functional/translation/translation.md +0 -38
  463. package/docs/src/docs/decorators/ancestor-attribute.md +0 -59
  464. package/docs/src/docs/decorators/auto-subscribe.md +0 -40
  465. package/docs/src/docs/decorators/bind.md +0 -77
  466. package/docs/src/docs/decorators/get.md +0 -160
  467. package/docs/src/docs/decorators/handle.md +0 -119
  468. package/docs/src/docs/decorators/on-assign.md +0 -63
  469. package/docs/src/docs/decorators/patch.md +0 -44
  470. package/docs/src/docs/decorators/post.md +0 -134
  471. package/docs/src/docs/decorators/publish.md +0 -56
  472. package/docs/src/docs/decorators/put.md +0 -51
  473. package/docs/src/docs/decorators/subscribe.md +0 -87
  474. package/docs/src/docs/decorators/wait-for-ancestors.md +0 -76
  475. package/docs/src/docs/directives/sub.md +0 -75
  476. package/docs/src/docs/directives/t.md +0 -73
  477. package/docs/src/docs/getting-started/components.md +0 -5
  478. package/docs/src/docs/getting-started/create-a-component.md +0 -136
  479. package/docs/src/docs/getting-started/dataFlow.md +0 -87
  480. package/docs/src/docs/getting-started/installation.md +0 -36
  481. package/docs/src/docs/misc/docs-mock-api.md +0 -62
  482. package/docs/src/docs/misc/dynamic-path.md +0 -71
  483. package/docs/src/docs/misc/endpoint.md +0 -45
  484. package/docs/src/docs/misc/html-integration.md +0 -14
  485. /package/{docs → dist}/img/concorde/plane_01.jpg +0 -0
  486. /package/{docs → dist}/img/concorde/plane_02.jpg +0 -0
  487. /package/{docs → dist}/img/concorde/plane_03.jpg +0 -0
  488. /package/{docs → dist}/img/concorde/plane_04.jpg +0 -0
  489. /package/{docs → dist}/img/concorde/plane_05.jpg +0 -0
  490. /package/{docs → dist}/img/concorde/plane_06.jpg +0 -0
  491. /package/{docs → dist}/img/concorde/plane_07.jpg +0 -0
  492. /package/{docs → dist}/img/concorde/plane_08.jpg +0 -0
  493. /package/{docs → dist}/img/concorde/plane_09.jpg +0 -0
  494. /package/{docs → dist}/img/concorde/plane_10.jpg +0 -0
  495. /package/{docs → dist}/img/concorde/plane_11.jpg +0 -0
  496. /package/{docs → dist}/img/concorde/plane_12.jpg +0 -0
  497. /package/{docs → dist}/img/concorde/plane_13.jpg +0 -0
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Install Concorde AI agent files into a project.
3
+ * Install the Concorde agent skill into a project.
4
4
  *
5
5
  * Usage:
6
6
  * node node_modules/@supersoniks/concorde/scripts/ai-init.mjs [options]
@@ -9,31 +9,17 @@
9
9
  * Options:
10
10
  * --project-root <dir> Project root (default: cwd)
11
11
  * --concorde-ai <dir> Concorde ai/ folder (default: auto-detect)
12
- * --overlay <dir> Extra layer (project kit) — uses AGENTS.concorde.md
13
- * --cursor-only Install only Cursor (.cursor/)
14
- * --jetbrains-only Install only JetBrains (.aiassistant/rules/)
15
- * --skip-agents Never write AGENTS.md (skills/rules only)
16
- * --merge-agents Opt-in: keep project preamble, append/refresh Concorde block
17
- * --force-agents Opt-in: replace AGENTS.md entirely (destructive)
12
+ * --overlay <dir> Extra skills from a project kit (<dir>/skills/<name>/)
13
+ * --no-links Do not link skills into .claude/ and .junie/
18
14
  *
19
- * AGENTS.md policy (non-invasive by default):
20
- * - Missing file → create Concorde guide
21
- * - Existing with <!-- concorde-ai --> → refresh managed zone only
22
- * - Existing without marker → leave untouched (project-owned, e.g. billetterie)
23
- * unless --merge-agents or --force-agents
15
+ * Skills:
16
+ * - Copied to .agents/skills/<name>/ (read natively by Cursor and other
17
+ * agents following the Agent Skills convention)
18
+ * - Linked per skill from .claude/skills/ (Claude Code) and .junie/skills/
19
+ * (JetBrains Junie); copied instead where symlinks are not allowed
20
+ * - Project skills with the same folder name are never overwritten
24
21
  *
25
- * Layout when writing:
26
- *
27
- * [optional project preamble — short, project-only]
28
- * <!-- concorde-ai -->
29
- * <package ai/AGENTS.md>
30
- * [--- + overlay AGENTS.concorde.md]
31
- *
32
- * Everything AFTER the marker is owned by Concorde and replaced on every run.
33
- * Do not copy the full Concorde guide into the preamble — use overlay/AGENTS.concorde.md
34
- * for project-specific agent notes (endpoints, dpKeys, …).
35
- *
36
- * Legacy: AGENTS.starter.md / AGENTS.overlay.md still read if AGENTS.concorde.md is missing.
22
+ * AGENTS.md belongs to the project: ai-init never reads nor writes it.
37
23
  */
38
24
 
39
25
  import fs from "node:fs";
@@ -42,15 +28,6 @@ import {fileURLToPath, pathToFileURL} from "node:url";
42
28
 
43
29
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
44
30
 
45
- const AGENTS_MARKER = "<!-- concorde-ai -->";
46
- /** Project Concorde notes for `--overlay` (preferred). */
47
- const OVERLAY_AGENTS_FILE = "AGENTS.concorde.md";
48
- /** @deprecated Prefer AGENTS.concorde.md */
49
- const OVERLAY_AGENTS_FILE_LEGACY = [
50
- "AGENTS.overlay.md",
51
- "AGENTS.starter.md",
52
- ];
53
-
54
31
  const args = process.argv.slice(2);
55
32
 
56
33
  function readArg(name) {
@@ -66,36 +43,11 @@ const overlayDir = readArg("--overlay")
66
43
  ? path.resolve(readArg("--overlay"))
67
44
  : undefined;
68
45
 
69
- const cursorOnly = flags.has("--cursor-only");
70
- const jetbrainsOnly = flags.has("--jetbrains-only");
71
- const skipAgents = flags.has("--skip-agents");
72
- const mergeAgents = flags.has("--merge-agents");
73
- const forceAgents = flags.has("--force-agents");
74
- const installCursor = !jetbrainsOnly;
75
- const installJetbrains = !cursorOnly;
76
-
77
- /**
78
- * Decide whether / how to write AGENTS.md.
79
- * @returns {"skip" | "create" | "refresh" | "merge" | "force"}
80
- */
81
- export function decideAgentsAction({
82
- existingText = "",
83
- skipAgents: skip = false,
84
- mergeAgents: merge = false,
85
- forceAgents: force = false,
86
- } = {}) {
87
- if (skip) return "skip";
88
- const text = existingText.replace(/\r\n/g, "\n");
89
- const exists = text.trim().length > 0;
90
- const hasMarker = text.includes(AGENTS_MARKER);
91
-
92
- if (!exists) return "create";
93
- if (hasMarker) return "refresh";
94
- if (force) return "force";
95
- if (merge) return "merge";
96
- return "skip";
97
- }
98
-
46
+ const noLinks = flags.has("--no-links");
47
+ /** Canonical skills folder, relative to the project root. */
48
+ export const SKILLS_DIR = ".agents/skills";
49
+ /** Agent-specific skills folders that get one symlink per skill. */
50
+ export const SKILL_LINK_DIRS = [".claude/skills", ".junie/skills"];
99
51
  function detectConcordeAi() {
100
52
  const explicit = readArg("--concorde-ai");
101
53
  if (explicit) return path.resolve(explicit);
@@ -111,33 +63,6 @@ function detectConcordeAi() {
111
63
  );
112
64
  }
113
65
 
114
- /**
115
- * Read project Concorde AGENTS notes from `--overlay` dir.
116
- * Prefers AGENTS.concorde.md; falls back to deprecated legacy names.
117
- * @returns {{ content: string, warnings: string[] }}
118
- */
119
- export function readOverlayAgents(overlayDir) {
120
- const warnings = [];
121
- if (!overlayDir) return {content: "", warnings};
122
-
123
- const preferred = path.join(overlayDir, OVERLAY_AGENTS_FILE);
124
- if (fs.existsSync(preferred)) {
125
- return {content: fs.readFileSync(preferred, "utf8"), warnings};
126
- }
127
-
128
- for (const legacyName of OVERLAY_AGENTS_FILE_LEGACY) {
129
- const legacy = path.join(overlayDir, legacyName);
130
- if (fs.existsSync(legacy)) {
131
- warnings.push(
132
- `Overlay uses deprecated ${legacyName} — rename to ${OVERLAY_AGENTS_FILE}.`,
133
- );
134
- return {content: fs.readFileSync(legacy, "utf8"), warnings};
135
- }
136
- }
137
-
138
- return {content: "", warnings};
139
- }
140
-
141
66
  function copyDir(src, dest) {
142
67
  if (!fs.existsSync(src)) return;
143
68
  fs.mkdirSync(dest, {recursive: true});
@@ -153,229 +78,98 @@ function copyDir(src, dest) {
153
78
  }
154
79
  }
155
80
 
156
- function normalizeHeading(title) {
157
- return title
158
- .normalize("NFKD")
159
- .replace(/\p{M}/gu, "")
160
- .toLowerCase()
161
- .replace(/[^a-z0-9]+/g, " ")
162
- .trim();
81
+ function listSkillNames(dir) {
82
+ if (!fs.existsSync(dir)) return [];
83
+ return fs
84
+ .readdirSync(dir, {withFileTypes: true})
85
+ .filter((e) => e.isDirectory() && fs.existsSync(path.join(dir, e.name, "SKILL.md")))
86
+ .map((e) => e.name)
87
+ .sort();
163
88
  }
164
89
 
165
- function isStockConcordeH1(title) {
166
- // "# Agents — Concorde" with optional project suffix in parentheses
167
- return /^agents\s+concorde(\s|$)/i.test(normalizeHeading(title));
90
+ function removePath(p) {
91
+ fs.rmSync(p, {recursive: true, force: true});
168
92
  }
169
93
 
170
- /**
171
- * Split markdown into a leading H1 block + ## sections (## title → body).
172
- * @returns {{ h1: string | null, sections: Array<{ title: string, body: string }> }}
173
- */
174
- function splitAgentsSections(markdown) {
175
- const text = markdown.replace(/\r\n/g, "\n").trim();
176
- if (!text) return {h1: null, sections: []};
177
-
178
- const parts = text.split(/\n(?=##\s+)/);
179
- let h1 = null;
180
- const sections = [];
181
-
182
- for (const part of parts) {
183
- const trimmed = part.trim();
184
- if (!trimmed) continue;
185
- if (trimmed.startsWith("## ")) {
186
- const nl = trimmed.indexOf("\n");
187
- const titleLine = nl === -1 ? trimmed : trimmed.slice(0, nl);
188
- const title = titleLine.replace(/^##\s+/, "").trim();
189
- const body = nl === -1 ? "" : trimmed.slice(nl + 1).trim();
190
- sections.push({title, body});
191
- } else if (h1 === null) {
192
- h1 = trimmed;
193
- } else {
194
- // Orphan content without ## — keep as synthetic section
195
- sections.push({title: "", body: trimmed});
196
- }
94
+ function isSymlink(p) {
95
+ try {
96
+ return fs.lstatSync(p).isSymbolicLink();
97
+ } catch {
98
+ return false;
197
99
  }
198
-
199
- return {h1, sections};
200
100
  }
201
101
 
202
- function baseHeadingSet(baseContent) {
203
- const {sections} = splitAgentsSections(baseContent);
204
- return new Set(sections.map((s) => normalizeHeading(s.title)).filter(Boolean));
205
- }
206
-
207
- /** Match "## Skills / rules" with "## Skills / rules (après installation)". */
208
- function isSameAgentsHeading(a, b) {
209
- if (!a || !b) return false;
210
- if (a === b) return true;
211
- const stripParen = (s) => s.replace(/\s*\(.*\)$/, "").trim();
212
- const aa = stripParen(a);
213
- const bb = stripParen(b);
214
- if (aa === bb) return true;
215
- return aa.startsWith(bb) || bb.startsWith(aa);
216
- }
217
-
218
- function isPackageHeading(titleKey, baseHeads) {
219
- for (const bh of baseHeads) {
220
- if (isSameAgentsHeading(titleKey, bh)) return true;
102
+ function pathExists(p) {
103
+ try {
104
+ fs.lstatSync(p);
105
+ return true;
106
+ } catch {
107
+ return false;
221
108
  }
222
- return false;
223
109
  }
224
110
 
225
111
  /**
226
- * True when preamble looks like a full (or near-full) copy of package AGENTS.md.
112
+ * Copy skills into `<projectRoot>/.agents/skills`, replacing previous copies.
113
+ * @param {string[]} sourceDirs skills folders (package first, then overlay)
114
+ * @returns {string[]} installed skill names
227
115
  */
228
- export function preambleDuplicatesBase(preamble, baseContent) {
229
- const p = preamble.trim();
230
- const b = baseContent.trim();
231
- if (!p || !b) return false;
232
-
233
- const fingerprints = [
234
- "sonic-fetch",
235
- "publishermanager",
236
- "formdataprovider",
237
- "dataprovide",
238
- "concorde-get-set-dp",
239
- ];
240
- const pNorm = p.toLowerCase();
241
- const hits = fingerprints.filter((fp) => pNorm.includes(fp)).length;
242
- const longEnough = p.length >= b.length * 0.45;
243
- const stockTitle = /^#\s*agents\s*[—–-]\s*concorde\b/im.test(p);
244
-
245
- return stockTitle && longEnough && hits >= 3;
246
- }
247
-
248
- /**
249
- * Keep only project-specific preamble bits (unique ## vs package, short custom H1).
250
- * Drops sections that duplicate Concorde ai/AGENTS.md so re-runs heal stacked copies.
251
- */
252
- export function slimPreamble(preamble, baseContent) {
253
- const raw = preamble.trim();
254
- if (!raw) return "";
255
-
256
- const {h1, sections} = splitAgentsSections(raw);
257
- const h1Title = h1?.split("\n")[0]?.replace(/^#\s+/, "").trim() ?? "";
258
- // Full forks OR any preamble titled like Concorde AGENTS → strip package ## sections
259
- const shouldDedup =
260
- preambleDuplicatesBase(raw, baseContent) || isStockConcordeH1(h1Title);
261
-
262
- if (!shouldDedup) {
263
- return raw;
116
+ export function syncSkills(projectRoot, sourceDirs) {
117
+ const dest = path.join(projectRoot, SKILLS_DIR);
118
+ const installed = new Map();
119
+ for (const dir of sourceDirs) {
120
+ for (const name of listSkillNames(dir)) installed.set(name, path.join(dir, name));
264
121
  }
265
122
 
266
- const baseHeads = baseHeadingSet(baseContent);
267
- const kept = [];
268
-
269
- for (const section of sections) {
270
- const key = normalizeHeading(section.title);
271
- if (!key) {
272
- if (!preambleDuplicatesBase(section.body, baseContent)) {
273
- kept.push(section.body);
274
- }
275
- continue;
276
- }
277
- if (!isPackageHeading(key, baseHeads)) {
278
- kept.push(`## ${section.title}\n\n${section.body}`.trim());
279
- }
280
- }
281
-
282
- let intro = "";
283
- if (h1) {
284
- const firstLine = h1.split("\n")[0].trim();
285
- const title = firstLine.replace(/^#\s+/, "");
286
- if (isStockConcordeH1(title) && /[()]/.test(title)) {
287
- intro = firstLine;
288
- } else if (!isStockConcordeH1(title)) {
289
- intro = firstLine;
290
- }
123
+ for (const [name, from] of installed) {
124
+ const to = path.join(dest, name);
125
+ removePath(to);
126
+ copyDir(from, to);
291
127
  }
292
-
293
- return [intro, ...kept].filter(Boolean).join("\n\n").trim();
294
- }
295
-
296
- export function buildManagedAgents(baseContent, overlayContent) {
297
- const parts = [baseContent.trim()];
298
- if (overlayContent?.trim()) {
299
- parts.push(overlayContent.trim());
300
- }
301
- return parts.join("\n\n---\n\n");
128
+ return [...installed.keys()].sort();
302
129
  }
303
130
 
304
131
  /**
305
- * Build final AGENTS.md. Never stacks managed (post-marker) content.
306
- * @returns {{ markdown: string, warnings: string[] }}
132
+ * Link each skill from the agent-specific folders to `.agents/skills/<name>`.
133
+ * Skips a folder that already resolves to `.agents/skills` (whole-dir symlink).
134
+ * Replaces earlier links, and copies of package skills (`packageNames`); never
135
+ * overwrites a project's own skill of the same name. Falls back to a copy when
136
+ * symlinks are not allowed.
137
+ * @returns {Array<{ dir: string, mode: "linked" | "copied" | "shared" }>}
307
138
  */
308
- export function buildAgentsFile({
309
- existing = "",
310
- baseContent,
311
- overlayContent = "",
312
- mergeAgents: merge = false,
313
- forceAgents: force = false,
314
- }) {
315
- const warnings = [];
316
- const combined = buildManagedAgents(baseContent, overlayContent);
317
-
318
- // Destructive replace: ignore any existing project content
319
- if (force && !existing.replace(/\r\n/g, "\n").includes(AGENTS_MARKER)) {
320
- return {markdown: `${combined}\n`, warnings};
321
- }
322
-
323
- let preamble = "";
324
- const existingText = existing.replace(/\r\n/g, "\n");
325
-
326
- if (existingText.includes(AGENTS_MARKER)) {
327
- preamble = existingText.split(AGENTS_MARKER)[0].trimEnd();
328
- } else if (merge && existingText.trim()) {
329
- preamble = existingText.trimEnd();
330
- }
331
-
332
- const hadMarker = existingText.includes(AGENTS_MARKER);
333
-
334
- if (preamble) {
335
- const before = preamble;
336
- preamble = slimPreamble(preamble, baseContent);
337
- if (before.trim() && !preamble) {
338
- warnings.push(
339
- "AGENTS.md preamble duplicated Concorde ai/AGENTS.md — dropped. Put project-only notes in overlay AGENTS.concorde.md (or a short preamble before <!-- concorde-ai -->).",
340
- );
341
- } else if (before.trim() && preamble !== before.trim()) {
342
- warnings.push(
343
- "AGENTS.md preamble slimmed: removed sections that duplicate package AGENTS.md.",
344
- );
139
+ export function linkSkills(
140
+ projectRoot,
141
+ names,
142
+ {packageNames = [], linkDirs = SKILL_LINK_DIRS} = {},
143
+ ) {
144
+ const source = path.join(projectRoot, SKILLS_DIR);
145
+ const sourceReal = fs.realpathSync(source);
146
+ const results = [];
147
+
148
+ for (const linkDir of linkDirs) {
149
+ const dir = path.join(projectRoot, linkDir);
150
+ if (fs.existsSync(dir) && fs.realpathSync(dir) === sourceReal) {
151
+ results.push({dir: linkDir, mode: "shared"});
152
+ continue;
345
153
  }
154
+ fs.mkdirSync(dir, {recursive: true});
155
+ let mode = "linked";
156
+ for (const name of names) {
157
+ const target = path.join(dir, name);
158
+ if (pathExists(target)) {
159
+ const owned = isSymlink(target) || packageNames.includes(name);
160
+ if (!owned) continue;
161
+ removePath(target);
162
+ }
163
+ try {
164
+ fs.symlinkSync(path.relative(dir, path.join(source, name)), target, "dir");
165
+ } catch {
166
+ copyDir(path.join(source, name), target);
167
+ mode = "copied";
168
+ }
169
+ }
170
+ results.push({dir: linkDir, mode});
346
171
  }
347
-
348
- // Always emit the marker when refreshing a marked file or merging a preamble,
349
- // so re-runs stay idempotent even if the preamble was fully dropped.
350
- const emitMarker = hadMarker || Boolean(preamble) || merge;
351
- const markdown = emitMarker
352
- ? preamble
353
- ? `${preamble.trimEnd()}\n\n${AGENTS_MARKER}\n\n${combined}\n`
354
- : `${AGENTS_MARKER}\n\n${combined}\n`
355
- : `${combined}\n`;
356
-
357
- return {markdown, warnings};
358
- }
359
-
360
- export function mergeAgentsFile(targetPath, baseContent, overlayContent, options = {}) {
361
- const merge = options.mergeAgents ?? false;
362
- const force = options.forceAgents ?? false;
363
- let existing = "";
364
- if (fs.existsSync(targetPath)) {
365
- existing = fs.readFileSync(targetPath, "utf8");
366
- }
367
-
368
- const {markdown, warnings} = buildAgentsFile({
369
- existing,
370
- baseContent,
371
- overlayContent,
372
- mergeAgents: merge,
373
- forceAgents: force,
374
- });
375
-
376
- fs.mkdirSync(path.dirname(targetPath), {recursive: true});
377
- fs.writeFileSync(targetPath, markdown);
378
- return warnings;
172
+ return results;
379
173
  }
380
174
 
381
175
  function main() {
@@ -385,96 +179,27 @@ function main() {
385
179
  console.log(` source: ${concordeAi}`);
386
180
  if (overlayDir) console.log(` overlay: ${overlayDir}`);
387
181
 
388
- if (installCursor) {
389
- copyDir(
390
- path.join(concordeAi, "cursor", "rules"),
391
- path.join(projectRoot, ".cursor", "rules"),
392
- );
393
- copyDir(
394
- path.join(concordeAi, "skills"),
395
- path.join(projectRoot, ".cursor", "skills"),
396
- );
397
-
398
- if (overlayDir) {
399
- copyDir(
400
- path.join(overlayDir, "cursor", "rules"),
401
- path.join(projectRoot, ".cursor", "rules"),
402
- );
403
- copyDir(
404
- path.join(overlayDir, "skills"),
405
- path.join(projectRoot, ".cursor", "skills"),
406
- );
407
- }
408
- }
409
-
410
- if (installJetbrains) {
411
- copyDir(
412
- path.join(concordeAi, "jetbrains", "rules"),
413
- path.join(projectRoot, ".aiassistant", "rules"),
414
- );
415
-
416
- if (overlayDir) {
417
- copyDir(
418
- path.join(overlayDir, "jetbrains", "rules"),
419
- path.join(projectRoot, ".aiassistant", "rules"),
420
- );
421
- }
422
- }
423
-
424
- const agentsPath = path.join(projectRoot, "AGENTS.md");
425
- let existingAgents = "";
426
- if (fs.existsSync(agentsPath)) {
427
- existingAgents = fs.readFileSync(agentsPath, "utf8");
428
- }
429
-
430
- const action = decideAgentsAction({
431
- existingText: existingAgents,
432
- skipAgents,
433
- mergeAgents,
434
- forceAgents,
435
- });
436
-
437
- if (action === "skip") {
438
- if (skipAgents) {
439
- console.log(" ⊘ AGENTS.md skipped (--skip-agents)");
440
- } else if (existingAgents.trim()) {
441
- console.log(
442
- " ⊘ AGENTS.md left untouched (project-owned, no <!-- concorde-ai --> marker).",
443
- );
444
- console.log(
445
- " Use --merge-agents to append a Concorde block, or --force-agents to replace.",
446
- );
447
- } else {
448
- console.log(" ⊘ AGENTS.md skipped");
449
- }
450
- } else {
451
- const baseAgents = fs.readFileSync(path.join(concordeAi, "AGENTS.md"), "utf8");
452
- const {content: overlayAgents, warnings: overlayWarnings} =
453
- readOverlayAgents(overlayDir);
454
-
455
- const warnings = [
456
- ...overlayWarnings,
457
- ...mergeAgentsFile(agentsPath, baseAgents, overlayAgents, {
458
- mergeAgents: action === "merge" || action === "refresh",
459
- forceAgents: action === "force",
460
- }),
461
- ];
462
- for (const w of warnings) {
463
- console.warn(` ⚠ ${w}`);
182
+ const packageSkills = path.join(concordeAi, "skills");
183
+ const skillNames = syncSkills(projectRoot, [
184
+ packageSkills,
185
+ ...(overlayDir ? [path.join(overlayDir, "skills")] : []),
186
+ ]);
187
+ console.log(` ✓ ${SKILLS_DIR} (${skillNames.join(", ")})`);
188
+
189
+ if (!noLinks) {
190
+ for (const {dir, mode} of linkSkills(projectRoot, skillNames, {
191
+ packageNames: listSkillNames(packageSkills),
192
+ })) {
193
+ const label =
194
+ mode === "shared"
195
+ ? `already points to ${SKILLS_DIR}`
196
+ : mode === "copied"
197
+ ? "copied (symlinks not allowed here)"
198
+ : "linked";
199
+ console.log(` ✓ ${dir} (${label})`);
464
200
  }
465
- const label =
466
- action === "create"
467
- ? "created"
468
- : action === "merge"
469
- ? "merged"
470
- : action === "force"
471
- ? "replaced (--force-agents)"
472
- : "refreshed";
473
- console.log(` ✓ AGENTS.md (${label})`);
474
201
  }
475
202
 
476
- if (installCursor) console.log(" ✓ .cursor/skills + .cursor/rules");
477
- if (installJetbrains) console.log(" ✓ .aiassistant/rules");
478
203
  console.log("Done.");
479
204
  }
480
205