bestax-mcp 1.0.1 → 1.1.0

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/data/catalog.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": {
4
4
  "package": "@allxsmith/bestax-bulma",
5
- "version": "5.11.1"
5
+ "version": "5.11.2"
6
6
  },
7
7
  "docsBase": "https://bestax.io/docs",
8
8
  "categories": [
package/dist/format.d.ts CHANGED
@@ -11,6 +11,20 @@
11
11
  * separate call, because most questions do not need them.
12
12
  */
13
13
  import type { CatalogEntry, ComponentRecord, CssVar, Example, Part, Skill } from './data.js';
14
+ /**
15
+ * Tag an outbound link with `utm_source=bestax-mcp` so a docs or Storybook
16
+ * visit that started here shows up as such in the site analytics. Render-time
17
+ * only — the URLs in `data/` are generated and stay canonical. Idempotent, and
18
+ * anything that is not an http(s) URL passes through unchanged.
19
+ *
20
+ * Coverage is deliberately partial: only links this server composes itself —
21
+ * the Docs/Storybook footer on component responses and the version-drift
22
+ * notice — go through here. Skill bodies and reference docs are served
23
+ * verbatim from the bundled markdown, untagged links included, because
24
+ * rewriting URLs inside arbitrary markdown/code examples risks corrupting
25
+ * them. Do not "fix" that by running this over served markdown.
26
+ */
27
+ export declare function attributed(url: string): string;
14
28
  export declare function table(headers: string[], rows: string[][]): string;
15
29
  export declare function renderPart(part: Part, { heading }?: {
16
30
  heading?: boolean | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,MAAM,EACN,OAAO,EACP,IAAI,EAEJ,KAAK,EACN,MAAM,WAAW,CAAC;AAUnB,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAOjE;AAsBD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAc,EAAE;;CAAK,GAAG,MAAM,CAiCtE;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,MAAM,EAAE,GAChB,MAAM,CAsDR;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAI1D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAmBpD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAkB7D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAgBpD;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;;;;;EAM3D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM;;;;;;EAK1C"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,MAAM,EACN,OAAO,EACP,IAAI,EAEJ,KAAK,EACN,MAAM,WAAW,CAAC;AAUnB;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgB9C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAOjE;AAsBD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAc,EAAE;;CAAK,GAAG,MAAM,CAiCtE;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,MAAM,EAAE,GAChB,MAAM,CAwDR;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAI1D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAmBpD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAkB7D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAgBpD;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;;;;;EAM3D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM;;;;;;EAK1C"}
package/dist/format.js CHANGED
@@ -4,6 +4,38 @@ const cell = (text) => String(text ?? '')
4
4
  .replace(/\|/g, '\\|')
5
5
  .replace(/\r?\n/g, ' ')
6
6
  .trim();
7
+ /**
8
+ * Tag an outbound link with `utm_source=bestax-mcp` so a docs or Storybook
9
+ * visit that started here shows up as such in the site analytics. Render-time
10
+ * only — the URLs in `data/` are generated and stay canonical. Idempotent, and
11
+ * anything that is not an http(s) URL passes through unchanged.
12
+ *
13
+ * Coverage is deliberately partial: only links this server composes itself —
14
+ * the Docs/Storybook footer on component responses and the version-drift
15
+ * notice — go through here. Skill bodies and reference docs are served
16
+ * verbatim from the bundled markdown, untagged links included, because
17
+ * rewriting URLs inside arbitrary markdown/code examples risks corrupting
18
+ * them. Do not "fix" that by running this over served markdown.
19
+ */
20
+ export function attributed(url) {
21
+ if (!/^https?:\/\//.test(url))
22
+ return url;
23
+ // Split the fragment FIRST: the already-tagged check below must inspect
24
+ // only the query. A `#utm_source=bestax-mcp` inside a fragment (or the
25
+ // same text inside another parameter's value) is not attribution — the
26
+ // analytics request never sees it — so matching it would skip tagging.
27
+ // Do not use URL.searchParams: it re-encodes Storybook `path=/story/...`
28
+ // as `%2F`.
29
+ const hashIndex = url.indexOf('#');
30
+ const hash = hashIndex === -1 ? '' : url.slice(hashIndex);
31
+ const withoutHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
32
+ const queryIndex = withoutHash.indexOf('?');
33
+ const query = queryIndex === -1 ? '' : withoutHash.slice(queryIndex + 1);
34
+ if (query.split('&').includes('utm_source=bestax-mcp'))
35
+ return url;
36
+ const sep = queryIndex === -1 ? '?' : '&';
37
+ return `${withoutHash}${sep}utm_source=bestax-mcp${hash}`;
38
+ }
7
39
  export function table(headers, rows) {
8
40
  if (!rows.length)
9
41
  return '';
@@ -105,9 +137,10 @@ export function renderComponent(record, include) {
105
137
  if (include.includes('related') && record.related.length) {
106
138
  out.push(`**Related:** ${record.related.map(r => `\`${r}\``).join(', ')}.`);
107
139
  }
108
- const links = [`Docs: ${record.docsUrl}`];
109
- if (record.storybook)
110
- links.push(`Storybook: ${record.storybook}`);
140
+ const links = [`Docs: ${attributed(record.docsUrl)}`];
141
+ if (record.storybook) {
142
+ links.push(`Storybook: ${attributed(record.storybook)}`);
143
+ }
111
144
  out.push(links.join(' · '));
112
145
  return out.join('\n\n');
113
146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,SAAS,EAEV,MAAM,yCAAyC,CAAC;AA6FjD,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAChC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,CAurBpB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,SAAS,EAEV,MAAM,yCAAyC,CAAC;AA6FjD,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAChC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,CAyrBpB"}
package/dist/server.js CHANGED
@@ -579,8 +579,10 @@ export async function createServer(options = {}) {
579
579
  });
580
580
  // -- Prompts, one per skill ----------------------------------------------
581
581
  //
582
- // Generated from the manifest, never listed here. skills/CLAUDE.md counts the
583
- // roster as already duplicated in five places; this would have been a sixth.
582
+ // Generated from the manifest, never listed here. The roster is derived, not
583
+ // hand-listed (#540); the prose copies that cannot be derived are held to the
584
+ // directory by the skills-roster conformance check (`pnpm check:conformance
585
+ // --only=skills-roster`). A list here would be one more copy for it to chase.
584
586
  for (const skill of skills) {
585
587
  server.registerPrompt(skill.promptName, {
586
588
  title: skill.name,
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;CACzD;AAkBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI7D;AAcD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB;AAyCD,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,CAetB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAS5D"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;CACzD;AAkBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI7D;AAcD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB;AAyCD,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,CAetB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAS5D"}
package/dist/version.js CHANGED
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { readFile } from 'node:fs/promises';
17
17
  import { dirname, join, parse } from 'node:path';
18
+ import { attributed } from './format.js';
18
19
  const PACKAGE = '@allxsmith/bestax-bulma';
19
20
  /**
20
21
  * The one string in this server that does not come from its own committed data.
@@ -143,5 +144,5 @@ export function versionNote(info) {
143
144
  }
144
145
  return (`⚠ This index documents ${PACKAGE} ${info.indexed}; this project has ` +
145
146
  `${info.installed}. Props, defaults and CSS variables may differ — check ` +
146
- `https://bestax.io/docs before relying on anything above.`);
147
+ `${attributed('https://bestax.io/docs')} before relying on anything above.`);
147
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bestax-mcp",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "MCP server for @allxsmith/bestax-bulma — component props, examples, CSS variables and agent skills, served offline from a version-pinned index",
5
5
  "type": "module",
6
6
  "bin": {