nemar-cli 0.5.1-dev.255 → 0.5.1-dev.256
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
|
@@ -400,7 +400,7 @@ Description:
|
|
|
400
400
|
|
|
401
401
|
Examples:
|
|
402
402
|
$ nemar auth regenerate-key`).action(async()=>{console.log(W.yellow("API Key Regeneration")),console.log(W.gray(`This will revoke your current key and generate a new one
|
|
403
|
-
`));let{email:D}=await MD.prompt([{type:"input",name:"email",message:"Email address associated with your account:",validate:($)=>{if(!$||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test($))return"Please enter a valid email address";return!0}}]),F=C("Sending verification email...").start();try{let $=await uv(D);F.succeed("Verification email sent"),console.log(),console.log("Next steps:"),console.log(" 1. Check your email for a verification link"),console.log(" 2. Click the link to generate your new API key"),console.log(" 3. Copy the new key and run 'nemar auth login'"),console.log(),console.log(W.gray("The link expires in 1 hour"))}catch($){if($ instanceof u)F.fail($.message);else F.fail("Failed to send verification email"),console.log(W.gray(" Check your internet connection"))}});import{existsSync as c0,mkdtempSync as HHD,readFileSync as x5,writeFileSync as FB}from"fs";import{tmpdir as WHD}from"os";import{basename as qHD,join as y5,resolve as Y1}from"path";var{spawn:mD}=globalThis.Bun;import{existsSync as eGD,statSync as DHD}from"fs";import{homedir as s2}from"os";import{join as P5}from"path";var{spawn:k5}=globalThis.Bun;var S5="jsr:@bids/validator",FHD=604800000;async function v5(){try{let D=k5({cmd:["deno","--version"],stdout:"pipe",stderr:"pipe"}),F=await new Response(D.stdout).text();await D.exited;let $=F.match(/deno\s+(\d+\.\d+\.\d+)/);return{installed:!0,version:$?$[1]:void 0}}catch{return{installed:!1}}}function r2(){try{let D=process.platform,F=process.env.DENO_DIR||(D==="darwin"?P5(s2(),"Library","Caches","deno"):D==="win32"?P5(process.env.LOCALAPPDATA||P5(s2(),"AppData","Local"),"deno"):P5(s2(),".cache","deno")),$=P5(F,"deps");if(!eGD($))return!0;let B=DHD($);return Date.now()-B.mtimeMs>FHD}catch{return!0}}async function t2(){try{let D=k5({cmd:["deno","run",`--reload=${S5}`,"-ERWN",S5,"--version"],stdout:"pipe",stderr:"pipe"}),F=await new Response(D.stdout).text();await D.exited;let $=F.match(/(\d+\.\d+\.\d+)/);return $?$[1]:null}catch{return null}}async function e2(){try{let D=k5({cmd:["deno","run","-ERWN",S5,"--version"],stdout:"pipe",stderr:"pipe"}),F=await new Response(D.stdout).text();await D.exited;let $=F.match(/(\d+\.\d+\.\d+)/);return $?$[1]:null}catch{return null}}function iy(D,F={}){let $=["run"];if(F.forceReload)$.push(`--reload=${S5}`);if($.push("-ERWN",S5,D),F.json)$.push("--json");if(F.config)$.push("--config",F.config);if(F.ignoreWarnings)$.push("--ignoreWarnings");if(F.recursive)$.push("--recursive");if(F.prune)$.push("--prune");if(F.verbose)$.push("--verbose");if(F.extraArgs?.length)$.push(...F.extraArgs);return $}async function ay(D,F={}){let $=iy(D,{...F,json:!0}),B=k5({cmd:["deno",...$],stdout:"pipe",stderr:"pipe"}),J=await new Response(B.stdout).text(),Q=await new Response(B.stderr).text(),X=await B.exited;if(X!==0&&!J.trim())throw Error(Q.includes("error:")?Q.split(`
|
|
403
|
+
`));let{email:D}=await MD.prompt([{type:"input",name:"email",message:"Email address associated with your account:",validate:($)=>{if(!$||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test($))return"Please enter a valid email address";return!0}}]),F=C("Sending verification email...").start();try{let $=await uv(D);F.succeed("Verification email sent"),console.log(),console.log("Next steps:"),console.log(" 1. Check your email for a verification link"),console.log(" 2. Click the link to generate your new API key"),console.log(" 3. Copy the new key and run 'nemar auth login'"),console.log(),console.log(W.gray("The link expires in 1 hour"))}catch($){if($ instanceof u)F.fail($.message);else F.fail("Failed to send verification email"),console.log(W.gray(" Check your internet connection"))}});import{existsSync as c0,mkdtempSync as HHD,readFileSync as x5,writeFileSync as FB}from"fs";import{tmpdir as WHD}from"os";import{basename as qHD,join as y5,resolve as Y1}from"path";var{spawn:mD}=globalThis.Bun;import{existsSync as eGD,statSync as DHD}from"fs";import{homedir as s2}from"os";import{join as P5}from"path";var{spawn:k5}=globalThis.Bun;var S5="jsr:@bids/validator@^2",FHD=604800000;async function v5(){try{let D=k5({cmd:["deno","--version"],stdout:"pipe",stderr:"pipe"}),F=await new Response(D.stdout).text();await D.exited;let $=F.match(/deno\s+(\d+\.\d+\.\d+)/);return{installed:!0,version:$?$[1]:void 0}}catch{return{installed:!1}}}function r2(){try{let D=process.platform,F=process.env.DENO_DIR||(D==="darwin"?P5(s2(),"Library","Caches","deno"):D==="win32"?P5(process.env.LOCALAPPDATA||P5(s2(),"AppData","Local"),"deno"):P5(s2(),".cache","deno")),$=P5(F,"deps");if(!eGD($))return!0;let B=DHD($);return Date.now()-B.mtimeMs>FHD}catch{return!0}}async function t2(){try{let D=k5({cmd:["deno","run",`--reload=${S5}`,"-ERWN",S5,"--version"],stdout:"pipe",stderr:"pipe"}),F=await new Response(D.stdout).text();await D.exited;let $=F.match(/(\d+\.\d+\.\d+)/);return $?$[1]:null}catch{return null}}async function e2(){try{let D=k5({cmd:["deno","run","-ERWN",S5,"--version"],stdout:"pipe",stderr:"pipe"}),F=await new Response(D.stdout).text();await D.exited;let $=F.match(/(\d+\.\d+\.\d+)/);return $?$[1]:null}catch{return null}}function iy(D,F={}){let $=["run"];if(F.forceReload)$.push(`--reload=${S5}`);if($.push("-ERWN",S5,D),F.json)$.push("--json");if(F.config)$.push("--config",F.config);if(F.ignoreWarnings)$.push("--ignoreWarnings");if(F.recursive)$.push("--recursive");if(F.prune)$.push("--prune");if(F.verbose)$.push("--verbose");if(F.extraArgs?.length)$.push(...F.extraArgs);return $}async function ay(D,F={}){let $=iy(D,{...F,json:!0}),B=k5({cmd:["deno",...$],stdout:"pipe",stderr:"pipe"}),J=await new Response(B.stdout).text(),Q=await new Response(B.stderr).text(),X=await B.exited;if(X!==0&&!J.trim())throw Error(Q.includes("error:")?Q.split(`
|
|
404
404
|
`).find((K)=>K.includes("error:"))||"Validation failed":`Validation failed with exit code ${X}`);let Y;try{Y=JSON.parse(J)}catch{throw Error(`Failed to parse validator output: ${J.slice(0,200)}`)}let G=Y.issues.issues||[],H=G.filter((K)=>K.severity==="error").length,q=G.filter((K)=>K.severity==="warning").length;return{valid:H===0,issues:G,codeMessages:Y.issues.codeMessages||{},summary:Y.summary,errorCount:H,warningCount:q}}async function oy(D,F={}){let $=iy(D,F),B=k5({cmd:["deno",...$],stdout:"pipe",stderr:"pipe"}),J=await new Response(B.stdout).text(),Q=await new Response(B.stderr).text(),X=await B.exited;return{stdout:J,stderr:Q,exitCode:X}}function sy(D,F=!0){let $=[],B=D.issues.filter((Y)=>Y.severity==="error"),J=D.issues.filter((Y)=>Y.severity==="warning");if(D.valid)$.push(F?"\x1B[32m\u2713 Dataset is valid BIDS\x1B[0m":"\u2713 Dataset is valid BIDS");else $.push(F?"\x1B[31m\u2717 Dataset has validation errors\x1B[0m":"\u2717 Dataset has validation errors");if($.push(""),B.length>0){$.push(F?"\x1B[31mErrors:\x1B[0m":"Errors:");for(let Y of B){let G=F?`\x1B[31m${Y.code}\x1B[0m`:Y.code,H=D.codeMessages[Y.code]?.split(`
|
|
405
405
|
`)[0]||"";if($.push(` ${G}: ${H}`),$.push(` ${Y.location}`),Y.issueMessage)$.push(` ${Y.issueMessage.split(`
|
|
406
406
|
`)[0]}`)}$.push("")}if(J.length>0){$.push(F?"\x1B[33mWarnings:\x1B[0m":"Warnings:");for(let Y of J){let G=F?`\x1B[33m${Y.code}\x1B[0m`:Y.code,H=D.codeMessages[Y.code]?.split(`
|
|
@@ -739,7 +739,7 @@ Examples:
|
|
|
739
739
|
$ nemar sandbox # Run sandbox training
|
|
740
740
|
$ nemar sandbox status # Check if training is completed
|
|
741
741
|
$ nemar sandbox reset # Reset for re-training
|
|
742
|
-
`).action(UHD);async function UHD(){if(console.log(),console.log(W.bold("NEMAR Sandbox Training")),console.log(W.gray("Verify your setup and learn the upload workflow")),console.log(),!vD()){console.log(W.red("Not authenticated")),console.log(W.gray("Run 'nemar auth login' first"));return}let D=Y0();if(D.sandboxCompleted){console.log(W.green("Sandbox training already completed!")),console.log(W.gray(`Dataset ID: ${D.sandboxDatasetId}`)),console.log(),console.log("You can upload real datasets with:"),console.log(W.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(W.gray("To re-run training, use: nemar sandbox reset"));return}console.log(W.bold("Step 1/6: Checking prerequisites..."));let F=C("Checking git-annex and SSH...").start(),$=await b$();if(!$.allPassed){F.fail("Prerequisites check failed"),console.log(),console.log(W.red("Missing requirements:"));for(let I of $.errors)console.log(W.yellow(` - ${I}`));if(!$.githubSSH.accessible)console.log(W.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 l$(D.githubUsername);if(!J.authenticated){B.fail("GitHub CLI not authenticated"),console.log(W.red(` ${J.error}`)),console.log(),console.log("GitHub CLI is required for sandbox training. Install and authenticate:"),console.log(W.cyan(" brew install gh # or visit https://cli.github.com/")),console.log(W.cyan(" gh auth login"));return}if(D.githubUsername&&!J.matches)B.warn("GitHub CLI user mismatch"),console.log(W.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(W.cyan(` gh auth login # Login as ${D.githubUsername}`)),console.log(),console.log(W.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(W.bold("Step 2/6: Generating test dataset..."));let Q=C("Creating minimal BIDS structure...").start(),X;try{let I=Bx();X=I.root;let w=Jx(I);Q.succeed(`Test dataset created (${v3(w)})`),console.log(W.gray(` Location: ${X}`))}catch(I){Q.fail("Failed to generate test dataset"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`));return}console.log(),console.log(W.bold("Step 3/6: Registering sandbox dataset..."));let Y=C("Creating dataset on NEMAR...").start(),G,H,q,K,V,Z;try{let I=await g$({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});G=I.dataset.dataset_id,H=I.dataset.ssh_url,q=I.dataset.github_url,K=I.s3_config,V=I.dataset.s3_prefix,Z=I.upload_urls||{},Y.succeed(`Sandbox dataset created: ${W.cyan(G)}`),console.log(W.gray(` GitHub: ${q}`)),await new Promise((w)=>setTimeout(w,1e4))}catch(I){if(Y.fail("Failed to create sandbox dataset"),I instanceof u)console.log(W.red(` ${I.message}`));else console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`));v1(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(W.red(` Received: ${q||"(empty)"}`)),console.log(W.red(" Expected format: https://github.com/owner/repo")),console.log(),console.log("This may indicate a backend issue. Please contact support."),v1(X);return}let M=await d$(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(W.yellow(` ${M.error}`)),console.log(),console.log("You may need to accept the invitation manually:"),console.log(W.cyan(` https://github.com/${L}/invitations`)),console.log();console.log(),console.log(W.bold("Step 4/6: Initializing repository..."));let N=C("Setting up git-annex...").start(),O=D.username&&D.email?{name:D.username,email:D.email}:void 0;try{await u$(X,{author:O}),await m$(X),await p$(X,H),N.succeed("Repository initialized")}catch(I){N.fail("Failed to initialize repository"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`)),v1(X);return}if(console.log(),console.log(W.bold("Step 5/6: Uploading to S3...")),Object.keys(Z).length===0)console.log(W.yellow(" No data files to upload (metadata only)"));else{let I=C("Uploading test data...").start();try{let c=0,GD=Object.keys(Z).length,S=await c$(X,Z,{jobs:4,onProgress:(JD)=>{if(JD.status==="completed"||JD.status==="failed")c++,I.text=`Uploading... ${c}/${GD} files`}});if(S.failed.length>0){I.fail(`Upload failed for ${S.failed.length} file(s)`);for(let JD of S.failed)console.log(W.red(` Failed: ${JD}`));if(S.error)console.log(W.red(` Error: ${S.error}`));console.log(),console.log(W.yellow("Sandbox training aborted due to upload failures.")),console.log(W.gray("Please check your network connection and try again.")),v1(X);return}I.succeed(`Uploaded ${S.uploaded} file(s)`)}catch(c){I.fail("Upload failed"),console.log(W.red(` ${c instanceof Error?c.message:"Unknown error"}`)),v1(X);return}let w=C("Registering file URLs...").start();try{let c={};for(let S of Object.keys(Z))c[S]=`${K.public_url}/${V}/objects/${S}`;let GD=await n$(X,c);if(!GD.success){w.fail(`URL registration failed for ${GD.failed.length} file(s)`);for(let S of GD.failed)console.log(W.red(` Failed: ${S}`));console.log(),console.log(W.yellow("Sandbox training aborted due to URL registration failures.")),console.log(W.gray("This may indicate a git-annex configuration issue.")),v1(X);return}w.succeed(`Registered ${GD.registered} file URLs`)}catch(c){w.fail("Failed to register URLs"),console.log(W.red(` ${c instanceof Error?c.message:"Unknown error"}`)),v1(X);return}}console.log(),console.log(W.bold("Step 6/6: Pushing to GitHub..."));let g=C("Saving and pushing...").start();try{await j5(X,"Initial sandbox training upload",O),await T5(X),g.succeed("Pushed to GitHub")}catch(I){g.fail("Failed to push to GitHub"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`)),v1(X);return}let j=C("Finalizing...").start();try{await h$(G),await Qy(G),R0("sandboxCompleted",!0),R0("sandboxDatasetId",G),j.succeed("Sandbox training complete!")}catch(I){j.fail("Failed to finalize"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`)),v1(X);return}v1(X),console.log(),console.log(W.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(W.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(W.gray(`Sandbox dataset: ${G}`))}BB.command("status").description("Check sandbox training completion status").option("--refresh","Fetch latest status from server").action(async(D)=>{if(!vD()){console.log(W.red("Not authenticated")),console.log(W.gray("Run 'nemar auth login' first"));return}if(D.refresh){let F=C("Checking status...").start();try{let $=await Yy();if(R0("sandboxCompleted",$.sandbox_completed),$.sandbox_dataset_id)R0("sandboxDatasetId",$.sandbox_dataset_id);if(F.stop(),$.sandbox_completed){if(console.log(W.green("Sandbox training: Completed")),console.log(W.gray(` Dataset ID: ${$.sandbox_dataset_id}`)),$.sandbox_completed_at)console.log(W.gray(` Completed: ${$.sandbox_completed_at}`))}else console.log(W.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(W.cyan(" nemar sandbox"))}catch($){if(F.fail("Failed to check status"),$ instanceof u)console.log(W.red(` ${$.message}`))}}else{let F=Y0();if(F.sandboxCompleted)console.log(W.green("Sandbox training: Completed")),console.log(W.gray(` Dataset ID: ${F.sandboxDatasetId}`));else console.log(W.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(W.cyan(" nemar sandbox"))}});BB.command("reset").description("Reset sandbox training status for re-training").option(yD,xD).option(lD,dD).action(async(D)=>{if(!vD()){console.log(W.red("Not authenticated")),console.log(W.gray("Run 'nemar auth login' first"));return}if(!Y0().sandboxCompleted){console.log(W.yellow("Sandbox training not yet completed")),console.log(W.gray("Nothing to reset"));return}let $=await OD("Reset sandbox training status? You will need to complete training again.",D);if($!=="confirmed"){console.log(W.gray($==="declined"?"Skipped":"Cancelled"));return}let B=C("Resetting sandbox status...").start();try{await Xy(),h2("sandboxCompleted"),h2("sandboxDatasetId"),B.succeed("Sandbox status reset"),console.log(),console.log("Run sandbox training again with:"),console.log(W.cyan(" nemar sandbox"))}catch(J){if(B.fail("Failed to reset"),J instanceof u)console.log(W.red(` ${J.message}`));else console.log(W.red(` ${J instanceof Error?J.message:"Unknown error"}`))}});var Qx={name:"nemar-cli",version:"0.5.1-dev.255",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 Xx=Qx.version;var y1=new H0;y1.name("nemar").description(`CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource)
|
|
742
|
+
`).action(UHD);async function UHD(){if(console.log(),console.log(W.bold("NEMAR Sandbox Training")),console.log(W.gray("Verify your setup and learn the upload workflow")),console.log(),!vD()){console.log(W.red("Not authenticated")),console.log(W.gray("Run 'nemar auth login' first"));return}let D=Y0();if(D.sandboxCompleted){console.log(W.green("Sandbox training already completed!")),console.log(W.gray(`Dataset ID: ${D.sandboxDatasetId}`)),console.log(),console.log("You can upload real datasets with:"),console.log(W.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(W.gray("To re-run training, use: nemar sandbox reset"));return}console.log(W.bold("Step 1/6: Checking prerequisites..."));let F=C("Checking git-annex and SSH...").start(),$=await b$();if(!$.allPassed){F.fail("Prerequisites check failed"),console.log(),console.log(W.red("Missing requirements:"));for(let I of $.errors)console.log(W.yellow(` - ${I}`));if(!$.githubSSH.accessible)console.log(W.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 l$(D.githubUsername);if(!J.authenticated){B.fail("GitHub CLI not authenticated"),console.log(W.red(` ${J.error}`)),console.log(),console.log("GitHub CLI is required for sandbox training. Install and authenticate:"),console.log(W.cyan(" brew install gh # or visit https://cli.github.com/")),console.log(W.cyan(" gh auth login"));return}if(D.githubUsername&&!J.matches)B.warn("GitHub CLI user mismatch"),console.log(W.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(W.cyan(` gh auth login # Login as ${D.githubUsername}`)),console.log(),console.log(W.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(W.bold("Step 2/6: Generating test dataset..."));let Q=C("Creating minimal BIDS structure...").start(),X;try{let I=Bx();X=I.root;let w=Jx(I);Q.succeed(`Test dataset created (${v3(w)})`),console.log(W.gray(` Location: ${X}`))}catch(I){Q.fail("Failed to generate test dataset"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`));return}console.log(),console.log(W.bold("Step 3/6: Registering sandbox dataset..."));let Y=C("Creating dataset on NEMAR...").start(),G,H,q,K,V,Z;try{let I=await g$({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});G=I.dataset.dataset_id,H=I.dataset.ssh_url,q=I.dataset.github_url,K=I.s3_config,V=I.dataset.s3_prefix,Z=I.upload_urls||{},Y.succeed(`Sandbox dataset created: ${W.cyan(G)}`),console.log(W.gray(` GitHub: ${q}`)),await new Promise((w)=>setTimeout(w,1e4))}catch(I){if(Y.fail("Failed to create sandbox dataset"),I instanceof u)console.log(W.red(` ${I.message}`));else console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`));v1(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(W.red(` Received: ${q||"(empty)"}`)),console.log(W.red(" Expected format: https://github.com/owner/repo")),console.log(),console.log("This may indicate a backend issue. Please contact support."),v1(X);return}let M=await d$(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(W.yellow(` ${M.error}`)),console.log(),console.log("You may need to accept the invitation manually:"),console.log(W.cyan(` https://github.com/${L}/invitations`)),console.log();console.log(),console.log(W.bold("Step 4/6: Initializing repository..."));let N=C("Setting up git-annex...").start(),O=D.username&&D.email?{name:D.username,email:D.email}:void 0;try{await u$(X,{author:O}),await m$(X),await p$(X,H),N.succeed("Repository initialized")}catch(I){N.fail("Failed to initialize repository"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`)),v1(X);return}if(console.log(),console.log(W.bold("Step 5/6: Uploading to S3...")),Object.keys(Z).length===0)console.log(W.yellow(" No data files to upload (metadata only)"));else{let I=C("Uploading test data...").start();try{let c=0,GD=Object.keys(Z).length,S=await c$(X,Z,{jobs:4,onProgress:(JD)=>{if(JD.status==="completed"||JD.status==="failed")c++,I.text=`Uploading... ${c}/${GD} files`}});if(S.failed.length>0){I.fail(`Upload failed for ${S.failed.length} file(s)`);for(let JD of S.failed)console.log(W.red(` Failed: ${JD}`));if(S.error)console.log(W.red(` Error: ${S.error}`));console.log(),console.log(W.yellow("Sandbox training aborted due to upload failures.")),console.log(W.gray("Please check your network connection and try again.")),v1(X);return}I.succeed(`Uploaded ${S.uploaded} file(s)`)}catch(c){I.fail("Upload failed"),console.log(W.red(` ${c instanceof Error?c.message:"Unknown error"}`)),v1(X);return}let w=C("Registering file URLs...").start();try{let c={};for(let S of Object.keys(Z))c[S]=`${K.public_url}/${V}/objects/${S}`;let GD=await n$(X,c);if(!GD.success){w.fail(`URL registration failed for ${GD.failed.length} file(s)`);for(let S of GD.failed)console.log(W.red(` Failed: ${S}`));console.log(),console.log(W.yellow("Sandbox training aborted due to URL registration failures.")),console.log(W.gray("This may indicate a git-annex configuration issue.")),v1(X);return}w.succeed(`Registered ${GD.registered} file URLs`)}catch(c){w.fail("Failed to register URLs"),console.log(W.red(` ${c instanceof Error?c.message:"Unknown error"}`)),v1(X);return}}console.log(),console.log(W.bold("Step 6/6: Pushing to GitHub..."));let g=C("Saving and pushing...").start();try{await j5(X,"Initial sandbox training upload",O),await T5(X),g.succeed("Pushed to GitHub")}catch(I){g.fail("Failed to push to GitHub"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`)),v1(X);return}let j=C("Finalizing...").start();try{await h$(G),await Qy(G),R0("sandboxCompleted",!0),R0("sandboxDatasetId",G),j.succeed("Sandbox training complete!")}catch(I){j.fail("Failed to finalize"),console.log(W.red(` ${I instanceof Error?I.message:"Unknown error"}`)),v1(X);return}v1(X),console.log(),console.log(W.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(W.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(W.gray(`Sandbox dataset: ${G}`))}BB.command("status").description("Check sandbox training completion status").option("--refresh","Fetch latest status from server").action(async(D)=>{if(!vD()){console.log(W.red("Not authenticated")),console.log(W.gray("Run 'nemar auth login' first"));return}if(D.refresh){let F=C("Checking status...").start();try{let $=await Yy();if(R0("sandboxCompleted",$.sandbox_completed),$.sandbox_dataset_id)R0("sandboxDatasetId",$.sandbox_dataset_id);if(F.stop(),$.sandbox_completed){if(console.log(W.green("Sandbox training: Completed")),console.log(W.gray(` Dataset ID: ${$.sandbox_dataset_id}`)),$.sandbox_completed_at)console.log(W.gray(` Completed: ${$.sandbox_completed_at}`))}else console.log(W.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(W.cyan(" nemar sandbox"))}catch($){if(F.fail("Failed to check status"),$ instanceof u)console.log(W.red(` ${$.message}`))}}else{let F=Y0();if(F.sandboxCompleted)console.log(W.green("Sandbox training: Completed")),console.log(W.gray(` Dataset ID: ${F.sandboxDatasetId}`));else console.log(W.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(W.cyan(" nemar sandbox"))}});BB.command("reset").description("Reset sandbox training status for re-training").option(yD,xD).option(lD,dD).action(async(D)=>{if(!vD()){console.log(W.red("Not authenticated")),console.log(W.gray("Run 'nemar auth login' first"));return}if(!Y0().sandboxCompleted){console.log(W.yellow("Sandbox training not yet completed")),console.log(W.gray("Nothing to reset"));return}let $=await OD("Reset sandbox training status? You will need to complete training again.",D);if($!=="confirmed"){console.log(W.gray($==="declined"?"Skipped":"Cancelled"));return}let B=C("Resetting sandbox status...").start();try{await Xy(),h2("sandboxCompleted"),h2("sandboxDatasetId"),B.succeed("Sandbox status reset"),console.log(),console.log("Run sandbox training again with:"),console.log(W.cyan(" nemar sandbox"))}catch(J){if(B.fail("Failed to reset"),J instanceof u)console.log(W.red(` ${J.message}`));else console.log(W.red(` ${J instanceof Error?J.message:"Unknown error"}`))}});var Qx={name:"nemar-cli",version:"0.5.1-dev.256",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 Xx=Qx.version;var y1=new H0;y1.name("nemar").description(`CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource)
|
|
743
743
|
|
|
744
744
|
NEMAR is a curated repository for neurophysiology data in BIDS format.
|
|
745
745
|
This CLI provides tools for uploading, downloading, and managing datasets.`).version(Xx,"-v, --version","Output the current version").option("--no-color","Disable colored output").option("--verbose","Enable verbose output").addHelpText("after",`
|
package/package.json
CHANGED