DEV Community

Aarish mansur
Aarish mansur

Posted on

I build a Tool for Open source Maintainers

Sanity Challenge Path Two Submission

This is a submission for the Sanity Challenge, Path Two: Vibe-Code Something Strange

What I Built

As someone who is contributing for a good amount of time I noticed a problem as in bigger and legacy codebases a lot of issues are opened daily and honestly maintainers dont have time to give their full attention to every issue.

So I build Mento its an AI powered maintainer is copilot that fetches your GitHub issues generates plain English summaries with urgency scores and runs an intelligent triage pipeline that learns from past decisions to suggest P0–P4 priorities.

The more issues you triage the smarter it gets. Currently its in early development so you dont have to login via Github just bring your LLM key from any router (curently we Provide over 10+ router options )

Demo

Hero page

Features

Fetching issues

Live demo: https://mainto-five.vercel.app/

Code

GitHub repository: https://github.com/AarishMansur/Mainto

My Build Process

I build Mento with OpenCode and Nextjs so I didnt use any wireframes or no planning docs I use Sanity Docs and couple of Prompts which worked for me

I use santity as the agents memory so that every fetched issue, AI summary, triage decision, and learned pattern gets stored as a structured document and the agent reads from them before making it next decision and not forgetting sanity Live colloboration for real time updates and the Presentation Tool to map Studio documents directly to app routes

The more you triage the better it gets

These are some of the prompts I used:

Prompt 1: Product Direction

Build a maintainer focused web app that connects to GitHub repositories and helps open source maintainers understand which issues need attention first. Include repository search, issue cards, AI summaries, urgency scores, suggested actions, and a clean dashboard experience.

Prompt 2: Issue Summaries

Create an AI summarization flow for GitHub issues. Return a structured result containing a concise summary, an urgency score from 1 to 10, three to five key points, and two to three suggested actions. The output should be easy for a maintainer to scan quickly.

Prompt 3: Sanity Data Modeling

Model the Mainto workflow in Sanity. Create document types for GitHub issues, generated issue summaries, historical triage patterns, and maintainer triage decisions. Use references between related documents and include fields for urgency, priority, reasoning, suggested actions, and resolution history.

Prompt 4: Triage Pipeline

Add a workflow pipeline with New, Summarized, Prioritized, In Review, and Resolved stages. Let the AI prioritize issues from P0 to P4 using historical patterns, matching keywords, labels, and previous maintainer decisions.

How I designed my Sanity Schema

GitHub Issue

import { defineField, defineType } from 'sanity'

export const issueType = defineType({
  name: 'issue',
  title: 'GitHub Issue',
  type: 'document',
  fields: [
    defineField({ name: 'githubId', type: 'number', validation: (Rule) => Rule.required() }),
    defineField({ name: 'repoOwner', type: 'string', validation: (Rule) => Rule.required() }),
    defineField({ name: 'repoName', type: 'string', validation: (Rule) => Rule.required() }),
    defineField({ name: 'title', type: 'string', validation: (Rule) => Rule.required() }),
    defineField({ name: 'body', type: 'text' }),
    defineField({ name: 'state', type: 'string', options: { list: [{ title: 'Open', value: 'open' }, { title: 'Closed', value: 'closed' }] } }),
    defineField({ name: 'labels', type: 'array', of: [{ type: 'string' }] }),
    defineField({ name: 'commentsCount', type: 'number' }),
    defineField({ name: 'workflowStatus', type: 'string', initialValue: 'new', options: { list: [
      { title: 'New', value: 'new' },
      { title: 'Summarized', value: 'summarized' },
      { title: 'Prioritized', value: 'prioritized' },
      { title: 'In Review', value: 'in_review' },
      { title: 'Resolved', value: 'resolved' },
    ]}}),
    defineField({ name: 'agentPriority', type: 'string', options: { list: [
      { title: 'P0 - Critical', value: 'P0' },
      { title: 'P1 - High', value: 'P1' },
      { title: 'P2 - Medium', value: 'P2' },
      { title: 'P3 - Low', value: 'P3' },
      { title: 'P4 - Backlog', value: 'P4' },
    ]}}),
    defineField({ name: 'agentReasoning', type: 'text' }),
    defineField({ name: 'matchedPatternIds', type: 'array', of: [{ type: 'reference', to: [{ type: 'triagePattern' }] }] }),
    defineField({ name: 'maintainerDecision', type: 'string', options: { list: [
      { title: 'Accepted', value: 'accepted' },
      { title: 'Overridden Higher', value: 'overridden_higher' },
      { title: 'Overridden Lower', value: 'overridden_lower' },
      { title: 'Pending', value: 'pending' },
    ]}}),
  ],
})
Enter fullscreen mode Exit fullscreen mode

