@rigstate/mcp 0.7.2 → 0.7.4
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 +58 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/tools/get-latest-decisions.ts +8 -9
- package/src/tools/get-next-roadmap-step.ts +38 -33
- package/src/tools/get-project-context.ts +26 -37
- package/src/tools/list-roadmap-tasks.ts +22 -23
- package/src/tools/planning-tools.ts +16 -2
package/dist/index.js
CHANGED
|
@@ -1937,14 +1937,19 @@ async function getProjectContext(supabase, userId, projectId) {
|
|
|
1937
1937
|
repository_tree: projectRow.repository_tree
|
|
1938
1938
|
};
|
|
1939
1939
|
const stackDef = projectRow.architectural_dna?.stack_definition;
|
|
1940
|
-
const
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
const
|
|
1945
|
-
const
|
|
1946
|
-
const
|
|
1947
|
-
const { data:
|
|
1940
|
+
const { data: allChunks, error: chunksError } = await supabase.rpc("get_roadmap_chunks_secure", {
|
|
1941
|
+
p_project_id: projectId,
|
|
1942
|
+
p_user_id: userId
|
|
1943
|
+
});
|
|
1944
|
+
const tasks = allChunks || [];
|
|
1945
|
+
const activeTask = tasks.find((t) => ["IN_PROGRESS", "ACTIVE"].includes(t.status));
|
|
1946
|
+
const nextTask = tasks.filter((t) => ["PENDING", "LOCKED"].includes(t.status)).sort((a, b) => a.step_number - b.step_number)[0];
|
|
1947
|
+
const { data: agentTasks } = await supabase.rpc("get_agent_bridge_secure", {
|
|
1948
|
+
p_project_id: projectId,
|
|
1949
|
+
p_user_id: userId,
|
|
1950
|
+
p_limit: 2
|
|
1951
|
+
});
|
|
1952
|
+
const roadmapItems = tasks.sort((a, b) => new Date(b.updated_at || b.created_at).getTime() - new Date(a.updated_at || a.created_at).getTime()).slice(0, 2);
|
|
1948
1953
|
const techStack = {
|
|
1949
1954
|
framework: null,
|
|
1950
1955
|
orm: null,
|
|
@@ -2027,7 +2032,7 @@ Description: ${project.description}`);
|
|
|
2027
2032
|
summaryParts.push("\nLatest AI Executions:");
|
|
2028
2033
|
agentTasks.forEach((t) => {
|
|
2029
2034
|
const time = t.completed_at ? new Date(t.completed_at).toLocaleString() : "Recently";
|
|
2030
|
-
summaryParts.push(`- [${time}] ${t.
|
|
2035
|
+
summaryParts.push(`- [${time}] ${t.roadmap_title || "Task"}: ${t.execution_summary || "Completed"}`);
|
|
2031
2036
|
});
|
|
2032
2037
|
}
|
|
2033
2038
|
if (roadmapItems && roadmapItems.length > 0) {
|
|
@@ -2211,8 +2216,11 @@ including active roadmap steps and council session feedback.`,
|
|
|
2211
2216
|
}
|
|
2212
2217
|
});
|
|
2213
2218
|
async function getLatestDecisions(supabase, userId, projectId, limit = 5) {
|
|
2214
|
-
const { data:
|
|
2215
|
-
|
|
2219
|
+
const { data: hasAccess, error: accessError } = await supabase.rpc("check_project_access_secure", {
|
|
2220
|
+
p_project_id: projectId,
|
|
2221
|
+
p_user_id: userId
|
|
2222
|
+
});
|
|
2223
|
+
if (accessError || !hasAccess) {
|
|
2216
2224
|
throw new Error("Project not found or access denied");
|
|
2217
2225
|
}
|
|
2218
2226
|
const { data: sessionData, error: sessionError } = await supabase.from("council_sessions").select("id, project_id, recruited_agents, feedback_summary, duration_ms, sprints_count, tasks_count, created_at").eq("project_id", projectId).order("created_at", { ascending: false }).limit(limit);
|
|
@@ -2767,22 +2775,30 @@ Shows active and locked steps with their step numbers.`,
|
|
|
2767
2775
|
}
|
|
2768
2776
|
});
|
|
2769
2777
|
async function listRoadmapTasks(supabase, userId, projectId) {
|
|
2770
|
-
const { data:
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
}
|
|
2774
|
-
const { data: tasks, error } = await supabase.from("roadmap_chunks").select("id, title, priority, status, step_number, prompt_content").eq("project_id", projectId).neq("status", "COMPLETED").order("priority", { ascending: false }).order("step_number", { ascending: true });
|
|
2778
|
+
const { data: tasks, error } = await supabase.rpc("get_roadmap_chunks_secure", {
|
|
2779
|
+
p_project_id: projectId,
|
|
2780
|
+
p_user_id: userId
|
|
2781
|
+
});
|
|
2775
2782
|
if (error) {
|
|
2783
|
+
if (error.message.includes("Access Denied")) {
|
|
2784
|
+
throw new Error("Project not found or access denied");
|
|
2785
|
+
}
|
|
2776
2786
|
console.error("Failed to fetch roadmap tasks:", error);
|
|
2777
2787
|
throw new Error("Failed to fetch roadmap tasks");
|
|
2778
2788
|
}
|
|
2779
|
-
const
|
|
2789
|
+
const activeTasks = (tasks || []).filter((t) => t.status !== "COMPLETED").sort((a, b) => {
|
|
2790
|
+
if (a.priority !== b.priority) {
|
|
2791
|
+
const priorityOrder = { "CRITICAL": 3, "HIGH": 2, "MEDIUM": 1, "LOW": 0 };
|
|
2792
|
+
return (priorityOrder[b.priority] || 0) - (priorityOrder[a.priority] || 0);
|
|
2793
|
+
}
|
|
2794
|
+
return a.step_number - b.step_number;
|
|
2795
|
+
});
|
|
2796
|
+
const formatted = activeTasks.length > 0 ? activeTasks.map((t) => {
|
|
2780
2797
|
const statusEmoji = t.status === "ACTIVE" ? "\u{1F535}" : "\u{1F512}";
|
|
2781
|
-
const priorityStr = t.priority ? `[${t.priority}]` : "";
|
|
2782
2798
|
return `${statusEmoji} Step ${t.step_number}: ${t.title} (ID: ${t.id})`;
|
|
2783
2799
|
}).join("\n") : "No active or locked tasks found in the roadmap.";
|
|
2784
2800
|
return {
|
|
2785
|
-
tasks:
|
|
2801
|
+
tasks: activeTasks.map((t) => ({
|
|
2786
2802
|
id: t.id,
|
|
2787
2803
|
title: t.title,
|
|
2788
2804
|
priority: t.priority,
|
|
@@ -2804,29 +2820,38 @@ Useful for transitioning between tasks.`,
|
|
|
2804
2820
|
handler: async (args, context) => {
|
|
2805
2821
|
const result = await getNextRoadmapStep(
|
|
2806
2822
|
context.supabase,
|
|
2823
|
+
context.userId,
|
|
2807
2824
|
args.projectId,
|
|
2808
2825
|
args.currentStepId
|
|
2809
2826
|
);
|
|
2810
2827
|
return { content: [{ type: "text", text: result.message }] };
|
|
2811
2828
|
}
|
|
2812
2829
|
});
|
|
2813
|
-
async function getNextRoadmapStep(supabase, projectId, currentStepId) {
|
|
2830
|
+
async function getNextRoadmapStep(supabase, userId, projectId, currentStepId) {
|
|
2831
|
+
const { data: allTasks, error: fetchError } = await supabase.rpc("get_roadmap_chunks_secure", {
|
|
2832
|
+
p_project_id: projectId,
|
|
2833
|
+
p_user_id: userId
|
|
2834
|
+
});
|
|
2835
|
+
if (fetchError) {
|
|
2836
|
+
throw new Error(`Failed to fetch roadmap data: ${fetchError.message}`);
|
|
2837
|
+
}
|
|
2838
|
+
const tasks = allTasks || [];
|
|
2814
2839
|
let currentStepNumber = 0;
|
|
2815
2840
|
if (currentStepId) {
|
|
2816
|
-
const
|
|
2841
|
+
const current = tasks.find((t) => t.id === currentStepId);
|
|
2817
2842
|
if (current) {
|
|
2818
2843
|
currentStepNumber = current.step_number;
|
|
2819
2844
|
}
|
|
2820
2845
|
} else {
|
|
2821
|
-
const
|
|
2846
|
+
const active = tasks.filter((t) => ["ACTIVE", "IN_PROGRESS"].includes(t.status)).sort((a, b) => a.step_number - b.step_number)[0];
|
|
2822
2847
|
if (active) {
|
|
2823
|
-
|
|
2848
|
+
return {
|
|
2849
|
+
nextStep: active,
|
|
2850
|
+
message: `Current active step: [Step ${active.step_number}] ${active.title}`
|
|
2851
|
+
};
|
|
2824
2852
|
}
|
|
2825
2853
|
}
|
|
2826
|
-
const
|
|
2827
|
-
if (error && error.code !== "PGRST116") {
|
|
2828
|
-
throw new Error(`Failed to fetch next roadmap step: ${error.message}`);
|
|
2829
|
-
}
|
|
2854
|
+
const nextStep = tasks.filter((t) => t.step_number > currentStepNumber && t.status !== "COMPLETED").sort((a, b) => a.step_number - b.step_number)[0];
|
|
2830
2855
|
if (!nextStep) {
|
|
2831
2856
|
return {
|
|
2832
2857
|
nextStep: null,
|
|
@@ -3617,8 +3642,8 @@ registry.register({
|
|
|
3617
3642
|
});
|
|
3618
3643
|
async function saveToProjectBrain(supabase, userId, input) {
|
|
3619
3644
|
const { projectId, title, content, category, tags } = input;
|
|
3620
|
-
const { data:
|
|
3621
|
-
if (
|
|
3645
|
+
const { data: hasAccess, error: accessError } = await supabase.rpc("check_project_access_secure", { p_project_id: projectId, p_user_id: userId });
|
|
3646
|
+
if (accessError || !hasAccess) throw new Error("Access denied");
|
|
3622
3647
|
const fullContent = `# ${title}
|
|
3623
3648
|
|
|
3624
3649
|
${content}`;
|
|
@@ -3640,6 +3665,8 @@ ${content}`;
|
|
|
3640
3665
|
}
|
|
3641
3666
|
async function updateRoadmapStatus(supabase, userId, input) {
|
|
3642
3667
|
const { projectId, chunkId, status } = input;
|
|
3668
|
+
const { data: hasAccess, error: accessError } = await supabase.rpc("check_project_access_secure", { p_project_id: projectId, p_user_id: userId });
|
|
3669
|
+
if (accessError || !hasAccess) throw new Error("Access denied");
|
|
3643
3670
|
const dbStatus = status === "TODO" ? "LOCKED" : status === "IN_PROGRESS" ? "ACTIVE" : "COMPLETED";
|
|
3644
3671
|
const { error } = await supabase.from("roadmap_chunks").update({ status: dbStatus }).eq("id", chunkId).eq("project_id", projectId);
|
|
3645
3672
|
if (error) throw new Error(`Update failed: ${error.message}`);
|
|
@@ -3653,6 +3680,8 @@ async function updateRoadmapStatus(supabase, userId, input) {
|
|
|
3653
3680
|
}
|
|
3654
3681
|
async function addRoadmapChunk(supabase, userId, input) {
|
|
3655
3682
|
const { projectId, title, description, priority } = input;
|
|
3683
|
+
const { data: hasAccess, error: accessError } = await supabase.rpc("check_project_access_secure", { p_project_id: projectId, p_user_id: userId });
|
|
3684
|
+
if (accessError || !hasAccess) throw new Error("Access denied");
|
|
3656
3685
|
const { data: maxStep } = await supabase.from("roadmap_chunks").select("step_number").eq("project_id", projectId).order("step_number", { ascending: false }).limit(1).single();
|
|
3657
3686
|
const nextStepNum = (maxStep?.step_number || 0) + 1;
|
|
3658
3687
|
const { data, error } = await supabase.from("roadmap_chunks").insert({
|