@supersoniks/concorde 5.1.2 → 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 (130) hide show
  1. package/.agents/skills/concorde-docs/SKILL.md +1 -1
  2. package/README.md +1 -1
  3. package/ai/README.md +29 -41
  4. package/ai/skills/concorde/SKILL.md +54 -324
  5. package/ai/skills/concorde/rules/composition.md +32 -0
  6. package/ai/skills/concorde/rules/data.md +47 -0
  7. package/ai/skills/concorde/rules/http.md +25 -0
  8. package/ai/skills/concorde/rules/lists-forms.md +35 -0
  9. package/ai/skills/concorde/rules/styling.md +46 -0
  10. package/ai/skills/concorde/rules/troubleshooting.md +45 -0
  11. package/build-infos.json +1 -1
  12. package/concorde-core.bundle.js +21 -21
  13. package/concorde-core.es.js +977 -980
  14. package/custom-elements-manifest.public.config.mjs +8 -0
  15. package/{.tmp-cem/custom-elements.json → custom-elements.json} +11722 -8868
  16. package/dist/concorde-core.bundle.js +21 -21
  17. package/dist/concorde-core.es.js +977 -980
  18. package/dist/docs-mock-api-sw.js +58 -223
  19. package/dist/docs-mock-api-sw.js.map +4 -4
  20. package/dist/img/concorde/plane_01.jpg +0 -0
  21. package/dist/img/concorde/plane_02.jpg +0 -0
  22. package/dist/img/concorde/plane_03.jpg +0 -0
  23. package/dist/img/concorde/plane_04.jpg +0 -0
  24. package/dist/img/concorde/plane_05.jpg +0 -0
  25. package/dist/img/concorde/plane_06.jpg +0 -0
  26. package/dist/img/concorde/plane_07.jpg +0 -0
  27. package/dist/img/concorde/plane_08.jpg +0 -0
  28. package/dist/img/concorde/plane_09.jpg +0 -0
  29. package/dist/img/concorde/plane_10.jpg +0 -0
  30. package/dist/img/concorde/plane_11.jpg +0 -0
  31. package/dist/img/concorde/plane_12.jpg +0 -0
  32. package/dist/img/concorde/plane_13.jpg +0 -0
  33. package/dist/img/og-concorde.jpg +0 -0
  34. package/dist/robots.txt +11 -10
  35. package/docs/.htaccess +7 -0
  36. package/docs/about.html +111 -0
  37. package/docs/about.md +22 -0
  38. package/docs/assets/{index-BgG6FFPt.js → index-6sS76xWj.js} +482 -500
  39. package/docs/assets/{index-x89XINSG.css → index-DkdPbH0F.css} +1 -1
  40. package/docs/core/components/functional/date/date.md +1 -1
  41. package/docs/core/components/functional/list/list.html +7 -5
  42. package/docs/core/components/functional/list/list.md +6 -2
  43. package/docs/core/components/ui/card/card.html +1 -1
  44. package/docs/core/components/ui/card/card.md +1 -1
  45. package/docs/core/components/ui/image/image.html +17 -17
  46. package/docs/core/components/ui/image/image.md +17 -17
  47. package/docs/core/components/ui/modal/modal.html +2 -2
  48. package/docs/core/components/ui/modal/modal.md +2 -2
  49. package/docs/custom-elements.json +16559 -0
  50. package/docs/docs/decorators/bind.html +22 -21
  51. package/docs/docs/decorators/bind.md +23 -24
  52. package/docs/docs/getting-started/ai-agents.html +50 -94
  53. package/docs/docs/getting-started/ai-agents.md +29 -55
  54. package/docs/docs/getting-started/dataFlow.html +1 -1
  55. package/docs/docs/getting-started/dataFlow.md +1 -1
  56. package/docs/docs/index.html +1 -1
  57. package/docs/hubs/decorators.html +11 -16
  58. package/docs/hubs/remote-data.html +5 -9
  59. package/docs/img/og-concorde.jpg +0 -0
  60. package/docs/index.html +91 -2
  61. package/docs/index.md +2 -2
  62. package/docs/llms-full.txt +58 -74
  63. package/docs/llms.txt +6 -4
  64. package/docs/privacy.html +122 -0
  65. package/docs/privacy.md +32 -0
  66. package/docs/sitemap.xml +6 -0
  67. package/docs/src/core/components/functional/date/date.md +1 -1
  68. package/docs/src/core/components/functional/list/list.md +6 -2
  69. package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  70. package/docs/src/core/components/functional/sdui/component-catalog.json +1 -1
  71. package/docs/src/core/components/ui/card/card.md +1 -1
  72. package/docs/src/core/components/ui/image/image.md +17 -17
  73. package/docs/src/core/components/ui/modal/modal.md +2 -2
  74. package/docs/src/docs/decorators/bind.md +23 -24
  75. package/docs/src/docs/getting-started/ai-agents.md +29 -55
  76. package/docs/src/docs/getting-started/dataFlow.md +1 -1
  77. package/docs/src/docs/search/docs-search.json +100 -55
  78. package/docs/src/tsconfig.json +11 -5
  79. package/index.html +89 -0
  80. package/package.json +8 -4
  81. package/public/img/og-concorde.jpg +0 -0
  82. package/scripts/ai-init.mjs +104 -379
  83. package/scripts/ai-init.test.mjs +81 -239
  84. package/scripts/docs-markdown-vite-plugin.ts +11 -5
  85. package/scripts/docs-public-url.mjs +6 -0
  86. package/scripts/docs.htaccess +7 -0
  87. package/scripts/generate-cem.mjs +244 -0
  88. package/scripts/generate-cem.test.mjs +122 -0
  89. package/scripts/generate-crawl-docs.mjs +29 -5
  90. package/scripts/generate-sdui-catalog.mjs +11 -10
  91. package/scripts/post-build-docs.js +3 -0
  92. package/scripts/pre-publish.mjs +2 -1
  93. package/scripts/site-pages.mjs +212 -0
  94. package/scripts/site-pages.test.mjs +116 -0
  95. package/site-pages/about.md +22 -0
  96. package/site-pages/privacy.md +32 -0
  97. package/src/core/components/functional/date/date.md +1 -1
  98. package/src/core/components/functional/list/list.md +6 -2
  99. package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  100. package/src/core/components/functional/sdui/component-catalog.json +1 -1
  101. package/src/core/components/ui/card/card.md +1 -1
  102. package/src/core/components/ui/image/image.md +17 -17
  103. package/src/core/components/ui/modal/modal.md +2 -2
  104. package/src/core/decorators/subscriber/bind.ts +9 -14
  105. package/src/docs/components/docs-demo-sources.ts +3 -3
  106. package/src/docs/decorators/bind.md +23 -24
  107. package/src/docs/docs-location.spec.ts +10 -0
  108. package/src/docs/docs-location.ts +10 -0
  109. package/src/docs/example/decorators-demo-bind-demos.ts +11 -28
  110. package/src/docs/example/docs-toggle-demos.ts +1 -1
  111. package/src/docs/getting-started/ai-agents.md +29 -55
  112. package/src/docs/getting-started/dataFlow.md +1 -1
  113. package/src/docs/home/home.ts +3 -1
  114. package/src/docs/navigation/navigation.ts +1 -1
  115. package/src/docs/search/docs-search.json +100 -55
  116. package/src/docs/search/markdown-renderer.ts +6 -1
  117. package/src/docs/tailwind/css/docs/content.css +4 -5
  118. package/src/tsconfig.json +11 -5
  119. package/src/tsconfig.tsbuildinfo +1 -1
  120. package/ai/AGENTS.md +0 -56
  121. package/ai/cursor/rules/concorde-menu.mdc +0 -15
  122. package/ai/cursor/rules/concorde-scope.mdc +0 -14
  123. package/ai/cursor/rules/concorde-theme.mdc +0 -13
  124. package/ai/cursor/rules/concorde.mdc +0 -66
  125. package/ai/jetbrains/rules/concorde.md +0 -53
  126. package/ai/skills/concorde-get-set-dp/SKILL.md +0 -194
  127. package/ai/skills/concorde-imports/SKILL.md +0 -78
  128. package/ai/skills/concorde-menu/SKILL.md +0 -74
  129. package/ai/skills/concorde-scope/SKILL.md +0 -70
  130. package/ai/skills/concorde-theme/SKILL.md +0 -57
