Last active
February 19, 2026 11:41
-
-
Save gcapnias/e04577c11a78f02dc76f6e298f87c6ad to your computer and use it in GitHub Desktop.
An MCP server `tasks-mcp-server` that can keep track of features for implementation by an agent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env node | |
| var He=Object.create;var Q=Object.defineProperty;var Be=Object.getOwnPropertyDescriptor;var qe=Object.getOwnPropertyNames;var Ge=Object.getPrototypeOf,Xe=Object.prototype.hasOwnProperty;var We=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(s,c)=>(typeof require<"u"?require:s)[c]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var ze=(o,s)=>()=>(s||o((s={exports:{}}).exports,s),s.exports);var Ye=(o,s,c,u)=>{if(s&&typeof s=="object"||typeof s=="function")for(let l of qe(s))!Xe.call(o,l)&&l!==c&&Q(o,l,{get:()=>s[l],enumerable:!(u=Be(s,l))||u.enumerable});return o};var Ke=(o,s,c)=>(c=o!=null?He(Ge(o)):{},Ye(s||!o||!o.__esModule?Q(c,"default",{value:o,enumerable:!0}):c,o));var ne=ze((P,re)=>{(function(o,s){typeof P=="object"&&typeof re<"u"?s(P):typeof define=="function"&&define.amd?define(["exports"],s):(o=typeof globalThis<"u"?globalThis:o||self,s(o.heap={}))})(P,(function(o){"use strict";var s=function(r,e,t,n){function a(i){return i instanceof t?i:new t(function(f){f(i)})}return new(t||(t=Promise))(function(i,f){function g(b){try{h(n.next(b))}catch(N){f(N)}}function A(b){try{h(n.throw(b))}catch(N){f(N)}}function h(b){b.done?i(b.value):a(b.value).then(g,A)}h((n=n.apply(r,e||[])).next())})},c=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,a,i,f=Object.create((typeof Iterator=="function"?Iterator:Object).prototype);return f.next=g(0),f.throw=g(1),f.return=g(2),typeof Symbol=="function"&&(f[Symbol.iterator]=function(){return this}),f;function g(h){return function(b){return A([h,b])}}function A(h){if(n)throw new TypeError("Generator is already executing.");for(;f&&(f=0,h[0]&&(t=0)),t;)try{if(n=1,a&&(i=h[0]&2?a.return:h[0]?a.throw||((i=a.return)&&i.call(a),0):a.next)&&!(i=i.call(a,h[1])).done)return i;switch(a=0,i&&(h=[h[0]&2,i.value]),h[0]){case 0:case 1:i=h;break;case 4:return t.label++,{value:h[1],done:!1};case 5:t.label++,a=h[1],h=[0];continue;case 7:h=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(h[0]===6||h[0]===2)){t=0;continue}if(h[0]===3&&(!i||h[1]>i[0]&&h[1]<i[3])){t.label=h[1];break}if(h[0]===6&&t.label<i[1]){t.label=i[1],i=h;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(h);break}i[2]&&t.ops.pop(),t.trys.pop();continue}h=e.call(r,t)}catch(b){h=[6,b],a=0}finally{n=i=0}if(h[0]&5)throw h[1];return{value:h[0]?h[1]:void 0,done:!0}}},u=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),a,i=[],f;try{for(;(e===void 0||e-- >0)&&!(a=n.next()).done;)i.push(a.value)}catch(g){f={error:g}}finally{try{a&&!a.done&&(t=n.return)&&t.call(n)}finally{if(f)throw f.error}}return i},l=function(r,e,t){if(t||arguments.length===2)for(var n=0,a=e.length,i;n<a;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},d=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return{next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},p=(function(){function r(e){e===void 0&&(e=r.minComparator);var t=this;this.compare=e,this.heapArray=[],this._limit=0,this.offer=this.add,this.element=this.peek,this.poll=this.pop,this._invertedCompare=function(n,a){return t.compare(n,a).then(function(i){return-1*i})}}return r.getChildrenIndexOf=function(e){return[e*2+1,e*2+2]},r.getParentIndexOf=function(e){if(e<=0)return-1;var t=e%2?1:2;return Math.floor((e-t)/2)},r.getSiblingIndexOf=function(e){if(e<=0)return-1;var t=e%2?1:-1;return e+t},r.minComparator=function(e,t){return s(this,void 0,void 0,function(){return c(this,function(n){return e>t?[2,1]:e<t?[2,-1]:[2,0]})})},r.maxComparator=function(e,t){return s(this,void 0,void 0,function(){return c(this,function(n){return t>e?[2,1]:t<e?[2,-1]:[2,0]})})},r.minComparatorNumber=function(e,t){return s(this,void 0,void 0,function(){return c(this,function(n){return[2,e-t]})})},r.maxComparatorNumber=function(e,t){return s(this,void 0,void 0,function(){return c(this,function(n){return[2,t-e]})})},r.defaultIsEqual=function(e,t){return s(this,void 0,void 0,function(){return c(this,function(n){return[2,e===t]})})},r.print=function(e){function t(b){var N=r.getParentIndexOf(b);return Math.floor(Math.log2(N+1))}function n(b,N){for(var T="";N>0;--N)T+=b;return T}for(var a=0,i=[],f=t(e.length-1)+2,g=0;a<e.length;){var A=t(a)+1;a===0&&(A=0);var h=String(e.get(a));h.length>g&&(g=h.length),i[A]=i[A]||[],i[A].push(h),a+=1}return i.map(function(b,N){var T=Math.pow(2,f-N)-1;return n(" ",Math.floor(T/2)*g)+b.map(function(R){var k=(g-R.length)/2;return n(" ",Math.ceil(k))+R+n(" ",Math.floor(k))}).join(n(" ",T*g))}).join(` | |
| `)},r.heapify=function(e,t){return s(this,void 0,void 0,function(){var n;return c(this,function(a){switch(a.label){case 0:return n=new r(t),n.heapArray=e,[4,n.init()];case 1:return a.sent(),[2,n]}})})},r.heappop=function(e,t){var n=new r(t);return n.heapArray=e,n.pop()},r.heappush=function(e,t,n){return s(this,void 0,void 0,function(){var a;return c(this,function(i){switch(i.label){case 0:return a=new r(n),a.heapArray=e,[4,a.push(t)];case 1:return i.sent(),[2]}})})},r.heappushpop=function(e,t,n){var a=new r(n);return a.heapArray=e,a.pushpop(t)},r.heapreplace=function(e,t,n){var a=new r(n);return a.heapArray=e,a.replace(t)},r.heaptop=function(e,t,n){t===void 0&&(t=1);var a=new r(n);return a.heapArray=e,a.top(t)},r.heapbottom=function(e,t,n){t===void 0&&(t=1);var a=new r(n);return a.heapArray=e,a.bottom(t)},r.nlargest=function(e,t,n){return s(this,void 0,void 0,function(){var a;return c(this,function(i){switch(i.label){case 0:return a=new r(n),a.heapArray=l([],u(t),!1),[4,a.init()];case 1:return i.sent(),[2,a.top(e)]}})})},r.nsmallest=function(e,t,n){return s(this,void 0,void 0,function(){var a;return c(this,function(i){switch(i.label){case 0:return a=new r(n),a.heapArray=l([],u(t),!1),[4,a.init()];case 1:return i.sent(),[2,a.bottom(e)]}})})},r.prototype.add=function(e){return s(this,void 0,void 0,function(){return c(this,function(t){switch(t.label){case 0:return[4,this._sortNodeUp(this.heapArray.push(e)-1)];case 1:return t.sent(),this._applyLimit(),[2,!0]}})})},r.prototype.addAll=function(e){return s(this,void 0,void 0,function(){var t,n,a;return c(this,function(i){switch(i.label){case 0:t=this.length,(a=this.heapArray).push.apply(a,l([],u(e),!1)),n=this.length,i.label=1;case 1:return t<n?[4,this._sortNodeUp(t)]:[3,4];case 2:i.sent(),i.label=3;case 3:return++t,[3,1];case 4:return this._applyLimit(),[2,!0]}})})},r.prototype.bottom=function(){return s(this,arguments,void 0,function(e){return e===void 0&&(e=1),c(this,function(t){return this.heapArray.length===0||e<=0?[2,[]]:this.heapArray.length===1?[2,[this.heapArray[0]]]:e>=this.heapArray.length?[2,l([],u(this.heapArray),!1)]:[2,this._bottomN_push(~~e)]})})},r.prototype.check=function(){return s(this,void 0,void 0,function(){var e,t,n,a,i,f,g,A,h;return c(this,function(b){switch(b.label){case 0:e=0,b.label=1;case 1:if(!(e<this.heapArray.length))return[3,10];t=this.heapArray[e],n=this.getChildrenOf(e),b.label=2;case 2:b.trys.push([2,7,8,9]),a=(A=void 0,d(n)),i=a.next(),b.label=3;case 3:return i.done?[3,6]:(f=i.value,[4,this.compare(t,f)]);case 4:if(b.sent()>0)return[2,t];b.label=5;case 5:return i=a.next(),[3,3];case 6:return[3,9];case 7:return g=b.sent(),A={error:g},[3,9];case 8:try{i&&!i.done&&(h=a.return)&&h.call(a)}finally{if(A)throw A.error}return[7];case 9:return++e,[3,1];case 10:return[2]}})})},r.prototype.clear=function(){this.heapArray=[]},r.prototype.clone=function(){var e=new r(this.comparator());return e.heapArray=this.toArray(),e._limit=this._limit,e},r.prototype.comparator=function(){return this.compare},r.prototype.contains=function(e){return s(this,arguments,void 0,function(t,n){var a,i,f,g,A,h;return n===void 0&&(n=r.defaultIsEqual),c(this,function(b){switch(b.label){case 0:b.trys.push([0,5,6,7]),a=d(this.heapArray),i=a.next(),b.label=1;case 1:return i.done?[3,4]:(f=i.value,[4,n(f,t)]);case 2:if(b.sent())return[2,!0];b.label=3;case 3:return i=a.next(),[3,1];case 4:return[3,7];case 5:return g=b.sent(),A={error:g},[3,7];case 6:try{i&&!i.done&&(h=a.return)&&h.call(a)}finally{if(A)throw A.error}return[7];case 7:return[2,!1]}})})},r.prototype.init=function(e){return s(this,void 0,void 0,function(){var t;return c(this,function(n){switch(n.label){case 0:e&&(this.heapArray=l([],u(e),!1)),t=r.getParentIndexOf(this.length-1),n.label=1;case 1:return t>=0?[4,this._sortNodeDown(t)]:[3,4];case 2:n.sent(),n.label=3;case 3:return--t,[3,1];case 4:return this._applyLimit(),[2]}})})},r.prototype.isEmpty=function(){return this.length===0},r.prototype.leafs=function(){if(this.heapArray.length===0)return[];var e=r.getParentIndexOf(this.heapArray.length-1);return this.heapArray.slice(e+1)},Object.defineProperty(r.prototype,"length",{get:function(){return this.heapArray.length},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"limit",{get:function(){return this._limit},set:function(e){this._limit=~~e,this._applyLimit()},enumerable:!1,configurable:!0}),r.prototype.peek=function(){return this.heapArray[0]},r.prototype.pop=function(){return s(this,void 0,void 0,function(){var e;return c(this,function(t){return e=this.heapArray.pop(),this.length>0&&e!==void 0?[2,this.replace(e)]:[2,e]})})},r.prototype.push=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return s(this,void 0,void 0,function(){return c(this,function(n){return e.length<1?[2,!1]:e.length===1?[2,this.add(e[0])]:[2,this.addAll(e)]})})},r.prototype.pushpop=function(e){return s(this,void 0,void 0,function(){var t;return c(this,function(n){switch(n.label){case 0:return[4,this.compare(this.heapArray[0],e)];case 1:return n.sent()<0?(t=u([this.heapArray[0],e],2),e=t[0],this.heapArray[0]=t[1],[4,this._sortNodeDown(0)]):[3,3];case 2:n.sent(),n.label=3;case 3:return[2,e]}})})},r.prototype.remove=function(e){return s(this,arguments,void 0,function(t,n){var a,i,f,g=this;return n===void 0&&(n=r.defaultIsEqual),c(this,function(A){switch(A.label){case 0:return this.heapArray.length?t!==void 0?[3,2]:[4,this.pop()]:[2,!1];case 1:return A.sent(),[2,!0];case 2:a=[0],A.label=3;case 3:return a.length?(i=a.shift(),[4,n(this.heapArray[i],t)]):[3,13];case 4:return A.sent()?i!==0?[3,6]:[4,this.pop()]:[3,11];case 5:return A.sent(),[3,10];case 6:return i!==this.heapArray.length-1?[3,7]:(this.heapArray.pop(),[3,10]);case 7:return this.heapArray.splice(i,1,this.heapArray.pop()),[4,this._sortNodeUp(i)];case 8:return A.sent(),[4,this._sortNodeDown(i)];case 9:A.sent(),A.label=10;case 10:return[2,!0];case 11:f=r.getChildrenIndexOf(i).filter(function(h){return h<g.heapArray.length}),a.push.apply(a,l([],u(f),!1)),A.label=12;case 12:return[3,3];case 13:return[2,!1]}})})},r.prototype.replace=function(e){return s(this,void 0,void 0,function(){var t;return c(this,function(n){switch(n.label){case 0:return t=this.heapArray[0],this.heapArray[0]=e,[4,this._sortNodeDown(0)];case 1:return n.sent(),[2,t]}})})},r.prototype.size=function(){return this.length},r.prototype.top=function(){return s(this,arguments,void 0,function(e){return e===void 0&&(e=1),c(this,function(t){return this.heapArray.length===0||e<=0?[2,[]]:this.heapArray.length===1||e===1?[2,[this.heapArray[0]]]:e>=this.heapArray.length?[2,l([],u(this.heapArray),!1)]:[2,this._topN_push(~~e)]})})},r.prototype.toArray=function(){return l([],u(this.heapArray),!1)},r.prototype.toString=function(){return this.heapArray.toString()},r.prototype.get=function(e){return this.heapArray[e]},r.prototype.getChildrenOf=function(e){var t=this;return r.getChildrenIndexOf(e).map(function(n){return t.heapArray[n]}).filter(function(n){return n!==void 0})},r.prototype.getParentOf=function(e){var t=r.getParentIndexOf(e);return this.heapArray[t]},r.prototype[Symbol.iterator]=function(){return c(this,function(e){switch(e.label){case 0:return this.length?[4,this.pop()]:[3,2];case 1:return e.sent(),[3,0];case 2:return[2]}})},r.prototype.iterator=function(){return this},r.prototype._applyLimit=function(){if(this._limit&&this._limit<this.heapArray.length)for(var e=this.heapArray.length-this._limit;e;)this.heapArray.pop(),--e},r.prototype._bottomN_push=function(e){return s(this,void 0,void 0,function(){var t,n,a,i,g,f,g;return c(this,function(A){switch(A.label){case 0:return t=new r(this.compare),t.limit=e,t.heapArray=this.heapArray.slice(-e),[4,t.init()];case 1:for(A.sent(),n=this.heapArray.length-1-e,a=r.getParentIndexOf(n),i=[],g=n;g>a;--g)i.push(g);f=this.heapArray,A.label=2;case 2:return i.length?(g=i.shift(),[4,this.compare(f[g],t.peek())]):[3,6];case 3:return A.sent()>0?[4,t.replace(f[g])]:[3,5];case 4:A.sent(),g%2&&i.push(r.getParentIndexOf(g)),A.label=5;case 5:return[3,2];case 6:return[2,t.toArray()]}})})},r.prototype._moveNode=function(e,t){var n=this.heapArray[e];this.heapArray[e]=this.heapArray[t],this.heapArray[t]=n},r.prototype._sortNodeDown=function(e){return s(this,void 0,void 0,function(){var t,n,a,i,f,g,A;return c(this,function(h){switch(h.label){case 0:t=this.heapArray.length,n=e,a=this.heapArray[e],i=2*e+1,h.label=1;case 1:return i<t?(f=i+1,A=f>=t,A?[3,3]:[4,this.compare(this.heapArray[i],this.heapArray[f])]):[3,5];case 2:A=h.sent()<0,h.label=3;case 3:return g=A?i:f,[4,this.compare(this.heapArray[g],a)];case 4:if(h.sent()<0)this.heapArray[e]=this.heapArray[g],e=g,i=2*e+1;else return[3,5];return[3,1];case 5:return e!==n&&(this.heapArray[e]=a),[2]}})})},r.prototype._sortNodeUp=function(e){return s(this,void 0,void 0,function(){var t,n,a;return c(this,function(i){switch(i.label){case 0:t=this.heapArray[e],n=e,i.label=1;case 1:return e>0?(a=r.getParentIndexOf(e),[4,this.compare(t,this.heapArray[a])]):[3,3];case 2:if(i.sent()<0)this.heapArray[e]=this.heapArray[a],e=a;else return[3,3];return[3,1];case 3:return e!==n&&(this.heapArray[e]=t),[2]}})})},r.prototype._topN_push=function(e){return s(this,void 0,void 0,function(){var t,n,a,i;return c(this,function(f){switch(f.label){case 0:t=new r(this._invertedCompare),t.limit=e,n=[0],a=this.heapArray,f.label=1;case 1:return n.length?(i=n.shift(),i<a.length?t.length<e?[4,t.push(a[i])]:[3,3]:[3,6]):[3,7];case 2:return f.sent(),n.push.apply(n,l([],u(r.getChildrenIndexOf(i)),!1)),[3,6];case 3:return[4,this.compare(a[i],t.peek())];case 4:return f.sent()<0?[4,t.replace(a[i])]:[3,6];case 5:f.sent(),n.push.apply(n,l([],u(r.getChildrenIndexOf(i)),!1)),f.label=6;case 6:return[3,1];case 7:return[2,t.toArray()]}})})},r.prototype._topN_fill=function(e){return s(this,void 0,void 0,function(){var t,n,a,i,f,f;return c(this,function(g){switch(g.label){case 0:return t=this.heapArray,n=new r(this._invertedCompare),n.limit=e,n.heapArray=t.slice(0,e),[4,n.init()];case 1:for(g.sent(),a=r.getParentIndexOf(e-1)+1,i=[],f=a;f<e;++f)i.push.apply(i,l([],u(r.getChildrenIndexOf(f).filter(function(A){return A<t.length})),!1));(e-1)%2&&i.push(e),g.label=2;case 2:return i.length?(f=i.shift(),f<t.length?[4,this.compare(t[f],n.peek())]:[3,5]):[3,6];case 3:return g.sent()<0?[4,n.replace(t[f])]:[3,5];case 4:g.sent(),i.push.apply(i,l([],u(r.getChildrenIndexOf(f)),!1)),g.label=5;case 5:return[3,2];case 6:return[2,n.toArray()]}})})},r.prototype._topN_heap=function(e){return s(this,void 0,void 0,function(){var t,n,a,i,f;return c(this,function(g){switch(g.label){case 0:t=this.clone(),n=[],a=0,g.label=1;case 1:return a<e?(f=(i=n).push,[4,t.pop()]):[3,4];case 2:f.apply(i,[g.sent()]),g.label=3;case 3:return++a,[3,1];case 4:return[2,n]}})})},r.prototype._topIdxOf=function(e){return s(this,void 0,void 0,function(){var t,n,a,i;return c(this,function(f){switch(f.label){case 0:if(!e.length)return[2,-1];t=0,n=e[t],a=1,f.label=1;case 1:return a<e.length?[4,this.compare(e[a],n)]:[3,4];case 2:i=f.sent(),i<0&&(t=a,n=e[a]),f.label=3;case 3:return++a,[3,1];case 4:return[2,t]}})})},r.prototype._topOf=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return s(this,void 0,void 0,function(){var n;return c(this,function(a){switch(a.label){case 0:return n=new r(this.compare),[4,n.init(e)];case 1:return a.sent(),[2,n.peek()]}})})},r})(),y=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,a,i,f=Object.create((typeof Iterator=="function"?Iterator:Object).prototype);return f.next=g(0),f.throw=g(1),f.return=g(2),typeof Symbol=="function"&&(f[Symbol.iterator]=function(){return this}),f;function g(h){return function(b){return A([h,b])}}function A(h){if(n)throw new TypeError("Generator is already executing.");for(;f&&(f=0,h[0]&&(t=0)),t;)try{if(n=1,a&&(i=h[0]&2?a.return:h[0]?a.throw||((i=a.return)&&i.call(a),0):a.next)&&!(i=i.call(a,h[1])).done)return i;switch(a=0,i&&(h=[h[0]&2,i.value]),h[0]){case 0:case 1:i=h;break;case 4:return t.label++,{value:h[1],done:!1};case 5:t.label++,a=h[1],h=[0];continue;case 7:h=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(h[0]===6||h[0]===2)){t=0;continue}if(h[0]===3&&(!i||h[1]>i[0]&&h[1]<i[3])){t.label=h[1];break}if(h[0]===6&&t.label<i[1]){t.label=i[1],i=h;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(h);break}i[2]&&t.ops.pop(),t.trys.pop();continue}h=e.call(r,t)}catch(b){h=[6,b],a=0}finally{n=i=0}if(h[0]&5)throw h[1];return{value:h[0]?h[1]:void 0,done:!0}}},v=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),a,i=[],f;try{for(;(e===void 0||e-- >0)&&!(a=n.next()).done;)i.push(a.value)}catch(g){f={error:g}}finally{try{a&&!a.done&&(t=n.return)&&t.call(n)}finally{if(f)throw f.error}}return i},E=function(r,e,t){if(t||arguments.length===2)for(var n=0,a=e.length,i;n<a;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},S=function(r){return~~r},_=(function(){function r(e){e===void 0&&(e=r.minComparator);var t=this;this.compare=e,this.heapArray=[],this._limit=0,this.offer=this.add,this.element=this.peek,this.poll=this.pop,this.removeAll=this.clear,this._invertedCompare=function(n,a){return-1*t.compare(n,a)}}return r.getChildrenIndexOf=function(e){return[e*2+1,e*2+2]},r.getParentIndexOf=function(e){return e<=0?-1:e-1>>1},r.getSiblingIndexOf=function(e){if(e<=0)return-1;var t=e%2?1:-1;return e+t},r.minComparator=function(e,t){return e>t?1:e<t?-1:0},r.maxComparator=function(e,t){return t>e?1:t<e?-1:0},r.minComparatorNumber=function(e,t){return e-t},r.maxComparatorNumber=function(e,t){return t-e},r.defaultIsEqual=function(e,t){return e===t},r.print=function(e){function t(b){var N=r.getParentIndexOf(b);return Math.floor(Math.log2(N+1))}function n(b,N){for(var T="";N>0;--N)T+=b;return T}for(var a=0,i=[],f=t(e.length-1)+2,g=0;a<e.length;){var A=t(a)+1;a===0&&(A=0);var h=String(e.get(a));h.length>g&&(g=h.length),i[A]=i[A]||[],i[A].push(h),a+=1}return i.map(function(b,N){var T=Math.pow(2,f-N)-1;return n(" ",Math.floor(T/2)*g)+b.map(function(R){var k=(g-R.length)/2;return n(" ",Math.ceil(k))+R+n(" ",Math.floor(k))}).join(n(" ",T*g))}).join(` | |
| `)},r.heapify=function(e,t){var n=new r(t);return n.heapArray=e,n.init(),n},r.heappop=function(e,t){var n=new r(t);return n.heapArray=e,n.pop()},r.heappush=function(e,t,n){var a=new r(n);a.heapArray=e,a.push(t)},r.heappushpop=function(e,t,n){var a=new r(n);return a.heapArray=e,a.pushpop(t)},r.heapreplace=function(e,t,n){var a=new r(n);return a.heapArray=e,a.replace(t)},r.heaptop=function(e,t,n){t===void 0&&(t=1);var a=new r(n);return a.heapArray=e,a.top(t)},r.heapbottom=function(e,t,n){t===void 0&&(t=1);var a=new r(n);return a.heapArray=e,a.bottom(t)},r.nlargest=function(e,t,n){var a=new r(n);return a.heapArray=E([],v(t),!1),a.init(),a.top(e)},r.nsmallest=function(e,t,n){var a=new r(n);return a.heapArray=E([],v(t),!1),a.init(),a.bottom(e)},r.prototype.add=function(e){return this._sortNodeUp(this.heapArray.push(e)-1),this._applyLimit(),!0},r.prototype.addAll=function(e){var t,n=this.length;(t=this.heapArray).push.apply(t,E([],v(e),!1));for(var a=this.length;n<a;++n)this._sortNodeUp(n);return this._applyLimit(),!0},r.prototype.bottom=function(e){return e===void 0&&(e=1),this.heapArray.length===0||e<=0?[]:this.heapArray.length===1?[this.heapArray[0]]:e>=this.heapArray.length?E([],v(this.heapArray),!1):this._bottomN_push(~~e)},r.prototype.check=function(){var e=this;return this.heapArray.find(function(t,n){return!!e.getChildrenOf(n).find(function(a){return e.compare(t,a)>0})})},r.prototype.clear=function(){this.heapArray=[]},r.prototype.clone=function(){var e=new r(this.comparator());return e.heapArray=this.toArray(),e._limit=this._limit,e},r.prototype.comparator=function(){return this.compare},r.prototype.contains=function(e,t){return t===void 0&&(t=r.defaultIsEqual),this.indexOf(e,t)!==-1},r.prototype.init=function(e){e&&(this.heapArray=E([],v(e),!1));for(var t=r.getParentIndexOf(this.length-1);t>=0;--t)this._sortNodeDown(t);this._applyLimit()},r.prototype.isEmpty=function(){return this.length===0},r.prototype.indexOf=function(e,t){if(t===void 0&&(t=r.defaultIsEqual),this.heapArray.length===0)return-1;for(var n=[],a=0;a<this.heapArray.length;){var i=this.heapArray[a];if(t(i,e))return a;this.compare(i,e)<=0&&n.push.apply(n,E([],v(r.getChildrenIndexOf(a)),!1)),a=n.shift()||this.heapArray.length}return-1},r.prototype.indexOfEvery=function(e,t){if(t===void 0&&(t=r.defaultIsEqual),this.heapArray.length===0)return[];for(var n=[],a=[],i=0;i<this.heapArray.length;){var f=this.heapArray[i];t(f,e)?(a.push(i),n.push.apply(n,E([],v(r.getChildrenIndexOf(i)),!1))):this.compare(f,e)<=0&&n.push.apply(n,E([],v(r.getChildrenIndexOf(i)),!1)),i=n.shift()||this.heapArray.length}return a},r.prototype.leafs=function(){if(this.heapArray.length===0)return[];var e=r.getParentIndexOf(this.heapArray.length-1);return this.heapArray.slice(e+1)},Object.defineProperty(r.prototype,"length",{get:function(){return this.heapArray.length},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"limit",{get:function(){return this._limit},set:function(e){e<0||isNaN(e)?this._limit=0:this._limit=~~e,this._applyLimit()},enumerable:!1,configurable:!0}),r.prototype.setLimit=function(e){return this.limit=e,e<0||isNaN(e)?NaN:this._limit},r.prototype.peek=function(){return this.heapArray[0]},r.prototype.pop=function(){var e=this.heapArray.pop();return this.length>0&&e!==void 0?this.replace(e):e},r.prototype.push=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return e.length<1?!1:e.length===1?this.add(e[0]):this.addAll(e)},r.prototype.pushpop=function(e){var t;return this.compare(this.heapArray[0],e)<0&&(t=v([this.heapArray[0],e],2),e=t[0],this.heapArray[0]=t[1],this._sortNodeDown(0)),e},r.prototype.remove=function(e,t){var n=this;if(t===void 0&&(t=r.defaultIsEqual),!this.heapArray.length)return!1;if(e===void 0)return this.pop(),!0;for(var a=[0];a.length;){var i=a.shift();if(t(this.heapArray[i],e))return i===0?this.pop():i===this.heapArray.length-1?this.heapArray.pop():(this.heapArray.splice(i,1,this.heapArray.pop()),this._sortNodeUp(i),this._sortNodeDown(i)),!0;if(this.compare(this.heapArray[i],e)<=0){var f=r.getChildrenIndexOf(i).filter(function(g){return g<n.heapArray.length});a.push.apply(a,E([],v(f),!1))}}return!1},r.prototype.replace=function(e){var t=this.heapArray[0];return this.heapArray[0]=e,this._sortNodeDown(0),t},r.prototype.size=function(){return this.length},r.prototype.top=function(e){return e===void 0&&(e=1),this.heapArray.length===0||e<=0?[]:this.heapArray.length===1||e===1?[this.heapArray[0]]:e>=this.heapArray.length?E([],v(this.heapArray),!1):this._topN_push(~~e)},r.prototype.toArray=function(){return E([],v(this.heapArray),!1)},r.prototype.toString=function(){return this.heapArray.toString()},r.prototype.get=function(e){return this.heapArray[e]},r.prototype.getChildrenOf=function(e){var t=this;return r.getChildrenIndexOf(e).map(function(n){return t.heapArray[n]}).filter(function(n){return n!==void 0})},r.prototype.getParentOf=function(e){var t=r.getParentIndexOf(e);return this.heapArray[t]},r.prototype[Symbol.iterator]=function(){return y(this,function(e){switch(e.label){case 0:return this.length?[4,this.pop()]:[3,2];case 1:return e.sent(),[3,0];case 2:return[2]}})},r.prototype.iterator=function(){return this.toArray()},r.prototype._applyLimit=function(){if(this._limit>0&&this._limit<this.heapArray.length)for(var e=this.heapArray.length-this._limit;e;)this.heapArray.pop(),--e},r.prototype._bottomN_push=function(e){var t=new r(this.compare);t.limit=e,t.heapArray=this.heapArray.slice(-e),t.init();for(var n=this.heapArray.length-1-e,a=r.getParentIndexOf(n),i=[],f=n;f>a;--f)i.push(f);for(var g=this.heapArray;i.length;){var f=i.shift();this.compare(g[f],t.peek())>0&&(t.replace(g[f]),f%2&&i.push(r.getParentIndexOf(f)))}return t.toArray()},r.prototype._moveNode=function(e,t){var n=this.heapArray[e];this.heapArray[e]=this.heapArray[t],this.heapArray[t]=n},r.prototype._sortNodeDown=function(e){for(var t=this.heapArray.length,n=e,a=this.heapArray[e],i=2*e+1;i<t;){var f=i+1,g=f>=t||this.compare(this.heapArray[i],this.heapArray[f])<0?i:f;if(this.compare(this.heapArray[g],a)<0)this.heapArray[e]=this.heapArray[g],e=g,i=2*e+1;else break}e!==n&&(this.heapArray[e]=a)},r.prototype._sortNodeUp=function(e){for(var t=this.heapArray[e],n=e;e>0;){var a=r.getParentIndexOf(e);if(this.compare(t,this.heapArray[a])<0)this.heapArray[e]=this.heapArray[a],e=a;else break}e!==n&&(this.heapArray[e]=t)},r.prototype._topN_push=function(e){var t=new r(this._invertedCompare);t.limit=e;for(var n=[0],a=this.heapArray;n.length;){var i=n.shift();i<a.length&&(t.length<e?(t.push(a[i]),n.push.apply(n,E([],v(r.getChildrenIndexOf(i)),!1))):this.compare(a[i],t.peek())<0&&(t.replace(a[i]),n.push.apply(n,E([],v(r.getChildrenIndexOf(i)),!1))))}return t.toArray()},r.prototype._topN_fill=function(e){var t=this.heapArray,n=new r(this._invertedCompare);n.limit=e,n.heapArray=t.slice(0,e),n.init();for(var a=r.getParentIndexOf(e-1)+1,i=[],f=a;f<e;++f)i.push.apply(i,E([],v(r.getChildrenIndexOf(f).filter(function(g){return g<t.length})),!1));for((e-1)%2&&i.push(e);i.length;){var f=i.shift();f<t.length&&this.compare(t[f],n.peek())<0&&(n.replace(t[f]),i.push.apply(i,E([],v(r.getChildrenIndexOf(f)),!1)))}return n.toArray()},r.prototype._topN_heap=function(e){for(var t=this.clone(),n=[],a=0;a<e;++a)n.push(t.pop());return n},r.prototype._topIdxOf=function(e){if(!e.length)return-1;for(var t=0,n=e[t],a=1;a<e.length;++a){var i=this.compare(e[a],n);i<0&&(t=a,n=e[a])}return t},r.prototype._topOf=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];var n=new r(this.compare);return n.init(e),n.peek()},r})();o.Heap=_,o.HeapAsync=p,o.default=_,o.toInt=S,Object.defineProperty(o,"__esModule",{value:!0})}))});import{McpServer as at}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as ct}from"@modelcontextprotocol/sdk/server/stdio.js";import{StreamableHTTPServerTransport as je}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as Pe}from"@modelcontextprotocol/sdk/types.js";import{z as J}from"zod";import z from"express";import{createServer as ut}from"node:https";import{readFileSync as Me}from"node:fs";import{randomUUID as Ue}from"node:crypto";import*as $e from"node:path";import{DatabaseSync as Ve}from"node:sqlite";import*as j from"path";import*as Z from"os";var M=class{db;constructor(s){this.db=s}query(s,...c){let u=this.db.prepare(s);return c.length===1&&Array.isArray(c[0])?u.all(...c[0]):c.length>0?u.all(...c):u.all()}execute(s,...c){let u=this.db.prepare(s);return c.length===1&&Array.isArray(c[0])?u.run(...c[0]):c.length>0?u.run(...c):u.run()}beginTransaction(){this.db.exec("BEGIN")}commit(){this.db.exec("COMMIT")}rollback(){this.db.exec("ROLLBACK")}close(){}},D=class{id;priority;category;name;description;steps;passes;in_progress;dependencies;constructor(s){this.id=s.id??0,this.priority=s.priority??999,this.category=s.category??"",this.name=s.name??"",this.description=s.description??"",this.steps=s.steps??[],this.passes=s.passes??!1,this.in_progress=s.in_progress??!1,this.dependencies=s.dependencies??null}to_dict(){return{id:this.id,priority:this.priority,category:this.category,name:this.name,description:this.description,steps:this.steps,passes:this.passes??!1,in_progress:this.in_progress??!1,dependencies:this.dependencies??[]}}get_dependencies_safe(){return this.dependencies===null?[]:Array.isArray(this.dependencies)?this.dependencies.filter(s=>typeof s=="number"):[]}};function ee(o){let s=o||process.cwd();return j.join(s,"features.db")}function Qe(o){o.prepare("PRAGMA table_info(features)").all().map(u=>u.name).includes("in_progress")||o.exec("ALTER TABLE features ADD COLUMN in_progress BOOLEAN DEFAULT 0")}function Ze(o){o.exec("UPDATE features SET passes = 0 WHERE passes IS NULL"),o.exec("UPDATE features SET in_progress = 0 WHERE in_progress IS NULL")}function et(o){o.prepare("PRAGMA table_info(features)").all().map(u=>u.name).includes("dependencies")||o.exec("ALTER TABLE features ADD COLUMN dependencies TEXT DEFAULT NULL")}function te(o){let s=j.resolve(o);if(Z.platform()==="win32"){if(s.startsWith("\\\\"))return!0}else try{let u=We("fs").readFileSync("/proc/mounts","utf-8");for(let l of u.split(` | |
| `)){let d=l.split(/\s+/);if(d.length>=3){let p=d[1],y=d[2];if(s.startsWith(p)&&["nfs","nfs4","cifs","smbfs","fuse.sshfs"].includes(y))return!0}}}catch{}return!1}function tt(o){o.exec(` | |
| CREATE TABLE IF NOT EXISTS schedules ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| project_name TEXT NOT NULL, | |
| start_time TEXT NOT NULL, | |
| duration_minutes INTEGER NOT NULL, | |
| days_of_week INTEGER NOT NULL DEFAULT 127, | |
| enabled BOOLEAN NOT NULL DEFAULT 1, | |
| yolo_mode BOOLEAN NOT NULL DEFAULT 0, | |
| model TEXT, | |
| max_concurrency INTEGER NOT NULL DEFAULT 3, | |
| crash_count INTEGER NOT NULL DEFAULT 0, | |
| created_at TEXT NOT NULL, | |
| CHECK (duration_minutes >= 1 AND duration_minutes <= 1440), | |
| CHECK (days_of_week >= 0 AND days_of_week <= 127), | |
| CHECK (max_concurrency >= 1 AND max_concurrency <= 5), | |
| CHECK (crash_count >= 0) | |
| ) | |
| `),o.exec("CREATE INDEX IF NOT EXISTS ix_schedules_project_name ON schedules(project_name)"),o.exec("CREATE INDEX IF NOT EXISTS ix_schedules_enabled ON schedules(enabled)"),o.exec(` | |
| CREATE TABLE IF NOT EXISTS schedule_overrides ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| schedule_id INTEGER NOT NULL, | |
| override_type TEXT NOT NULL, | |
| expires_at TEXT NOT NULL, | |
| created_at TEXT NOT NULL, | |
| FOREIGN KEY (schedule_id) REFERENCES schedules(id) ON DELETE CASCADE | |
| ) | |
| `);let c=o.prepare("PRAGMA table_info(schedules)").all().map(u=>u.name);c.includes("crash_count")||o.exec("ALTER TABLE schedules ADD COLUMN crash_count INTEGER DEFAULT 0"),c.includes("max_concurrency")||o.exec("ALTER TABLE schedules ADD COLUMN max_concurrency INTEGER DEFAULT 3")}function F(o){let s=o||ee(),c=new Ve(s,{timeout:3e4});c.exec(` | |
| CREATE TABLE IF NOT EXISTS features ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| priority INTEGER NOT NULL DEFAULT 999, | |
| category TEXT NOT NULL, | |
| name TEXT NOT NULL, | |
| description TEXT NOT NULL, | |
| steps TEXT NOT NULL, | |
| passes BOOLEAN NOT NULL DEFAULT 0, | |
| in_progress BOOLEAN NOT NULL DEFAULT 0, | |
| dependencies TEXT DEFAULT NULL | |
| ) | |
| `),c.exec("CREATE INDEX IF NOT EXISTS ix_features_priority ON features(priority)"),c.exec("CREATE INDEX IF NOT EXISTS ix_features_passes ON features(passes)"),c.exec("CREATE INDEX IF NOT EXISTS ix_features_in_progress ON features(in_progress)"),c.exec("CREATE INDEX IF NOT EXISTS ix_feature_status ON features(passes, in_progress)");let l=te(s)?"DELETE":"WAL";return c.exec(`PRAGMA journal_mode = ${l}`),Qe(c),Ze(c),et(c),tt(c),{engine:c,session_maker:()=>new M(c)}}var nt=Ke(ne(),1);function U(o,s,c){if(s===c)return!0;let u=new Map(o.map(v=>[v.id,v])),l=u.get(s),d=u.get(c);if(!l||!d)return!1;let p=new Set;function y(v,E=0){if(E>50||v===s)return!0;if(p.has(v))return!1;p.add(v);let S=u.get(v);if(!S)return!1;let _=S.dependencies||[];for(let r of _)if(y(r,E+1))return!0;return!1}return y(c)}function Y(o){if(o.length===0)return new Map;let s=new Map(o.map(_=>[_.id,[]])),c=new Map(o.map(_=>[_.id,[]]));for(let _ of o){let r=_.dependencies||[];for(let e of r)s.has(e)&&(s.get(e).push(_.id),c.get(_.id).push(e))}let u=new Map,d=o.filter(_=>(c.get(_.id)||[]).length===0).map(_=>_.id).map(_=>[_,0]);for(;d.length>0;){let[_,r]=d.shift();(!u.has(_)||r>u.get(_))&&u.set(_,r);for(let e of s.get(_)||[])d.push([e,r+1])}for(let _ of o)u.has(_.id)||u.set(_.id,0);let p=new Map(o.map(_=>[_.id,0])),y=[...u.keys()].sort((_,r)=>(u.get(r)||0)-(u.get(_)||0));for(let _ of y)for(let r of c.get(_)||[])p.set(r,(p.get(r)||0)+1+(p.get(_)||0));let v=Math.max(...u.values()),E=Math.max(...p.values()),S=new Map;for(let _ of o){let r=_.id,e=E>0?(p.get(r)||0)/E:0,t=v>0?1-(u.get(r)||0)/v:1,n=_.priority,a=(10-Math.min(n,10))/10;S.set(r,1e3*e+100*t+10*a)}return S}import*as C from"fs";import*as L from"path";function K(o,s){let c=o||process.cwd(),u=L.join(c,"feature_list.json");if(!C.existsSync(u))return!1;let{session_maker:l}=s?{session_maker:s}:F(L.join(c,"features.db")),d=l();try{let S=d.query("SELECT COUNT(*) as count FROM features")[0]?.count||0;if(S>0)return console.log(`Database already has ${S} features, skipping migration`),!1}finally{d.close()}let p;try{let S=C.readFileSync(u,"utf-8");p=JSON.parse(S)}catch(S){return S instanceof Error&&console.error(`Error parsing feature_list.json: ${S.message}`),!1}if(!Array.isArray(p))return console.error("Error: feature_list.json must contain a JSON array"),!1;let y=l();try{y.beginTransaction();let S=0;for(let r=0;r<p.length;r++){let e=p[r],t=new D({id:e.id??r+1,priority:e.priority??r+1,category:e.category??"uncategorized",name:e.name??`Feature ${r+1}`,description:e.description??"",steps:e.steps??[],passes:e.passes??!1,in_progress:e.in_progress??!1,dependencies:e.dependencies??null}),n=JSON.stringify(t.steps),a=t.dependencies?JSON.stringify(t.dependencies):null;y.execute(`INSERT INTO features (id, priority, category, name, description, steps, passes, in_progress, dependencies) | |
| VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,t.id,t.priority,t.category,t.name,t.description,n,t.passes?1:0,t.in_progress?1:0,a),S++}y.commit();let _=y.query("SELECT COUNT(*) as count FROM features")[0]?.count||0;console.log(`Migrated ${_} features from JSON to SQLite`)}catch(S){return y.rollback(),S instanceof Error&&console.error(`Error during migration: ${S.message}`),!1}finally{y.close()}let v=new Date().toISOString().replace(/[-:]/g,"").replace(/\..+/,"").replace("T","_"),E=L.join(c,`feature_list.json.backup.${v}`);try{C.renameSync(u,E),console.log(`Original JSON backed up to: ${L.basename(E)}`)}catch(S){S instanceof Error&&console.warn(`Warning: Could not backup JSON file: ${S.message}`)}return!0}import*as w from"node:fs";import*as V from"node:path";import*as ie from"node:os";var $=V.join(ie.tmpdir(),"feature-priority.lock"),se=5e3,st=50,H=null;function B(){let o=Date.now();for(;;)try{H=w.openSync($,"wx");return}catch(s){if(s.code==="EEXIST"){if(Date.now()-o>=se){try{let u=w.statSync($);if(Date.now()-u.mtimeMs>se){w.unlinkSync($);continue}}catch{}throw new Error("Failed to acquire priority lock: timeout")}it(st)}else throw new Error(`Failed to acquire priority lock: ${s.message}`)}}function q(){if(H!==null)try{w.closeSync(H),H=null}catch{}try{w.unlinkSync($)}catch{}}function it(o){let s=Date.now()+o;for(;Date.now()<s;);}var X=null,G=null;function oe(o){let{engine:s,session_maker:c}=F(o);G=s,X=c;let u=process.cwd();K(u,c)}function W(){G&&(G.close(),G=null,X=null)}function x(){if(!X)throw new Error("Database not initialized");return X()}function ae(){let o=x();try{let s=o.query("SELECT passes, in_progress FROM features"),c=s.length,u=s.filter(p=>p.passes).length,l=s.filter(p=>p.in_progress).length,d=c>0?Math.round(u/c*100*10)/10:0;return JSON.stringify({passing:u,in_progress:l,total:c,percentage:d})}finally{o.close()}}function ce(o){let s=x();try{let c=s.query("SELECT * FROM features WHERE id = ?",o);if(c.length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});let u=c[0],l={id:u.id,priority:u.priority,category:u.category,name:u.name,description:u.description,steps:JSON.parse(u.steps||"[]"),passes:!!u.passes,in_progress:!!u.in_progress,dependencies:u.dependencies?JSON.parse(u.dependencies):null};return JSON.stringify(l)}finally{s.close()}}function ue(o){let s=x();try{let c=s.query("SELECT id, name, passes, in_progress, dependencies FROM features WHERE id = ?",[o]);if(c.length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});let u=c[0];return JSON.stringify({id:u.id,name:u.name,passes:!!u.passes,in_progress:!!u.in_progress,dependencies:u.dependencies?JSON.parse(u.dependencies):[]})}finally{s.close()}}function pe(o){let s=x();try{let c=s.query("SELECT id, name FROM features WHERE id = ?",o);return c.length===0?JSON.stringify({error:`Feature with ID ${o} not found`}):(s.execute("UPDATE features SET passes = ?, in_progress = ? WHERE id = ?",1,0,o),JSON.stringify({success:!0,feature_id:o,name:c[0].name}))}catch(c){return JSON.stringify({error:`Failed to mark feature passing: ${c}`})}finally{s.close()}}function le(o){let s=x();try{if(s.query("SELECT * FROM features WHERE id = ?",o).length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});s.execute("UPDATE features SET passes = ?, in_progress = ? WHERE id = ?",0,0,o);let u=s.query("SELECT * FROM features WHERE id = ?",[o])[0],l={id:u.id,priority:u.priority,category:u.category,name:u.name,description:u.description,steps:JSON.parse(u.steps||"[]"),passes:!!u.passes,in_progress:!!u.in_progress,dependencies:u.dependencies?JSON.parse(u.dependencies):null};return JSON.stringify({message:`Feature #${o} marked as failing - regression detected`,feature:l})}catch(c){return JSON.stringify({error:`Failed to mark feature failing: ${c}`})}finally{s.close()}}function fe(o){let s=x();try{let c=s.query("SELECT * FROM features WHERE id = ?",o);if(c.length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});let u=c[0];if(u.passes)return JSON.stringify({error:"Cannot skip a feature that is already passing"});let l=u.priority;B();try{let p=(s.query("SELECT MAX(priority) as max_priority FROM features")[0]?.max_priority??0)+1;return s.execute("UPDATE features SET priority = ?, in_progress = ? WHERE id = ?",p,0,o),JSON.stringify({id:o,name:u.name,old_priority:l,new_priority:p,message:`Feature '${u.name}' moved to end of queue`})}finally{q()}}catch(c){return JSON.stringify({error:`Failed to skip feature: ${c}`})}finally{s.close()}}function de(o){let s=x();try{let c=s.query("SELECT * FROM features WHERE id = ?",o);if(c.length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});let u=c[0];if(u.passes)return JSON.stringify({error:`Feature with ID ${o} is already passing`});if(u.in_progress)return JSON.stringify({error:`Feature with ID ${o} is already in-progress`});s.execute("UPDATE features SET in_progress = ? WHERE id = ?",1,o);let l=s.query("SELECT * FROM features WHERE id = ?",o)[0],d={id:l.id,priority:l.priority,category:l.category,name:l.name,description:l.description,steps:JSON.parse(l.steps||"[]"),passes:!!l.passes,in_progress:!!l.in_progress,dependencies:l.dependencies?JSON.parse(l.dependencies):null};return JSON.stringify(d)}catch(c){return JSON.stringify({error:`Failed to mark feature in-progress: ${c}`})}finally{s.close()}}function he(o){let s=x();try{let c=s.query("SELECT * FROM features WHERE id = ?",o);if(c.length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});let u=c[0];if(u.passes)return JSON.stringify({error:`Feature with ID ${o} is already passing`});let l=!!u.in_progress;l||s.execute("UPDATE features SET in_progress = ? WHERE id = ?",1,o);let d=s.query("SELECT * FROM features WHERE id = ?",[o])[0],p={id:d.id,priority:d.priority,category:d.category,name:d.name,description:d.description,steps:JSON.parse(d.steps||"[]"),passes:!!d.passes,in_progress:!!d.in_progress,dependencies:d.dependencies?JSON.parse(d.dependencies):null,already_claimed:l};return JSON.stringify(p)}catch(c){return JSON.stringify({error:`Failed to claim feature: ${c}`})}finally{s.close()}}function ye(o){let s=x();try{if(s.query("SELECT * FROM features WHERE id = ?",o).length===0)return JSON.stringify({error:`Feature with ID ${o} not found`});s.execute("UPDATE features SET in_progress = ? WHERE id = ?",0,o);let u=s.query("SELECT * FROM features WHERE id = ?",[o])[0],l={id:u.id,priority:u.priority,category:u.category,name:u.name,description:u.description,steps:JSON.parse(u.steps||"[]"),passes:!!u.passes,in_progress:!!u.in_progress,dependencies:u.dependencies?JSON.parse(u.dependencies):null};return JSON.stringify(l)}catch(c){return JSON.stringify({error:`Failed to clear in-progress status: ${c}`})}finally{s.close()}}function ge(o){let s=x();try{for(let c=0;c<o.length;c++){let u=o[c];if(!u.category||!u.name||!u.description||!u.steps)return JSON.stringify({error:`Feature at index ${c} missing required fields (category, name, description, steps)`});let l=u.depends_on_indices||[];if(l.length>0){if(l.length>20)return JSON.stringify({error:`Feature at index ${c} has ${l.length} dependencies, max is ${20}`});if(new Set(l).size!==l.length)return JSON.stringify({error:`Feature at index ${c} has duplicate dependencies`});for(let d of l){if(!Number.isInteger(d)||d<0)return JSON.stringify({error:`Feature at index ${c} has invalid dependency index: ${d}`});if(d>=c)return JSON.stringify({error:`Feature at index ${c} cannot depend on feature at index ${d} (forward reference not allowed)`})}}}B();try{let u=(s.query("SELECT MAX(priority) as max_priority FROM features")[0]?.max_priority??0)+1,l=[];for(let p=0;p<o.length;p++){let y=o[p];s.execute("INSERT INTO features (priority, category, name, description, steps, passes, in_progress, dependencies) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",[u+p,y.category,y.name,y.description,JSON.stringify(y.steps),0,0,null]);let v=s.query("SELECT last_insert_rowid() as id");l.push(v[0].id)}let d=0;for(let p=0;p<o.length;p++){let y=o[p].depends_on_indices||[];if(y.length>0){let v=y.map(E=>l[E]).sort((E,S)=>E-S);s.execute("UPDATE features SET dependencies = ? WHERE id = ?",[JSON.stringify(v),l[p]]),d++}}return JSON.stringify({created:l.length,with_dependencies:d})}finally{q()}}catch(c){return JSON.stringify({error:String(c)})}finally{s.close()}}function me(o,s,c,u){let l=x();try{B();try{let p=(l.query("SELECT MAX(priority) as max_priority FROM features")[0]?.max_priority??0)+1;l.execute("INSERT INTO features (priority, category, name, description, steps, passes, in_progress, dependencies) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",[p,o,s,c,JSON.stringify(u),0,0,null]);let v=l.query("SELECT last_insert_rowid() as id")[0].id,S=l.query("SELECT * FROM features WHERE id = ?",v)[0],_={id:S.id,priority:S.priority,category:S.category,name:S.name,description:S.description,steps:JSON.parse(S.steps||"[]"),passes:!!S.passes,in_progress:!!S.in_progress,dependencies:S.dependencies?JSON.parse(S.dependencies):null};return JSON.stringify({success:!0,message:`Created feature: ${s}`,feature:_})}finally{q()}}catch(d){return JSON.stringify({error:String(d)})}finally{l.close()}}function _e(o,s){let c=x();try{if(o===s)return JSON.stringify({error:"A feature cannot depend on itself"});let u=c.query("SELECT * FROM features WHERE id = ?",o),l=c.query("SELECT * FROM features WHERE id = ?",s);if(u.length===0)return JSON.stringify({error:`Feature ${o} not found`});if(l.length===0)return JSON.stringify({error:`Dependency feature ${s} not found`});let d=u[0],p=d.dependencies?JSON.parse(d.dependencies):[];if(p.length>=20)return JSON.stringify({error:`Maximum ${20} dependencies allowed per feature`});if(p.includes(s))return JSON.stringify({error:"Dependency already exists"});let v=c.query("SELECT * FROM features").map(S=>({id:S.id,priority:S.priority,category:S.category,name:S.name,description:S.description,steps:JSON.parse(S.steps||"[]"),passes:!!S.passes,in_progress:!!S.in_progress,dependencies:S.dependencies?JSON.parse(S.dependencies):null}));if(U(v,o,s))return JSON.stringify({error:"Cannot add: would create circular dependency"});p.push(s);let E=p.sort((S,_)=>S-_);return c.execute("UPDATE features SET dependencies = ? WHERE id = ?",JSON.stringify(E),o),JSON.stringify({success:!0,feature_id:o,dependencies:E})}catch(u){return JSON.stringify({error:`Failed to add dependency: ${u}`})}finally{c.close()}}function Ee(o,s){let c=x();try{let u=c.query("SELECT * FROM features WHERE id = ?",o);if(u.length===0)return JSON.stringify({error:`Feature ${o} not found`});let l=u[0],d=l.dependencies?JSON.parse(l.dependencies):[];if(!d.includes(s))return JSON.stringify({error:"Dependency does not exist"});let p=d.filter(v=>v!==s),y=p.length>0?JSON.stringify(p):null;return c.execute("UPDATE features SET dependencies = ? WHERE id = ?",y,o),JSON.stringify({success:!0,feature_id:o,dependencies:p})}catch(u){return JSON.stringify({error:`Failed to remove dependency: ${u}`})}finally{c.close()}}function Se(o=10){let s=x();try{let u=s.query("SELECT * FROM features").map(y=>({id:y.id,priority:y.priority,category:y.category,name:y.name,description:y.description,steps:JSON.parse(y.steps||"[]"),passes:!!y.passes,in_progress:!!y.in_progress,dependencies:y.dependencies?JSON.parse(y.dependencies):null})),l=new Set(u.filter(y=>y.passes).map(y=>y.id)),d=[];for(let y of u){if(y.passes||y.in_progress)continue;(y.dependencies||[]).every(E=>l.has(E))&&d.push(y)}let p=Y(u);return d.sort((y,v)=>{let E=p.get(y.id)??0,S=p.get(v.id)??0;return E!==S?S-E:y.priority!==v.priority?y.priority-v.priority:y.id-v.id}),JSON.stringify({features:d.slice(0,o),count:Math.min(d.length,o),total_ready:d.length})}finally{s.close()}}function ve(o=20){let s=x();try{let u=s.query("SELECT * FROM features").map(p=>({id:p.id,priority:p.priority,category:p.category,name:p.name,description:p.description,steps:JSON.parse(p.steps||"[]"),passes:!!p.passes,in_progress:!!p.in_progress,dependencies:p.dependencies?JSON.parse(p.dependencies):null})),l=new Set(u.filter(p=>p.passes).map(p=>p.id)),d=[];for(let p of u){if(p.passes)continue;let v=(p.dependencies||[]).filter(E=>!l.has(E));v.length>0&&d.push({...p,blocked_by:v})}return JSON.stringify({features:d.slice(0,o),count:Math.min(d.length,o),total_blocked:d.length})}finally{s.close()}}function Ae(){let o=x();try{let c=o.query("SELECT * FROM features").map(p=>({id:p.id,priority:p.priority,category:p.category,name:p.name,description:p.description,steps:JSON.parse(p.steps||"[]"),passes:!!p.passes,in_progress:!!p.in_progress,dependencies:p.dependencies?JSON.parse(p.dependencies):null})),u=new Set(c.filter(p=>p.passes).map(p=>p.id)),l=[],d=[];for(let p of c){let y=p.dependencies||[],v=y.filter(S=>!u.has(S)),E;p.passes?E="done":v.length>0?E="blocked":p.in_progress?E="in_progress":E="pending",l.push({id:p.id,name:p.name,category:p.category,status:E,priority:p.priority,dependencies:y});for(let S of y)d.push({source:S,target:p.id})}return JSON.stringify({nodes:l,edges:d})}finally{o.close()}}function be(o,s){let c=x();try{if(s.includes(o))return JSON.stringify({error:"A feature cannot depend on itself"});if(s.length>20)return JSON.stringify({error:`Maximum ${20} dependencies allowed`});if(new Set(s).size!==s.length)return JSON.stringify({error:"Duplicate dependencies not allowed"});if(c.query("SELECT * FROM features WHERE id = ?",o).length===0)return JSON.stringify({error:`Feature ${o} not found`});let l=c.query("SELECT * FROM features"),d=new Set(l.map(_=>_.id)),p=s.filter(_=>!d.has(_));if(p.length>0)return JSON.stringify({error:`Dependencies not found: ${JSON.stringify(p)}`});let v=l.map(_=>({id:_.id,priority:_.priority,category:_.category,name:_.name,description:_.description,steps:JSON.parse(_.steps||"[]"),passes:!!_.passes,in_progress:!!_.in_progress,dependencies:_.dependencies?JSON.parse(_.dependencies):null})).map(_=>_.id===o?{..._,dependencies:s}:_);for(let _ of s)if(U(v,o,_))return JSON.stringify({error:`Cannot add dependency ${_}: would create circular dependency`});let E=s.length>0?[...s].sort((_,r)=>_-r):[],S=E.length>0?JSON.stringify(E):null;return c.execute("UPDATE features SET dependencies = ? WHERE id = ?",S,o),JSON.stringify({success:!0,feature_id:o,dependencies:E})}catch(u){return JSON.stringify({error:`Failed to set dependencies: ${u}`})}finally{c.close()}}import{z as m}from"zod";var Oe=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to mark as passing")}),Ne=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to mark as failing")}),xe=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to skip")}),Te=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to mark as in-progress")}),we=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to clear in-progress status")}),ar=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to retrieve")}),Ie=m.object({feature_id:m.number().int().min(1).describe("The ID of the feature to claim")}),ot=m.object({category:m.string().min(1).max(100).describe("Feature category"),name:m.string().min(1).max(255).describe("Feature name"),description:m.string().min(1).describe("Detailed description"),steps:m.array(m.string()).min(1).describe("Implementation/test steps"),depends_on_indices:m.array(m.number().int().min(0)).optional().describe("Array indices of features in batch that this feature depends on")}),Ce=m.object({features:m.array(ot).min(1).describe("List of features to create")}),Le=m.object({category:m.string().min(1).max(100).describe('Feature category (e.g., "Authentication", "API", "UI")'),name:m.string().min(1).max(255).describe("Feature name"),description:m.string().min(1).describe("Detailed description of the feature"),steps:m.array(m.string()).min(1).describe("List of implementation/verification steps")}),Re=m.object({feature_id:m.number().int().min(1).describe("Feature to add dependency to"),dependency_id:m.number().int().min(1).describe("ID of the dependency feature")}),ke=m.object({feature_id:m.number().int().min(1).describe("Feature to remove dependency from"),dependency_id:m.number().int().min(1).describe("ID of dependency to remove")}),De=m.object({feature_id:m.number().int().min(1).describe("Feature to set dependencies for"),dependency_ids:m.array(m.number().int().min(1)).describe("List of dependency feature IDs")}),Fe=m.object({limit:m.number().int().min(1).max(50).default(10).describe("Max features to return")}),Je=m.object({limit:m.number().int().min(1).max(100).default(20).describe("Max features to return")}),cr=m.object({id:m.number(),priority:m.number(),category:m.string(),name:m.string(),description:m.string(),steps:m.array(m.string()),passes:m.boolean(),in_progress:m.boolean(),dependencies:m.array(m.number()).nullable()}),ur=m.object({passing:m.number(),in_progress:m.number(),total:m.number(),percentage:m.number()}),pr=m.object({success:m.boolean(),feature_id:m.number().optional(),name:m.string().optional(),message:m.string().optional()}),lr=m.object({error:m.string()});var pt=process.env.PROJECT_DIR||".",lt=$e.join(pt,"features.db");oe(lt);var O=new at({name:"features",version:"1.0.0"});O.registerTool("feature_get_stats",{title:"Get Feature Statistics",description:"Get statistics about feature completion progress. Returns passing, in-progress, total, and percentage.",inputSchema:J.object({})},async()=>{let o=ae();return{content:[{type:"text",text:o}],structuredContent:JSON.parse(o)}});O.registerTool("feature_get_by_id",{title:"Get Feature By ID",description:"Get a specific feature by its ID with full details",inputSchema:J.object({feature_id:J.number().int().min(1).describe("The ID of the feature to retrieve")})},async({feature_id:o})=>{let s=ce(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_get_summary",{title:"Get Feature Summary",description:"Get minimal feature info: id, name, status, and dependencies only",inputSchema:J.object({feature_id:J.number().int().min(1).describe("The ID of the feature")})},async({feature_id:o})=>{let s=ue(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_mark_passing",{title:"Mark Feature as Passing",description:"Mark a feature as passing after successful implementation",inputSchema:Oe},async({feature_id:o})=>{let s=pe(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_mark_failing",{title:"Mark Feature as Failing",description:"Mark a feature as failing after finding a regression",inputSchema:Ne},async({feature_id:o})=>{let s=le(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_skip",{title:"Skip Feature",description:"Skip a feature by moving it to the end of the priority queue",inputSchema:xe},async({feature_id:o})=>{let s=fe(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_mark_in_progress",{title:"Mark Feature In Progress",description:"Mark a feature as in-progress to prevent other agents from working on it",inputSchema:Te},async({feature_id:o})=>{let s=de(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_claim_and_get",{title:"Claim and Get Feature",description:"Atomically claim a feature (mark in-progress) and return its full details",inputSchema:Ie},async({feature_id:o})=>{let s=he(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_clear_in_progress",{title:"Clear In Progress Status",description:"Clear in-progress status from a feature",inputSchema:we},async({feature_id:o})=>{let s=ye(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_create_bulk",{title:"Create Multiple Features",description:"Create multiple features in a single operation with dependencies",inputSchema:Ce},async({features:o})=>{let s=ge(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_create",{title:"Create Single Feature",description:"Create a single feature in the project backlog",inputSchema:Le},async({category:o,name:s,description:c,steps:u})=>{let l=me(o,s,c,u);return{content:[{type:"text",text:l}],structuredContent:JSON.parse(l)}});O.registerTool("feature_add_dependency",{title:"Add Dependency",description:"Add a dependency relationship between features",inputSchema:Re},async({feature_id:o,dependency_id:s})=>{let c=_e(o,s);return{content:[{type:"text",text:c}],structuredContent:JSON.parse(c)}});O.registerTool("feature_remove_dependency",{title:"Remove Dependency",description:"Remove a dependency from a feature",inputSchema:ke},async({feature_id:o,dependency_id:s})=>{let c=Ee(o,s);return{content:[{type:"text",text:c}],structuredContent:JSON.parse(c)}});O.registerTool("feature_get_ready",{title:"Get Ready Features",description:"Get all features ready to start (dependencies satisfied, not in progress)",inputSchema:Fe},async({limit:o=10})=>{let s=Se(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_get_blocked",{title:"Get Blocked Features",description:"Get features that are blocked by unmet dependencies",inputSchema:Je},async({limit:o=20})=>{let s=ve(o);return{content:[{type:"text",text:s}],structuredContent:JSON.parse(s)}});O.registerTool("feature_get_graph",{title:"Get Dependency Graph",description:"Get dependency graph data for visualization",inputSchema:{}},async()=>{let o=Ae();return{content:[{type:"text",text:o}],structuredContent:JSON.parse(o)}});O.registerTool("feature_set_dependencies",{title:"Set All Dependencies",description:"Set all dependencies for a feature at once, replacing any existing dependencies",inputSchema:De},async({feature_id:o,dependency_ids:s})=>{let c=be(o,s);return{content:[{type:"text",text:c}],structuredContent:JSON.parse(c)}});function ft(){let o=process.argv.slice(2),s="stdio",c=8080,u,l;for(let d=0;d<o.length;d++){let p=o[d];p==="--http"?s="http":p==="--https"?s="https":p==="--port"&&d+1<o.length?(c=parseInt(o[d+1],10),d++):p==="--cert"&&d+1<o.length?(u=o[d+1],d++):p==="--key"&&d+1<o.length&&(l=o[d+1],d++)}return{mode:s,port:c,certPath:u,keyPath:l}}async function dt(){let o=new ct;await O.connect(o),console.error("MCP server running on stdio")}async function ht(o){let s=z();s.use(z.json());let c={};s.post("/mcp",async(u,l)=>{let d=u.headers["mcp-session-id"],p;if(d&&c[d])p=c[d];else if(!d&&Pe(u.body))p=new je({sessionIdGenerator:()=>Ue(),onsessioninitialized:y=>{c[y]=p,console.error("Session initialized:",y)},onsessionclosed:y=>{delete c[y],console.error("Session closed:",y)}}),p.onclose=()=>{p.sessionId&&delete c[p.sessionId]},await O.connect(p);else{l.status(400).json({jsonrpc:"2.0",error:{code:-32e3,message:"Invalid session"},id:null});return}await p.handleRequest(u,l,u.body)}),s.get("/mcp",async(u,l)=>{let d=u.headers["mcp-session-id"],p=c[d];p?await p.handleRequest(u,l):l.status(400).send("Invalid session")}),s.delete("/mcp",async(u,l)=>{let d=u.headers["mcp-session-id"],p=c[d];p?await p.handleRequest(u,l):l.status(400).send("Invalid session")}),s.listen(o,()=>{console.error(`MCP server running on http://localhost:${o}/mcp`)})}async function yt(o,s,c){if(!s||!c)throw new Error("HTTPS mode requires --cert and --key arguments");let u=z();u.use(z.json());let l={};u.post("/mcp",async(p,y)=>{let v=p.headers["mcp-session-id"],E;if(v&&l[v])E=l[v];else if(!v&&Pe(p.body))E=new je({sessionIdGenerator:()=>Ue(),onsessioninitialized:S=>{l[S]=E,console.error("Session initialized:",S)},onsessionclosed:S=>{delete l[S],console.error("Session closed:",S)}}),E.onclose=()=>{E.sessionId&&delete l[E.sessionId]},await O.connect(E);else{y.status(400).json({jsonrpc:"2.0",error:{code:-32e3,message:"Invalid session"},id:null});return}await E.handleRequest(p,y,p.body)}),u.get("/mcp",async(p,y)=>{let v=p.headers["mcp-session-id"],E=l[v];E?await E.handleRequest(p,y):y.status(400).send("Invalid session")}),u.delete("/mcp",async(p,y)=>{let v=p.headers["mcp-session-id"],E=l[v];E?await E.handleRequest(p,y):y.status(400).send("Invalid session")}),ut({cert:Me(s),key:Me(c)},u).listen(o,()=>{console.error(`MCP server running on https://localhost:${o}/mcp`)})}async function gt(){let{mode:o,port:s,certPath:c,keyPath:u}=ft();process.on("SIGINT",()=>{W(),process.exit(0)}),process.on("SIGTERM",()=>{W(),process.exit(0)}),o==="http"?await ht(s):o==="https"?await yt(s,c,u):await dt()}gt().catch(o=>{console.error("Server error:",o),W(),process.exit(1)}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "servers": { | |
| "gcapnias/feature-mcp-server": { | |
| "type": "stdio", | |
| "command": "npx", | |
| "args": [ | |
| "-y", | |
| "https://gist.github.com/gcapnias/e04577c11a78f02dc76f6e298f87c6ad" | |
| ], | |
| "cwd": "./" | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "@gcapnias/tasks-mcp-server", | |
| "version": "0.0.1", | |
| "type": "module", | |
| "bin": { | |
| "tasks-mcp-server": "index.js" | |
| }, | |
| "scripts": { | |
| "build": "esbuild src/index.ts --platform=node --format=esm --banner:js=\"#!/usr/bin/env node\" --outfile=dist/index.js && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"", | |
| "dev": "pnpm build --watch", | |
| "start": "node dist/index.js", | |
| "clean": "rm -rf dist", | |
| "test": "vitest run", | |
| "test:watch": "vitest" | |
| }, | |
| "dependencies": { | |
| "@modelcontextprotocol/sdk": "^1.26.0", | |
| "@types/express": "5.0.6", | |
| "express": "5.2.1", | |
| "zod": "^4.3.6" | |
| }, | |
| "devDependencies": { | |
| "@types/node": "^25.2.3", | |
| "esbuild": "^0.27.3", | |
| "typescript": "^5.9.3", | |
| "vitest": "^4.0.18" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment