@stacklist-app/brandkit 1.2.2 → 1.2.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.
package/README.md CHANGED
@@ -43,6 +43,8 @@ A brandkit guide isn't just a page for people — `build` (and the standalone `e
43
43
 
44
44
  `build` also makes the data **discoverable from the deployed page**: it injects `<link rel="alternate" type="application/json" href="brand.json">` and embeds the brand inline as `<script type="application/json" id="brandkit-brand">`, so an agent that fetches the URL gets structured brand data with zero extra requests.
45
45
 
46
+ And for a person who wants to hand the guide to their own agent, the sidebar shows a **"Using an AI agent?"** callout with a one-click copy-paste prompt — it carries absolute URLs to `brand.json` / `tokens.json` / `brand.md` and tells the agent to read those instead of scraping the page. Hide it with `brand.agentCallout: false`.
47
+
46
48
  A JSON Schema for `config.json` ships at [`config.schema.json`](config.schema.json) — point your editor's `$schema` at it for validation and autocomplete.
47
49
 
48
50
  ## Framework integrations
@@ -51,7 +51,8 @@
51
51
  "date": { "type": "string" },
52
52
  "guideLabel": { "type": "string", "description": "Renames the 'Web Style Guide' label in the header and footer." },
53
53
  "headerLogo": { "type": "string", "description": "Path to a logo image shown in the header instead of the text wordmark (use a light/reversed logo)." },
54
- "sidebarLogo": { "type": "string", "description": "Path to a logo image shown at the top of the left menu instead of the brand name (use a dark logo)." }
54
+ "sidebarLogo": { "type": "string", "description": "Path to a logo image shown at the top of the left menu instead of the brand name (use a dark logo)." },
55
+ "agentCallout": { "type": "boolean", "description": "Show the 'Using an AI agent?' callout under the sidebar nav — a copy-paste prompt pointing an agent at the brand.json / tokens.json / brand.md exports. Defaults to true; set false to hide it." }
55
56
  }
56
57
  },
57
58
  "fonts": {
package/dist/engine.js CHANGED
@@ -123,6 +123,57 @@
123
123
  }).join('');
124
124
  }
125
125
 
126
+ /* ==============================================================
127
+ 2b. Render agent callout — a paste-ready prompt that points an AI
128
+ agent at the machine-readable exports (brand.json / tokens.json /
129
+ brand.md) so it reads structured brand data instead of scraping the
130
+ rendered page. Opt out with brand.agentCallout === false.
131
+ ============================================================== */
132
+ function renderAgentCallout() {
133
+ var box = document.getElementById('agent-callout');
134
+ if (!box) return;
135
+ if (cfg.brand && cfg.brand.agentCallout === false) return;
136
+
137
+ // Resolve export URLs relative to this page exactly as a link would, so
138
+ // the pasted prompt carries absolute URLs the agent can fetch directly.
139
+ // Clear any userinfo so basic-auth creds in the page URL don't leak into
140
+ // the copied prompt (a relative path already drops the page query/hash).
141
+ function exportUrl(file) {
142
+ var u = new URL(file, location.href);
143
+ u.username = ''; u.password = '';
144
+ return u.href;
145
+ }
146
+ var brandUrl, tokensUrl, mdUrl;
147
+ try {
148
+ brandUrl = exportUrl('brand.json');
149
+ tokensUrl = exportUrl('tokens.json');
150
+ mdUrl = exportUrl('brand.md');
151
+ } catch (_) {
152
+ brandUrl = 'brand.json'; tokensUrl = 'tokens.json'; mdUrl = 'brand.md';
153
+ }
154
+ // Strip control chars / newlines and collapse whitespace so a hostile
155
+ // brand name can't smuggle instructions into the paste-ready agent prompt.
156
+ var name = ((cfg.brand && (cfg.brand.displayName || cfg.brand.name)) || 'this brand')
157
+ .replace(/[\u0000-\u001F\u007F\u00AD\u200B-\u200F\u202A-\u202E\u2060-\u2069\uFEFF]/g, ' ').replace(/\s+/g, ' ').trim() || 'this brand';
158
+ var prompt =
159
+ 'This page is a brandkit brand guide for ' + name + '. It publishes ' +
160
+ 'machine-readable brand data — read these instead of scraping the page:\n\n' +
161
+ '- ' + brandUrl + ' — full structured brand: colors (roles + contrast), typography, voice, logos, spacing\n' +
162
+ '- ' + tokensUrl + ' — W3C design tokens (DTCG $type/$value), for code and design tooling\n' +
163
+ '- ' + mdUrl + ' — brand brief: how to stay on-brand\n\n' +
164
+ 'Fetch them, then apply ' + name + "'s colors, type, and voice to what you're building.";
165
+
166
+ box.innerHTML =
167
+ '<div class="sidebar-agent-title">Using an AI agent?</div>' +
168
+ '<p class="sidebar-agent-desc">Paste this so it reads the brand data, not the page.</p>' +
169
+ '<button type="button" class="sidebar-agent-btn" id="agent-callout-btn">Copy agent prompt</button>';
170
+ // Set the payload via property (not an HTML attribute) so no font/brand
171
+ // value needs escaping and newlines survive intact.
172
+ var btn = box.querySelector('#agent-callout-btn');
173
+ if (btn) btn.dataset.copy = prompt;
174
+ box.hidden = false;
175
+ }
176
+
126
177
  /* ==============================================================
127
178
  3. Render colors
128
179
  ============================================================== */