package/docs/sitemap.xml CHANGED
@@ -9,6 +9,12 @@
9
9
  <url>
10
10
  <loc>https://concorde.supersoniks.org/docs/index.html</loc>
11
11
  </url>
12
+ <url>
13
+ <loc>https://concorde.supersoniks.org/about</loc>
14
+ </url>
15
+ <url>
16
+ <loc>https://concorde.supersoniks.org/privacy</loc>
17
+ </url>
12
18
  <url>
13
19
  <loc>https://concorde.supersoniks.org/hubs/decorators.html</loc>
14
20
  </url>
@@ -116,7 +116,7 @@ A child `<template data-value="<part>">` wraps a part in your own markup: `weekd
116
116
  <template data-value="year"><span class="block text-lg font-bold leading-tight"></span></template>
117
117
  <template data-value="to"><span class="block my-1 text-3xl leading-none">↓</span></template>
118
118
  </sonic-date>
119
- <sonic-image src="img/concorde/plane_03.jpg" alt="Concorde specifications board" ratio="1/1" cover></sonic-image>
119
+ <sonic-image src="/img/concorde/plane_03.jpg" alt="Concorde specifications board" ratio="1/1" cover></sonic-image>
120
120
  </div>
121
121
  </template>
122
122
  </sonic-code>
@@ -1,6 +1,6 @@
1
1
  # List
2
2
 
3
- **`sonic-list`** renders one row per entry of its `props` array, either set directly or loaded with `fetch`. From Lit, pass a row renderer on the `items` property; in plain HTML, declare `<template>` children. Each row gets its own data provider at `<dataProvider>/list-item/<index>`.
3
+ **`sonic-list`** renders one row per entry of its `props` array, either set directly or loaded with `fetch`. In TypeScript, prefer the `.items` row renderer (with `.separator` · `.noItems` · `.skeleton`); `<template>` children are for plain HTML hosts without Lit. Each row gets its own data provider at `<dataProvider>/list-item/<index>`.
4
4
 
5
5
  ## Basic example
6
6
 
@@ -16,7 +16,7 @@ Add `fetch` to load `props` from `serviceURL` + `endPoint` (or `dataProvider` wh
16
16
  </template>
17
17
  </sonic-code>
18
18
 
19
- Fetch attributes (`lazyload` · `refetchEveryMs` · headers · authentication) are shared with [Fetch](/core/components/functional/fetch).
19
+ This example uses HTML templates; from Lit, use the [row renderer](#row-renderer) instead. Fetch attributes (`lazyload` · `refetchEveryMs` · headers · authentication) are shared with [Fetch](/core/components/functional/fetch).
20
20
 
21
21
  ## Row renderer
22
22
 
@@ -98,6 +98,8 @@ With no `loader`, nothing is shown while fetching. Set `loader` (`fixed`) or `lo
98
98
  | `loader` | `fixed` (when empty) · `inline` | Loader shown while fetching. None by default |
