@bearnie/mcp 0.1.1 → 0.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.
package/README.md CHANGED
@@ -4,7 +4,7 @@ An MCP (Model Context Protocol) server that enables AI assistants like Claude, G
4
4
 
5
5
  ## Features
6
6
 
7
- - **List Components**: Browse all available Bearnie components
7
+ - **List Components**: Browse all available Bearnie components (including the barrel export)
8
8
  - **Search Components**: Find components by name, description, or category
9
9
  - **Get Component Details**: View component source code and dependencies
10
10
  - **Add Components**: Install components directly to your Astro project
@@ -92,36 +92,57 @@ Get detailed information about a specific component, including its source code.
92
92
 
93
93
  **Parameters:**
94
94
 
95
- - `name` (string): Component name (e.g., "button", "accordion")
95
+ - `name` (string): Component name (e.g., "button", "accordion", "barrel")
96
96
 
97
97
  **Example prompt:** "Show me the Bearnie button component"
98
98
 
99
99
  ### `add_component`
100
100
 
101
- Add a component to your Astro project. Creates files in `src/components/bearnie/`.
101
+ Add a component to your Astro project. Creates files in `src/components/bearnie/`, utilities in `src/utils/`, and styles in `src/styles/`.
102
102
 
103
103
  **Parameters:**
104
104
 
105
105
  - `name` (string): Component name to add
106
106
  - `cwd` (string, optional): Working directory
107
107
 
108
- **Example prompt:** "Add the accordion component to my project"
108
+ **Example prompts:**
109
+
110
+ - "Add the accordion component to my project"
111
+ - "Add the barrel export for named imports"
112
+
113
+ Install components first, then add `barrel` last for `import { Button, Card } from "@/components/bearnie"`.
114
+
115
+ ### `add_components`
116
+
117
+ Add multiple components in one step. Resolves registry dependencies and installs `barrel` last when included.
118
+
119
+ **Parameters:**
120
+
121
+ - `names` (string[]): Component names to add
122
+ - `cwd` (string, optional): Working directory
123
+
124
+ **Example prompt:** "Add button, card, and barrel to my project"
109
125
 
110
126
  ## Environment Variables
111
127
 
112
- - `BEARNIE_REGISTRY_URL`: Override the default registry URL (default: `https://bearnie.dev/registry`)
128
+ | Variable | Description |
129
+ | -------- | ----------- |
130
+ | `BEARNIE_REGISTRY_URL` | Override the default registry URL (default: `https://bearnie.dev/registry`) |
131
+ | `BEARNIE_REGISTRY_PATH` | Local file path to registry (for development) |
113
132
 
114
133
  ## Development
115
134
 
135
+ From the monorepo root:
136
+
116
137
  ```bash
117
- # Install dependencies
118
138
  npm install
139
+ npm run build:packages
140
+ ```
119
141
 
120
- # Build
121
- npm run build
142
+ Test with a local registry:
122
143
 
123
- # Development mode (watch)
124
- npm run dev
144
+ ```bash
145
+ BEARNIE_REGISTRY_PATH=./public/registry npx @bearnie/mcp
125
146
  ```
126
147
 
127
148
  ## License
package/dist/index.d.ts CHANGED
@@ -1 +1,3 @@
1
1
  #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -6,10 +6,13 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/index.ts
9
+ import { readFileSync } from "fs";
10
+ import { fileURLToPath } from "url";
11
+ import { dirname, join } from "path";
9
12
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
14
 
12
- // node_modules/zod/v4/classic/external.js
15
+ // ../../node_modules/zod/v4/classic/external.js
13
16
  var external_exports = {};
