@vailent/pulse-mcp 1.2.0 → 1.3.0
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/server.js +48 -16
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -40498,14 +40498,32 @@ async function handlePodMembers(params) {
|
|
|
40498
40498
|
return ok(data, `${(data || []).length} members in pod`, (data || []).length);
|
|
40499
40499
|
}
|
|
40500
40500
|
case "add": {
|
|
40501
|
-
const
|
|
40502
|
-
|
|
40503
|
-
|
|
40501
|
+
const userId = params.userId;
|
|
40502
|
+
let displayName = params.displayName;
|
|
40503
|
+
let initials = params.initials;
|
|
40504
|
+
let role = params.role || "engineer";
|
|
40505
|
+
if (userId) {
|
|
40506
|
+
const { data: user } = await supabase.from("users").select("full_name, job_title").eq("id", userId).single();
|
|
40507
|
+
if (!user) return err("User not found", "NOT_FOUND");
|
|
40508
|
+
if (!displayName) displayName = user.full_name;
|
|
40509
|
+
if (!initials) {
|
|
40510
|
+
initials = displayName.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2);
|
|
40511
|
+
}
|
|
40512
|
+
if (!params.role) {
|
|
40513
|
+
const jobTitles = user.job_title || ["member"];
|
|
40514
|
+
role = jobTitles.includes("product_lead") ? "product_lead" : jobTitles.includes("designer") ? "designer" : "engineer";
|
|
40515
|
+
}
|
|
40516
|
+
}
|
|
40517
|
+
if (!displayName?.trim()) return err("displayName is required (or provide userId)", "MISSING_PARAM");
|
|
40518
|
+
if (!initials) {
|
|
40519
|
+
initials = displayName.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2);
|
|
40520
|
+
}
|
|
40504
40521
|
const { data, error: error2 } = await supabase.from("pod_members").insert({
|
|
40505
40522
|
pod_id: podId,
|
|
40523
|
+
user_id: userId || null,
|
|
40506
40524
|
display_name: displayName.trim(),
|
|
40507
40525
|
initials,
|
|
40508
|
-
role
|
|
40526
|
+
role
|
|
40509
40527
|
}).select().single();
|
|
40510
40528
|
if (error2) return err(error2.message);
|
|
40511
40529
|
return ok(data, `Added ${displayName} to pod`);
|
|
@@ -40598,7 +40616,7 @@ function getGitEmail(scope) {
|
|
|
40598
40616
|
async function lookupByEmail(supabase, email3) {
|
|
40599
40617
|
const { data } = await supabase.from("users").select("id, email, full_name, job_title").eq("email", email3).limit(1).single();
|
|
40600
40618
|
if (!data) return null;
|
|
40601
|
-
return { id: data.id, email: data.email, fullName: data.full_name, jobTitle: data.job_title || "member" };
|
|
40619
|
+
return { id: data.id, email: data.email, fullName: data.full_name, jobTitle: data.job_title || ["member"] };
|
|
40602
40620
|
}
|
|
40603
40621
|
|
|
40604
40622
|
// tools/features.ts
|
|
@@ -40674,7 +40692,10 @@ async function handleFeatures(params) {
|
|
|
40674
40692
|
weekStart: "week_start",
|
|
40675
40693
|
size: "size",
|
|
40676
40694
|
projectName: "project_name",
|
|
40677
|
-
sortOrder: "sort_order"
|
|
40695
|
+
sortOrder: "sort_order",
|
|
40696
|
+
prdText: "prd_text",
|
|
40697
|
+
prdFileUrl: "prd_file_url",
|
|
40698
|
+
prdFileName: "prd_file_name"
|
|
40678
40699
|
};
|
|
40679
40700
|
const updates = { updated_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
40680
40701
|
for (const [key, col] of Object.entries(allowedFields)) {
|
|
@@ -47470,7 +47491,9 @@ function formatWeekStart(date4) {
|
|
|
47470
47491
|
async function handleBriefing(params) {
|
|
47471
47492
|
const supabase = getAdminClient();
|
|
47472
47493
|
const currentUser = await getCurrentUser();
|
|
47473
|
-
const
|
|
47494
|
+
const paramTitle = params.jobTitle;
|
|
47495
|
+
const jobTitles = paramTitle ? [paramTitle] : currentUser?.jobTitle || ["engineer"];
|
|
47496
|
+
const jobTitle = jobTitles.find((t) => t === "leadership") || jobTitles.find((t) => t === "product_lead") || jobTitles.find((t) => t === "designer") || jobTitles.find((t) => t === "engineer") || jobTitles.find((t) => t === "sales") || jobTitles[0] || "engineer";
|
|
47474
47497
|
const podIds = params.podIds;
|
|
47475
47498
|
const now = /* @__PURE__ */ new Date();
|
|
47476
47499
|
const thisWeekStart = getWeekStart(now);
|
|
@@ -47539,7 +47562,7 @@ async function handleTeam(params) {
|
|
|
47539
47562
|
id: u.id,
|
|
47540
47563
|
email: u.email,
|
|
47541
47564
|
fullName: u.full_name,
|
|
47542
|
-
jobTitle: u.job_title || "member",
|
|
47565
|
+
jobTitle: u.job_title || ["member"],
|
|
47543
47566
|
role: u.role,
|
|
47544
47567
|
isActive: u.is_active,
|
|
47545
47568
|
pods: userPods
|
|
@@ -47549,11 +47572,16 @@ async function handleTeam(params) {
|
|
|
47549
47572
|
}
|
|
47550
47573
|
case "update_role": {
|
|
47551
47574
|
const userId = params.userId;
|
|
47552
|
-
const
|
|
47553
|
-
if (!userId || !
|
|
47554
|
-
const
|
|
47575
|
+
const rawTitle = params.jobTitle;
|
|
47576
|
+
if (!userId || !rawTitle) return err("userId and jobTitle are required", "MISSING_PARAM");
|
|
47577
|
+
const titles = Array.isArray(rawTitle) ? rawTitle : [rawTitle];
|
|
47578
|
+
if (titles.length === 0) return err("At least one role is required", "INVALID_PARAM");
|
|
47579
|
+
const valid = ["product_lead", "engineer", "designer", "leadership", "sales", "member"];
|
|
47580
|
+
const invalid = titles.filter((t) => !valid.includes(t));
|
|
47581
|
+
if (invalid.length > 0) return err(`Invalid role(s): ${invalid.join(", ")}`, "INVALID_PARAM");
|
|
47582
|
+
const { error: error2 } = await supabase.from("users").update({ job_title: titles, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", userId);
|
|
47555
47583
|
if (error2) return err(error2.message);
|
|
47556
|
-
return ok({ userId, jobTitle }, `Updated
|
|
47584
|
+
return ok({ userId, jobTitle: titles }, `Updated roles to ${titles.join(", ")}`);
|
|
47557
47585
|
}
|
|
47558
47586
|
case "assign_pod": {
|
|
47559
47587
|
const userId = params.userId;
|
|
@@ -47564,8 +47592,8 @@ async function handleTeam(params) {
|
|
|
47564
47592
|
const { data: user } = await supabase.from("users").select("full_name, job_title").eq("id", userId).single();
|
|
47565
47593
|
const displayName = user?.full_name || "Unknown";
|
|
47566
47594
|
const initials = displayName.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2);
|
|
47567
|
-
const
|
|
47568
|
-
const podRole =
|
|
47595
|
+
const jobTitles = user?.job_title || ["member"];
|
|
47596
|
+
const podRole = jobTitles.includes("product_lead") ? "product_lead" : jobTitles.includes("designer") ? "designer" : "engineer";
|
|
47569
47597
|
await supabase.from("pod_members").insert({
|
|
47570
47598
|
pod_id: podId,
|
|
47571
47599
|
user_id: userId,
|
|
@@ -47609,6 +47637,7 @@ server.tool(
|
|
|
47609
47637
|
action: external_exports4.enum(["list", "add", "update", "remove"]),
|
|
47610
47638
|
podId: external_exports4.string().describe("Pod ID"),
|
|
47611
47639
|
memberId: external_exports4.string().optional().describe("Member ID (for update/remove)"),
|
|
47640
|
+
userId: external_exports4.string().optional().describe("User ID \u2014 links pod member to a user (for add). Auto-populates name/initials/role from user."),
|
|
47612
47641
|
displayName: external_exports4.string().optional().describe("Display name"),
|
|
47613
47642
|
initials: external_exports4.string().optional().describe("2-letter initials"),
|
|
47614
47643
|
role: external_exports4.string().optional().describe("Role: engineer, product_lead, designer")
|
|
@@ -47617,7 +47646,7 @@ server.tool(
|
|
|
47617
47646
|
);
|
|
47618
47647
|
server.tool(
|
|
47619
47648
|
"pulse_features",
|
|
47620
|
-
"Manage features and tasks. Actions: list (filter by pod/workstream/week/status/size), get, create (feature or task via size param), update (phase/step/status/blocker/week), delete, add_note, reorder.",
|
|
47649
|
+
"Manage features and tasks. Actions: list (filter by pod/workstream/week/status/size), get, create (feature or task via size param), update (phase/step/status/blocker/week/prdText/prdFileUrl), delete, add_note, reorder.",
|
|
47621
47650
|
{
|
|
47622
47651
|
action: external_exports4.enum(["list", "get", "create", "update", "delete", "add_note", "reorder"]),
|
|
47623
47652
|
featureId: external_exports4.string().optional().describe("Feature ID"),
|
|
@@ -47634,6 +47663,9 @@ server.tool(
|
|
|
47634
47663
|
blockerText: external_exports4.string().optional().describe("Blocker description"),
|
|
47635
47664
|
sortOrder: external_exports4.number().optional().describe("Sort order for drag-to-reorder"),
|
|
47636
47665
|
projectColor: external_exports4.string().optional().describe("Project color hex"),
|
|
47666
|
+
prdText: external_exports4.string().optional().describe("PRD text content (for update)"),
|
|
47667
|
+
prdFileUrl: external_exports4.string().optional().describe("PRD file URL (for update)"),
|
|
47668
|
+
prdFileName: external_exports4.string().optional().describe("PRD file name (for update)"),
|
|
47637
47669
|
note: external_exports4.string().optional().describe("Note text (for add_note)"),
|
|
47638
47670
|
items: external_exports4.array(external_exports4.object({ id: external_exports4.string(), sortOrder: external_exports4.number() })).optional().describe("Items to reorder"),
|
|
47639
47671
|
limit: external_exports4.number().optional().describe("Max results")
|
|
@@ -47749,7 +47781,7 @@ server.tool(
|
|
|
47749
47781
|
{
|
|
47750
47782
|
action: external_exports4.enum(["list", "update_role", "assign_pod"]),
|
|
47751
47783
|
userId: external_exports4.string().optional().describe("User ID"),
|
|
47752
|
-
jobTitle: external_exports4.string().optional().describe("Job title: product_lead, engineer, designer, leadership, sales, member"),
|
|
47784
|
+
jobTitle: external_exports4.union([external_exports4.string(), external_exports4.array(external_exports4.string())]).optional().describe("Job title(s): product_lead, engineer, designer, leadership, sales, member. Accepts single string or array."),
|
|
47753
47785
|
podId: external_exports4.string().optional().nullable().describe("Pod ID (null to remove from pods)")
|
|
47754
47786
|
},
|
|
47755
47787
|
async (params) => handleTeam(params)
|