@gruum/cli 0.1.2 → 0.1.3
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/gruum.mjs +8 -9
- package/package.json +1 -1
package/gruum.mjs
CHANGED
|
@@ -53,21 +53,20 @@ ${t}
|
|
|
53
53
|
${s}
|
|
54
54
|
|
|
55
55
|
Waiting for confirmation\u2026
|
|
56
|
-
`);let r=Date.now()+600*1e3;for(;Date.now()<r;){await new Promise(a=>setTimeout(a,2e3));let o=await $t(null,`/api/cli/pair/poll?pairingId=${encodeURIComponent(n.pairingId)}&verifier=${encodeURIComponent(n.verifier)}`);if(!o.ok)continue;let i=await o.json();if(i.status==="expired")return process.stderr.write(
|
|
57
|
-
`),
|
|
58
|
-
`),
|
|
59
|
-
`),1}async function Jr(t,e){let n=Ql(t.repoDir);if(!n)return process.stderr.write(`gruum: this folder has no GitHub origin, so it can't be matched to a Gruum project.
|
|
60
|
-
`),null;let s=tc(t);if(s&&s.repo===n)return s;let r=await $t(e,`/api/v2/cli/projects?repo=${encodeURIComponent(n)}`);if(r.status===401)return process.stderr.write(`gruum: sign-in expired. Run gruum login again.
|
|
61
|
-
`),null;if(!r.ok)return null;let o=await r.json(),i=Array.isArray(o.projects)?o.projects:[];if(i.length===0)return process.stderr.write(`gruum: no Gruum project is connected to ${n}. Create a v2 project for that repository, then run gruum check again.
|
|
56
|
+
`);let r=Date.now()+600*1e3;for(;Date.now()<r;){await new Promise(a=>setTimeout(a,2e3));let o=await $t(null,`/api/cli/pair/poll?pairingId=${encodeURIComponent(n.pairingId)}&verifier=${encodeURIComponent(n.verifier)}`);if(!o.ok)continue;let i=await o.json();if(i.status==="expired")return process.stderr.write("gruum: that code expired. Run `npx @gruum/cli login` again.\n"),1;if(i.status==="connected"&&i.token)return ql({token:i.token,apiOrigin:Mt}),process.stdout.write(`Signed in. This CLI can read specs for your projects.
|
|
57
|
+
`),0}return process.stderr.write("gruum: sign-in timed out. Run `npx @gruum/cli login` again.\n"),1}async function Jr(t,e){let n=Ql(t.repoDir);if(!n)return process.stderr.write(`gruum: this folder has no GitHub origin, so it can't be matched to a Gruum project.
|
|
58
|
+
`),null;let s=tc(t);if(s&&s.repo===n)return s;let r=await $t(e,`/api/v2/cli/projects?repo=${encodeURIComponent(n)}`);if(r.status===401)return process.stderr.write("gruum: sign-in expired. Run `npx @gruum/cli login` again.\n"),null;if(!r.ok)return null;let o=await r.json(),i=Array.isArray(o.projects)?o.projects:[];if(i.length===0)return process.stderr.write(`gruum: no Gruum project is connected to ${n}. Create a v2 project for that repository, then run \`npx @gruum/cli check\` again.
|
|
62
59
|
`),null;let a=Br(i,t.root);if(!a){let l=i.map(c=>` ${c.name} (${c.id})${c.rootPath?` #${c.rootPath}`:""}`).join(`
|
|
63
|
-
`);return process.stderr.write(`gruum: ${n} matches more than one project. Set "root" in .gruum/config.json to the folder alias, then run gruum check again.
|
|
60
|
+
`);return process.stderr.write(`gruum: ${n} matches more than one project. Set "root" in .gruum/config.json to the folder alias, then run \`npx @gruum/cli check\` again.
|
|
64
61
|
${l}
|
|
65
62
|
`),null}return wt(Kr(t),a),a}async function Ae(t,e){if(e)return"local";let n=Wr();if(!n)return"local";try{let s=await Jr(t,n);if(!s)return"local";let r=Se(t.repoDir),o=await $t(n,`/api/v2/cli/projects/${encodeURIComponent(s.id)}/baseline?concept=button&branch=${encodeURIComponent(r)}`);if(o.status===404||!o.ok)return"local";let i=await o.json(),a=Zt(i.baseline);return a?(wt(Gt(t),a),wt($n(t),i.exceptions??{}),"remote"):"local"}catch{return process.stderr.write(`gruum: couldn't reach Gruum. Checking the spec cached in .gruum/baseline.json.
|
|
66
63
|
`),"local"}}async function _n(t){let e=Wr();if(!e)return null;let n=await Jr(t,e);return n?{credentials:e,project:n}:null}async function Zr(t,e,n,s){let r=await _n(t);if(!r)return;let o=Se(t.repoDir);if(o)try{let i=await $t(r.credentials,`/api/v2/cli/projects/${encodeURIComponent(r.project.id)}/drift`,{method:"POST",body:JSON.stringify({action:"observe",concept:"button",branch:o,commit:Gr(t.repoDir),baselineVersion:n,source:s,items:e})});i.ok||process.stderr.write(`gruum: couldn't report this check (${i.status}). The local result still stands.
|
|
67
64
|
`)}catch{process.stderr.write(`gruum: couldn't reach Gruum to report this check. The local result still stands.
|
|
68
65
|
`)}}async function Xr(t,e,n){let s=await _n(t);if(!s)return{ok:!1,text:"Sign in with gruum login before requesting an exception."};let r=Se(t.repoDir);if(!r)return{ok:!1,text:"This folder is not on a named git branch."};try{let o=await $t(s.credentials,`/api/v2/cli/projects/${encodeURIComponent(s.project.id)}/drift`,{method:"POST",body:JSON.stringify({action:"request",concept:"button",branch:r,commit:Gr(t.repoDir),reason:n,item:e})}),i=await o.json().catch(()=>({}));if(!o.ok)return{ok:!1,text:i.error||`Request failed (${o.status}).`};let a=i.reviewUrl?`${Ur(s.credentials)}${i.reviewUrl}`:"",l=i.created?`Exception request ${i.id} is pending review.`:`An exception for this change is already pending (${i.id}).`;return{ok:!0,text:a?`${l}
|
|
69
66
|
${a}`:l}}catch{return{ok:!1,text:"Couldn't reach Gruum to request an exception."}}}async function Yr(t,e){let n=await _n(t);if(!n)return{ok:!1,text:"Sign in with gruum login to see exception status."};let s=Se(t.repoDir);try{let r=await $t(n.credentials,`/api/v2/cli/projects/${encodeURIComponent(n.project.id)}/drift?concept=button&branch=${encodeURIComponent(s)}`);if(!r.ok)return{ok:!1,text:`Couldn't load exceptions (${r.status}).`};let o=await r.json(),i=Array.isArray(o.requests)?o.requests:[],a=e?i.filter(l=>l.id===e):i;return a.length===0?{ok:!0,text:e?`No exception request ${e} on ${s||"this branch"}.`:`No exception requests on ${s||"this branch"}.`}:{ok:!0,text:a.map(l=>`${l.id} ${l.status} ${l.title} (${l.branch})`).join(`
|
|
70
|
-
`)}}catch{return{ok:!1,text:"Couldn't reach Gruum to read exception status."}}}var In="0.1.
|
|
67
|
+
`)}}catch{return{ok:!1,text:"Couldn't reach Gruum to read exception status."}}}var In="0.1.3",qr=`gruum ${In}: keep buttons on the Gruum spec
|
|
68
|
+
|
|
69
|
+
Run it as \`npx @gruum/cli <command>\`.
|
|
71
70
|
|
|
72
71
|
Usage:
|
|
73
72
|
gruum login
|
|
@@ -94,7 +93,7 @@ Usage:
|
|
|
94
93
|
gruum mcp
|
|
95
94
|
Stdio MCP server: gruum_button_spec, gruum_check_buttons,
|
|
96
95
|
gruum_request_exception, and gruum_exception_status.
|
|
97
|
-
`,sc=new Set(["--baseline","--root","--out","--cli","--files"]);function rc(t){let e=[],n=new Map;for(let s=0;s<t.length;s++){let r=t[s];if(!r.startsWith("--")){e.push(r);continue}let o=r.indexOf("="),i=o===-1?r:r.slice(0,o),a=o===-1?void 0:r.slice(o+1),l=n.get(i)??[];if(a!==void 0)l.push(a);else if(i==="--files")for(;t[s+1]&&!t[s+1].startsWith("--");)l.push(t[++s]);else sc.has(i)&&t[s+1]!==void 0&&l.push(t[++s]);n.set(i,l)}return{positional:e,flags:n}}var U=(t,e)=>t.flags.has(e),ut=(t,e)=>t.flags.get(e)?.[0];function Dt(t,e=process.cwd()){let n=vn(e),s=ut(t,"--root")??Sn(n).root??"";return vn(e,s)}var Re="No spec found. Publish one from Gruum, or draft one locally with `gruum baseline --write`.";function to(t,e){let n=vt(t,ut(e,"--baseline"));return n||process.stderr.write(`gruum: ${Re}
|
|
96
|
+
`,sc=new Set(["--baseline","--root","--out","--cli","--files"]);function rc(t){let e=[],n=new Map;for(let s=0;s<t.length;s++){let r=t[s];if(!r.startsWith("--")){e.push(r);continue}let o=r.indexOf("="),i=o===-1?r:r.slice(0,o),a=o===-1?void 0:r.slice(o+1),l=n.get(i)??[];if(a!==void 0)l.push(a);else if(i==="--files")for(;t[s+1]&&!t[s+1].startsWith("--");)l.push(t[++s]);else sc.has(i)&&t[s+1]!==void 0&&l.push(t[++s]);n.set(i,l)}return{positional:e,flags:n}}var U=(t,e)=>t.flags.has(e),ut=(t,e)=>t.flags.get(e)?.[0];function Dt(t,e=process.cwd()){let n=vn(e),s=ut(t,"--root")??Sn(n).root??"";return vn(e,s)}var Re="No spec found. Publish one from Gruum, or draft one locally with `npx @gruum/cli baseline --write`.";function to(t,e){let n=vt(t,ut(e,"--baseline"));return n||process.stderr.write(`gruum: ${Re}
|
|
98
97
|
`),n}function Kt(t,e,n){let s={...e,checkedAt:new Date().toISOString(),baselineVersion:n.baseline.version,items:n.items};return Cn(t,s),s}async function oc(t){let e=Dt(t);await Ae(e,U(t,"--baseline"));let n=to(e,t);if(!n)return 0;let s=xt(e,n,{staged:U(t,"--staged")});U(t,"--staged")||Kt(e,$e(e),s);let r=(t.flags.get("--files")??[]).map(l=>N.relative(N.join(e.repoDir,e.root),N.resolve(l)).split(N.sep).join("/")),o=Le(s.items,r),i=Ce(e);(U(t,"--ci")||U(t,"--report"))&&await Zr(e,o,n.version,U(t,"--ci")?"ci":"local"),U(t,"--json")?process.stdout.write(`${JSON.stringify({baselineVersion:n.version,items:o,exceptions:i},null,2)}
|
|
99
98
|
`):process.stdout.write(`${Gn(o,{baselineVersion:n.version,files:s.result.index.files,skipped:s.result.index.skipped},i)}
|
|
100
99
|
`);let a=Pt(o,i);if(U(t,"--strict")){let l=o.some(c=>c.severity==="block"&&i[c.id]==="pending");return a.length>0||l?1:0}if(U(t,"--ci")&&a.length===0){let l=o.filter(c=>i[c.id]==="pending");l.length>0&&process.stdout.write(`${l.length} pending exception${l.length===1?"":"s"}; this run does not fail on them.
|