nemar-cli 0.10.5-PR1448.fdfd7f1 → 0.10.5-PR1452.6442d66

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 +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -99,7 +99,7 @@ ${t}`,ESe,SSe,$Se=(e,t,r)=>{let n=r===""?"":`with ${r.trim()}() `,o=DSe.bind(nul
99
99
  `)}var pE=!1;var{spawn:mLe}=globalThis.Bun;async function C(e,t={}){let r={...process.env,GIT_TERMINAL_PROMPT:"0",...t.env};for(let u of t.unsetEnv??[])delete r[u];let n=mLe({cmd:e,cwd:t.cwd,...t.stdin===void 0?{}:{stdin:new TextEncoder().encode(t.stdin)},stdout:"pipe",stderr:"pipe",env:r}),o=!1,i;if(t.timeout)i=setTimeout(()=>{o=!0,n.kill()},t.timeout);if(mE()){let u=t.cwd?` (cwd=${t.cwd})`:"";Tf(l.dim(`$ ${e.join(" ")}${u}`))}let s=await new Response(n.stdout).text(),a=await new Response(n.stderr).text(),c=await n.exited;if(i)clearTimeout(i);if(mE()){if(s.trim())Tf(l.dim(s.trimEnd()));if(a.trim())Tf(l.yellow(a.trimEnd()));Tf(l.dim(`(exit ${c})`))}if(o)return{stdout:s,stderr:a||`Command timed out after ${Math.round(t.timeout/1000)}s`,exitCode:c??1,timedOut:!0};return{stdout:s,stderr:a,exitCode:c,timedOut:!1}}var vt=O(()=>{Xe()});function gLe(){if(process.platform==="darwin")return"macos";if(process.platform==="win32")return"windows";return"linux"}function oY(e,t=gLe()){return e.installInstructions[t]}function yLe(e){let t=e.match(/(\d+\.\d+(?:\.\d+)?)/);return t?t[1]:void 0}function xLe(){let e=Number(process.env.TEST_PROBE_TIMEOUT_MS);return Number.isFinite(e)&&e>0?e:bLe}async function iY(e){try{let{exitCode:t,stdout:r,timedOut:n}=await C(e.cmd,{timeout:xLe()});if(n)return{available:!1,timedOut:!0};if(t!==0)return{available:!1};return{available:!0,version:yLe(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 Nf(){let e=Object.entries(nY);return Promise.all(e.map(async([t,r])=>{let{available:n,version:o,timedOut:i}=await iY(r);return{key:t,name:r.name,purpose:r.purpose,required:r.required,available:n,version:o,timedOut:i,installInstruction:oY(r)}}))}async function sY(){let t=(await Nf()).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 Oa(e){let r=hLe[e].map((s)=>nY[s]).filter(Boolean),n=await Promise.all(r.map(async(s)=>{let a=await iY(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 o=n.filter((s)=>!s.available&&!s.timedOut&&s.check.required).map((s)=>({tool:s.check.name,installInstruction:oY(s.check)}));if(o.length===0)return;let i=[`
101
101
  Missing required tools:`];for(let s of o)i.push(` ${s.tool} not installed`),i.push(` Install: ${s.installInstruction}`);throw Error(i.join(`
102
- `))}var nY,hLe,bLe=4000;var jf=O(()=>{vt();nY={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)"}}},hLe={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 cY;var aY=O(()=>{cY={name:"nemar-cli",version:"0.10.5-PR1448.fdfd7f1",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/","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:{"@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",bcryptjs:"^3.0.3",husky:"^9.1.7","lint-staged":"^16.3.2",typescript:"^5.5.4",wrangler:"^4.70.0",yaml:"^2.8.4"}}});var Ei;var qf=O(()=>{aY();Ei=cY.version});import{mkdirSync as vLe,readdirSync as wLe,unlinkSync as DLe,writeFileSync as ELe}from"fs";import{join as hE}from"path";function mY(){Ol=!0}function Fa(){return Ol}function hY(e,t=process.env){return e.includes("--debug")||t.NEMAR_DEBUG==="1"}function Lf(e){pY=e,$r(`Step: ${e}`)}function Bf(){dY=!0}function gY(){return dY}function yE(){fY=!0}function yY(){return fY}function $r(e){if(Ol)process.stderr.write(`[debug] ${e}
102
+ `))}var nY,hLe,bLe=4000;var jf=O(()=>{vt();nY={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)"}}},hLe={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 cY;var aY=O(()=>{cY={name:"nemar-cli",version:"0.10.5-PR1452.6442d66",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/","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:{"@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",bcryptjs:"^3.0.3",husky:"^9.1.7","lint-staged":"^16.3.2",typescript:"^5.5.4",wrangler:"^4.70.0",yaml:"^2.8.4"}}});var Ei;var qf=O(()=>{aY();Ei=cY.version});import{mkdirSync as vLe,readdirSync as wLe,unlinkSync as DLe,writeFileSync as ELe}from"fs";import{join as hE}from"path";function mY(){Ol=!0}function Fa(){return Ol}function hY(e,t=process.env){return e.includes("--debug")||t.NEMAR_DEBUG==="1"}function Lf(e){pY=e,$r(`Step: ${e}`)}function Bf(){dY=!0}function gY(){return dY}function yE(){fY=!0}function yY(){return fY}function $r(e){if(Ol)process.stderr.write(`[debug] ${e}
103
103
  `)}function kLe(e){let t={};for(let[r,n]of Object.entries(e))t[r]=CLe.has(r.toLowerCase())?"[REDACTED]":n;return t}function xY(e){let t=e.indexOf("@");if(t<=0)return"***";return`${e[0]}***${e.slice(t)}`}function gE(e,t,r=0){if(r>ALe)return"[REDACTED: depth]";if(Array.isArray(t))return t.map((n)=>gE(e,n,r+1));if(t&&typeof t==="object"){let n={};for(let[o,i]of Object.entries(t))n[o]=gE(o,i,r+1);return n}if(typeof t==="string"){if(RLe.test(e))return"[REDACTED]";return t.replace(bY,xY)}return t}function bE(e){return e.replace(OLe,"Bearer [REDACTED]").replace(FLe,"[REDACTED_AWS_KEY]").replace(PLe,"$1[REDACTED]").replace(ILe,"$1$2=[REDACTED]").replace(bY,xY)}function TLe(e){return bE(e)}function lY(e,t=$Le){if(e===void 0)return;let r=e;try{let n=JSON.parse(e);r=JSON.stringify(gE("",n))}catch{}if(r=bE(r),Buffer.byteLength(r,"utf8")>t)r=`${Buffer.from(r,"utf8").subarray(0,t).toString("utf8")}... [truncated]`;return r}function P0(e){if(!Ol)return;let t=TLe(e.url);try{let r={...e,url:t,requestHeaders:e.requestHeaders?kLe(e.requestHeaders):void 0,requestBody:lY(e.requestBody),responseBody:lY(e.responseBody)};F0.push(r),$r(`${e.method} ${t} -> ${e.status??"ERROR"} (${e.durationMs}ms)`)}catch(r){let n=T(r);F0.push({method:e.method,url:t,status:e.status,durationMs:e.durationMs,note:`redaction failed: ${n}`}),$r(`redaction failed for ${e.method} ${t}: ${n}`)}}async function NLe(){let e=[];try{let t=process.versions.bun?`Bun ${process.versions.bun}`:`Node ${process.version}`;e.push(`CLI version: ${Ei}`),e.push(`OS/Arch: ${process.platform}/${process.arch}`),e.push(`Runtime: ${t}`)}catch(t){e.push(`(could not read CLI/OS/runtime info: ${T(t)})`)}e.push(""),e.push("Active account:");try{let t=ot();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: ${T(t)})`)}e.push(""),e.push("External tools:");try{let t=await Nf();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: ${T(t)})`)}return e}async function xE(){return(await NLe()).join(`
104
104
  `)}async function _Y(){if(!Ol||O0!==void 0)return;try{O0=await xE()}catch(e){let t=T(e);O0=`(could not build environment report: ${t})`,$r(`environment snapshot failed: ${t}`)}}function vY(e){if(uY.has(e))return{flag:e};for(let t of uY){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 jLe(e){let t=[];for(let r=0;r<e.length;r++){let n=e[r],o=vY(n);if(!o){t.push(n);continue}if(o.kind==="long-eq")t.push(`${o.flag}=[REDACTED]`);else if(o.kind==="short-attached")t.push(`${o.flag}[REDACTED]`);else if(t.push(n),r+1<e.length)t.push("[REDACTED]"),r++}return t}function qLe(e){let t=[];for(let r=0;r<e.length;r++){let n=e[r],o=vY(n);if(!o){t.push(n);continue}if(!o.kind&&r+1<e.length)r++}return t}function MLe(e){let t=[];for(let n of qLe(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 LLe(e,t){let r=[];if(r.push("NEMAR CLI Debug Log"),r.push(`Generated: ${new Date().toISOString()}`),r.push(`Command: nemar ${bE(jLe(e).join(" "))}`),r.push(""),r.push(O0??"(environment snapshot unavailable)"),r.push(""),r.push("HTTP requests:"),F0.length===0)r.push(" (none)");else F0.forEach((n,o)=>{if(r.push(` [${o+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: ${pY??"(none recorded)"}`),r.push(`Exit code: ${t}`),`${r.join(`
105
105
  `)}
@@ -422,7 +422,7 @@ After Approval:
422
422
  - Tags are protected (prevents version manipulation)
423
423
  - Data is protected by S3 Object Lock`).action(async(e,t)=>{if(!Z())return;let r=t.resume?`Resume publication of ${e}`:`Approve and publish ${e}`;console.log(l.cyan(`
424
424
  ${r}
425
- `));let n=!1,o=!0;try{n=(await z0(e)).anonymous===!0}catch{o=!1}let i=Kh(n);if(o)console.log(n?`This is an ANONYMOUS RELEASE and will run ${i.length} of the ${bs.length} orchestrator steps:`:`This will run the following ${i.length}-step orchestrator:`);else console.log(l.yellow(`Could not read the request's state, so this lists all ${i.length} steps; an anonymous release runs fewer.`));let s=Math.ceil(i.length/2);for(let m=0;m<s;m++){let p=i[m],h=i[m+s],y=(b,v)=>{let S=b==="doi_create"&&t.sandbox?`${Nw[b]} (SANDBOX)`:Nw[b];return`${String(v).padStart(2," ")}. ${S}`},x=y(p,m+1).padEnd(34," ");console.log(` ${x}${h?y(h,m+s+1):""}`.trimEnd())}if(n)console.log(),console.log(l.yellow(" The GitHub repository stays PRIVATE and no identifier is published:")),console.log(l.yellow(" the concept and version DOIs stay reserved until the deposit is published for real."));if(console.log(),t.sandbox)console.log(l.yellow("\u2501".repeat(60))),console.log(l.yellow.bold(" SANDBOX MODE ENABLED")),console.log(l.yellow("\u2501".repeat(60))),console.log(l.yellow(" \u2022 DOI will be created in sandbox mode (EZID test shoulder)")),console.log(l.yellow(" \u2022 DOI will NOT be indexed by DataCite")),console.log(l.yellow(" \u2022 DOI will NOT resolve in production")),console.log(l.yellow(" \u2022 Use this for testing workflows only")),console.log(l.yellow("\u2501".repeat(60))),console.log();let a=await $e(`${r}?`,t);if(a!=="confirmed"){console.log(l.dim(a==="declined"?"Skipped":"Cancelled"));return}let c="Running publication workflow (this may take a few minutes)...",u=D(c).start(),d=c;function f(m){let p=m.step.replace(/_/g," "),h=`Step ${m.stepIndex}/${m.stepTotal}: ${p}`;if(m.step==="s3_lock"&&m.s3LockLocked!==void 0&&m.s3LockTotal!==void 0&&m.s3LockTotal>0){let y=(m.s3LockLocked/m.s3LockTotal*100).toFixed(1),x=m.s3LockResumed?" (resumed)":"";return`${h} | Locking S3 objects: ${m.s3LockLocked}/${m.s3LockTotal} (${y}%)${x}`}if(m.step==="s3_lock"&&m.s3LockLocked!==void 0){let y=m.s3LockResumed?" (resumed)":"";return`${h} | Locking S3 objects: ${m.s3LockLocked}${y}`}return h}try{let m=await ql(e,!!t.resume,!!t.sandbox,!!t.skipCiCheck,(p)=>{u.stop();let h=p.step?p.step.replace(/_/g," "):"step";console.log(l.yellow(` [!] ${h} failed: ${p.error}`)),console.log(l.dim(` Retrying in ${Math.round(p.delayMs/1000)}s (attempt ${p.attempt+1}/${p.maxAttempts})...`)),u.start(d)},(p)=>{d=f(p),u.text=d});if(u.succeed(m.message),m.step_results&&m.step_results.length>0){console.log();let p=m.step_results,h=p.length;p.forEach((y,x)=>{let b=`[${String(x+1).padStart(2," ")}/${h}]`,v=y.step.replace(/_/g," ");if(y.status==="completed"){let S=(y.duration_ms/1000).toFixed(1),A=y.attempts>1?` (attempt ${y.attempts})`:"";console.log(` ${l.green("[x]")} ${l.dim(b)} ${v} ${l.dim(`(${S}s${A})`)}`)}else if(y.status==="failed")console.log(` ${l.red("[!]")} ${l.dim(b)} ${v}${y.error?`: ${l.red(y.error)}`:""}`);else console.log(` ${l.dim("[-]")} ${l.dim(b)} ${l.dim(v)} ${l.dim("(skipped)")}`)}),console.log()}else if(m.steps_completed){console.log();for(let p of m.steps_completed)console.log(` ${l.green("[x]")} ${p.replace(/_/g," ")}`);console.log()}if(m.warning)console.log(l.yellow(` Warning: ${m.warning}`))}catch(m){Qe(m,u,"Failed to approve publication",{422:"Fix the CI issues and retry with --resume"});let p=m.stepResults;if(p&&p.length>0){console.log(),console.log(l.dim("Step timeline (last attempt):"));let h=p.length;p.forEach((y,x)=>{let b=`[${String(x+1).padStart(2," ")}/${h}]`,v=y.step.replace(/_/g," "),S=(y.duration_ms/1000).toFixed(1),A=y.attempts>1?` (attempt ${y.attempts})`:"";if(y.status==="completed")console.log(` ${l.green("[x]")} ${l.dim(b)} ${v} ${l.dim(`(${S}s${A})`)}`);else if(y.status==="failed")console.log(` ${l.red("[!]")} ${l.dim(b)} ${v}${y.error?`: ${l.red(y.error)}`:""}`);else console.log(` ${l.dim("[-]")} ${l.dim(b)} ${l.dim(v)} ${l.dim("(skipped)")}`)}),console.log()}}});ue.addCommand(zy);ue.command("revert").description("Revert a dataset to a previous version (creates PR for review)").argument("<dataset-id>","Dataset ID (e.g., nm000104)").argument("[version]","Target version to revert to (e.g., 1.0.0)").option("--list","List available versions without reverting").option("--force","Direct push to main without PR (emergency only)").option("--message <msg>","Custom revert commit message").option("--dir <path>","Use existing local clone instead of cloning fresh").option(Ae,Oe).option(He,je).action(async(e,t,r)=>{if(!Z())return;let n=await tp();if(!n.allPassed){console.log(l.red("Error: Missing prerequisites"));for(let E of n.errors)console.log(l.dim(` - ${E}`));return}let o,i=!0;if(r.dir){if(!Ly(r.dir)){console.log(l.red(`Error: Directory not found: ${r.dir}`));return}o=r.dir,i=!1}else o=Ni(process.cwd(),`${e}-revert-${Date.now()}`);let s=D("Fetching dataset info...").start(),a;try{a=await It(e),s.succeed(`Found dataset: ${a.name}`)}catch(E){if(E instanceof q)if(s.fail(E.message),E.statusCode===404||E.statusCode===400)console.log(l.red(`Error: Dataset ${e} not found`)),console.log(l.dim(` ${E.message}`));else console.log(l.red(`Error: ${E.message}`));else{s.fail("Failed to fetch dataset");let P=E instanceof Error?E.message:String(E);console.log(l.red(`Error: Could not load dataset ${e}: ${P}`))}return}if(!a.github_repo){console.log(l.red("Error: Dataset has no GitHub repository"));return}if(i){let E=D(`Cloning ${e}...`).start(),P=`https://github.com/${a.github_repo}.git`,k=await fr(P,o);if(!k.success){E.fail(`Clone failed: ${k.error}`);return}E.succeed(`Cloned to ${o}`)}let c=await $X(o);if(c.length===0){console.log(l.yellow("No versions found for this dataset")),console.log(l.dim(" Dataset may not have any tagged releases yet"));return}if(r.list){console.log(`
425
+ `));let n=!1,o=null;try{n=(await z0(e)).anonymous===!0}catch(m){o=m instanceof Error?m.message:String(m)}let i=Kh(n);if(o===null)console.log(n?`This is an ANONYMOUS RELEASE and will run ${i.length} of the ${bs.length} orchestrator steps:`:`This will run the following ${i.length}-step orchestrator:`);else console.log(l.yellow(`Could not read the request's state (${o}), so this lists all ${i.length} steps; an anonymous release runs fewer.`));let s=Math.ceil(i.length/2);for(let m=0;m<s;m++){let p=i[m],h=i[m+s],y=(b,v)=>{let S=b==="doi_create"&&t.sandbox?`${Nw[b]} (SANDBOX)`:Nw[b];return`${String(v).padStart(2," ")}. ${S}`},x=y(p,m+1).padEnd(34," ");console.log(` ${x}${h?y(h,m+s+1):""}`.trimEnd())}if(n)console.log(),console.log(l.yellow(" The GitHub repository stays PRIVATE and no identifier is published:")),console.log(l.yellow(" the concept and version DOIs stay reserved until the deposit is published for real."));if(console.log(),t.sandbox)console.log(l.yellow("\u2501".repeat(60))),console.log(l.yellow.bold(" SANDBOX MODE ENABLED")),console.log(l.yellow("\u2501".repeat(60))),console.log(l.yellow(" \u2022 DOI will be created in sandbox mode (EZID test shoulder)")),console.log(l.yellow(" \u2022 DOI will NOT be indexed by DataCite")),console.log(l.yellow(" \u2022 DOI will NOT resolve in production")),console.log(l.yellow(" \u2022 Use this for testing workflows only")),console.log(l.yellow("\u2501".repeat(60))),console.log();let a=await $e(`${r}?`,t);if(a!=="confirmed"){console.log(l.dim(a==="declined"?"Skipped":"Cancelled"));return}let c="Running publication workflow (this may take a few minutes)...",u=D(c).start(),d=c;function f(m){let p=m.step.replace(/_/g," "),h=`Step ${m.stepIndex}/${m.stepTotal}: ${p}`;if(m.step==="s3_lock"&&m.s3LockLocked!==void 0&&m.s3LockTotal!==void 0&&m.s3LockTotal>0){let y=(m.s3LockLocked/m.s3LockTotal*100).toFixed(1),x=m.s3LockResumed?" (resumed)":"";return`${h} | Locking S3 objects: ${m.s3LockLocked}/${m.s3LockTotal} (${y}%)${x}`}if(m.step==="s3_lock"&&m.s3LockLocked!==void 0){let y=m.s3LockResumed?" (resumed)":"";return`${h} | Locking S3 objects: ${m.s3LockLocked}${y}`}return h}try{let m=await ql(e,!!t.resume,!!t.sandbox,!!t.skipCiCheck,(p)=>{u.stop();let h=p.step?p.step.replace(/_/g," "):"step";console.log(l.yellow(` [!] ${h} failed: ${p.error}`)),console.log(l.dim(` Retrying in ${Math.round(p.delayMs/1000)}s (attempt ${p.attempt+1}/${p.maxAttempts})...`)),u.start(d)},(p)=>{d=f(p),u.text=d});if(u.succeed(m.message),m.step_results&&m.step_results.length>0){console.log();let p=m.step_results,h=p.length;p.forEach((y,x)=>{let b=`[${String(x+1).padStart(2," ")}/${h}]`,v=y.step.replace(/_/g," ");if(y.status==="completed"){let S=(y.duration_ms/1000).toFixed(1),A=y.attempts>1?` (attempt ${y.attempts})`:"";console.log(` ${l.green("[x]")} ${l.dim(b)} ${v} ${l.dim(`(${S}s${A})`)}`)}else if(y.status==="failed")console.log(` ${l.red("[!]")} ${l.dim(b)} ${v}${y.error?`: ${l.red(y.error)}`:""}`);else console.log(` ${l.dim("[-]")} ${l.dim(b)} ${l.dim(v)} ${l.dim("(skipped)")}`)}),console.log()}else if(m.steps_completed){console.log();for(let p of m.steps_completed)console.log(` ${l.green("[x]")} ${p.replace(/_/g," ")}`);console.log()}if(m.warning)console.log(l.yellow(` Warning: ${m.warning}`))}catch(m){Qe(m,u,"Failed to approve publication",{422:"Fix the CI issues and retry with --resume"});let p=m.stepResults;if(p&&p.length>0){console.log(),console.log(l.dim("Step timeline (last attempt):"));let h=p.length;p.forEach((y,x)=>{let b=`[${String(x+1).padStart(2," ")}/${h}]`,v=y.step.replace(/_/g," "),S=(y.duration_ms/1000).toFixed(1),A=y.attempts>1?` (attempt ${y.attempts})`:"";if(y.status==="completed")console.log(` ${l.green("[x]")} ${l.dim(b)} ${v} ${l.dim(`(${S}s${A})`)}`);else if(y.status==="failed")console.log(` ${l.red("[!]")} ${l.dim(b)} ${v}${y.error?`: ${l.red(y.error)}`:""}`);else console.log(` ${l.dim("[-]")} ${l.dim(b)} ${l.dim(v)} ${l.dim("(skipped)")}`)}),console.log()}}});ue.addCommand(zy);ue.command("revert").description("Revert a dataset to a previous version (creates PR for review)").argument("<dataset-id>","Dataset ID (e.g., nm000104)").argument("[version]","Target version to revert to (e.g., 1.0.0)").option("--list","List available versions without reverting").option("--force","Direct push to main without PR (emergency only)").option("--message <msg>","Custom revert commit message").option("--dir <path>","Use existing local clone instead of cloning fresh").option(Ae,Oe).option(He,je).action(async(e,t,r)=>{if(!Z())return;let n=await tp();if(!n.allPassed){console.log(l.red("Error: Missing prerequisites"));for(let E of n.errors)console.log(l.dim(` - ${E}`));return}let o,i=!0;if(r.dir){if(!Ly(r.dir)){console.log(l.red(`Error: Directory not found: ${r.dir}`));return}o=r.dir,i=!1}else o=Ni(process.cwd(),`${e}-revert-${Date.now()}`);let s=D("Fetching dataset info...").start(),a;try{a=await It(e),s.succeed(`Found dataset: ${a.name}`)}catch(E){if(E instanceof q)if(s.fail(E.message),E.statusCode===404||E.statusCode===400)console.log(l.red(`Error: Dataset ${e} not found`)),console.log(l.dim(` ${E.message}`));else console.log(l.red(`Error: ${E.message}`));else{s.fail("Failed to fetch dataset");let P=E instanceof Error?E.message:String(E);console.log(l.red(`Error: Could not load dataset ${e}: ${P}`))}return}if(!a.github_repo){console.log(l.red("Error: Dataset has no GitHub repository"));return}if(i){let E=D(`Cloning ${e}...`).start(),P=`https://github.com/${a.github_repo}.git`,k=await fr(P,o);if(!k.success){E.fail(`Clone failed: ${k.error}`);return}E.succeed(`Cloned to ${o}`)}let c=await $X(o);if(c.length===0){console.log(l.yellow("No versions found for this dataset")),console.log(l.dim(" Dataset may not have any tagged releases yet"));return}if(r.list){console.log(`
426
426
  ${l.cyan("Available Versions:")}
427
427
  `);for(let E of c)console.log(` ${l.green(E.version)} ${l.dim(E.date)} ${l.dim(E.commit)}`);return}let u=t;if(!u){console.log(`
428
428
  ${l.cyan("Available Versions:")}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nemar-cli",
3
- "version": "0.10.5-PR1448.fdfd7f1",
3
+ "version": "0.10.5-PR1452.6442d66",
4
4
  "description": "CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource) dataset management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",