@supersoniks/concorde 4.9.2 → 4.9.4

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.
@@ -137,6 +137,7 @@ const packageJsonPath = path.resolve(__dirname, "../package.json");
137
137
  let packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
138
138
 
139
139
  const pExports = {
140
+ "./bundle": "./concorde-core.bundle.js",
140
141
  "./core/components/ui/icon/icons.json":
141
142
  "./src/core/components/ui/icon/icons.json",
142
143
  "./core/components/functional/sdui/default-library.json":
@@ -1,4 +1,5 @@
1
1
  import Icons from "@supersoniks/concorde/core/components/ui/icon/icons";
2
+ import { ancestorAttribute } from "@supersoniks/concorde/core/decorators/Subscriber";
2
3
  import {
3
4
  css,
4
5
  LitElement,
@@ -82,6 +83,8 @@ export class Icon extends LitElement {
82
83
  name: this.name,
83
84
  prefix: this.prefix,
84
85
  library: this.library,
86
+ customLibraryPath: this.customIconLibraryPath,
87
+ customLibraryDefaultPrefix: this.customIconDefaultPrefix,
85
88
  });
86
89
  }
87
90
 
@@ -102,6 +105,14 @@ export class Icon extends LitElement {
102
105
  */
103
106
  @property({ type: String }) library = "";
104
107
 
108
+ @ancestorAttribute("customIconLibraryPath", { dynamic: true })
109
+ @state()
110
+ customIconLibraryPath: string | null = null;
111
+
112
+ @ancestorAttribute("customIconDefaultPrefix", { dynamic: true })
113
+ @state()
114
+ customIconDefaultPrefix: string | null = null;
115
+
105
116
  connectedCallback() {
106
117
  this.setAttribute("aria-hidden", "true");
107
118
  super.connectedCallback();
@@ -110,7 +121,10 @@ export class Icon extends LitElement {
110
121
  if (
111
122
  changedProperties.has("name") ||
112
123
  changedProperties.has("prefix") ||
113
- changedProperties.has("library")
124
+ changedProperties.has("library") ||
125
+ (this.library === "custom" &&
126
+ (changedProperties.has("customIconLibraryPath") ||
127
+ changedProperties.has("customIconDefaultPrefix")))
114
128
  ) {
115
129
  this.updateIcon();
116
130
  }
@@ -43,22 +43,38 @@ const libraries = {
43
43
  type Libraries = typeof libraries;
44
44
  type LibraryKey = keyof Libraries;
45
45
  type Library = Partial<{ url: string; defaultPrefix: string }>;
46
- let hasEnabledCustomLibrary = false;
47
- function enableCustomLibrary() {
48
- if (hasEnabledCustomLibrary) return;
49
46
 
50
- libraries.custom.url =
51
- document
52
- .querySelector("[customIconLibraryPath]")
53
- ?.getAttribute("customIconLibraryPath") || "";
54
- libraries.custom.defaultPrefix =
55
- document
56
- .querySelector("[customIconDefaultPrefix]")
57
- ?.getAttribute("customIconDefaultPrefix") || "";
47
+ function resolveCustomLibraryConfig(params: IconConf): Library {
48
+ let url = params.customLibraryPath;
49
+ let defaultPrefix = params.customLibraryDefaultPrefix;
58
50
 
59
- if (libraries.custom.url) {
60
- hasEnabledCustomLibrary = true;
51
+ // Attribut optionnel : peut être défini sur un ancêtre (scope / theme) ou,
52
+ // en secours, n'importe où dans le document (ex. config globale au boot).
53
+ if (url == null) {
54
+ const globalEl = document.querySelector("[customIconLibraryPath]");
55
+ url = globalEl?.getAttribute("customIconLibraryPath") ?? "";
56
+ if (defaultPrefix == null) {
57
+ defaultPrefix =
58
+ globalEl?.getAttribute("customIconDefaultPrefix") ??
59
+ document
60
+ .querySelector("[customIconDefaultPrefix]")
61
+ ?.getAttribute("customIconDefaultPrefix") ??
62
+ "";
63
+ }
61
64
  }
65
+
66
+ return {
67
+ url: url || "",
68
+ defaultPrefix: defaultPrefix || "",
69
+ };
70
+ }
71
+
72
+ function resolveLibraryItem(library: string, params: IconConf): Library | null {
73
+ if (!(library in libraries)) return null;
74
+ if (library !== "custom") {
75
+ return libraries[library as LibraryKey] as Library;
76
+ }
77
+ return resolveCustomLibraryConfig(params);
62
78
  }
63
79
  const iconCachStr = sessionStorage.getItem("sonicIconsCache");
64
80
  const iconCache = iconCachStr
@@ -70,6 +86,8 @@ export declare type IconConf = {
70
86
  name: string;
71
87
  prefix?: string;
72
88
  library?: string;
89
+ customLibraryPath?: string | null;
90
+ customLibraryDefaultPrefix?: string | null;
73
91
  };
74
92
  export default class Icons {
75
93
  static default = {
@@ -81,15 +99,23 @@ export default class Icons {
81
99
  /**
82
100
  * SVGS en ligne
83
101
  */
84
- if (library == "custom") {
85
- enableCustomLibrary();
102
+ if (!library) {
103
+ return unsafeHTML(iconsAsRecord["core"][params.name] || "");
86
104
  }
87
- if (library && library in libraries) {
88
- const libraryItem = libraries[library as LibraryKey] as Library;
105
+ const libraryItem = resolveLibraryItem(library, params);
106
+ if (libraryItem) {
107
+ // Pas d'URL encore (ancêtre ou config globale pas prête) : on attend
108
+ // sans fetch ni cache ; @ancestorAttribute relancera le chargement.
109
+ if (library === "custom" && !libraryItem.url) {
110
+ return "";
111
+ }
89
112
  const prefix: string = params.prefix || libraryItem.defaultPrefix || "";
90
113
  const libIcons = iconsAsRecord[library] || ({} as Library);
91
114
  iconsAsRecord[library] = libIcons;
92
- const libIconsKey = prefix + "-" + name;
115
+ const libIconsKey =
116
+ library === "custom"
117
+ ? `${libraryItem.url}|${prefix}-${name}`
118
+ : `${prefix}-${name}`;
93
119
 
94
120
  /**
95
121
  * Si l'icone a déjà été chargée on ne la recharge pas
@@ -26,16 +26,36 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
26
26
 
27
27
  | Flag | Effect |
28
28
  |------|--------|
29
- | `--merge-agents` | Append to an existing `AGENTS.md` instead of replacing it |
30
- | `--overlay <dir>` | Copy extra rules/skills from another layer (e.g. starter kit) |
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.starter.md` for project-only agent notes |
31
33
  | `--cursor-only` | Install only `.cursor/skills` and `.cursor/rules` |
32
34
  | `--jetbrains-only` | Install only `.aiassistant/rules/` |
33
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.starter.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.starter.md` (overlay). If the preamble duplicates package `AGENTS.md`, `ai-init` slims or drops it and prints a warning.
53
+
34
54
  ## What gets installed
35
55
 
36
56
  | Path | Role |
37
57
  |------|------|
38
- | `AGENTS.md` | Project-level guide for agents (Concorde conventions) |
58
+ | `AGENTS.md` | Created only if missing; existing project-owned files are left alone unless `--merge-agents` / `--force-agents` |
39
59
  | `.cursor/skills/concorde/` | Core Lit + DataProvider patterns |
40
60
  | `.cursor/skills/concorde-imports/` | Short `@supersoniks/concorde/…` import paths |
41
61
  | `.cursor/skills/concorde-scope/` | `serviceURL`, `formDataProvider`, API configuration |
@@ -49,7 +69,7 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
49
69
 
50
70
  1. **Starter project:** [Installation](#docs/_getting-started/concorde-outside.md/concorde-outside) — `yarn ai:sync` is wired in the kit.
51
71
  2. **Existing / manual Vite project:** [Manual installation](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install), then **`ai-init`** after `yarn add @supersoniks/concorde`.
52
- 3. Commit `AGENTS.md`, `.cursor/`, and `.aiassistant/` if your team shares agent settings.
72
+ 3. Commit `.cursor/` and `.aiassistant/` (and `AGENTS.md` only if you opted in / it was created) if your team shares agent settings.
53
73
  4. Re-run the same command when you bump `@supersoniks/concorde` to refresh skills from `node_modules/@supersoniks/concorde/ai/`.
54
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`).
55
75