99
99
  | `debug` | boolean | Shows each row's data on hover |
100
100
 
101
+ Properties (TypeScript / Lit, preferred):
102
+
101
103
  | Property | Type | Description |
102
104
  |----------|------|-------------|
103
105
  | `props` | array · object | Rows to render |
@@ -107,6 +109,8 @@ With no `loader`, nothing is shown while fetching. Set `loader` (`fixed`) or `lo
107
109
  | `skeleton` | `() => TemplateResult` | Rendered while fetching |
108
110
  | `itemPropertyMap` | object | `propertyMap` passed to each row subscriber |
109
111
 
112
+ Templates (plain HTML hosts):
113
+
110
114
  | Template | Description |
111
115
  |----------|-------------|
112
116
  | `<template>` | Row markup; several are used in turn |
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-10-26T08:58:38.625Z",
3
+ "generatedAt": "2026-10-27T09:09:14.532Z",
4
4
  "count": 66,
5
5
  "items": [
6
6
  {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-10-26T08:58:38.625Z",
3
+ "generatedAt": "2026-10-27T09:09:14.532Z",
4
4
  "componentCount": 67,
5
5
  "components": [
6
6
  {
@@ -160,7 +160,7 @@ Header, media, body, and footer together.
160
160
  <sonic-image
161
161
  rounded
162
162
  ratio="16/9"
163
- src="img/concorde/plane_04.jpg"
163
+ src="/img/concorde/plane_04.jpg"
164
164
  alt="Concorde on the apron under a blue sky"
165
165
  ></sonic-image>
166
166
  <p class="mb-0">
@@ -10,31 +10,31 @@ With no `rounded`, corners are square. Boolean `rounded` uses the theme token `-
10
10
  <template>
