@bridge-ds/cli 0.11.0 → 0.11.2

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 (2) hide show
  1. package/dist/index.js +86 -6
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2543,7 +2543,8 @@ function defineConfig(input) {
2543
2543
  styleSuffix: input.components.styleSuffix ?? ".module.css",
2544
2544
  reference: input.components.reference,
2545
2545
  index: input.components.index,
2546
- specs: input.components.specs
2546
+ specs: input.components.specs,
2547
+ ...input.components.styles ? { styles: input.components.styles.map(trimSlashes) } : {}
2547
2548
  } : void 0,
2548
2549
  docs: { ...input.docs },
2549
2550
  changesets: pkg ? { dir: trimSlashes(input.changesets?.dir ?? ".changeset"), package: pkg } : void 0,
@@ -2667,6 +2668,7 @@ function loadConfig(source) {
2667
2668
  problems.push('"contrast" must be { "path", "modes"? }');
2668
2669
  const comps = d.components;
2669
2670
  if (comps !== void 0 && (!isObj(comps) || !isStr(comps.dir))) problems.push('"components.dir" must be a non-empty string');
2671
+ if (isObj(comps) && comps.styles !== void 0 && !isStrList(comps.styles)) problems.push('"components.styles" must be a list of globs');
2670
2672
  const cs = d.changeset;
2671
2673
  if (cs !== void 0 && (!isObj(cs) || !isStr(cs.package))) problems.push('"changeset.package" must be a non-empty string');
2672
2674
  const css = d.changesets;
@@ -4048,6 +4050,33 @@ var EXPLORATION_USE_CASES = [
4048
4050
  ];
4049
4051
  var EXPLORATION_STATUS_LABEL = { active: "Running", promoted: "Promoted to review", closed: "Closed" };
4050
4052
 
4053
+ // ../core/src/titles.ts
4054
+ var escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4055
+ function properWord(word, names) {
4056
+ const bare = word.replace(/[^\p{L}\p{N}]+$/u, "");
4057
+ if (!bare) return false;
4058
+ if (names.some((n) => n === bare)) return true;
4059
+ return new RegExp("\\p{Lu}", "u").test(bare.slice(1));
4060
+ }
4061
+ function lowerFirstWord(text, names = []) {
4062
+ const first = text.split(/\s+/)[0] ?? "";
4063
+ if (!first || properWord(first, names)) return text;
4064
+ return `${text.charAt(0).toLowerCase()}${text.slice(1)}`;
4065
+ }
4066
+ function subjectTitle(subject, title, names = []) {
4067
+ const t = title.trim().replace(/\.$/, "");
4068
+ const keep = [subject, ...names];
4069
+ const s = subject.trim();
4070
+ if (!s) return t;
4071
+ const m = new RegExp(`^${escape(s)}(?=$|[^\\p{L}\\p{N}])\\s*(:)?\\s*`, "iu").exec(t);
4072
+ if (m) {
4073
+ const rest = t.slice(m[0].length);
4074
+ if (!rest) return s;
4075
+ return m[1] ? `${s}: ${lowerFirstWord(rest, keep)}` : `${s} ${rest}`;
4076
+ }
4077
+ return `${s}: ${lowerFirstWord(t, keep)}`;
4078
+ }
4079
+
4051
4080
  // ../core/src/requests.ts
4052
4081
  var REQUEST_KINDS = [
4053
4082
  { value: "new-component", label: "New component", hint: "A component the design system does not have yet." },
@@ -4061,8 +4090,7 @@ var REQUEST_KINDS = [
4061
4090
  ];
4062
4091
  var REQUEST_LABEL = "component-change";
4063
4092
  function requestIssueTitle(r) {
4064
- const t = r.title.trim().replace(/\.$/, "");
4065
- return `${r.component}: ${t.charAt(0).toLowerCase()}${t.slice(1)}`;
4093
+ return subjectTitle(r.component, r.title);
4066
4094
  }
4067
4095
  var REQUEST_STATUS_LABEL = { requested: "Requested", "in-progress": "In progress", done: "Done", declined: "Declined" };
4068
4096
  function validateIntegrations(i) {
@@ -4094,6 +4122,16 @@ function jiraIssueFields(r, jira, issueUrl) {
4094
4122
  }
4095
4123
 
4096
4124
  // ../core/src/suggestions.ts
4125
+ var SUGGESTION_STATE_LABELS = {
4126
+ "needs-review": "suggestion: needs review",
4127
+ "changes-requested": "suggestion: changes requested",
4128
+ approved: "suggestion: approved",
4129
+ applying: "suggestion: applying"
4130
+ };
4131
+ var SUGGESTION_FINAL_LABELS = {
4132
+ applied: "suggestion: applied",
4133
+ declined: "suggestion: declined"
4134
+ };
4097
4135
  var SUGGESTION_STATUS_LABEL = {
4098
4136
  "needs-review": "Needs review",
4099
4137
  "changes-requested": "Changes requested",
@@ -4103,6 +4141,7 @@ var SUGGESTION_STATUS_LABEL = {
4103
4141
  declined: "Declined",
4104
4142
  outdated: "Outdated"
4105
4143
  };
4144
+ var SUGGESTION_STATUS_LABELS = [...Object.values(SUGGESTION_STATE_LABELS), ...Object.values(SUGGESTION_FINAL_LABELS)];
4106
4145
 
4107
4146
  // ../core/src/suggestion-apply.ts
4108
4147
  var SUGGESTION_APPLY_EXIT = {
@@ -5099,6 +5138,8 @@ var REPO_MODEL_DEFAULTS = {
5099
5138
  componentSpecs: "packages/react/component-specs.json",
5100
5139
  /** Optional token usage notes (group -> sentence), relative to tokens.root, when tokens.usage is not set. */
5101
5140
  tokensUsage: "usage.json",
5141
+ /** Most global stylesheets read (components.styles): a broad glob never turns into hundreds of reads. */
5142
+ maxStylesheets: 50,
5102
5143
  repo: { owner: "peterbono", repo: "ai-design-system-demo", defaultBranch: "main" }
5103
5144
  };
5104
5145
  function siteRepoFromConfig(config, raw, fallback = REPO_MODEL_DEFAULTS.repo) {
@@ -5120,6 +5161,32 @@ function siteRepoFromConfig(config, raw, fallback = REPO_MODEL_DEFAULTS.repo) {
5120
5161
  changes: config.changes ?? DEFAULT_CHANGES_MODE
5121
5162
  };
5122
5163
  }
5164
+ function styleGlobs(config) {
5165
+ if (config.components?.styles) return [...config.components.styles];
5166
+ const parent = parentDir(config.components?.dir ?? REPO_MODEL_DEFAULTS.componentsDir);
5167
+ const at = (dir) => parent ? `${parent}/${dir}/**/*.css` : `${dir}/**/*.css`;
5168
+ return [at("styles"), at("theme")];
5169
+ }
5170
+ function globBase(glob) {
5171
+ const segs = glob.split("/");
5172
+ const fixed = [];
5173
+ for (const seg of segs.slice(0, -1)) {
5174
+ if (/[*?[{]/.test(seg)) break;
5175
+ fixed.push(seg);
5176
+ }
5177
+ return fixed.join("/");
5178
+ }
5179
+ async function listStylesheets(source, config) {
5180
+ const globs = styleGlobs(config);
5181
+ const matchers = globs.map(globToRegExp);
5182
+ const compDir = config.components?.dir ?? REPO_MODEL_DEFAULTS.componentsDir;
5183
+ const bases = [...new Set(globs.map(globBase))].filter((b, _, all) => !all.some((o) => o !== b && (o === "" || b.startsWith(`${o}/`))));
5184
+ const listed = (await Promise.all(bases.map((b) => source.list(b)))).flat();
5185
+ const paths = [...new Set(listed)].filter((p) => matchers.some((re) => re.test(p)) && !p.startsWith(`${compDir}/`)).sort();
5186
+ const max = REPO_MODEL_DEFAULTS.maxStylesheets;
5187
+ if (paths.length <= max) return { globs, paths, problems: [] };
5188
+ return { globs, paths: paths.slice(0, max), problems: [`components.styles matches ${paths.length} files: Bridge reads the first ${max}. Narrow the globs to the stylesheets the library ships.`] };
5189
+ }
5123
5190
  function withModelDefaults(raw) {
5124
5191
  const tokens2 = raw.tokens && typeof raw.tokens === "object" ? raw.tokens : {};
5125
5192
  return {
@@ -5184,6 +5251,10 @@ async function loadRepoModel(source, options = {}) {
5184
5251
  }
5185
5252
  codeRead.push(indexPath);
5186
5253
  }
5254
+ const listedStyles = await listStylesheets(source, config);
5255
+ problems.push(...listedStyles.problems);
5256
+ const stylePaths = listedStyles.paths;
5257
+ codeRead.push(...stylePaths);
5187
5258
  const seen = /* @__PURE__ */ new Set();
5188
5259
  const fresh = (paths) => paths.filter((p) => {
5189
5260
  if (seen.has(p)) return false;
@@ -5251,6 +5322,11 @@ async function loadRepoModel(source, options = {}) {
5251
5322
  const list2 = scanComponents({ dir: comps.dir, files: compFiles, readText: readMore, indexText, indexRel, docsSuffix: comps.docsSuffix, styleSuffix: comps.styleSuffix, describeVar, problems });
5252
5323
  components = { dir: comps.dir, index: indexText === void 0 ? void 0 : indexPath, families: indexText === void 0 ? [] : parseComponentFamilies(indexText, indexRel), list: list2 };
5253
5324
  }
5325
+ const styleVars = {};
5326
+ for (const p of stylePaths) {
5327
+ const text = readMore(p);
5328
+ if (text !== void 0) styleVars[p] = cssVarsIn(text);
5329
+ }
5254
5330
  const specsText = readMore(specsPath);
5255
5331
  let specsFile = null;
5256
5332
  let coverage = [];
@@ -5274,6 +5350,7 @@ async function loadRepoModel(source, options = {}) {
5274
5350
  tokens: { root, files, rows, usage },
5275
5351
  contrast: { path: contrastPath, specs, pairs: pairs3 },
5276
5352
  components,
5353
+ styles: { globs: listedStyles.globs, vars: styleVars },
5277
5354
  specs: { path: specsPath, file: specsFile, coverage }
5278
5355
  };
5279
5356
  }
@@ -5358,7 +5435,8 @@ function buildSnapshot(input) {
5358
5435
  summary: snapshotSummary(model),
5359
5436
  contrast: { ...model.contrast.path ? { path: model.contrast.path } : {}, pairs: model.contrast.pairs.map(({ fgToken: _fg, bgToken: _bg, ...rest }) => rest) },
5360
5437
  audits: input.audits ?? [],
5361
- problems: [...model.problems]
5438
+ problems: [...model.problems],
5439
+ styles: [...model.styles.globs]
5362
5440
  };
5363
5441
  }
5364
5442
  var SNAPSHOT_LLMS_FILE = "llms.txt";
@@ -7162,6 +7240,7 @@ async function runBranch(a, root, io = defaultIO()) {
7162
7240
  io.print(`#${r.pr} ${r.title} (${r.product.name})`);
7163
7241
  io.print(`${r.status.label}. ${r.approvalNeeded} needed; approved by ${r.approvals.approvedBy.map((x) => `@${x}`).join(", ") || "nobody yet"}.`);
7164
7242
  if (r.approvals.soloOwner) io.print(r.approvals.soloOwner);
7243
+ io.print(`${r.tests.label}.`);
7165
7244
  if (r.merge.blockedBy?.length) for (const x of r.merge.blockedBy) io.print(` ${x}`);
7166
7245
  io.print(`Next: ${r.next}`);
7167
7246
  io.print(r.url);
@@ -7609,7 +7688,8 @@ async function rolesReport(opts) {
7609
7688
  }
7610
7689
 
7611
7690
  // src/index.ts
7612
- import { brand, BridgeContext as BridgeContext8, CONFIG_FILE as CONFIG_FILE2, core, detectConfig, GitRefSource, history as hist, LocalSource, ops, optionsFromArgv, serveStdio, toConfigJson, VERSION } from "@bridge-ds/mcp";
7691
+ import { brand, BridgeContext as BridgeContext8, CONFIG_FILE as CONFIG_FILE2, core, detectConfig, GitRefSource, history as hist, LocalSource, ops, optionsFromArgv, serveStdio, toConfigJson } from "@bridge-ds/mcp";
7692
+ var VERSION = true ? "0.11.2" : "dev";
7613
7693
  var MCP_PACKAGE = "@bridge-ds/mcp";
7614
7694
  var HELP = `bridge ${VERSION}: design system as code, for you and your Claude
7615
7695
 
@@ -8270,11 +8350,11 @@ async function main() {
8270
8350
  if (cmd === "review") return runReview(a, root);
8271
8351
  if (cmd === "products" || cmd === "settings" || cmd === "coverage") return runStudioRead(cmd, a, root);
8272
8352
  if (cmd === "docs" && a._[1] === "save") return runDocsSave(a, root);
8353
+ if (cmd === "version" || !cmd && has7(a, "version")) return print(VERSION), 0;
8273
8354
  if (!cmd || has7(a, "help") || cmd === "help") {
8274
8355
  print(HELP);
8275
8356
  return cmd || has7(a, "help") ? 0 : 2;
8276
8357
  }
8277
- if (cmd === "--version" || cmd === "version") return print(VERSION), 0;
8278
8358
  switch (cmd) {
8279
8359
  case "init":
8280
8360
  await init(a, root);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bridge-ds/cli",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "type": "module",
5
5
  "description": "bridge CLI: set up Bridge in a design system repo, check tokens in CI, search and diff tokens, propose changes, start the MCP server.",
6
6
  "license": "MIT",
@@ -43,8 +43,8 @@
43
43
  "build:package": "node ../../scripts/build-packages.mjs cli"
44
44
  },
45
45
  "dependencies": {
46
- "@bridge-ds/mcp": "^0.8.2",
47
- "@bridge-ds/visual": "^0.3.9",
46
+ "@bridge-ds/mcp": "^0.8.4",
47
+ "@bridge-ds/visual": "^0.3.11",
48
48
  "typescript": "5.9.3"
49
49
  },
50
50
  "devDependencies": {