nemar-cli 0.4.0-dev.195 → 0.4.0-dev.196
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
|
@@ -176,7 +176,7 @@ ${E.cyan("CI Status:")} ${D}
|
|
|
176
176
|
`);let B=$.bids_validation.present,J=B?E.green("[x]"):E.red("[ ]");if(console.log(` ${J} BIDS Validation`),B){let Y=$.bids_validation.status==="success"?E.green:$.bids_validation.status==="failure"?E.red:E.yellow;if(console.log(` Status: ${Y($.bids_validation.status)}`),$.bids_validation.url)console.log(` URL: ${E.gray($.bids_validation.url)}`)}else console.log(` ${E.gray("Not deployed. Use 'nemar admin ci add' to deploy.")}`);let Q=$.version_check.present,X=Q?E.green("[x]"):E.red("[ ]");if(console.log(` ${X} Version Check`),!Q)console.log(` ${E.gray("Not deployed. Use 'nemar admin ci add' to deploy.")}`);console.log()}catch($){M1($,F,"Failed to check CI status",{404:"Dataset not found"})}});_2.command("add").description("Deploy CI workflows to a dataset repository").argument("<dataset-id>","Dataset ID (e.g., nm000104)").option(vD,yD).option(hD,bD).action(async(D,F)=>{if(!cD())return;console.log(E.cyan(`
|
|
177
177
|
Deploy CI workflows to: ${D}
|
|
178
178
|
`)),console.log("This will add the following workflows:"),console.log(" 1. BIDS Validation (runs on PRs)"),console.log(" 2. Version Check (ensures version bump on PRs)"),console.log(" 3. PR Merge Handler (creates releases, publishes DOIs)"),console.log();let $=await gD(`Deploy CI workflows to ${D}?`,F);if($!=="confirmed"){console.log(E.gray($==="declined"?"Skipped":"Cancelled"));return}let B=R(`Deploying CI workflows to ${D}...`).start();try{let J=await w$(D);B.succeed("CI workflows deployed"),console.log();for(let Q of J.workflows_deployed)console.log(` ${E.green("[x]")} ${Q}`);console.log()}catch(J){M1(J,B,"Failed to deploy CI workflows",{404:"Dataset not found"})}});_0.addCommand(_2);var T5=new B0("doi").description("DOI management");T5.command("create").description("Create concept DOI for a dataset").argument("<dataset-id>","Dataset ID (e.g., nm000104)").option("--title <title>","DOI title (defaults to dataset name)").option("--description <desc>","DOI description").option("--provider <provider>","DOI provider: ezid (default) or zenodo","ezid").option("--sandbox","Use sandbox/test DOI").option(vD,yD).option(hD,bD).action(async(D,F)=>{if(!cD())return;let $=R("Fetching dataset info...").start(),B;try{B=await a1(D),$.succeed(`Found dataset: ${B.name}`)}catch(G){if(G instanceof c){if($.fail(G.message),G.statusCode===404)console.log(E.gray(" Dataset not found"))}else $.fail("Failed to fetch dataset");return}try{let G=await L5(D);if(G.concept_doi){if(console.log(E.yellow(`
|
|
179
|
-
Dataset already has a concept DOI:`)),console.log(` Concept DOI: ${E.cyan(G.concept_doi)}`),G.zenodo_concept_url)console.log(` Zenodo URL: ${G.zenodo_concept_url}`);return}}catch{}if(console.log(),console.log(E.cyan("Dataset Information:")),console.log(` ID: ${B.dataset_id}`),console.log(` Name: ${B.name}`),B.github_repo)console.log(` GitHub: ${B.github_repo}`);if(F.sandbox)console.log(` Mode: ${E.yellow("SANDBOX (test DOI)")}`);console.log();let J=F.provider==="zenodo"?"zenodo":"ezid";if(F.sandbox){if(console.log(E.yellow("\u2501".repeat(60))),console.log(E.yellow.bold(" SANDBOX MODE ENABLED")),console.log(E.yellow("\u2501".repeat(60))),J==="zenodo")console.log(E.yellow(" \u2022 Using Zenodo sandbox (sandbox.zenodo.org)"));else console.log(E.yellow(" \u2022 Using EZID test shoulder (doi:10.5072/FK2)")),console.log(E.yellow(" \u2022 Test DOIs auto-delete after 2 weeks"));console.log(E.yellow(" \u2022 DOI will NOT be indexed by DataCite")),console.log(E.yellow(" \u2022 DOI will NOT resolve in production")),console.log(E.yellow(" \u2022 Use this for testing workflows only")),console.log(E.yellow("\u2501".repeat(60))),console.log()}console.log(E.red("WARNING: DOIs are PERMANENT and cannot be deleted!")),console.log(E.gray("The DOI will be pre-reserved but not published until the first version release.")),console.log(` Provider: ${E.cyan(J.toUpperCase())}`),console.log();let Q=F.sandbox?`Create TEST concept DOI via ${J.toUpperCase()} SANDBOX?`:`Create PERMANENT concept DOI via ${J.toUpperCase()} PRODUCTION?`,X=await gD(Q,F);if(X!=="confirmed"){console.log(E.gray(X==="declined"?"Skipped":"Cancelled"));return}let Y=R(`Creating concept DOI via ${J.toUpperCase()}...`).start();try{let G=await xv(D,{title:F.title,description:F.description,sandbox:F.sandbox,provider:J});Y.succeed("Concept DOI created successfully");let H=R("Applying branch protection...").start();try{let W=await O$(D);if(W.warnings&&W.warnings.length>0){H.warn("Branch protection applied with warnings");for(let K of W.warnings)console.log(E.yellow(` Warning: ${K}`))}else H.succeed("Branch protection applied")}catch(W){if(H.warn("Could not apply branch protection"),W instanceof c){if(console.log(E.gray(` ${W.message}`)),W.statusCode===403)console.log(E.gray(" Check admin credentials and permissions"))}else console.log(E.gray(` ${W instanceof Error?W.message:"Unknown error"}`));console.log(E.gray(" Manual setup: Go to GitHub repo Settings > Branches > Add rule"))}if(console.log(),console.log(E.green("DOI Information:")),console.log(` Concept DOI: ${E.cyan(G.concept_doi)}`),console.log(` Provider: ${G.provider.toUpperCase()}`),G.provider==="ezid")console.log(` DOI URL: ${G.doi_url}`),console.log(` EZID ID: ${G.ezid_identifier}`);else console.log(` Zenodo URL: ${G.zenodo_url}`);if(G.metadata_warning)console.log(E.yellow(` Warning: ${G.metadata_warning}`));if(console.log(),console.log(E.yellow("Next steps:")),console.log(" 1. Set up automatic DOI publishing by running:"),console.log(E.gray(` ${G.setup_command}`)),console.log(" (paste the webhook token when prompted)"),console.log(),console.log(" 2. Update dataset_description.json with DatasetDOI field"),console.log(" 3. Create a PR and merge it to trigger version DOI publication"),console.log(),F.sandbox)console.log(E.gray("Note: This is a sandbox DOI and will not resolve in production."))}catch(G){if(G instanceof c){if(Y.fail(G.message),G.statusCode===403)console.log(E.gray(" This command requires admin privileges"))}else Y.fail("Failed to create concept DOI"),console.log(E.gray(` ${I0(G)}`))}});T5.command("info").description("Get DOI info for a dataset").argument("<dataset-id>","Dataset ID (e.g., nm000104)").action(async(D)=>{if(!cD())return;let F=R("Fetching DOI info...").start();try{let $=await L5(D);if(F.stop(),console.log(),console.log(E.cyan(`DOI Information for ${D}:`)),console.log(` Dataset Name: ${$.name}`),console.log(),$.concept_doi){if(console.log(E.green("Concept DOI:")),console.log(` DOI: ${$.concept_doi}`),console.log(` URL: https://doi.org/${$.concept_doi}`),console.log(` Provider: ${($.doi_provider||"zenodo").toUpperCase()}`),$.doi_provider==="ezid"){if($.ezid_identifier)console.log(` EZID ID: ${$.ezid_identifier}`);if($.ezid_status){let B=$.ezid_status==="public"?E.green:E.yellow;console.log(` Status: ${B($.ezid_status)}`)}}if($.zenodo_concept_url){if(console.log(` Zenodo: ${$.zenodo_concept_url}`),$.zenodo_concept_url.includes("sandbox.zenodo.org"))console.log(),console.log(E.yellow("Mode: SANDBOX (test DOI)")),console.log(E.yellow(" This DOI is not indexed by DataCite and will not resolve in production"))}}else console.log(E.yellow("No concept DOI created yet")),console.log(E.gray(" Use 'nemar admin doi create' to create one"));if(console.log(),$.latest_version_doi){if(console.log(E.green("Latest Version DOI:")),console.log(` DOI: ${$.latest_version_doi}`),console.log(` URL: https://doi.org/${$.latest_version_doi}`),$.zenodo_latest_version_url)console.log(` Zenodo: ${$.zenodo_latest_version_url}`)}else if($.concept_doi)console.log(E.yellow("No version DOI published yet")),console.log(E.gray(" Version DOIs are created automatically on PR merge"))}catch($){if($ instanceof c){if(F.fail($.message),$.statusCode===404)console.log(E.gray(" Dataset not found"));else if($.statusCode===403)console.log(E.gray(" This command requires admin privileges"))}else F.fail("Failed to fetch DOI info")}});T5.command("update").description("Update EZID DOI metadata or status").argument("<dataset-id>","Dataset ID (e.g., nm000104)").option("--make-public","Transition DOI from reserved to public (permanent)").option("--refresh","Refresh metadata from BIDS dataset_description.json").option(vD,yD).option(hD,bD).action(async(D,F)=>{if(!cD())return;if(!F.makePublic&&!F.refresh){console.log(E.yellow("No action specified. Use --make-public and/or --refresh."));return}if(F.makePublic){console.log(E.red("WARNING: Making a DOI public is PERMANENT!")),console.log(E.gray(" The DOI will be findable in DataCite and cannot be reverted.")),console.log();let B=await gD(`Make DOI for ${D} PUBLIC and permanent?`,F);if(B!=="confirmed"){console.log(E.gray(B==="declined"?"Skipped":"Cancelled"));return}}let $=R("Updating DOI...").start();try{let B=await I2(D,{status:F.makePublic?"public":void 0,refresh_metadata:F.refresh});$.succeed("DOI updated successfully"),console.log(),console.log(` EZID ID: ${E.cyan(B.ezid_identifier)}`),console.log(` Status: ${B.status==="public"?E.green(B.status):E.yellow(B.status)}`),console.log(` URL: ${B.doi_url}`)}catch(B){if(B instanceof c){if($.fail(B.message),B.statusCode===400)console.log(E.gray(" DOI update is only supported for EZID-managed DOIs"))}else $.fail("Failed to update DOI"),console.log(E.gray(` ${I0(B)}`))}});T5.command("enrich").description("Enrich DOI metadata with ORCIDs, descriptions, funding, and more").argument("<dataset-id>","Dataset ID (e.g., nm000104)").option("--no-llm","Skip LLM-based enrichment from README").option("--sandbox","Use sandbox DOI").option(vD,yD).option(hD,bD).action(async(D,F)=>{if(!cD())return;let $=R("Fetching dataset and existing enrichment...").start(),B;try{B=await a1(D),$.succeed(`Dataset: ${B.name}`)}catch(K){if(K instanceof c)$.fail(K.message);else $.fail("Failed to fetch dataset");return}let J,Q=!1;try{J=await L5(D)}catch(K){if(K instanceof c&&K.statusCode===404);else Q=!0,console.log(E.yellow(` Warning: Could not fetch DOI info: ${I0(K)}`))}if(J?.concept_doi)console.log(` DOI: ${E.cyan(J.concept_doi)}`);let X={version:"1.0"};console.log(),console.log(E.cyan("--- Author ORCIDs ---"));let{updateAuthors:Y}=await xD.prompt([{type:"confirm",name:"updateAuthors",message:"Update author ORCIDs?",default:!1}]);if(Y){let K={},V=!0;while(V){let{authorName:A}=await xD.prompt([{type:"input",name:"authorName",message:'Author name (as in BIDS, e.g., "Shirazi, Yahya"):'}]);if(!A)break;let{orcid:Z}=await xD.prompt([{type:"input",name:"orcid",message:`ORCID for "${A}" (Enter to skip):`,validate:(N)=>{if(!N)return!0;return R$.test(N)||"Invalid ORCID format (XXXX-XXXX-XXXX-XXXX)"}}]),U={};if(Z)U.orcid=Z;let{affiliation:L}=await xD.prompt([{type:"input",name:"affiliation",message:`Affiliation for "${A}" (optional):`}]);if(L)U.affiliation=L;if(U.orcid||U.affiliation)K[A]=U;let{more:M}=await xD.prompt([{type:"confirm",name:"more",message:"Add another author?",default:!0}]);V=M}if(Object.keys(K).length>0)X.authors=K}if(F.llm!==!1){console.log(),console.log(E.cyan("--- Generating enrichment from README ---"));let K=process.env.OPENROUTER_API_KEY;if(!K)console.log(E.yellow(" OPENROUTER_API_KEY not set; skipping LLM enrichment")),console.log(E.gray(" Set it in your environment to enable LLM-based enrichment"));else{let V=R("Analyzing README and dataset metadata...").start();try{let{enrichFromReadme:A}=await Promise.resolve().then(() => (Vy(),zy)),Z=B.github_repo;if(!Z)V.warn("No GitHub repository configured for this dataset");else{let U=await Ay(Z,"README");if(!U)V.warn("Could not fetch README from repository");else{let L=await Ay(Z,"dataset_description.json"),M={};if(L)try{M=JSON.parse(L)}catch{console.log(E.yellow(" Warning: Could not parse dataset_description.json; LLM will use README only"))}let N=await A(U,M,K);if(V.succeed("LLM enrichment complete"),N.description)console.log(` Description: ${N.description.slice(0,100)}...`),X.description=N.description;if(N.methodsDescription)X.methodsDescription=N.methodsDescription;if(N.keywords&&N.keywords.length>0)console.log(` Keywords: ${N.keywords.join(", ")}`),X.keywords=N.keywords;if(N.fundingReferences&&N.fundingReferences.length>0)console.log(` Funding: ${N.fundingReferences.map((O)=>`${O.funderName} ${O.awardNumber||""}`).join(", ")}`),X.fundingReferences=N.fundingReferences;if(N.relatedDois&&N.relatedDois.length>0)console.log(` Related DOIs: ${N.relatedDois.map((O)=>`${O.doi} (${O.relationType})`).join(", ")}`),X.relatedDois=N.relatedDois}}}catch(A){V.fail("LLM enrichment failed"),console.log(E.gray(` ${I0(A)}`))}}}console.log(),console.log(E.cyan("--- Dataset stats ---"));let G=R("Computing dataset sizes and formats...").start();try{let K=await av(D),V=PF(K.total_size);X.sizes=[`${V} (${K.file_count} files)`],X.formats=K.extensions,G.succeed(`Sizes: ${V} (${K.file_count} files), Formats: ${K.extensions.join(", ")}`)}catch(K){G.warn("Could not compute dataset stats"),console.log(E.gray(` ${I0(K)}`))}console.log(),console.log(E.cyan("--- Review ---")),console.log(JSON.stringify(X,null,2)),console.log();let H=await gD("Commit to repo and refresh DOI?",F,!0);if(H!=="confirmed"){console.log(E.gray(H==="declined"?"Skipped":"Cancelled"));return}let W=R("Saving enrichment...").start();try{let K=await iv(D,X);if(W.succeed(K.message),K.bidsignore_updated)console.log(E.gray(" .bidsignore updated to include nemar_metadata.json"));if(!J&&Q)try{J=await L5(D)}catch{}if(J?.ezid_identifier){let V=R("Refreshing DOI metadata...").start();try{await I2(D,{refresh_metadata:!0}),V.succeed("DOI metadata refreshed")}catch(A){V.warn("Could not refresh DOI metadata"),console.log(E.gray(` ${I0(A)}`))}}else if(Q)console.log(E.yellow(" DOI refresh skipped: could not verify DOI exists. Run 'nemar admin doi update --refresh' manually."))}catch(K){if(K instanceof c)W.fail(K.message);else W.fail("Failed to save enrichment"),console.log(E.gray(` ${I0(K)}`))}});_0.addCommand(T5);var f$=new B0("publish").description("Publication workflow management");f$.command("list").description("List publication requests").option("-s, --status <status>","Filter by status (requested, approving, published, denied)").addHelpText("after",`
|
|
179
|
+
Dataset already has a concept DOI:`)),console.log(` Concept DOI: ${E.cyan(G.concept_doi)}`),G.zenodo_concept_url)console.log(` Zenodo URL: ${G.zenodo_concept_url}`);return}}catch(G){if(process.env.DEBUG)console.error("[debug] DOI info fetch:",G)}if(console.log(),console.log(E.cyan("Dataset Information:")),console.log(` ID: ${B.dataset_id}`),console.log(` Name: ${B.name}`),B.github_repo)console.log(` GitHub: ${B.github_repo}`);if(F.sandbox)console.log(` Mode: ${E.yellow("SANDBOX (test DOI)")}`);console.log();let J=F.provider==="zenodo"?"zenodo":"ezid";if(F.sandbox){if(console.log(E.yellow("\u2501".repeat(60))),console.log(E.yellow.bold(" SANDBOX MODE ENABLED")),console.log(E.yellow("\u2501".repeat(60))),J==="zenodo")console.log(E.yellow(" \u2022 Using Zenodo sandbox (sandbox.zenodo.org)"));else console.log(E.yellow(" \u2022 Using EZID test shoulder (doi:10.5072/FK2)")),console.log(E.yellow(" \u2022 Test DOIs auto-delete after 2 weeks"));console.log(E.yellow(" \u2022 DOI will NOT be indexed by DataCite")),console.log(E.yellow(" \u2022 DOI will NOT resolve in production")),console.log(E.yellow(" \u2022 Use this for testing workflows only")),console.log(E.yellow("\u2501".repeat(60))),console.log()}console.log(E.red("WARNING: DOIs are PERMANENT and cannot be deleted!")),console.log(E.gray("The DOI will be pre-reserved but not published until the first version release.")),console.log(` Provider: ${E.cyan(J.toUpperCase())}`),console.log();let Q=F.sandbox?`Create TEST concept DOI via ${J.toUpperCase()} SANDBOX?`:`Create PERMANENT concept DOI via ${J.toUpperCase()} PRODUCTION?`,X=await gD(Q,F);if(X!=="confirmed"){console.log(E.gray(X==="declined"?"Skipped":"Cancelled"));return}let Y=R(`Creating concept DOI via ${J.toUpperCase()}...`).start();try{let G=await xv(D,{title:F.title,description:F.description,sandbox:F.sandbox,provider:J});Y.succeed("Concept DOI created successfully");let H=R("Applying branch protection...").start();try{let W=await O$(D);if(W.warnings&&W.warnings.length>0){H.warn("Branch protection applied with warnings");for(let K of W.warnings)console.log(E.yellow(` Warning: ${K}`))}else H.succeed("Branch protection applied")}catch(W){if(H.warn("Could not apply branch protection"),W instanceof c){if(console.log(E.gray(` ${W.message}`)),W.statusCode===403)console.log(E.gray(" Check admin credentials and permissions"))}else console.log(E.gray(` ${W instanceof Error?W.message:"Unknown error"}`));console.log(E.gray(" Manual setup: Go to GitHub repo Settings > Branches > Add rule"))}if(console.log(),console.log(E.green("DOI Information:")),console.log(` Concept DOI: ${E.cyan(G.concept_doi)}`),console.log(` Provider: ${G.provider.toUpperCase()}`),G.provider==="ezid")console.log(` DOI URL: ${G.doi_url}`),console.log(` EZID ID: ${G.ezid_identifier}`);else console.log(` Zenodo URL: ${G.zenodo_url}`);if(G.metadata_warning)console.log(E.yellow(` Warning: ${G.metadata_warning}`));if(console.log(),console.log(E.yellow("Next steps:")),console.log(" 1. Set up automatic DOI publishing by running:"),console.log(E.gray(` ${G.setup_command}`)),console.log(" (paste the webhook token when prompted)"),console.log(),console.log(" 2. Update dataset_description.json with DatasetDOI field"),console.log(" 3. Create a PR and merge it to trigger version DOI publication"),console.log(),F.sandbox)console.log(E.gray("Note: This is a sandbox DOI and will not resolve in production."))}catch(G){if(G instanceof c){if(Y.fail(G.message),G.statusCode===403)console.log(E.gray(" This command requires admin privileges"))}else Y.fail("Failed to create concept DOI"),console.log(E.gray(` ${I0(G)}`))}});T5.command("info").description("Get DOI info for a dataset").argument("<dataset-id>","Dataset ID (e.g., nm000104)").action(async(D)=>{if(!cD())return;let F=R("Fetching DOI info...").start();try{let $=await L5(D);if(F.stop(),console.log(),console.log(E.cyan(`DOI Information for ${D}:`)),console.log(` Dataset Name: ${$.name}`),console.log(),$.concept_doi){if(console.log(E.green("Concept DOI:")),console.log(` DOI: ${$.concept_doi}`),console.log(` URL: https://doi.org/${$.concept_doi}`),console.log(` Provider: ${($.doi_provider||"zenodo").toUpperCase()}`),$.doi_provider==="ezid"){if($.ezid_identifier)console.log(` EZID ID: ${$.ezid_identifier}`);if($.ezid_status){let B=$.ezid_status==="public"?E.green:E.yellow;console.log(` Status: ${B($.ezid_status)}`)}}if($.zenodo_concept_url){if(console.log(` Zenodo: ${$.zenodo_concept_url}`),$.zenodo_concept_url.includes("sandbox.zenodo.org"))console.log(),console.log(E.yellow("Mode: SANDBOX (test DOI)")),console.log(E.yellow(" This DOI is not indexed by DataCite and will not resolve in production"))}}else console.log(E.yellow("No concept DOI created yet")),console.log(E.gray(" Use 'nemar admin doi create' to create one"));if(console.log(),$.latest_version_doi){if(console.log(E.green("Latest Version DOI:")),console.log(` DOI: ${$.latest_version_doi}`),console.log(` URL: https://doi.org/${$.latest_version_doi}`),$.zenodo_latest_version_url)console.log(` Zenodo: ${$.zenodo_latest_version_url}`)}else if($.concept_doi)console.log(E.yellow("No version DOI published yet")),console.log(E.gray(" Version DOIs are created automatically on PR merge"))}catch($){if($ instanceof c){if(F.fail($.message),$.statusCode===404)console.log(E.gray(" Dataset not found"));else if($.statusCode===403)console.log(E.gray(" This command requires admin privileges"))}else F.fail("Failed to fetch DOI info")}});T5.command("update").description("Update EZID DOI metadata or status").argument("<dataset-id>","Dataset ID (e.g., nm000104)").option("--make-public","Transition DOI from reserved to public (permanent)").option("--refresh","Refresh metadata from BIDS dataset_description.json").option(vD,yD).option(hD,bD).action(async(D,F)=>{if(!cD())return;if(!F.makePublic&&!F.refresh){console.log(E.yellow("No action specified. Use --make-public and/or --refresh."));return}if(F.makePublic){console.log(E.red("WARNING: Making a DOI public is PERMANENT!")),console.log(E.gray(" The DOI will be findable in DataCite and cannot be reverted.")),console.log();let B=await gD(`Make DOI for ${D} PUBLIC and permanent?`,F);if(B!=="confirmed"){console.log(E.gray(B==="declined"?"Skipped":"Cancelled"));return}}let $=R("Updating DOI...").start();try{let B=await I2(D,{status:F.makePublic?"public":void 0,refresh_metadata:F.refresh});$.succeed("DOI updated successfully"),console.log(),console.log(` EZID ID: ${E.cyan(B.ezid_identifier)}`),console.log(` Status: ${B.status==="public"?E.green(B.status):E.yellow(B.status)}`),console.log(` URL: ${B.doi_url}`)}catch(B){if(B instanceof c){if($.fail(B.message),B.statusCode===400)console.log(E.gray(" DOI update is only supported for EZID-managed DOIs"))}else $.fail("Failed to update DOI"),console.log(E.gray(` ${I0(B)}`))}});T5.command("enrich").description("Enrich DOI metadata with ORCIDs, descriptions, funding, and more").argument("<dataset-id>","Dataset ID (e.g., nm000104)").option("--no-llm","Skip LLM-based enrichment from README").option("--sandbox","Use sandbox DOI").option(vD,yD).option(hD,bD).action(async(D,F)=>{if(!cD())return;let $=R("Fetching dataset and existing enrichment...").start(),B;try{B=await a1(D),$.succeed(`Dataset: ${B.name}`)}catch(K){if(K instanceof c)$.fail(K.message);else $.fail("Failed to fetch dataset");return}let J,Q=!1;try{J=await L5(D)}catch(K){if(K instanceof c&&K.statusCode===404);else Q=!0,console.log(E.yellow(` Warning: Could not fetch DOI info: ${I0(K)}`))}if(J?.concept_doi)console.log(` DOI: ${E.cyan(J.concept_doi)}`);let X={version:"1.0"};console.log(),console.log(E.cyan("--- Author ORCIDs ---"));let{updateAuthors:Y}=await xD.prompt([{type:"confirm",name:"updateAuthors",message:"Update author ORCIDs?",default:!1}]);if(Y){let K={},V=!0;while(V){let{authorName:A}=await xD.prompt([{type:"input",name:"authorName",message:'Author name (as in BIDS, e.g., "Shirazi, Yahya"):'}]);if(!A)break;let{orcid:Z}=await xD.prompt([{type:"input",name:"orcid",message:`ORCID for "${A}" (Enter to skip):`,validate:(N)=>{if(!N)return!0;return R$.test(N)||"Invalid ORCID format (XXXX-XXXX-XXXX-XXXX)"}}]),U={};if(Z)U.orcid=Z;let{affiliation:L}=await xD.prompt([{type:"input",name:"affiliation",message:`Affiliation for "${A}" (optional):`}]);if(L)U.affiliation=L;if(U.orcid||U.affiliation)K[A]=U;let{more:M}=await xD.prompt([{type:"confirm",name:"more",message:"Add another author?",default:!0}]);V=M}if(Object.keys(K).length>0)X.authors=K}if(F.llm!==!1){console.log(),console.log(E.cyan("--- Generating enrichment from README ---"));let K=process.env.OPENROUTER_API_KEY;if(!K)console.log(E.yellow(" OPENROUTER_API_KEY not set; skipping LLM enrichment")),console.log(E.gray(" Set it in your environment to enable LLM-based enrichment"));else{let V=R("Analyzing README and dataset metadata...").start();try{let{enrichFromReadme:A}=await Promise.resolve().then(() => (Vy(),zy)),Z=B.github_repo;if(!Z)V.warn("No GitHub repository configured for this dataset");else{let U=await Ay(Z,"README");if(!U)V.warn("Could not fetch README from repository");else{let L=await Ay(Z,"dataset_description.json"),M={};if(L)try{M=JSON.parse(L)}catch{console.log(E.yellow(" Warning: Could not parse dataset_description.json; LLM will use README only"))}let N=await A(U,M,K);if(V.succeed("LLM enrichment complete"),N.description)console.log(` Description: ${N.description.slice(0,100)}...`),X.description=N.description;if(N.methodsDescription)X.methodsDescription=N.methodsDescription;if(N.keywords&&N.keywords.length>0)console.log(` Keywords: ${N.keywords.join(", ")}`),X.keywords=N.keywords;if(N.fundingReferences&&N.fundingReferences.length>0)console.log(` Funding: ${N.fundingReferences.map((O)=>`${O.funderName} ${O.awardNumber||""}`).join(", ")}`),X.fundingReferences=N.fundingReferences;if(N.relatedDois&&N.relatedDois.length>0)console.log(` Related DOIs: ${N.relatedDois.map((O)=>`${O.doi} (${O.relationType})`).join(", ")}`),X.relatedDois=N.relatedDois}}}catch(A){V.fail("LLM enrichment failed"),console.log(E.gray(` ${I0(A)}`))}}}console.log(),console.log(E.cyan("--- Dataset stats ---"));let G=R("Computing dataset sizes and formats...").start();try{let K=await av(D),V=PF(K.total_size);X.sizes=[`${V} (${K.file_count} files)`],X.formats=K.extensions,G.succeed(`Sizes: ${V} (${K.file_count} files), Formats: ${K.extensions.join(", ")}`)}catch(K){G.warn("Could not compute dataset stats"),console.log(E.gray(` ${I0(K)}`))}console.log(),console.log(E.cyan("--- Review ---")),console.log(JSON.stringify(X,null,2)),console.log();let H=await gD("Commit to repo and refresh DOI?",F,!0);if(H!=="confirmed"){console.log(E.gray(H==="declined"?"Skipped":"Cancelled"));return}let W=R("Saving enrichment...").start();try{let K=await iv(D,X);if(W.succeed(K.message),K.bidsignore_updated)console.log(E.gray(" .bidsignore updated to include nemar_metadata.json"));if(!J&&Q)try{J=await L5(D)}catch(V){if(process.env.DEBUG)console.error("[debug] DOI info re-fetch:",V)}if(J?.ezid_identifier){let V=R("Refreshing DOI metadata...").start();try{await I2(D,{refresh_metadata:!0}),V.succeed("DOI metadata refreshed")}catch(A){V.warn("Could not refresh DOI metadata"),console.log(E.gray(` ${I0(A)}`))}}else if(Q)console.log(E.yellow(" DOI refresh skipped: could not verify DOI exists. Run 'nemar admin doi update --refresh' manually."))}catch(K){if(K instanceof c)W.fail(K.message);else W.fail("Failed to save enrichment"),console.log(E.gray(` ${I0(K)}`))}});_0.addCommand(T5);var f$=new B0("publish").description("Publication workflow management");f$.command("list").description("List publication requests").option("-s, --status <status>","Filter by status (requested, approving, published, denied)").addHelpText("after",`
|
|
180
180
|
Description:
|
|
181
181
|
List all publication requests from users, with optional filtering by status.
|
|
182
182
|
Shows dataset ID, status, requesting user, and current progress.
|
|
@@ -645,7 +645,7 @@ Examples:
|
|
|
645
645
|
$ nemar sandbox # Run sandbox training
|
|
646
646
|
$ nemar sandbox status # Check if training is completed
|
|
647
647
|
$ nemar sandbox reset # Reset for re-training
|
|
648
|
-
`).action(nGD);async function nGD(){if(console.log(),console.log(E.bold("NEMAR Sandbox Training")),console.log(E.gray("Verify your setup and learn the upload workflow")),console.log(),!PD()){console.log(E.red("Not authenticated")),console.log(E.gray("Run 'nemar auth login' first"));return}let D=F0();if(D.sandboxCompleted){console.log(E.green("Sandbox training already completed!")),console.log(E.gray(`Dataset ID: ${D.sandboxDatasetId}`)),console.log(),console.log("You can upload real datasets with:"),console.log(E.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(E.gray("To re-run training, use: nemar sandbox reset"));return}console.log(E.bold("Step 1/6: Checking prerequisites..."));let F=R("Checking git-annex and SSH...").start(),$=await I$();if(!$.allPassed){F.fail("Prerequisites check failed"),console.log(),console.log(E.red("Missing requirements:"));for(let P of $.errors)console.log(E.yellow(` - ${P}`));if(!$.githubSSH.accessible)console.log(E.gray(" Run 'nemar auth setup-ssh' to configure SSH"));return}F.succeed("All prerequisites met");let B=R("Verifying GitHub CLI authentication...").start(),J=await k$(D.githubUsername);if(!J.authenticated){B.fail("GitHub CLI not authenticated"),console.log(E.red(` ${J.error}`)),console.log(),console.log("GitHub CLI is required for sandbox training. Install and authenticate:"),console.log(E.cyan(" brew install gh # or visit https://cli.github.com/")),console.log(E.cyan(" gh auth login"));return}if(D.githubUsername&&!J.matches)B.warn("GitHub CLI user mismatch"),console.log(E.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(E.cyan(` gh auth login # Login as ${D.githubUsername}`)),console.log(),console.log(E.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(E.bold("Step 2/6: Generating test dataset..."));let Q=R("Creating minimal BIDS structure...").start(),X;try{let P=gy();X=P.root;let QD=hy(P);Q.succeed(`Test dataset created (${PF(QD)})`),console.log(E.gray(` Location: ${X}`))}catch(P){Q.fail("Failed to generate test dataset"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`));return}console.log(),console.log(E.bold("Step 3/6: Registering sandbox dataset..."));let Y=R("Creating dataset on NEMAR...").start(),G,H,W,K,V,A;try{let P=await j$({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=P.dataset.dataset_id,H=P.dataset.ssh_url,W=P.dataset.github_url,K=P.s3_config,V=P.dataset.s3_prefix,A=P.upload_urls||{},Y.succeed(`Sandbox dataset created: ${E.cyan(G)}`),console.log(E.gray(` GitHub: ${W}`)),await new Promise((QD)=>setTimeout(QD,1e4))}catch(P){if(Y.fail("Failed to create sandbox dataset"),P instanceof c)console.log(E.red(` ${P.message}`));else console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`));N1(X);return}let Z=R("Accepting GitHub repository invitation...").start(),U=W?.match(/github\.com\/([a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+)/),L=U?U[1].replace(/\.git$/,""):null;if(!L){Z.fail("Invalid GitHub repository URL from backend"),console.log(E.red(` Received: ${W||"(empty)"}`)),console.log(E.red(" Expected format: https://github.com/owner/repo")),console.log(),console.log("This may indicate a backend issue. Please contact support."),N1(X);return}let M=await v$(L);if(M.accepted)if(M.alreadyCollaborator)Z.succeed("Already a collaborator on this repository");else Z.succeed("GitHub invitation accepted");else Z.warn("Could not auto-accept invitation"),console.log(E.yellow(` ${M.error}`)),console.log(),console.log("You may need to accept the invitation manually:"),console.log(E.cyan(` https://github.com/${L}/invitations`)),console.log();console.log(),console.log(E.bold("Step 4/6: Initializing repository..."));let N=R("Setting up git-annex...").start(),O=D.username&&D.email?{name:D.username,email:D.email}:void 0;try{await P$(X,{author:O}),await S$(X),await y$(X,H),N.succeed("Repository initialized")}catch(P){N.fail("Failed to initialize repository"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`)),N1(X);return}if(console.log(),console.log(E.bold("Step 5/6: Uploading to S3...")),Object.keys(A).length===0)console.log(E.yellow(" No data files to upload (metadata only)"));else{let P=R("Uploading test data...").start();try{let fD=0,$0=Object.keys(A).length,v=await x$(X,A,{jobs:4,onProgress:(qD)=>{if(qD.status==="completed"||qD.status==="failed")fD++,P.text=`Uploading... ${fD}/${$0} files`}});if(v.failed.length>0){P.fail(`Upload failed for ${v.failed.length} file(s)`);for(let qD of v.failed)console.log(E.red(` Failed: ${qD}`));if(v.error)console.log(E.red(` Error: ${v.error}`));console.log(),console.log(E.yellow("Sandbox training aborted due to upload failures.")),console.log(E.gray("Please check your network connection and try again.")),N1(X);return}P.succeed(`Uploaded ${v.uploaded} file(s)`)}catch(fD){P.fail("Upload failed"),console.log(E.red(` ${fD instanceof Error?fD.message:"Unknown error"}`)),N1(X);return}let QD=R("Registering file URLs...").start();try{let fD={};for(let v of Object.keys(A))fD[v]=`${K.public_url}/${V}/objects/${v}`;let $0=await _$(X,fD);if(!$0.success){QD.fail(`URL registration failed for ${$0.failed.length} file(s)`);for(let v of $0.failed)console.log(E.red(` Failed: ${v}`));console.log(),console.log(E.yellow("Sandbox training aborted due to URL registration failures.")),console.log(E.gray("This may indicate a git-annex configuration issue.")),N1(X);return}QD.succeed(`Registered ${$0.registered} file URLs`)}catch(fD){QD.fail("Failed to register URLs"),console.log(E.red(` ${fD instanceof Error?fD.message:"Unknown error"}`)),N1(X);return}}console.log(),console.log(E.bold("Step 6/6: Pushing to GitHub..."));let b=R("Saving and pushing...").start();try{await M5(X,"Initial sandbox training upload",O),await N5(X),b.succeed("Pushed to GitHub")}catch(P){b.fail("Failed to push to GitHub"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`)),N1(X);return}let w=R("Finalizing...").start();try{await O$(G),await hv(G),V0("sandboxCompleted",!0),V0("sandboxDatasetId",G),w.succeed("Sandbox training complete!")}catch(P){w.fail("Failed to finalize"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`)),N1(X);return}N1(X),console.log(),console.log(E.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(E.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(E.gray(`Sandbox dataset: ${G}`))}p$.command("status").description("Check sandbox training completion status").option("--refresh","Fetch latest status from server").action(async(D)=>{if(!PD()){console.log(E.red("Not authenticated")),console.log(E.gray("Run 'nemar auth login' first"));return}if(D.refresh){let F=R("Checking status...").start();try{let $=await uv();if(V0("sandboxCompleted",$.sandbox_completed),$.sandbox_dataset_id)V0("sandboxDatasetId",$.sandbox_dataset_id);if(F.stop(),$.sandbox_completed){if(console.log(E.green("Sandbox training: Completed")),console.log(E.gray(` Dataset ID: ${$.sandbox_dataset_id}`)),$.sandbox_completed_at)console.log(E.gray(` Completed: ${$.sandbox_completed_at}`))}else console.log(E.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(E.cyan(" nemar sandbox"))}catch($){if(F.fail("Failed to check status"),$ instanceof c)console.log(E.red(` ${$.message}`))}}else{let F=F0();if(F.sandboxCompleted)console.log(E.green("Sandbox training: Completed")),console.log(E.gray(` Dataset ID: ${F.sandboxDatasetId}`));else console.log(E.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(E.cyan(" nemar sandbox"))}});p$.command("reset").description("Reset sandbox training status for re-training").option(vD,yD).option(hD,bD).action(async(D)=>{if(!PD()){console.log(E.red("Not authenticated")),console.log(E.gray("Run 'nemar auth login' first"));return}if(!F0().sandboxCompleted){console.log(E.yellow("Sandbox training not yet completed")),console.log(E.gray("Nothing to reset"));return}let $=await gD("Reset sandbox training status? You will need to complete training again.",D);if($!=="confirmed"){console.log(E.gray($==="declined"?"Skipped":"Cancelled"));return}let B=R("Resetting sandbox status...").start();try{await bv(),w2("sandboxCompleted"),w2("sandboxDatasetId"),B.succeed("Sandbox status reset"),console.log(),console.log("Run sandbox training again with:"),console.log(E.cyan(" nemar sandbox"))}catch(J){if(B.fail("Failed to reset"),J instanceof c)console.log(E.red(` ${J.message}`));else console.log(E.red(` ${J instanceof Error?J.message:"Unknown error"}`))}});var by={name:"nemar-cli",version:"0.4.0-dev.195",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 uy=by.version;var C1=new B0;C1.name("nemar").description(`CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource)
|
|
648
|
+
`).action(nGD);async function nGD(){if(console.log(),console.log(E.bold("NEMAR Sandbox Training")),console.log(E.gray("Verify your setup and learn the upload workflow")),console.log(),!PD()){console.log(E.red("Not authenticated")),console.log(E.gray("Run 'nemar auth login' first"));return}let D=F0();if(D.sandboxCompleted){console.log(E.green("Sandbox training already completed!")),console.log(E.gray(`Dataset ID: ${D.sandboxDatasetId}`)),console.log(),console.log("You can upload real datasets with:"),console.log(E.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(E.gray("To re-run training, use: nemar sandbox reset"));return}console.log(E.bold("Step 1/6: Checking prerequisites..."));let F=R("Checking git-annex and SSH...").start(),$=await I$();if(!$.allPassed){F.fail("Prerequisites check failed"),console.log(),console.log(E.red("Missing requirements:"));for(let P of $.errors)console.log(E.yellow(` - ${P}`));if(!$.githubSSH.accessible)console.log(E.gray(" Run 'nemar auth setup-ssh' to configure SSH"));return}F.succeed("All prerequisites met");let B=R("Verifying GitHub CLI authentication...").start(),J=await k$(D.githubUsername);if(!J.authenticated){B.fail("GitHub CLI not authenticated"),console.log(E.red(` ${J.error}`)),console.log(),console.log("GitHub CLI is required for sandbox training. Install and authenticate:"),console.log(E.cyan(" brew install gh # or visit https://cli.github.com/")),console.log(E.cyan(" gh auth login"));return}if(D.githubUsername&&!J.matches)B.warn("GitHub CLI user mismatch"),console.log(E.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(E.cyan(` gh auth login # Login as ${D.githubUsername}`)),console.log(),console.log(E.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(E.bold("Step 2/6: Generating test dataset..."));let Q=R("Creating minimal BIDS structure...").start(),X;try{let P=gy();X=P.root;let QD=hy(P);Q.succeed(`Test dataset created (${PF(QD)})`),console.log(E.gray(` Location: ${X}`))}catch(P){Q.fail("Failed to generate test dataset"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`));return}console.log(),console.log(E.bold("Step 3/6: Registering sandbox dataset..."));let Y=R("Creating dataset on NEMAR...").start(),G,H,W,K,V,A;try{let P=await j$({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=P.dataset.dataset_id,H=P.dataset.ssh_url,W=P.dataset.github_url,K=P.s3_config,V=P.dataset.s3_prefix,A=P.upload_urls||{},Y.succeed(`Sandbox dataset created: ${E.cyan(G)}`),console.log(E.gray(` GitHub: ${W}`)),await new Promise((QD)=>setTimeout(QD,1e4))}catch(P){if(Y.fail("Failed to create sandbox dataset"),P instanceof c)console.log(E.red(` ${P.message}`));else console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`));N1(X);return}let Z=R("Accepting GitHub repository invitation...").start(),U=W?.match(/github\.com\/([a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+)/),L=U?U[1].replace(/\.git$/,""):null;if(!L){Z.fail("Invalid GitHub repository URL from backend"),console.log(E.red(` Received: ${W||"(empty)"}`)),console.log(E.red(" Expected format: https://github.com/owner/repo")),console.log(),console.log("This may indicate a backend issue. Please contact support."),N1(X);return}let M=await v$(L);if(M.accepted)if(M.alreadyCollaborator)Z.succeed("Already a collaborator on this repository");else Z.succeed("GitHub invitation accepted");else Z.warn("Could not auto-accept invitation"),console.log(E.yellow(` ${M.error}`)),console.log(),console.log("You may need to accept the invitation manually:"),console.log(E.cyan(` https://github.com/${L}/invitations`)),console.log();console.log(),console.log(E.bold("Step 4/6: Initializing repository..."));let N=R("Setting up git-annex...").start(),O=D.username&&D.email?{name:D.username,email:D.email}:void 0;try{await P$(X,{author:O}),await S$(X),await y$(X,H),N.succeed("Repository initialized")}catch(P){N.fail("Failed to initialize repository"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`)),N1(X);return}if(console.log(),console.log(E.bold("Step 5/6: Uploading to S3...")),Object.keys(A).length===0)console.log(E.yellow(" No data files to upload (metadata only)"));else{let P=R("Uploading test data...").start();try{let fD=0,$0=Object.keys(A).length,v=await x$(X,A,{jobs:4,onProgress:(qD)=>{if(qD.status==="completed"||qD.status==="failed")fD++,P.text=`Uploading... ${fD}/${$0} files`}});if(v.failed.length>0){P.fail(`Upload failed for ${v.failed.length} file(s)`);for(let qD of v.failed)console.log(E.red(` Failed: ${qD}`));if(v.error)console.log(E.red(` Error: ${v.error}`));console.log(),console.log(E.yellow("Sandbox training aborted due to upload failures.")),console.log(E.gray("Please check your network connection and try again.")),N1(X);return}P.succeed(`Uploaded ${v.uploaded} file(s)`)}catch(fD){P.fail("Upload failed"),console.log(E.red(` ${fD instanceof Error?fD.message:"Unknown error"}`)),N1(X);return}let QD=R("Registering file URLs...").start();try{let fD={};for(let v of Object.keys(A))fD[v]=`${K.public_url}/${V}/objects/${v}`;let $0=await _$(X,fD);if(!$0.success){QD.fail(`URL registration failed for ${$0.failed.length} file(s)`);for(let v of $0.failed)console.log(E.red(` Failed: ${v}`));console.log(),console.log(E.yellow("Sandbox training aborted due to URL registration failures.")),console.log(E.gray("This may indicate a git-annex configuration issue.")),N1(X);return}QD.succeed(`Registered ${$0.registered} file URLs`)}catch(fD){QD.fail("Failed to register URLs"),console.log(E.red(` ${fD instanceof Error?fD.message:"Unknown error"}`)),N1(X);return}}console.log(),console.log(E.bold("Step 6/6: Pushing to GitHub..."));let b=R("Saving and pushing...").start();try{await M5(X,"Initial sandbox training upload",O),await N5(X),b.succeed("Pushed to GitHub")}catch(P){b.fail("Failed to push to GitHub"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`)),N1(X);return}let w=R("Finalizing...").start();try{await O$(G),await hv(G),V0("sandboxCompleted",!0),V0("sandboxDatasetId",G),w.succeed("Sandbox training complete!")}catch(P){w.fail("Failed to finalize"),console.log(E.red(` ${P instanceof Error?P.message:"Unknown error"}`)),N1(X);return}N1(X),console.log(),console.log(E.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(E.cyan(" nemar dataset upload ./your-dataset")),console.log(),console.log(E.gray(`Sandbox dataset: ${G}`))}p$.command("status").description("Check sandbox training completion status").option("--refresh","Fetch latest status from server").action(async(D)=>{if(!PD()){console.log(E.red("Not authenticated")),console.log(E.gray("Run 'nemar auth login' first"));return}if(D.refresh){let F=R("Checking status...").start();try{let $=await uv();if(V0("sandboxCompleted",$.sandbox_completed),$.sandbox_dataset_id)V0("sandboxDatasetId",$.sandbox_dataset_id);if(F.stop(),$.sandbox_completed){if(console.log(E.green("Sandbox training: Completed")),console.log(E.gray(` Dataset ID: ${$.sandbox_dataset_id}`)),$.sandbox_completed_at)console.log(E.gray(` Completed: ${$.sandbox_completed_at}`))}else console.log(E.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(E.cyan(" nemar sandbox"))}catch($){if(F.fail("Failed to check status"),$ instanceof c)console.log(E.red(` ${$.message}`))}}else{let F=F0();if(F.sandboxCompleted)console.log(E.green("Sandbox training: Completed")),console.log(E.gray(` Dataset ID: ${F.sandboxDatasetId}`));else console.log(E.yellow("Sandbox training: Not completed")),console.log(),console.log("Run sandbox training with:"),console.log(E.cyan(" nemar sandbox"))}});p$.command("reset").description("Reset sandbox training status for re-training").option(vD,yD).option(hD,bD).action(async(D)=>{if(!PD()){console.log(E.red("Not authenticated")),console.log(E.gray("Run 'nemar auth login' first"));return}if(!F0().sandboxCompleted){console.log(E.yellow("Sandbox training not yet completed")),console.log(E.gray("Nothing to reset"));return}let $=await gD("Reset sandbox training status? You will need to complete training again.",D);if($!=="confirmed"){console.log(E.gray($==="declined"?"Skipped":"Cancelled"));return}let B=R("Resetting sandbox status...").start();try{await bv(),w2("sandboxCompleted"),w2("sandboxDatasetId"),B.succeed("Sandbox status reset"),console.log(),console.log("Run sandbox training again with:"),console.log(E.cyan(" nemar sandbox"))}catch(J){if(B.fail("Failed to reset"),J instanceof c)console.log(E.red(` ${J.message}`));else console.log(E.red(` ${J instanceof Error?J.message:"Unknown error"}`))}});var by={name:"nemar-cli",version:"0.4.0-dev.196",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 uy=by.version;var C1=new B0;C1.name("nemar").description(`CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource)
|
|
649
649
|
|
|
650
650
|
NEMAR is a curated repository for neurophysiology data in BIDS format.
|
|
651
651
|
This CLI provides tools for uploading, downloading, and managing datasets.`).version(uy,"-v, --version","Output the current version").option("--no-color","Disable colored output").option("--verbose","Enable verbose output").addHelpText("after",`
|
package/package.json
CHANGED