11
11
  <div class="grid gap-6 grid-cols-3 lg:grid-cols-4 items-end text-center text-xs">
12
12
  <div>
13
- <sonic-image ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
13
+ <sonic-image ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
14
14
  <p class="mt-2">default</p>
15
15
  </div>
16
16
  <div>
17
- <sonic-image rounded="sm" ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
17
+ <sonic-image rounded="sm" ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
18
18
  <p class="mt-2">sm</p>
19
19
  </div>
20
20
  <div>
21
- <sonic-image rounded ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
21
+ <sonic-image rounded ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
22
22
  <p class="mt-2">rounded</p>
23
23
  </div>
24
24
  <div>
25
- <sonic-image rounded="md" ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
25
+ <sonic-image rounded="md" ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
26
26
  <p class="mt-2">md</p>
27
27
  </div>
28
28
  <div>
29
- <sonic-image rounded="lg" ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
29
+ <sonic-image rounded="lg" ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
30
30
  <p class="mt-2">lg</p>
31
31
  </div>
32
32
  <div>
33
- <sonic-image rounded="xl" ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
33
+ <sonic-image rounded="xl" ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
34
34
  <p class="mt-2">xl</p>
35
35
  </div>
36
36
  <div>
37
- <sonic-image rounded="full" ratio="1/1" src="img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
37
+ <sonic-image rounded="full" ratio="1/1" src="/img/concorde/plane_04.jpg" alt="Concorde on the apron"></sonic-image>
38
38
  <p class="mt-2">full</p>
39
39
  </div>
40
40
  </div>
@@ -48,10 +48,10 @@ With no `rounded`, corners are square. Boolean `rounded` uses the theme token `-
48
48
  <sonic-code>
49
49
  <template>
50
50
  <div class="grid gap-8 grid-cols-2 items-center">
51
- <sonic-image src="img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
52
- <sonic-image ratio="16/9" src="img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
53
- <sonic-image ratio="1/1" src="img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
54
- <sonic-image ratio="2/3" src="img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
51
+ <sonic-image src="/img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
52
+ <sonic-image ratio="16/9" src="/img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
53
+ <sonic-image ratio="1/1" src="/img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
54
+ <sonic-image ratio="2/3" src="/img/concorde/plane_12.jpg" alt="Concorde at the gate"></sonic-image>
55
55
  </div>
56
56
  </template>
57
57
  </sonic-code>
@@ -63,8 +63,8 @@ With no `rounded`, corners are square. Boolean `rounded` uses the theme token `-
63
63
  <sonic-code>
64
64
  <template>
65
65
  <div class="grid gap-8 grid-cols-2 items-center">
66
- <sonic-image ratio="11/4" src="img/concorde/plane_11.jpg" alt="Concorde flying over a field"></sonic-image>
67
- <sonic-image objectPosition="center top" ratio="11/4" src="img/concorde/plane_11.jpg" alt="Concorde flying over a field"></sonic-image>
66
+ <sonic-image ratio="11/4" src="/img/concorde/plane_11.jpg" alt="Concorde flying over a field"></sonic-image>
67
+ <sonic-image objectPosition="center top" ratio="11/4" src="/img/concorde/plane_11.jpg" alt="Concorde flying over a field"></sonic-image>
68
68
  </div>
69
69
  </template>
70
70
  </sonic-code>
