ralph-hero-mcp-server 2.4.6 → 2.4.7

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.
@@ -2,7 +2,8 @@
2
2
  * MCP tools for GitHub Projects V2 management operations.
3
3
  *
4
4
  * Provides tools for archiving/unarchiving items, removing items from projects,
5
- * adding existing issues to projects, linking repositories, and clearing field values.
5
+ * adding existing issues to projects, linking repositories, clearing field values,
6
+ * and managing project status updates (create, update, delete).
6
7
  */
7
8
  import { z } from "zod";
8
9
  import { toolSuccess, toolError } from "../types.js";
@@ -596,5 +597,160 @@ export function registerProjectManagementTools(server, client, fieldCache) {
596
597
  return toolError(`Failed to update collaborators: ${message}`);
597
598
  }
598
599
  });
600
+ // -------------------------------------------------------------------------
601
+ // ralph_hero__create_status_update
602
+ // -------------------------------------------------------------------------
603
+ server.tool("ralph_hero__create_status_update", "Post a project-level status update with health designation. Visible in GitHub Projects UI header and panel. Returns: id, status, body, startDate, targetDate, createdAt.", {
604
+ owner: z.string().optional().describe("GitHub owner. Defaults to env var"),
605
+ repo: z.string().optional().describe("Repository name. Defaults to env var"),
606
+ status: z.enum(["ON_TRACK", "AT_RISK", "OFF_TRACK", "INACTIVE", "COMPLETE"])
607
+ .describe("Project health designation"),
608
+ body: z.string().optional().describe("Status update body (markdown)"),
609
+ startDate: z.string().optional().describe("Start date (YYYY-MM-DD)"),
610
+ targetDate: z.string().optional().describe("Target date (YYYY-MM-DD)"),
611
+ }, async (args) => {
612
+ try {
613
+ const { projectNumber, projectOwner } = resolveFullConfig(client, args);
614
+ await ensureFieldCache(client, fieldCache, projectOwner, projectNumber);
615
+ const projectId = fieldCache.getProjectId();
616
+ if (!projectId) {
617
+ return toolError("Could not resolve project ID");
618
+ }
619
+ const vars = {
620
+ projectId,
621
+ statusValue: args.status,
622
+ };
623
+ if (args.body !== undefined)
624
+ vars.body = args.body;
625
+ if (args.startDate !== undefined)
626
+ vars.startDate = args.startDate;
627
+ if (args.targetDate !== undefined)
628
+ vars.targetDate = args.targetDate;
629
+ const result = await client.projectMutate(`mutation($projectId: ID!, $statusValue: ProjectV2StatusUpdateStatus!, $body: String, $startDate: Date, $targetDate: Date) {
630
+ createProjectV2StatusUpdate(input: {
631
+ projectId: $projectId,
632
+ status: $statusValue,
633
+ body: $body,
634
+ startDate: $startDate,
635
+ targetDate: $targetDate
636
+ }) {
637
+ statusUpdate {
638
+ id
639
+ status
640
+ body
641
+ startDate
642
+ targetDate
643
+ createdAt
644
+ }
645
+ }
646
+ }`, vars);
647
+ const su = result.createProjectV2StatusUpdate.statusUpdate;
648
+ return toolSuccess({
649
+ id: su.id,
650
+ status: su.status,
651
+ body: su.body,
652
+ startDate: su.startDate,
653
+ targetDate: su.targetDate,
654
+ createdAt: su.createdAt,
655
+ });
656
+ }
657
+ catch (error) {
658
+ const message = error instanceof Error ? error.message : String(error);
659
+ return toolError(`Failed to create status update: ${message}`);
660
+ }
661
+ });
662
+ // -------------------------------------------------------------------------
663
+ // ralph_hero__update_status_update
664
+ // -------------------------------------------------------------------------
665
+ server.tool("ralph_hero__update_status_update", "Update an existing project status update. Modify body, status designation, or dates. Returns: id, status, body, startDate, targetDate, updatedAt.", {
666
+ owner: z.string().optional().describe("GitHub owner. Defaults to env var"),
667
+ repo: z.string().optional().describe("Repository name. Defaults to env var"),
668
+ statusUpdateId: z.string().describe("Node ID of the status update to modify"),
669
+ status: z.enum(["ON_TRACK", "AT_RISK", "OFF_TRACK", "INACTIVE", "COMPLETE"]).optional()
670
+ .describe("Updated project health designation"),
671
+ body: z.string().optional().describe("Updated body (markdown)"),
672
+ startDate: z.string().optional().describe("Updated start date (YYYY-MM-DD)"),
673
+ targetDate: z.string().optional().describe("Updated target date (YYYY-MM-DD)"),
674
+ }, async (args) => {
675
+ try {
676
+ if (args.status === undefined &&
677
+ args.body === undefined &&
678
+ args.startDate === undefined &&
679
+ args.targetDate === undefined) {
680
+ return toolError("At least one field to update is required (status, body, startDate, targetDate)");
681
+ }
682
+ const { projectNumber, projectOwner } = resolveFullConfig(client, args);
683
+ await ensureFieldCache(client, fieldCache, projectOwner, projectNumber);
684
+ const vars = {
685
+ statusUpdateId: args.statusUpdateId,
686
+ };
687
+ if (args.status !== undefined)
688
+ vars.statusValue = args.status;
689
+ if (args.body !== undefined)
690
+ vars.body = args.body;
691
+ if (args.startDate !== undefined)
692
+ vars.startDate = args.startDate;
693
+ if (args.targetDate !== undefined)
694
+ vars.targetDate = args.targetDate;
695
+ const result = await client.projectMutate(`mutation($statusUpdateId: ID!, $statusValue: ProjectV2StatusUpdateStatus, $body: String, $startDate: Date, $targetDate: Date) {
696
+ updateProjectV2StatusUpdate(input: {
697
+ statusUpdateId: $statusUpdateId,
698
+ status: $statusValue,
699
+ body: $body,
700
+ startDate: $startDate,
701
+ targetDate: $targetDate
702
+ }) {
703
+ statusUpdate {
704
+ id
705
+ status
706
+ body
707
+ startDate
708
+ targetDate
709
+ updatedAt
710
+ }
711
+ }
712
+ }`, vars);
713
+ const su = result.updateProjectV2StatusUpdate.statusUpdate;
714
+ return toolSuccess({
715
+ id: su.id,
716
+ status: su.status,
717
+ body: su.body,
718
+ startDate: su.startDate,
719
+ targetDate: su.targetDate,
720
+ updatedAt: su.updatedAt,
721
+ });
722
+ }
723
+ catch (error) {
724
+ const message = error instanceof Error ? error.message : String(error);
725
+ return toolError(`Failed to update status update: ${message}`);
726
+ }
727
+ });
728
+ // -------------------------------------------------------------------------
729
+ // ralph_hero__delete_status_update
730
+ // -------------------------------------------------------------------------
731
+ server.tool("ralph_hero__delete_status_update", "Delete a project status update. This action cannot be undone. Returns: deletedStatusUpdateId.", {
732
+ owner: z.string().optional().describe("GitHub owner. Defaults to env var"),
733
+ repo: z.string().optional().describe("Repository name. Defaults to env var"),
734
+ statusUpdateId: z.string().describe("Node ID of the status update to delete"),
735
+ }, async (args) => {
736
+ try {
737
+ const { projectNumber, projectOwner } = resolveFullConfig(client, args);
738
+ await ensureFieldCache(client, fieldCache, projectOwner, projectNumber);
739
+ const result = await client.projectMutate(`mutation($statusUpdateId: ID!) {
740
+ deleteProjectV2StatusUpdate(input: {
741
+ statusUpdateId: $statusUpdateId
742
+ }) {
743
+ deletedStatusUpdateId
744
+ }
745
+ }`, { statusUpdateId: args.statusUpdateId });
746
+ return toolSuccess({
747
+ deletedStatusUpdateId: result.deleteProjectV2StatusUpdate.deletedStatusUpdateId,
748
+ });
749
+ }
750
+ catch (error) {
751
+ const message = error instanceof Error ? error.message : String(error);
752
+ return toolError(`Failed to delete status update: ${message}`);
753
+ }
754
+ });
599
755
  }
600
756
  //# sourceMappingURL=project-management-tools.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-hero-mcp-server",
3
- "version": "2.4.6",
3
+ "version": "2.4.7",
4
4
  "description": "MCP server for GitHub Projects V2 - Ralph workflow automation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",