@bridge-ds/mcp 0.11.1 → 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.
@@ -4018,13 +4018,21 @@ var labelNames = (labels) => labels.map((l) => typeof l === "string" ? l : l.nam
4018
4018
  function isExplorationPull(p) {
4019
4019
  return isExplorationBranch(p.headRef) || labelNames(p.labels).includes(EXPLORATION_LABEL) || Boolean(parseExplorationBody(p.body));
4020
4020
  }
4021
+ function isUnlabeledExploration(p) {
4022
+ if (p.state !== "open" || p.draft !== true) return false;
4023
+ const names4 = labelNames(p.labels ?? []);
4024
+ if (names4.includes(EXPLORATION_LABEL) || names4.includes(EXPLORATION_ARCHIVED_LABEL) || names4.includes(EXPLORATION_READY_LABEL)) return false;
4025
+ const block = parseExplorationBody(p.body);
4026
+ if (block?.doneAt) return false;
4027
+ return isExplorationBranch(p.headRef) || Boolean(block);
4028
+ }
4021
4029
  function isHandedOff(p) {
4022
4030
  return labelNames(p.labels).includes(EXPLORATION_READY_LABEL) || Boolean(parseExplorationBody(p.body)?.doneAt);
4023
4031
  }
4024
4032
  function explorationStatus(p) {
4025
4033
  const merged = Boolean(p.merged || p.merged_at || p.state === "merged");
4026
4034
  if (p.state !== "open" && !merged) return "closed";
4027
- if (p.state === "open" && labelNames(p.labels).includes(EXPLORATION_LABEL)) return "active";
4035
+ if (p.state === "open" && (labelNames(p.labels).includes(EXPLORATION_LABEL) || isUnlabeledExploration(p))) return "active";
4028
4036
  if (!isHandedOff(p)) return "promoted";
4029
4037
  if (merged) return "shipped";
4030
4038
  if (p.draft === false) return "building";
@@ -4038,6 +4046,7 @@ function isHeldExploration(p) {
4038
4046
  if (p.state !== void 0 && p.state !== "open") return false;
4039
4047
  const names4 = labelNames(p.labels ?? []);
4040
4048
  if (names4.includes(EXPLORATION_LABEL) || names4.includes(EXPLORATION_ARCHIVED_LABEL)) return true;
4049
+ if (isUnlabeledExploration({ state: "open", draft: p.draft, labels: p.labels, headRef: p.headRef ?? p.head?.ref, body: p.body })) return true;
4041
4050
  return names4.includes(EXPLORATION_READY_LABEL) && p.draft !== false;
4042
4051
  }
4043
4052
  var explorationTakeCommands = (branch) => ["git fetch origin", `git checkout ${branch}`];
@@ -4570,7 +4579,7 @@ async function startExplorationOnGitHub(gh, e, s) {
4570
4579
  const ctx = { owner: gh.owner, repo: gh.name, packages: s.packages, apps: s.apps, ...s.requests?.length ? { requests: s.requests } : {}, ...s.inProduct ? { inProduct: s.inProduct } : {} };
4571
4580
  const title = full.jira ? `${full.jira.trim().toUpperCase()} ${explorationPrTitle(full)}` : explorationPrTitle(full);
4572
4581
  const pr = await x.createPullRequest({ title, head: branch, base: s.base, body: explorationPrBody(full, ctx), draft: true });
4573
- await x.addLabels(pr.number, [EXPLORATION_LABEL, ...s.labels ?? []]);
4582
+ const labelsMissing = await labelExploration(x, pr.number, s.labels ?? [], s.retryMs);
4574
4583
  await x.updatePullRequest(pr.number, { body: explorationPrBody(full, { ...ctx, pr: pr.number }) }).catch(() => void 0);
4575
4584
  return {
4576
4585
  branch,
@@ -4579,9 +4588,21 @@ async function startExplorationOnGitHub(gh, e, s) {
4579
4588
  url: pr.url,
4580
4589
  commit: commit.sha,
4581
4590
  tryIt: { state: "building" },
4582
- previews: previewLinks(s.apps, { branch, pr: pr.number, sha: commit.sha })
4591
+ previews: previewLinks(s.apps, { branch, pr: pr.number, sha: commit.sha }),
4592
+ ...labelsMissing.length ? { labelsMissing } : {}
4583
4593
  };
4584
4594
  }
4595
+ var wait = (ms) => new Promise((r) => setTimeout(r, ms));
4596
+ async function labelExploration(gh, pr, extra, retryMs = 600) {
4597
+ let labeled = false;
4598
+ for (let i = 0; i < 3 && !labeled; i++) {
4599
+ if (i) await wait(retryMs * i);
4600
+ labeled = await gh.addLabels(pr, [EXPLORATION_LABEL]);
4601
+ }
4602
+ const more = extra.filter((l) => l !== EXPLORATION_LABEL);
4603
+ const moreOk = more.length ? await gh.addLabels(pr, more) : true;
4604
+ return [...labeled ? [] : [EXPLORATION_LABEL], ...moreOk ? [] : more];
4605
+ }
4585
4606
  async function productRepoAccess(gh) {
4586
4607
  try {
4587
4608
  const r = await gh.getRepo();
@@ -9858,6 +9879,7 @@ async function markFigmaChangeDraftedOnGitHub(gh, n) {
9858
9879
  var BUILD_REQUEST_LABEL = "bridge-build";
9859
9880
  var SOURCE_FIGMA_LABEL = "source: figma";
9860
9881
  var BUILD_STALE_DAYS = 7;
9882
+ var BUILD_DECLINED_DAYS = 7;
9861
9883
  var names3 = (labels) => (labels ?? []).map((l) => (typeof l === "string" ? l : l.name ?? "").toLowerCase());
9862
9884
  function isFigmaPush(p) {
9863
9885
  const l = names3(p.labels);
@@ -10069,7 +10091,8 @@ function buildRequestStatus(x, now = Date.now(), nameOf = (l) => l) {
10069
10091
  if (s === "shipped") return { status: s, ...shippedAt ? { at: shippedAt } : {} };
10070
10092
  return { status: s };
10071
10093
  });
10072
- if (status === "not-planned") timeline.push({ status: "not-planned", ...x.issue?.closedAt ? { at: x.issue.closedAt } : {} });
10094
+ const closedOn = x.issue ? x.issue.closedAt : own?.closedAt ?? own?.updatedAt;
10095
+ if (status === "not-planned") timeline.push({ status: "not-planned", ...closedOn ? { at: closedOn } : {} });
10073
10096
  return {
10074
10097
  status,
10075
10098
  label: status === "requested" && stale ? `Requested ${ageDays} days ago` : BUILD_STATUS_LABEL[status],
@@ -10147,9 +10170,10 @@ var BUILD_FILTER_LABEL = {
10147
10170
  "in-progress": "In progress",
10148
10171
  "shipped-this-week": "Shipped this week"
10149
10172
  };
10173
+ var declinedAt = (v) => v.status === "not-planned" ? v.timeline.find((e) => e.status === "not-planned")?.at ?? null : null;
10150
10174
  function matchesBuildFilter(v, f, now = Date.now()) {
10151
10175
  const nowMs = typeof now === "number" ? now : now.getTime();
10152
- const recent = (iso) => Boolean(iso) && nowMs - Date.parse(iso) <= 7 * DAY;
10176
+ const recent = (iso, days = 7) => Boolean(iso) && nowMs - Date.parse(iso) <= days * DAY;
10153
10177
  switch (f) {
10154
10178
  case "waiting":
10155
10179
  return v.status === "requested";
@@ -10158,7 +10182,7 @@ function matchesBuildFilter(v, f, now = Date.now()) {
10158
10182
  case "shipped-this-week":
10159
10183
  return v.status === "shipped" && recent(v.shippedAt);
10160
10184
  default:
10161
- return v.status === "not-planned" ? recent(v.timeline.find((e) => e.status === "not-planned")?.at) : true;
10185
+ return v.status === "not-planned" ? recent(declinedAt(v), BUILD_DECLINED_DAYS) : true;
10162
10186
  }
10163
10187
  }
10164
10188
  var openBuildRequests = (views) => views.filter((v) => v.status !== "shipped" && v.status !== "not-planned");
@@ -17130,7 +17154,7 @@ async function proposeFigmaFixesOp(ctx, a) {
17130
17154
  }
17131
17155
 
17132
17156
  // src/server.ts
17133
- var VERSION = true ? "0.11.1" : "dev";
17157
+ var VERSION = true ? "0.11.2" : "dev";
17134
17158
  var BRIDGE_SITE = "https://bridge.floriangouloubi.com";
17135
17159
  var SERVER_INFO = {
17136
17160
  name: "bridge",
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  VERSION,
4
4
  optionsFromArgv,
5
5
  serveStdio
6
- } from "./chunk-FRHGLK6Z.js";
6
+ } from "./chunk-P2UU6IKZ.js";
7
7
  import "./chunk-HNGVASTJ.js";
8
8
 
9
9
  // src/index.ts
package/dist/lib.js CHANGED
@@ -42,7 +42,7 @@ import {
42
42
  studio_exports,
43
43
  suggestions_exports,
44
44
  tokenNote
45
- } from "./chunk-FRHGLK6Z.js";
45
+ } from "./chunk-P2UU6IKZ.js";
46
46
  import {
47
47
  CONFIG_FILE,
48
48
  loadConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bridge-ds/mcp",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "type": "module",
5
5
  "description": "Bridge MCP server: lets Claude (Claude Code, Claude Desktop or any MCP client) read, check and propose changes to a DTCG design system repo through pull requests.",
6
6
  "license": "FSL-1.1-MIT",
@@ -55,8 +55,8 @@
55
55
  "build:package": "node ../../scripts/build-packages.mjs mcp"
56
56
  },
57
57
  "dependencies": {
58
- "@bridge-ds/core": "^0.22.0",
59
- "@bridge-ds/visual": "^0.3.16",
58
+ "@bridge-ds/core": "^0.23.0",
59
+ "@bridge-ds/visual": "^0.3.17",
60
60
  "@modelcontextprotocol/sdk": "1.31.0",
61
61
  "typescript": "5.9.3",
62
62
  "zod": "3.25.76"