@productbrain/mcp 0.0.1-beta.6435 → 0.0.1-beta.6437

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.
@@ -386,6 +386,34 @@ function sanitizeSingleLineField(str) {
386
386
  return stripControlChars(str).replace(/\s+/g, " ").trim();
387
387
  }
388
388
 
389
+ // src/lib/ownerLine.ts
390
+ function formatOwnerLine(owner, options = {}) {
391
+ const ids = options.ids ?? true;
392
+ const label = options.label ?? "Owner:";
393
+ switch (owner.kind) {
394
+ case "one":
395
+ return `${label} ${owner.role.name} in ${owner.team.name}`;
396
+ case "default":
397
+ return `${label} Team Lead, ${owner.team.name} (default \u2014 nobody assigned)`;
398
+ case "unavailable":
399
+ return `${label} none \u2014 no Team Lead available`;
400
+ case "many":
401
+ return `${label} conflicting \u2014 ${owner.count}${owner.truncated ? "+" : ""} owners recorded`;
402
+ case "dangling": {
403
+ const named = owner.team && owner.role ? `${owner.role.name} in ${owner.team.name} is archived` : owner.role ? `role ${owner.role.name} is archived` : owner.team ? `team ${owner.team.name} is archived` : "the owning team or role is archived";
404
+ return ids ? `${label} couldn't be resolved \u2014 ${named} (team ${owner.teamId}, role ${owner.roleId})` : `${label} couldn't be resolved \u2014 ${named}`;
405
+ }
406
+ case "overflow": {
407
+ const reason = "couldn't be resolved \u2014 this team is too large to check";
408
+ return ids ? `${label} ${reason} (team ${owner.teamId})` : `${label} ${reason}`;
409
+ }
410
+ default: {
411
+ const _exhaustive = owner;
412
+ return _exhaustive;
413
+ }
414
+ }
415
+ }
416
+
389
417
  // src/tools/knowledge-helpers.ts
390
418
  var EPISTEMIC_COLLECTIONS = /* @__PURE__ */ new Set(["insights", "assumptions"]);
391
419
  function deriveEpistemicStatus(entry) {
@@ -448,7 +476,10 @@ var ownerOutputShape = z2.discriminatedUnion("kind", [
448
476
  // Review round 2: count is capped at OWNERSHIP_DISPLAY_CAP; truncated is true when a row past
449
477
  // that cap exists, so 3+ duplicates are never silently reported as exactly 2.
450
478
  z2.object({ kind: z2.literal("many"), count: z2.number(), truncated: z2.boolean() }),
451
- z2.object({ kind: z2.literal("dangling"), teamId: z2.string(), roleId: z2.string() }),
479
+ // WP-753 O5b fix round 1 (item 1), nested round 3 (item 6): team/role optional — present only
480
+ // when entryOwnershipRead.ts could name the archived/dead target without leaking a foreign
481
+ // workspace's name. Nested (not flat teamName/roleName) to match the `one`/`default` kinds.
482
+ z2.object({ kind: z2.literal("dangling"), teamId: z2.string(), roleId: z2.string(), team: ownerTeam.pick({ name: true }).optional(), role: ownerRole.pick({ name: true }).optional() }),
452
483
  // PRRT_kwDORS4ils6igqYN (round 2): the routed team's membership scan overflowed the cap — an
453
484
  // active Team Lead may still exist; distinct from `unavailable` (asserts none does).
454
485
  z2.object({ kind: z2.literal("overflow"), teamId: z2.string() })
@@ -458,21 +489,9 @@ function parseOwnerOutput(raw) {
458
489
  const result2 = ownerOutputShape.safeParse(raw);
459
490
  return result2.success ? result2.data : void 0;
460
491
  }
461
- function formatOwnerLine(owner) {
462
- switch (owner.kind) {
463
- case "one":
464
- return `**Owner:** ${sanitizeSingleLineField(owner.role.name)} in ${sanitizeSingleLineField(owner.team.name)}`;
465
- case "default":
466
- return `**Owner:** ${sanitizeSingleLineField(owner.team.name)} Team Lead (by default, no ownership row)`;
467
- case "unavailable":
468
- return "**Owner:** none \u2014 no Team Lead available";
469
- case "many":
470
- return `**Owner:** present but unresolvable: ${owner.count}${owner.truncated ? "+" : ""} ownership rows`;
471
- case "dangling":
472
- return `**Owner:** unresolved (team ${owner.teamId}, role ${owner.roleId})`;
473
- case "overflow":
474
- return `**Owner:** unresolved \u2014 routed team ${owner.teamId} has too many membership rows to safely scan; repair its membership structure`;
475
- }
492
+ function formatOwnerLine2(owner) {
493
+ const sanitized = owner.kind === "one" ? { ...owner, team: { name: sanitizeSingleLineField(owner.team.name) }, role: { name: sanitizeSingleLineField(owner.role.name) } } : owner.kind === "default" ? { ...owner, team: { name: sanitizeSingleLineField(owner.team.name) } } : owner.kind === "dangling" ? { ...owner, ...owner.team ? { team: { name: sanitizeSingleLineField(owner.team.name) } } : {}, ...owner.role ? { role: { name: sanitizeSingleLineField(owner.role.name) } } : {} } : owner;
494
+ return formatOwnerLine(sanitized, { label: "**Owner:**" });
476
495
  }
477
496
  function extractPreview(data, maxLen) {
478
497
  if (!data || typeof data !== "object") return "";
@@ -4974,7 +4993,7 @@ async function handleGet(entryId) {
4974
4993
  if (e.sourceRef) lines.push(`**Source ref:** ${e.sourceRef}`);
4975
4994
  if (e.sourceExcerpt) lines.push(`**Source excerpt:** ${e.sourceExcerpt}`);
4976
4995
  const parsedOwner = parseOwnerOutput(e.owner);
4977
- if (parsedOwner) lines.push(formatOwnerLine(parsedOwner));
4996
+ if (parsedOwner) lines.push(formatOwnerLine2(parsedOwner));
4978
4997
  if (epistemic) lines.push(formatEpistemicLine(epistemic));
4979
4998
  const { line: whyLine, why, whySourceKey } = renderWhyLine(e);
4980
4999
  if (whyLine !== null) lines.push(whyLine);
@@ -16650,4 +16669,4 @@ export {
16650
16669
  createProductBrainServer,
16651
16670
  initFeatureFlags
16652
16671
  };
16653
- //# sourceMappingURL=chunk-XJNKMI7O.js.map
16672
+ //# sourceMappingURL=chunk-7TLBTMIV.js.map