issueSummary — AI Generated Summary

export const issueSummaryType = defineType({
  name: 'issueSummary',
  title: 'Issue Summary',
  type: 'document',
  fields: [
    defineField({ name: 'githubId', type: 'number', validation: (Rule) => Rule.required() }),
    defineField({ name: 'summary', type: 'text', validation: (Rule) => Rule.required() }),
    defineField({ name: 'urgencyScore', type: 'number', validation: (Rule) => Rule.min(1).max(10) }),
    defineField({ name: 'keyPoints', type: 'array', of: [{ type: 'string' }] }),
    defineField({ name: 'suggestedActions', type: 'array', of: [{ type: 'string' }] }),
    defineField({ name: 'generatedAt', type: 'datetime' }),
  ],
})
Enter fullscreen mode Exit fullscreen mode

triagePattern — Agent Memory

export const triagePatternType = defineType({
  name: 'triagePattern',
  title: 'Triage Pattern',
  type: 'document',
  fields: [
    defineField({ name: 'name', type: 'string', validation: (Rule) => Rule.required() }),
    defineField({ name: 'keywords', type: 'array', of: [{ type: 'string' }] }),
    defineField({ name: 'labels', type: 'array', of: [{ type: 'string' }] }),
    defineField({ name: 'avgUrgency', type: 'number' }),
    defineField({ name: 'typicalPriority', type: 'string' }),
    defineField({ name: 'typicalResolution', type: 'string' }),
    defineField({ name: 'patternCount', type: 'number', initialValue: 0 }),
  ],
})
Enter fullscreen mode Exit fullscreen mode

triageDecision — Maintainer Feedback Loop

export const triageDecisionType = defineType({
  name: 'triageDecision',
  title: 'Triage Decision',
  type: 'document',
  fields: [
    defineField({ name: 'issueId', type: 'number', validation: (Rule) => Rule.required() }),
    defineField({ name: 'issueTitle', type: 'string', validation: (Rule) => Rule.required() }),
    defineField({ name: 'priority', type: 'string', validation: (Rule) => Rule.required() }),
    defineField({ name: 'reasoning', type: 'text' }),
    defineField({ name: 'matchedPatternIds', type: 'array', of: [{ type: 'reference', to: [{ type: 'triagePattern' }] }] }),
    defineField({ name: 'resolution', type: 'string' }),
    defineField({ name: 'agentAccuracy', type: 'string', options: { list: [
      { title: 'Correct', value: 'correct' },
      { title: 'Partially Correct', value: 'partial' },
      { title: 'Incorrect', value: 'incorrect' },
    ]}}),
    defineField({ name: 'decidedAt', type: 'datetime' }),
  ],
})
Enter fullscreen mode Exit fullscreen mode

Sanity Project Details

  • Project ID: vni5slia
  • Dataset: production (public read)

Agent Session

https://dev.to/agent_sessions/vibe-coding-sanity-hackthon-y8hbb0

Top comments (14)

Collapse
 
himanshu_748 profile image
Himanshu Kumar

Looks so Good!

Collapse
 
aarishmansur profile image
Aarish mansur

Thanks Himanshu

Collapse
 
rushu profile image
RUSHU

Let's goo đŸĨŗ

Website looks amazing

Collapse
 
aarishmansur profile image
Aarish mansur

Thanks rushu

Collapse
 
harshit_parihar_65bae918e profile image
Harshit Parihar

Cfbr

Collapse
 
aarishmansur profile image
Aarish mansur

Thanks Harshit

Collapse
 
anish_maniyar_6f4a8d996ed profile image
Anish Maniyar

Lfg nice project

Collapse
 
aarishmansur profile image
Aarish mansur

Thanks anish

Collapse
 
xlr8_jay profile image
Jay Yadav

can u teach me too ? lets connect

Collapse
 
aarishmansur profile image
Aarish mansur

yes lets connect đŸĨ°

Collapse
 
halwaii_ profile image
Dacron Polymer

great bro . keep it up

Collapse
 
aarishmansur profile image
Aarish mansur

Thanks Dacron

Collapse
 
roshan_kumar_cd9b876cb869 profile image
Roshan Kumar • Edited

seems interesting to me as it could lower the amount of workload for me

Collapse
 
aarishmansur profile image
Aarish mansur

next GSSOC preparation 😂