nemar-cli 0.6.2-dev.309 → 0.6.3-dev.311
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -96,7 +96,7 @@ Rules:
|
|
|
96
96
|
IsCitedBy, Cites, IsSupplementTo, IsSupplementedBy, References, IsReferencedBy,
|
|
97
97
|
IsDescribedBy, Describes, IsVersionOf, HasVersion, IsPartOf, HasPart
|
|
98
98
|
- Omit any field where you have no information. Return {} if nothing can be extracted.
|
|
99
|
-
- Do NOT hallucinate DOIs or funding numbers.`;var ax=$D(()=>{cx()});var D_={};kB(D_,{runE2ETest:()=>OHD});import{cpSync as LHD,existsSync as tx,mkdirSync as MHD,mkdtempSync as ox,readFileSync as NHD,rmSync as sx,writeFileSync as TW}from"fs";import{tmpdir as rx}from"os";import{join as R6,resolve as wW}from"path";var{spawn:CHD}=globalThis.Bun;function R0(D,...F){if(D.verbose)console.log(" ",...F)}async function ex(D,F){let $=performance.now();try{return await F(),{name:D,passed:!0,duration_ms:Math.round(performance.now()-$)}}catch(B){let J=B instanceof Error?B.message:String(B);return{name:D,passed:!1,duration_ms:Math.round(performance.now()-$),error:J}}}async function RHD(D){let F=[];for(let{name:$,fn:B}of D){let J=await ex($,B);if(F.push(J),!J.passed)break}return F}async function B9(D,F={}){let $=CHD({cmd:D,cwd:F.cwd,stdout:"pipe",stderr:"pipe",env:{...process.env,...F.env}}),B=await new Response($.stdout).text(),J=await new Response($.stderr).text(),Q=await $.exited;return{stdout:B,stderr:J,exitCode:Q}}function a0(D,F){if(!D.success)throw Error(`${F}: ${D.error}`)}function jHD(){let D=[wW(__dirname,"../../test/fixtures/bids-minimal"),wW(__dirname,"../test/fixtures/bids-minimal"),wW(process.cwd(),"test/fixtures/bids-minimal")];for(let F of D)if(tx(F))return F;throw Error("Could not find test/fixtures/bids-minimal. Run from the nemar-cli root directory.")}async function OHD(D){let F=D.verbose??!1,$=performance.now(),B=ox(R6(rx(),"nemar-e2e-upload-")),J=ox(R6(rx(),"nemar-e2e-clone-")),Q={uploadDir:B,cloneDir:J,verbose:F},X=[];if(!D.skipReset)X.push({name:"Reset nm099999",fn:async()=>{let W=await Tx(q4);if(R0(Q,`S3 objects deleted: ${W.steps.s3_deleted}`),R0(Q,`GitHub recreated: ${W.steps.github_recreated}`),R0(Q,`D1 cleaned: ${W.steps.d1_cleaned}`),!W.success){let G=[];if(!W.steps.github_recreated)G.push("GitHub");if(!W.steps.d1_cleaned)G.push("D1");throw Error(`Reset partially failed: ${G.join(", ")}`)}}});X.push({name:"Prepare upload",fn:async()=>{let W=jHD();LHD(W,B,{recursive:!0}),R0(Q,`Copied fixtures to ${B}`)}},{name:"Init git + annex",fn:async()=>{a0(await s3(B,{force:!0}),"initDataset"),a0(await r3(B),"configureLargefiles"),R0(Q,"Git + git-annex initialized")}},{name:"Configure remotes",fn:async()=>{Q.creds=await W4(q4),R0(Q,`S3 prefix: ${Q.creds.s3.prefix}`),a0(await t5(B,{name:"nemar-s3",bucket:Q.creds.s3.bucket,prefix:`${q4}/objects`,region:Q.creds.s3.region,publicUrl:`https://${Q.creds.s3.bucket}.s3.${Q.creds.s3.region}.amazonaws.com/${q4}/objects`},f1(Q.creds.credentials)),"configureS3Remote");let W=`git@github.com:nemarDatasets/${q4}.git`;a0(await e3(B,W),"configureGitHubRemote"),R0(Q,"S3 + GitHub remotes configured")}},{name:"Upload to S3",fn:async()=>{a0(await r5(B),"gitAnnexAdd"),a0(await M6(B,"Initial BIDS dataset"),"saveDataset");let W=await H4(B,"nemar-s3",4,f1(Q.creds
|
|
99
|
+
- Do NOT hallucinate DOIs or funding numbers.`;var ax=$D(()=>{cx()});var D_={};kB(D_,{runE2ETest:()=>OHD});import{cpSync as LHD,existsSync as tx,mkdirSync as MHD,mkdtempSync as ox,readFileSync as NHD,rmSync as sx,writeFileSync as TW}from"fs";import{tmpdir as rx}from"os";import{join as R6,resolve as wW}from"path";var{spawn:CHD}=globalThis.Bun;function R0(D,...F){if(D.verbose)console.log(" ",...F)}async function ex(D,F){let $=performance.now();try{return await F(),{name:D,passed:!0,duration_ms:Math.round(performance.now()-$)}}catch(B){let J=B instanceof Error?B.message:String(B);return{name:D,passed:!1,duration_ms:Math.round(performance.now()-$),error:J}}}async function RHD(D){let F=[];for(let{name:$,fn:B}of D){let J=await ex($,B);if(F.push(J),!J.passed)break}return F}async function B9(D,F={}){let $=CHD({cmd:D,cwd:F.cwd,stdout:"pipe",stderr:"pipe",env:{...process.env,...F.env}}),B=await new Response($.stdout).text(),J=await new Response($.stderr).text(),Q=await $.exited;return{stdout:B,stderr:J,exitCode:Q}}function a0(D,F){if(!D.success)throw Error(`${F}: ${D.error}`)}function jHD(){let D=[wW(__dirname,"../../test/fixtures/bids-minimal"),wW(__dirname,"../test/fixtures/bids-minimal"),wW(process.cwd(),"test/fixtures/bids-minimal")];for(let F of D)if(tx(F))return F;throw Error("Could not find test/fixtures/bids-minimal. Run from the nemar-cli root directory.")}async function OHD(D){let F=D.verbose??!1,$=performance.now(),B=ox(R6(rx(),"nemar-e2e-upload-")),J=ox(R6(rx(),"nemar-e2e-clone-")),Q={uploadDir:B,cloneDir:J,verbose:F},X=[];if(!D.skipReset)X.push({name:"Reset nm099999",fn:async()=>{let W=await Tx(q4);if(R0(Q,`S3 objects deleted: ${W.steps.s3_deleted}`),R0(Q,`GitHub recreated: ${W.steps.github_recreated}`),R0(Q,`D1 cleaned: ${W.steps.d1_cleaned}`),!W.success){let G=[];if(!W.steps.github_recreated)G.push("GitHub");if(!W.steps.d1_cleaned)G.push("D1");throw Error(`Reset partially failed: ${G.join(", ")}`)}}});X.push({name:"Prepare upload",fn:async()=>{let W=jHD();LHD(W,B,{recursive:!0}),R0(Q,`Copied fixtures to ${B}`)}},{name:"Init git + annex",fn:async()=>{a0(await s3(B,{force:!0}),"initDataset"),a0(await r3(B),"configureLargefiles"),R0(Q,"Git + git-annex initialized")}},{name:"Configure remotes",fn:async()=>{Q.creds=await W4(q4),R0(Q,`S3 prefix: ${Q.creds.s3.prefix}`),a0(await t5(B,{name:"nemar-s3",bucket:Q.creds.s3.bucket,prefix:`${q4}/objects`,region:Q.creds.s3.region,publicUrl:`https://${Q.creds.s3.bucket}.s3.${Q.creds.s3.region}.amazonaws.com/${q4}/objects`},f1(Q.creds.credentials)),"configureS3Remote");let W=`git@github.com:nemarDatasets/${q4}.git`;a0(await e3(B,W),"configureGitHubRemote"),R0(Q,"S3 + GitHub remotes configured")}},{name:"Upload to S3",fn:async()=>{a0(await r5(B),"gitAnnexAdd"),a0(await M6(B,"Initial BIDS dataset"),"saveDataset");let W=await H4(B,"nemar-s3",4,f1(Q.creds?.credentials));a0(W,"copyToAnnexRemote"),R0(Q,`Files copied to S3: ${W.filesCopied}`),await G4(B)}},{name:"Push to GitHub",fn:async()=>{let W=await N6(B);if(a0(W,"pushToGitHub"),W.warning)R0(Q,`Warning: ${W.warning}`);R0(Q,"Pushed to GitHub (main + git-annex branches)")}},{name:"Clone fresh",fn:async()=>{let W=`git@github.com:nemarDatasets/${q4}.git`;a0(await C6(W,J),"cloneDataset");let G=await t3(J,"nemar-s3");if(!G.success)throw Error(`enableS3Remote: ${G.error}`);R0(Q,`Clone at ${J}, S3 remote enabled: ${G.enabled}`)}},{name:"Download + verify",fn:async()=>{let W=f1(Q.creds?.credentials),G={AWS_ACCESS_KEY_ID:W.accessKeyId,AWS_SECRET_ACCESS_KEY:W.secretAccessKey};if(W.sessionToken)G.AWS_SESSION_TOKEN=W.sessionToken;let{stdout:q,stderr:E,exitCode:V}=await B9(["git","annex","get","."],{cwd:J,env:G});if(V!==0)throw Error(`getDatasetData: ${E.trim()}`);let Z=q.match(/^get .+ ok$/gm);R0(Q,`Files downloaded: ${Z?Z.length:0}`);let A=R6(J,"sub-01/eeg/sub-01_task-rest_eeg.edf");if(!tx(A))throw Error("EDF file not found after download");let{size:U}=Bun.file(A);if(U<512)throw Error(`EDF file too small: ${U} bytes`);R0(Q,`EDF file verified: ${U} bytes`)}},{name:"Update cycle",fn:async()=>{let W=R6(J,"sub-02/eeg");MHD(W,{recursive:!0});let G=Buffer.alloc(1024);G.write("0".padEnd(8),0,"ascii"),TW(R6(W,"sub-02_task-rest_eeg.edf"),G),TW(R6(W,"sub-02_task-rest_eeg.json"),JSON.stringify({TaskName:"rest",SamplingFrequency:256}));let q=NHD(R6(J,"participants.tsv"),"utf-8");TW(R6(J,"participants.tsv"),`${q.trimEnd()}
|
|
100
100
|
sub-02 30 F
|
|
101
101
|
`);let E=`e2e-update-${Date.now()}`,{exitCode:V}=await B9(["git","checkout","-b",E],{cwd:J});if(V!==0)throw Error("Failed to create update branch");a0(await r5(J),"gitAnnexAdd (update)"),a0(await M6(J,"Add sub-02"),"saveDataset (update)"),Q.creds=await W4(q4);let Z=await H4(J,"nemar-s3",4,f1(Q.creds.credentials));a0(Z,"copyToAnnexRemote (update)"),R0(Q,`Update files copied to S3: ${Z.filesCopied}`),await G4(J);let A=await N6(J,"origin",E);a0(A,"pushToGitHub (update branch)");let{exitCode:U,stderr:L}=await B9(["git","push","origin","git-annex"],{cwd:J});if(U!==0)throw Error(`Failed to push git-annex branch: ${L.trim()}`);R0(Q,`Update pushed to branch: ${E}`)}});let Y=await RHD(X);if(!D.skipCleanup&&Y.every((W)=>W.passed))Y.push(await ex("Cleanup",async()=>{await B9(["chmod","-R","u+w",B]),await B9(["chmod","-R","u+w",J]),sx(B,{recursive:!0,force:!0}),sx(J,{recursive:!0,force:!0}),R0(Q,"Temp directories cleaned up")}));return THD(Y,$,B,J,D.skipCleanup)}function THD(D,F,$,B,J){let Q={passed:D.every((X)=>X.passed),steps:D,total_duration_ms:Math.round(performance.now()-F)};if(J)Q.upload_dir=$,Q.clone_dir=B;return Q}var __dirname="/home/runner/work/nemar-cli/nemar-cli/src/lib",q4="nm099999";var F_=$D(()=>{o3();$9()});var XG=c(QG(),1),{program:AqD,createCommand:LqD,createArgument:MqD,createOption:NqD,CommanderError:CqD,InvalidArgumentError:RqD,InvalidOptionArgumentError:jqD,Command:Z0,Argument:OqD,Option:TqD,Help:wqD}=XG.default;import{existsSync as wHD}from"fs";import{join as IHD}from"path";var YG=(D=0)=>(F)=>`\x1B[${F+D}m`,WG=(D=0)=>(F)=>`\x1B[${38+D};5;${F}m`,GG=(D=0)=>(F,$,B)=>`\x1B[${38+D};2;${F};${$};${B}m`,yD={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}},PqD=Object.keys(yD.modifier),Of=Object.keys(yD.color),Tf=Object.keys(yD.bgColor),SqD=[...Of,...Tf];function wf(){let D=new Map;for(let[F,$]of Object.entries(yD)){for(let[B,J]of Object.entries($))yD[B]={open:`\x1B[${J[0]}m`,close:`\x1B[${J[1]}m`},$[B]=yD[B],D.set(J[0],J[1]);Object.defineProperty(yD,F,{value:$,enumerable:!1})}return Object.defineProperty(yD,"codes",{value:D,enumerable:!1}),yD.color.close="\x1B[39m",yD.bgColor.close="\x1B[49m",yD.color.ansi=YG(),yD.color.ansi256=WG(),yD.color.ansi16m=GG(),yD.bgColor.ansi=YG(10),yD.bgColor.ansi256=WG(10),yD.bgColor.ansi16m=GG(10),Object.defineProperties(yD,{rgbToAnsi256:{value(F,$,B){if(F===$&&$===B){if(F<8)return 16;if(F>248)return 231;return Math.round((F-8)/247*24)+232}return 16+36*Math.round(F/255*5)+6*Math.round($/255*5)+Math.round(B/255*5)},enumerable:!1},hexToRgb:{value(F){let $=/[a-f\d]{6}|[a-f\d]{3}/i.exec(F.toString(16));if(!$)return[0,0,0];let[B]=$;if(B.length===3)B=[...B].map((Q)=>Q+Q).join("");let J=Number.parseInt(B,16);return[J>>16&255,J>>8&255,J&255]},enumerable:!1},hexToAnsi256:{value:(F)=>yD.rgbToAnsi256(...yD.hexToRgb(F)),enumerable:!1},ansi256ToAnsi:{value(F){if(F<8)return 30+F;if(F<16)return 90+(F-8);let $,B,J;if(F>=232)$=((F-232)*10+8)/255,B=$,J=$;else{F-=16;let Y=F%36;$=Math.floor(F/36)/5,B=Math.floor(Y/6)/5,J=Y%6/5}let Q=Math.max($,B,J)*2;if(Q===0)return 30;let X=30+(Math.round(J)<<2|Math.round(B)<<1|Math.round($));if(Q===2)X+=60;return X},enumerable:!1},rgbToAnsi:{value:(F,$,B)=>yD.ansi256ToAnsi(yD.rgbToAnsi256(F,$,B)),enumerable:!1},hexToAnsi:{value:(F)=>yD.ansi256ToAnsi(yD.hexToAnsi256(F)),enumerable:!1}}),yD}var If=wf(),z1=If;import uB from"process";import Pf from"os";import HG from"tty";function s0(D,F=globalThis.Deno?globalThis.Deno.args:uB.argv){let $=D.startsWith("-")?"":D.length===1?"-":"--",B=F.indexOf($+D),J=F.indexOf("--");return B!==-1&&(J===-1||B<J)}var{env:xD}=uB,E9;if(s0("no-color")||s0("no-colors")||s0("color=false")||s0("color=never"))E9=0;else if(s0("color")||s0("colors")||s0("color=true")||s0("color=always"))E9=1;function Sf(){if("FORCE_COLOR"in xD){if(xD.FORCE_COLOR==="true")return 1;if(xD.FORCE_COLOR==="false")return 0;return xD.FORCE_COLOR.length===0?1:Math.min(Number.parseInt(xD.FORCE_COLOR,10),3)}}function kf(D){if(D===0)return!1;return{level:D,hasBasic:!0,has256:D>=2,has16m:D>=3}}function vf(D,{streamIsTTY:F,sniffFlags:$=!0}={}){let B=Sf();if(B!==void 0)E9=B;let J=$?E9:B;if(J===0)return 0;if($){if(s0("color=16m")||s0("color=full")||s0("color=truecolor"))return 3;if(s0("color=256"))return 2}if("TF_BUILD"in xD&&"AGENT_NAME"in xD)return 1;if(D&&!F&&J===void 0)return 0;let Q=J||0;if(xD.TERM==="dumb")return Q;if(uB.platform==="win32"){let X=Pf.release().split(".");if(Number(X[0])>=10&&Number(X[2])>=10586)return Number(X[2])>=14931?3:2;return 1}if("CI"in xD){if(["GITHUB_ACTIONS","GITEA_ACTIONS","CIRCLECI"].some((X)=>(X in xD)))return 3;if(["TRAVIS","APPVEYOR","GITLAB_CI","BUILDKITE","DRONE"].some((X)=>(X in xD))||xD.CI_NAME==="codeship")return 1;return Q}if("TEAMCITY_VERSION"in xD)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(xD.TEAMCITY_VERSION)?1:0;if(xD.COLORTERM==="truecolor")return 3;if(xD.TERM==="xterm-kitty")return 3;if(xD.TERM==="xterm-ghostty")return 3;if(xD.TERM==="wezterm")return 3;if("TERM_PROGRAM"in xD){let X=Number.parseInt((xD.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(xD.TERM_PROGRAM){case"iTerm.app":return X>=3?3:2;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(xD.TERM))return 2;if(/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(xD.TERM))return 1;if("COLORTERM"in xD)return 1;return Q}function qG(D,F={}){let $=vf(D,{streamIsTTY:D&&D.isTTY,...F});return kf($)}var yf={stdout:qG({isTTY:HG.isatty(1)}),stderr:qG({isTTY:HG.isatty(2)})},EG=yf;function KG(D,F,$){let B=D.indexOf(F);if(B===-1)return D;let J=F.length,Q=0,X="";do X+=D.slice(Q,B)+F+$,Q=B+J,B=D.indexOf(F,Q);while(B!==-1);return X+=D.slice(Q),X}function zG(D,F,$,B){let J=0,Q="";do{let X=D[B-1]==="\r";Q+=D.slice(J,X?B-1:B)+F+(X?`\r
|
|
102
102
|
`:`
|
|
@@ -784,7 +784,7 @@ Examples:
|
|
|
784
784
|
$ nemar sandbox # Run sandbox training
|
|
785
785
|
$ nemar sandbox status # Check if training is completed
|
|
786
786
|
$ nemar sandbox reset # Reset for re-training
|
|
787
|
-
`).action(WqD);async function WqD(){if(console.log(),console.log(H.bold("NEMAR Sandbox Training")),console.log(H.gray("Verify your setup and learn the upload workflow")),console.log(),!kD()){console.log(H.red("Not authenticated")),console.log(H.gray("Run 'nemar auth login' first"));return}let D=tD();if(D.sandboxCompleted){console.log(H.green("Sandbox training already completed!")),console.log(H.gray(`Dataset ID: ${D.sandboxDatasetId}`)),console.log(),console.log("You can upload real datasets with:"),console.log(H.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(H.gray("To re-run training, use: nemar sandbox reset"));return}console.log(H.bold("Step 1/6: Checking prerequisites..."));let F=C("Checking git-annex and SSH...").start(),$=await ZB();if(!$.allPassed){F.fail("Prerequisites check failed"),console.log(),console.log(H.red("Missing requirements:"));for(let I of $.errors)console.log(H.yellow(` - ${I}`));if(!$.githubSSH.accessible)console.log(H.gray(" Run 'nemar auth setup-ssh' to configure SSH"));return}F.succeed("All prerequisites met");let B=C("Verifying GitHub CLI authentication...").start(),J=await UB(D.githubUsername);if(!J.authenticated){B.fail("GitHub CLI not authenticated"),console.log(H.red(` ${J.error}`)),console.log(),console.log("GitHub CLI is required for sandbox training. Install and authenticate:"),console.log(H.cyan(" brew install gh # or visit https://cli.github.com/")),console.log(H.cyan(" gh auth login"));return}if(D.githubUsername&&!J.matches)B.warn("GitHub CLI user mismatch"),console.log(H.yellow(` ${J.error}`)),console.log(),console.log("Your gh CLI is authenticated as a different GitHub account than your NEMAR account."),console.log("This may cause issues with repository access. To fix:"),console.log(H.cyan(` gh auth login # Login as ${D.githubUsername}`)),console.log(),console.log(H.yellow("WARNING: If upload fails with permission errors, this mismatch is the likely cause.")),console.log();else B.succeed(`GitHub CLI authenticated as ${J.username}`);console.log(),console.log(H.bold("Step 2/6: Generating test dataset..."));let Q=C("Creating minimal BIDS structure...").start(),X;try{let I=I_();X=I.root;let P=P_(I);Q.succeed(`Test dataset created (${DF(P)})`),console.log(H.gray(` Location: ${X}`))}catch(I){Q.fail("Failed to generate test dataset"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`));return}console.log(),console.log(H.bold("Step 3/6: Registering sandbox dataset..."));let Y=C("Creating dataset on NEMAR...").start(),W,G,q,E,V,Z;try{let I=await zB({name:"Sandbox Training Dataset",description:"Placeholder dataset for sandbox training",files:[{path:"sub-01/eeg/sub-01_task-rest_eeg.edf",size:512000,type:"data"},{path:"dataset_description.json",size:200,type:"metadata"},{path:"participants.tsv",size:50,type:"metadata"},{path:"README",size:500,type:"metadata"},{path:"sub-01/eeg/sub-01_task-rest_eeg.json",size:300,type:"metadata"}],sandbox:!0});W=I.dataset.dataset_id,G=I.dataset.ssh_url,q=I.dataset.github_url,E=I.s3_config,V=I.dataset.s3_prefix,Z=I.upload_urls||{},Y.succeed(`Sandbox dataset created: ${H.cyan(W)}`),console.log(H.gray(` GitHub: ${q}`)),await new Promise((P)=>setTimeout(P,1e4))}catch(I){if(Y.fail("Failed to create sandbox dataset"),I instanceof m)console.log(H.red(` ${I.message}`));else console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`));h1(X);return}let A=C("Accepting GitHub repository invitation...").start(),U=q?.match(/github\.com\/([a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+)/),L=U?U[1].replace(/\.git$/,""):null;if(!L){A.fail("Invalid GitHub repository URL from backend"),console.log(H.red(` Received: ${q||"(empty)"}`)),console.log(H.red(" Expected format: https://github.com/owner/repo")),console.log(),console.log("This may indicate a backend issue. Please contact support."),h1(X);return}let M=await AB(L);if(M.accepted)if(M.alreadyCollaborator)A.succeed("Already a collaborator on this repository");else A.succeed("GitHub invitation accepted");else A.warn("Could not auto-accept invitation"),console.log(H.yellow(` ${M.error}`)),console.log(),console.log("You may need to accept the invitation manually:"),console.log(H.cyan(` https://github.com/${L}/invitations`)),console.log();console.log(),console.log(H.bold("Step 4/6: Initializing repository..."));let N=C("Setting up git-annex...").start(),w=D.username&&D.email?{name:D.username,email:D.email}:void 0;try{await s3(X,{author:w}),await r3(X),await e3(X,G),N.succeed("Repository initialized")}catch(I){N.fail("Failed to initialize repository"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`)),h1(X);return}if(console.log(),console.log(H.bold("Step 5/6: Uploading to S3...")),Object.keys(Z).length===0)console.log(H.yellow(" No data files to upload (metadata only)"));else{let I=C("Uploading test data...").start();try{let a=0,VD=Object.keys(Z).length,ED=await _x(X,Z,{jobs:4,onProgress:(dD)=>{if(dD.status==="completed"||dD.status==="failed")a++,I.text=`Uploading... ${a}/${VD} files`}});if(ED.failed.length>0){I.fail(`Upload failed for ${ED.failed.length} file(s)`);for(let dD of ED.failed)console.log(H.red(` Failed: ${dD}`));if(ED.error)console.log(H.red(` Error: ${ED.error}`));console.log(),console.log(H.yellow("Sandbox training aborted due to upload failures.")),console.log(H.gray("Please check your network connection and try again.")),h1(X);return}I.succeed(`Uploaded ${ED.uploaded} file(s)`)}catch(a){I.fail("Upload failed"),console.log(H.red(` ${a instanceof Error?a.message:"Unknown error"}`)),h1(X);return}let P=C("Registering file URLs...").start();try{let a={};for(let ED of Object.keys(Z))a[ED]=`${E.public_url}/${V}/objects/${ED}`;let VD=await fx(X,a);if(!VD.success){P.fail(`URL registration failed for ${VD.failed.length} file(s)`);for(let ED of VD.failed)console.log(H.red(` Failed: ${ED}`));console.log(),console.log(H.yellow("Sandbox training aborted due to URL registration failures.")),console.log(H.gray("This may indicate a git-annex configuration issue.")),h1(X);return}P.succeed(`Registered ${VD.registered} file URLs`)}catch(a){P.fail("Failed to register URLs"),console.log(H.red(` ${a instanceof Error?a.message:"Unknown error"}`)),h1(X);return}}console.log(),console.log(H.bold("Step 6/6: Pushing to GitHub..."));let g=C("Saving and pushing...").start();try{await M6(X,"Initial sandbox training upload",w),await N6(X),g.succeed("Pushed to GitHub")}catch(I){g.fail("Failed to push to GitHub"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`)),h1(X);return}let O=C("Finalizing...").start();try{await VB(W),await zx(W),w8("sandboxCompleted",!0),w8("sandboxDatasetId",W),O.succeed("Sandbox training complete!")}catch(I){O.fail("Failed to finalize"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`)),h1(X);return}h1(X),console.log(),console.log(H.green.bold("Congratulations! Sandbox training completed successfully.")),console.log(),console.log("Your setup is verified and you're ready to upload real datasets:"),console.log(H.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(H.gray(`Sandbox dataset: ${W}`))}PB.command("status").description("Check sandbox training completion status").option("--refresh","Fetch latest status from server").action(async(D)=>{if(!kD()){console.log(H.red("Not authenticated")),console.log(H.gray("Run 'nemar auth login' first"));return}if(D.refresh){let F=C("Checking status...").start();try{let $=await Zx();if(w8("sandboxCompleted",$.sandbox_completed),$.sandbox_dataset_id)w8("sandboxDatasetId",$.sandbox_dataset_id);if(F.stop(),$.sandbox_completed){if(console.log(H.green("Sandbox training: Completed")),console.log(H.gray(` Dataset ID: ${$.sandbox_dataset_id}`)),$.sandbox_completed_at)console.log(H.gray(` Completed: ${$.sandbox_completed_at}`))}else console.log(H.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(H.cyan(" nemar sandbox"))}catch($){if(F.fail("Failed to check status"),$ instanceof m)console.log(H.red(` ${$.message}`))}}else{let F=tD();if(F.sandboxCompleted)console.log(H.green("Sandbox training: Completed")),console.log(H.gray(` Dataset ID: ${F.sandboxDatasetId}`));else console.log(H.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(H.cyan(" nemar sandbox"))}});PB.command("reset").description("Reset sandbox training status for re-training").option(OD,TD).option(lD,vD).action(async(D)=>{if(!kD()){console.log(H.red("Not authenticated")),console.log(H.gray("Run 'nemar auth login' first"));return}if(!tD().sandboxCompleted){console.log(H.yellow("Sandbox training not yet completed")),console.log(H.gray("Nothing to reset"));return}let $=await ID("Reset sandbox training status? You will need to complete training again.",D);if($!=="confirmed"){console.log(H.gray($==="declined"?"Skipped":"Cancelled"));return}let B=C("Resetting sandbox status...").start();try{await Vx(),MW("sandboxCompleted"),MW("sandboxDatasetId"),B.succeed("Sandbox status reset"),console.log(),console.log("Run sandbox training again with:"),console.log(H.cyan(" nemar sandbox"))}catch(J){if(B.fail("Failed to reset"),J instanceof m)console.log(H.red(` ${J.message}`));else console.log(H.red(` ${J instanceof Error?J.message:"Unknown error"}`))}});var S_={name:"nemar-cli",version:"0.6.2-dev.309",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:fix":"biome check --fix src/",format:"biome format --write src/",typecheck:"tsc --noEmit",prepublishOnly:"bun run build","docs:generate":"bun run scripts/generate-docs.ts","docs:serve":"mkdocs serve","docs:build":"mkdocs build"},keywords:["nemar","bids","neuroimaging","eeg","emg","datalad","cli"],author:"NEMAR Team",license:"MIT",repository:{type:"git",url:"git+https://github.com/nemarOrg/nemar-cli.git"},bugs:{url:"https://github.com/nemarOrg/nemar-cli/issues"},homepage:"https://nemar-cli.pages.dev",engines:{bun:">=1.0.0"},files:["dist","README.md","LICENSE"],dependencies:{chalk:"^5.3.0",commander:"^12.1.0",conf:"^13.0.1",inquirer:"^9.2.15",ora:"^8.0.1",zod:"^3.23.8"},devDependencies:{"@biomejs/biome":"1.9.4","@types/bcryptjs":"^3.0.0","@types/bun":"latest","@types/inquirer":"^9.0.7",bcryptjs:"^3.0.3",typescript:"^5.5.4"}};var k_=S_.version;var E1=new Z0;E1.name("nemar").description(`CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource)
|
|
787
|
+
`).action(WqD);async function WqD(){if(console.log(),console.log(H.bold("NEMAR Sandbox Training")),console.log(H.gray("Verify your setup and learn the upload workflow")),console.log(),!kD()){console.log(H.red("Not authenticated")),console.log(H.gray("Run 'nemar auth login' first"));return}let D=tD();if(D.sandboxCompleted){console.log(H.green("Sandbox training already completed!")),console.log(H.gray(`Dataset ID: ${D.sandboxDatasetId}`)),console.log(),console.log("You can upload real datasets with:"),console.log(H.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(H.gray("To re-run training, use: nemar sandbox reset"));return}console.log(H.bold("Step 1/6: Checking prerequisites..."));let F=C("Checking git-annex and SSH...").start(),$=await ZB();if(!$.allPassed){F.fail("Prerequisites check failed"),console.log(),console.log(H.red("Missing requirements:"));for(let I of $.errors)console.log(H.yellow(` - ${I}`));if(!$.githubSSH.accessible)console.log(H.gray(" Run 'nemar auth setup-ssh' to configure SSH"));return}F.succeed("All prerequisites met");let B=C("Verifying GitHub CLI authentication...").start(),J=await UB(D.githubUsername);if(!J.authenticated){B.fail("GitHub CLI not authenticated"),console.log(H.red(` ${J.error}`)),console.log(),console.log("GitHub CLI is required for sandbox training. Install and authenticate:"),console.log(H.cyan(" brew install gh # or visit https://cli.github.com/")),console.log(H.cyan(" gh auth login"));return}if(D.githubUsername&&!J.matches)B.warn("GitHub CLI user mismatch"),console.log(H.yellow(` ${J.error}`)),console.log(),console.log("Your gh CLI is authenticated as a different GitHub account than your NEMAR account."),console.log("This may cause issues with repository access. To fix:"),console.log(H.cyan(` gh auth login # Login as ${D.githubUsername}`)),console.log(),console.log(H.yellow("WARNING: If upload fails with permission errors, this mismatch is the likely cause.")),console.log();else B.succeed(`GitHub CLI authenticated as ${J.username}`);console.log(),console.log(H.bold("Step 2/6: Generating test dataset..."));let Q=C("Creating minimal BIDS structure...").start(),X;try{let I=I_();X=I.root;let P=P_(I);Q.succeed(`Test dataset created (${DF(P)})`),console.log(H.gray(` Location: ${X}`))}catch(I){Q.fail("Failed to generate test dataset"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`));return}console.log(),console.log(H.bold("Step 3/6: Registering sandbox dataset..."));let Y=C("Creating dataset on NEMAR...").start(),W,G,q,E,V,Z;try{let I=await zB({name:"Sandbox Training Dataset",description:"Placeholder dataset for sandbox training",files:[{path:"sub-01/eeg/sub-01_task-rest_eeg.edf",size:512000,type:"data"},{path:"dataset_description.json",size:200,type:"metadata"},{path:"participants.tsv",size:50,type:"metadata"},{path:"README",size:500,type:"metadata"},{path:"sub-01/eeg/sub-01_task-rest_eeg.json",size:300,type:"metadata"}],sandbox:!0});W=I.dataset.dataset_id,G=I.dataset.ssh_url,q=I.dataset.github_url,E=I.s3_config,V=I.dataset.s3_prefix,Z=I.upload_urls||{},Y.succeed(`Sandbox dataset created: ${H.cyan(W)}`),console.log(H.gray(` GitHub: ${q}`)),await new Promise((P)=>setTimeout(P,1e4))}catch(I){if(Y.fail("Failed to create sandbox dataset"),I instanceof m)console.log(H.red(` ${I.message}`));else console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`));h1(X);return}let A=C("Accepting GitHub repository invitation...").start(),U=q?.match(/github\.com\/([a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+)/),L=U?U[1].replace(/\.git$/,""):null;if(!L){A.fail("Invalid GitHub repository URL from backend"),console.log(H.red(` Received: ${q||"(empty)"}`)),console.log(H.red(" Expected format: https://github.com/owner/repo")),console.log(),console.log("This may indicate a backend issue. Please contact support."),h1(X);return}let M=await AB(L);if(M.accepted)if(M.alreadyCollaborator)A.succeed("Already a collaborator on this repository");else A.succeed("GitHub invitation accepted");else A.warn("Could not auto-accept invitation"),console.log(H.yellow(` ${M.error}`)),console.log(),console.log("You may need to accept the invitation manually:"),console.log(H.cyan(` https://github.com/${L}/invitations`)),console.log();console.log(),console.log(H.bold("Step 4/6: Initializing repository..."));let N=C("Setting up git-annex...").start(),w=D.username&&D.email?{name:D.username,email:D.email}:void 0;try{await s3(X,{author:w}),await r3(X),await e3(X,G),N.succeed("Repository initialized")}catch(I){N.fail("Failed to initialize repository"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`)),h1(X);return}if(console.log(),console.log(H.bold("Step 5/6: Uploading to S3...")),Object.keys(Z).length===0)console.log(H.yellow(" No data files to upload (metadata only)"));else{let I=C("Uploading test data...").start();try{let a=0,VD=Object.keys(Z).length,ED=await _x(X,Z,{jobs:4,onProgress:(dD)=>{if(dD.status==="completed"||dD.status==="failed")a++,I.text=`Uploading... ${a}/${VD} files`}});if(ED.failed.length>0){I.fail(`Upload failed for ${ED.failed.length} file(s)`);for(let dD of ED.failed)console.log(H.red(` Failed: ${dD}`));if(ED.error)console.log(H.red(` Error: ${ED.error}`));console.log(),console.log(H.yellow("Sandbox training aborted due to upload failures.")),console.log(H.gray("Please check your network connection and try again.")),h1(X);return}I.succeed(`Uploaded ${ED.uploaded} file(s)`)}catch(a){I.fail("Upload failed"),console.log(H.red(` ${a instanceof Error?a.message:"Unknown error"}`)),h1(X);return}let P=C("Registering file URLs...").start();try{let a={};for(let ED of Object.keys(Z))a[ED]=`${E.public_url}/${V}/objects/${ED}`;let VD=await fx(X,a);if(!VD.success){P.fail(`URL registration failed for ${VD.failed.length} file(s)`);for(let ED of VD.failed)console.log(H.red(` Failed: ${ED}`));console.log(),console.log(H.yellow("Sandbox training aborted due to URL registration failures.")),console.log(H.gray("This may indicate a git-annex configuration issue.")),h1(X);return}P.succeed(`Registered ${VD.registered} file URLs`)}catch(a){P.fail("Failed to register URLs"),console.log(H.red(` ${a instanceof Error?a.message:"Unknown error"}`)),h1(X);return}}console.log(),console.log(H.bold("Step 6/6: Pushing to GitHub..."));let g=C("Saving and pushing...").start();try{await M6(X,"Initial sandbox training upload",w),await N6(X),g.succeed("Pushed to GitHub")}catch(I){g.fail("Failed to push to GitHub"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`)),h1(X);return}let O=C("Finalizing...").start();try{await VB(W),await zx(W),w8("sandboxCompleted",!0),w8("sandboxDatasetId",W),O.succeed("Sandbox training complete!")}catch(I){O.fail("Failed to finalize"),console.log(H.red(` ${I instanceof Error?I.message:"Unknown error"}`)),h1(X);return}h1(X),console.log(),console.log(H.green.bold("Congratulations! Sandbox training completed successfully.")),console.log(),console.log("Your setup is verified and you're ready to upload real datasets:"),console.log(H.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(H.gray(`Sandbox dataset: ${W}`))}PB.command("status").description("Check sandbox training completion status").option("--refresh","Fetch latest status from server").action(async(D)=>{if(!kD()){console.log(H.red("Not authenticated")),console.log(H.gray("Run 'nemar auth login' first"));return}if(D.refresh){let F=C("Checking status...").start();try{let $=await Zx();if(w8("sandboxCompleted",$.sandbox_completed),$.sandbox_dataset_id)w8("sandboxDatasetId",$.sandbox_dataset_id);if(F.stop(),$.sandbox_completed){if(console.log(H.green("Sandbox training: Completed")),console.log(H.gray(` Dataset ID: ${$.sandbox_dataset_id}`)),$.sandbox_completed_at)console.log(H.gray(` Completed: ${$.sandbox_completed_at}`))}else console.log(H.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(H.cyan(" nemar sandbox"))}catch($){if(F.fail("Failed to check status"),$ instanceof m)console.log(H.red(` ${$.message}`))}}else{let F=tD();if(F.sandboxCompleted)console.log(H.green("Sandbox training: Completed")),console.log(H.gray(` Dataset ID: ${F.sandboxDatasetId}`));else console.log(H.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(H.cyan(" nemar sandbox"))}});PB.command("reset").description("Reset sandbox training status for re-training").option(OD,TD).option(lD,vD).action(async(D)=>{if(!kD()){console.log(H.red("Not authenticated")),console.log(H.gray("Run 'nemar auth login' first"));return}if(!tD().sandboxCompleted){console.log(H.yellow("Sandbox training not yet completed")),console.log(H.gray("Nothing to reset"));return}let $=await ID("Reset sandbox training status? You will need to complete training again.",D);if($!=="confirmed"){console.log(H.gray($==="declined"?"Skipped":"Cancelled"));return}let B=C("Resetting sandbox status...").start();try{await Vx(),MW("sandboxCompleted"),MW("sandboxDatasetId"),B.succeed("Sandbox status reset"),console.log(),console.log("Run sandbox training again with:"),console.log(H.cyan(" nemar sandbox"))}catch(J){if(B.fail("Failed to reset"),J instanceof m)console.log(H.red(` ${J.message}`));else console.log(H.red(` ${J instanceof Error?J.message:"Unknown error"}`))}});var S_={name:"nemar-cli",version:"0.6.3-dev.311",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:fix":"biome check --fix src/",format:"biome format --write src/",typecheck:"tsc --noEmit",prepublishOnly:"bun run build","docs:generate":"bun run scripts/generate-docs.ts","docs:serve":"mkdocs serve","docs:build":"mkdocs build"},keywords:["nemar","bids","neuroimaging","eeg","emg","datalad","cli"],author:"NEMAR Team",license:"MIT",repository:{type:"git",url:"git+https://github.com/nemarOrg/nemar-cli.git"},bugs:{url:"https://github.com/nemarOrg/nemar-cli/issues"},homepage:"https://nemar-cli.pages.dev",engines:{bun:">=1.0.0"},files:["dist","README.md","LICENSE"],dependencies:{chalk:"^5.3.0",commander:"^12.1.0",conf:"^13.0.1",inquirer:"^9.2.15",ora:"^8.0.1",zod:"^3.23.8"},devDependencies:{"@biomejs/biome":"1.9.4","@types/bcryptjs":"^3.0.0","@types/bun":"latest","@types/inquirer":"^9.0.7",bcryptjs:"^3.0.3",typescript:"^5.5.4"}};var k_=S_.version;var E1=new Z0;E1.name("nemar").description(`CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource)
|
|
788
788
|
|
|
789
789
|
NEMAR is a curated repository for neurophysiology data in BIDS format.
|
|
790
790
|
This CLI provides tools for uploading, downloading, and managing datasets.`).version(k_,"-v, --version","Output the current version").option("--no-color","Disable colored output").option("--verbose","Enable verbose output").addHelpText("after",`
|
package/package.json
CHANGED