14
17
  __export(external_exports, {
15
18
  $brand: () => $brand,
@@ -250,7 +253,7 @@ __export(external_exports, {
250
253
  xor: () => xor
251
254
  });
252
255
 
253
- // node_modules/zod/v4/core/index.js
256
+ // ../../node_modules/zod/v4/core/index.js
254
257
  var core_exports2 = {};
255
258
  __export(core_exports2, {
256
259
  $ZodAny: () => $ZodAny,
@@ -528,7 +531,7 @@ __export(core_exports2, {
528
531
  version: () => version
529
532
  });
530
533
 
531
- // node_modules/zod/v4/core/core.js
534
+ // ../../node_modules/zod/v4/core/core.js
532
535
  var NEVER = Object.freeze({
533
536
  status: "aborted"
534
537
  });
@@ -603,7 +606,7 @@ function config(newConfig) {
603
606
  return globalConfig;
604
607
  }
605
608
 
606
- // node_modules/zod/v4/core/util.js
609
+ // ../../node_modules/zod/v4/core/util.js
607
610
  var util_exports = {};
608
611
  __export(util_exports, {
609
612
  BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
@@ -776,10 +779,10 @@ function mergeDefs(...defs) {
776
779
  function cloneDef(schema) {
777
780
  return mergeDefs(schema._zod.def);
778
781
  }
779
- function getElementAtPath(obj, path2) {
780
- if (!path2)
782
+ function getElementAtPath(obj, path3) {
783
+ if (!path3)
781
784
  return obj;
782
- return path2.reduce((acc, key) => acc?.[key], obj);
785
+ return path3.reduce((acc, key) => acc?.[key], obj);
783
786
  }
784
787
  function promiseAllObject(promisesObj) {
785
788
  const keys = Object.keys(promisesObj);
@@ -1162,11 +1165,11 @@ function aborted(x, startIndex = 0) {
1162
1165
  }
1163
1166
  return false;
1164
1167
  }
1165
- function prefixIssues(path2, issues) {
1168
+ function prefixIssues(path3, issues) {
1166
1169
  return issues.map((iss) => {
1167
1170
  var _a2;
1168
1171
  (_a2 = iss).path ?? (_a2.path = []);
1169
- iss.path.unshift(path2);
1172
+ iss.path.unshift(path3);
1170
1173
  return iss;
1171
1174
  });
1172
1175
  }
@@ -1282,7 +1285,7 @@ var Class = class {
1282
1285
  }
1283
1286
  };
1284
1287
 
1285
- // node_modules/zod/v4/core/errors.js
1288
+ // ../../node_modules/zod/v4/core/errors.js
1286
1289
  var initializer = (inst, def) => {
1287
1290
  inst.name = "$ZodError";
1288
1291
  Object.defineProperty(inst, "_zod", {
@@ -1349,7 +1352,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
1349
1352
  }
1350
1353
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
1351
1354
  const result = { errors: [] };
1352
- const processError = (error49, path2 = []) => {
1355
+ const processError = (error49, path3 = []) => {
1353
1356
  var _a2, _b;
1354
1357
  for (const issue2 of error49.issues) {
1355
1358
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -1359,7 +1362,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
1359
1362
  } else if (issue2.code === "invalid_element") {
1360
1363
  processError({ issues: issue2.issues }, issue2.path);
1361
1364
  } else {
1362
- const fullpath = [...path2, ...issue2.path];
1365
+ const fullpath = [...path3, ...issue2.path];
1363
1366
  if (fullpath.length === 0) {
1364
1367
  result.errors.push(mapper(issue2));
1365
1368
  continue;
@@ -1391,8 +1394,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
1391
1394
  }
1392
1395
  function toDotPath(_path) {
1393
1396
  const segs = [];
1394
- const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1395
- for (const seg of path2) {
1397
+ const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1398
+ for (const seg of path3) {
1396
1399
  if (typeof seg === "number")
1397
1400
  segs.push(`[${seg}]`);
1398
1401
  else if (typeof seg === "symbol")
@@ -1418,7 +1421,7 @@ function prettifyError(error48) {
1418
1421
  return lines.join("\n");
1419
1422
  }
1420
1423
 
1421
- // node_modules/zod/v4/core/parse.js
1424
+ // ../../node_modules/zod/v4/core/parse.js
1422
1425
  var _parse = (_Err) => (schema, value, _ctx, _params) => {
1423
1426
  const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
1424
1427
  const result = schema._zod.run({ value, issues: [] }, ctx);
@@ -1506,7 +1509,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
1506
1509
  };
1507
1510
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
1508
1511
 
1509
- // node_modules/zod/v4/core/regexes.js
1512
+ // ../../node_modules/zod/v4/core/regexes.js
1510
1513
  var regexes_exports = {};
1511
1514
  __export(regexes_exports, {
1512
1515
  base64: () => base64,
@@ -1663,7 +1666,7 @@ var sha512_hex = /^[0-9a-fA-F]{128}$/;
1663
1666
  var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "==");
1664
1667
  var sha512_base64url = /* @__PURE__ */ fixedBase64url(86);
1665
1668
 
1666
- // node_modules/zod/v4/core/checks.js
1669
+ // ../../node_modules/zod/v4/core/checks.js
1667
1670
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
1668
1671
  var _a2;
1669
1672
  inst._zod ?? (inst._zod = {});
@@ -2211,7 +2214,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
2211
2214
  };
2212
2215
  });
2213
2216
 
2214
- // node_modules/zod/v4/core/doc.js
2217
+ // ../../node_modules/zod/v4/core/doc.js
2215
2218
  var Doc = class {
2216
2219
  constructor(args = []) {
2217
2220
  this.content = [];
@@ -2247,14 +2250,14 @@ var Doc = class {
2247
2250
  }
2248
2251
  };
2249
2252
 
2250
- // node_modules/zod/v4/core/versions.js
2253
+ // ../../node_modules/zod/v4/core/versions.js
2251
2254
  var version = {
2252
2255
  major: 4,
2253
2256
  minor: 3,
2254
2257
  patch: 6
2255
2258
  };
2256
2259
 
2257
- // node_modules/zod/v4/core/schemas.js
2260
+ // ../../node_modules/zod/v4/core/schemas.js
2258
2261
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
2259
2262
  var _a2;
2260
2263
  inst ?? (inst = {});
@@ -4225,7 +4228,7 @@ function handleRefineResult(result, payload, input, inst) {
4225
4228
  }
4226
4229
  }
4227
4230
 
4228
- // node_modules/zod/v4/locales/index.js
4231
+ // ../../node_modules/zod/v4/locales/index.js
4229
4232
  var locales_exports = {};
4230
4233
  __export(locales_exports, {
4231
4234
  ar: () => ar_default,
@@ -4279,7 +4282,7 @@ __export(locales_exports, {
4279
4282
  zhTW: () => zh_TW_default
4280
4283
  });
4281
4284
 
4282
- // node_modules/zod/v4/locales/ar.js
4285
+ // ../../node_modules/zod/v4/locales/ar.js
4283
4286
  var error = () => {
4284
4287
  const Sizable = {
4285
4288
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -4386,7 +4389,7 @@ function ar_default() {
4386
4389
  };
4387
4390
  }
4388
4391
 
4389
- // node_modules/zod/v4/locales/az.js
4392
+ // ../../node_modules/zod/v4/locales/az.js
4390
4393
  var error2 = () => {
4391
4394
  const Sizable = {
4392
4395
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
@@ -4492,7 +4495,7 @@ function az_default() {
4492
4495
  };
4493
4496
  }
4494
4497
 
4495
- // node_modules/zod/v4/locales/be.js
4498
+ // ../../node_modules/zod/v4/locales/be.js
4496
4499
  function getBelarusianPlural(count, one, few, many) {
4497
4500
  const absCount = Math.abs(count);
4498
4501
  const lastDigit = absCount % 10;
@@ -4649,7 +4652,7 @@ function be_default() {
4649
4652
  };
4650
4653
  }
4651
4654
 
4652
- // node_modules/zod/v4/locales/bg.js
4655
+ // ../../node_modules/zod/v4/locales/bg.js
4653
4656
  var error4 = () => {
4654
4657
  const Sizable = {
4655
4658
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -4770,7 +4773,7 @@ function bg_default() {
4770
4773
  };
4771
4774
  }
4772
4775
 
4773
- // node_modules/zod/v4/locales/ca.js
4776
+ // ../../node_modules/zod/v4/locales/ca.js
4774
4777
  var error5 = () => {
4775
4778
  const Sizable = {
4776
4779
  string: { unit: "car\xE0cters", verb: "contenir" },
@@ -4879,7 +4882,7 @@ function ca_default() {
4879
4882
  };
4880
4883
  }
4881
4884
 
4882
- // node_modules/zod/v4/locales/cs.js
4885
+ // ../../node_modules/zod/v4/locales/cs.js
4883
4886
  var error6 = () => {
4884
4887
  const Sizable = {
4885
4888
  string: { unit: "znak\u016F", verb: "m\xEDt" },
@@ -4991,7 +4994,7 @@ function cs_default() {
4991
4994
  };
4992
4995
  }
4993
4996
 
4994
- // node_modules/zod/v4/locales/da.js
4997
+ // ../../node_modules/zod/v4/locales/da.js
4995
4998
  var error7 = () => {
4996
4999
  const Sizable = {
4997
5000
  string: { unit: "tegn", verb: "havde" },
@@ -5107,7 +5110,7 @@ function da_default() {
5107
5110
  };
5108
5111
  }
5109
5112
 
5110
- // node_modules/zod/v4/locales/de.js
5113
+ // ../../node_modules/zod/v4/locales/de.js
5111
5114
  var error8 = () => {
5112
5115
  const Sizable = {
5113
5116
  string: { unit: "Zeichen", verb: "zu haben" },
@@ -5216,7 +5219,7 @@ function de_default() {
5216
5219
  };
5217
5220
  }
5218
5221
 
5219
- // node_modules/zod/v4/locales/en.js
5222
+ // ../../node_modules/zod/v4/locales/en.js
5220
5223
  var error9 = () => {
5221
5224
  const Sizable = {
5222
5225
  string: { unit: "characters", verb: "to have" },
@@ -5325,7 +5328,7 @@ function en_default() {
5325
5328
  };
5326
5329
  }
5327
5330
 
5328
- // node_modules/zod/v4/locales/eo.js
5331
+ // ../../node_modules/zod/v4/locales/eo.js
5329
5332
  var error10 = () => {
5330
5333
  const Sizable = {
5331
5334
  string: { unit: "karaktrojn", verb: "havi" },
@@ -5435,7 +5438,7 @@ function eo_default() {
5435
5438
  };
5436
5439
  }
5437
5440
 
5438
- // node_modules/zod/v4/locales/es.js
5441
+ // ../../node_modules/zod/v4/locales/es.js
5439
5442
  var error11 = () => {
5440
5443
  const Sizable = {
5441
5444
  string: { unit: "caracteres", verb: "tener" },
@@ -5568,7 +5571,7 @@ function es_default() {
5568
5571
  };
5569
5572
  }
5570
5573
 
5571
- // node_modules/zod/v4/locales/fa.js
5574
+ // ../../node_modules/zod/v4/locales/fa.js
5572
5575
  var error12 = () => {
5573
5576
  const Sizable = {
5574
5577
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -5683,7 +5686,7 @@ function fa_default() {
5683
5686
  };
5684
5687
  }
5685
5688
 
5686
- // node_modules/zod/v4/locales/fi.js
5689
+ // ../../node_modules/zod/v4/locales/fi.js
5687
5690
  var error13 = () => {
5688
5691
  const Sizable = {
5689
5692
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
@@ -5796,7 +5799,7 @@ function fi_default() {
5796
5799
  };
5797
5800
  }
5798
5801
 
5799
- // node_modules/zod/v4/locales/fr.js
5802
+ // ../../node_modules/zod/v4/locales/fr.js
5800
5803
  var error14 = () => {
5801
5804
  const Sizable = {
5802
5805
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -5905,7 +5908,7 @@ function fr_default() {
5905
5908
  };
5906
5909
  }
5907
5910
 
5908
- // node_modules/zod/v4/locales/fr-CA.js
5911
+ // ../../node_modules/zod/v4/locales/fr-CA.js
5909
5912
  var error15 = () => {
5910
5913
  const Sizable = {
5911
5914
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -6013,7 +6016,7 @@ function fr_CA_default() {
6013
6016
  };
6014
6017
  }
6015
6018
 
6016
- // node_modules/zod/v4/locales/he.js
6019
+ // ../../node_modules/zod/v4/locales/he.js
6017
6020
  var error16 = () => {
6018
6021
  const TypeNames = {
6019
6022
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
@@ -6208,7 +6211,7 @@ function he_default() {
6208
6211
  };
6209
6212
  }
6210
6213
 
6211
- // node_modules/zod/v4/locales/hu.js
6214
+ // ../../node_modules/zod/v4/locales/hu.js
6212
6215
  var error17 = () => {
6213
6216
  const Sizable = {
6214
6217
  string: { unit: "karakter", verb: "legyen" },
@@ -6317,7 +6320,7 @@ function hu_default() {
6317
6320
  };
6318
6321
  }
6319
6322
 
6320
- // node_modules/zod/v4/locales/hy.js
6323
+ // ../../node_modules/zod/v4/locales/hy.js
6321
6324
  function getArmenianPlural(count, one, many) {
6322
6325
  return Math.abs(count) === 1 ? one : many;
6323
6326
  }
@@ -6465,7 +6468,7 @@ function hy_default() {
6465
6468
  };
6466
6469
  }
6467
6470
 
6468
- // node_modules/zod/v4/locales/id.js
6471
+ // ../../node_modules/zod/v4/locales/id.js
6469
6472
  var error19 = () => {
6470
6473
  const Sizable = {
6471
6474
  string: { unit: "karakter", verb: "memiliki" },
@@ -6572,7 +6575,7 @@ function id_default() {
6572
6575
  };
6573
6576
  }
6574
6577
 
6575
- // node_modules/zod/v4/locales/is.js
6578
+ // ../../node_modules/zod/v4/locales/is.js
6576
6579
  var error20 = () => {
6577
6580
  const Sizable = {
6578
6581
  string: { unit: "stafi", verb: "a\xF0 hafa" },
@@ -6682,7 +6685,7 @@ function is_default() {
6682
6685
  };
6683
6686
  }
6684
6687
 
6685
- // node_modules/zod/v4/locales/it.js
6688
+ // ../../node_modules/zod/v4/locales/it.js
6686
6689
  var error21 = () => {
6687
6690
  const Sizable = {
6688
6691
  string: { unit: "caratteri", verb: "avere" },
@@ -6791,7 +6794,7 @@ function it_default() {
6791
6794
  };
6792
6795
  }
6793
6796
 
6794
- // node_modules/zod/v4/locales/ja.js
6797
+ // ../../node_modules/zod/v4/locales/ja.js
6795
6798
  var error22 = () => {
6796
6799
  const Sizable = {
6797
6800
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
@@ -6899,7 +6902,7 @@ function ja_default() {
6899
6902
  };
6900
6903
  }
6901
6904
 
6902
- // node_modules/zod/v4/locales/ka.js
6905
+ // ../../node_modules/zod/v4/locales/ka.js
6903
6906
  var error23 = () => {
6904
6907
  const Sizable = {
6905
6908
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -7012,7 +7015,7 @@ function ka_default() {
7012
7015
  };
7013
7016
  }
7014
7017
 
7015
- // node_modules/zod/v4/locales/km.js
7018
+ // ../../node_modules/zod/v4/locales/km.js
7016
7019
  var error24 = () => {
7017
7020
  const Sizable = {
7018
7021
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -7123,12 +7126,12 @@ function km_default() {
7123
7126
  };
7124
7127
  }
7125
7128
 
7126
- // node_modules/zod/v4/locales/kh.js
7129
+ // ../../node_modules/zod/v4/locales/kh.js
7127
7130
  function kh_default() {
7128
7131
  return km_default();
7129
7132
  }
7130
7133
 
7131
- // node_modules/zod/v4/locales/ko.js
7134
+ // ../../node_modules/zod/v4/locales/ko.js
7132
7135
  var error25 = () => {
7133
7136
  const Sizable = {
7134
7137
  string: { unit: "\uBB38\uC790", verb: "to have" },
@@ -7240,7 +7243,7 @@ function ko_default() {
7240
7243
  };
7241
7244
  }
7242
7245
 
7243
- // node_modules/zod/v4/locales/lt.js
7246
+ // ../../node_modules/zod/v4/locales/lt.js
7244
7247
  var capitalizeFirstCharacter = (text) => {
7245
7248
  return text.charAt(0).toUpperCase() + text.slice(1);
7246
7249
  };
@@ -7444,7 +7447,7 @@ function lt_default() {
7444
7447
  };
7445
7448
  }
7446
7449
 
7447
- // node_modules/zod/v4/locales/mk.js
7450
+ // ../../node_modules/zod/v4/locales/mk.js
7448
7451
  var error27 = () => {
7449
7452
  const Sizable = {
7450
7453
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -7554,7 +7557,7 @@ function mk_default() {
7554
7557
  };
7555
7558
  }
7556
7559
 
7557
- // node_modules/zod/v4/locales/ms.js
7560
+ // ../../node_modules/zod/v4/locales/ms.js
7558
7561
  var error28 = () => {
7559
7562
  const Sizable = {
7560
7563
  string: { unit: "aksara", verb: "mempunyai" },
@@ -7662,7 +7665,7 @@ function ms_default() {
7662
7665
  };
7663
7666
  }
7664
7667
 
7665
- // node_modules/zod/v4/locales/nl.js
7668
+ // ../../node_modules/zod/v4/locales/nl.js
7666
7669
  var error29 = () => {
7667
7670
  const Sizable = {
7668
7671
  string: { unit: "tekens", verb: "heeft" },
@@ -7773,7 +7776,7 @@ function nl_default() {
7773
7776
  };
7774
7777
  }
7775
7778
 
7776
- // node_modules/zod/v4/locales/no.js
7779
+ // ../../node_modules/zod/v4/locales/no.js
7777
7780
  var error30 = () => {
7778
7781
  const Sizable = {
7779
7782
  string: { unit: "tegn", verb: "\xE5 ha" },
@@ -7882,7 +7885,7 @@ function no_default() {
7882
7885
  };
7883
7886
  }
7884
7887
 
7885
- // node_modules/zod/v4/locales/ota.js
7888
+ // ../../node_modules/zod/v4/locales/ota.js
7886
7889
  var error31 = () => {
7887
7890
  const Sizable = {
7888
7891
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
@@ -7992,7 +7995,7 @@ function ota_default() {
7992
7995
  };
7993
7996
  }
7994
7997
 
7995
- // node_modules/zod/v4/locales/ps.js
7998
+ // ../../node_modules/zod/v4/locales/ps.js
7996
7999
  var error32 = () => {
7997
8000
  const Sizable = {
7998
8001
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
@@ -8107,7 +8110,7 @@ function ps_default() {
8107
8110
  };
8108
8111
  }
8109
8112
 
8110
- // node_modules/zod/v4/locales/pl.js
8113
+ // ../../node_modules/zod/v4/locales/pl.js
8111
8114
  var error33 = () => {
8112
8115
  const Sizable = {
8113
8116
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
@@ -8217,7 +8220,7 @@ function pl_default() {
8217
8220
  };
8218
8221
  }
8219
8222
 
8220
- // node_modules/zod/v4/locales/pt.js
8223
+ // ../../node_modules/zod/v4/locales/pt.js
8221
8224
  var error34 = () => {
8222
8225
  const Sizable = {
8223
8226
  string: { unit: "caracteres", verb: "ter" },
@@ -8326,7 +8329,7 @@ function pt_default() {
8326
8329
  };
8327
8330
  }
8328
8331
 
8329
- // node_modules/zod/v4/locales/ru.js
8332
+ // ../../node_modules/zod/v4/locales/ru.js
8330
8333
  function getRussianPlural(count, one, few, many) {
8331
8334
  const absCount = Math.abs(count);
8332
8335
  const lastDigit = absCount % 10;
@@ -8483,7 +8486,7 @@ function ru_default() {
8483
8486
  };
8484
8487
  }
8485
8488
 
8486
- // node_modules/zod/v4/locales/sl.js
8489
+ // ../../node_modules/zod/v4/locales/sl.js
8487
8490
  var error36 = () => {
8488
8491
  const Sizable = {
8489
8492
  string: { unit: "znakov", verb: "imeti" },
@@ -8593,7 +8596,7 @@ function sl_default() {
8593
8596
  };
8594
8597
  }
8595
8598
 
8596
- // node_modules/zod/v4/locales/sv.js
8599
+ // ../../node_modules/zod/v4/locales/sv.js
8597
8600
  var error37 = () => {
8598
8601
  const Sizable = {
8599
8602
  string: { unit: "tecken", verb: "att ha" },
@@ -8704,7 +8707,7 @@ function sv_default() {
8704
8707
  };
8705
8708
  }
8706
8709
 
8707
- // node_modules/zod/v4/locales/ta.js
8710
+ // ../../node_modules/zod/v4/locales/ta.js
8708
8711
  var error38 = () => {
8709
8712
  const Sizable = {
8710
8713
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -8815,7 +8818,7 @@ function ta_default() {
8815
8818
  };
8816
8819
  }
8817
8820
 
8818
- // node_modules/zod/v4/locales/th.js
8821
+ // ../../node_modules/zod/v4/locales/th.js
8819
8822
  var error39 = () => {
8820
8823
  const Sizable = {
8821
8824
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -8926,7 +8929,7 @@ function th_default() {
8926
8929
  };
8927
8930
  }
8928
8931
 
8929
- // node_modules/zod/v4/locales/tr.js
8932
+ // ../../node_modules/zod/v4/locales/tr.js
8930
8933
  var error40 = () => {
8931
8934
  const Sizable = {
8932
8935
  string: { unit: "karakter", verb: "olmal\u0131" },
@@ -9032,7 +9035,7 @@ function tr_default() {
9032
9035
  };
9033
9036
  }
9034
9037
 
9035
- // node_modules/zod/v4/locales/uk.js
9038
+ // ../../node_modules/zod/v4/locales/uk.js
9036
9039
  var error41 = () => {
9037
9040
  const Sizable = {
9038
9041
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -9141,12 +9144,12 @@ function uk_default() {
9141
9144
  };
9142
9145
  }
9143
9146
 
9144
- // node_modules/zod/v4/locales/ua.js
9147
+ // ../../node_modules/zod/v4/locales/ua.js
9145
9148
  function ua_default() {
9146
9149
  return uk_default();
9147
9150
  }
9148
9151
 
9149
- // node_modules/zod/v4/locales/ur.js
9152
+ // ../../node_modules/zod/v4/locales/ur.js
9150
9153
  var error42 = () => {
9151
9154
  const Sizable = {
9152
9155
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
@@ -9257,7 +9260,7 @@ function ur_default() {
9257
9260
  };
9258
9261
  }
9259
9262
 
9260
- // node_modules/zod/v4/locales/uz.js
9263
+ // ../../node_modules/zod/v4/locales/uz.js
9261
9264
  var error43 = () => {
9262
9265
  const Sizable = {
9263
9266
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
@@ -9367,7 +9370,7 @@ function uz_default() {
9367
9370
  };
9368
9371
  }
9369
9372
 
9370
- // node_modules/zod/v4/locales/vi.js
9373
+ // ../../node_modules/zod/v4/locales/vi.js
9371
9374
  var error44 = () => {
9372
9375
  const Sizable = {
9373
9376
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
@@ -9476,7 +9479,7 @@ function vi_default() {
9476
9479
  };
9477
9480
  }
9478
9481
 
9479
- // node_modules/zod/v4/locales/zh-CN.js
9482
+ // ../../node_modules/zod/v4/locales/zh-CN.js
9480
9483
  var error45 = () => {
9481
9484
  const Sizable = {
9482
9485
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
@@ -9586,7 +9589,7 @@ function zh_CN_default() {
9586
9589
  };
9587
9590
  }
9588
9591
 
9589
- // node_modules/zod/v4/locales/zh-TW.js
9592
+ // ../../node_modules/zod/v4/locales/zh-TW.js
9590
9593
  var error46 = () => {
9591
9594
  const Sizable = {
9592
9595
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
@@ -9694,7 +9697,7 @@ function zh_TW_default() {
9694
9697
  };
9695
9698
  }
9696
9699
 
9697
- // node_modules/zod/v4/locales/yo.js
9700
+ // ../../node_modules/zod/v4/locales/yo.js
9698
9701
  var error47 = () => {
9699
9702
  const Sizable = {
9700
9703
  string: { unit: "\xE0mi", verb: "n\xED" },
@@ -9802,7 +9805,7 @@ function yo_default() {
9802
9805
  };
9803
9806
  }
9804
9807
 
9805
- // node_modules/zod/v4/core/registries.js
9808
+ // ../../node_modules/zod/v4/core/registries.js
9806
9809
  var _a;
9807
9810
  var $output = /* @__PURE__ */ Symbol("ZodOutput");
9808
9811
  var $input = /* @__PURE__ */ Symbol("ZodInput");
@@ -9852,7 +9855,7 @@ function registry() {
9852
9855
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
9853
9856
  var globalRegistry = globalThis.__zod_globalRegistry;
9854
9857
 
9855
- // node_modules/zod/v4/core/api.js
9858
+ // ../../node_modules/zod/v4/core/api.js
9856
9859
  // @__NO_SIDE_EFFECTS__
9857
9860
  function _string(Class2, params) {
9858
9861
  return new Class2({
@@ -10891,7 +10894,7 @@ function _stringFormat(Class2, format, fnOrRegex, _params = {}) {
10891
10894
  return inst;
10892
10895
  }
10893
10896
 
10894
- // node_modules/zod/v4/core/to-json-schema.js
10897
+ // ../../node_modules/zod/v4/core/to-json-schema.js
10895
10898
  function initializeContext(params) {
10896
10899
  let target = params?.target ?? "draft-2020-12";
10897
10900
  if (target === "draft-4")
@@ -11243,7 +11246,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
11243
11246
  return finalize(ctx, schema);
11244
11247
  };
11245
11248
 
11246
- // node_modules/zod/v4/core/json-schema-processors.js
11249
+ // ../../node_modules/zod/v4/core/json-schema-processors.js
11247
11250
  var formatMap = {
11248
11251
  guid: "uuid",
11249
11252
  url: "uri",
@@ -11794,7 +11797,7 @@ function toJSONSchema(input, params) {
11794
11797
  return finalize(ctx, input);
11795
11798
  }
11796
11799
 
11797
- // node_modules/zod/v4/core/json-schema-generator.js
11800
+ // ../../node_modules/zod/v4/core/json-schema-generator.js
11798
11801
  var JSONSchemaGenerator = class {
11799
11802
  /** @deprecated Access via ctx instead */
11800
11803
  get metadataRegistry() {
@@ -11869,10 +11872,10 @@ var JSONSchemaGenerator = class {
11869
11872
  }
11870
11873
  };
11871
11874
 
11872
- // node_modules/zod/v4/core/json-schema.js
11875
+ // ../../node_modules/zod/v4/core/json-schema.js
11873
11876
  var json_schema_exports = {};
11874
11877
 
11875
- // node_modules/zod/v4/classic/schemas.js
11878
+ // ../../node_modules/zod/v4/classic/schemas.js
11876
11879
  var schemas_exports2 = {};
11877
11880
  __export(schemas_exports2, {
11878
11881
  ZodAny: () => ZodAny,
@@ -12041,7 +12044,7 @@ __export(schemas_exports2, {
12041
12044
  xor: () => xor
12042
12045
  });
12043
12046
 
12044
- // node_modules/zod/v4/classic/checks.js
12047
+ // ../../node_modules/zod/v4/classic/checks.js
12045
12048
  var checks_exports2 = {};
12046
12049
  __export(checks_exports2, {
12047
12050
  endsWith: () => _endsWith,
@@ -12075,7 +12078,7 @@ __export(checks_exports2, {
12075
12078
  uppercase: () => _uppercase
12076
12079
  });
12077
12080
 
12078
- // node_modules/zod/v4/classic/iso.js
12081
+ // ../../node_modules/zod/v4/classic/iso.js
12079
12082
  var iso_exports = {};
12080
12083
  __export(iso_exports, {
12081
12084
  ZodISODate: () => ZodISODate,
@@ -12116,7 +12119,7 @@ function duration2(params) {
12116
12119
  return _isoDuration(ZodISODuration, params);
12117
12120
  }
12118
12121
 
12119
- // node_modules/zod/v4/classic/errors.js
12122
+ // ../../node_modules/zod/v4/classic/errors.js
12120
12123
  var initializer2 = (inst, issues) => {
12121
12124
  $ZodError.init(inst, issues);
12122
12125
  inst.name = "ZodError";
@@ -12156,7 +12159,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
12156
12159
  Parent: Error
12157
12160
  });
12158
12161
 
12159
- // node_modules/zod/v4/classic/parse.js
12162
+ // ../../node_modules/zod/v4/classic/parse.js
12160
12163
  var parse2 = /* @__PURE__ */ _parse(ZodRealError);
12161
12164
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
12162
12165
  var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -12170,7 +12173,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
12170
12173
  var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
12171
12174
  var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
12172
12175
 
12173
- // node_modules/zod/v4/classic/schemas.js
12176
+ // ../../node_modules/zod/v4/classic/schemas.js
12174
12177
  var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
12175
12178
  $ZodType.init(inst, def);
12176
12179
  Object.assign(inst["~standard"], {
@@ -13249,7 +13252,7 @@ function preprocess(fn, schema) {
13249
13252
  return pipe(transform(fn), schema);
13250
13253
  }
13251
13254
 
13252
- // node_modules/zod/v4/classic/compat.js
13255
+ // ../../node_modules/zod/v4/classic/compat.js
13253
13256
  var ZodIssueCode = {
13254
13257
  invalid_type: "invalid_type",
13255
13258
  too_big: "too_big",
@@ -13275,7 +13278,7 @@ var ZodFirstPartyTypeKind;
13275
13278
  /* @__PURE__ */ (function(ZodFirstPartyTypeKind2) {
13276
13279
  })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
13277
13280
 
13278
- // node_modules/zod/v4/classic/from-json-schema.js
13281
+ // ../../node_modules/zod/v4/classic/from-json-schema.js
13279
13282
  var z = {
13280
13283
  ...schemas_exports2,
13281
13284
  ...checks_exports2,
@@ -13369,13 +13372,13 @@ function resolveRef(ref, ctx) {
13369
13372
  if (!ref.startsWith("#")) {
13370
13373
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
13371
13374
  }
13372
- const path2 = ref.slice(1).split("/").filter(Boolean);
13373
- if (path2.length === 0) {
13375
+ const path3 = ref.slice(1).split("/").filter(Boolean);
13376
+ if (path3.length === 0) {
13374
13377
  return ctx.rootSchema;
13375
13378
  }
13376
13379
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
13377
- if (path2[0] === defsKey) {
13378
- const key = path2[1];
13380
+ if (path3[0] === defsKey) {
13381
+ const key = path3[1];
13379
13382
  if (!key || !ctx.defs[key]) {
13380
13383
  throw new Error(`Reference not found: ${ref}`);
13381
13384
  }
@@ -13749,7 +13752,7 @@ function fromJSONSchema(schema, params) {
13749
13752
  return convertSchema(schema, ctx);
13750
13753
  }
13751
13754
 
13752
- // node_modules/zod/v4/classic/coerce.js
13755
+ // ../../node_modules/zod/v4/classic/coerce.js
13753
13756
  var coerce_exports = {};
13754
13757
  __export(coerce_exports, {
13755
13758
  bigint: () => bigint3,
@@ -13774,15 +13777,30 @@ function date4(params) {
13774
13777
  return _coercedDate(ZodDate, params);
13775
13778
  }
13776
13779
 
13777
- // node_modules/zod/v4/classic/external.js
13780
+ // ../../node_modules/zod/v4/classic/external.js
13778
13781
  config(en_default());
13779
13782
 
13780
13783
  // src/index.ts
13784
+ import fs2 from "fs-extra";
13785
+ import path2 from "path";
13786
+
13787
+ // src/install.ts
13781
13788
  import fs from "fs-extra";
13782
13789
  import path from "path";
13783
13790
  var REGISTRY_URL = process.env.BEARNIE_REGISTRY_URL || "https://bearnie.dev/registry";
13791
+ function getRegistryPath() {
13792
+ return process.env.BEARNIE_REGISTRY_PATH;
13793
+ }
13784
13794
  async function fetchComponent(name) {
13785
13795
  try {
13796
+ const registryPath = getRegistryPath();
13797
+ if (registryPath) {
13798
+ const componentPath = path.join(registryPath, `${name}.json`);
13799
+ if (await fs.pathExists(componentPath)) {
13800
+ return await fs.readJson(componentPath);
13801
+ }
13802
+ return null;
13803
+ }
13786
13804
  const response = await fetch(`${REGISTRY_URL}/${name}.json`);
13787
13805
  if (!response.ok) return null;
13788
13806
  return await response.json();
@@ -13792,6 +13810,14 @@ async function fetchComponent(name) {
13792
13810
  }
13793
13811
  async function fetchIndex() {
13794
13812
  try {
13813
+ const registryPath = getRegistryPath();
13814
+ if (registryPath) {
13815
+ const indexPath = path.join(registryPath, "index.json");
13816
+ if (await fs.pathExists(indexPath)) {
13817
+ return await fs.readJson(indexPath);
13818
+ }
13819
+ return null;
13820
+ }
13795
13821
  const response = await fetch(`${REGISTRY_URL}/index.json`);
13796
13822
  if (!response.ok) return null;
13797
13823
  return await response.json();
@@ -13799,19 +13825,152 @@ async function fetchIndex() {
13799
13825
  return null;
13800
13826
  }
13801
13827
  }
13828
+ function resolveInstallPath(projectRoot, file2, registryItem) {
13829
+ const relativePath = file2.path || file2.name;
13830
+ if (registryItem.type === "utility" || relativePath.startsWith("utils/")) {
13831
+ return path.join(
13832
+ projectRoot,
13833
+ "src/utils",
13834
+ relativePath.replace(/^utils\//, "")
13835
+ );
13836
+ }
13837
+ if (registryItem.type === "styles" || relativePath.startsWith("styles/")) {
13838
+ return path.join(
13839
+ projectRoot,
13840
+ "src/styles",
13841
+ relativePath.replace(/^styles\//, "")
13842
+ );
13843
+ }
13844
+ return path.join(projectRoot, "src/components/bearnie", relativePath);
13845
+ }
13846
+ async function resolveComponentDependencies(names, resolved = /* @__PURE__ */ new Set()) {
13847
+ const result = [];
13848
+ for (const name of names) {
13849
+ if (resolved.has(name)) continue;
13850
+ resolved.add(name);
13851
+ const component = await fetchComponent(name);
13852
+ if (!component) continue;
13853
+ if (component.registryDependencies?.length) {
13854
+ const deps = await resolveComponentDependencies(
13855
+ component.registryDependencies,
13856
+ resolved
13857
+ );
13858
+ result.push(...deps);
13859
+ }
13860
+ result.push(name);
13861
+ }
13862
+ return result;
13863
+ }
13864
+ function orderWithBarrelLast(names) {
13865
+ const unique = [...new Set(names)];
13866
+ const withoutBarrel = unique.filter((name) => name !== "barrel");
13867
+ if (unique.includes("barrel")) {
13868
+ withoutBarrel.push("barrel");
13869
+ }
13870
+ return withoutBarrel;
13871
+ }
13872
+ async function installSingleComponent(projectRoot, componentName) {
13873
+ const component = await fetchComponent(componentName);
13874
+ if (!component) {
13875
+ return {
13876
+ files: [],
13877
+ npmDependencies: [],
13878
+ error: `Component '${componentName}' not found`
13879
+ };
13880
+ }
13881
+ const files = [];
13882
+ const npmDependencies = [...component.dependencies ?? []];
13883
+ const installFiles = async (entry) => {
13884
+ for (const file2 of entry.files) {
13885
+ const filePath = resolveInstallPath(projectRoot, file2, entry);
13886
+ await fs.ensureDir(path.dirname(filePath));
13887
+ await fs.writeFile(filePath, file2.content);
13888
+ files.push(file2.path || file2.name);
13889
+ }
13890
+ };
13891
+ if (component.registryDependencies?.length) {
13892
+ for (const dep of component.registryDependencies) {
13893
+ const depComponent = await fetchComponent(dep);
13894
+ if (depComponent) {
13895
+ await installFiles(depComponent);
13896
+ npmDependencies.push(...depComponent.dependencies ?? []);
13897
+ }
13898
+ }
13899
+ }
13900
+ await installFiles(component);
13901
+ return { files, npmDependencies };
13902
+ }
13903
+ async function installComponents(projectRoot, names) {
13904
+ const resolved = await resolveComponentDependencies(names);
13905
+ const ordered = orderWithBarrelLast(resolved);
13906
+ const installed = [];
13907
+ const npmDependencies = /* @__PURE__ */ new Set();
13908
+ const errors = [];
13909
+ for (const name of ordered) {
13910
+ const result = await installSingleComponent(projectRoot, name);
13911
+ if (result.error) {
13912
+ errors.push(result.error);
13913
+ continue;
13914
+ }
13915
+ installed.push(name);
13916
+ result.npmDependencies.forEach((dep) => npmDependencies.add(dep));
13917
+ }
13918
+ return {
13919
+ installed,
13920
+ npmDependencies: [...npmDependencies],
13921
+ errors
13922
+ };
13923
+ }
13924
+ function toPascalCase(name) {
13925
+ return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
13926
+ }
13927
+ function getUsageExample(component) {
13928
+ if (component.name === "barrel") {
13929
+ return `\`\`\`astro
13930
+ ---
13931
+ import { Button, Card } from "@/components/bearnie";
13932
+ ---
13933
+
13934
+ <Button>Click me</Button>
13935
+ \`\`\``;
13936
+ }
13937
+ if (component.type === "styles") {
13938
+ return `\`\`\`css
13939
+ @import "tailwindcss";
13940
+ @import "./bearnie.css";
13941
+ \`\`\``;
13942
+ }
13943
+ if (component.type === "utility") {
13944
+ return "Utility added to `src/utils/`. Import it where needed in your components.";
13945
+ }
13946
+ const componentName = toPascalCase(component.name);
13947
+ return `\`\`\`astro
13948
+ ---
13949
+ import ${componentName} from "@/components/bearnie/${component.name}/${componentName}.astro";
13950
+ ---
13951
+
13952
+ <${componentName}>Content</${componentName}>
13953
+ \`\`\``;
13954
+ }
13955
+
13956
+ // src/index.ts
13957
+ var __dirname = dirname(fileURLToPath(import.meta.url));
13958
+ var pkg = JSON.parse(
13959
+ readFileSync(join(__dirname, "../package.json"), "utf-8")
13960
+ );
13802
13961
  function findProjectRoot(startDir) {
13803
13962
  let dir = startDir;
13804
- while (dir !== path.parse(dir).root) {
13805
- if (fs.existsSync(path.join(dir, "package.json"))) {
13963
+ while (dir !== path2.parse(dir).root) {
13964
+ if (fs2.existsSync(path2.join(dir, "package.json"))) {
13806
13965
  return dir;
13807
13966
  }
13808
- dir = path.dirname(dir);
13967
+ dir = path2.dirname(dir);
13809
13968
  }
13810
13969
  return null;
13811
13970
  }
13812
13971
  var server = new McpServer({
13813
13972
  name: "bearnie",
13814
- version: "0.1.0"
13973
+ version: pkg.version
13815
13974
  });
13816
13975
  server.tool(
13817
13976
  "list_components",
@@ -13829,11 +13988,14 @@ server.tool(
13829
13988
  ]
13830
13989
  };
13831
13990
  }
13832
- const grouped = index.components.reduce((acc, comp) => {
13833
- if (!acc[comp.category]) acc[comp.category] = [];
13834
- acc[comp.category].push(comp);
13835
- return acc;
13836
- }, {});
13991
+ const grouped = index.components.reduce(
13992
+ (acc, comp) => {
13993
+ if (!acc[comp.category]) acc[comp.category] = [];
13994
+ acc[comp.category].push(comp);
13995
+ return acc;
13996
+ },
13997
+ {}
13998
+ );
13837
13999
  let output = "# Available Bearnie Components\n\n";
13838
14000
  for (const [category, components] of Object.entries(grouped).sort()) {
13839
14001
  output += `## ${category.charAt(0).toUpperCase() + category.slice(1)}
@@ -13855,7 +14017,7 @@ server.tool(
13855
14017
  "Get detailed information about a specific Bearnie component including its files and dependencies",
13856
14018
  {
13857
14019
  name: external_exports.string().describe(
13858
- "The name of the component (e.g., 'button', 'accordion', 'dialog')"
14020
+ "The name of the component (e.g., 'button', 'accordion', 'dialog', 'barrel')"
13859
14021
  )
13860
14022
  },
13861
14023
  async ({ name }) => {
@@ -13916,7 +14078,7 @@ ${file2.content}
13916
14078
  );
13917
14079
  server.tool(
13918
14080
  "add_component",
13919
- "Add a Bearnie component to the current Astro project. This will create the component files in src/components/bearnie/",
14081
+ "Add a Bearnie component to the current Astro project. Creates files in src/components/bearnie/. Add the barrel export last with name 'barrel' after other components are installed.",
13920
14082
  {
13921
14083
  name: external_exports.string().describe(
13922
14084
  "The name of the component to add (e.g., 'button', 'accordion')"
@@ -13936,72 +14098,98 @@ server.tool(
13936
14098
  ]
13937
14099
  };
13938
14100
  }
13939
- const component = await fetchComponent(name.toLowerCase());
13940
- if (!component) {
14101
+ const result = await installComponents(projectRoot, [name.toLowerCase()]);
14102
+ if (result.errors.length > 0) {
13941
14103
  return {
13942
14104
  content: [
13943
14105
  {
13944
14106
  type: "text",
13945
- text: `Error: Component '${name}' not found. Use list_components to see available components.`
14107
+ text: `Error: ${result.errors.join(", ")}`
13946
14108
  }
13947
14109
  ]
13948
14110
  };
13949
14111
  }
13950
- const results = [];
13951
- const getFilePath = (file2, registryItem) => {
13952
- const relativePath = file2.path || file2.name;
13953
- if (registryItem.type === "utility" || relativePath.startsWith("utils/")) {
13954
- return path.join(projectRoot, "src", relativePath);
13955
- }
13956
- return path.join(projectRoot, "src/components/bearnie", relativePath);
14112
+ const component = await fetchComponent(name.toLowerCase());
14113
+ let output = `# Added ${name}
14114
+
14115
+ `;
14116
+ output += result.installed.map((item) => `\u2713 Added: ${item}`).join("\n");
14117
+ output += "\n\n";
14118
+ if (name.toLowerCase() === "barrel") {
14119
+ output += "Add components first, then install the barrel for named imports from `@/components/bearnie`.\n\n";
14120
+ }
14121
+ if (result.npmDependencies.length > 0) {
14122
+ output += `## Required NPM Dependencies
14123
+
14124
+ `;
14125
+ output += `\`\`\`bash
14126
+ npm install ${result.npmDependencies.join(" ")}
14127
+ \`\`\`
14128
+
14129
+ `;
14130
+ }
14131
+ if (component) {
14132
+ output += `## Usage
14133
+
14134
+ `;
14135
+ output += getUsageExample(component);
14136
+ }
14137
+ return {
14138
+ content: [{ type: "text", text: output }]
13957
14139
  };
13958
- if (component.registryDependencies?.length) {
13959
- for (const dep of component.registryDependencies) {
13960
- const depComponent = await fetchComponent(dep);
13961
- if (depComponent) {
13962
- for (const file2 of depComponent.files) {
13963
- const filePath = getFilePath(file2, depComponent);
13964
- await fs.ensureDir(path.dirname(filePath));
13965
- await fs.writeFile(filePath, file2.content);
13966
- results.push(`\u2713 Added dependency: ${file2.path || file2.name}`);
14140
+ }
14141
+ );
14142
+ server.tool(
14143
+ "add_components",
14144
+ "Add multiple Bearnie components to the current Astro project. Resolves registry dependencies and installs barrel last when included.",
14145
+ {
14146
+ names: external_exports.array(external_exports.string()).describe(
14147
+ "Component names to add (e.g., ['button', 'card', 'barrel'])"
14148
+ ),
14149
+ cwd: external_exports.string().optional().describe("The working directory (defaults to current directory)")
14150
+ },
14151
+ async ({ names, cwd }) => {
14152
+ const workingDir = cwd || process.cwd();
14153
+ const projectRoot = findProjectRoot(workingDir);
14154
+ if (!projectRoot) {
14155
+ return {
14156
+ content: [
14157
+ {
14158
+ type: "text",
14159
+ text: "Error: Could not find project root (no package.json found). Make sure you're in an Astro project."
13967
14160
  }
13968
- }
13969
- }
13970
- }
13971
- for (const file2 of component.files) {
13972
- const filePath = getFilePath(file2, component);
13973
- await fs.ensureDir(path.dirname(filePath));
13974
- await fs.writeFile(filePath, file2.content);
13975
- results.push(`\u2713 Added: ${file2.path || file2.name}`);
14161
+ ]
14162
+ };
13976
14163
  }
13977
- let output = `# Added ${component.name}
14164
+ const normalized = names.map((name) => name.toLowerCase());
14165
+ const result = await installComponents(projectRoot, normalized);
14166
+ let output = `# Added components
13978
14167
 
13979
14168
  `;
13980
- output += results.join("\n") + "\n\n";
13981
- if (component.dependencies?.length) {
13982
- output += `## Required NPM Dependencies
14169
+ if (result.installed.length > 0) {
14170
+ output += result.installed.map((item) => `\u2713 Added: ${item}`).join("\n");
14171
+ output += "\n\n";
14172
+ }
14173
+ if (result.errors.length > 0) {
14174
+ output += `## Errors
14175
+
14176
+ ${result.errors.map((error48) => `- ${error48}`).join("\n")}
13983
14177
 
13984
14178
  `;
13985
- output += `Run the following command to install required packages:
14179
+ }
14180
+ if (normalized.includes("barrel")) {
14181
+ output += "Barrel installed last for named imports from `@/components/bearnie`.\n\n";
14182
+ }
14183
+ if (result.npmDependencies.length > 0) {
14184
+ output += `## Required NPM Dependencies
13986
14185
 
13987
14186
  `;
13988
14187
  output += `\`\`\`bash
13989
- npm install ${component.dependencies.join(" ")}
14188
+ npm install ${result.npmDependencies.join(" ")}
13990
14189
  \`\`\`
13991
14190
 
13992
14191
  `;
13993
14192
  }
13994
- output += `## Usage
13995
-
13996
- `;
13997
- const componentName = component.name.charAt(0).toUpperCase() + component.name.slice(1).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
13998
- output += `\`\`\`astro
13999
- ---
14000
- import { ${componentName} } from "@/components/ui/${name}";
14001
- ---
14002
-
14003
- <${componentName}>Content</${componentName}>
14004
- \`\`\``;
14005
14193
  return {
14006
14194
  content: [{ type: "text", text: output }]
14007
14195
  };
@@ -0,0 +1,34 @@
1
+ export interface ComponentFile {
2
+ name: string;
3
+ path: string;
4
+ content: string;
5
+ }
6
+ export interface ComponentRegistry {
7
+ name: string;
8
+ type?: "utility" | "component" | "styles";
9
+ description: string;
10
+ category?: string;
11
+ files: ComponentFile[];
12
+ dependencies?: string[];
13
+ registryDependencies?: string[];
14
+ }
15
+ export interface InstallResult {
16
+ installed: string[];
17
+ npmDependencies: string[];
18
+ errors: string[];
19
+ }
20
+ export interface RegistryIndex {
21
+ components: Array<{
22
+ name: string;
23
+ description: string;
24
+ category: string;
25
+ }>;
26
+ }
27
+ export declare function fetchComponent(name: string): Promise<ComponentRegistry | null>;
28
+ export declare function fetchIndex(): Promise<RegistryIndex | null>;
29
+ export declare function resolveInstallPath(projectRoot: string, file: ComponentFile, registryItem: ComponentRegistry): string;
30
+ export declare function resolveComponentDependencies(names: string[], resolved?: Set<string>): Promise<string[]>;
31
+ export declare function installComponents(projectRoot: string, names: string[]): Promise<InstallResult>;
32
+ export declare function toPascalCase(name: string): string;
33
+ export declare function getUsageExample(component: ComponentRegistry): string;
34
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAiBnC;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiBhE;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,aAAa,EACnB,YAAY,EAAE,iBAAiB,GAC9B,MAAM,CAoBR;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,GAAE,GAAG,CAAC,MAAM,CAAa,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CAsBnB;AAmDD,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,aAAa,CAAC,CAuBxB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CA8BpE"}
package/package.json CHANGED
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "@bearnie/mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "MCP server for Bearnie UI components - enables AI assistants to add components to your project",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "bin": {
8
8
  "bearnie-mcp": "dist/index.js"
9
9
  },
10
+ "types": "dist/index.d.ts",
10
11
  "files": [
11
12
  "dist"
12
13
  ],
13
14
  "scripts": {
14
- "build": "tsup src/index.ts --format esm --dts --clean",
15
+ "build": "tsup src/index.ts --format esm --clean && tsc --emitDeclarationOnly",
15
16
  "dev": "tsup src/index.ts --format esm --watch",
16
17
  "typecheck": "tsc --noEmit"
17
18
  },
@@ -24,7 +25,7 @@
24
25
  "@types/fs-extra": "^11.0.4",
25
26
  "@types/node": "^20.14.9",
26
27
  "tsup": "^8.1.0",
27
- "typescript": "^5.5.3"
28
+ "typescript": "^5.7.3"
28
29
  },
29
30
  "engines": {
30
31
  "node": ">=18"