@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.
- package/dist/index.js +86 -6
- 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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
47
|
-
"@bridge-ds/visual": "^0.3.
|
|
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": {
|