@vailent/pulse-mcp 1.2.0 → 1.4.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 +52 -18
- 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,11 @@ 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",
|
|
40699
|
+
prdSummary: "prd_summary"
|
|
40678
40700
|
};
|
|
40679
40701
|
const updates = { updated_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
40680
40702
|
for (const [key, col] of Object.entries(allowedFields)) {
|
|
@@ -40813,7 +40835,7 @@ async function handleRequests(params) {
|
|
|
40813
40835
|
pod_id: podId,
|
|
40814
40836
|
project_name: params.projectName || null,
|
|
40815
40837
|
requester_name: params.requesterName || null,
|
|
40816
|
-
source: params.source || "
|
|
40838
|
+
source: params.source || "mcp",
|
|
40817
40839
|
type: params.requestType || "feature_request",
|
|
40818
40840
|
priority: params.priority || null,
|
|
40819
40841
|
sentiment: params.sentiment || null,
|
|
@@ -40891,7 +40913,7 @@ async function handleBugs(params) {
|
|
|
40891
40913
|
description: params.description || null,
|
|
40892
40914
|
pod_id: podId,
|
|
40893
40915
|
project_name: params.projectName || null,
|
|
40894
|
-
source: params.source || "
|
|
40916
|
+
source: params.source || "mcp",
|
|
40895
40917
|
type: "bug",
|
|
40896
40918
|
priority: params.priority || "medium",
|
|
40897
40919
|
status: "open"
|
|
@@ -47470,7 +47492,9 @@ function formatWeekStart(date4) {
|
|
|
47470
47492
|
async function handleBriefing(params) {
|
|
47471
47493
|
const supabase = getAdminClient();
|
|
47472
47494
|
const currentUser = await getCurrentUser();
|
|
47473
|
-
const
|
|
47495
|
+
const paramTitle = params.jobTitle;
|
|
47496
|
+
const jobTitles = paramTitle ? [paramTitle] : currentUser?.jobTitle || ["engineer"];
|
|
47497
|
+
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
47498
|
const podIds = params.podIds;
|
|
47475
47499
|
const now = /* @__PURE__ */ new Date();
|
|
47476
47500
|
const thisWeekStart = getWeekStart(now);
|
|
@@ -47539,7 +47563,7 @@ async function handleTeam(params) {
|
|
|
47539
47563
|
id: u.id,
|
|
47540
47564
|
email: u.email,
|
|
47541
47565
|
fullName: u.full_name,
|
|
47542
|
-
jobTitle: u.job_title || "member",
|
|
47566
|
+
jobTitle: u.job_title || ["member"],
|
|
47543
47567
|
role: u.role,
|
|
47544
47568
|
isActive: u.is_active,
|
|
47545
47569
|
pods: userPods
|
|
@@ -47549,11 +47573,16 @@ async function handleTeam(params) {
|
|
|
47549
47573
|
}
|
|
47550
47574
|
case "update_role": {
|
|
47551
47575
|
const userId = params.userId;
|
|
47552
|
-
const
|
|
47553
|
-
if (!userId || !
|
|
47554
|
-
const
|
|
47576
|
+
const rawTitle = params.jobTitle;
|
|
47577
|
+
if (!userId || !rawTitle) return err("userId and jobTitle are required", "MISSING_PARAM");
|
|
47578
|
+
const titles = Array.isArray(rawTitle) ? rawTitle : [rawTitle];
|
|
47579
|
+
if (titles.length === 0) return err("At least one role is required", "INVALID_PARAM");
|
|
47580
|
+
const valid = ["product_lead", "engineer", "designer", "leadership", "sales", "member"];
|
|
47581
|
+
const invalid = titles.filter((t) => !valid.includes(t));
|
|
47582
|
+
if (invalid.length > 0) return err(`Invalid role(s): ${invalid.join(", ")}`, "INVALID_PARAM");
|
|
47583
|
+
const { error: error2 } = await supabase.from("users").update({ job_title: titles, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", userId);
|
|
47555
47584
|
if (error2) return err(error2.message);
|
|
47556
|
-
return ok({ userId, jobTitle }, `Updated
|
|
47585
|
+
return ok({ userId, jobTitle: titles }, `Updated roles to ${titles.join(", ")}`);
|
|
47557
47586
|
}
|
|
47558
47587
|
case "assign_pod": {
|
|
47559
47588
|
const userId = params.userId;
|
|
@@ -47564,8 +47593,8 @@ async function handleTeam(params) {
|
|
|
47564
47593
|
const { data: user } = await supabase.from("users").select("full_name, job_title").eq("id", userId).single();
|
|
47565
47594
|
const displayName = user?.full_name || "Unknown";
|
|
47566
47595
|
const initials = displayName.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2);
|
|
47567
|
-
const
|
|
47568
|
-
const podRole =
|
|
47596
|
+
const jobTitles = user?.job_title || ["member"];
|
|
47597
|
+
const podRole = jobTitles.includes("product_lead") ? "product_lead" : jobTitles.includes("designer") ? "designer" : "engineer";
|
|
47569
47598
|
await supabase.from("pod_members").insert({
|
|
47570
47599
|
pod_id: podId,
|
|
47571
47600
|
user_id: userId,
|
|
@@ -47609,6 +47638,7 @@ server.tool(
|
|
|
47609
47638
|
action: external_exports4.enum(["list", "add", "update", "remove"]),
|
|
47610
47639
|
podId: external_exports4.string().describe("Pod ID"),
|
|
47611
47640
|
memberId: external_exports4.string().optional().describe("Member ID (for update/remove)"),
|
|
47641
|
+
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
47642
|
displayName: external_exports4.string().optional().describe("Display name"),
|
|
47613
47643
|
initials: external_exports4.string().optional().describe("2-letter initials"),
|
|
47614
47644
|
role: external_exports4.string().optional().describe("Role: engineer, product_lead, designer")
|
|
@@ -47617,7 +47647,7 @@ server.tool(
|
|
|
47617
47647
|
);
|
|
47618
47648
|
server.tool(
|
|
47619
47649
|
"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.",
|
|
47650
|
+
"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
47651
|
{
|
|
47622
47652
|
action: external_exports4.enum(["list", "get", "create", "update", "delete", "add_note", "reorder"]),
|
|
47623
47653
|
featureId: external_exports4.string().optional().describe("Feature ID"),
|
|
@@ -47634,6 +47664,10 @@ server.tool(
|
|
|
47634
47664
|
blockerText: external_exports4.string().optional().describe("Blocker description"),
|
|
47635
47665
|
sortOrder: external_exports4.number().optional().describe("Sort order for drag-to-reorder"),
|
|
47636
47666
|
projectColor: external_exports4.string().optional().describe("Project color hex"),
|
|
47667
|
+
prdText: external_exports4.string().optional().describe("PRD text content (for update)"),
|
|
47668
|
+
prdFileUrl: external_exports4.string().optional().describe("PRD file URL (for update)"),
|
|
47669
|
+
prdFileName: external_exports4.string().optional().describe("PRD file name (for update)"),
|
|
47670
|
+
prdSummary: external_exports4.string().optional().describe("AI-generated PRD summary (for update)"),
|
|
47637
47671
|
note: external_exports4.string().optional().describe("Note text (for add_note)"),
|
|
47638
47672
|
items: external_exports4.array(external_exports4.object({ id: external_exports4.string(), sortOrder: external_exports4.number() })).optional().describe("Items to reorder"),
|
|
47639
47673
|
limit: external_exports4.number().optional().describe("Max results")
|
|
@@ -47749,7 +47783,7 @@ server.tool(
|
|
|
47749
47783
|
{
|
|
47750
47784
|
action: external_exports4.enum(["list", "update_role", "assign_pod"]),
|
|
47751
47785
|
userId: external_exports4.string().optional().describe("User ID"),
|
|
47752
|
-
jobTitle: external_exports4.string().optional().describe("Job title: product_lead, engineer, designer, leadership, sales, member"),
|
|
47786
|
+
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
47787
|
podId: external_exports4.string().optional().nullable().describe("Pod ID (null to remove from pods)")
|
|
47754
47788
|
},
|
|
47755
47789
|
async (params) => handleTeam(params)
|