@@ -76,7 +76,7 @@ With no `rounded`, corners are square. Boolean `rounded` uses the theme token `-
76
76
  <sonic-code>
77
77
  <template>
78
78
  <div class="h-96 relative rounded-lg overflow-hidden">
79
- <sonic-image cover src="img/concorde/plane_10.jpg" alt="Concorde fleet parked in a star"></sonic-image>
79
+ <sonic-image cover src="/img/concorde/plane_10.jpg" alt="Concorde fleet parked in a star"></sonic-image>
80
80
  </div>
81
81
  </template>
82
82
  </sonic-code>
@@ -99,7 +99,7 @@ Set `transition` to `fade` or `fade-scale-out`. The image stays transparent unti
99
99
  img.loading = 'eager';
100
100
  img.style.width = '8rem';
101
101
  var pics = ['01', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13'];
102
- img.src = 'img/concorde/plane_' + pics[host.childElementCount % pics.length] + '.jpg';
102
+ img.src = '/img/concorde/plane_' + pics[host.childElementCount % pics.length] + '.jpg';
103
103
  host.appendChild(img);
104
104
  })()"
105
105
  >
@@ -117,7 +117,7 @@ Set `transition` to `fade` or `fade-scale-out`. The image stays transparent unti
117
117
  img.loading = 'eager';
118
118
  img.style.width = '8rem';
119
119
  var pics = ['01', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13'];
120
- img.src = 'img/concorde/plane_' + pics[host.childElementCount % pics.length] + '.jpg';
120
+ img.src = '/img/concorde/plane_' + pics[host.childElementCount % pics.length] + '.jpg';
121
121
  host.appendChild(img);
122
122
  })()"
123
123
  >
@@ -145,7 +145,7 @@ Always set a meaningful `alt`. Use `alt=""` only for decorative images.
145
145
  rounded="md"
146
146
  ratio="16/9"
147
147
  alt="Crowd gathered around Concorde at night"
148
- src="img/concorde/plane_07.jpg"
148
+ src="/img/concorde/plane_07.jpg"
149
149
  ></sonic-image>
150
150
  </template>
151
151
  </sonic-code>
@@ -88,7 +88,7 @@ Set **`width`** · **`height`** · **`maxWidth`** · **`maxHeight`** with CSS le
88
88
  >
89
89
  <sonic-image
90
90
  cover
91
- src="img/concorde/plane_12.jpg"
91
+ src="/img/concorde/plane_12.jpg"
92
92
  alt="Concorde at the gate with boarding stairs"
93
93
  ></sonic-image>
94
94
  </sonic-modal>
@@ -105,7 +105,7 @@ Set **`width`** · **`height`** · **`maxWidth`** · **`maxHeight`** with CSS le
105
105
  <sonic-modal fullscreen id="Fullscreen">
106
106
  <sonic-image
107
107
  cover
108
- src="img/concorde/plane_10.jpg"
108
+ src="/img/concorde/plane_10.jpg"
109
109
  alt="Concorde fleet parked in a star"
110
110
  ></sonic-image>
111
111
  </sonic-modal>
@@ -1,22 +1,26 @@
1
1
  # @bind
2
2
 
3
- Keeps a class property in sync with a path of the DataProvider store, in both directions when needed. Pass a dot-notation string or a [DataProviderKey](/docs/misc/dataProviderKey); add `{ reflect: true }` to push local writes back to the store. For read-only sync prefer [@subscribe](/docs/decorators/subscribe), and see [Data flow](/docs/getting-started/dataFlow) for the overall model.
3
+ `@bind(key)` keeps a class property and one path of the DataProvider store in sync. With `{ reflect: true }` the sync goes both ways: the property follows the store, and each assignment is written back to it. For one direction only, use the complementary decorators: [@subscribe](/docs/decorators/subscribe) to read, [@publish](/docs/decorators/publish) to write. See [Data flow](/docs/getting-started/dataFlow) for the overall model.
4
4
 
5
5
  ## Import
6
6
 
7
7
  <sonic-code language="typescript">
8
8
  <template>
9
9
  import { bind } from "@supersoniks/concorde/decorators";
10
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
11
+
12
+ type Flight = { flight: string; gate: string; boarded: number };
13
+ const flightKey = new DataProviderKey&lt;Flight&gt;("flight");
10
14
 
11
- @bind("flight.gate")
15
+ @bind(flightKey.boarded, { reflect: true })
12
16
  @state()
13
- gate = "";
17
+ boarded = 0;
14
18
  </template>
15
19
  </sonic-code>
16
20
 
17
21
  ## Basic usage
18
22
 
19
- The first path segment is the data provider id, the rest is dot notation (array items use a numeric index: `passengers.0`). The property updates each time the store value changes. Add `@state()` so Lit re-renders.
23
+ The key is a [DataProviderKey](/docs/misc/dataProviderKey): TypeScript checks that the property type matches `T` at that path. The property updates each time the store value changes. Add `@state()` so Lit re-renders.
20
24
 
21
25
  <sonic-code>
22
26
  <template>
@@ -25,26 +29,9 @@ The first path segment is the data provider id, the rest is dot notation (array
25
29
  </template>
26
30
  </sonic-code>
27
31
 
28
- ## Typed key
29
-
30
- With a `DataProviderKey<T>`, TypeScript checks that the property type matches `T` at that path.
31
-
32
- <sonic-code language="typescript">
33
- <template>
34
- import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
35
-
36
- type Flight = { flight: string; gate: string; boarded: number };
37
- const flightKey = new DataProviderKey&lt;Flight&gt;("flight");
38
-
39
- @bind(flightKey.boarded, { reflect: true })
40
- @state()
41
- boarded = 0;
42
- </template>
43
- </sonic-code>
44
-
45
32
  ## Reflect
46
33
 
47
- By default (`reflect: false`) the binding is one-way: assigning the property does not touch the store. With `reflect: true`, each assignment calls `set()` on the publisher, so every other subscriber sees the new value. An internal guard prevents update loops.
34
+ With `reflect: true`, each assignment to the property calls `set()` at the key path, so every other subscriber sees the new value. An internal guard prevents update loops. Without `reflect` (the default), assigning the property does not touch the store, and `@bind` behaves like `@subscribe`.
48
35
 
49
36
  <sonic-code>
50
37
  <template>
@@ -55,7 +42,19 @@ By default (`reflect: false`) the binding is one-way: assigning the property doe
55
42
 
56
43
  ## Dynamic path
57
44
 
58
- Placeholders such as `${index}` are resolved from properties of the same component, and `@bind` re-subscribes when they change. Write them in a plain string, not a backtick template literal. While a placeholder is `null` or `undefined` the binding is inactive; `{ skipEmptyPlaceholder: true }` also waits on `""`. Full rules: [Dynamic paths](/docs/misc/dynamic-path).
45
+ Placeholders such as `${index}` are resolved from properties of the same component, and `@bind` re-subscribes when they change. Declare them in the key's second generic and write them in a plain string, not a backtick template literal. While a placeholder is `null` or `undefined` the binding is inactive; `{ skipEmptyPlaceholder: true }` also waits on `""`. Full rules: [Dynamic paths](/docs/misc/dynamic-path).
46
+
47
+ <sonic-code language="typescript">
48
+ <template>
49
+ const personKey = new DataProviderKey&lt;Person, { dataProvider: string; index: number }&gt;(
50
+ "${dataProvider}.${index}",
51
+ );
52
+
53
+ @bind(personKey)
54
+ @state()
55
+ person: Person | null = null;
56
+ </template>
57
+ </sonic-code>
59
58
 
60
59
  <sonic-code>
61
60
  <template>
@@ -72,6 +71,6 @@ The decorator subscribes in `connectedCallback` and unsubscribes in `disconnecte
72
71
 
