nemar-cli 0.9.9 → 0.9.10-PR1151.4e75d55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ ${u.dim(`eta: ${e.eta}`)}`:"";process.stderr.write(`${t}
102
102
  ${r} ${e.message}
103
103
  ${n}${i}
104
104
  ${t}
105
- `)}var LV=!1;var T_=k(()=>{Ke()});var VV;var UV=k(()=>{VV={name:"nemar-cli",version:"0.9.9",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 && tsc --noEmit -p backend",prepublishOnly:"bun run build",prepare:"husky",postinstall:"bun scripts/postinstall-check.mjs",deploy:"wrangler deploy",preview:"wrangler dev"},keywords:["nemar","bids","neuroimaging","eeg","emg","datalad","cli"],author:"NEMAR Team",license:"CC-BY-NC-ND-4.0",repository:{type:"git",url:"git+https://github.com/nemarOrg/nemar-cli.git"},bugs:{url:"https://github.com/nemarOrg/nemar-cli/issues"},homepage:"https://docs.nemar.org",engines:{bun:">=1.0.0"},files:["dist","scripts/postinstall-check.mjs","README.md","LICENSE"],dependencies:{chalk:"^5.3.0",commander:"^12.1.0",conf:"^13.0.1","fuse.js":"^7.1.0",inquirer:"^9.2.15",ora:"^8.0.1",zod:"^3.23.8"},"lint-staged":{"src/**/*.{ts,tsx}":["biome check --fix"],"backend/src/**/*.{ts,tsx}":["biome check --fix"]},devDependencies:{"@biomejs/biome":"1.9.4","@types/bcryptjs":"^3.0.0","@types/bun":"latest","@types/inquirer":"^9.0.7",ajv:"^8.20.0","ajv-formats":"^3.0.1",bcryptjs:"^3.0.3",husky:"^9.1.7","lint-staged":"^16.3.2",typescript:"^5.5.4",wrangler:"^4.70.0",yaml:"^2.8.4"}}});var Ao;var bm=k(()=>{UV();Ao=VV.version});function U(e){if(e instanceof Error)return e.message;return String(e)}var M,ko;var gr=k(()=>{M=class M extends Error{statusCode;details;step;constructor(e,t,r,n){super(t);this.statusCode=e;this.details=r;this.step=n;this.name="ApiError"}};ko=class ko extends M{mode;eta;constructor(e,t,r,n){super(503,t,n);this.mode=e;this.eta=r;this.name="MaintenanceError"}}});function zV(){if(process.env.TEST_API_URL)return process.env.TEST_API_URL;if(q_)return N_;return ht().apiUrl||N_}async function I(e,t={},r=!1,n){let i=`${zV()}${e}`,s={"Content-Type":"application/json","X-CLI-Version":Ao,...t.headers};if(r){let c=ht();if(!c.apiKey&&r===!0)throw new M(401,"Not authenticated. Run 'nemar auth login' first.");if(c.apiKey)s.Authorization=`Bearer ${c.apiKey}`}let o;try{o=await fetch(i,{...t,headers:s})}catch(c){throw new M(0,`Network error: Could not connect to ${zV()}`,{originalError:c instanceof Error?c.message:String(c)})}let a;try{a=await o.json()}catch{throw new M(o.status,`Invalid response from server (status ${o.status})`)}if(!o.ok){if(o.status===503&&(a.mode==="read-only"||a.mode==="full")){let c=typeof a.message==="string"?a.message:"NEMAR is in maintenance mode. Please retry shortly.",l=typeof a.eta==="string"?a.eta:null,d=new ko(a.mode,c,l,a.details);throw xm(d),d}throw new M(o.status,a.error||a.message||"Request failed",a.details,typeof a.step==="string"?a.step:void 0)}if(n){let c=n.safeParse(a);if(!c.success)throw new M(o.status,`Response for ${e} did not match the expected NEMAR contract`,{issues:c.error.issues});return c.data}return a}var N_="https://api.nemar.org",q_;var Ps=k(()=>{ks();T_();bm();gr();q_=N_.includes("workers.dev")});async function HV(e,t){let r=new URLSearchParams;if(e)r.set("status",e);if(t)r.set("role",t);let n=r.toString()?`?${r.toString()}`:"";return I(`/admin/users${n}`,{},!0)}async function GV(e){return I(`/admin/approve/${e}`,{method:"POST"},!0)}async function WV(e){return I(`/admin/approve/by-id/${e}`,{method:"POST"},!0)}async function KV(e){return I(`/admin/revoke/${e}`,{method:"POST"},!0)}async function YV(e,t){return I(`/admin/users/${e}/role`,{method:"POST",body:JSON.stringify({role:t})},!0)}async function j_(e,t){return I(`/admin/datasets/${e}/visibility`,{method:"PATCH",body:JSON.stringify({visibility:t})},!0)}async function JV(e){return I(`/datasets/${e}/publish`,{method:"POST"},!0)}async function XV(e){return I(`/admin/datasets/${e}/ci`,{},!0)}async function Ri(e){return I(`/admin/datasets/${e}/ci`,{method:"POST"},!0)}async function M_(e){return I(`/admin/datasets/${e}/ci/validate`,{method:"POST"},!0)}async function B_(e){return I(`/admin/datasets/${e}/ci/sync`,{method:"POST"},!0)}async function QV(e,t){return I(`/admin/datasets/${e}/doi/concept`,{method:"POST",body:JSON.stringify(t)},!0)}async function dd(e){return I(`/admin/datasets/${e}/doi`,{},!0)}async function L_(e,t){return I(`/admin/datasets/${e}/doi/update`,{method:"POST",body:JSON.stringify(t)},!0)}async function ZV(e,t){return I(`/admin/datasets/${e}/withdraw`,{method:"POST",body:JSON.stringify({reason:t.reason,dry_run:t.dryRun})},!0)}async function ez(e,t){return I(`/admin/datasets/${e}/restore`,{method:"POST",body:JSON.stringify({dry_run:t.dryRun})},!0)}async function tz(e){return I(`/admin/datasets/${e}/reset`,{method:"POST"},!0)}async function rz(e,t=!1){return I(`/admin/datasets/${e}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:t})},!0)}async function nz(e){return I("/admin/datasets/bulk-delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dataset_ids:e})},!0)}async function iz(e){return I("/admin/datasets/import",{method:"POST",body:JSON.stringify(e)},!0)}async function sz(e){return I("/admin/datasets/exemplar",{method:"POST",body:JSON.stringify(e)},!0)}async function oz(e){return I(`/admin/datasets/${e}/exemplar/remint-dois`,{method:"POST"},!0)}async function U_(e,t){let r=new URLSearchParams;if(e)r.set("status",e);if(t!==void 0)r.set("blocklisted",t?"1":"0");let n=r.toString();return I(`/admin/imports${n?`?${n}`:""}`,{},!0)}async function az(e){return I(`/admin/imports/${e}/rollback`,{method:"POST"},!0)}async function cz(e){return I(`/admin/imports/${e}/retry`,{method:"POST"},!0)}async function V_(e){return I(`/admin/imports/${e}/verify`,{method:"POST"},!0)}async function uz(e){return I("/admin/imports/dispatch-cooldown",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dataset_ids:e})},!0)}async function Oc(e,t){return I(`/admin/datasets/${e}/reindex`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t??{})},!0)}async function lz(e,t){return I("/admin/datasets/reindex/bulk",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filter:e,...t??{}})},!0)}async function dz(e){let t=e?.limit??15;return I(`/admin/datasets/hed-sweep?limit=${encodeURIComponent(String(t))}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function fz(){return I("/admin/datasets/hed-sweep?reset=1",{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function pz(e){let t=e?.limit??15,r=new URLSearchParams({limit:String(t)});if(e?.olderThan!=null)r.set("older-than",String(e.olderThan));if(e?.before!=null)r.set("before",e.before);return I(`/admin/datasets/data-integrity-sweep?${r.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function mz(){return I("/admin/datasets/data-integrity-sweep?reset=1",{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function hz(e,t){let r=t?.write?"":"?dry_run=1";return I(`/admin/datasets/${e}/availability-report${r}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function gz(e){let t=e?.limit??30,r=new URLSearchParams({limit:String(t)});if(e?.missingOnly)r.set("missing-only","1");return I(`/admin/datasets/availability-report-sweep?${r.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function yz(){return I("/admin/datasets/availability-report-sweep?reset=1",{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function xz(e){let t=new URLSearchParams;if(e?.prefix)t.set("prefix",e.prefix);if(e?.visibility)t.set("visibility",e.visibility);if(e?.limit)t.set("limit",String(e.limit));let r=t.toString()?`?${t.toString()}`:"";return I(`/admin/fleet/drift${r}`,{},!0)}async function Ac(e,t){return I(`/admin/datasets/${e}/enforce`,{method:"POST",body:JSON.stringify({dry_run:t})},!0)}async function bz(e){return I("/admin/datasets/enforce/bulk",{method:"POST",body:JSON.stringify({prefix:e.prefix,visibility:e.visibility,limit:e.limit,dry_run:e.dryRun})},!0)}async function vz(e,t=!1){return I(`/admin/datasets/${e}/revalidate${t?"?force=true":""}`,{method:"POST"},!0)}async function _z(e){let t=e?`?user=${encodeURIComponent(e)}`:"";return I(`/admin/email-preferences${t}`,{},!0)}async function Dz(e,t){let r=t?`?user=${encodeURIComponent(t)}`:"";return I(`/admin/email-preferences${r}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)},!0)}async function z_(e){return I("/admin/notify",{method:"POST",body:JSON.stringify(e)},!0)}async function wz(){return I("/admin/summary/coverage",{},!0)}async function Ez(e,t,r){return I("/admin/manifest/dispatch",{method:"POST",body:JSON.stringify({dataset_id:e,version:t,skip_canary:r?.skipCanary??!1})},!0)}async function H_(e){return I("/admin/doctor/scan",{method:"POST",body:JSON.stringify({...e?.check&&{check:e.check},...e?.datasetId&&{dataset_id:e.datasetId}})},!0)}async function G_(e){return I("/admin/doctor/fix",{method:"POST",body:JSON.stringify({check:e.check,...e.datasetId&&{dataset_id:e.datasetId},...e.dryRun&&{dry_run:!0}})},!0)}var kc=k(()=>{Ps()});async function Zn(e,t){return I(`/datasets/${e}/upload-credentials`,{method:"POST",body:JSON.stringify({duration_seconds:t})},!0)}async function W_(e,t){return I(`/datasets/${e}/download-credentials`,{method:"POST",body:JSON.stringify({duration_seconds:t})},!0)}async function Sz(e){return I(`/admin/datasets/${e}/files`,{},!0)}async function $z(e){let t,r=0,n=[],i=!0;while(i){let s=await I(`/admin/datasets/${e}/s3-lock`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({continuation_token:t})},!0);if(r+=s.locked,s.failed?.length)n.push(...s.failed);if(i=s.hasMore,t=s.continuation_token,i&&!t)throw new M(500,"S3 lock paginated response missing continuation_token; aborting to avoid infinite loop")}return{locked:r,failed:n}}var Pc=k(()=>{Ps();gr()});async function _m(e){return I(`/datasets/${e}/ci/status`,{},!0)}async function Cz(e){return I(`/datasets/${e}/manifest`,{},!0)}async function Dm(e,t){return I(`/datasets/${e}/manifest/${t}`,{},!0)}function Fz(e){let t=e;if(!t.status)t.status="active";else if(!["active","archived","deleted"].includes(t.status))throw Error(`Invalid dataset status: ${t.status}`);if(!t.visibility)t.visibility="private";else if(!["public","private"].includes(t.visibility))throw Error(`Invalid dataset visibility: ${t.visibility}`);return t}async function Ic(e={}){let t=new URLSearchParams;if(e.mine)t.set("mine","true");if(e.search)t.set("search",e.search);if(e.modality)t.set("modality",e.modality);if(e.author)t.set("author",e.author);if(e.task)t.set("task",e.task);if(e.license)t.set("license",e.license);if(e.hasDoi)t.set("has_doi","true");if(e.hasHed)t.set("has_hed","1");if(e.dataComplete)t.set("data_complete","1");if(e.recent)t.set("recent",String(e.recent));if(e.sort)t.set("sort",e.sort);if(e.limit!=null)t.set("limit",String(e.limit));if(e.offset!=null)t.set("offset",String(e.offset));if(e.owner)t.set("owner",e.owner);let r=t.toString()?`?${t.toString()}`:"",n=await I(`/datasets${r}`,{},e.mine?!0:"optional");return n.datasets=n.datasets.map(Fz),n}async function Rz(e){return I(`/datasets/resolve/${e}`,{},"optional")}async function Oz(e,t={}){let r=new URLSearchParams({q:e});if(t.modality)r.set("modality",t.modality);if(t.limit)r.set("limit",String(t.limit));if(t.hasHed)r.set("has_hed","1");return I(`/datasets/search?${r.toString()}`,{},"optional")}async function gt(e){let t=await I(`/datasets/${e}`,{},"optional");return Fz(t.dataset)}async function Az(e){return I(`/datasets/${e}/versions`,{},!0)}async function wm(e){return I("/datasets",{method:"POST",body:JSON.stringify(e)},!0)}async function Em(e){return I(`/datasets/${e}/finalize`,{method:"POST"},!0)}async function K_(e){return I(`/datasets/${e}/request-access`,{method:"POST"},!0)}async function kz(e,t){let r=t?`?status=${t}`:"";return I(`/datasets/${e}/access-requests${r}`,{},!0)}async function Pz(e,t){return I(`/datasets/${e}/access-requests/${t}/approve`,{method:"POST"},!0)}async function Iz(e,t){return I(`/datasets/${e}/access-requests/${t}/deny`,{method:"POST"},!0)}async function Tz(e,t){return I(`/datasets/${e}/invite`,{method:"POST",body:JSON.stringify({username:t})},!0)}async function Nz(e){return I(`/datasets/${e}/collaborators`,{},!0)}async function qz(e,t){return I(`/admin/datasets/${e}/enrichment`,{method:"POST",body:JSON.stringify(t)},!0)}var vm;var Po=k(()=>{Ps();vm=/^\d{4}-\d{4}-\d{4}-\d{3}[\dX]$/});var Tc;var Uz=k(()=>{Tc=["ci_check","enrichment_check","s3_public_read","repo_public","tag_protect","doi_create","update_metadata","update_readme","create_tag","create_release","upload_to_zenodo","publish_doi","version_doi","s3_lock","sync_nemar","notify_user"]});async function Nc(e){return I(`/datasets/${e}/publish/request`,{method:"POST"},!0)}async function zz(e){return I(`/datasets/${e}/publish/status`,{},!0)}async function Hz(e){return I(`/datasets/${e}/publish/resend`,{method:"POST"},!0)}async function Gz(e){let t=e?`?status=${e}`:"";return I(`/admin/publish/requests${t}`,{},!0)}async function Wz(e,t){return I(`/admin/publish/${e}/deny`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reason:t})},!0)}function A3e(e,t=[]){if(e){let r=Tc.indexOf(e);if(r>=0)return r+1}return Math.min(t.length+1,Tc.length)}function k3e(e){if(!(e instanceof M))return!1;if(e.statusCode===0)return!0;if(e.statusCode===429)return!0;if(e.statusCode>=500&&e.statusCode<600)return!0;if(e.statusCode===403&&/repository has been locked/i.test(e.message))return!0;return!1}async function qc(e,t=!1,r=!1,n=!1,i,s){let c,l,d=0,f=!1,m,p=t,g=[],y;function x(v,_,E,S){if(!s)return;s({step:v,stepIndex:A3e(v,_),stepTotal:Tc.length,s3LockLocked:E,s3LockTotal:S,s3LockResumed:v==="s3_lock"&&f?!0:void 0})}for(let v=1;v<=5;v++)try{let _,E=!0;do{if(_=await I(`/admin/publish/${e}/approve`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resume:E?p:!0,sandbox:r,s3_lock_continuation_token:c,s3_lock_total:l,skip_ci_check:n})},!0),E=!1,_.step_results)g.push(..._.step_results);if(_.s3_lock_total!==void 0)l=_.s3_lock_total;if(_.s3_lock_batch_count!==void 0)d+=_.s3_lock_batch_count;let S=_.step??_.step_results?.[_.step_results.length-1]?.step;if(S&&(S!==m||S==="s3_lock"))x(S,_.steps_completed??[],S==="s3_lock"?d:void 0,S==="s3_lock"?l:void 0),m=S;if(_.hasMore&&_.s3_lock_continuation_token!==void 0)c=_.s3_lock_continuation_token;else break}while(_.hasMore);if(g.length>0)_.step_results=Vz(g);return _}catch(_){if(y=_,v===5||!k3e(_)){if(_ instanceof M&&g.length>0)_.stepResults=Vz(g);throw _}let S=_;if(i?.({attempt:v,maxAttempts:5,delayMs:1e4,step:S.step,error:S.message}),await new Promise((D)=>setTimeout(D,1e4)),p=!0,c!==void 0)f=!0}throw y}function Vz(e){let t=new Map;for(let r of e)t.set(r.step,r);return Array.from(t.values())}var fd=k(()=>{Uz();Ps();gr()});function Jz(e){X_=e}function Q_(){return X_}function pd(e){if(X_)process.stderr.write(`${e}
105
+ `)}var LV=!1;var T_=k(()=>{Ke()});var VV;var UV=k(()=>{VV={name:"nemar-cli",version:"0.9.10-PR1151.4e75d55",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 && tsc --noEmit -p backend",prepublishOnly:"bun run build",prepare:"husky",postinstall:"bun scripts/postinstall-check.mjs",deploy:"wrangler deploy",preview:"wrangler dev"},keywords:["nemar","bids","neuroimaging","eeg","emg","datalad","cli"],author:"NEMAR Team",license:"CC-BY-NC-ND-4.0",repository:{type:"git",url:"git+https://github.com/nemarOrg/nemar-cli.git"},bugs:{url:"https://github.com/nemarOrg/nemar-cli/issues"},homepage:"https://docs.nemar.org",engines:{bun:">=1.0.0"},files:["dist","scripts/postinstall-check.mjs","README.md","LICENSE"],dependencies:{chalk:"^5.3.0",commander:"^12.1.0",conf:"^13.0.1","fuse.js":"^7.1.0",inquirer:"^9.2.15",ora:"^8.0.1",zod:"^3.23.8"},"lint-staged":{"src/**/*.{ts,tsx}":["biome check --fix"],"backend/src/**/*.{ts,tsx}":["biome check --fix"]},devDependencies:{"@biomejs/biome":"1.9.4","@types/bcryptjs":"^3.0.0","@types/bun":"latest","@types/inquirer":"^9.0.7",ajv:"^8.20.0","ajv-formats":"^3.0.1",bcryptjs:"^3.0.3",husky:"^9.1.7","lint-staged":"^16.3.2",typescript:"^5.5.4",wrangler:"^4.70.0",yaml:"^2.8.4"}}});var Ao;var bm=k(()=>{UV();Ao=VV.version});function U(e){if(e instanceof Error)return e.message;return String(e)}var M,ko;var gr=k(()=>{M=class M extends Error{statusCode;details;step;constructor(e,t,r,n){super(t);this.statusCode=e;this.details=r;this.step=n;this.name="ApiError"}};ko=class ko extends M{mode;eta;constructor(e,t,r,n){super(503,t,n);this.mode=e;this.eta=r;this.name="MaintenanceError"}}});function zV(){if(process.env.TEST_API_URL)return process.env.TEST_API_URL;if(q_)return N_;return ht().apiUrl||N_}async function I(e,t={},r=!1,n){let i=`${zV()}${e}`,s={"Content-Type":"application/json","X-CLI-Version":Ao,...t.headers};if(r){let c=ht();if(!c.apiKey&&r===!0)throw new M(401,"Not authenticated. Run 'nemar auth login' first.");if(c.apiKey)s.Authorization=`Bearer ${c.apiKey}`}let o;try{o=await fetch(i,{...t,headers:s})}catch(c){throw new M(0,`Network error: Could not connect to ${zV()}`,{originalError:c instanceof Error?c.message:String(c)})}let a;try{a=await o.json()}catch{throw new M(o.status,`Invalid response from server (status ${o.status})`)}if(!o.ok){if(o.status===503&&(a.mode==="read-only"||a.mode==="full")){let c=typeof a.message==="string"?a.message:"NEMAR is in maintenance mode. Please retry shortly.",l=typeof a.eta==="string"?a.eta:null,d=new ko(a.mode,c,l,a.details);throw xm(d),d}throw new M(o.status,a.error||a.message||"Request failed",a.details,typeof a.step==="string"?a.step:void 0)}if(n){let c=n.safeParse(a);if(!c.success)throw new M(o.status,`Response for ${e} did not match the expected NEMAR contract`,{issues:c.error.issues});return c.data}return a}var N_="https://api.nemar.org",q_;var Ps=k(()=>{ks();T_();bm();gr();q_=N_.includes("workers.dev")});async function HV(e,t){let r=new URLSearchParams;if(e)r.set("status",e);if(t)r.set("role",t);let n=r.toString()?`?${r.toString()}`:"";return I(`/admin/users${n}`,{},!0)}async function GV(e){return I(`/admin/approve/${e}`,{method:"POST"},!0)}async function WV(e){return I(`/admin/approve/by-id/${e}`,{method:"POST"},!0)}async function KV(e){return I(`/admin/revoke/${e}`,{method:"POST"},!0)}async function YV(e,t){return I(`/admin/users/${e}/role`,{method:"POST",body:JSON.stringify({role:t})},!0)}async function j_(e,t){return I(`/admin/datasets/${e}/visibility`,{method:"PATCH",body:JSON.stringify({visibility:t})},!0)}async function JV(e){return I(`/datasets/${e}/publish`,{method:"POST"},!0)}async function XV(e){return I(`/admin/datasets/${e}/ci`,{},!0)}async function Ri(e){return I(`/admin/datasets/${e}/ci`,{method:"POST"},!0)}async function M_(e){return I(`/admin/datasets/${e}/ci/validate`,{method:"POST"},!0)}async function B_(e){return I(`/admin/datasets/${e}/ci/sync`,{method:"POST"},!0)}async function QV(e,t){return I(`/admin/datasets/${e}/doi/concept`,{method:"POST",body:JSON.stringify(t)},!0)}async function dd(e){return I(`/admin/datasets/${e}/doi`,{},!0)}async function L_(e,t){return I(`/admin/datasets/${e}/doi/update`,{method:"POST",body:JSON.stringify(t)},!0)}async function ZV(e,t){return I(`/admin/datasets/${e}/withdraw`,{method:"POST",body:JSON.stringify({reason:t.reason,dry_run:t.dryRun})},!0)}async function ez(e,t){return I(`/admin/datasets/${e}/restore`,{method:"POST",body:JSON.stringify({dry_run:t.dryRun})},!0)}async function tz(e){return I(`/admin/datasets/${e}/reset`,{method:"POST"},!0)}async function rz(e,t=!1){return I(`/admin/datasets/${e}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({force:t})},!0)}async function nz(e){return I("/admin/datasets/bulk-delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dataset_ids:e})},!0)}async function iz(e){return I("/admin/datasets/import",{method:"POST",body:JSON.stringify(e)},!0)}async function sz(e){return I("/admin/datasets/exemplar",{method:"POST",body:JSON.stringify(e)},!0)}async function oz(e){return I(`/admin/datasets/${e}/exemplar/remint-dois`,{method:"POST"},!0)}async function U_(e,t){let r=new URLSearchParams;if(e)r.set("status",e);if(t!==void 0)r.set("blocklisted",t?"1":"0");let n=r.toString();return I(`/admin/imports${n?`?${n}`:""}`,{},!0)}async function az(e){return I(`/admin/imports/${e}/rollback`,{method:"POST"},!0)}async function cz(e){return I(`/admin/imports/${e}/retry`,{method:"POST"},!0)}async function V_(e){return I(`/admin/imports/${e}/verify`,{method:"POST"},!0)}async function uz(e){return I("/admin/imports/dispatch-cooldown",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dataset_ids:e})},!0)}async function Oc(e,t){return I(`/admin/datasets/${e}/reindex`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t??{})},!0)}async function lz(e,t){return I("/admin/datasets/reindex/bulk",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filter:e,...t??{}})},!0)}async function dz(e){let t=e?.limit??15;return I(`/admin/datasets/hed-sweep?limit=${encodeURIComponent(String(t))}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function fz(){return I("/admin/datasets/hed-sweep?reset=1",{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function pz(e){let t=e?.limit??15,r=new URLSearchParams({limit:String(t)});if(e?.olderThan!=null)r.set("older-than",String(e.olderThan));if(e?.before!=null)r.set("before",e.before);return I(`/admin/datasets/data-integrity-sweep?${r.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function mz(){return I("/admin/datasets/data-integrity-sweep?reset=1",{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function hz(e,t){let r=t?.write?"":"?dry_run=1";return I(`/admin/datasets/${e}/availability-report${r}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function gz(e){let t=e?.limit??30,r=new URLSearchParams({limit:String(t)});if(e?.missingOnly)r.set("missing-only","1");return I(`/admin/datasets/availability-report-sweep?${r.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function yz(){return I("/admin/datasets/availability-report-sweep?reset=1",{method:"POST",headers:{"Content-Type":"application/json"}},!0)}async function xz(e){let t=new URLSearchParams;if(e?.prefix)t.set("prefix",e.prefix);if(e?.visibility)t.set("visibility",e.visibility);if(e?.limit)t.set("limit",String(e.limit));let r=t.toString()?`?${t.toString()}`:"";return I(`/admin/fleet/drift${r}`,{},!0)}async function Ac(e,t){return I(`/admin/datasets/${e}/enforce`,{method:"POST",body:JSON.stringify({dry_run:t})},!0)}async function bz(e){return I("/admin/datasets/enforce/bulk",{method:"POST",body:JSON.stringify({prefix:e.prefix,visibility:e.visibility,limit:e.limit,dry_run:e.dryRun})},!0)}async function vz(e,t=!1){return I(`/admin/datasets/${e}/revalidate${t?"?force=true":""}`,{method:"POST"},!0)}async function _z(e){let t=e?`?user=${encodeURIComponent(e)}`:"";return I(`/admin/email-preferences${t}`,{},!0)}async function Dz(e,t){let r=t?`?user=${encodeURIComponent(t)}`:"";return I(`/admin/email-preferences${r}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)},!0)}async function z_(e){return I("/admin/notify",{method:"POST",body:JSON.stringify(e)},!0)}async function wz(){return I("/admin/summary/coverage",{},!0)}async function Ez(e,t,r){return I("/admin/manifest/dispatch",{method:"POST",body:JSON.stringify({dataset_id:e,version:t,skip_canary:r?.skipCanary??!1})},!0)}async function H_(e){return I("/admin/doctor/scan",{method:"POST",body:JSON.stringify({...e?.check&&{check:e.check},...e?.datasetId&&{dataset_id:e.datasetId}})},!0)}async function G_(e){return I("/admin/doctor/fix",{method:"POST",body:JSON.stringify({check:e.check,...e.datasetId&&{dataset_id:e.datasetId},...e.dryRun&&{dry_run:!0}})},!0)}var kc=k(()=>{Ps()});async function Zn(e,t){return I(`/datasets/${e}/upload-credentials`,{method:"POST",body:JSON.stringify({duration_seconds:t})},!0)}async function W_(e,t){return I(`/datasets/${e}/download-credentials`,{method:"POST",body:JSON.stringify({duration_seconds:t})},!0)}async function Sz(e){return I(`/admin/datasets/${e}/files`,{},!0)}async function $z(e){let t,r=0,n=[],i=!0;while(i){let s=await I(`/admin/datasets/${e}/s3-lock`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({continuation_token:t})},!0);if(r+=s.locked,s.failed?.length)n.push(...s.failed);if(i=s.hasMore,t=s.continuation_token,i&&!t)throw new M(500,"S3 lock paginated response missing continuation_token; aborting to avoid infinite loop")}return{locked:r,failed:n}}var Pc=k(()=>{Ps();gr()});async function _m(e){return I(`/datasets/${e}/ci/status`,{},!0)}async function Cz(e){return I(`/datasets/${e}/manifest`,{},!0)}async function Dm(e,t){return I(`/datasets/${e}/manifest/${t}`,{},!0)}function Fz(e){let t=e;if(!t.status)t.status="active";else if(!["active","archived","deleted"].includes(t.status))throw Error(`Invalid dataset status: ${t.status}`);if(!t.visibility)t.visibility="private";else if(!["public","private"].includes(t.visibility))throw Error(`Invalid dataset visibility: ${t.visibility}`);return t}async function Ic(e={}){let t=new URLSearchParams;if(e.mine)t.set("mine","true");if(e.search)t.set("search",e.search);if(e.modality)t.set("modality",e.modality);if(e.author)t.set("author",e.author);if(e.task)t.set("task",e.task);if(e.license)t.set("license",e.license);if(e.hasDoi)t.set("has_doi","true");if(e.hasHed)t.set("has_hed","1");if(e.dataComplete)t.set("data_complete","1");if(e.recent)t.set("recent",String(e.recent));if(e.sort)t.set("sort",e.sort);if(e.limit!=null)t.set("limit",String(e.limit));if(e.offset!=null)t.set("offset",String(e.offset));if(e.owner)t.set("owner",e.owner);let r=t.toString()?`?${t.toString()}`:"",n=await I(`/datasets${r}`,{},e.mine?!0:"optional");return n.datasets=n.datasets.map(Fz),n}async function Rz(e){return I(`/datasets/resolve/${e}`,{},"optional")}async function Oz(e,t={}){let r=new URLSearchParams({q:e});if(t.modality)r.set("modality",t.modality);if(t.limit)r.set("limit",String(t.limit));if(t.hasHed)r.set("has_hed","1");return I(`/datasets/search?${r.toString()}`,{},"optional")}async function gt(e){let t=await I(`/datasets/${e}`,{},"optional");return Fz(t.dataset)}async function Az(e){return I(`/datasets/${e}/versions`,{},!0)}async function wm(e){return I("/datasets",{method:"POST",body:JSON.stringify(e)},!0)}async function Em(e){return I(`/datasets/${e}/finalize`,{method:"POST"},!0)}async function K_(e){return I(`/datasets/${e}/request-access`,{method:"POST"},!0)}async function kz(e,t){let r=t?`?status=${t}`:"";return I(`/datasets/${e}/access-requests${r}`,{},!0)}async function Pz(e,t){return I(`/datasets/${e}/access-requests/${t}/approve`,{method:"POST"},!0)}async function Iz(e,t){return I(`/datasets/${e}/access-requests/${t}/deny`,{method:"POST"},!0)}async function Tz(e,t){return I(`/datasets/${e}/invite`,{method:"POST",body:JSON.stringify({username:t})},!0)}async function Nz(e){return I(`/datasets/${e}/collaborators`,{},!0)}async function qz(e,t){return I(`/admin/datasets/${e}/enrichment`,{method:"POST",body:JSON.stringify(t)},!0)}var vm;var Po=k(()=>{Ps();vm=/^\d{4}-\d{4}-\d{4}-\d{3}[\dX]$/});var Tc;var Uz=k(()=>{Tc=["ci_check","enrichment_check","s3_public_read","repo_public","tag_protect","doi_create","update_metadata","update_readme","create_tag","create_release","upload_to_zenodo","publish_doi","version_doi","s3_lock","sync_nemar","notify_user"]});async function Nc(e){return I(`/datasets/${e}/publish/request`,{method:"POST"},!0)}async function zz(e){return I(`/datasets/${e}/publish/status`,{},!0)}async function Hz(e){return I(`/datasets/${e}/publish/resend`,{method:"POST"},!0)}async function Gz(e){let t=e?`?status=${e}`:"";return I(`/admin/publish/requests${t}`,{},!0)}async function Wz(e,t){return I(`/admin/publish/${e}/deny`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reason:t})},!0)}function A3e(e,t=[]){if(e){let r=Tc.indexOf(e);if(r>=0)return r+1}return Math.min(t.length+1,Tc.length)}function k3e(e){if(!(e instanceof M))return!1;if(e.statusCode===0)return!0;if(e.statusCode===429)return!0;if(e.statusCode>=500&&e.statusCode<600)return!0;if(e.statusCode===403&&/repository has been locked/i.test(e.message))return!0;return!1}async function qc(e,t=!1,r=!1,n=!1,i,s){let c,l,d=0,f=!1,m,p=t,g=[],y;function x(v,_,E,S){if(!s)return;s({step:v,stepIndex:A3e(v,_),stepTotal:Tc.length,s3LockLocked:E,s3LockTotal:S,s3LockResumed:v==="s3_lock"&&f?!0:void 0})}for(let v=1;v<=5;v++)try{let _,E=!0;do{if(_=await I(`/admin/publish/${e}/approve`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resume:E?p:!0,sandbox:r,s3_lock_continuation_token:c,s3_lock_total:l,skip_ci_check:n})},!0),E=!1,_.step_results)g.push(..._.step_results);if(_.s3_lock_total!==void 0)l=_.s3_lock_total;if(_.s3_lock_batch_count!==void 0)d+=_.s3_lock_batch_count;let S=_.step??_.step_results?.[_.step_results.length-1]?.step;if(S&&(S!==m||S==="s3_lock"))x(S,_.steps_completed??[],S==="s3_lock"?d:void 0,S==="s3_lock"?l:void 0),m=S;if(_.hasMore&&_.s3_lock_continuation_token!==void 0)c=_.s3_lock_continuation_token;else break}while(_.hasMore);if(g.length>0)_.step_results=Vz(g);return _}catch(_){if(y=_,v===5||!k3e(_)){if(_ instanceof M&&g.length>0)_.stepResults=Vz(g);throw _}let S=_;if(i?.({attempt:v,maxAttempts:5,delayMs:1e4,step:S.step,error:S.message}),await new Promise((D)=>setTimeout(D,1e4)),p=!0,c!==void 0)f=!0}throw y}function Vz(e){let t=new Map;for(let r of e)t.set(r.step,r);return Array.from(t.values())}var fd=k(()=>{Uz();Ps();gr()});function Jz(e){X_=e}function Q_(){return X_}function pd(e){if(X_)process.stderr.write(`${e}
106
106
  `)}var X_=!1;var Xz={};Ti(Xz,{runCommand:()=>F});var{spawn:P3e}=globalThis.Bun;async function F(e,t={}){let r={...process.env,GIT_TERMINAL_PROMPT:"0",...t.env};for(let l of t.unsetEnv??[])delete r[l];let n=P3e({cmd:e,cwd:t.cwd,stdout:"pipe",stderr:"pipe",env:r}),i=!1,s;if(t.timeout)s=setTimeout(()=>{i=!0,n.kill()},t.timeout);if(Q_()){let l=t.cwd?` (cwd=${t.cwd})`:"";pd(u.dim(`$ ${e.join(" ")}${l}`))}let o=await new Response(n.stdout).text(),a=await new Response(n.stderr).text(),c=await n.exited;if(s)clearTimeout(s);if(Q_()){if(o.trim())pd(u.dim(o.trimEnd()));if(a.trim())pd(u.yellow(a.trimEnd()));pd(u.dim(`(exit ${c})`))}if(i)return{stdout:o,stderr:a||`Command timed out after ${Math.round(t.timeout/1000)}s`,exitCode:c??1};return{stdout:o,stderr:a,exitCode:c}}var Bt=k(()=>{Ke()});async function I3e(){try{let{exitCode:e,stderr:t}=await F(["ssh","-T","-o","BatchMode=yes","-o","ConnectTimeout=5","git@github.com"]),r=t.includes("successfully authenticated");if(!r)console.warn("SSH test to github.com failed:",{exitCode:e,stderr:t.trim().slice(0,500)});return{works:r,error:r?void 0:t.trim().slice(0,500)}}catch(e){let t=e instanceof Error?e.message:String(e);return console.warn("SSH test exception:",t),{works:!1,error:t}}}async function md(){try{let{stdout:e,exitCode:t,stderr:r}=await F(["gh","auth","token"]);if(t!==0)return console.warn("gh CLI returned non-zero exit code:",t),console.warn("stderr:",r),{token:null,error:`gh auth token failed: ${r.trim()||"unknown error"}`};if(!e.trim())return console.warn("gh auth token returned empty output"),{token:null,error:"gh CLI returned empty token"};return{token:e.trim()}}catch(e){let t=e instanceof Error?e.message:String(e);if(console.error("Failed to get GitHub token from gh CLI:",t),t.includes("ENOENT")||t.includes("not found"))return{token:null,error:"gh CLI not installed (command not found)"};return{token:null,error:`gh CLI error: ${t}`}}}async function Sm(e){try{let{stdout:t,exitCode:r,stderr:n}=await F(["gh","api","user","--jq",".login"]);if(r!==0){if(n.includes("not logged in")||n.includes("auth login"))return{authenticated:!1,error:"gh CLI not authenticated. Run 'gh auth login' to authenticate."};return{authenticated:!1,error:`gh CLI error: ${n.trim()||"unknown error"}`}}let i=t.trim();if(!i)return{authenticated:!1,error:"gh CLI returned empty username"};if(e){let s=i.toLowerCase()===e.toLowerCase();return{authenticated:!0,username:i,matches:s,error:s?void 0:`gh CLI authenticated as '${i}', expected '${e}'`}}return{authenticated:!0,username:i}}catch(t){let r=t instanceof Error?t.message:String(t);if(r.includes("ENOENT")||r.includes("not found"))return{authenticated:!1,error:"gh CLI not installed. Install from https://cli.github.com/"};return{authenticated:!1,error:`Failed to verify gh CLI: ${r}`}}}async function $m(e){if(!/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/.test(e))return{accepted:!1,error:`Invalid repository format: ${e}`};let{stdout:t,exitCode:r,stderr:n}=await F(["gh","api","/user/repository_invitations"]);if(r!==0){if(n.includes("not logged in")||n.includes("auth login"))return{accepted:!1,error:"gh CLI not authenticated. Run 'gh auth login' to authenticate."};if(n.includes("API rate limit")||n.includes("403"))return{accepted:!1,error:"GitHub API rate limit exceeded. Please try again in a few minutes."};if(n.includes("ENOENT")||n.includes("not found"))return{accepted:!1,error:"gh CLI not installed. Install from https://cli.github.com/"};return{accepted:!1,error:`Failed to list invitations: ${n.trim()||"unknown error"}`}}let i=null;try{i=JSON.parse(t||"[]").find((l)=>l.repository.full_name===e)?.id??null}catch(a){let c=a instanceof Error?a.message:String(a);return console.error("Failed to parse GitHub invitations response:",c),console.error(" Raw response (first 500 chars):",(t||"").slice(0,500)),{accepted:!1,error:`Failed to parse GitHub API response: ${c}`}}if(!i){let{exitCode:a}=await F(["gh","api",`/repos/${e}`,"--silent"]);if(a===0)return{accepted:!0,alreadyCollaborator:!0};return{accepted:!1,error:`No pending invitation found for ${e}. You may need to accept it manually via GitHub.`}}let{exitCode:s,stderr:o}=await F(["gh","api","--method","PATCH",`/user/repository_invitations/${i}`]);if(s!==0)return{accepted:!1,error:`Failed to accept invitation: ${o.trim()||"unknown error"}`};return{accepted:!0}}async function ei(e,t,r="origin"){let n=t;if(process.env.GH_TOKEN&&t.startsWith("git@github.com:")){let i=process.env.GH_TOKEN.trim();if(!i||/\s/.test(i))return{success:!1,error:"GH_TOKEN environment variable is set but appears malformed (empty or contains whitespace)"};n=`https://github.com/${t.replace("git@github.com:","")}`,await F(["git","config","credential.https://github.com.helper",`!printf 'username=x-access-token\\npassword=${i}'`],{cwd:e})}else if(t.startsWith("git@github.com:")){let i=t.replace("git@github.com:",""),s=await md();if(s.token)n=`https://github.com/${i}`,await F(["git","config","credential.https://github.com.helper",`!printf 'username=x-access-token\\npassword=${s.token}'`],{cwd:e});else{let o=await I3e();if(o.works)n=t;else return{success:!1,error:`GitHub authentication not configured.
107
107
 
108
108
  gh CLI failed: ${s.error||"could not get token"}
@@ -456,7 +456,7 @@ Exemplar Fleet (${n.length})
456
456
  ${i} finding(s). Preview the remediation with: nemar admin doctor fix <check> --dry-run`))}catch(n){r.fail("Doctor scan failed"),console.error(u.red(U(n))),process.exit(1)}});FD.command("fix").description("Apply a check's remediation (writes; use --dry-run first)").argument("<check>","Check name (see: nemar admin doctor scan)").argument("[dataset-id]","Narrow to one dataset").option("--dry-run","List what would be fixed without writing").option("--json","Output raw JSON instead of the human summary").action(async(e,t,r)=>{if(!oe())return;if(r.dryRun){let c=w(`Listing ${e} findings (dry run)...`).start();try{let l=await G_({check:e,datasetId:t,dryRun:!0});if(c.stop(),r.json){console.log(JSON.stringify(l,null,2));return}console.log(`Would fix ${l.would_fix} finding(s) for ${u.bold(e)}:`);for(let d of l.findings)console.log(` ${d.dataset_id}${d.version?`@v${d.version}`:""}`)}catch(l){c.fail("Dry run failed"),console.error(u.red(U(l))),process.exit(1)}return}let n=w(`Scanning for ${e} findings...`).start(),i;try{i=(await H_({check:e,datasetId:t})).results[e]?.findings??[]}catch(c){n.fail("Doctor scan failed"),console.error(u.red(U(c))),process.exit(1);return}if(i.length===0){if(n.succeed(`${e}: nothing to fix`),r.json)console.log(JSON.stringify({check:e,total:0,results:[]},null,2));return}n.stop(),console.log(`${u.bold(e)}: ${i.length} finding(s) to fix`);let s=[...new Set(i.map((c)=>c.dataset_id))];n.start();let{totals:o,results:a}=await lTe(s,(c,l)=>{let d=i.filter((f)=>f.dataset_id===c&&f.version).map((f)=>`v${f.version}`).join(", ");return n.text=`Fixing ${c}${d?` (${d})`:""} [${l+1}/${s.length}]...`,G_({check:e,datasetId:c})},{onDataset:(c,l)=>{if(n.stop(),l.length===0)console.log(` resolved ${c}: healed between the scan and its fix turn`);for(let d of l){let f=`${d.dataset_id}${d.version?`@v${d.version}`:""}`;if(d.status==="fixed")console.log(` ${u.green("fixed")} ${f}`);else if(d.status==="skipped")console.log(` skipped ${f}: ${d.message??"already healthy"}`);else console.log(` ${u.red("FAILED")} ${f}: ${d.message??"unknown error"}`)}n.start()}});if(n.stop(),r.json)console.log(JSON.stringify({check:e,total:i.length,...o,results:a},null,2));else{let c=o.resolved>0?`, ${o.resolved} already resolved`:"";console.log(`
457
457
  ${u.bold(e)}: ${u.green(`${o.fixed} fixed`)}, ${o.skipped} skipped, ${o.failed>0?u.red(`${o.failed} failed`):"0 failed"}${c}`)}if(o.failed>0)process.exit(1)});async function lTe(e,t,r){let n={fixed:0,skipped:0,failed:0,resolved:0},i=[];for(let[s,o]of e.entries()){let a;try{let c=await t(o,s);if(a=c.results,a.length===0)n.resolved++;else n.fixed+=c.fixed,n.skipped+=c.skipped,n.failed+=c.failed}catch(c){n.failed++,a=[{dataset_id:o,status:"failed",message:U(c)}]}i.push(...a),r?.onDataset?.(o,a)}return{totals:n,results:i}}Ie.addCommand(FD);var RD=new Ee("email-preferences").description("Manage email notification preferences");RD.command("show").description("Show email notification preferences").option("--user <username>","(owner only) show another user's preferences").action(async(e)=>{if(!Ue())console.error(u.red("Not authenticated. Run: nemar auth login")),process.exit(1);let t=w("Fetching email preferences...").start();try{let r=await _z(e.user),n=r.username?`${r.username}'s`:"Your";t.succeed(`${n} email notification preferences:`),console.log();let i=[{key:"user_approval",label:"User approval notifications"},{key:"publication_request",label:"Publication request notifications"},{key:"announcements",label:"Announcement emails"}];for(let s of i){let a=r[s.key]?u.green("enabled"):u.dim("disabled");console.log(` ${s.label.padEnd(40)} ${a}`)}console.log(),console.log(u.dim(" Use 'nemar admin email-preferences update' to change settings."))}catch(r){t.fail("Failed to fetch preferences"),console.error(u.red(U(r)))}});RD.command("update").description("Update email notification preferences").option("--user-approval <bool>","Enable/disable user approval notifications").option("--publication-request <bool>","Enable/disable publication request notifications").option("--announcements <bool>","Enable/disable announcement emails").option("--all <bool>","Enable/disable all notifications").option("--user <username>","(owner only) update another user's preferences").action(async(e)=>{if(!Ue())console.error(u.red("Not authenticated. Run: nemar auth login")),process.exit(1);function t(i){if(i===void 0)return;let s=i.toLowerCase();if(s==="true"||s==="1"||s==="on"||s==="yes")return!0;if(s==="false"||s==="0"||s==="off"||s==="no")return!1;console.error(u.red(`Invalid boolean value: "${i}". Use true/false, on/off, yes/no.`)),process.exit(1)}let r={};if(e.all!==void 0){let i=t(e.all);r.user_approval=i,r.publication_request=i,r.announcements=i}else{let i=t(e.userApproval),s=t(e.publicationRequest),o=t(e.announcements);if(i===void 0&&s===void 0&&o===void 0)console.error(u.red("No preferences specified.")),console.log(" --user-approval <bool> User approval notifications"),console.log(" --publication-request <bool> Publication request notifications"),console.log(" --announcements <bool> Announcement emails"),console.log(" --all <bool> All notifications"),process.exit(1);if(i!==void 0)r.user_approval=i;if(s!==void 0)r.publication_request=s;if(o!==void 0)r.announcements=o}let n=w("Updating email preferences...").start();try{let i=await Dz(r,e.user),s=i.username?`${i.username}'s`:"Your";n.succeed(`${s} email preferences updated:`),console.log(),console.log(` User approval: ${i.user_approval?u.green("enabled"):u.dim("disabled")}`),console.log(` Publication request: ${i.publication_request?u.green("enabled"):u.dim("disabled")}`),console.log(` Announcements: ${i.announcements?u.green("enabled"):u.dim("disabled")}`)}catch(i){n.fail("Failed to update preferences"),console.error(u.red(U(i)))}});Ie.addCommand(RD);var Gm=new Ee("notice").description("Manage system notices displayed to CLI users");Gm.command("list").description("List all notices (including expired)").action(async()=>{if(!Ue())console.error(u.red("Not authenticated. Run: nemar auth login")),process.exit(1);let e=w("Fetching notices...").start();try{let{notices:t}=await Mz();if(t.length===0){e.succeed("No notices found.");return}e.succeed(`${t.length} notice(s):`),console.log();for(let r of t){let i={critical:u.red.bold,warning:u.yellow,maintenance:u.magenta,announcement:u.green,tip:u.blue,info:u.blue}[r.level]||u.white,s=r.expires_at&&new Date(r.expires_at)<new Date?u.dim(" (expired)"):"";if(console.log(` ${u.dim(`#${r.id}`)} ${i(`[${r.level.toUpperCase()}]`)} ${u.dim(`scope:${r.scope}`)}${s}`),console.log(` ${r.message}`),console.log(` ${u.dim(`Created: ${r.created_at}`)}`),r.expires_at)console.log(` ${u.dim(`Expires: ${r.expires_at}`)}`);console.log()}}catch(t){Ze(t,e,"Failed to fetch notices")}});Gm.command("set").description("Create a new system notice").requiredOption("-m, --message <text>","Notice message text").option("-l, --level <level>","Notice level: tip, announcement, maintenance, warning, critical","tip").option("-s, --scope <scope>","Target scope: all, admins, members","all").option("-e, --expires <datetime>","Expiry datetime (ISO 8601)").action(async(e)=>{if(!Ue())console.error(u.red("Not authenticated. Run: nemar auth login")),process.exit(1);if(![...Y_,"info"].includes(e.level))console.error(u.red(`Invalid level: ${e.level}. Use ${Y_.join(", ")}.`)),process.exit(1);if(!["all","admins","members"].includes(e.scope))console.error(u.red(`Invalid scope: ${e.scope}. Use all, admins, or members.`)),process.exit(1);let t=w("Creating notice...").start();try{let r=await Bz({message:e.message,level:e.level,scope:e.scope,expires_at:e.expires});if(t.succeed(`Notice created (ID: ${r.id})`),console.log(` Level: ${r.level}`),console.log(` Scope: ${r.scope}`),console.log(` Message: ${r.message}`),r.expires_at)console.log(` Expires: ${r.expires_at}`)}catch(r){Ze(r,t,"Failed to create notice")}});Gm.command("clear <id>").description("Delete a notice by ID").option(Re,Oe).option(qe,Te).action(async(e,t)=>{if(!Ue())console.error(u.red("Not authenticated. Run: nemar auth login")),process.exit(1);let r=Number.parseInt(e,10);if(Number.isNaN(r))console.error(u.red("Invalid notice ID")),process.exit(1);if(!await Fe(`Delete notice #${r}?`,t,!1))return;let i=w("Deleting notice...").start();try{await Lz(r),i.succeed(`Notice #${r} deleted`)}catch(s){Ze(s,i,"Failed to delete notice")}});Ie.addCommand(Gm);Ie.command("notify").description("Send an email to a group or a single user").option("--to <group>","Recipient group: all, admins, members").option("--user <username>","Send to a single user by username").requiredOption("--subject <text>","Email subject line").option("--body <text>","Email body (markdown)").option("--body-file <path>","Read email body from file (markdown)").option("--dry-run","Preview recipients without sending").option(Re,Oe).option(qe,Te).action(async(e)=>{if(!Ue())console.error(u.red("Not authenticated. Run: nemar auth login")),process.exit(1);if(e.to&&e.user)console.error(u.red("--to and --user are mutually exclusive. Provide exactly one.")),process.exit(1);if(!e.to&&!e.user)console.error(u.red("Provide either --to <group> or --user <username>.")),process.exit(1);if(e.to&&!["all","admins","members"].includes(e.to))console.error(u.red(`Invalid group: ${e.to}. Use all, admins, or members.`)),process.exit(1);let t;if(e.bodyFile){if(!OG(e.bodyFile))console.error(u.red(`File not found: ${e.bodyFile}`)),process.exit(1);t=eTe(e.bodyFile,"utf-8")}else if(e.body)t=e.body;else console.error(u.red("Email body required. Use --body or --body-file.")),process.exit(1);let r=e.user?`user:${e.user}`:e.to,n=e.user?{user:e.user,subject:e.subject,body:t}:{to:e.to,subject:e.subject,body:t};if(e.dryRun){let a=w("Checking recipients...").start();try{let c=await z_({...n,dry_run:!0});if("dry_run"in c){a.succeed(`Dry run: ${c.recipient_count} recipient(s) for "${c.recipient_group}"`),console.log();for(let l of c.recipients)console.log(` ${l}`)}}catch(c){Ze(c,a,"Failed to check recipients")}return}console.log(u.bold("Email preview:")),console.log(` To: ${u.cyan(r)}`),console.log(` Subject: ${e.subject}`),console.log(` Body: ${t.length>100?`${t.substring(0,100)}...`:t}`),console.log();let i=e.user?`Send this email to ${e.user}?`:"Send this broadcast email?";if(!await Fe(i,e,!1))return;let o=w(e.user?`Sending to ${e.user}...`:"Sending broadcast...").start();try{let a=await z_(n);if("broadcast_id"in a)if(a.failure_count>0){o.warn(`Email send: ${a.recipient_count} delivered, ${a.failure_count} failed`);for(let c of a.failed_recipients)console.log(u.red(` Failed: ${c}`))}else{let c=e.user?`Email sent to ${e.user}`:`Broadcast sent to ${a.recipient_count} recipient(s)`;o.succeed(`${c} (ID: ${a.broadcast_id})`)}}catch(a){Ze(a,o,"Failed to send email")}});var dTe=1500;function fTe(e){switch(e.kind){case"ok":return u.green(`ok ${e.schema_version}`);case"stale":return u.yellow(`stale ${e.schema_version}`);case"missing":return u.red("missing");case"error":return u.red(`error ${e.status||"?"}: ${e.message}`)}}function pTe(e){return e.kind==="stale"||e.kind==="missing"}function mTe(e){let r=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(`^${r}$`)}var LG=new Ee("summary").description("summary.json coverage across published dataset versions");LG.command("check").description("Report which (dataset_id, version) pairs have stale or missing summary.json").option("--fix","Dispatch generate-manifest for every stale/missing version").option("--id <id>","Limit to a single dataset_id (exact match)").option("--match <glob>","Limit to dataset_ids matching a glob pattern: `*` matches any run of chars, `?` matches one char. Examples: `on*`, `nm00010?`, `*99999`. Can be combined with --id (id wins if both passed).").option("--only-stale","Print only rows that are not ok (suppresses ok rows)").option("--json","Emit the full report as JSON instead of a table").option(Re,Oe).option(qe,Te).action(async(e)=>{if(!oe())return;let t=w("Building coverage report...").start(),r;try{r=await wz()}catch(m){Ze(m,t,"Failed to fetch coverage report");return}t.succeed(`Coverage: target=schema ${r.target_schema}, versions=${r.totals.versions}`);let n=r.versions,i=null;if(e.id){if(n=n.filter((m)=>m.dataset_id===e.id),i=`dataset_id=${e.id}`,n.length===0){console.log(u.yellow(`No rows for ${i}`));return}}else if(e.match){let m=mTe(e.match);if(n=n.filter((p)=>m.test(p.dataset_id)),i=`--match ${e.match}`,n.length===0){console.log(u.yellow(`No rows match ${i}`));return}console.log(u.dim(`Scoped to ${n.length} version(s) matching ${e.match}`))}if(e.json){console.log(JSON.stringify(i?{...r,versions:n,totals:RG(n)}:r,null,2));return}let s=e.onlyStale?n.filter((m)=>m.state.kind!=="ok"):n;if(s.length===0)console.log(u.green("All versions at target schema \u2014 no drift."));else{let m=Math.max(...s.map((g)=>g.dataset_id.length),10),p=Math.max(...s.map((g)=>g.version.length),7);for(let g of s)console.log(` ${g.dataset_id.padEnd(m)} ${g.version.padEnd(p)} ${fTe(g.state)}`)}let o=i?RG(n):r.totals;if(console.log(),console.log(` Total: ${o.versions} ${u.green(`ok=${o.ok}`)} ${u.yellow(`stale=${o.stale}`)} ${u.red(`missing=${o.missing}`)} ${u.red(`error=${o.error}`)}`),!e.fix){if(o.stale+o.missing>0)console.log(u.dim(`
458
458
  Run with --fix to dispatch generate-manifest for the ${o.stale+o.missing} drifted version(s).`));return}let a=n.filter((m)=>pTe(m.state));if(a.length===0){console.log(u.green(`
459
- Nothing to dispatch.`));return}let c=i?` (scoped to ${i})`:"",l=await Fe(`Dispatch generate-manifest for ${a.length} version(s)${c}? Each dispatch queues a runner job on nemarDatasets/.github.`,e);if(l!=="confirmed"){console.log(u.dim(l==="declined"?"Skipped":"Cancelled"));return}let d=0,f=0;console.log();for(let[m,p]of a.entries()){let g=`${p.dataset_id}@${p.version}`,y=w(`[${m+1}/${a.length}] dispatching ${g}...`).start();try{await Ez(p.dataset_id,p.version),y.succeed(`[${m+1}/${a.length}] dispatched ${g}`),d++}catch(x){y.fail(`[${m+1}/${a.length}] ${g}: ${U(x)}`),f++}if(m<a.length-1)await new Promise((x)=>setTimeout(x,dTe))}if(console.log(),console.log(f===0?u.green(`All ${d} dispatches succeeded.`):u.yellow(`${d} succeeded, ${f} failed.`)),console.log(u.dim("Workflow runs will appear on https://github.com/nemarDatasets/.github/actions. Re-run `nemar admin summary check` once they complete to verify drift cleared.")),f>0)process.exitCode=1});function RG(e){return{versions:e.length,ok:e.filter((t)=>t.state.kind==="ok").length,stale:e.filter((t)=>t.state.kind==="stale").length,missing:e.filter((t)=>t.state.kind==="missing").length,error:e.filter((t)=>t.state.kind==="error").length}}Ie.addCommand(LG);Ke();Bn();rn();ud();var hTe=/^v?\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\d*)?$/,gTe=/^v\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\d*)?$/;function yTe(e){return e.startsWith("v")?e:`v${e}`}var UG=O.string().regex(hTe,"must be a semver version, optionally v-prefixed").transform(yTe),mQe=O.string().regex(gTe,"must be the canonical v-prefixed tag (vX.Y.Z)");ud();var xTe=O.object({id:O.number().int(),username:O.string().nullable(),email:O.string(),github_username:O.string().nullable(),role:O.string(),orcid:O.string().nullable().optional(),created_at:O.string().optional(),approved_at:O.string().nullable().optional(),dataset_count:O.number().int().optional(),sandbox_completed:O.boolean().optional(),sandbox_completed_at:O.string().nullable().optional(),sandbox_dataset_id:O.string().nullable().optional()}).passthrough(),bTe=O.object({prefix:O.string(),created_at:O.string(),last_used_at:O.string().nullable()}).passthrough().nullable(),VG=O.object({user:xTe,token:bTe.optional()}).passthrough();ud();var vTe="0.3.0",_Te=O.enum(["openneuro","nemar","gin","other"]),Cd=O.union([O.literal(0),O.literal(1)]).nullable(),zG=O.object({dataset_id:O.string(),id:O.string().optional(),name:O.string(),description:O.string().nullable().optional(),status:O.string(),visibility:O.string(),concept_doi:O.string().nullable().optional(),doi:O.string().nullable().optional(),created_at:O.string(),updated_at:O.string().optional(),owner_username:O.string().nullable().optional(),source:O.string().nullable().optional(),modalities:O.string().optional(),participants:O.number().int().nonnegative(),tasks:O.string().optional(),authors:O.string().optional(),license:O.string().optional(),file_size:O.number().nonnegative(),file_size_formatted:O.string().optional(),total_files:O.number().nonnegative().nullable().optional(),num_citations:O.number().int().nonnegative().optional(),n_channels:O.number().int().nullable().optional(),electrode_system:O.string().nullable().optional(),has_hed:Cd.optional(),hed_version:O.string().nullable().optional(),data_complete:Cd.optional(),bytes_present:O.number().nonnegative().nullable().optional(),latest_version:UG.nullable().optional()}).passthrough(),DTe=zG.extend({file_size:O.number().nonnegative().nullable(),modalities:O.string().nullable().optional(),tasks:O.string().nullable().optional(),authors:O.string().nullable().optional(),license:O.string().nullable().optional(),owner_github:O.string().nullable().optional(),attestation_deposit_type:O.enum(["owner","redistribution"]).nullable().optional(),attestation_key_status:O.enum(["destroyed","retained"]).nullable().optional(),attestation_deidentified:Cd.optional(),attestation_no_duplicate:Cd.optional(),attestation_upstream_source:O.string().nullable().optional(),attestation_accepted_at:O.string().nullable().optional()}).passthrough(),wTe=O.object({id:O.string(),name:O.string(),modalities:O.string().nullable().optional(),participants:O.number().int().nullable().optional(),doi:O.string().nullable().optional(),tasks:O.string().nullable().optional(),authors:O.string().nullable().optional(),has_hed:Cd.optional(),score:O.number().optional(),snippet:O.string().optional()}).passthrough(),vQe=O.object({datasets:O.array(zG),count:O.number().int().nonnegative(),total_count:O.number().int().nonnegative().optional(),limit:O.number().int().optional(),offset:O.number().int().optional()}).passthrough(),_Qe=O.object({results:O.array(wTe),count:O.number().int().nonnegative(),method:O.string().optional(),min_score:O.number().optional()}).passthrough(),DQe=O.object({dataset:DTe}).passthrough(),wQe=O.object({schema_version:O.literal(vTe),doc_type:O.literal("dataset"),dataset_id:O.string().regex(/^[a-z]{2}\d+$/,"neuroschema dataset_id pattern"),name:O.string(),source:_Te,recording_modality:O.array(O.string()).min(1),description:O.string().nullable().optional(),bids_version:O.string().nullable().optional(),license:O.string().nullable().optional()}).passthrough();Ps();async function HG(e){return I(`/auth/check-username?username=${encodeURIComponent(e)}`)}async function GG(e){return I(`/auth/check-github?username=${encodeURIComponent(e)}`)}async function WG(e){return I("/auth/signup",{method:"POST",body:JSON.stringify(e)})}async function OD(e){return I("/auth/login",{method:"POST",body:JSON.stringify({api_key:e})})}async function KG(e){return I("/auth/resend-verification",{method:"POST",body:JSON.stringify({email:e})})}async function YG(e,t){return I("/auth/retrieve-key",{method:"POST",body:JSON.stringify({email:e,password:t})})}async function JG(e){return I("/auth/request-key-regeneration",{method:"POST",body:JSON.stringify({email:e})})}async function Wm(){return(await I("/users/me",{},!0,VG)).user}async function XG(e){return I("/sandbox/complete",{method:"POST",body:JSON.stringify({dataset_id:e})},!0)}async function QG(){return I("/sandbox/reset",{method:"POST"},!0)}async function ZG(){return I("/sandbox/status",{},!0)}gr();ks();Bt();var eW={git:{name:"git",purpose:"version control for dataset metadata",cmd:["git","--version"],required:!0,installInstructions:{macos:"brew install git (or install Xcode Command Line Tools)",linux:"sudo apt-get install git OR sudo dnf install git",windows:"winget install Git.Git (or https://git-scm.com/download/win)"}},"git-annex":{name:"git-annex",purpose:"large-file data transfer (upload/download)",cmd:["git-annex","version"],required:!0,installInstructions:{macos:"brew install git-annex",linux:"sudo apt-get install git-annex OR sudo dnf install git-annex",windows:"Download the installer from https://git-annex.branchable.com/install/Windows/"}},gh:{name:"GitHub CLI (gh)",purpose:"GitHub authentication + repository operations",cmd:["gh","--version"],required:!0,installInstructions:{macos:"brew install gh",linux:"See https://cli.github.com/manual/installation",windows:"winget install GitHub.cli (or: scoop install gh)"}},aws:{name:"AWS CLI",purpose:"S3 data upload/download",cmd:["aws","--version"],required:!0,installInstructions:{macos:"brew install awscli",linux:"pip install awscli OR sudo snap install aws-cli --classic",windows:"winget install Amazon.AWSCLI (or the MSI from https://aws.amazon.com/cli/)"}},deno:{name:"Deno",purpose:"BIDS validation",cmd:["deno","--version"],required:!0,installInstructions:{macos:"brew install deno (or: curl -fsSL https://deno.land/install.sh | sh)",linux:"curl -fsSL https://deno.land/install.sh | sh",windows:"winget install DenoLand.Deno (or: irm https://deno.land/install.ps1 | iex)"}}},ETe={upload:["git-annex","gh","aws","deno"],download:["gh"],clone:["git","gh"],push:["git-annex","gh"],publish:["gh","aws"],update:["git","gh"],release:["git","gh"]};function STe(){if(process.platform==="darwin")return"macos";if(process.platform==="win32")return"windows";return"linux"}function tW(e,t=STe()){return e.installInstructions[t]}function $Te(e){let t=e.match(/(\d+\.\d+(?:\.\d+)?)/);return t?t[1]:void 0}async function rW(e){try{let{exitCode:t,stdout:r}=await F(e.cmd);if(t!==0)return{available:!1};return{available:!0,version:$Te(r)}}catch(t){let r=t instanceof Error?t.message:String(t);if(!r.includes("ENOENT")&&!r.includes("not found"))console.error(` Warning: ${e.name} check failed unexpectedly: ${r}`);return{available:!1}}}async function AD(){let e=Object.entries(eW);return Promise.all(e.map(async([t,r])=>{let{available:n,version:i}=await rW(r);return{key:t,name:r.name,purpose:r.purpose,required:r.required,available:n,version:i,installInstruction:tW(r)}}))}async function nW(){let t=(await AD()).filter((r)=>r.required&&!r.available);if(t.length===0)return[];console.warn(`
459
+ Nothing to dispatch.`));return}let c=i?` (scoped to ${i})`:"",l=await Fe(`Dispatch generate-manifest for ${a.length} version(s)${c}? Each dispatch queues a runner job on nemarDatasets/.github.`,e);if(l!=="confirmed"){console.log(u.dim(l==="declined"?"Skipped":"Cancelled"));return}let d=0,f=0;console.log();for(let[m,p]of a.entries()){let g=`${p.dataset_id}@${p.version}`,y=w(`[${m+1}/${a.length}] dispatching ${g}...`).start();try{await Ez(p.dataset_id,p.version),y.succeed(`[${m+1}/${a.length}] dispatched ${g}`),d++}catch(x){y.fail(`[${m+1}/${a.length}] ${g}: ${U(x)}`),f++}if(m<a.length-1)await new Promise((x)=>setTimeout(x,dTe))}if(console.log(),console.log(f===0?u.green(`All ${d} dispatches succeeded.`):u.yellow(`${d} succeeded, ${f} failed.`)),console.log(u.dim("Workflow runs will appear on https://github.com/nemarDatasets/.github/actions. Re-run `nemar admin summary check` once they complete to verify drift cleared.")),f>0)process.exitCode=1});function RG(e){return{versions:e.length,ok:e.filter((t)=>t.state.kind==="ok").length,stale:e.filter((t)=>t.state.kind==="stale").length,missing:e.filter((t)=>t.state.kind==="missing").length,error:e.filter((t)=>t.state.kind==="error").length}}Ie.addCommand(LG);Ke();Bn();rn();ud();var hTe=/^v?\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\d*)?$/,gTe=/^v\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\d*)?$/;function yTe(e){return e.startsWith("v")?e:`v${e}`}var UG=O.string().regex(hTe,"must be a semver version, optionally v-prefixed").transform(yTe),mQe=O.string().regex(gTe,"must be the canonical v-prefixed tag (vX.Y.Z)");ud();var xTe=O.object({id:O.number().int(),username:O.string().nullable(),email:O.string(),github_username:O.string().nullable(),role:O.string(),orcid:O.string().nullable().optional(),created_at:O.string().optional(),approved_at:O.string().nullable().optional(),dataset_count:O.number().int().optional(),sandbox_completed:O.boolean().optional(),sandbox_completed_at:O.string().nullable().optional(),sandbox_dataset_id:O.string().nullable().optional()}).passthrough(),bTe=O.object({prefix:O.string(),created_at:O.string(),last_used_at:O.string().nullable()}).passthrough().nullable(),VG=O.object({user:xTe,token:bTe.optional()}).passthrough();ud();var vTe="0.3.0",_Te=O.enum(["openneuro","nemar","gin","other"]),Cd=O.union([O.literal(0),O.literal(1)]).nullable(),zG=O.object({dataset_id:O.string(),id:O.string().optional(),name:O.string(),description:O.string().nullable().optional(),status:O.string(),visibility:O.string(),concept_doi:O.string().nullable().optional(),doi:O.string().nullable().optional(),created_at:O.string(),updated_at:O.string().optional(),owner_username:O.string().nullable().optional(),source:O.string().nullable().optional(),modalities:O.string().optional(),participants:O.number().int().nonnegative(),tasks:O.string().optional(),authors:O.string().optional(),license:O.string().optional(),file_size:O.number().nonnegative(),file_size_formatted:O.string().optional(),total_files:O.number().nonnegative().nullable().optional(),num_citations:O.number().int().nonnegative().optional(),n_channels:O.number().int().nullable().optional(),electrode_system:O.string().nullable().optional(),has_hed:Cd.optional(),hed_version:O.string().nullable().optional(),data_complete:Cd.optional(),bytes_present:O.number().nonnegative().nullable().optional(),latest_version:UG.nullable().optional()}).passthrough(),DTe=zG.extend({file_size:O.number().nonnegative().nullable(),modalities:O.string().nullable().optional(),tasks:O.string().nullable().optional(),authors:O.string().nullable().optional(),license:O.string().nullable().optional(),owner_github:O.string().nullable().optional(),attestation_deposit_type:O.enum(["owner","redistribution"]).nullable().optional(),attestation_key_status:O.enum(["destroyed","retained"]).nullable().optional(),attestation_deidentified:Cd.optional(),attestation_no_duplicate:Cd.optional(),attestation_upstream_source:O.string().nullable().optional(),attestation_accepted_at:O.string().nullable().optional()}).passthrough(),wTe=O.object({id:O.string(),name:O.string(),modalities:O.string().nullable().optional(),participants:O.number().int().nullable().optional(),doi:O.string().nullable().optional(),tasks:O.string().nullable().optional(),authors:O.string().nullable().optional(),has_hed:Cd.optional(),score:O.number().optional(),snippet:O.string().optional()}).passthrough(),vQe=O.object({datasets:O.array(zG),count:O.number().int().nonnegative(),total_count:O.number().int().nonnegative().optional(),limit:O.number().int().optional(),offset:O.number().int().optional()}).passthrough(),_Qe=O.object({results:O.array(wTe),count:O.number().int().nonnegative(),returned:O.number().int().nonnegative().optional(),offset:O.number().int().nonnegative().optional(),limit:O.number().int().optional(),candidate_ceiling:O.number().int().optional(),method:O.string().optional(),min_score:O.number().optional()}).passthrough(),DQe=O.object({dataset:DTe}).passthrough(),wQe=O.object({schema_version:O.literal(vTe),doc_type:O.literal("dataset"),dataset_id:O.string().regex(/^[a-z]{2}\d+$/,"neuroschema dataset_id pattern"),name:O.string(),source:_Te,recording_modality:O.array(O.string()).min(1),description:O.string().nullable().optional(),bids_version:O.string().nullable().optional(),license:O.string().nullable().optional()}).passthrough();Ps();async function HG(e){return I(`/auth/check-username?username=${encodeURIComponent(e)}`)}async function GG(e){return I(`/auth/check-github?username=${encodeURIComponent(e)}`)}async function WG(e){return I("/auth/signup",{method:"POST",body:JSON.stringify(e)})}async function OD(e){return I("/auth/login",{method:"POST",body:JSON.stringify({api_key:e})})}async function KG(e){return I("/auth/resend-verification",{method:"POST",body:JSON.stringify({email:e})})}async function YG(e,t){return I("/auth/retrieve-key",{method:"POST",body:JSON.stringify({email:e,password:t})})}async function JG(e){return I("/auth/request-key-regeneration",{method:"POST",body:JSON.stringify({email:e})})}async function Wm(){return(await I("/users/me",{},!0,VG)).user}async function XG(e){return I("/sandbox/complete",{method:"POST",body:JSON.stringify({dataset_id:e})},!0)}async function QG(){return I("/sandbox/reset",{method:"POST"},!0)}async function ZG(){return I("/sandbox/status",{},!0)}gr();ks();Bt();var eW={git:{name:"git",purpose:"version control for dataset metadata",cmd:["git","--version"],required:!0,installInstructions:{macos:"brew install git (or install Xcode Command Line Tools)",linux:"sudo apt-get install git OR sudo dnf install git",windows:"winget install Git.Git (or https://git-scm.com/download/win)"}},"git-annex":{name:"git-annex",purpose:"large-file data transfer (upload/download)",cmd:["git-annex","version"],required:!0,installInstructions:{macos:"brew install git-annex",linux:"sudo apt-get install git-annex OR sudo dnf install git-annex",windows:"Download the installer from https://git-annex.branchable.com/install/Windows/"}},gh:{name:"GitHub CLI (gh)",purpose:"GitHub authentication + repository operations",cmd:["gh","--version"],required:!0,installInstructions:{macos:"brew install gh",linux:"See https://cli.github.com/manual/installation",windows:"winget install GitHub.cli (or: scoop install gh)"}},aws:{name:"AWS CLI",purpose:"S3 data upload/download",cmd:["aws","--version"],required:!0,installInstructions:{macos:"brew install awscli",linux:"pip install awscli OR sudo snap install aws-cli --classic",windows:"winget install Amazon.AWSCLI (or the MSI from https://aws.amazon.com/cli/)"}},deno:{name:"Deno",purpose:"BIDS validation",cmd:["deno","--version"],required:!0,installInstructions:{macos:"brew install deno (or: curl -fsSL https://deno.land/install.sh | sh)",linux:"curl -fsSL https://deno.land/install.sh | sh",windows:"winget install DenoLand.Deno (or: irm https://deno.land/install.ps1 | iex)"}}},ETe={upload:["git-annex","gh","aws","deno"],download:["gh"],clone:["git","gh"],push:["git-annex","gh"],publish:["gh","aws"],update:["git","gh"],release:["git","gh"]};function STe(){if(process.platform==="darwin")return"macos";if(process.platform==="win32")return"windows";return"linux"}function tW(e,t=STe()){return e.installInstructions[t]}function $Te(e){let t=e.match(/(\d+\.\d+(?:\.\d+)?)/);return t?t[1]:void 0}async function rW(e){try{let{exitCode:t,stdout:r}=await F(e.cmd);if(t!==0)return{available:!1};return{available:!0,version:$Te(r)}}catch(t){let r=t instanceof Error?t.message:String(t);if(!r.includes("ENOENT")&&!r.includes("not found"))console.error(` Warning: ${e.name} check failed unexpectedly: ${r}`);return{available:!1}}}async function AD(){let e=Object.entries(eW);return Promise.all(e.map(async([t,r])=>{let{available:n,version:i}=await rW(r);return{key:t,name:r.name,purpose:r.purpose,required:r.required,available:n,version:i,installInstruction:tW(r)}}))}async function nW(){let t=(await AD()).filter((r)=>r.required&&!r.available);if(t.length===0)return[];console.warn(`
460
460
  Heads up: some tools NEMAR needs for uploading/validating aren't installed yet:`);for(let r of t)console.warn(` - ${r.name} (${r.purpose})`),console.warn(` Install: ${r.installInstruction}`);return console.warn("Run `nemar doctor` anytime to re-check. You can finish signup without them.\n"),t}async function qo(e){let r=ETe[e].map((o)=>eW[o]).filter(Boolean),i=(await Promise.all(r.map(async(o)=>({check:o,available:(await rW(o)).available})))).filter((o)=>!o.available&&o.check.required).map((o)=>({tool:o.check.name,installInstruction:tW(o.check)}));if(i.length===0)return;let s=[`
461
461
  Missing required tools:`];for(let o of i)s.push(` ${o.tool} not installed`),s.push(` Install: ${o.installInstruction}`);throw Error(s.join(`
462
462
  `))}import{appendFileSync as CTe,existsSync as Ms,mkdirSync as iW,readFileSync as Ym,writeFileSync as FTe}from"fs";import{homedir as RTe}from"os";import{join as Km}from"path";var{spawn:sW}=globalThis.Bun;function jo(){let e=Km(RTe(),".ssh");return{sshDir:e,privateKey:Km(e,"nemar_ed25519"),publicKey:Km(e,"nemar_ed25519.pub"),configFile:Km(e,"config")}}function oW(){let e=jo();return Ms(e.privateKey)&&Ms(e.publicKey)}async function aW(e){let t=jo();if(!Ms(t.sshDir))try{iW(t.sshDir,{mode:448})}catch(r){return{success:!1,error:`Cannot create ~/.ssh directory: ${r.message}`}}if(Ms(t.privateKey))try{return{success:!0,publicKey:Ym(t.publicKey,"utf-8").trim()}}catch(r){return{success:!1,error:`NEMAR SSH key exists but cannot read public key: ${r.message}`}}try{let r=sW({cmd:["ssh-keygen","-t","ed25519","-f",t.privateKey,"-N","","-C",`nemar-cli-${e}`],stdout:"pipe",stderr:"pipe"}),n=await new Response(r.stderr).text();if(await r.exited!==0)return{success:!1,error:`ssh-keygen failed: ${n}`};return{success:!0,publicKey:Ym(t.publicKey,"utf-8").trim()}}catch(r){return{success:!1,error:`Failed to generate SSH key: ${r.message}`}}}function cW(){let e=jo();if(!Ms(e.publicKey))return null;try{return Ym(e.publicKey,"utf-8").trim()}catch{return null}}function OTe(){let e=jo();if(!Ms(e.configFile))return!1;try{let t=Ym(e.configFile,"utf-8");return t.includes("IdentityFile ~/.ssh/nemar_ed25519")||t.includes(`IdentityFile ${e.privateKey}`)}catch{return!1}}function uW(){let e=jo();if(!Ms(e.sshDir))try{iW(e.sshDir,{mode:448})}catch(r){return{success:!1,error:`Cannot create ~/.ssh directory: ${r.message}`}}if(OTe())return{success:!0};let t=`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nemar-cli",
3
- "version": "0.9.9",
3
+ "version": "0.9.10-PR1151.4e75d55",
4
4
  "description": "CLI for NEMAR (Neuroelectromagnetic Data Archive and Tools Resource) dataset management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",