@entrydesk/cli 1.29.0 → 1.31.0
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/README.md +19 -0
- package/dist/agents-PRK5LQNG.js +43 -0
- package/dist/{billing-LXGGM4BO.js → billing-L6QQXRZW.js} +1 -1
- package/dist/{budget-3KJ75AIF.js → budget-NSNB4TFT.js} +1 -1
- package/dist/chunk-FKRIIPBA.js +2 -0
- package/dist/chunk-JMYSCKCF.js +2 -0
- package/dist/chunk-UVF7TGFB.js +120 -0
- package/dist/config-2JH7KXGU.js +4 -0
- package/dist/{config-help-2YHNIPHU.js → config-help-ND4I4Y4D.js} +1 -1
- package/dist/{connectors-YUVHSMJD.js → connectors-26E6RK7B.js} +8 -8
- package/dist/help-KDHCFJNF.js +4 -0
- package/dist/index.js +1 -1
- package/dist/login-WXXDXOHI.js +2 -0
- package/dist/logout-6S6KRPMB.js +2 -0
- package/dist/{marketplace-4NZ4R2RK.js → marketplace-WV4PKSWS.js} +8 -8
- package/dist/mcp-2Q5DRF4P.js +4 -0
- package/dist/{meeting-NAS2QHFI.js → meeting-ZI2UOSO6.js} +5 -5
- package/dist/models-TXYNHCLD.js +3 -0
- package/dist/{notifications-CSXLCFK2.js → notifications-5CD6KFTP.js} +3 -3
- package/dist/{profile-4GVYKBJP.js → profile-OMP7YDYA.js} +1 -1
- package/dist/{recordings-GJIO55FV.js → recordings-MLYXHDWH.js} +3 -3
- package/dist/{schedules-7CGTNN5S.js → schedules-GIAYSDUE.js} +9 -9
- package/dist/{skills-OOY3DP3O.js → skills-IK7KZZ45.js} +3 -3
- package/dist/status-OKGY6H3C.js +2 -0
- package/dist/task-XXJ5PAJF.js +179 -0
- package/dist/{tasks-SJWOHL6F.js → tasks-2TMKPOTB.js} +9 -9
- package/dist/tool-HMD5ROEP.js +35 -0
- package/dist/{update-B3LT5ALF.js → update-DM47OUD3.js} +2 -2
- package/dist/{usage-IQW77ZHI.js → usage-TLLEU4K7.js} +5 -5
- package/dist/version-USTE3KNX.js +2 -0
- package/dist/workflow-PRS2UCQT.js +62 -0
- package/dist/{workspaces-KDZIJPII.js → workspaces-HML7DEAL.js} +3 -3
- package/package.json +9 -7
- package/dist/agents-HRFKKSCB.js +0 -43
- package/dist/chunk-GN6HSCLY.js +0 -4
- package/dist/chunk-LHRI5YM6.js +0 -2
- package/dist/chunk-NOSHH4TO.js +0 -8
- package/dist/chunk-YAWZE3PA.js +0 -91
- package/dist/chunk-ZIAOI7B2.js +0 -2
- package/dist/config-53QOLH2T.js +0 -4
- package/dist/help-FBKSAMA7.js +0 -4
- package/dist/login-BKSNJT4R.js +0 -2
- package/dist/logout-U64RQTQO.js +0 -2
- package/dist/mcp-EON5KZPT.js +0 -4
- package/dist/models-E3O6GOH5.js +0 -3
- package/dist/status-KK6P75DT.js +0 -2
- package/dist/task-ET6X7N52.js +0 -211
- package/dist/token-5JSZTSX7.js +0 -2
- package/dist/token-util-U6DGFQDY.js +0 -2
- package/dist/tool-TW7BI2LH.js +0 -35
- package/dist/version-TG5WFL3B.js +0 -2
- package/dist/workflow-J6RX65V7.js +0 -62
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{C as ge,P as he,T as J,r as ye,y as O}from"./chunk-UVF7TGFB.js";import"./chunk-JMYSCKCF.js";import Mt from"crypto";import M from"fs";import h from"fs/promises";import ke from"os";import k from"path";import{Readable as _t}from"stream";import{pipeline as Kt}from"stream/promises";import zt from"adm-zip";import Wt from"archiver";import{isHTTPError as Gt}from"ky";import ne from"fs/promises";import ie from"path";import{execFileSync as kt}from"child_process";import x from"fs";import yt from"os";import $ from"path";import rt from"os";import B from"fs";import Qe from"os";import _ from"path";import le from"fs";import we from"path";var qe="skills-lock.json",V=".entrydesk",ce=1;function Se(){return{version:ce,skills:{}}}function ve(e){return we.join(e,V,qe)}function I(e){try{let t=JSON.parse(le.readFileSync(ve(e),"utf8"));return t.version!==ce||typeof t.skills!="object"||t.skills===null?Se():t}catch{return Se()}}function be(e,t){let o={};for(let s of Object.keys(t.skills).toSorted())o[s]=t.skills[s];let r={version:ce,...t.workspaceId?{workspaceId:t.workspaceId}:{},skills:o},i=ve(e);le.mkdirSync(we.dirname(i),{recursive:!0}),le.writeFileSync(i,`${JSON.stringify(r,null,2)}
|
|
3
3
|
`,"utf8")}function Z(e,t){return I(e).skills[t]}function F(e,t,o){let r=I(e);r.skills[t]=o,be(e,r)}function Ie(e,t){let o=I(e);if(!(t in o.skills))return!1;let{[t]:r,...i}=o.skills;return be(e,{...o,skills:i}),!0}var et="project.json",tt="global-link.json";function Le(e){try{let t=JSON.parse(B.readFileSync(e,"utf8"));return typeof t.workspaceId!="string"||t.workspaceId===""?void 0:t}catch{return}}function xe(e,t){B.mkdirSync(_.dirname(e),{recursive:!0}),B.writeFileSync(e,`${JSON.stringify(t,null,2)}
|
|
4
4
|
`,"utf8")}function $e(e){return B.existsSync(e)?(B.rmSync(e),!0):!1}function R(e){return _.join(e,V,et)}function H(){return _.join(Qe.homedir(),V,tt)}function Ee(){return Le(H())}function Y(e){xe(H(),e)}function Pe(){return $e(H())}function ae(e=process.cwd()){let t=_.resolve(e);for(;;){if(B.existsSync(R(t)))return t;let o=_.dirname(t);if(o===t)return;t=o}}function ot(e){return Le(R(e))}function X(e,t){xe(R(e),t)}function je(e){return $e(R(e))}function Ae(e=process.cwd()){let t=ae(e);if(!t)return;let o=ot(t);return o?{rootDir:t,link:o}:void 0}function Ce(e){let t=O();if(e&&t&&e!==t)throw new Error(`This directory is linked to a workspace on ${e}, but the active profile points at ${t}. Re-run 'entrydesk skills link' or switch profile.`)}function q(){process.env.ENTRYDESK_API_URL&&console.error("Note: the recorded apiUrl comes from the ENTRYDESK_API_URL environment variable. This link pins the directory to that API \u2014 if the override was temporary, re-run the link without it.")}function v(e,t){if(e){let r=rt.homedir(),i=Ee();return i?(Ce(i.apiUrl),{rootDir:r,workspaceId:i.workspaceId,linked:!0}):{rootDir:r,workspaceId:t,linked:!1}}let o=Ae(process.cwd());return o?(Ce(o.link.apiUrl),{rootDir:o.rootDir,workspaceId:o.link.workspaceId,linked:!0}):{rootDir:process.cwd(),workspaceId:t,linked:!1}}import E from"fs";import K from"path";function Q(e,t){let o=K.dirname(e);E.mkdirSync(o,{recursive:!0});let r=E.mkdtempSync(K.join(o,`.${K.basename(e)}.tmp-`)),i=K.join(r,"next"),s=K.join(r,"prev");E.mkdirSync(i,{recursive:!0});let c=!1;try{t(i),E.existsSync(e)&&(E.renameSync(e,s),c=!0),E.renameSync(i,e)}catch(n){throw c&&!E.existsSync(e)&&E.renameSync(s,e),n}finally{E.rmSync(r,{recursive:!0,force:!0})}}import{createHash as Re}from"crypto";import ee from"fs";import z from"path";var De=new Set([".git","node_modules","__pycache__",".DS_Store","__MACOSX"]),Ne="SKILL.md";function nt(e){let t=ee.readdirSync(e,{withFileTypes:!0}).filter(r=>!De.has(r.name));if(t.some(r=>r.isFile()&&r.name===Ne))return e;let o=t.filter(r=>r.isDirectory());if(o.length===1){let r=z.join(e,o[0].name);if(ee.existsSync(z.join(r,Ne)))return r}return e}function Te(e,t,o){for(let r of ee.readdirSync(t,{withFileTypes:!0})){if(De.has(r.name))continue;let i=z.join(t,r.name);r.isDirectory()?Te(e,i,o):r.isFile()&&o.push({rel:z.relative(e,i).split(z.sep).join("/"),abs:i})}}function it(e){let t=[];Te(e,e,t),t.sort((r,i)=>r.rel<i.rel?-1:r.rel>i.rel?1:0);let o=Re("sha256");for(let r of t){let i=Re("sha256").update(ee.readFileSync(r.abs)).digest("hex");o.update(r.rel).update("\0").update(i).update("\0")}return o.digest("hex")}function P(e){return it(nt(e))}import L from"fs";import S from"path";var N=[{id:"claude-code",displayName:"Claude Code",skillsSubdir:S.join(".claude","skills"),rootMarker:".claude"},{id:"codex",displayName:"Codex",skillsSubdir:S.join(".codex","skills"),rootMarker:".codex"},{id:"cursor",displayName:"Cursor",skillsSubdir:S.join(".cursor","skills"),rootMarker:".cursor"},{id:"universal",displayName:"Universal (.agents)",skillsSubdir:S.join(".agents","skills"),rootMarker:".agents"}];function te(e,t){return S.join(t,e.skillsSubdir)}function st(e){let t=N.filter(o=>o.id==="universal"||L.existsSync(S.join(e,o.rootMarker)));return t.length>0?t:N.filter(o=>o.id==="universal")}function Ue(e){let t;try{t=L.lstatSync(e)}catch{return}t.isSymbolicLink()?L.unlinkSync(e):t.isDirectory()?L.rmSync(e,{recursive:!0,force:!0}):L.rmSync(e,{force:!0})}function lt(e,t,o,r="symlink"){let i=S.basename(S.dirname(t))||t,s=S.join(t,o);if(L.mkdirSync(t,{recursive:!0}),Ue(s),r==="symlink")try{let c=S.relative(t,e);return L.symlinkSync(c,s,process.platform==="win32"?"junction":"dir"),{agentId:i,linkPath:s,mode:"symlink",ok:!0}}catch{}try{return L.cpSync(e,s,{recursive:!0}),{agentId:i,linkPath:s,mode:"copy",ok:!0}}catch(c){return{agentId:i,linkPath:s,mode:"copy",ok:!1,error:c instanceof Error?c.message:String(c)}}}function Oe(e,t){let o=S.join(e,t);try{L.lstatSync(o)}catch{return!1}return Ue(o),!0}function Fe(e,t){let o;try{o=L.lstatSync(e)}catch{return!1}return o.isSymbolicLink()?S.resolve(S.dirname(e),L.readlinkSync(e))===S.resolve(t):!1}function ct(e,t){return t&&t.length>0?t.includes("*")?[...N]:N.filter(o=>t.includes(o.id)):st(e)}function oe(e,t,o,r="symlink",i){return ct(o,i).map(s=>lt(e,te(s,o),t,r))}import re from"path";var at=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function fe(e){if(!at.test(e))throw new Error(`Invalid skill name "${e}": must be lowercase letters, digits and single hyphens (e.g. "my-skill").`)}function b(e,t){fe(t);let o=re.resolve(e,".entrydesk","skills"),r=re.resolve(o,t);if(r!==re.join(o,t)||!r.startsWith(o+re.sep))throw new Error(`Refusing unsafe skill path for "${t}".`);return r}async function j(e,t,o){let r=[],i;do{let s=await e.listAvailableSkills(t,o,{nextKey:i,limit:100});r.push(...s.skills),i=s.nextKey}while(i);return r}import A from"fs";import de from"os";import D from"path";var Be=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu,ft=/^([\w.-]+)\/([\w.-]+)(?:\/(.+))?$/u;function dt(e){return e==="~"?de.homedir():e.startsWith("~/")||e.startsWith("~\\")?D.join(de.homedir(),e.slice(2)):e}function ut(e){return e.startsWith("./")||e.startsWith("../")||e.startsWith("/")||e.startsWith("~")||e.startsWith(".\\")||/^[a-zA-Z]:[\\/]/u.test(e)}function pt(e){let t=/^https?:\/\/github\.com\/([\w.-]+)\/([\w.-]+?)(?:\.git)?(?:\/tree\/([^/]+)(?:\/(.+))?)?\/?$/u.exec(e);return t?{type:"github",owner:t[1],repo:t[2],gitRef:t[3],subpath:t[4],url:`https://github.com/${t[1]}/${t[2]}`}:null}function He(e){let t=e.trim();if(ut(t))return{type:"local",path:D.resolve(dt(t))};if(t.startsWith("ed:")){let i=t.slice(3);return{type:"entrydesk",ref:i,isId:Be.test(i)}}if(Be.test(t))return{type:"entrydesk",ref:t,isId:!0};if(t.startsWith("git@")||t.endsWith(".git"))return{type:"git",url:t};let o=pt(t);if(o)return o;if(/^https?:\/\//u.test(t))return{type:"git",url:t};let r=ft.exec(t);return r?{type:"github",owner:r[1],repo:r[2],subpath:r[3],url:`https://github.com/${r[1]}/${r[2]}`}:{type:"entrydesk",ref:t,isId:!1}}function ue(e){return e.type==="github"?"github":e.type}var mt=new Set([".git","node_modules","__pycache__",".DS_Store",".entrydesk"]);function pe(e,t){if(!A.existsSync(D.join(e,"SKILL.md")))throw new Error(`No SKILL.md found at ${e}`);let o=A.realpathSync(e),r=A.existsSync(t)?A.realpathSync(t):D.resolve(t);if(o===r)return;let i=A.mkdtempSync(D.join(de.tmpdir(),"ed-local-skill-")),s=D.join(i,"skill");try{A.cpSync(o,s,{recursive:!0,filter:c=>!mt.has(D.basename(c))}),Q(t,c=>{A.cpSync(s,c,{recursive:!0})})}finally{A.rmSync(i,{recursive:!0,force:!0})}}var gt="skills@1.5.12";function Me(e){try{let t=x.readFileSync($.join(e,"SKILL.md"),"utf8"),o=/^name:\s*(.+?)\s*$/mu.exec(t.split(/^---\s*$/mu)[1]??"");if(o?.[1])return o[1].replace(/^['"]|['"]$/gu,"")}catch{}return $.basename(e)}async function ht(e,t){let{default:o}=await import("adm-zip"),r=new o(e);Q(t,i=>{let s=$.resolve(i)+$.sep;for(let c of r.getEntries()){if(c.isDirectory)continue;let n=$.resolve(i,c.entryName);if(!n.startsWith(s))throw new Error(`Zip entry contains path traversal: ${c.entryName}`);x.mkdirSync($.dirname(n),{recursive:!0}),x.writeFileSync(n,c.getData())}})}async function St(e,t){if(t.isId)return t.ref;let r=(await j(e.client,e.accessToken,e.workspaceId)).find(i=>i.name===t.ref||i.id===t.ref);if(!r)throw new Error(`Skill not found in workspace: ${t.ref}`);return r.id}function wt(e,t,o){let r=x.mkdtempSync($.join(yt.tmpdir(),"ed-npx-skills-")),i=["-y",gt,"add",e,"--copy","--yes"];try{kt("npx",i,{cwd:r,stdio:o?["ignore","pipe","pipe"]:"inherit"})}catch(l){throw x.rmSync(r,{recursive:!0,force:!0}),new Error(`npx skills failed for ${e}. Ensure npx + network are available. (${l instanceof Error?l.message:String(l)})`,{cause:l})}let s=$.join(r,".agents","skills");if(!x.existsSync(s))throw x.rmSync(r,{recursive:!0,force:!0}),new Error(`npx skills produced no skills under ${s}`);let c=x.readdirSync(s,{withFileTypes:!0}).filter(l=>l.isDirectory());if(c.length===0)throw x.rmSync(r,{recursive:!0,force:!0}),new Error("npx skills installed no skill directory");let n=c[0];if(c.length>1){let l=t.type==="github"&&t.subpath?$.basename(t.subpath):void 0,f=l?c.find(a=>a.name===l):void 0;if(!f)throw x.rmSync(r,{recursive:!0,force:!0}),new Error(`npx skills installed [${c.map(a=>a.name).join(", ")}]; ${l?`none matched the subpath "${l}"`:"specify a subpath to pick one"}.`);n=f}return{dir:$.join(s,n.name),tmpRoot:r}}async function _e(e,t){let o=e.configKey;if(!o)throw new Error("Missing source. Usage: entrydesk skills add <source>");let r=He(o),i=!!e.global,s=v(i,t.workspaceId),c=s.rootDir,n={...t,workspaceId:s.workspaceId};if(!s.linked){let u={workspaceId:t.workspaceId,apiUrl:O()};q(),i?Y(u):X(process.cwd(),u)}let l,f,a;if(r.type==="entrydesk"){f=await St(n,r);let u=await n.client.downloadSkillCurrent(n.accessToken,n.workspaceId,f);l=u.name,a=b(c,l);let m=await fetch(u.url);if(!m.ok)throw new Error(`Failed to download ${l}: ${m.status}`);await ht(Buffer.from(await m.arrayBuffer()),a)}else if(r.type==="local")l=Me(r.path),a=b(c,l),pe(r.path,a);else{let{dir:u,tmpRoot:m}=wt(o,r,!!e.json);try{l=Me(u),a=b(c,l),pe(u,a)}finally{x.rmSync(m,{recursive:!0,force:!0})}}let y=P(a),g={source:o,sourceType:ue(r),skillId:f,localHash:y,lastPulledHash:r.type==="entrydesk"?y:"",mode:"symlink",...r.type==="github"?{sourceUrl:r.url,ref:r.gitRef,subpath:r.subpath}:{},...r.type==="git"?{sourceUrl:r.url}:{}};F(c,l,g);let d=oe(a,l,c,"symlink",e.agents);e.json?console.info(JSON.stringify({name:l,sourceType:ue(r),hash:y},null,2)):console.info(`\u2713 added ${l} (${r.type}, ${y.slice(0,12)}) \u2192 agents: ${d.map(u=>u.agentId).join(", ")}`)}import G from"fs";import vt from"os";import W from"path";import bt from"archiver";function It(e){return typeof e!="object"||e===null?!1:e.response?.status===404||/\b404\b/u.test(String(e.message??""))}function Lt(e){return e.remoteHash===null?"create":e.currentHash===e.baseHash?"noop":!e.force&&e.remoteHash!==e.lastPulledHash?"stale":"push"}function xt(e){return new Promise((t,o)=>{let r=[],i=bt("zip",{zlib:{level:9}});i.on("data",s=>r.push(s)),i.on("error",o),i.on("end",()=>t(Buffer.concat(r))),i.directory(e,!1),i.finalize()})}async function $t(e,t){let{url:o}=await e.client.downloadSkillCurrent(e.accessToken,e.workspaceId,t),r=await fetch(o);if(!r.ok)throw new Error(`download for staleness check failed: ${r.status}`);let i=G.mkdtempSync(W.join(vt.tmpdir(),"ed-push-cmp-"));try{let{default:s}=await import("adm-zip");for(let c of new s(Buffer.from(await r.arrayBuffer())).getEntries()){if(c.isDirectory)continue;let n=W.resolve(i,c.entryName);n.startsWith(W.resolve(i)+W.sep)&&(G.mkdirSync(W.dirname(n),{recursive:!0}),G.writeFileSync(n,c.getData()))}return P(i)}finally{G.rmSync(i,{recursive:!0,force:!0})}}async function Ke(e,t,o,r,i,s,c){let n=await xt(r),l=new FormData;l.append("file",new Blob([n],{type:"application/zip"}),`${o}.zip`),c&&l.append("force","true");let f=await e.client.uploadSkill(e.accessToken,e.workspaceId,l);F(t,o,{...s,skillId:f.id,localHash:i,lastPulledHash:i})}async function Et(e,t,o,r,i){let s=b(t,o);if(!G.existsSync(s))throw new Error(`No local copy for ${o}`);let c=P(s);if(r.skillId){let f=null;try{f=await $t(e,r.skillId)}catch(a){if(!It(a))throw a}if(f!==null){let a=Lt({currentHash:c,baseHash:r.localHash,lastPulledHash:r.lastPulledHash,remoteHash:f,force:i});return a==="noop"||a==="stale"||await Ke(e,t,o,s,c,r,!0),a}}let l=(await j(e.client,e.accessToken,e.workspaceId)).find(f=>f.name===o);return l&&!i?"name-conflict":(await Ke(e,t,o,s,c,r,!!l),"create")}async function ze(e,t){let{rootDir:o,workspaceId:r}=v(!!e.global,t.workspaceId),i={...t,workspaceId:r},s=!!e.force,c=e.configKey?[e.configKey]:Object.keys(I(o).skills);if(c.length===0){console.info("Nothing to push \u2014 no tracked skills.");return}let n=!1;for(let l of c){let f=Z(o,l);if(!f){console.info(`\u2717 ${l}: not tracked (run: entrydesk skills add <source>)`),n=!0;continue}let a=await Et(i,o,l,f,s),y={create:`\u2713 pushed ${l} (created in workspace)`,push:`\u2713 pushed ${l}`,noop:`\xB7 ${l} unchanged`,stale:`\u2717 ${l} rejected \u2014 remote changed since last pull. Run 'entrydesk skills pull ${l}' first (or --force).`,"name-conflict":`\u2717 ${l} rejected \u2014 a different skill named "${l}" already exists in the workspace. Pull it first, or --force to overwrite.`};console.info(y[a]),(a==="stale"||a==="name-conflict")&&(n=!0)}n&&(process.exitCode=1)}import me from"fs";import Pt from"path";function jt(e,t,o,r){let i=[],s=[];for(let c of N){let n=Pt.join(te(c,t),e);try{me.lstatSync(n)}catch{continue}r||Fe(n,o)?i.push(c.id):s.push(c.id)}return{removable:i,preserved:s}}async function We(e,t){let o=e.configKey;if(!o)throw new Error("Missing skill name. Usage: entrydesk skills remove <name>");fe(o);let{rootDir:r,workspaceId:i}=v(!!e.global,t.workspaceId),s=Z(r,o),c=b(r,o),n=me.existsSync(c),l=!!s||n,{removable:f,preserved:a}=jt(o,r,c,l);if(!(l||f.length>0)&&!(e.remote&&s?.skillId)){a.length>0?console.info(`Left ${o} untouched in ${a.join(", ")} \u2014 not EntryDesk-managed; remove it manually if intended.`):console.info(`Nothing to remove \u2014 ${o} is not installed.`);return}let g=!1;e.remote&&(s?.skillId?(await t.client.deleteSkill(t.accessToken,i,s.skillId),g=!0):console.info(`\xB7 skipped --remote: no known workspace skillId for ${o} (it was never pushed from here).`));for(let p of N)f.includes(p.id)&&Oe(te(p,r),o);n&&me.rmSync(c,{recursive:!0,force:!0}),Ie(r,o);let d={name:o,canonicalRemoved:n,agentsUnlinked:f,agentsPreserved:a,untracked:!s,remoteDeleted:g};if(e.json){console.info(JSON.stringify(d,null,2));return}let u=f.length>0?` (agents: ${f.join(", ")})`:"",m=a.length>0?` \u2014 kept non-managed entries in ${a.join(", ")}`:"";console.info(`\u2713 removed ${o}${u}${g?" + deleted from workspace":""}${m}`)}import At from"fs";function Ct(e,t,o){return t?(o??e.localHash)===e.lastPulledHash?"synced":"ahead":e.skillId?"remote-deleted":"local-only"}var Ge={synced:"\u2014",ahead:"push (local edits)","local-only":"push (never uploaded)","remote-deleted":"push to restore, or remove","remote-only":"add / pull to install"},Rt={synced:"\u2713",ahead:"\u2191","local-only":"\u2299","remote-deleted":"\u26A0","remote-only":"\u2601"};async function Je(e,t){let o=!!e.global,{rootDir:r,workspaceId:i}=v(o,t.workspaceId),s=o?"global":"project",c=I(r).skills,n=await j(t.client,t.accessToken,i),l=new Map(n.map(d=>[d.id,d])),f=new Map(n.map(d=>[d.name,d])),a=[],y=new Set;for(let[d,u]of Object.entries(c)){let m=u.skillId?l.get(u.skillId):f.get(d);m&&y.add(m.id);let p=b(r,d),w=At.existsSync(p)?P(p):null,T=Ct(u,!!m,w);a.push({name:d,scope:s,state:T,hint:Ge[T]})}for(let d of n)y.has(d.id)||a.push({name:d.name,scope:s,state:"remote-only",hint:Ge["remote-only"]});if(a.sort((d,u)=>d.name<u.name?-1:d.name>u.name?1:0),e.json){console.info(JSON.stringify(a,null,2));return}if(a.length===0){console.info("No skills tracked locally or available in the workspace.");return}let g=(d,u)=>d.padEnd(u);console.info(`${g("NAME",26)}${g("SCOPE",9)}STATUS`);for(let d of a)console.info(`${g(d.name,26)}${g(d.scope,9)}${Rt[d.state]} ${g(d.state,16)}${d.hint}`)}var Ve=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;function Nt(e,t){let o=e.configKey&&Ve.test(e.configKey)?e.configKey:t.workspaceId,r={workspaceId:o,apiUrl:O()};if(q(),e.global)Y(r),console.info(`Linked ${H()} \u2192 workspace ${o}`);else{let i=process.cwd();X(i,r),console.info(`Linked ${R(i)} \u2192 workspace ${o}`)}}function Dt(e){if(e.global){Pe()?console.info(`Unlinked ${H()}`):console.info("No global link found.");return}let t=ae(process.cwd());t&&je(t)?console.info(`Unlinked ${R(t)}`):console.info("No project link found.")}async function Tt(e,t,o,r,i){let s=o.skillId;if(!s){let{skills:p}=await e.client.listAvailableSkills(e.accessToken,e.workspaceId),w=p.find(T=>T.name===o.name);if(!w)throw new Error(`Skill not found in workspace: ${o.name}`);s=w.id}let{url:c,name:n}=await e.client.downloadSkillCurrent(e.accessToken,e.workspaceId,s),l=await fetch(c);if(!l.ok)throw new Error(`Failed to download ${n}: ${l.status}`);let f=Buffer.from(await l.arrayBuffer()),a=b(t,n);await ne.rm(a,{recursive:!0,force:!0}),await ne.mkdir(a,{recursive:!0});let{default:y}=await import("adm-zip"),g=ie.resolve(a)+ie.sep;for(let p of new y(f).getEntries()){if(p.isDirectory)continue;let w=ie.resolve(a,p.entryName);if(!w.startsWith(g))throw new Error(`Zip entry contains path traversal: ${p.entryName}`);await ne.mkdir(ie.dirname(w),{recursive:!0}),await ne.writeFile(w,p.getData())}let d=P(a);F(t,n,{source:s,sourceType:"entrydesk",skillId:s,localHash:d,lastPulledHash:d,mode:"symlink"});let m=oe(a,n,t,"symlink",i);return r||console.info(`\u2713 pulled ${n} (${d.slice(0,12)}) \u2192 agents: ${m.map(p=>p.agentId).join(", ")}`),{name:n,hash:d}}async function Ut(e,t){let{rootDir:o,workspaceId:r}=v(!!e.global,t.workspaceId),i={...t,workspaceId:r},s=!!e.json,c=[];if(e.configKey)c.push(Ve.test(e.configKey)?{skillId:e.configKey}:{name:e.configKey});else{let l=I(o).skills;for(let[f,a]of Object.entries(l))c.push({skillId:a.skillId,name:f});if(c.length===0){console.info("Nothing to pull \u2014 no tracked skills. Try: entrydesk skills pull <name>");return}}let n=[];for(let l of c)n.push(await Tt(i,o,l,s,e.agents));s&&console.info(JSON.stringify(n,null,2))}var Ot=new Set(["add","pull","push","status","remove","link","unlink"]);function Ze(e){return Ot.has(e)}function Ye(e,t){return e.action==="add"?_e(e,t):e.action==="pull"?Ut(e,t):e.action==="push"?ze(e,t):e.action==="status"?Je(e,t):e.action==="remove"?We(e,t):(e.action==="link"?Nt(e,t):e.action==="unlink"&&Dt(e),Promise.resolve())}function Ft(e){return e.all?"all":e.remote&&!e.local?"remote":e.local&&!e.remote?"local":"all"}function Bt(e,t,o){let r=new Map(t.map(n=>[n.name,n])),i=new Map(Object.entries(e)),s=new Set;if(o!=="remote")for(let n of i.keys())s.add(n);if(o!=="local")for(let n of r.keys())s.add(n);let c=[];for(let n of s){let l=i.get(n),f=r.get(n);c.push({name:n,local:!!l,remote:!!f,sourceType:l?.sourceType,skillId:l?.skillId??f?.id})}return c.sort((n,l)=>n.name<l.name?-1:n.name>l.name?1:0),c}function Ht(e){return e.local&&e.remote?"local+remote":e.local?"local-only":"remote-only"}async function Xe(e,t){let o=Ft(e),{rootDir:r,workspaceId:i}=v(!!e.global,t.workspaceId),s=o==="remote"?{}:I(r).skills,c=o==="local"?[]:await j(t.client,t.accessToken,i),n=Bt(s,c,o);if(e.json){console.info(JSON.stringify(n,null,2));return}if(n.length===0){console.info(o==="local"?"No skills tracked locally.":"No skills available in the workspace.");return}let l=(f,a)=>f.padEnd(a);console.info(`${l("NAME",28)}${l("WHERE",14)}SOURCE`);for(let f of n)console.info(`${l(f.name,28)}${l(Ht(f),14)}${f.sourceType??"\u2014"}`)}function C(){console.log(`
|
|
5
5
|
Usage: entrydesk skills [list|upload|delete|download|toggle|versions|share] [options]
|
|
@@ -16,7 +16,7 @@ Commands:
|
|
|
16
16
|
remove <name> Uninstall a skill locally (--remote also deletes it from the workspace)
|
|
17
17
|
|
|
18
18
|
Options:
|
|
19
|
-
--me Only list skills created
|
|
19
|
+
--me Only list skills you created
|
|
20
20
|
--force Overwrite an existing skill with the same name
|
|
21
21
|
--local / --remote / --all For list: scope the inventory (local lock / workspace / merged)
|
|
22
22
|
--remote For remove: also delete the skill from the workspace
|
|
@@ -26,5 +26,5 @@ Options:
|
|
|
26
26
|
--role owner|editor|viewer Role for --add-user (default: viewer)
|
|
27
27
|
--json Output JSON (for list/upload)
|
|
28
28
|
`)}function Jt(e,t){let o=k.relative(e,t);return o===""||!o.startsWith("..")&&!k.isAbsolute(o)}async function Vt(e){let t=await h.realpath(e),o=[process.cwd(),ke.homedir()];if(!(await Promise.all(o.map(async s=>{try{return await h.realpath(s)}catch{return k.resolve(s)}}))).some(s=>Jt(s,t)))throw new Error("Invalid upload path: must be within the current directory or your home directory.")}async function Zt(e){let t=await h.mkdtemp(k.join(ke.tmpdir(),"entrydesk-skill-")),o=k.join(t,`${k.basename(e)}.zip`);return await new Promise((r,i)=>{let s=M.createWriteStream(o),c=Wt("zip",{zlib:{level:9}});s.on("close",()=>r()),s.on("error",i),c.on("error",i),c.pipe(s),c.directory(e,!1),c.finalize()}),{zipPath:o,cleanupDir:t}}function Yt(e){console.log(`Versions (${e.length}):
|
|
29
|
-
`);for(let t of e){let o=new Date(t.createdAt).toLocaleString();if(console.log(` v${t.versionNumber} \xB7 ${o}`),t.description){let r=t.description.length>100?`${t.description.slice(0,100)}
|
|
29
|
+
`);for(let t of e){let o=new Date(t.createdAt).toLocaleString();if(console.log(` v${t.versionNumber} \xB7 ${o}`),t.description){let r=t.description.length>100?`${t.description.slice(0,100)}\u2026`:t.description;console.log(` ${r}`)}console.log(` Version ID: ${t.id}`),console.log("")}}function Xt(e){let t=ye(e);if(console.log(`User grants (${t.length}):`),t.length===0){console.log(" (none)");return}for(let o of t)console.log(` - ${o.user.name} <${o.user.email}> \xB7 ${o.role}`),console.log(` ID: ${o.userId}`)}async function Vr(e){if(e.help){C();return}let t,o;try{let n=await he();t=n.accessToken,o=n.workspaceId}catch(n){J(n)}let r=e.action||"list",i=new ge;if(Ze(r)){try{await Ye(e,{accessToken:t,workspaceId:o,client:i})}catch(n){J(n)}return}if(r==="list"&&(e.local||e.remote||e.all)){try{await Xe(e,{accessToken:t,workspaceId:o,client:i})}catch(n){J(n)}return}if(r==="upload"){let n=e.configKey;n||(console.error("Missing file path."),C(),process.exit(1));let l=k.resolve(n),f;try{f=await h.stat(l)}catch{console.error(`File not found: ${l}`),process.exit(1)}let a=l,y=null;try{try{await Vt(l)}catch(m){let p=m instanceof Error?m.message:"Invalid upload path.";console.error(p),process.exit(1)}if(f.isDirectory()){let m=await Zt(l);a=m.zipPath,y=m.cleanupDir}else f.isFile()||(console.error(`Not a file or directory: ${l}`),process.exit(1));k.extname(a).toLowerCase()!==".zip"&&(console.error("Only .zip files are supported for upload."),process.exit(1));let g=await h.readFile(a),d=new FormData;d.append("file",new Blob([g],{type:"application/zip"}),k.basename(a)),e.force&&d.append("force","true");let u;try{u=await i.uploadSkill(t,o,d)}catch(m){throw Gt(m)&&m.response.status===409&&(console.error("Upload failed: A skill with this name already exists."),console.error("Use --force to overwrite the existing skill."),process.exit(1)),m}if(e.json){console.log(JSON.stringify(u));return}console.log(`Uploaded skill: ${u.name}`),console.log(` ID: ${u.id}`),console.log(` Version ID: ${u.versionId}`),console.log(` Description: ${u.description}`);return}finally{y&&await h.rm(y,{recursive:!0,force:!0})}}if(r==="toggle"){let n=e.configKey;n||(console.error("Missing skill ID."),C(),process.exit(1)),e.enable===e.disable&&(console.error("Pass exactly one of --enable or --disable."),process.exit(1));let l=!!e.enable,f=await i.updateSkillPreference(t,o,n,l);if(e.json){console.log(JSON.stringify(f));return}console.log(`${f.isEnabled?"Enabled":"Disabled"} skill for you: ${n}`);return}if(r==="versions"){let n=e.configKey;n||(console.error("Missing skill ID."),C(),process.exit(1));let l=await i.getSkillVersions(t,o,n);if(e.json){console.log(JSON.stringify(l));return}if(l.versions.length===0){console.log("No versions for this skill.");return}Yt(l.versions);return}if(r==="share"){let n=e.configKey;n||(console.error("Missing skill ID."),C(),process.exit(1));let l=e.role??"viewer";if(e.addUser){let a=await i.upsertSkillGrant(t,o,n,e.addUser,l);if(e.json){console.log(JSON.stringify(a));return}console.log(`Granted ${l} to user ${e.addUser}`);return}if(e.removeUser){if(await i.removeSkillGrant(t,o,n,e.removeUser),e.json){console.log(JSON.stringify({userId:e.removeUser,removed:!0}));return}console.log(`Revoked access for user ${e.removeUser}`);return}let f=await i.getSkillGrants(t,o,n);if(e.json){console.log(JSON.stringify(f));return}Xt(f);return}if(r==="delete"){let n=e.configKey;n||(console.error("Missing skill ID."),C(),process.exit(1)),await i.deleteSkill(t,o,n),console.log(`Deleted skill: ${n}`);return}if(r==="download"){let n=e.configKey;n||(console.error("Missing skill ID."),C(),process.exit(1));let{url:l,name:f}=await i.downloadSkillCurrent(t,o,n);(f.includes("/")||f.includes(k.sep)||f==="."||f===".."||!f)&&(console.error(`Invalid skill name for output directory: ${f}`),process.exit(1));let a=k.resolve(f),y=await h.mkdtemp(k.join(ke.tmpdir(),"entrydesk-skill-download-")),g=k.join(y,`${f}.zip`);try{let d=await fetch(l);if(!d.ok)throw new Error(`Failed to download skill zip: ${d.status} ${d.statusText}`);if(!d.body)throw new Error("Response body is empty");let u=M.createWriteStream(g);await Kt(_t.fromWeb(d.body),u);let m=await h.mkdtemp(k.join(k.dirname(a),".entrydesk-skill-extract-")),p=null;try{e.json||console.log("Extracting\u2026");let w=new zt(g),T=k.resolve(m)+k.sep;for(let U of w.getEntries()){if(U.isDirectory)continue;let se=k.resolve(m,U.entryName);if(!se.startsWith(T))throw new Error(`Zip entry contains path traversal: ${U.entryName}`);await h.mkdir(k.dirname(se),{recursive:!0}),await h.writeFile(se,U.getData())}M.existsSync(a)&&(p=k.join(k.dirname(a),`.entrydesk-backup-${Mt.randomUUID()}`),e.json||console.log(`Replacing existing directory: ${a}`),await h.rename(a,p));try{await h.rename(m,a),p&&M.existsSync(p)&&(await h.rm(p,{recursive:!0,force:!0}),p=null)}catch(U){throw p&&M.existsSync(p)&&(await h.rename(p,a),p=null),U}}catch(w){if(await h.rm(m,{recursive:!0,force:!0}),p&&M.existsSync(p))try{await h.rename(p,a)}catch{console.error(`Warning: Could not restore backup. Your original files are at: ${p}`)}throw w}if(e.json){console.log(JSON.stringify({skillId:n,skillName:f,outputDir:a}));return}console.log(`Downloaded skill "${f}" to ${a}`)}finally{await h.rm(y,{recursive:!0,force:!0})}return}r!=="list"&&(console.error(`Unknown skills command: ${r}`),C(),process.exit(1));let s=[],c;do{let n=await i.listAvailableSkills(t,o,{createdBy:e.createdBy,nextKey:c,limit:100});s.push(...n.skills),c=n.nextKey}while(c);if(e.json){console.log(JSON.stringify(s));return}if(s.length===0){console.log("No skills in this workspace yet. Upload one with `entrydesk skills upload <path>`, or browse `entrydesk marketplace`.");return}console.log(`Available skills (${s.length}):
|
|
30
30
|
`);for(let n of s)console.log(` ${n.name} (${n.provider})`),console.log(` ${n.description.slice(0,120)}`),console.log(` ID: ${n.id}`),console.log(` Author: ${n.author.name}`),console.log("")}export{C as printSkillsUsage,Vr as runSkills};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{B as f,C as p,H as d,L as m,O as u,T as k,v as g,w as c,y as a}from"./chunk-UVF7TGFB.js";import"./chunk-JMYSCKCF.js";async function C(n){try{let o=g.getEffectiveProfileName(),e=a(),s={model:c.getDefaultModel(),connectors:c.getDefaultConnectorIds()},l=d();if(l){n.json?console.log(JSON.stringify({loggedIn:!0,authSource:l.authSource,profile:o,server:e,workspaceId:l.workspaceId,defaults:s})):(console.log(`Profile: ${o}`),console.log(`Server: ${e}`),console.log(`Authenticated via ${l.label} (no login required)`),console.log(`Workspace ID: ${l.workspaceId}`));return}let r=await f.getAll();if(!r){n.json?console.log(JSON.stringify({loggedIn:!1,profile:o,server:e,defaults:s})):(console.log(`Profile: ${o}`),console.log(`Server: ${e}`),console.log("Not logged in"),console.log("Run `entrydesk login` to log in"));return}let t;if(r.workspaceId)try{let i=new p,I=await u(),{workspaces:w}=await i.getWorkspaces(I);t=w.find(S=>S.id===r.workspaceId)?.name}catch(i){if(i instanceof m){n.json?console.log(JSON.stringify({loggedIn:!1,profile:o,server:e,defaults:s})):(console.log(`Profile: ${o}`),console.log(`Server: ${e}`),console.log("Not logged in"),console.log("Run `entrydesk login` to log in"));return}}n.json?console.log(JSON.stringify({loggedIn:!0,authSource:"file",profile:o,server:e,email:r.email,workspaceId:r.workspaceId,workspaceName:t,defaults:s})):(console.log(`Profile: ${o}`),console.log(`Server: ${e}`),console.log(`Logged in as ${r.email}`),t&&console.log(`Workspace: ${t}`),r.workspaceId&&console.log(`Workspace ID: ${r.workspaceId}`))}catch(o){k(o)}}export{C as runStatus};
|