73
72
  | Argument | Type | Description |
74
73
  |----------|------|-------------|
75
- | `path` | `string` or `DataProviderKey<T>` | Store path to bind. Supports `${prop}` placeholders |
74
+ | `key` | `DataProviderKey<T>` | Store path to bind. Supports `${prop}` placeholders |
76
75
  | `options.reflect` | `boolean` (default `false`) | Write local assignments back to the store |
77
76
  | `options.skipEmptyPlaceholder` | `boolean` (default `false`) | Treat a placeholder resolved to `""` as not ready |
@@ -1,10 +1,10 @@
1
- # AI agents (skills & AGENTS.md)
1
+ # AI agents (skill)
2
2
 
3
- Concorde ships **skills**, **rules**, and a root **`AGENTS.md`** so Cursor, JetBrains AI Assistant, and other coding agents follow framework patterns (DataProvider, decorators, short imports, scope, theme, migrations).
3
+ Concorde ships one [Agent Skill](https://agentskills.io), `concorde`, so coding agents follow the framework patterns. Cursor, Claude Code, JetBrains Junie and other agents load it on their own when they work on Concorde code; there is nothing to add to your `AGENTS.md`.
4
4
 
5
- On a [starter](/docs/getting-started/installation) project, run `yarn ai:sync` after install. On an existing project, install Concorde first, then use `ai-init` below.
5
+ On a [starter](/docs/getting-started/installation) project, run `yarn ai:sync` after install. On an existing project, install Concorde first, then run `ai-init`.
6
6
 
7
- ## Dedicated commands
7
+ ## Commands
8
8
 
9
9
  | Context | Command |
10
10
  |---------|---------|
@@ -12,65 +12,39 @@ On a [starter](/docs/getting-started/installation) project, run `yarn ai:sync` a
12
12
  | Any consumer app (after `yarn add @supersoniks/concorde`) | `node node_modules/@supersoniks/concorde/scripts/ai-init.mjs` |
13
13
  | Concorde repo (contributors) | `yarn ai-init` |
14
14
 
15
- <sonic-code language="shell">
16
- <template>
17
- # Starter (from project root)
18
- yarn ai:sync
15
+ Re-run the same command after each Concorde upgrade to refresh the skill.
19
16
 
20
- # Manual / existing project
21
- node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
22
- </template>
23
- </sonic-code>
17
+ ## The skill
24
18
 
25
- ## Useful flags
19
+ `SKILL.md` is the entry point: where to find the truth (the project, these docs, `custom-elements.json`), the critical rules and the imports. Details live in `rules/` files that the agent reads only for the topic at hand.
26
20
 
27
- | Flag | Effect |
28
- |------|--------|
29
- | `--skip-agents` | Never write `AGENTS.md` (skills / rules only) |
30
- | `--merge-agents` | Opt-in: keep the project preamble and append / refresh the Concorde block |
31
- | `--force-agents` | Opt-in: **replace** the whole `AGENTS.md` (destructive) |
32
- | `--overlay <dir>` | Extra rules/skills + optional `AGENTS.concorde.md` for project-only Concorde agent notes |
33
- | `--cursor-only` | Install only `.cursor/skills` and `.cursor/rules` |
34
- | `--jetbrains-only` | Install only `.aiassistant/rules/` |
35
-
36
- ## `AGENTS.md` policy (non-invasive)
37
-
38
- | Situation | Default |
39
- |-----------|---------|
40
- | No `AGENTS.md` | Create the Concorde guide |
41
- | File with `<!-- concorde-ai -->` | Refresh the managed zone only |
42
- | File **without** marker (project notes) | **Left untouched** — skills / rules are enough |
43
- | `--merge-agents` / `--force-agents` / `--skip-agents` | See flags above |
44
-
45
- ```text
46
- [optional project preamble — short, project-only]
47
- <!-- concorde-ai -->
48
- <package ai/AGENTS.md>
49
- [--- + overlay AGENTS.concorde.md]
50
- ```
51
-
52
- Everything **after** `<!-- concorde-ai -->` is replaced on each `ai-init` run (idempotent). Do not paste a full copy of the Concorde guide above the marker — put project-specific notes in `AGENTS.concorde.md` (overlay). If the preamble duplicates package `AGENTS.md`, `ai-init` slims or drops it and prints a warning. Legacy filenames `AGENTS.overlay.md` / `AGENTS.starter.md` are still accepted with a deprecation warning.
21
+ | File | Topic |
22
+ |------|-------|
23
+ | `SKILL.md` | Sources, critical rules, component shape, imports |
24
+ | `rules/data.md` | Store, `DataProviderKey`, `@subscribe` / `@publish` / `@bind` / `@handle`, `sub()`, `get` / `set` / `dp` |
25
+ | `rules/http.md` | `Endpoint`, `@get` / `@post`, API configuration |
26
+ | `rules/lists-forms.md` | `sonic-list` / `sonic-queue`, form fields |
27
+ | `rules/styling.md` | Theme, tokens, classes, styling rules |
28
+ | `rules/composition.md` | Parts of compound components, built-in states |
29
+ | `rules/troubleshooting.md` | Symptom → cause → fix: values not updating, requests not sent, empty lists |
53
30
 
54
31
  ## What gets installed
55
32
 
56
33
  | Path | Role |
57
34
  |------|------|
58
- | `AGENTS.md` | Created only if missing; existing project-owned files are left alone unless `--merge-agents` / `--force-agents` |
59
- | `.cursor/skills/concorde/` | Core Lit + DataProvider patterns |
60
- | `.cursor/skills/concorde-imports/` | Short `@supersoniks/concorde/…` import paths |
61
- | `.cursor/skills/concorde-scope/` | `serviceURL`, `formDataProvider`, API configuration |
62
- | `.cursor/skills/concorde-theme/` | `sonic-theme` and `--sc-*` tokens |
63
- | `.cursor/skills/concorde-menu/` | `sonic-menu` navigation |
64
- | `.cursor/skills/concorde-get-set-dp/` | `get` / `set` / `dp` and `DataProviderKey` migration |
65
- | `.cursor/rules/concorde.mdc` | Cursor rules (always-on patterns) |
66
- | `.aiassistant/rules/concorde.md` | JetBrains AI Assistant rules |
35
+ | `.agents/skills/concorde/` | The skill (read directly by Cursor) |
36
+ | `.claude/skills/concorde` | Symlink for Claude Code |
37
+ | `.junie/skills/concorde` | Symlink for JetBrains Junie |
38
+
39
+ Where symlinks are not allowed (some Windows setups), the skill is copied instead. Your own skills in these folders are never touched. Commit `.agents/` and the links if your team shares agent settings.
40
+
41
+ **`AGENTS.md` stays yours:** `ai-init` never reads or writes it.
67
42
 
68
- ## Workflow
43
+ ## Flags
69
44
 
70
- 1. **Starter project:** [Installation](/docs/getting-started/installation) — `yarn ai:sync` is wired in the kit.
71
- 2. **Existing project:** run **`ai-init`** after `yarn add @supersoniks/concorde`.
72
- 3. Commit `.cursor/` and `.aiassistant/` (and `AGENTS.md` only if you opted in / it was created) if your team shares agent settings.
73
- 4. Re-run the same command when you bump `@supersoniks/concorde` to refresh skills from `node_modules/@supersoniks/concorde/ai/`.
74
- 5. In Cursor, skills under `.cursor/skills/` are picked up automatically; mention a skill in chat for focused tasks (e.g. migration → `concorde-get-set-dp`).
45
+ | Flag | Effect |
46
+ |------|--------|
47
+ | `--no-links` | Install `.agents/skills` only, without the `.claude` / `.junie` links |
48
+ | `--overlay <dir>` | Also install the skills found in `<dir>/skills/` (project kit) |
75
49
 
76
- Source files in the npm package: `node_modules/@supersoniks/concorde/ai/` (see also `ai/README.md` in the [Concorde repository](https://github.com/supersoniks/concorde)).
50
+ Source files in the npm package: `node_modules/@supersoniks/concorde/ai/skills/concorde/`.
@@ -19,7 +19,7 @@ Recommended patterns for new Concorde apps (Lit + TypeScript). Under the hood, d
19
19
  | Derived / aggregate (JSONata) | `derive()` or `sonic-jsonata` — [Jsonata](/core/components/functional/jsonata) |
20
20
  | Offline doc demos | `serviceURL="/docs-mock-api"` — [Local API demos](/docs/misc/docs-mock-api) |
21
21
 
22
- Skill: `concorde-get-set-dp` in the package `ai/` folder.
22
+ Agent skill: `concorde` (`rules/data.md`), see [AI agents](/docs/getting-started/ai-agents).
23
23
 
24
24
  ## DataProviderKey
25
25