@@ -686,6 +737,13 @@
686
737
  copyText(codeLine.dataset.copy);
687
738
  return;
688
739
  }
740
+
741
+ // Agent callout prompt
742
+ var agentBtn = e.target.closest('#agent-callout-btn');
743
+ if (agentBtn) {
744
+ copyText(agentBtn.dataset.copy);
745
+ return;
746
+ }
689
747
  });
690
748
  }
691
749
 
@@ -886,6 +944,7 @@
886
944
  bootstrap();
887
945
  renderShell();
888
946
  renderNav();
947
+ renderAgentCallout();
889
948
  renderSectionIntros();
890
949
  renderColors();
891
950
  renderGradients();
package/dist/index.html CHANGED
@@ -14,6 +14,7 @@
14
14
  <nav class="sidebar">
15
15
  <div class="sidebar-brand">brandkit</div>
16
16
  <ul class="sidebar-nav" id="nav"></ul>
17
+ <div class="sidebar-agent" id="agent-callout" hidden></div>
17
18
  </nav>
18
19
 
19
20
  <!-- Main Content -->
package/dist/styles.css CHANGED
@@ -129,11 +129,49 @@ body {
129
129
  .sidebar-nav a:hover { color: var(--ink); background: var(--cloud); }
130
130
  .sidebar-nav a.active { color: var(--accent-text); border-left-color: var(--accent-text); background: rgba(var(--accent-rgb), 0.04); font-weight: 500; }
131
131
 
132
+ /* Agent callout — paste-ready prompt that points an AI agent at the exports */
133
+ .sidebar-agent {
134
+ margin: 28px 16px 8px;
135
+ padding: 14px;
136
+ border: 1px solid var(--mist);
137
+ border-radius: 12px;
138
+ background: rgba(var(--accent-rgb), 0.04);
139
+ }
140
+ .sidebar-agent-title {
141
+ font-size: 12px;
142
+ font-weight: 600;
143
+ color: var(--ink);
144
+ margin-bottom: 4px;
145
+ }
146
+ .sidebar-agent-desc {
147
+ font-size: 11px;
148
+ line-height: 1.4;
149
+ color: var(--slate);
150
+ margin: 0 0 10px;
151
+ }
152
+ .sidebar-agent-btn {
153
+ display: block;
154
+ width: 100%;
155
+ padding: 7px 10px;
156
+ font-size: 12px;
157
+ font-weight: 500;
158
+ font-family: inherit;
159
+ color: var(--primary-foreground);
160
+ background: var(--primary);
161
+ border: none;
162
+ border-radius: 8px;
163
+ cursor: pointer;
164
+ transition: filter 150ms ease;
165
+ }
166
+ .sidebar-agent-btn:hover { filter: brightness(0.9); }
167
+ .sidebar-agent-btn:active { transform: translateY(1px); }
168
+ .sidebar-agent-btn:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
169
+
132
170
  /* ── Sidebar Grouped Navigation ── */
133
171
  .nav-group {
134
172
  padding: 20px 24px 6px;
135
173
  font-family: var(--font-body), sans-serif;
136
- font-size: 10px;
174
+ font-size: 12px;
137
175
  font-weight: 700;
138
176
  letter-spacing: 0.10em;
139
177
  text-transform: uppercase;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacklist-app/brandkit",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Config-driven brand guide that bolts onto any website. Zero dependencies.",
5
5
  "main": "lib/resolve.js",
6
6
  "bin": {