nemar-cli 0.10.17-PR1720.0fefe49 → 0.10.17-PR1720.80985fa

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.
Files changed (2) hide show
  1. package/dist/index.js +6 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -99,7 +99,7 @@ ${t}`,OPe,TPe,FPe=(e,t,r)=>{let n=r===""?"":`with ${r.trim()}() `,i=APe.bind(nul
99
99
  `)}var x2=!1;var{spawn:mJe}=globalThis.Bun;function ql(e,t=[]){let r=e.replace(hJe,'("$1","<redacted>")');for(let n of t)if(n.length>=gJe)r=r.split(n).join("<redacted>");return r}function Yx(e){let t=["AWS_SESSION_TOKEN","AWS_SECRET_ACCESS_KEY","AWS_ACCESS_KEY_ID"],r=new Set;for(let n of[process.env,e??{}])for(let i of t){let o=n[i];if(typeof o==="string"&&o.length>0)r.add(o)}return[...r]}async function Ite(e,t){let r=e.getReader(),n=new TextDecoder,i="";while(!0){let{done:o,value:s}=await r.read();if(o)break;if(s.byteLength===0)continue;t(),i+=n.decode(s,{stream:!0})}return i+n.decode()}async function k(e,t={}){let r={...process.env,GIT_TERMINAL_PROMPT:"0",...t.env};for(let b of t.unsetEnv??[])delete r[b];let n=mJe({cmd:e,cwd:t.cwd,...t.stdin===void 0?{}:{stdin:new TextEncoder().encode(t.stdin)},stdout:"pipe",stderr:"pipe",env:r}),i=!1,o,s,a=performance.now(),c=()=>{if(s!==void 0)clearTimeout(s),s=void 0},u=()=>{if(!t.onInactivityWarning)return;c(),s=setTimeout(()=>{s=void 0;try{t.onInactivityWarning?.(performance.now()-a)}catch{console.error("Could not display subprocess inactivity warning; the child result is unaffected.")}},t.inactivityWarningAfterMs??yJe)};if(u(),t.timeout)o=setTimeout(()=>{i=!0,c(),n.kill()},t.timeout);let d=Jx()?[...Yx(r),...t.redact??[]]:[];if(Jx()){let b=t.cwd?` (cwd=${t.cwd})`:"";Ac(l.dim(ql(`$ ${e.join(" ")}${b}`,d)))}let f=()=>{a=performance.now(),u()},m,p,g,h=n.exited.then((b)=>(c(),b));try{[m,p,g]=await Promise.all([Ite(n.stdout,f),Ite(n.stderr,f),h])}finally{if(c(),o)clearTimeout(o)}if(Jx()){if(t.sensitiveOutput)Ac(l.dim("[sensitive subprocess output suppressed]"));else{if(m.trim())Ac(l.dim(ql(m.trimEnd(),d)));if(p.trim())Ac(l.yellow(ql(p.trimEnd(),d)))}Ac(l.dim(`(exit ${g})`))}if(i)return{stdout:m,stderr:p||`Command timed out after ${Math.round(t.timeout/1000)}s`,exitCode:g??1,timedOut:!0};return{stdout:m,stderr:p,exitCode:g,timedOut:!1}}var hJe,gJe=8,yJe=120000;var Nt=I(()=>{Ze();hJe=/\(\s*"((?:x-amz-)[^"]*|authorization|proxy-authorization)"\s*,\s*"[^"]*"\s*\)/gi});function xJe(){if(process.platform==="darwin")return"macos";if(process.platform==="win32")return"windows";return"linux"}function jte(e,t=xJe()){return e.installInstructions[t]}function wJe(e){let t=e.match(/(\d+\.\d+(?:\.\d+)?)/);return t?t[1]:void 0}function _Je(){let e=Number(process.env.TEST_PROBE_TIMEOUT_MS);return Number.isFinite(e)&&e>0?e:vJe}async function Mte(e){try{let{exitCode:t,stdout:r,timedOut:n}=await k(e.cmd,{timeout:_Je()});if(n)return{available:!1,timedOut:!0};if(t!==0)return{available:!1};return{available:!0,version:wJe(r)}}catch(t){let r=t instanceof Error?t.message:String(t);if(!r.includes("ENOENT")&&!r.includes("not found"))console.error(` Warning: ${e.name} check failed unexpectedly: ${r}`);return{available:!1}}}async function ch(){let e=Object.entries(Nte);return Promise.all(e.map(async([t,r])=>{let{available:n,version:i,timedOut:o}=await Mte(r);return{key:t,name:r.name,purpose:r.purpose,required:r.required,available:n,version:i,timedOut:o,installInstruction:jte(r)}}))}async function qte(){let t=(await ch()).filter((r)=>r.required&&!r.available);if(t.length===0)return[];console.warn(`
100
100
  Heads up: some tools NEMAR needs for uploading/validating aren't installed yet:`);for(let r of t)console.warn(` - ${r.name} (${r.purpose})`),console.warn(` Install: ${r.installInstruction}`);return console.warn("Run `nemar doctor` anytime to re-check. You can finish signup without them.\n"),t}async function Ll(e){let r=bJe[e].map((s)=>Nte[s]).filter(Boolean),n=await Promise.all(r.map(async(s)=>{let a=await Mte(s);return{check:s,available:a.available,timedOut:a.timedOut}}));for(let s of n)if(s.timedOut&&s.check.required)console.warn(`Warning: ${s.check.name} did not respond to a version check in time; continuing anyway.`);let i=n.filter((s)=>!s.available&&!s.timedOut&&s.check.required).map((s)=>({tool:s.check.name,installInstruction:jte(s.check)}));if(i.length===0)return;let o=[`
101
101
  Missing required tools:`];for(let s of i)o.push(` ${s.tool} not installed`),o.push(` Install: ${s.installInstruction}`);throw Error(o.join(`
102
- `))}var Nte,bJe,vJe=4000;var lh=I(()=>{Nt();Nte={git:{name:"git",purpose:"version control for dataset metadata",cmd:["git","--version"],required:!0,installInstructions:{macos:"brew install git (or install Xcode Command Line Tools)",linux:"sudo apt-get install git OR sudo dnf install git",windows:"winget install Git.Git (or https://git-scm.com/download/win)"}},"git-annex":{name:"git-annex",purpose:"large-file data transfer (upload/download)",cmd:["git-annex","version"],required:!0,installInstructions:{macos:"brew install git-annex",linux:"sudo apt-get install git-annex OR sudo dnf install git-annex",windows:"Download the installer from https://git-annex.branchable.com/install/Windows/"}},gh:{name:"GitHub CLI (gh)",purpose:"GitHub authentication + repository operations",cmd:["gh","--version"],required:!0,installInstructions:{macos:"brew install gh",linux:"See https://cli.github.com/manual/installation",windows:"winget install GitHub.cli (or: scoop install gh)"}},aws:{name:"AWS CLI",purpose:"S3 data upload/download",cmd:["aws","--version"],required:!0,installInstructions:{macos:"brew install awscli",linux:"pip install awscli OR sudo snap install aws-cli --classic",windows:"winget install Amazon.AWSCLI (or the MSI from https://aws.amazon.com/cli/)"}},deno:{name:"Deno",purpose:"BIDS validation",cmd:["deno","--version"],required:!0,installInstructions:{macos:"brew install deno (or: curl -fsSL https://deno.land/install.sh | sh)",linux:"curl -fsSL https://deno.land/install.sh | sh",windows:"winget install DenoLand.Deno (or: irm https://deno.land/install.ps1 | iex)"}}},bJe={upload:["git-annex","gh","aws","deno"],download:["gh"],clone:["git","gh"],push:["git-annex","gh"],publish:["gh","aws"],update:["git","gh"],release:["git","gh"]}});var Bte;var Lte=I(()=>{Bte={name:"nemar-cli",packageManager:"bun@1.4.3",version:"0.10.17-PR1720.0fefe49",description:"CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource) dataset management",type:"module",main:"dist/index.js",bin:{nemar:"dist/index.js"},scripts:{dev:"bun run src/index.ts",build:"bun build src/index.ts --outdir dist --target bun --minify && sed '1s|#!/usr/bin/env node|#!/usr/bin/env bun|' dist/index.js > dist/index.js.tmp && mv dist/index.js.tmp dist/index.js",test:"bun test",lint:"biome check src/","lint:scrub":"biome check scripts/scrub shared/identifier-scrub.ts test/scrub","test:scrub":"bun test --preload ./test/scrub/helpers/temp-dirs-preload.ts --path-ignore-patterns='__run_every_scrub_suite__' test/scrub test/identifier-scan.test.ts test/identifier-scrub.test.ts test/identifier-dates.test.ts test/identifier-fleet.test.ts","migrations:d1-check":"bun run scripts/d1-migration-check.ts","zarr:geometry-check":"bun run backend/scripts/zarr-geometry-conformance.ts","lint:fix":"biome check --fix src/",format:"biome format --write src/",typecheck:"tsc --noEmit && tsc --noEmit -p backend","generate-openapi":"bun run scripts/generate-openapi.ts",prepublishOnly:"bun run build",prepare:"husky",postinstall:"bun scripts/postinstall-check.mjs",deploy:"wrangler deploy",preview:"wrangler dev"},keywords:["nemar","bids","neuroimaging","eeg","emg","datalad","cli"],author:"NEMAR Team",license:"CC-BY-NC-ND-4.0",repository:{type:"git",url:"git+https://github.com/nemarOrg/nemar-cli.git"},bugs:{url:"https://github.com/nemarOrg/nemar-cli/issues"},homepage:"https://docs.nemar.org",engines:{bun:">=1.0.0"},files:["dist","scripts/postinstall-check.mjs","scripts/recover-datasets.json","scripts/withdrawn-datasets.json","README.md","LICENSE"],dependencies:{chalk:"^5.3.0",commander:"^12.1.0",conf:"^13.0.1",inquirer:"^9.2.15",ora:"^8.0.1",semver:"^7.8.5",zod:"^3.23.8"},"lint-staged":{"src/**/*.{ts,tsx}":["biome check --fix"],"backend/src/**/*.{ts,tsx}":["biome check --fix"]},devDependencies:{"@anthropic-ai/sdk":"^0.132.1","@asteasolutions/zod-to-openapi":"^7.3.4","@biomejs/biome":"1.9.4","@types/bun":"latest","@types/inquirer":"^9.0.7","@types/semver":"^7.8.0",ajv:"^8.20.0","ajv-formats":"^3.0.1",husky:"^9.1.7","lint-staged":"^16.3.2",typescript:"^5.5.4",wrangler:"^4.70.0",yaml:"^2.8.4"}}});var Ji;var Df=I(()=>{Lte();Ji=Bte.version});import{mkdirSync as EJe,readdirSync as SJe,unlinkSync as $Je,writeFileSync as kJe}from"fs";import{join as w2}from"path";function Wte(){Ef=!0}function Bl(){return Ef}function Kte(e,t=process.env){return e.includes("--debug")||t.NEMAR_DEBUG==="1"}function dh(e){Gte=e,Zt(`Step: ${e}`)}function fh(){Vte=!0}function Jte(){return Vte}function Qt(){Hte=!0}function Yte(){return Hte}function Zt(e){if(Ef)process.stderr.write(`[debug] ${e}
102
+ `))}var Nte,bJe,vJe=4000;var lh=I(()=>{Nt();Nte={git:{name:"git",purpose:"version control for dataset metadata",cmd:["git","--version"],required:!0,installInstructions:{macos:"brew install git (or install Xcode Command Line Tools)",linux:"sudo apt-get install git OR sudo dnf install git",windows:"winget install Git.Git (or https://git-scm.com/download/win)"}},"git-annex":{name:"git-annex",purpose:"large-file data transfer (upload/download)",cmd:["git-annex","version"],required:!0,installInstructions:{macos:"brew install git-annex",linux:"sudo apt-get install git-annex OR sudo dnf install git-annex",windows:"Download the installer from https://git-annex.branchable.com/install/Windows/"}},gh:{name:"GitHub CLI (gh)",purpose:"GitHub authentication + repository operations",cmd:["gh","--version"],required:!0,installInstructions:{macos:"brew install gh",linux:"See https://cli.github.com/manual/installation",windows:"winget install GitHub.cli (or: scoop install gh)"}},aws:{name:"AWS CLI",purpose:"S3 data upload/download",cmd:["aws","--version"],required:!0,installInstructions:{macos:"brew install awscli",linux:"pip install awscli OR sudo snap install aws-cli --classic",windows:"winget install Amazon.AWSCLI (or the MSI from https://aws.amazon.com/cli/)"}},deno:{name:"Deno",purpose:"BIDS validation",cmd:["deno","--version"],required:!0,installInstructions:{macos:"brew install deno (or: curl -fsSL https://deno.land/install.sh | sh)",linux:"curl -fsSL https://deno.land/install.sh | sh",windows:"winget install DenoLand.Deno (or: irm https://deno.land/install.ps1 | iex)"}}},bJe={upload:["git-annex","gh","aws","deno"],download:["gh"],clone:["git","gh"],push:["git-annex","gh"],publish:["gh","aws"],update:["git","gh"],release:["git","gh"]}});var Bte;var Lte=I(()=>{Bte={name:"nemar-cli",packageManager:"bun@1.4.3",version:"0.10.17-PR1720.80985fa",description:"CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource) dataset management",type:"module",main:"dist/index.js",bin:{nemar:"dist/index.js"},scripts:{dev:"bun run src/index.ts",build:"bun build src/index.ts --outdir dist --target bun --minify && sed '1s|#!/usr/bin/env node|#!/usr/bin/env bun|' dist/index.js > dist/index.js.tmp && mv dist/index.js.tmp dist/index.js",test:"bun test",lint:"biome check src/","lint:scrub":"biome check scripts/scrub shared/identifier-scrub.ts test/scrub","test:scrub":"bun test --preload ./test/scrub/helpers/temp-dirs-preload.ts --path-ignore-patterns='__run_every_scrub_suite__' test/scrub test/identifier-scan.test.ts test/identifier-scrub.test.ts test/identifier-dates.test.ts test/identifier-fleet.test.ts","migrations:d1-check":"bun run scripts/d1-migration-check.ts","zarr:geometry-check":"bun run backend/scripts/zarr-geometry-conformance.ts","lint:fix":"biome check --fix src/",format:"biome format --write src/",typecheck:"tsc --noEmit && tsc --noEmit -p backend","generate-openapi":"bun run scripts/generate-openapi.ts",prepublishOnly:"bun run build",prepare:"husky",postinstall:"bun scripts/postinstall-check.mjs",deploy:"wrangler deploy",preview:"wrangler dev"},keywords:["nemar","bids","neuroimaging","eeg","emg","datalad","cli"],author:"NEMAR Team",license:"CC-BY-NC-ND-4.0",repository:{type:"git",url:"git+https://github.com/nemarOrg/nemar-cli.git"},bugs:{url:"https://github.com/nemarOrg/nemar-cli/issues"},homepage:"https://docs.nemar.org",engines:{bun:">=1.0.0"},files:["dist","scripts/postinstall-check.mjs","scripts/recover-datasets.json","scripts/withdrawn-datasets.json","README.md","LICENSE"],dependencies:{chalk:"^5.3.0",commander:"^12.1.0",conf:"^13.0.1",inquirer:"^9.2.15",ora:"^8.0.1",semver:"^7.8.5",zod:"^3.23.8"},"lint-staged":{"src/**/*.{ts,tsx}":["biome check --fix"],"backend/src/**/*.{ts,tsx}":["biome check --fix"]},devDependencies:{"@anthropic-ai/sdk":"^0.132.1","@asteasolutions/zod-to-openapi":"^7.3.4","@biomejs/biome":"1.9.4","@types/bun":"latest","@types/inquirer":"^9.0.7","@types/semver":"^7.8.0",ajv:"^8.20.0","ajv-formats":"^3.0.1",husky:"^9.1.7","lint-staged":"^16.3.2",typescript:"^5.5.4",wrangler:"^4.70.0",yaml:"^2.8.4"}}});var Ji;var Df=I(()=>{Lte();Ji=Bte.version});import{mkdirSync as EJe,readdirSync as SJe,unlinkSync as $Je,writeFileSync as kJe}from"fs";import{join as w2}from"path";function Wte(){Ef=!0}function Bl(){return Ef}function Kte(e,t=process.env){return e.includes("--debug")||t.NEMAR_DEBUG==="1"}function dh(e){Gte=e,Zt(`Step: ${e}`)}function fh(){Vte=!0}function Jte(){return Vte}function Qt(){Hte=!0}function Yte(){return Hte}function Zt(e){if(Ef)process.stderr.write(`[debug] ${e}
103
103
  `)}function OJe(e){let t={};for(let[r,n]of Object.entries(e))t[r]=AJe.has(r.toLowerCase())?"[REDACTED]":n;return t}function Zte(e){let t=e.indexOf("@");if(t<=0)return"***";return`${e[0]}***${e.slice(t)}`}function v2(e,t,r=0){if(r>FJe)return"[REDACTED: depth]";if(Array.isArray(t))return t.map((n)=>v2(e,n,r+1));if(t&&typeof t==="object"){let n={};for(let[i,o]of Object.entries(t))n[i]=v2(i,o,r+1);return n}if(typeof t==="string"){if(TJe.test(e))return"[REDACTED]";return t.replace(Xte,Zte)}return t}function _2(e){return e.replace(PJe,"Bearer [REDACTED]").replace(IJe,"[REDACTED_AWS_KEY]").replace(NJe,"$1[REDACTED]").replace(jJe,"$1$2=[REDACTED]").replace(Xte,Zte)}function MJe(e){return _2(e)}function Ute(e,t=RJe){if(e===void 0)return;let r=e;try{let n=JSON.parse(e);r=JSON.stringify(v2("",n))}catch{}if(r=_2(r),Buffer.byteLength(r,"utf8")>t)r=`${Buffer.from(r,"utf8").subarray(0,t).toString("utf8")}... [truncated]`;return r}function Qx(e){if(!Ef)return;let t=MJe(e.url);try{let r={...e,url:t,requestHeaders:e.requestHeaders?OJe(e.requestHeaders):void 0,requestBody:Ute(e.requestBody),responseBody:Ute(e.responseBody)};Zx.push(r),Zt(`${e.method} ${t} -> ${e.status??"ERROR"} (${e.durationMs}ms)`)}catch(r){let n=q(r);Zx.push({method:e.method,url:t,status:e.status,durationMs:e.durationMs,note:`redaction failed: ${n}`}),Zt(`redaction failed for ${e.method} ${t}: ${n}`)}}async function qJe(){let e=[];try{let t=process.versions.bun?`Bun ${process.versions.bun}`:`Node ${process.version}`;e.push(`CLI version: ${Ji}`),e.push(`OS/Arch: ${process.platform}/${process.arch}`),e.push(`Runtime: ${t}`)}catch(t){e.push(`(could not read CLI/OS/runtime info: ${q(t)})`)}e.push(""),e.push("Active account:");try{let t=Ft();if(t.apiKey){if(t.username)e.push(` Username: ${t.username}`);if(e.push(` API URL: ${t.apiUrl}`),t.role)e.push(` Role: ${t.role}`);e.push(` Sandbox completed: ${!!t.sandboxCompleted}`)}else e.push(" (not authenticated)")}catch(t){e.push(` (could not read account config: ${q(t)})`)}e.push(""),e.push("External tools:");try{let t=await ch();for(let r of t){let n=r.available?r.version??"installed":r.timedOut?"(timed out)":"not installed";e.push(` ${r.name}: ${n}`)}}catch(t){e.push(` (could not probe external tools: ${q(t)})`)}return e}async function D2(){return(await qJe()).join(`
104
104
  `)}async function Qte(){if(!Ef||Xx!==void 0)return;try{Xx=await D2()}catch(e){let t=q(e);Xx=`(could not build environment report: ${t})`,Zt(`environment snapshot failed: ${t}`)}}function ere(e){if(zte.has(e))return{flag:e};for(let t of zte){if(!e.startsWith(t)||e.length<=t.length)continue;if(t.length===2)return{flag:t,kind:"short-attached"};if(e[t.length]==="=")return{flag:t,kind:"long-eq"}}return null}function LJe(e){let t=[];for(let r=0;r<e.length;r++){let n=e[r],i=ere(n);if(!i){t.push(n);continue}if(i.kind==="long-eq")t.push(`${i.flag}=[REDACTED]`);else if(i.kind==="short-attached")t.push(`${i.flag}[REDACTED]`);else if(t.push(n),r+1<e.length)t.push("[REDACTED]"),r++}return t}function BJe(e){let t=[];for(let r=0;r<e.length;r++){let n=e[r],i=ere(n);if(!i){t.push(n);continue}if(!i.kind&&r+1<e.length)r++}return t}function UJe(e){let t=[];for(let n of BJe(e)){if(n.startsWith("-"))continue;if(t.push(n),t.length===2)break}return(t.length>0?t.join("-"):"nemar").replace(/[^a-zA-Z0-9_-]/g,"_")}function zJe(e,t){let r=[];if(r.push("NEMAR CLI Debug Log"),r.push(`Generated: ${new Date().toISOString()}`),r.push(`Command: nemar ${_2(LJe(e).join(" "))}`),r.push(""),r.push(Xx??"(environment snapshot unavailable)"),r.push(""),r.push("HTTP requests:"),Zx.length===0)r.push(" (none)");else Zx.forEach((n,i)=>{if(r.push(` [${i+1}] ${n.method} ${n.url} -> ${n.status??"ERROR"} (${n.durationMs}ms)`),n.error)r.push(` Error: ${n.error}`);if(n.note)r.push(` Note: ${n.note}`);if(n.requestHeaders)r.push(` Request headers: ${JSON.stringify(n.requestHeaders)}`);if(n.requestBody)r.push(` Request body: ${n.requestBody}`);if(n.responseBody)r.push(` Response body: ${n.responseBody}`)});return r.push(""),r.push(`Failing step: ${Gte??"(none recorded)"}`),r.push(`Exit code: ${t}`),`${r.join(`
105
105
  `)}
@@ -252,7 +252,7 @@ ${s.join(`
252
252
 
253
253
  `);return{title:i,summary:o.join(`
254
254
  `),text:a}}Ul();Jt();Yn();import{spawn as Qet}from"child_process";function ett(e,t){if(e==="darwin")return{command:"open",args:[t]};if(e==="win32")return{command:"cmd",args:["/c","start","",t]};if(e==="linux")return{command:"xdg-open",args:[t]};return null}function zf(e){if(process.env.NEMAR_NO_BROWSER==="1")return!1;let t=ett(process.platform,e);if(!t)return!1;try{let r=Qet(t.command,t.args,{stdio:"ignore",detached:!0});return r.on("error",(n)=>{Zt(`openInBrowser: ${t.command} failed: ${n instanceof Error?n.message:n}`)}),r.unref(),!0}catch(r){return Zt(`openInBrowser: could not spawn ${t.command}: ${r instanceof Error?r.message:r}`),!1}}Yi();Yn();Nt();var Uc="nemarDatasets",Vf=20000,mae=15000;function iv(e,t){return`https://github.com/${Uc}/${e}/pull/${t}`}function yae(e,t){return`gh pr review ${t} --repo ${Uc}/${e} --approve`}function ss(e=process.env){let t=e.NEMAR_GITHUB_API_URL?.trim();if(!t)return"https://api.github.com";try{let r=new URL(t),n=["127.0.0.1","localhost","[::1]"].includes(r.hostname);if(r.protocol==="http:"&&n)return t.replace(/\/+$/,"")}catch{}throw Error("NEMAR_GITHUB_API_URL is set but is not an http://127.0.0.1, http://localhost or http://[::1] address. It is only for tests, so it is refused rather than ignored; unset it to use GitHub.")}async function bae(e=process.env,t=k){let r=e.GH_TOKEN?.trim();if(r)return{ok:!0,token:r,source:"GH_TOKEN"};try{let{stdout:n,exitCode:i,stderr:o,timedOut:s}=await t(["gh","auth","token","--hostname","github.com"],{unsetEnv:["GH_TOKEN","GITHUB_TOKEN"],timeout:mae,sensitiveOutput:!0});if(s)return{ok:!1,reason:`gh did not answer within ${mae/1000} seconds (a locked keyring waiting for a prompt?). Set GH_TOKEN, or run 'gh auth status'.`};if(i===0&&n.trim())return{ok:!0,token:n.trim(),source:"gh"};return{ok:!1,reason:`gh has no signed-in account for github.com (${o.trim().split(`
255
- `)[0]||`exit ${i}`}).`}}catch(n){let i=n instanceof Error?n.message:String(n);return{ok:!1,reason:i.includes("ENOENT")||i.includes("not found")?"The GitHub CLI (gh) is not installed.":`gh could not be run: ${i}`}}}function Hf(e){return{Authorization:`Bearer ${e}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"nemar-cli pr-reviews","Content-Type":"application/json"}}async function xae(e,t=ss()){let r;try{r=await fetch(`${t}/user`,{headers:Hf(e),signal:AbortSignal.timeout(Vf)})}catch(s){return{ok:!1,kind:"unreachable",reason:`GitHub could not be reached (${s instanceof Error?s.message:String(s)}).`}}if(r.status===401)return{ok:!1,kind:"rejected",reason:"GitHub rejected this token."};if(!r.ok){let s=await r.text().catch(()=>"");if(r.status===403&&!/rate limit|abuse/i.test(s))return{ok:!1,kind:"not_a_person",reason:"This token does not belong to a GitHub user (an app or workflow token cannot approve for you)."};return{ok:!1,kind:"unreachable",reason:`GitHub answered HTTP ${r.status} when asked whose token this is. Try again in a moment.`}}let n=Symbol("unreadable"),i=await r.json().catch(()=>n);if(i===n)return{ok:!1,kind:"unreachable",reason:"GitHub answered, but the answer could not be read when asked whose token this is. Try again in a moment."};let o=i;if(typeof o?.login!=="string"||typeof o.id!=="number"||o.type!=="User"||o.login.endsWith("[bot]"))return{ok:!1,kind:"not_a_person",reason:"This token does not belong to a GitHub user, so it cannot approve for you."};return{ok:!0,user:{login:o.login,id:o.id}}}function wae(e,t){if(!e)return"unlinked";return e.toLowerCase()===t.toLowerCase()?"match":"mismatch"}function Nh(e,t){let r=typeof t==="object"&&t!==null&&"message"in t?Jl(t.message,160):"";return r?`${r} (HTTP ${e})`:`GitHub answered HTTP ${e}.`}async function ov(e,t,r,n=ss()){let i;try{i=await fetch(`${n}/repos/${Uc}/${t}/pulls/${r}`,{headers:Hf(e),signal:AbortSignal.timeout(Vf)})}catch(u){return{ok:!1,status:0,reason:`GitHub could not be reached (${u instanceof Error?u.message:String(u)}).`}}let o=await i.json().catch(()=>null);if(!i.ok)return{ok:!1,status:i.status,reason:i.status===404?`${Uc}/${t} has no pull request #${r}, or your GitHub account cannot see it.`:Nh(i.status,o)};let s=o?.head,a=o?.base,c=o?.user;if(typeof s?.sha!=="string"||!/^[0-9a-f]{40}$/.test(s.sha))return{ok:!1,status:i.status,reason:"GitHub's answer had no head commit."};return{ok:!0,value:{state:o?.merged===!0?"merged":o?.state==="open"?"open":"closed",draft:o?.draft===!0,baseRef:typeof a?.ref==="string"?a.ref:"",headSha:s.sha,authorLogin:typeof c?.login==="string"?c.login:"",mergeableState:typeof o?.mergeable_state==="string"?o.mergeable_state:"unknown"}}}function vae(e){if(e.state==="merged")return"This pull request is already merged.";if(e.state==="closed")return"This pull request is closed.";if(e.baseRef!=="main")return`This pull request targets ${Jl(e.baseRef,40)||"another branch"}, not main. The review queue covers pull requests to main.`;if(e.draft)return"This pull request is a draft. Ask the author to mark it ready first.";return null}function ttt(e){return typeof e==="string"&&Uf.includes(e)?e:null}var rtt=["pass","fail","uncertain"];function _ae(e,t){let r=typeof e==="object"&&e!==null?e:null;if(!r)return{ok:!1,why:"the NEMAR API sent no review"};let n=ttt(r.verdict);if(n===null)return{ok:!1,why:"the NEMAR API sent a verdict this version of the CLI does not know; update the CLI"};if(r.head_sha!==t)return{ok:!1,why:"the NEMAR API answered about a different commit than GitHub reports"};let i=r.stale_verdict??null;if(i!==null&&!rtt.includes(i))return{ok:!1,why:"the NEMAR API sent a review this version of the CLI cannot read"};let o=r.review_current??null;if(o!==null&&typeof o!=="boolean")return{ok:!1,why:"the NEMAR API sent a review this version of the CLI cannot read"};let s=r.author?.standing,a=s?.paused===!0?`The contributor's pull requests are not reviewed automatically (paused ${s.because==="maintainer"?"by a maintainer":"by their record"}).`:null;return{ok:!0,verdict:n,detail:typeof r.detail==="string"?r.detail:null,staleVerdict:i,reviewCurrent:o,contributorNote:a,outcome:o===!0?r.review?.outcome??null:null}}function Dae(e){if(e.unread)return{kind:"needs_force",reason:`The automated review could not be read (${e.unread}), so its verdict is unknown. Pass --force to approve without it.`};switch(e.verdict){case"pass":return{kind:"proceed"};case"fail":return{kind:"needs_force",reason:"The automated review says this pull request needs changes. Read it with `show`, and pass --force to approve it anyway."};case"in_progress":return{kind:"needs_force",reason:"The automated review of this commit is still running. Wait for it, or pass --force to approve without it."};case"uncertain":return{kind:"confirm",warning:"The automated review could not decide whether this is a good change."};case"could_not_decide":return{kind:"confirm",warning:"The automated review ended without a verdict."};case"not_reviewed":return{kind:"confirm",warning:e.staleVerdict===null?"The automated review has not read this commit.":`The automated review read a different commit of this pull request (it said: ${e.staleVerdict}), not this one.`}}}function sv(e){return{ok:!1,outcome:"unknown",status:0,reason:`GitHub did not answer (${e instanceof Error?e.message:String(e)}).`}}async function UC(e,t,r,n,i,o,s=ss()){let a;try{a=await fetch(`${s}/repos/${Uc}/${t}/pulls/${r}/reviews`,{method:"POST",headers:Hf(e),body:JSON.stringify({commit_id:n,event:"APPROVE",body:o}),signal:AbortSignal.timeout(Vf)})}catch(d){return sv(d)}let c=await a.json().catch(()=>null);if(!a.ok)return{ok:!1,outcome:a.status>=500?"unknown":"refused",status:a.status,reason:Nh(a.status,c)};if(typeof c?.state!=="string")return{ok:!1,outcome:"unknown",status:a.status,reason:`GitHub answered HTTP ${a.status}, but its answer could not be read.`};let u=typeof c.user?.login==="string"?c.user.login:"";if(c.state!=="APPROVED"||c.commit_id!==n||u.toLowerCase()!==i.toLowerCase()){let d=[c.state!=="APPROVED"?`state ${Jl(c.state,20)}`:"",u.toLowerCase()!==i.toLowerCase()?`by @${Jl(u,40)||"?"}`:"",c.commit_id!==n?`commit ${typeof c.commit_id==="string"?Jl(c.commit_id,40).slice(0,7):"?"}`:""].filter(Boolean);return{ok:!1,outcome:"different",status:a.status,reason:`GitHub recorded a review, but not the approval that was asked for (${d.join(", ")}).`}}return{ok:!0}}async function Eae(e,t,r,n,i=ss()){let o;try{o=await fetch(`${i}/repos/${Uc}/${t}/issues/${r}/comments`,{method:"POST",headers:Hf(e),body:JSON.stringify({body:n}),signal:AbortSignal.timeout(Vf)})}catch(a){return sv(a)}let s=await o.json().catch(()=>null);if(!o.ok)return{ok:!1,outcome:o.status>=500?"unknown":"refused",status:o.status,reason:Nh(o.status,s)};if(typeof s?.id!=="number")return{ok:!1,outcome:"unknown",status:o.status,reason:`GitHub answered HTTP ${o.status}, but its answer could not be read.`};return{ok:!0}}async function Sae(e,t,r,n=ss()){let i;try{i=await fetch(`${n}/repos/${Uc}/${t}/pulls/${r}`,{method:"PATCH",headers:Hf(e),body:JSON.stringify({state:"closed"}),signal:AbortSignal.timeout(Vf)})}catch(s){return sv(s)}let o=await i.json().catch(()=>null);if(!i.ok)return{ok:!1,outcome:i.status>=500?"unknown":"refused",status:i.status,reason:Nh(i.status,o)};if(typeof o?.state!=="string")return{ok:!1,outcome:"unknown",status:i.status,reason:`GitHub answered HTTP ${i.status}, but its answer could not be read.`};if(o.state!=="closed")return{ok:!1,outcome:"different",status:i.status,reason:`GitHub answered, but the pull request is ${Jl(o.state,20)}, not closed.`};return{ok:!0}}var av=["merge","squash","rebase"],ntt="clean",itt=new Map([["blocked","a required check or review is not satisfied"],["behind","the branch is behind main"],["dirty","it has merge conflicts"],["unstable","a check or status that is not required is not passing or has not reported, for example the automated review holding the pull request"],["draft","it is a draft"],["unknown","GitHub has not said whether it can be merged"]]);function hae(e){return itt.get(e)??"this tool merges only a pull request GitHub reports as clean"}function cv(e){let t=e&&e.length>0?e:"unknown";if(t===ntt)return{ok:!0};return{ok:!1,why:`GitHub reports this pull request as '${gae(t)}' (${hae(t)}), so a merge would not be attempted.`,card:`${hae(t)} (GitHub: ${gae(t)})`,advice:t==="unknown"?"retry":"without_merge"}}function gae(e){return/^[a-z][a-z_]{0,29}$/.test(e)?e:"unrecognised"}async function $ae(e,t,r,n,i={}){let o=i.base??ss(),s=i.sleep??((d)=>new Promise((f)=>setTimeout(f,d))),a=i.tries??5,c=n.mergeableState,u=c===void 0?0:1;for(;;){if(c===void 0){let d=await ov(e,t,r,o);if(!d.ok)return{ok:!1,kind:"unreadable",status:d.status,reason:d.reason};if(d.value.state!=="open")return{ok:!1,kind:"closed",merged:d.value.state==="merged"};if(d.value.headSha!==n.headSha)return{ok:!1,kind:"moved"};c=d.value.mergeableState,u++}if(c!=="unknown"||u>=a)return{ok:!0,state:c};await s(1000),c=void 0}}function kae(e){if(e.kind==="moved")return{ok:!1,why:"The pull request changed while it was being read.",card:"the pull request changed while it was being read",advice:"retry"};if(e.kind==="closed")return{ok:!1,why:`The pull request is no longer open (it was ${e.merged?"merged":"closed"}).`,card:"the pull request is no longer open",advice:"none"};let t=e.reason.replace(/\.$/,"");return{ok:!1,why:`Could not check whether it can be merged (${t}).`,card:`could not be checked (${t})`,advice:"retry"}}async function lv(e,t,r,n,i={}){let o=await $ae(e,t,r,n,i);return o.ok?cv(o.state):kae(o)}async function zC(e,t,r,n,i={}){let o=await lv(e,t,r,{headSha:n},i);return o.ok?o:{...o,why:`Checked again just before approving: ${o.why}`}}async function VC(e,t,r,n,i,o={}){let s=o.base??ss(),a=await $ae(e,t,r,{headSha:n},o);if(!a.ok){if(a.kind==="moved")return{ok:!1,outcome:"not_sent",status:409,reason:"The pull request changed after it was approved, so it was not merged."};if(a.kind==="closed")return{ok:!1,outcome:"not_sent",status:409,reason:`Not merged: ${kae(a).why} The approval stands.`};return{ok:!1,outcome:"not_sent",status:a.status,reason:`Not merged: ${a.reason} The approval stands.`}}let c=cv(a.state);if(!c.ok)return{ok:!1,outcome:"not_sent",status:405,mergeableState:a.state,reason:`Not merged: ${c.why} The approval stands.`};let u;try{u=await fetch(`${s}/repos/${Uc}/${t}/pulls/${r}/merge`,{method:"PUT",headers:Hf(e),body:JSON.stringify({sha:n,merge_method:i}),signal:AbortSignal.timeout(Vf)})}catch(f){return sv(f)}let d=await u.json().catch(()=>null);if(!u.ok)return{ok:!1,outcome:u.status>=500?"unknown":"refused",status:u.status,reason:Nh(u.status,d)};if(d?.merged!==!0)return{ok:!1,outcome:"unknown",status:u.status,reason:`GitHub answered HTTP ${u.status}, but did not say the pull request was merged.`};return{ok:!0}}function Rae(e){switch(e.trim().toLowerCase()){case"y":case"yes":return"approve";case"n":case"no":return"close";case"c":case"comment":return"comment";case"d":case"details":return"details";case"s":case"skip":return"skip";case"q":case"quit":return"quit";default:return null}}function Aae(e){let t=[];if(e.bids!=="pass"||e.version!=="pass")t.push(`A required check is not green (BIDS ${Cae(e.bids)}, version ${Cae(e.version)}), so GitHub would not let it merge.`);if(!e.merge.ok)t.push(e.merge.why);if(e.gate.kind==="needs_force"&&!e.force)t.push(e.gate.reason);return t.length===0?{ok:!0}:{ok:!1,reason:t.join(" ")}}function Cae(e){switch(e){case"pass":return"ok";case"fail":return"failing";case"pending":return"pending";case"missing":return"missing";default:return"unknown"}}import{createInterface as ott}from"readline";class HC{rl;lines=[];waiting=[];output;typeAhead;ended=!1;wasInterrupted=!1;constructor(e=process.stdin,t=process.stdout,r={}){this.output=t,this.typeAhead=r.typeAhead??(e.isTTY===!0?"discard":"keep"),this.rl=ott({input:e,output:t,terminal:e.isTTY===!0}),this.rl.on("line",(n)=>{let i=this.waiting.shift();if(i)i(n);else this.lines.push(n)}),this.rl.on("SIGINT",()=>{this.wasInterrupted=!0,this.lines.length=0,this.rl.close()}),this.rl.on("close",()=>{this.ended=!0;for(let n of this.waiting.splice(0))n(null)})}get interrupted(){return this.wasInterrupted}ask(e){if(this.wasInterrupted)return Promise.resolve(null);let t=this.lines.shift();if(t!==void 0)return this.output.write(`${e}${t}
255
+ `)[0]||`exit ${i}`}).`}}catch(n){let i=n instanceof Error?n.message:String(n);return{ok:!1,reason:i.includes("ENOENT")||i.includes("not found")?"The GitHub CLI (gh) is not installed.":`gh could not be run: ${i}`}}}function Hf(e){return{Authorization:`Bearer ${e}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"nemar-cli pr-reviews","Content-Type":"application/json"}}async function xae(e,t=ss()){let r;try{r=await fetch(`${t}/user`,{headers:Hf(e),signal:AbortSignal.timeout(Vf)})}catch(s){return{ok:!1,kind:"unreachable",reason:`GitHub could not be reached (${s instanceof Error?s.message:String(s)}).`}}if(r.status===401)return{ok:!1,kind:"rejected",reason:"GitHub rejected this token."};if(!r.ok){let s=await r.text().catch(()=>"");if(r.status===403&&!/rate limit|abuse/i.test(s))return{ok:!1,kind:"not_a_person",reason:"This token does not belong to a GitHub user (an app or workflow token cannot approve for you)."};return{ok:!1,kind:"unreachable",reason:`GitHub answered HTTP ${r.status} when asked whose token this is. Try again in a moment.`}}let n=Symbol("unreadable"),i=await r.json().catch(()=>n);if(i===n)return{ok:!1,kind:"unreachable",reason:"GitHub answered, but the answer could not be read when asked whose token this is. Try again in a moment."};let o=i;if(typeof o?.login!=="string"||typeof o.id!=="number"||o.type!=="User"||o.login.endsWith("[bot]"))return{ok:!1,kind:"not_a_person",reason:"This token does not belong to a GitHub user, so it cannot approve for you."};return{ok:!0,user:{login:o.login,id:o.id}}}function wae(e,t){if(!e)return"unlinked";return e.toLowerCase()===t.toLowerCase()?"match":"mismatch"}function Nh(e,t){let r=typeof t==="object"&&t!==null&&"message"in t?Jl(t.message,160):"";return r?`${r} (HTTP ${e})`:`GitHub answered HTTP ${e}.`}async function ov(e,t,r,n=ss()){let i;try{i=await fetch(`${n}/repos/${Uc}/${t}/pulls/${r}`,{headers:Hf(e),signal:AbortSignal.timeout(Vf)})}catch(u){return{ok:!1,status:0,reason:`GitHub could not be reached (${u instanceof Error?u.message:String(u)}).`}}let o=await i.json().catch(()=>null);if(!i.ok)return{ok:!1,status:i.status,reason:i.status===404?`${Uc}/${t} has no pull request #${r}, or your GitHub account cannot see it.`:Nh(i.status,o)};let s=o?.head,a=o?.base,c=o?.user;if(typeof s?.sha!=="string"||!/^[0-9a-f]{40}$/.test(s.sha))return{ok:!1,status:i.status,reason:"GitHub's answer had no head commit."};return{ok:!0,value:{state:o?.merged===!0?"merged":o?.state==="open"?"open":"closed",draft:o?.draft===!0,baseRef:typeof a?.ref==="string"?a.ref:"",headSha:s.sha,authorLogin:typeof c?.login==="string"?c.login:"",mergeableState:typeof o?.mergeable_state==="string"?o.mergeable_state:"unknown"}}}function vae(e){if(e.state==="merged")return"This pull request is already merged.";if(e.state==="closed")return"This pull request is closed.";if(e.baseRef!=="main")return`This pull request targets ${Jl(e.baseRef,40)||"another branch"}, not main. The review queue covers pull requests to main.`;if(e.draft)return"This pull request is a draft. Ask the author to mark it ready first.";return null}function ttt(e){return typeof e==="string"&&Uf.includes(e)?e:null}var rtt=["pass","fail","uncertain"];function _ae(e,t){let r=typeof e==="object"&&e!==null?e:null;if(!r)return{ok:!1,why:"the NEMAR API sent no review"};let n=ttt(r.verdict);if(n===null)return{ok:!1,why:"the NEMAR API sent a verdict this version of the CLI does not know; update the CLI"};if(r.head_sha!==t)return{ok:!1,why:"the NEMAR API answered about a different commit than GitHub reports"};let i=r.stale_verdict??null;if(i!==null&&!rtt.includes(i))return{ok:!1,why:"the NEMAR API sent a review this version of the CLI cannot read"};let o=r.review_current??null;if(o!==null&&typeof o!=="boolean")return{ok:!1,why:"the NEMAR API sent a review this version of the CLI cannot read"};let s=r.author?.standing,a=s?.paused===!0?`The contributor's pull requests are not reviewed automatically (paused ${s.because==="maintainer"?"by a maintainer":"by their record"}).`:null;return{ok:!0,verdict:n,detail:typeof r.detail==="string"?r.detail:null,staleVerdict:i,reviewCurrent:o,contributorNote:a,outcome:o===!0?r.review?.outcome??null:null}}function Dae(e){if(e.unread)return{kind:"needs_force",reason:`The automated review could not be read (${e.unread}), so its verdict is unknown. Pass --force to approve without it.`};switch(e.verdict){case"pass":return{kind:"proceed"};case"fail":return{kind:"needs_force",reason:"The automated review says this pull request needs changes. Read it with `show`, and pass --force to approve it anyway."};case"in_progress":return{kind:"needs_force",reason:"The automated review of this commit is still running. Wait for it, or pass --force to approve without it."};case"uncertain":return{kind:"confirm",warning:"The automated review could not decide whether this is a good change."};case"could_not_decide":return{kind:"confirm",warning:"The automated review ended without a verdict."};case"not_reviewed":return{kind:"confirm",warning:e.staleVerdict===null?"The automated review has not read this commit.":`The automated review read a different commit of this pull request (it said: ${e.staleVerdict}), not this one.`}}}function sv(e){return{ok:!1,outcome:"unknown",status:0,reason:`GitHub did not answer (${e instanceof Error?e.message:String(e)}).`}}async function UC(e,t,r,n,i,o,s=ss()){let a;try{a=await fetch(`${s}/repos/${Uc}/${t}/pulls/${r}/reviews`,{method:"POST",headers:Hf(e),body:JSON.stringify({commit_id:n,event:"APPROVE",body:o}),signal:AbortSignal.timeout(Vf)})}catch(d){return sv(d)}let c=await a.json().catch(()=>null);if(!a.ok)return{ok:!1,outcome:a.status>=500?"unknown":"refused",status:a.status,reason:Nh(a.status,c)};if(typeof c?.state!=="string")return{ok:!1,outcome:"unknown",status:a.status,reason:`GitHub answered HTTP ${a.status}, but its answer could not be read.`};let u=typeof c.user?.login==="string"?c.user.login:"";if(c.state!=="APPROVED"||c.commit_id!==n||u.toLowerCase()!==i.toLowerCase()){let d=[c.state!=="APPROVED"?`state ${Jl(c.state,20)}`:"",u.toLowerCase()!==i.toLowerCase()?`by @${Jl(u,40)||"?"}`:"",c.commit_id!==n?`commit ${typeof c.commit_id==="string"?Jl(c.commit_id,40).slice(0,7):"?"}`:""].filter(Boolean);return{ok:!1,outcome:"different",status:a.status,reason:`GitHub recorded a review, but not the approval that was asked for (${d.join(", ")}).`}}return{ok:!0}}async function Eae(e,t,r,n,i=ss()){let o;try{o=await fetch(`${i}/repos/${Uc}/${t}/issues/${r}/comments`,{method:"POST",headers:Hf(e),body:JSON.stringify({body:n}),signal:AbortSignal.timeout(Vf)})}catch(a){return sv(a)}let s=await o.json().catch(()=>null);if(!o.ok)return{ok:!1,outcome:o.status>=500?"unknown":"refused",status:o.status,reason:Nh(o.status,s)};if(typeof s?.id!=="number")return{ok:!1,outcome:"unknown",status:o.status,reason:`GitHub answered HTTP ${o.status}, but its answer could not be read.`};return{ok:!0}}async function Sae(e,t,r,n=ss()){let i;try{i=await fetch(`${n}/repos/${Uc}/${t}/pulls/${r}`,{method:"PATCH",headers:Hf(e),body:JSON.stringify({state:"closed"}),signal:AbortSignal.timeout(Vf)})}catch(s){return sv(s)}let o=await i.json().catch(()=>null);if(!i.ok)return{ok:!1,outcome:i.status>=500?"unknown":"refused",status:i.status,reason:Nh(i.status,o)};if(typeof o?.state!=="string")return{ok:!1,outcome:"unknown",status:i.status,reason:`GitHub answered HTTP ${i.status}, but its answer could not be read.`};if(o.state!=="closed")return{ok:!1,outcome:"different",status:i.status,reason:`GitHub answered, but the pull request is ${Jl(o.state,20)}, not closed.`};return{ok:!0}}var av=["merge","squash","rebase"],ntt="clean",itt=new Map([["blocked","a required check or review is not satisfied"],["behind","the branch is behind main"],["dirty","it has merge conflicts"],["unstable","a check or status that is not required is not passing or has not reported, for example the automated review holding the pull request"],["draft","it is a draft"],["unknown","GitHub has not said whether it can be merged"]]);function hae(e){return itt.get(e)??"this tool merges only a pull request GitHub reports as clean"}function cv(e){let t=e&&e.length>0?e:"unknown";if(t===ntt)return{ok:!0};return{ok:!1,why:`GitHub reports this pull request as '${gae(t)}' (${hae(t)}), so a merge would not be attempted.`,card:`${hae(t)} (GitHub: ${gae(t)})`,advice:t==="unknown"?"retry":"without_merge"}}function gae(e){return/^[a-z][a-z_]{0,29}$/.test(e)?e:"unrecognised"}async function $ae(e,t,r,n,i={}){let o=i.base??ss(),s=i.sleep??((d)=>new Promise((f)=>setTimeout(f,d))),a=i.tries??5,c=n.mergeableState,u=c===null?0:1;for(;;){if(c===null){let d=await ov(e,t,r,o);if(!d.ok)return{ok:!1,kind:"unreadable",status:d.status,reason:d.reason};if(d.value.state!=="open")return{ok:!1,kind:"closed",merged:d.value.state==="merged"};if(d.value.headSha!==n.headSha)return{ok:!1,kind:"moved"};c=d.value.mergeableState,u++}if(c!=="unknown"||u>=a)return{ok:!0,state:c};await s(1000),c=null}}function kae(e){if(e.kind==="moved")return{ok:!1,why:"The pull request changed since it was read.",card:"the pull request changed since it was read",advice:"rerun"};if(e.kind==="closed")return{ok:!1,why:`The pull request is no longer open (it was ${e.merged?"merged":"closed"}).`,card:"the pull request is no longer open",advice:"none"};let t=e.reason.replace(/\.$/,"");return{ok:!1,why:`Could not check whether it can be merged (${t}).`,card:`could not be checked (${t})`,advice:"retry"}}async function lv(e,t,r,n,i={}){let o=await $ae(e,t,r,n,i);return o.ok?cv(o.state):kae(o)}async function zC(e,t,r,n,i={}){let o=await lv(e,t,r,{headSha:n,mergeableState:null},i);return o.ok?o:{...o,why:`Checked again just before approving: ${o.why}`}}async function VC(e,t,r,n,i,o={}){let s=o.base??ss(),a=await $ae(e,t,r,{headSha:n,mergeableState:null},o);if(!a.ok){if(a.kind==="moved")return{ok:!1,outcome:"not_sent",status:409,reason:"The pull request changed after it was approved, so it was not merged."};if(a.kind==="closed")return{ok:!1,outcome:"not_sent",status:409,reason:`Not merged: ${kae(a).why} The approval stands.`};return{ok:!1,outcome:"not_sent",status:a.status,reason:`Not merged: ${a.reason} The approval stands.`}}let c=cv(a.state);if(!c.ok)return{ok:!1,outcome:"not_sent",status:405,merge:c,reason:`Not merged: ${c.why} The approval stands.`};let u;try{u=await fetch(`${s}/repos/${Uc}/${t}/pulls/${r}/merge`,{method:"PUT",headers:Hf(e),body:JSON.stringify({sha:n,merge_method:i}),signal:AbortSignal.timeout(Vf)})}catch(f){return sv(f)}let d=await u.json().catch(()=>null);if(!u.ok)return{ok:!1,outcome:u.status>=500?"unknown":"refused",status:u.status,reason:Nh(u.status,d)};if(d?.merged!==!0)return{ok:!1,outcome:"unknown",status:u.status,reason:`GitHub answered HTTP ${u.status}, but did not say the pull request was merged.`};return{ok:!0}}function Rae(e){switch(e.trim().toLowerCase()){case"y":case"yes":return"approve";case"n":case"no":return"close";case"c":case"comment":return"comment";case"d":case"details":return"details";case"s":case"skip":return"skip";case"q":case"quit":return"quit";default:return null}}function Aae(e){let t=[];if(e.bids!=="pass"||e.version!=="pass")t.push(`A required check is not green (BIDS ${Cae(e.bids)}, version ${Cae(e.version)}), so GitHub would not let it merge.`);if(!e.merge.ok)t.push(e.merge.why);if(e.gate.kind==="needs_force"&&!e.force)t.push(e.gate.reason);return t.length===0?{ok:!0}:{ok:!1,reason:t.join(" ")}}function Cae(e){switch(e){case"pass":return"ok";case"fail":return"failing";case"pending":return"pending";case"missing":return"missing";default:return"unknown"}}import{createInterface as ott}from"readline";class HC{rl;lines=[];waiting=[];output;typeAhead;ended=!1;wasInterrupted=!1;constructor(e=process.stdin,t=process.stdout,r={}){this.output=t,this.typeAhead=r.typeAhead??(e.isTTY===!0?"discard":"keep"),this.rl=ott({input:e,output:t,terminal:e.isTTY===!0}),this.rl.on("line",(n)=>{let i=this.waiting.shift();if(i)i(n);else this.lines.push(n)}),this.rl.on("SIGINT",()=>{this.wasInterrupted=!0,this.lines.length=0,this.rl.close()}),this.rl.on("close",()=>{this.ended=!0;for(let n of this.waiting.splice(0))n(null)})}get interrupted(){return this.wasInterrupted}ask(e){if(this.wasInterrupted)return Promise.resolve(null);let t=this.lines.shift();if(t!==void 0)return this.output.write(`${e}${t}
256
256
  `),Promise.resolve(t);if(this.ended)return Promise.resolve(null);return this.rl.setPrompt(e),this.rl.prompt(),new Promise((r)=>this.waiting.push(r))}async discardTyped(e=0){if(this.typeAhead!=="discard")return 0;if(e>0)await new Promise((r)=>setTimeout(r,e));let t=this.lines.length;return this.lines.length=0,t}close(){this.rl.close()}}var stt=/^(nm|xx|on)\d{6}$/,Oae=200,att=/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})$/;function Ee(e){return typeof e==="string"?e.replace(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu,""):""}function jh(e,t){let r=Ee(e);return r.length>t?`${r.slice(0,t-1)}\u2026`:r}function Pae(e,t=Date.now()){let r=Date.parse(e);if(Number.isNaN(r))return"?";let n=Math.max(0,Math.floor((t-r)/1000));if(n<3600)return`${Math.floor(n/60)}m`;if(n<86400)return`${Math.floor(n/3600)}h`;return`${Math.floor(n/86400)}d`}var ctt={contributor_paused:"contributor paused",rate_limited:"rate limited",daily_limit:"daily limit",unreported:"never reported"};function ltt(e){return ctt[e]??Ee(e).replaceAll("_"," ")}var utt={pass:"pass",fail:"fail",uncertain:"uncertain",not_reviewed:"not reviewed",in_progress:"in progress",could_not_decide:"could not decide"};function zc(e){return utt[e]??Ee(e).replaceAll("_"," ")}function dv(e){switch(e){case"pass":return l.green;case"fail":return l.red;case"uncertain":case"could_not_decide":return l.yellow;case"in_progress":return l.cyan;case"not_reviewed":return l.dim;default:return l.yellow}}function JC(e){let t=zc(e.verdict);if(e.verdict==="not_reviewed"&&e.review_current===!1)return`${t} (other commit)`;return e.detail?`${t} (${ltt(e.detail)})`:t}var dtt={pass:["ok",l.green],fail:["FAIL",l.red],pending:["pending",l.yellow],missing:["none",l.yellow],unknown:["?",l.yellow]};function fv(e,t){let[r,n]=dtt[e]??["?",l.yellow];return n(r.padEnd(t))}function ftt(e,t=Date.now()){if(e.length===0)return[];let r=e.map((f)=>({e:f,mark:f.needs_you?"*":" ",ds:Ee(f.dataset_id),pr:`#${Ee(String(f.pr_number))}`,author:jh(f.author_login,20),from:jh(f.from_fork?`fork ${f.head_label}`:`branch ${f.head_label}`,34),verdict:jh(`${JC(f)}${f.draft?" [draft]":""}`,40),age:Pae(f.created_at,t)})),n=(f,m)=>Math.max(m,...r.map((p)=>f(p).length)),i=n((f)=>f.pr,3),o=n((f)=>f.author,6),s=n((f)=>f.from,4),a=n((f)=>f.verdict,7),c=n((f)=>f.age,3),u=l.dim(` ${"DATASET".padEnd(8)} ${"PR".padStart(i)} ${"AUTHOR".padEnd(o)} ${"FROM".padEnd(s)} ${"REVIEW".padEnd(a)} ${"BIDS".padEnd(7)} ${"VERSION".padEnd(7)} ${"AGE".padStart(c)} LINK`),d=r.map((f)=>`${f.e.needs_you?l.bold.cyan(f.mark):f.mark} ${f.ds.padEnd(8)} ${f.pr.padStart(i)} ${f.author.padEnd(o)} ${l.dim(f.from.padEnd(s))} ${dv(f.e.verdict)(f.verdict.padEnd(a))} ${fv(f.e.bids,7)} ${fv(f.e.version,7)} ${f.age.padStart(c)} ${Ee(f.e.url)}`);return[u,...d]}function GC(e){return e.split(`
257
257
  `).map((t)=>Ee(t.replace(/\s+$/,"")).replace(/<\/?details>/g,"").replace(/<summary>(.*?)<\/summary>/g,"$1").replace(/^### (.*)$/,(r,n)=>l.bold(n)).replace(/\*\*(.+?)\*\*/g,(r,n)=>l.bold(n))).join(`
258
258
  `).replace(/\n{3,}/g,`
@@ -280,8 +280,9 @@ the GitHub account linked to your NEMAR account (if one is linked), and approves
280
280
  you were shown. It asks before approving unless you add --yes. A failing review, a running one, or
281
281
  one that could not be read needs --force. Nothing merges unless you add --merge (or answer y in
282
282
  'next'), and then only if GitHub reports the pull request clean. That is checked BEFORE anything is
283
- approved, and again just before the approval is written: a pull request that is not clean (one the
284
- automated review holds is expected to be reported 'unstable') is neither approved nor merged by
283
+ approved, and again just before the approval is written (GitHub has no approve-and-merge call, so
284
+ that narrows the window to one request and cannot close it): a pull request that is not clean (one
285
+ the automated review holds is expected to be reported 'unstable') is neither approved nor merged by
285
286
  --merge or y, you are told which state GitHub gave and why, and 'approve' without --merge approves
286
287
  it. The merge is then attempted once, and it never tries a merge GitHub reports as blocked.
287
288
  If 'gh' holds no signed-in account, or the token is an app or workflow token,
@@ -311,7 +312,7 @@ Worker, which says so; after 'allow', the same command starts it. --all leaves d
311
312
  before spending (--yes skips that), and stops when the daily pool is spent, exiting 1 so a script
312
313
  knows some were not tried.
313
314
  `).action(async(e,t,r)=>{if(!Vc(r.json))process.exit(1);let n=hv(r.json);if(r.all){if(e!==void 0||t!==void 0)Nr("Give either <dataset> <pr> or --all, not both.",void 0,r.json);await btt(r);return}if(e===void 0||t===void 0)Nr("Give a dataset and a pull request number, or --all.","nemar admin pr-reviews start nm000108 12",r.json);if(r.dryRun)Nr("--dry-run goes with --all.",void 0,r.json);let i=Mh(e,r.json),o=XC(t,r.json),s=r.json?null:S("Starting the review...").start(),a;try{a=await z2(i,o),s?.stop()}catch(c){if(c instanceof V&&YC(c)==="no_such_pull_request"){if(s?.fail(`${i} #${o}: GitHub has no such pull request.`),!s)n(l.red("GitHub has no such pull request."));Qt(),process.exit(1)}as(c,s,"Could not start the review",r.json)}if(r.json){if(console.log(JSON.stringify(a,null,2)),!a.dispatched&&WC.has(a.reason))process.exit(1);return}if(a.dispatched)console.log(`${l.bold(`${i} #${o}`)} ${l.green(Lae(a))}. ${l.dim("The pull request's check shows the review as running.")}`);else{let c=Bae(a),u=WC.has(a.reason);if(console.log(`${l.bold(`${i} #${o}`)} ${u?l.red(c):l.yellow(c)}`),u)process.exit(1)}Gf(a.environment)});async function btt(e){let t=e.json===!0,r=t?null:S("Reading the open pull requests...").start(),n;try{n=await ow({verdicts:["not_reviewed","could_not_decide"]}),r?.stop()}catch(p){as(p,r,"Could not read the open pull requests",e.json)}if(!n.review_enabled)Nr("The automated review is off in this environment (PR_REVIEW_ENABLED), so nothing was started.",`Set PR_REVIEW_ENABLED = "1" in the Worker's [vars], deploy, then run this again.`,e.json);let i=n.entries.filter((p)=>p.draft),o=n.entries.filter((p)=>!p.draft),s=n.truncated||n.skipped.unreadable>0,a={environment:n.environment,drafts:i.length,truncated:s};if(!t){if(console.log(),o.length===0)console.log(s?"Nothing to start in what GitHub returned.":"Nothing to start: no open pull request is waiting for a review.");else{console.log(l.bold(`${o.length} pull request${o.length===1?"":"s"} waiting for a review (none of the current commit, or one that was declined or ended without a verdict)`));for(let p of o)console.log(` ${p.dataset_id} #${p.pr_number} ${Ee(p.author_login)} ${l.dim(jh(p.title,60))}`)}if(i.length>0)console.log(l.dim(`${i.length} draft${i.length===1?"":"s"} left out.`));if(s)console.log(l.yellow("GitHub returned fewer pull requests than exist, or some could not be read, so this list is incomplete."))}if(o.length===0){if(t)console.log(JSON.stringify({...a,results:[],failed:0,not_tried:0},null,2));return}if(e.dryRun){if(t){let p=o.map((g)=>({dataset_id:g.dataset_id,pr_number:g.pr_number,author_login:g.author_login}));console.log(JSON.stringify({...a,dry_run:!0,would_start:p},null,2))}else console.log(l.dim(`
314
- This was a dry run: nothing was started.`));return}if(!t)console.log();if(await Ie(`Start the automated review of ${o.length} pull request${o.length===1?"":"s"}? Each is one model call.`,{yes:e.yes})!=="confirmed")(t?console.error:console.log)("Cancelled."),process.exit(1);let u=[],d=0,f=0;for(let p=0;p<o.length;p++){let g=o[p],h=`${g.dataset_id} #${g.pr_number}`;try{let b=await z2(g.dataset_id,g.pr_number);if(u.push({...b,dataset_id:g.dataset_id,pr_number:g.pr_number}),!t)console.log(` ${h} ${b.dispatched?l.green(Lae(b)):l.yellow(Bae(b))}`);if(b.reason==="daily_limit"){f=o.length-(p+1);break}}catch(b){d++;let x=b instanceof V?YC(b)??`http_${b.statusCode}`:"unknown";if(u.push({dataset_id:g.dataset_id,pr_number:g.pr_number,error:x}),!t){let w=x==="no_such_pull_request";console.log(` ${h} ${l.red(w?"failed: GitHub has no such pull request":`failed: ${b instanceof V?Ee(b.message):"could not be started"}`)}`)}}}if(t)console.log(JSON.stringify({...a,results:u,failed:d,not_tried:f},null,2));else{let p=u.filter((x)=>("reason"in x)),g=p.filter((x)=>x.dispatched).length,h=p.filter((x)=>x.reason==="duplicate").length,b=p.length-g-h;if(console.log(),console.log(`${g} started, ${h} already had a review, ${b} not started, ${d} failed`),f>0)console.log(l.yellow(`Stopped: the platform's daily pool is spent, so ${f} were not tried. It counts the last 24 hours; run this again once reviews from then have aged out.`));Gf(n.environment)}let m=u.some((p)=>("reason"in p)&&!p.dispatched&&WC.has(p.reason));if(d>0||m||f>0)process.exit(1)}function KC(e,t,r){if(e==="none")return null;if(e==="retry")return t==="approve"?"Run the same command again in a moment.":"Try y again in a moment, or s to skip it.";return t==="approve"?"To approve without merging, run it again without --merge. The merge is then yours to make on GitHub.":`To approve it without merging, run: nemar admin pr-reviews approve ${r.dataset} ${r.pr} (without --merge). Here, s leaves it and c comments.`}function Tae(e,t){return Nr(`${e.why} Nothing was approved or merged.`,KC(e.advice,"approve",t)??void 0)}cs.command("approve <dataset> <pr>").description("Approve a pull request as YOURSELF (your GitHub login); merges only with --merge").option("--merge","Merge it after approving, once (refused before anything is approved unless GitHub reports it clean)").option("--method <method>",`How to merge, with --merge: ${av.join(", ")}`,"merge").option("--message <text>","The text of your approval").option("--force","Approve although the review failed, is running, or could not be read").option("--dry-run","Check your token, the pull request and the review and show what would be approved; approve and merge nothing").option("-y, --yes","Do not ask for confirmation (a failing, running or unreadable review still needs --force)").action(async(e,t,r)=>{if(!Vc())process.exit(1);let n=Mh(e),i=XC(t),o=r.method;if(!av.includes(o))Nr(`"${Ee(r.method)}" is not a merge method.`,`Use: ${av.join(", ")}`);let s=iv(n,i),a;try{a=ss()}catch(L){return Nr(L instanceof Error?L.message:String(L))}let{token:c,me:u,match:d}=await Nae(a,{dataset:n,pr:i,url:s}),f=await jae(c,n,i,a);if(!f.ok)return qae(f);let{live:m,head:p,verdict:g,detail:h,reviewCurrent:b,contributorNote:x,unread:w,gate:D}=f.value;if(D.kind==="needs_force"&&!r.force)Nr(D.reason);if(r.merge){let L=await lv(c,n,i,m,{base:a});if(!L.ok)Tae(L,{dataset:n,pr:i})}if(console.log(),console.log(l.bold(`Approve ${n} #${i}`)),console.log(` Author: @${Ee(m.authorLogin)}`),console.log(` Commit: ${Ys(p)}`),console.log(` Review: ${Mae({verdict:g,detail:h,reviewCurrent:b,unread:w})}`),x)console.log(l.yellow(` ${Ee(x)}`));if(console.log(` You are: @${u.login} ${d==="match"?l.dim("(linked to your NEMAR account)"):l.yellow("(your NEMAR account names no GitHub login, so this cannot be checked)")}`),D.kind==="confirm")console.log(l.yellow(` ${D.warning}`));if(D.kind==="needs_force")console.log(l.yellow(" Approving anyway (--force)."));if(r.merge)console.log(` Then: merge (${o}) if GitHub reports it clean`);if(r.dryRun){console.log(),console.log(l.cyan("Dry run: nothing was approved or merged."));return}if(await Ie(`Approve ${n} #${i} as @${u.login}?`,{yes:r.yes})!=="confirmed")console.log(l.dim("Not approved.")),process.exit(1);if(r.merge){let L=await zC(c,n,i,p,{base:a});if(!L.ok)Tae(L,{dataset:n,pr:i})}let E=r.message?.slice(0,2000)||`Approved with nemar admin pr-reviews approve. Automated review of this commit: ${w?"unknown":zc(g)}.`,A=await UC(c,n,i,p,u.login,E,a);if(!A.ok){if(A.outcome==="unknown")console.log(l.yellow(A.reason)),console.log(l.yellow(`Outcome unknown: GitHub may have recorded the approval. Check ${s} before trying again.`)),process.exit(1);if(A.outcome==="different")Nr(A.reason,`Check ${s} before trying again.`);Nr(`Not approved: ${A.reason}`)}if(console.log(l.green(`Approved ${n} #${i} at ${Ys(p)} as @${u.login}.`)),!r.merge){let L=cv(m.mergeableState);console.log(l.dim(!L.ok&&L.advice==="without_merge"?` It is not merged. ${L.why} Merge it on GitHub when you decide to.`:" It is not merged. Run approve again with --merge (this records another approval), or merge it on GitHub."));return}let T=await VC(c,n,i,p,o,{base:a});if(!T.ok){if(console.log(l.yellow(T.reason)),T.outcome==="unknown")console.log(l.yellow(`Outcome unknown: GitHub may have merged it. Check ${s} before trying again.`));process.exit(1)}console.log(l.green(`Merged ${n} #${i} (${o}).`))});function xtt(e){let t=[e.merged&&`${e.merged} merged`,e.approved&&`${e.approved} approved but not merged`,e.closed&&`${e.closed} closed`,e.commented&&`${e.commented} commented`,e.skipped&&`${e.skipped} skipped`,e.failed&&`${e.failed} failed`,e.unknown&&`${e.unknown} with an unknown outcome (check the pull request)`].filter(Boolean);return t.length===0?"Nothing was changed.":`Done: ${t.join(", ")}.`}function wtt(e){return e.skipped+e.failed+e.unknown+e.approved}function uv(e,t){if(e.outcome==="unknown")return console.log(l.yellow(e.reason)),console.log(l.yellow(`Outcome unknown: GitHub may have ${t.mayHave}. Check ${t.url}.`)),t.tally.unknown++,!0;if(e.outcome==="different")return console.log(l.red(e.reason)),console.log(l.dim(` Check ${t.url}.`)),t.tally.unknown++,!0;if(t.tally[t.bucket]++,e.outcome==="not_sent")return console.log(l.yellow(e.reason)),!1;return console.log(l.red(`Not ${t.didNot}: ${e.reason}`)),!1}function vtt(e){if(e.unread)return`The report could not be read (${Ee(e.unread)}).`;if(e.reviewCurrent===!1)return"The review on record is of another commit, so its report is not shown.";if(e.verdict==="in_progress")return"The review is still running.";if(e.verdict==="not_reviewed")return"This commit has not been reviewed.";return"A review of this commit is on record, but its report could not be read."}cs.command("next").description("Go through the pull requests that need you, one at a time: y approves and squash-merges, n closes with a comment, c comments").option("--dataset <id>","Only this dataset").option("--author <login>","Only pull requests opened by this GitHub login").option("--all","Include pull requests whose review failed or is still running").option("--force","Let y approve although the review failed, is running, or could not be read").option("--once","Handle one pull request and stop").addHelpText("after",`
315
+ This was a dry run: nothing was started.`));return}if(!t)console.log();if(await Ie(`Start the automated review of ${o.length} pull request${o.length===1?"":"s"}? Each is one model call.`,{yes:e.yes})!=="confirmed")(t?console.error:console.log)("Cancelled."),process.exit(1);let u=[],d=0,f=0;for(let p=0;p<o.length;p++){let g=o[p],h=`${g.dataset_id} #${g.pr_number}`;try{let b=await z2(g.dataset_id,g.pr_number);if(u.push({...b,dataset_id:g.dataset_id,pr_number:g.pr_number}),!t)console.log(` ${h} ${b.dispatched?l.green(Lae(b)):l.yellow(Bae(b))}`);if(b.reason==="daily_limit"){f=o.length-(p+1);break}}catch(b){d++;let x=b instanceof V?YC(b)??`http_${b.statusCode}`:"unknown";if(u.push({dataset_id:g.dataset_id,pr_number:g.pr_number,error:x}),!t){let w=x==="no_such_pull_request";console.log(` ${h} ${l.red(w?"failed: GitHub has no such pull request":`failed: ${b instanceof V?Ee(b.message):"could not be started"}`)}`)}}}if(t)console.log(JSON.stringify({...a,results:u,failed:d,not_tried:f},null,2));else{let p=u.filter((x)=>("reason"in x)),g=p.filter((x)=>x.dispatched).length,h=p.filter((x)=>x.reason==="duplicate").length,b=p.length-g-h;if(console.log(),console.log(`${g} started, ${h} already had a review, ${b} not started, ${d} failed`),f>0)console.log(l.yellow(`Stopped: the platform's daily pool is spent, so ${f} were not tried. It counts the last 24 hours; run this again once reviews from then have aged out.`));Gf(n.environment)}let m=u.some((p)=>("reason"in p)&&!p.dispatched&&WC.has(p.reason));if(d>0||m||f>0)process.exit(1)}function KC(e,t,r){if(e==="none")return null;if(e==="retry"||e==="rerun"){if(t==="next")return"s skips it; run 'nemar admin pr-reviews next' again to look again.";return e==="retry"?"Run the same command again in a moment.":"Run the same command again to read it as it is now."}return t==="approve"?"To approve without merging, run it again without --merge. The merge is then yours to make on GitHub.":`To approve it without merging, run: nemar admin pr-reviews approve ${r.dataset} ${r.pr} (without --merge). Here, s leaves it and c comments.`}function Tae(e,t){return Nr(`${e.why} Nothing was approved or merged.`,KC(e.advice,"approve",t)??void 0)}cs.command("approve <dataset> <pr>").description("Approve a pull request as YOURSELF (your GitHub login); merges only with --merge").option("--merge","Merge it after approving, once (refused before anything is approved unless GitHub reports it clean)").option("--method <method>",`How to merge, with --merge: ${av.join(", ")}`,"merge").option("--message <text>","The text of your approval").option("--force","Approve although the review failed, is running, or could not be read").option("--dry-run","Check your token, the pull request and the review and show what would be approved; approve and merge nothing").option("-y, --yes","Do not ask for confirmation (a failing, running or unreadable review still needs --force)").action(async(e,t,r)=>{if(!Vc())process.exit(1);let n=Mh(e),i=XC(t),o=r.method;if(!av.includes(o))Nr(`"${Ee(r.method)}" is not a merge method.`,`Use: ${av.join(", ")}`);let s=iv(n,i),a;try{a=ss()}catch(L){return Nr(L instanceof Error?L.message:String(L))}let{token:c,me:u,match:d}=await Nae(a,{dataset:n,pr:i,url:s}),f=await jae(c,n,i,a);if(!f.ok)return qae(f);let{live:m,head:p,verdict:g,detail:h,reviewCurrent:b,contributorNote:x,unread:w,gate:D}=f.value;if(D.kind==="needs_force"&&!r.force)Nr(D.reason);if(r.merge){let L=await lv(c,n,i,m,{base:a});if(!L.ok)Tae(L,{dataset:n,pr:i})}if(console.log(),console.log(l.bold(`Approve ${n} #${i}`)),console.log(` Author: @${Ee(m.authorLogin)}`),console.log(` Commit: ${Ys(p)}`),console.log(` Review: ${Mae({verdict:g,detail:h,reviewCurrent:b,unread:w})}`),x)console.log(l.yellow(` ${Ee(x)}`));if(console.log(` You are: @${u.login} ${d==="match"?l.dim("(linked to your NEMAR account)"):l.yellow("(your NEMAR account names no GitHub login, so this cannot be checked)")}`),D.kind==="confirm")console.log(l.yellow(` ${D.warning}`));if(D.kind==="needs_force")console.log(l.yellow(" Approving anyway (--force)."));if(r.merge)console.log(` Then: merge (${o}) if GitHub reports it clean`);if(r.dryRun){console.log(),console.log(l.cyan("Dry run: nothing was approved or merged."));return}if(await Ie(`Approve ${n} #${i} as @${u.login}?`,{yes:r.yes})!=="confirmed")console.log(l.dim("Not approved.")),process.exit(1);if(r.merge){let L=await zC(c,n,i,p,{base:a});if(!L.ok)Tae(L,{dataset:n,pr:i})}let E=r.message?.slice(0,2000)||`Approved with nemar admin pr-reviews approve. Automated review of this commit: ${w?"unknown":zc(g)}.`,A=await UC(c,n,i,p,u.login,E,a);if(!A.ok){if(A.outcome==="unknown")console.log(l.yellow(A.reason)),console.log(l.yellow(`Outcome unknown: GitHub may have recorded the approval. Check ${s} before trying again.`)),process.exit(1);if(A.outcome==="different")Nr(A.reason,`Check ${s} before trying again.`);Nr(`Not approved: ${A.reason}`)}if(console.log(l.green(`Approved ${n} #${i} at ${Ys(p)} as @${u.login}.`)),!r.merge){let L=cv(m.mergeableState);console.log(l.dim(!L.ok&&L.advice==="without_merge"?` It is not merged. ${L.why} Merge it on GitHub when you decide to.`:" It is not merged. Run approve again with --merge (this records another approval), or merge it on GitHub."));return}let T=await VC(c,n,i,p,o,{base:a});if(!T.ok){if(console.log(l.yellow(T.reason)),T.outcome==="unknown")console.log(l.yellow(`Outcome unknown: GitHub may have merged it. Check ${s} before trying again.`));process.exit(1)}console.log(l.green(`Merged ${n} #${i} (${o}).`))});function xtt(e){let t=[e.merged&&`${e.merged} merged`,e.approved&&`${e.approved} approved but not merged`,e.closed&&`${e.closed} closed`,e.commented&&`${e.commented} commented`,e.skipped&&`${e.skipped} skipped`,e.failed&&`${e.failed} failed`,e.unknown&&`${e.unknown} with an unknown outcome (check the pull request)`].filter(Boolean);return t.length===0?"Nothing was changed.":`Done: ${t.join(", ")}.`}function wtt(e){return e.skipped+e.failed+e.unknown+e.approved}function uv(e,t){if(e.outcome==="unknown")return console.log(l.yellow(e.reason)),console.log(l.yellow(`Outcome unknown: GitHub may have ${t.mayHave}. Check ${t.url}.`)),t.tally.unknown++,!0;if(e.outcome==="different")return console.log(l.red(e.reason)),console.log(l.dim(` Check ${t.url}.`)),t.tally.unknown++,!0;if(t.tally[t.bucket]++,e.outcome==="not_sent")return console.log(l.yellow(e.reason)),!1;return console.log(l.red(`Not ${t.didNot}: ${e.reason}`)),!1}function vtt(e){if(e.unread)return`The report could not be read (${Ee(e.unread)}).`;if(e.reviewCurrent===!1)return"The review on record is of another commit, so its report is not shown.";if(e.verdict==="in_progress")return"The review is still running.";if(e.verdict==="not_reviewed")return"This commit has not been reviewed.";return"A review of this commit is on record, but its report could not be read."}cs.command("next").description("Go through the pull requests that need you, one at a time: y approves and squash-merges, n closes with a comment, c comments").option("--dataset <id>","Only this dataset").option("--author <login>","Only pull requests opened by this GitHub login").option("--all","Include pull requests whose review failed or is still running").option("--force","Let y approve although the review failed, is running, or could not be read").option("--once","Handle one pull request and stop").addHelpText("after",`
315
316
  For each pull request it shows who opened it, the automated review's summary, whether the two
316
317
  required checks (BIDS and version) are green and whether the version went up, then waits for one
317
318
  answer:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nemar-cli",
3
3
  "packageManager": "bun@1.4.3",
4
- "version": "0.10.17-PR1720.0fefe49",
4
+ "version": "0.10.17-PR1720.80985fa",
5
5
  "description": "CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource) dataset management",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",