@grum-os/cli 0.3.5 → 0.3.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.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <img src="brand.svg" alt="Grum" width="228" height="64" />
1
+ <img src="https://cdn.jsdelivr.net/npm/@grum-os/cli/brand.png" alt="Grum" width="228" height="64" />
2
2
 
3
3
  # Grum
4
4
 
@@ -19,7 +19,7 @@ npx @grum-os/cli
19
19
  Grum opens a wizard. The arrow keys move, Enter selects, and 1, 2, or 3 jump straight to a row. `q` quits.
20
20
 
21
21
  ```text
22
- 1 check Check this repository against its design contract
22
+ 1 check Check your changes against the design contract
23
23
  2 setup Sign in, link this repository, set up Cursor
24
24
  3 login Sign in to Grum
25
25
  ```
package/brand.png ADDED
Binary file
package/content.md5 CHANGED
@@ -1 +1 @@
1
- 78a3046bc5a5bb380da405ed25060485
1
+ 539becde0182054688c3ec1acae1a564
package/grum.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- globalThis.__GRUM_VERSION__="0.3.5";
2
+ globalThis.__GRUM_VERSION__="0.3.7";
3
3
  import{chmodSync as Gg,existsSync as It,rmSync as wo}from"node:fs";import B from"node:path";import{createInterface as qg,emitKeypressEvents as Vg}from"node:readline";import{fileURLToPath as Wg}from"node:url";var $o=(e,t,n)=>Math.min(n,Math.max(t,e)),Pt=e=>$o(Math.round(e),0,255).toString(16).padStart(2,"0").toUpperCase();function Fl({r:e,g:t,b:n,a:r}){let o=`#${Pt(e)}${Pt(t)}${Pt(n)}`,s=Math.round($o(r,0,1)*255);return s>=255?o:`${o}${Pt(s)}`}function Ul(e){let t=e.replace(/^#/,"");if(!/^[0-9a-f]+$/i.test(t)||![3,4,6,8].includes(t.length))return null;let n=t.length<=4?[...t].map(s=>s+s).join(""):t,r=parseInt(n.slice(0,6),16),o=n.length===8?parseInt(n.slice(6,8),16)/255:1;return{r:r>>16&255,g:r>>8&255,b:r&255,a:o}}function Lt(e,t){let n=e.trim();return n.endsWith("%")?parseFloat(n)/100*t:parseFloat(n)}function Bl(e,t,n){let r=s=>(s+e/30)%12,o=s=>n-t*Math.min(n,1-n)*Math.max(-1,Math.min(r(s)-3,9-r(s),1));return[o(0)*255,o(8)*255,o(4)*255]}function On(e){let t=e.trim().toLowerCase();if(t.startsWith("#"))return Ul(t);let n=t.match(/^(rgba?|hsla?)\(([^)]*)\)$/);if(!n?.[1]||n[2]==null)return null;let r=n[2].split(/[\s,/]+/).filter(Boolean);if(r.length<3)return null;let o=r[3]!=null?Lt(r[3],1):1;if(n[1].startsWith("rgb")){let[p,f,m]=r.slice(0,3).map(b=>Lt(b,255));return[p,f,m,o].some(Number.isNaN)?null:{r:p,g:f,b:m,a:o}}let s=parseFloat(r[0]),i=Lt(r[1],1),l=Lt(r[2],1);if([s,i,l,o].some(Number.isNaN))return null;let[a,c,u]=Bl((s%360+360)%360,i,l);return{r:a,g:c,b:u,a:o}}function pe(e){let t=On(e);return t?Fl(t):null}function Co({r:e,g:t,b:n}){let r=p=>{let f=p/255;return f<=.04045?f/12.92:((f+.055)/1.055)**2.4},[o,s,i]=[r(e),r(t),r(n)],l=(o*.4124+s*.3576+i*.1805)/.95047,a=o*.2126+s*.7152+i*.0722,c=(o*.0193+s*.1192+i*.9505)/1.08883,u=p=>p>.008856?Math.cbrt(p):7.787*p+16/116;return[116*u(a)-16,500*(u(l)-u(a)),200*(u(a)-u(c))]}function Nn(e){return`--color-${e.replace(/^#/,"").slice(0,6).toLowerCase()}`}function Mt(e,t){let n=On(e),r=On(t);if(!n||!r)return 1/0;let[o,s,i]=Co(n),[l,a,c]=Co(r);return Math.hypot(o-l,s-a,i-c)}var Fn=/#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3,4})\b|\b(?:rgba?|hsla?)\([^)]*\)/gi;var Un={slate:{50:"#f8fafc",100:"#f1f5f9",200:"#e2e8f0",300:"#cbd5e1",400:"#94a3b8",500:"#64748b",600:"#475569",700:"#334155",800:"#1e293b",900:"#0f172a",950:"#020617"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},zinc:{50:"#fafafa",100:"#f4f4f5",200:"#e4e4e7",300:"#d4d4d8",400:"#a1a1aa",500:"#71717a",600:"#52525b",700:"#3f3f46",800:"#27272a",900:"#18181b",950:"#09090b"},neutral:{50:"#fafafa",100:"#f5f5f5",200:"#e5e5e5",300:"#d4d4d4",400:"#a3a3a3",500:"#737373",600:"#525252",700:"#404040",800:"#262626",900:"#171717",950:"#0a0a0a"},stone:{50:"#fafaf9",100:"#f5f5f4",200:"#e7e5e4",300:"#d6d3d1",400:"#a8a29e",500:"#78716c",600:"#57534e",700:"#44403c",800:"#292524",900:"#1c1917",950:"#0c0a09"},red:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d",950:"#450a0a"},orange:{50:"#fff7ed",100:"#ffedd5",200:"#fed7aa",300:"#fdba74",400:"#fb923c",500:"#f97316",600:"#ea580c",700:"#c2410c",800:"#9a3412",900:"#7c2d12",950:"#431407"},amber:{50:"#fffbeb",100:"#fef3c7",200:"#fde68a",300:"#fcd34d",400:"#fbbf24",500:"#f59e0b",600:"#d97706",700:"#b45309",800:"#92400e",900:"#78350f",950:"#451a03"},yellow:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12",950:"#422006"},lime:{50:"#f7fee7",100:"#ecfccb",200:"#d9f99d",300:"#bef264",400:"#a3e635",500:"#84cc16",600:"#65a30d",700:"#4d7c0f",800:"#3f6212",900:"#365314",950:"#1a2e05"},green:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d",950:"#052e16"},emerald:{50:"#ecfdf5",100:"#d1fae5",200:"#a7f3d0",300:"#6ee7b7",400:"#34d399",500:"#10b981",600:"#059669",700:"#047857",800:"#065f46",900:"#064e3b",950:"#022c22"},teal:{50:"#f0fdfa",100:"#ccfbf1",200:"#99f6e4",300:"#5eead4",400:"#2dd4bf",500:"#14b8a6",600:"#0d9488",700:"#0f766e",800:"#115e59",900:"#134e4a",950:"#042f2e"},cyan:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},sky:{50:"#f0f9ff",100:"#e0f2fe",200:"#bae6fd",300:"#7dd3fc",400:"#38bdf8",500:"#0ea5e9",600:"#0284c7",700:"#0369a1",800:"#075985",900:"#0c4a6e",950:"#082f49"},blue:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"},indigo:{50:"#eef2ff",100:"#e0e7ff",200:"#c7d2fe",300:"#a5b4fc",400:"#818cf8",500:"#6366f1",600:"#4f46e5",700:"#4338ca",800:"#3730a3",900:"#312e81",950:"#1e1b4b"},violet:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},purple:{50:"#faf5ff",100:"#f3e8ff",200:"#e9d5ff",300:"#d8b4fe",400:"#c084fc",500:"#a855f7",600:"#9333ea",700:"#7e22ce",800:"#6b21a8",900:"#581c87",950:"#3b0764"},fuchsia:{50:"#fdf4ff",100:"#fae8ff",200:"#f5d0fe",300:"#f0abfc",400:"#e879f9",500:"#d946ef",600:"#c026d3",700:"#a21caf",800:"#86198f",900:"#701a75",950:"#4a044e"},pink:{50:"#fdf2f8",100:"#fce7f3",200:"#fbcfe8",300:"#f9a8d4",400:"#f472b6",500:"#ec4899",600:"#db2777",700:"#be185d",800:"#9d174d",900:"#831843",950:"#500724"},rose:{50:"#fff1f2",100:"#ffe4e6",200:"#fecdd3",300:"#fda4af",400:"#fb7185",500:"#f43f5e",600:"#e11d48",700:"#be123c",800:"#9f1239",900:"#881337",950:"#4c0519"}};function So(e){let t=e.lastIndexOf("-");return t<=0?null:Un[e.slice(0,t)]?.[e.slice(t+1)]??null}function Ro(e){let t=[],n=0,r=0;for(let o=0;o<e.length;o++){let s=e[o];s==="("||s==="["?n++:s===")"||s==="]"?n=Math.max(0,n-1):s===","&&n===0&&(t.push(e.slice(r,o).trim()),r=o+1)}return t.push(e.slice(r).trim()),t.filter(Boolean)}function zl(e,t){if(!e)return t;let n=Ro(e);return Ro(t).flatMap(r=>n.map(o=>r.includes("&")?r.replaceAll("&",o):`${o} ${r}`)).join(", ")}var Gl=/^@(?:-\w+-)?(?:keyframes|font-face|property)\b/i;function Bn(e){let t=e.replace(/\/\*[\s\S]*?\*\//g,i=>i.replace(/[^\n]/g," ")),n=[],r=[],o=0,s=1;for(let i=0;i<t.length;i++){let l=t[i];if(l===`
4
4
  `&&s++,l==="{"){let a=t.slice(o,i).trim(),c=r[r.length-1];c&&(c.own+=t.slice(c.segStart,o));let u=/^@theme\b/i.test(a),p=a.startsWith("@")&&!u,f=[...r].reverse().find(m=>!m.isAt)??null;r.push({raw:a,resolved:p?a:u?":root":zl(f?.resolved??null,a),isAt:p,skip:(c?.skip??!1)||p&&Gl.test(a),line:s,own:"",segStart:i+1}),o=i+1}else if(l==="}"){let a=r.pop();if(a){a.own+=t.slice(a.segStart,i),!a.isAt&&!a.skip&&n.push({selector:a.resolved,body:a.own,line:a.line,context:r.filter(u=>u.isAt).map(u=>u.raw.replace(/\s+/g," ")).join(" \xB7 ")});let c=r[r.length-1];c&&(c.segStart=i+1)}o=i+1}else l===";"&&(o=i+1)}return n}function zn(e){let t=[],n=0,r=0,o=s=>{let i=s.indexOf(":");if(i<=0)return;let l=s.slice(0,i).trim(),a=s.slice(i+1).replace(/\s+/g," ").trim();/^-{0,2}[a-z][\w-]*$/i.test(l)&&a&&t.push({property:l,value:a})};for(let s=0;s<e.length;s++){let i=e[s];i==="("?n++:i===")"?n=Math.max(0,n-1):i===";"&&n===0&&(o(e.slice(r,s)),r=s+1)}return o(e.slice(r)),t}var Ao={color:"Color",typography:"Typography",spacing:"Spacing",radius:"Radius",shadow:"Shadows",other:"Other"},ql=/\.(css|scss|sass|less|pcss)$/i,Vl=/^(?::root|html|body|:host)?(?:\[data-[\w-]+(?:[~|^$*]?=[^\]]*)?\]|\.(?:light|dark|theme-[\w-]+))*$/i;function Eo(e){let t=e.split(",").map(n=>n.trim());return t.length>0&&t.every(n=>n!==""&&Vl.test(n))}function _o(e){return ql.test(e)}var Wn=["color","typography","spacing","radius","button"],Kn={color:"Color",typography:"Typography",spacing:"Spacing",radius:"Radius",button:"Buttons"},Ot={raw:"Hard-coded value",near:"Near-identical colors",undefined:"Token not in contract","look-new":"Button not in contract","look-changed":"Button look changed","state-missing":"Button state missing","native-button":"Raw <button>","prop-unknown":"Unknown button variant"},Wl=/\.(tsx|jsx|ts|js|mjs|vue|svelte|astro|html)$/i,Jn=/(^|\/)(tests?|__tests__|__mocks__|fixtures|stories)\/|\.(test|spec|stories)\.|(^|\/)(tailwind|postcss|vite|next|webpack|eslint)\.config\.|\.d\.ts$/i,Hl=[[/^(color|background(-color)?|border(-(top|right|bottom|left))?(-color)?|outline(-color)?|fill|stroke|caret-color|accent-color|text-decoration-color|box-shadow)$/i,"color"],[/^(font-size|line-height|letter-spacing|font)$/i,"typography"],[/^(padding|margin)(-(top|right|bottom|left|inline|block)(-(start|end))?)?$|^(gap|row-gap|column-gap)$/i,"spacing"],[/^border(-(top|bottom)-(left|right))?-radius$/i,"radius"]];function Kl(e){return Hl.find(([t])=>t.test(e))?.[1]??null}var Jl=/(?<![\w.#-])(\d*\.?\d+)(px|rem)\b/g,To=/var\(\s*(--[\w-]+)/g,Xl=[[/\b(?:p|px|py|pt|pr|pb|pl|ps|pe|m|mx|my|mt|mr|mb|ml|gap|gap-x|gap-y|space-x|space-y)-\[(\d*\.?\d+(?:px|rem))\]/g,"spacing","spacing"],[/\btext-\[(\d*\.?\d+(?:px|rem))\]/g,"typography","font-size"],[/\bleading-\[(\d*\.?\d+(?:px|rem))\]/g,"typography","line-height"],[/\brounded(?:-[trblse]{1,2})?-\[(\d*\.?\d+(?:px|rem))\]/g,"radius","border-radius"]],Zl=[[/(?<![\w[-])(?:p|px|py|pt|pr|pb|pl|m|mx|my|mt|mr|mb|ml|gap|gap-x|gap-y|space-x|space-y)-(?:\d+(?:\.5)?|px)(?![\w[])/g,"spacing"],[/(?<![\w[-])text-(?:xs|sm|base|lg|[2-9]?xl)(?![\w[-])/g,"typography"],[/(?<![\w[-])rounded(?:-[trblse]{1,2})?(?:-(?:none|sm|md|lg|[2-3]?xl|full))?(?![\w[-])/g,"radius"]],Yl=/(?<![\w-])(bg|text|border|ring|fill|stroke|outline|from|via|to|divide|placeholder|decoration)-([a-z][\w-]*)/g,Ql={bg:"background",from:"background",via:"background",to:"background",border:"border-color",ring:"border-color",outline:"border-color",divide:"border-color"};function ec(e){if(e==="white")return"#FFFFFF";if(e==="black")return"#000000";let t=e.match(/^([a-z]+)-(\d{2,3})$/);return t?Un[t[1]]?.[t[2]]?.toUpperCase()??null:null}function Nt(e){let t=e.trim();return t.length>140?`${t.slice(0,137)}\u2026`:t}function tc(e,t){return!e.startsWith("#")||e.length>5?!0:/[a-f]/i.test(e)||/[:'"`[(]\s*$/.test(t)}function nc(e,t,n,r,o){let s=t.split(`
5
5
  `);for(let i of Bn(t)){let l=Eo(i.selector);for(let a of zn(i.body)){if(a.property.startsWith("--")){!l&&!o.has(a.property)&&o.set(a.property,a.value);continue}if(a.property.startsWith("$"))continue;let c=Kl(a.property);if(!c)continue;let u=s.findIndex((b,h)=>h>=i.line-1&&b.includes(a.property)),p=u>=0?u+1:i.line,f={file:e,line:p,snippet:Nt(s[p-1]??`${a.property}: ${a.value}`)};for(let b of a.value.matchAll(To))r.push({area:c,name:b[1],property:a.property,place:f});let m=a.value.replace(/var\([^)]*\)/g,"");if(c==="color")for(let b of m.matchAll(Fn))n.push({area:c,value:b[0],property:a.property,place:f});else for(let b of m.matchAll(Jl))parseFloat(b[1])!==0&&n.push({area:c,value:`${b[1]}${b[2]}`,property:a.property,place:f})}}}function rc(e,t,n,r,o,s){t.split(`
@@ -77,7 +77,7 @@ ${Ki(n,l>0)}`},ledger:{...e,followups:{...e.followups,[s]:l+1}}}}function Kr(e){
77
77
  ${Hi(s)}
78
78
 
79
79
  ${Ki(n,!1)}`}}var pd="2025-06-18",kn=`Check before you finish. ${wt}`,xn={grum_contract:`Grum design contract: this repository's design contract as reviewed in Grum: its color, typography, spacing and radius tokens, its buttons (components, looks and how to select them, and the written rules), and review decisions. Read it before writing or restyling UI, including any button. ${kn}`,grum_check:`Grum check: check the working tree against the design contract and list new drift with a one-line fix each. Drift already on the default branch isn't listed. Run it before you stop. ${kn}`,grum_request_review:`Grum review request: ask the project's owners to allow one drift item. Call this only after the user chooses to keep the style and request review. Send the drift key from grum_check, the user's reason and the page URL where it renders; Grum captures how it looks for the reviewer. ${kn}`,grum_review_status:`Grum review status: review requested, allowed or rejected (with the reviewer's note) for this project's drift. Pass a key to read one. ${kn}`},vn=e=>typeof e=="string"?e:"";function Zi(e){let t={type:"object",properties:{},additionalProperties:!1};return[{name:"grum_contract",description:xn.grum_contract,inputSchema:t,run:()=>e.contract()},{name:"grum_check",description:xn.grum_check,inputSchema:{type:"object",properties:{paths:{type:"array",items:{type:"string"},description:"Only report drift in these files (relative to the repository root). Omit to check everything."}},additionalProperties:!1},run:n=>e.check(Array.isArray(n.paths)?n.paths.filter(r=>typeof r=="string"):[])},{name:"grum_request_review",description:xn.grum_request_review,inputSchema:{type:"object",properties:{key:{type:"string",description:"The drift key from grum_check."},reason:{type:"string",description:"Why the contract has no token for this, in the user's words."},url:{type:"string",description:"The page where the element renders, for example http://localhost:3200/pricing. Grum captures how it looks and sends the picture. Needed when the repo's dev server port isn't in package.json."}},required:["key","reason"],additionalProperties:!1},run:n=>e.request(vn(n.key),vn(n.reason),vn(n.url))},{name:"grum_review_status",description:xn.grum_review_status,inputSchema:{type:"object",properties:{key:{type:"string",description:"One drift key. Omit to list all."}},additionalProperties:!1},run:n=>e.status(vn(n.key)||void 0)}]}var bt=(e,t)=>({jsonrpc:"2.0",id:e,result:t}),Cn=(e,t,n)=>({jsonrpc:"2.0",id:e,error:{code:t,message:n}});async function Yi(e,t,n){if(!e||typeof e!="object")return Cn(null,-32600,"Invalid request");let r=e,o=!("id"in r),s=r.id??null;if(typeof r.method!="string")return o?null:Cn(s,-32600,"Invalid request");let i=r.params??{};switch(r.method){case"initialize":return bt(s,{protocolVersion:typeof i.protocolVersion=="string"?i.protocolVersion:pd,capabilities:{tools:{listChanged:!1}},serverInfo:n});case"ping":return bt(s,{});case"tools/list":return bt(s,{tools:t.map(({name:l,description:a,inputSchema:c})=>({name:l,description:a,inputSchema:c}))});case"tools/call":{let l=t.find(c=>c.name===i.name);if(!l)return Cn(s,-32602,`Unknown tool: ${String(i.name)}`);let a=i.arguments&&typeof i.arguments=="object"?i.arguments:{};try{let c=await l.run(a);return bt(s,{content:[{type:"text",text:c.text}],isError:c.isError??!1})}catch(c){return bt(s,{content:[{type:"text",text:c instanceof Error?c.message:String(c)}],isError:!0})}}default:return o?null:Cn(s,-32601,`Method not found: ${r.method}`)}}var Qi=[" @@@@@@@ @@@@@@@","@@@@@@@@@ @@@@@@@@@","@@@@@@@@@ @@@@@@@@@"," @@@@@@@@@@@@@@@@@@"," @@@@@@@@"," @@@@@@ "," @@@@@@@@@@@@@@@@@@","@@@@@@@@@ @@@@@@@@@","@@@@@@@@@ @@@@@@@@@"," @@@@@@@ @@@@@@@"],fd=Math.max(...Qi.map(e=>e.length)),dd=[" .d8888b."," d88P Y88b"," 888 888"," 888 888d888 888 888 88888b.d88b.",' 888 88888 888P" 888 888 888 "888 "88b'," 88 888 888 888 888 888 888 888"," 88b d88P 888 Y88b 888 888 888 888",' "Y8888P88 888 "Y88888 888 888 888'],ea=Qi.map((e,t)=>{let n=dd[t-1];return n?`${e.padEnd(fd)} ${n}`:e}).join(`
80
- `),gd="\x1B[38;2;28;142;241m",md="\x1B[38;2;196;160;0m",$n="\x1B[0m",ta=e=>`${gd}${e}${$n}`,hd=[{name:"check",blurb:"Check this repository against its design contract"},{name:"setup",blurb:"Sign in, link this repository, set up Cursor"}];function kt(e){return[...hd,e?{name:"logout",blurb:"Sign out of Grum"}:{name:"login",blurb:"Sign in to Grum"}]}var na="\u2191\u2193 move Enter select 1\u20133 jump q quit",ra=/^[A-Za-z0-9_-]{1,80}$/;function Jr(e){if(!e||typeof e!="object")return null;let t=e,n=typeof t.repo=="string"?t.repo.trim():"",r=typeof t.workspace?.name=="string"?t.workspace.name.trim():"";if(!n||!r)return null;let o=t.workspace?.id,s=typeof t.site=="string"?t.site.trim():"";return{workspace:r,workspaceId:typeof o=="string"&&ra.test(o)?o:null,repo:n,site:s||null}}function yd(e){return e&&e.replace(/^https?:\/\//,"").replace(/\/$/,"")||null}function oa(e){let t=yd(e.site);return`${[e.workspace,e.repo,...t?[t]:[]].join(" \xB7 ")}`}function sa(e,t){return ra.test(t)?`${e.replace(/\/$/,"")}/w/${t}`:null}function ia(e,t){if(e===200||t.code==="not-scanned"){let o=Jr(t.project);return o?{line:oa(o),workspaceId:o.workspaceId}:null}if(t.code!=="choose-project"||!Array.isArray(t.projects))return null;let n=t.projects.flatMap(o=>{let s=Jr(o);return s?[s]:[]}),r=n[0];return r?{line:`Connected to ${n.map(o=>o.workspace).join(", ")} \xB7 ${r.repo}`,workspaceId:null}:null}function aa(e,t,n){if(!e||!t||e.apiOrigin!==n||e.project.repo.toLowerCase()!==t.toLowerCase())return null;let r=Jr(e.project);return r?{line:oa(r),workspaceId:r.workspaceId}:null}var la="\x1B[2m",wd=e=>`${la}${e}${$n}`;function bd(e){return`${la}\x1B]8;;${e}\x1B\\${e}\x1B]8;;\x1B\\${$n}`}function ca(e,t=null,n=!1,r=null){let o=[t,r].filter(a=>a),s=o.length?`${o.join(`
80
+ `),gd="\x1B[38;2;28;142;241m",md="\x1B[38;2;196;160;0m",$n="\x1B[0m",ta=e=>`${gd}${e}${$n}`,hd=[{name:"check",blurb:"Check your changes against the design contract"},{name:"setup",blurb:"Sign in, link this repository, set up Cursor"}];function kt(e){return[...hd,e?{name:"logout",blurb:"Sign out of Grum"}:{name:"login",blurb:"Sign in to Grum"}]}var na="\u2191\u2193 move Enter select 1\u20133 jump q quit",ra=/^[A-Za-z0-9_-]{1,80}$/;function Jr(e){if(!e||typeof e!="object")return null;let t=e,n=typeof t.repo=="string"?t.repo.trim():"",r=typeof t.workspace?.name=="string"?t.workspace.name.trim():"";if(!n||!r)return null;let o=t.workspace?.id,s=typeof t.site=="string"?t.site.trim():"";return{workspace:r,workspaceId:typeof o=="string"&&ra.test(o)?o:null,repo:n,site:s||null}}function yd(e){return e&&e.replace(/^https?:\/\//,"").replace(/\/$/,"")||null}function oa(e){let t=yd(e.site);return`${[e.workspace,e.repo,...t?[t]:[]].join(" \xB7 ")}`}function sa(e,t){return ra.test(t)?`${e.replace(/\/$/,"")}/w/${t}`:null}function ia(e,t){if(e===200||t.code==="not-scanned"){let o=Jr(t.project);return o?{line:oa(o),workspaceId:o.workspaceId}:null}if(t.code!=="choose-project"||!Array.isArray(t.projects))return null;let n=t.projects.flatMap(o=>{let s=Jr(o);return s?[s]:[]}),r=n[0];return r?{line:`Connected to ${n.map(o=>o.workspace).join(", ")} \xB7 ${r.repo}`,workspaceId:null}:null}function aa(e,t,n){if(!e||!t||e.apiOrigin!==n||e.project.repo.toLowerCase()!==t.toLowerCase())return null;let r=Jr(e.project);return r?{line:oa(r),workspaceId:r.workspaceId}:null}var la="\x1B[2m",wd=e=>`${la}${e}${$n}`;function bd(e){return`${la}\x1B]8;;${e}\x1B\\${e}\x1B]8;;\x1B\\${$n}`}function ca(e,t=null,n=!1,r=null){let o=[t,r].filter(a=>a),s=o.length?`${o.join(`
81
81
  `)}
82
82
 
83
83
  `:"",i=ea.split(`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@grum-os/cli",
3
- "version": "0.3.5",
4
- "contentHash": "78a3046bc5a5bb380da405ed25060485",
3
+ "version": "0.3.7",
4
+ "contentHash": "539becde0182054688c3ec1acae1a564",
5
5
  "description": "Keep a repository on the design contract reviewed in Grum: a local drift check, review requests, Cursor hooks and an MCP server.",
6
6
  "homepage": "https://app.grum.so",
7
7
  "keywords": [
@@ -22,7 +22,7 @@
22
22
  "grum.mjs",
23
23
  "content.md5",
24
24
  "README.md",
25
- "brand.svg"
25
+ "brand.png"
26
26
  ],
27
27
  "engines": {
28
28
  "node": ">=22"
package/brand.svg DELETED
@@ -1,17 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="228" height="64" viewBox="0 0 114.0468 32" role="img" aria-label="Grum">
2
- <style>
3
- .word { fill: #1a1a1a; }
4
- @media (prefers-color-scheme: dark) {
5
- .word { fill: #f2f2f2; }
6
- }
7
- </style>
8
- <path fill="#1c8ef1" d="M24.9594 0C27.4583 0 28.7083 0.000321239 29.6582 0.496867C30.4469 0.909293 31.0907 1.55298 31.5031 2.34169C31.9997 3.2915 32 4.54146 32 7.04014C32 9.53859 31.9997 10.788 31.5031 11.7378C31.0907 12.5265 30.4469 13.1702 29.6582 13.5826C28.7083 14.0792 27.4583 14.0795 24.9594 14.0795C24.4568 14.0795 24.0048 14.0793 23.5956 14.0751C22.5207 14.0639 21.5658 14.9246 21.5658 15.9996C21.5658 17.0746 22.5207 17.9355 23.5957 17.9247C24.0049 17.9206 24.4568 17.9205 24.9594 17.9205C27.4583 17.9205 28.7083 17.92 29.6582 18.4166C30.4471 18.829 31.0907 19.4733 31.5031 20.2622C31.9997 21.212 32 22.4612 32 24.9598C32 27.4584 31.9996 28.7077 31.5031 29.6575C31.0907 30.4464 30.4471 31.0907 29.6582 31.5031C28.7083 31.9997 27.4583 32 24.9594 32C22.4607 32 21.2112 31.9997 20.2614 31.5031C19.4724 31.0907 18.8281 30.4464 18.4156 29.6575C17.9192 28.7077 17.9195 27.4581 17.9195 24.9598C17.9195 24.4567 17.9195 24.0043 17.9237 23.5947C17.9345 22.5206 17.0742 21.5665 16 21.5665C14.9258 21.5665 14.0655 22.5206 14.0763 23.5946C14.0805 24.0043 14.0806 24.4567 14.0806 24.9598C14.0806 27.4584 14.0802 28.7077 13.5837 29.6575C13.1712 30.4464 12.5276 31.0907 11.7386 31.5031C10.7888 31.9997 9.53875 32 7.03988 32C4.54126 32 3.2917 31.9996 2.34187 31.5031C1.55293 31.0907 0.909362 30.4464 0.496905 29.6575C0.000398815 28.7077 0 27.4584 0 24.9598C2.87333e-10 22.4612 0.00033322 21.212 0.496905 20.2622C0.909395 19.4733 1.55291 18.829 2.34187 18.4166C3.2917 17.92 4.54126 17.9205 7.03988 17.9205C7.54303 17.9205 7.99554 17.9205 8.4052 17.9246C9.48015 17.9355 10.435 17.0745 10.435 15.9996C10.435 14.9246 9.48015 14.064 8.4052 14.0751C7.99555 14.0793 7.54303 14.0795 7.03988 14.0795C4.54126 14.0795 3.2917 14.0792 2.34187 13.5826C1.55308 13.1702 0.909354 12.5265 0.496905 11.7378C0.000347435 10.788 1.37868e-09 9.53859 0 7.04014C0 4.54146 0.000321269 3.2915 0.496905 2.34169C0.909354 1.55296 1.55308 0.909277 2.34187 0.496867C3.2917 0.000345826 4.54126 1.21426e-09 7.03988 0C9.53875 0 10.7888 0.000321239 11.7386 0.496867C12.5275 0.909285 13.1712 1.55297 13.5837 2.34169C14.0802 3.2915 14.0806 4.54146 14.0806 7.04014C14.0806 7.54427 14.0805 7.99753 14.0763 8.40772C14.0652 9.48211 14.9255 10.4366 16 10.4366C17.0745 10.4366 17.9349 9.48203 17.9238 8.40772C17.9196 7.99753 17.9195 7.54427 17.9195 7.04014C17.9195 4.54146 17.919 3.2915 18.4156 2.34169C18.828 1.5528 19.4724 0.909325 20.2614 0.496867C21.2112 0.00033775 22.4607 5.45318e-10 24.9594 0Z" />
9
- <g class="word" transform="translate(46 6.145)">
10
- <g transform="translate(-15.7148 0)">
11
- <path d="M63.3766 8.1C65.3476 6.885 66.8866 5.94 68.1826 5.94C68.9926 5.94 69.1276 6.615 68.8306 7.695L67.3726 12.906H67.6426C69.6136 9.315 72.3136 5.94 74.7976 5.94C75.6886 5.94 76.6606 6.507 76.1476 8.073L74.6896 12.474H74.9326C76.9036 9.045 79.4686 5.94 81.8446 5.94C82.7356 5.94 83.6806 6.48 83.1946 8.073L80.6566 16.281C80.4406 16.956 80.6566 17.361 81.1426 17.361C81.8446 17.361 82.6546 16.983 83.7616 16.227V17.307C82.0336 18.711 79.9276 19.71 78.6046 19.71C77.7136 19.71 77.3626 19.332 77.9566 17.415L80.3326 9.72C80.6026 8.883 80.3866 8.64 80.1166 8.64C78.6586 8.64 74.2576 15.039 73.1236 19.17L70.5586 19.71L73.4476 9.477C73.6096 8.883 73.4206 8.64 73.1506 8.64C71.6926 8.64 67.1836 15.039 66.0496 19.17L63.5926 19.71L66.1846 9.126C66.3196 8.559 66.1846 8.1 63.3766 8.91V8.1Z" />
12
- </g>
13
- <path d="M33.7 19.71C32.809 19.71 31.756 19.143 32.35 17.577C33.376 14.85 34.294 12.096 35.023 9.369C35.212 8.694 35.023 8.289 34.537 8.289C33.835 8.289 33.025 8.667 31.918 9.423V8.343C33.646 6.939 35.752 5.94 37.075 5.94C37.966 5.94 38.209 6.372 37.723 8.235C36.994 10.962 36.103 13.689 35.077 16.416C34.942 16.767 35.158 17.01 35.428 17.01C36.886 17.01 41.611 10.611 42.745 6.48L45.202 5.94L42.745 16.281C42.583 16.956 42.772 17.361 43.258 17.361C43.96 17.361 44.77 16.983 45.877 16.227V17.307C44.149 18.711 42.043 19.71 40.72 19.71C39.829 19.71 39.532 19.332 40.072 17.415L41.638 11.961H41.503C39.397 15.822 36.346 19.71 33.7 19.71Z" />
14
- <path d="M21.0836 8.1C23.0546 6.885 24.5936 5.94 25.8896 5.94C26.6996 5.94 26.9966 6.507 26.5376 7.695L25.3496 10.827H25.6196C27.5636 7.857 29.7776 5.94 31.2626 5.94C31.7216 5.94 31.9916 6.237 31.9916 6.696C31.9916 7.938 30.8846 8.91 30.3176 9.018L28.9136 9.261C26.8616 10.206 25.2416 13.014 23.9186 16.713L23.2166 19.17L20.7596 19.71L23.8106 9.126C23.9726 8.559 23.8106 8.1 21.0836 8.91V8.1Z" />
15
- <path d="M8.775 19.71C2.97 19.71 0 16.686 0 12.501C0 6.561 5.697 0 13.122 0C15.255 0 17.199 0.351001 18.792 0.809999L18.225 5.94H17.55C16.956 2.646 15.093 1.485 11.88 1.485C6.75 1.485 3.159 6.642 3.159 11.799C3.159 15.552 5.265 18.225 8.91 18.225C11.691 18.225 13.527 17.28 13.851 15.768L14.931 10.611L10.341 10.746L10.935 9.261H20.007L19.467 10.476C18.063 10.476 17.469 10.827 17.172 12.231L16.416 15.714C16.389 15.849 16.389 15.957 16.389 16.065C16.389 16.632 16.767 16.821 17.874 16.821L17.82 17.469C14.094 18.792 11.475 19.71 8.775 19.71Z" />
16
- </g>
17
- </svg>