@entrydesk/cli 2.1.0-beta.2 → 2.1.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.
Files changed (91) hide show
  1. package/README.md +84 -12
  2. package/dist/{add-DXYghmJz.js → add-D4yZrlJH.js} +9 -1
  3. package/dist/{agents-Drg2ZD85.js → agents-3dOJzTmM.js} +9 -1
  4. package/dist/{billing-Bkk1BhAw.js → billing-Cyk-IzGv.js} +9 -1
  5. package/dist/{budget-dazpYOON.js → budget-znTQ0rkG.js} +9 -1
  6. package/dist/build-task-request-config-C62XneUL.js +10 -0
  7. package/dist/commands--5Ein-MI.js +10 -0
  8. package/dist/commands-D5BrzwFc.js +10 -0
  9. package/dist/{config-CSJx1Xlt.js → config-D-9dIy19.js} +9 -1
  10. package/dist/confirm-Ct432t3K.js +10 -0
  11. package/dist/connectors-B7smri5B.js +11 -0
  12. package/dist/{file-upload-BmP4AJY0.js → file-upload-D2s_clGk.js} +8 -0
  13. package/dist/{format-C3tQC6LL.js → format-DCvznP70.js} +8 -0
  14. package/dist/{hash-Ddmw8YE4.js → hash-CnSb1n2t.js} +8 -0
  15. package/dist/index.js +51 -16
  16. package/dist/{installer-iaoPJQn3.js → installer-CKB3jBE-.js} +8 -0
  17. package/dist/instruction-BzftVNfK.js +10 -0
  18. package/dist/isRecord-BNZWvqVS.js +10 -0
  19. package/dist/{login-ACaFCfsh.js → login-Ch3S9nh6.js} +9 -1
  20. package/dist/logout-BFFnjWjY.js +10 -0
  21. package/dist/{marketplace-S_4fkbWt.js → marketplace-DNm78dKX.js} +9 -1
  22. package/dist/mcp-D2zejorr.js +11 -0
  23. package/dist/mcp-client-ltOwvE7T.js +10 -0
  24. package/dist/{meeting-BG76tnT9.js → meeting-BdLr54zK.js} +9 -1
  25. package/dist/message-utils-DiNLK_84.js +15 -0
  26. package/dist/{models-CkepW_-c.js → models-6WioEQKB.js} +9 -1
  27. package/dist/{notifications-BAMcYXhl.js → notifications-DIokyl4e.js} +9 -1
  28. package/dist/options-Dpxg1wT1.js +10 -0
  29. package/dist/paginate-C9ixtica.js +10 -0
  30. package/dist/paths-CZAS8cbS.js +10 -0
  31. package/dist/{profile-BzXbLYDw.js → profile-CWsA2P_O.js} +9 -1
  32. package/dist/profile-storage-CuiJZpFD.js +68 -0
  33. package/dist/{project-B9uLW5nn.js → project-c8F30d-Q.js} +9 -1
  34. package/dist/project-context-C0ozCzKH.js +10 -0
  35. package/dist/{project-governance-CwVlxGE2.js → project-governance-DRDjqvX8.js} +9 -1
  36. package/dist/{project-sources-BzMkopCj.js → project-sources-DFn7Tn7u.js} +9 -1
  37. package/dist/project-sources-write-Bz0lGCid.js +10 -0
  38. package/dist/{project-tasks-CnXLm061.js → project-tasks-DnOrMxr3.js} +9 -1
  39. package/dist/{push-DWIgzvqe.js → push-mojEdys2.js} +9 -1
  40. package/dist/{recordings-_HnTtukO.js → recordings-BbeRVH0H.js} +9 -1
  41. package/dist/remote-D3JMUBbh.js +10 -0
  42. package/dist/remove-BLF3muSH.js +10 -0
  43. package/dist/resolve-BoqGhxVK.js +14 -0
  44. package/dist/resource-grants-CtIINiDN.js +10 -0
  45. package/dist/{rolldown-runtime-CIdiawuB.js → rolldown-runtime-CiM6yMNq.js} +8 -0
  46. package/dist/{schedules-DACWrdY_.js → schedules-ec4cS2A0.js} +10 -2
  47. package/dist/skills-C0xCUb-M.js +10 -0
  48. package/dist/status-Bfh5hjTq.js +10 -0
  49. package/dist/status-DpYhlJPA.js +10 -0
  50. package/dist/stdin-B18x8pUF.js +10 -0
  51. package/dist/task-DfLoMsmZ.js +108 -0
  52. package/dist/tasks-Bl8A2HW6.js +22 -0
  53. package/dist/tasks-CA2QZ8rX.js +10 -0
  54. package/dist/tool-B8CuZYYb.js +17 -0
  55. package/dist/{update-D09UponU.js → update-BVBj3leV.js} +9 -1
  56. package/dist/{usage-Dibnsgtg.js → usage-CIhTZm98.js} +9 -1
  57. package/dist/{usage-audit-Be431Kj1.js → usage-audit-BUcbqdAc.js} +11 -3
  58. package/dist/version-C1OwBsCd.js +10 -0
  59. package/dist/workflow-DJSq8hY5.js +14 -0
  60. package/dist/{workspaces-rVOwf5zp.js → workspaces-BM_3Miqs.js} +9 -1
  61. package/package.json +15 -10
  62. package/dist/build-task-request-config-BDlX-M_P.js +0 -2
  63. package/dist/commands-DUKXJUfr.js +0 -2
  64. package/dist/commands-FVFeS1MV.js +0 -2
  65. package/dist/confirm-BrJZbaxf.js +0 -2
  66. package/dist/connectors-CHcopt49.js +0 -3
  67. package/dist/instruction-BXKEUplM.js +0 -2
  68. package/dist/logout-BX4YsOqw.js +0 -2
  69. package/dist/mcp-DOUHU2_Z.js +0 -3
  70. package/dist/mcp-client-LcmqajIh.js +0 -2
  71. package/dist/options-CgmngSTC.js +0 -2
  72. package/dist/paginate-DUu8qbek.js +0 -2
  73. package/dist/paths-DQh1PdjS.js +0 -2
  74. package/dist/profile-storage-DlaupNlV.js +0 -60
  75. package/dist/project-context-VlX5GZxr.js +0 -2
  76. package/dist/project-sources-write-D3WzWqet.js +0 -2
  77. package/dist/remote-nEFOyIM2.js +0 -2
  78. package/dist/remove-Cpen9pWn.js +0 -2
  79. package/dist/resolve-7OXPmNrX.js +0 -6
  80. package/dist/resource-grants-D-ImlByb.js +0 -2
  81. package/dist/skills-BenhDHKq.js +0 -2
  82. package/dist/status-BKd81bGK.js +0 -2
  83. package/dist/status-ErhWpQxW.js +0 -2
  84. package/dist/stdin-DzzLUF6W.js +0 -2
  85. package/dist/task-CvQD8Y4d.js +0 -104
  86. package/dist/tasks-C4dAgHmR.js +0 -2
  87. package/dist/tasks-CnncSIan.js +0 -14
  88. package/dist/terminal-text-D04u1hg1.js +0 -2
  89. package/dist/tool-CpSoLUlR.js +0 -5
  90. package/dist/version-BTqAbDeB.js +0 -2
  91. package/dist/workflow-Dx41WM43.js +0 -6
package/README.md CHANGED
@@ -5,6 +5,11 @@ rendering, and scripting-friendly JSON output.
5
5
 
6
6
  ## Installation
7
7
 
8
+ Requires **Node.js 24 or newer** (`engines.node` in `package.json` is the source
9
+ of truth; it tracks the monorepo root). On an older Node the CLI refuses to run
10
+ and says which version it needs, rather than starting and then failing
11
+ mid-command.
12
+
8
13
  ```bash
9
14
  npm install -g @entrydesk/cli
10
15
  ```
@@ -279,6 +284,7 @@ The `sources-*` commands maintain that list the way the Hub's Sources tab does
279
284
  entrydesk project sources-add 1 ./brief.pdf --description "The launch brief"
280
285
  entrydesk project sources-add 1 https://example.com/spec
281
286
  entrydesk project sources-edit 1 file <fileId> --description "Signed-off scope"
287
+ entrydesk project sources-edit 1 file <fileId> --title "Launch brief" # How the AI names it
282
288
  entrydesk project sources-refetch 1 <linkId> # Snapshot goes back to pending
283
289
  entrydesk project sources-rm 1 link <linkId>
284
290
  ```
@@ -310,16 +316,24 @@ their reason on stderr and exit non-zero. With `--json` that reason is the
310
316
  `{ "status": … }` object from the API — `download` with a short-lived
311
317
  `downloadUrl`, `pending`, or `failed` with the error — again on stderr.
312
318
 
313
- A read that is cut short says so on stderr too, never on stdout, and names the
314
- `--offset` to resume from where the source can be paged. With `--json` the same
315
- facts are the `truncated` and `nextOffset` fields of the object on stdout.
316
- `--offset` implies `--full`, since a summary is not paged and an offset against
317
- one means nothing — resuming needs only the offset the previous read reported.
319
+ A long source comes back one capped page at a time. A read that is cut short
320
+ says so on stderr, never on stdout, and names the `--offset` to continue from;
321
+ with `--json` the same facts are the `truncated` and `nextOffset` fields of the
322
+ object on stdout. Repeat with the reported offset until the read is no longer
323
+ truncated — only ever pass back what the server reported:
324
+
325
+ ```bash
326
+ entrydesk project context-read 1 file <fileId> > brief.md
327
+ entrydesk project context-read 1 file <fileId> --offset 50000 --revision <rev> >> brief.md
328
+ ```
318
329
 
319
- Both depths are a task's: a file or a link snapshot has one, and the server
320
- serves its stored text up to a fixed cap whether or not you pass `--full`. That
321
- is why a truncated one reports no offset to resume from — it says it was cut
322
- short and there is nothing further to ask for.
330
+ What the offset counts depends on the source. For a task it is the number of
331
+ newest messages to skip, so `--offset` implies `--full` — a summary is not
332
+ paged. A file or a link snapshot has one depth, `--full` changes nothing, and
333
+ the offset is a position in its stored text. It comes with a `--revision`
334
+ naming the stored text it was measured against: a snapshot refetched between
335
+ two pages fails the next read instead of quietly serving new bytes at the old
336
+ offset, so start again from the beginning when that happens.
323
337
 
324
338
  ### Governance
325
339
 
@@ -377,14 +391,57 @@ to be issued with them.
377
391
  ## Tools
378
392
 
379
393
  ```bash
380
- entrydesk tool list # List all available tools
381
- entrydesk tool list --prefix agent # Filter by tool prefix
382
- entrydesk tool get agent__search_agents # Show a tool's details
394
+ entrydesk tool search "send a group chat message" --json
395
+ entrydesk tool search "read a spreadsheet" --namespace google_drive --json
396
+ entrydesk tool list # List directly exposed tools
397
+ entrydesk tool list --prefix agent # Filter the direct list by prefix
398
+ entrydesk tool get agent__search_agents --json # Get the input schema
383
399
  entrydesk tool call agent__search_agents --input '{"limit": 5}'
384
400
  entrydesk tool call agent__search_agents --input-file input.json
385
401
  echo '{"limit": 5}' | entrydesk tool call agent__search_agents
386
402
  ```
387
403
 
404
+ `tool list` is the server's direct tool list, not a complete connector catalog.
405
+ Connector tools can be discovered and called even when they are absent from this
406
+ list. Use `tool search` with an English description of the operation, including
407
+ the service name when known. `--namespace` restricts connector discovery to exact
408
+ namespaces copied from previous results; omit it when you do not know them.
409
+
410
+ If you already know the exact name, `tool get <name> --json` retrieves its input
411
+ schema, including for tools absent from the direct list. Read the schema, prepare
412
+ JSON in a file, then use `tool call <name> --input-file input.json --json` in your
413
+ script. The file or stdin keeps message bodies and other source text out of shell
414
+ quoting. Run `entrydesk tool call --help` for input options.
415
+
416
+ `list --json` returns an array, `get --json` returns a tool object, and
417
+ `call --json` returns the MCP result. `search --json` returns the discovery object
418
+ with `primaryTools`, optional `relatedTools`, `toolSchemas`, `authStatuses`, and
419
+ `error`. Search matches are not an exhaustive list. Check `authStatuses` before
420
+ calling a connector that needs authorization.
421
+
422
+ Discovery errors use `TOOL_DISCOVERY_FAILED`, preserving the server's explanation.
423
+ If lookup returns no schema, the CLI suggests checking the name and connector
424
+ connection: the server may report a name missing when its connector is unavailable,
425
+ so that response does not prove the tool does not exist.
426
+ Errors go to stderr with exit status 1. A partially failed search still writes its
427
+ results to stdout and exits with status 1, so scripts can retain successful matches
428
+ without treating the search as complete. JSON stdout contains no help text.
429
+
430
+ ### Updating the sandbox CLI
431
+
432
+ The CLI in a sandbox comes from its image, independently of the API release.
433
+ After publishing a CLI version containing these commands, update the exact
434
+ `@entrydesk/cli` pin in both `apps/entrydesk/sandbox/Dockerfile` and
435
+ `apps/entrydesk/sandbox/Dockerfile.gke`, then rebuild and release the affected
436
+ sandbox images. If an environment still uses E2B, update its separate template
437
+ as well. Do not pin an unpublished version.
438
+
439
+ Verify a fresh sandbox with `entrydesk --version`, `entrydesk tool call --help`,
440
+ and `entrydesk tool search --help`. Against the target workspace, use a known
441
+ connector tool name absent from `tool list` and confirm `tool get <name> --json`
442
+ returns its schema. These checks do not execute the connector operation. Existing
443
+ sandboxes may retain their old CLI until they are recreated.
444
+
388
445
  ## MCP Server
389
446
 
390
447
  ```bash
@@ -511,6 +568,21 @@ entrydesk config set hubUrl http://localhost:3000
511
568
  entrydesk config unset apiUrl
512
569
  ```
513
570
 
571
+ When only `hubUrl` is set, the CLI asks that Hub where its API lives
572
+ (`GET <hubUrl>/.well-known/entrydesk/client`) the first time a command sends an
573
+ API request, and caches the answer per Hub in `~/.entrydesk/hub-discovery.json`
574
+ for five minutes; the profile config is left untouched. Commands that never
575
+ call the API (`config`, `profile`, `version`) do not contact the Hub, and
576
+ `entrydesk status` shows the API as resolved on first request until then.
577
+ `entrydesk logout` does reach the API to revoke the session, so it resolves
578
+ the URL, and it clears the local credentials either way.
579
+ `ENTRYDESK_API_URL` and a configured `apiUrl` both take precedence and skip
580
+ discovery. If a Hub has no discovery endpoint, the CLI falls back to the
581
+ matching API for `app.entrydesk.com`, `entrydesk.dcard.io` and `stage.gntc.io`,
582
+ and fails the request with an error for any other Hub instead of sending it to
583
+ the production API — set `apiUrl` explicitly in that case. With neither URL
584
+ set, the CLI uses `https://app.entrydesk.com` and `https://api.entrydesk.com`.
585
+
514
586
  ### Running Against a Local API
515
587
 
516
588
  Point the CLI at a locally running API for one command, or persist it in the
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{E as e}from"./profile-storage-DlaupNlV.js";import{a as t,d as n,f as r,g as i,i as a,r as o}from"./paths-DQh1PdjS.js";import{t as s}from"./hash-Ddmw8YE4.js";import{r as c}from"./installer-iaoPJQn3.js";import{t as l}from"./remote-nEFOyIM2.js";import u from"node:fs";import d from"node:os";import f from"node:path";import p from"cross-spawn";function m(e,t){let n=f.dirname(e);u.mkdirSync(n,{recursive:!0});let r=u.mkdtempSync(f.join(n,`.${f.basename(e)}.tmp-`)),i=f.join(r,`next`),a=f.join(r,`prev`);u.mkdirSync(i,{recursive:!0});let o=!1;try{t(i),u.existsSync(e)&&(u.renameSync(e,a),o=!0),u.renameSync(i,e)}catch(t){throw o&&!u.existsSync(e)&&u.renameSync(a,e),t}finally{u.rmSync(r,{recursive:!0,force:!0})}}const h=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu,g=/^([\w.-]+)\/([\w.-]+)(?:\/(.+))?$/u;function _(e){return e===`~`?d.homedir():e.startsWith(`~/`)||e.startsWith(`~\\`)?f.join(d.homedir(),e.slice(2)):e}function v(e){return e.startsWith(`./`)||e.startsWith(`../`)||e.startsWith(`/`)||e.startsWith(`~`)||e.startsWith(`.\\`)||/^[a-zA-Z]:[\\/]/u.test(e)}function y(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 b(e){let t=e.trim();if(v(t))return{type:`local`,path:f.resolve(_(t))};if(t.startsWith(`ed:`)){let e=t.slice(3);return{type:`entrydesk`,ref:e,isId:h.test(e)}}if(h.test(t))return{type:`entrydesk`,ref:t,isId:!0};if(t.startsWith(`git@`)||t.endsWith(`.git`))return{type:`git`,url:t};let n=y(t);if(n)return n;if(/^https?:\/\//u.test(t))return{type:`git`,url:t};let r=g.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 x(e){return e.type===`github`?`github`:e.type}const S=new Set([`.git`,`node_modules`,`__pycache__`,`.DS_Store`,`.entrydesk`]);function C(e,t){if(!u.existsSync(f.join(e,`SKILL.md`)))throw Error(`No SKILL.md found at ${e}`);let n=u.realpathSync(e);if(n===(u.existsSync(t)?u.realpathSync(t):f.resolve(t)))return;let r=u.mkdtempSync(f.join(d.tmpdir(),`ed-local-skill-`)),i=f.join(r,`skill`);try{u.cpSync(n,i,{recursive:!0,filter:e=>!S.has(f.basename(e))}),m(t,e=>{u.cpSync(i,e,{recursive:!0})})}finally{u.rmSync(r,{recursive:!0,force:!0})}}function w(e){try{let t=u.readFileSync(f.join(e,`SKILL.md`),`utf8`),n=/^name:\s*(.+?)\s*$/mu.exec(t.split(/^---\s*$/mu)[1]??``);if(n?.[1])return n[1].replace(/^['"]|['"]$/gu,``)}catch{}return f.basename(e)}async function T(e,t){let{default:n}=await import(`adm-zip`),r=new n(e);m(t,e=>{let t=f.resolve(e)+f.sep;for(let n of r.getEntries()){if(n.isDirectory)continue;let r=f.resolve(e,n.entryName);if(!r.startsWith(t))throw Error(`Zip entry contains path traversal: ${n.entryName}`);u.mkdirSync(f.dirname(r),{recursive:!0}),u.writeFileSync(r,n.getData())}})}async function E(e,t){if(t.isId)return t.ref;let n=(await l(e.client,e.accessToken,e.workspaceId)).find(e=>e.name===t.ref||e.id===t.ref);if(!n)throw Error(`Skill not found in workspace: ${t.ref}`);return n.id}function D(e,t,n){let r=u.mkdtempSync(f.join(d.tmpdir(),`ed-npx-skills-`)),i=[`-y`,`skills@1.5.12`,`add`,e,`--copy`,`--yes`];try{let e=p.sync(`npx`,i,{cwd:r,stdio:n?[`ignore`,`pipe`,`pipe`]:`inherit`});if(e.error)throw e.error;if(e.status!==0){let t=e.stderr?.toString().trim();throw Error(`npx exited with code ${e.status??`null`}${t?`: ${t}`:``}`)}}catch(t){throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills failed for ${e}. Ensure npx + network are available. (${t instanceof Error?t.message:String(t)})`,{cause:t})}let a=f.join(r,`.agents`,`skills`);if(!u.existsSync(a))throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills produced no skills under ${a}`);let o=u.readdirSync(a,{withFileTypes:!0}).filter(e=>e.isDirectory());if(o.length===0)throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills installed no skill directory`);let s=o[0];if(o.length>1){let e=t.type===`github`&&t.subpath?f.basename(t.subpath):void 0,n=e?o.find(t=>t.name===e):void 0;if(!n)throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills installed [${o.map(e=>e.name).join(`, `)}]; ${e?`none matched the subpath "${e}"`:`specify a subpath to pick one`}.`);s=n}return{dir:f.join(a,s.name),tmpRoot:r}}async function O(l,d,f){let p=b(l),m=!!d.global,h=a(m,f.workspaceId),g=h.rootDir,_={...f,workspaceId:h.workspaceId};if(!h.linked){let i={workspaceId:f.workspaceId,apiUrl:e()};t(),m?n(i):r(process.cwd(),i)}let v,y,S;if(p.type===`entrydesk`){y=await E(_,p);let e=await _.client.downloadSkillCurrent(_.accessToken,_.workspaceId,y);v=e.name,S=o(g,v);let t=await fetch(e.url);if(!t.ok)throw Error(`Failed to download ${v}: ${t.status}`);await T(Buffer.from(await t.arrayBuffer()),S)}else if(p.type===`local`)v=w(p.path),S=o(g,v),C(p.path,S);else{let{dir:e,tmpRoot:t}=D(l,p,!!d.json);try{v=w(e),S=o(g,v),C(e,S)}finally{u.rmSync(t,{recursive:!0,force:!0})}}let O=s(S),k={source:l,sourceType:x(p),skillId:y,localHash:O,lastPulledHash:p.type===`entrydesk`?O:``,mode:`symlink`,...p.type===`github`?{sourceUrl:p.url,ref:p.gitRef,subpath:p.subpath}:{},...p.type===`git`?{sourceUrl:p.url}:{}};i(g,v,k);let A=c(S,v,g,`symlink`,d.agent);d.json?console.info(JSON.stringify({name:v,sourceType:x(p),hash:O},null,2)):console.info(`✓ added ${v} (${p.type}, ${O.slice(0,12)}) → agents: ${A.map(e=>e.agentId).join(`, `)}`)}export{O as runSkillsAdd};
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{M as e}from"./profile-storage-CuiJZpFD.js";import{a as t,d as n,f as r,g as i,i as a,r as o}from"./paths-CZAS8cbS.js";import{t as s}from"./hash-CnSb1n2t.js";import{r as c}from"./installer-CKB3jBE-.js";import{t as l}from"./remote-D3JMUBbh.js";import u from"node:fs";import d from"node:os";import f from"node:path";import p from"cross-spawn";function m(e,t){let n=f.dirname(e);u.mkdirSync(n,{recursive:!0});let r=u.mkdtempSync(f.join(n,`.${f.basename(e)}.tmp-`)),i=f.join(r,`next`),a=f.join(r,`prev`);u.mkdirSync(i,{recursive:!0});let o=!1;try{t(i),u.existsSync(e)&&(u.renameSync(e,a),o=!0),u.renameSync(i,e)}catch(t){throw o&&!u.existsSync(e)&&u.renameSync(a,e),t}finally{u.rmSync(r,{recursive:!0,force:!0})}}const h=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu,g=/^([\w.-]+)\/([\w.-]+)(?:\/(.+))?$/u;function _(e){return e===`~`?d.homedir():e.startsWith(`~/`)||e.startsWith(`~\\`)?f.join(d.homedir(),e.slice(2)):e}function v(e){return e.startsWith(`./`)||e.startsWith(`../`)||e.startsWith(`/`)||e.startsWith(`~`)||e.startsWith(`.\\`)||/^[a-zA-Z]:[\\/]/u.test(e)}function y(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 b(e){let t=e.trim();if(v(t))return{type:`local`,path:f.resolve(_(t))};if(t.startsWith(`ed:`)){let e=t.slice(3);return{type:`entrydesk`,ref:e,isId:h.test(e)}}if(h.test(t))return{type:`entrydesk`,ref:t,isId:!0};if(t.startsWith(`git@`)||t.endsWith(`.git`))return{type:`git`,url:t};let n=y(t);if(n)return n;if(/^https?:\/\//u.test(t))return{type:`git`,url:t};let r=g.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 x(e){return e.type===`github`?`github`:e.type}const S=new Set([`.git`,`node_modules`,`__pycache__`,`.DS_Store`,`.entrydesk`]);function C(e,t){if(!u.existsSync(f.join(e,`SKILL.md`)))throw Error(`No SKILL.md found at ${e}`);let n=u.realpathSync(e);if(n===(u.existsSync(t)?u.realpathSync(t):f.resolve(t)))return;let r=u.mkdtempSync(f.join(d.tmpdir(),`ed-local-skill-`)),i=f.join(r,`skill`);try{u.cpSync(n,i,{recursive:!0,filter:e=>!S.has(f.basename(e))}),m(t,e=>{u.cpSync(i,e,{recursive:!0})})}finally{u.rmSync(r,{recursive:!0,force:!0})}}function w(e){try{let t=u.readFileSync(f.join(e,`SKILL.md`),`utf8`),n=/^name:\s*(.+?)\s*$/mu.exec(t.split(/^---\s*$/mu)[1]??``);if(n?.[1])return n[1].replace(/^['"]|['"]$/gu,``)}catch{}return f.basename(e)}async function T(e,t){let{default:n}=await import(`adm-zip`),r=new n(e);m(t,e=>{let t=f.resolve(e)+f.sep;for(let n of r.getEntries()){if(n.isDirectory)continue;let r=f.resolve(e,n.entryName);if(!r.startsWith(t))throw Error(`Zip entry contains path traversal: ${n.entryName}`);u.mkdirSync(f.dirname(r),{recursive:!0}),u.writeFileSync(r,n.getData())}})}async function E(e,t){if(t.isId)return t.ref;let n=(await l(e.client,e.accessToken,e.workspaceId)).find(e=>e.name===t.ref||e.id===t.ref);if(!n)throw Error(`Skill not found in workspace: ${t.ref}`);return n.id}function D(e,t,n){let r=u.mkdtempSync(f.join(d.tmpdir(),`ed-npx-skills-`)),i=[`-y`,`skills@1.5.12`,`add`,e,`--copy`,`--yes`];try{let e=p.sync(`npx`,i,{cwd:r,stdio:n?[`ignore`,`pipe`,`pipe`]:`inherit`});if(e.error)throw e.error;if(e.status!==0){let t=e.stderr?.toString().trim();throw Error(`npx exited with code ${e.status??`null`}${t?`: ${t}`:``}`)}}catch(t){throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills failed for ${e}. Ensure npx + network are available. (${t instanceof Error?t.message:String(t)})`,{cause:t})}let a=f.join(r,`.agents`,`skills`);if(!u.existsSync(a))throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills produced no skills under ${a}`);let o=u.readdirSync(a,{withFileTypes:!0}).filter(e=>e.isDirectory());if(o.length===0)throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills installed no skill directory`);let s=o[0];if(o.length>1){let e=t.type===`github`&&t.subpath?f.basename(t.subpath):void 0,n=e?o.find(t=>t.name===e):void 0;if(!n)throw u.rmSync(r,{recursive:!0,force:!0}),Error(`npx skills installed [${o.map(e=>e.name).join(`, `)}]; ${e?`none matched the subpath "${e}"`:`specify a subpath to pick one`}.`);s=n}return{dir:f.join(a,s.name),tmpRoot:r}}async function O(l,d,f){let p=b(l),m=!!d.global,h=await a(m,f.workspaceId),g=h.rootDir,_={...f,workspaceId:h.workspaceId};if(!h.linked){let i={workspaceId:f.workspaceId,apiUrl:await e()};t(),m?n(i):r(process.cwd(),i)}let v,y,S;if(p.type===`entrydesk`){y=await E(_,p);let e=await _.client.downloadSkillCurrent(_.accessToken,_.workspaceId,y);v=e.name,S=o(g,v);let t=await fetch(e.url);if(!t.ok)throw Error(`Failed to download ${v}: ${t.status}`);await T(Buffer.from(await t.arrayBuffer()),S)}else if(p.type===`local`)v=w(p.path),S=o(g,v),C(p.path,S);else{let{dir:e,tmpRoot:t}=D(l,p,!!d.json);try{v=w(e),S=o(g,v),C(e,S)}finally{u.rmSync(t,{recursive:!0,force:!0})}}let O=s(S),k={source:l,sourceType:x(p),skillId:y,localHash:O,lastPulledHash:p.type===`entrydesk`?O:``,mode:`symlink`,...p.type===`github`?{sourceUrl:p.url,ref:p.gitRef,subpath:p.subpath}:{},...p.type===`git`?{sourceUrl:p.url}:{}};i(g,v,k);let A=c(S,v,g,`symlink`,d.agent);d.json?console.info(JSON.stringify({name:v,sourceType:x(p),hash:O},null,2)):console.info(`✓ added ${v} (${p.type}, ${O.slice(0,12)}) → agents: ${A.map(e=>e.agentId).join(`, `)}`)}export{O as runSkillsAdd};
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{At as e,Nt as t,Pt as n,at as r,b as i,u as a}from"./profile-storage-DlaupNlV.js";import{t as o}from"./resource-grants-D-ImlByb.js";function s(t){return t?n([...new Set(t)]):e}function c(e){console.log(`Available agents (${e.length}):\n`);for(let t of e){if(console.log(` ${t.name} (${t.visibility})`),t.description){let e=t.description.length>80?`${t.description.slice(0,80)}…`:t.description;console.log(` ${e}`)}console.log(` ID: ${t.id}`),console.log(``)}}function l(e){console.log(`My agents (${e.length}):\n`);for(let t of e){let e=[];t.latestVersionNumber!=null&&e.push(`v${t.latestVersionNumber}`),t.hasUnpublishedChanges&&e.push(`unpublished changes`);let n=e.length>0?` (${e.join(` · `)})`:``;if(console.log(` ${t.name}${n}`),t.description){let e=t.description.length>80?`${t.description.slice(0,80)}…`:t.description;console.log(` ${e}`)}console.log(` ${t.myRole??`no-role`} · ID: ${t.id}`),console.log(``)}}function u(e){if(console.log(`${e.name}\n`),console.log(` ID: ${e.id}`),e.visibility&&console.log(` Visibility: ${e.visibility}`),e.model&&console.log(` Model: ${e.model.name}`),e.author&&console.log(` Author: ${e.author.name}${e.author.isMe?` (you)`:``}`),e.description&&console.log(` Description: ${e.description}`),e.capabilities){let n=t(e.capabilities).map(e=>r(e));n.length>0&&console.log(` Capabilities: ${n.join(`, `)}`)}e.connectors&&e.connectors.length>0&&console.log(` Connectors: ${e.connectors.map(e=>e.name).join(`, `)}`),e.tools&&e.tools.length>0&&console.log(` Tools: ${e.tools.length}`),e.conversationStarters&&e.conversationStarters.length>0&&console.log(` Starters: ${e.conversationStarters.length}`),e.systemPrompt&&console.log(`\n System prompt:\n${e.systemPrompt}`)}async function d(e){let{accessToken:t,workspaceId:n}=await a(),r=new i;if(e.mine){let i=[],a=e.all?void 0:e.nextKey;for(let o=0;;o++){o>=100&&(console.error(`Reached maximum page limit (100). Use --limit and --next-key for manual pagination.`),process.exit(1));let s=await r.getMyAgents(t,n,{limit:e.limit,nextKey:a});if(i.push(...s.agents),a=s.nextKey,!e.all||!a)break}if(e.json){console.log(JSON.stringify({agents:i,nextKey:a}));return}if(i.length===0){console.log("You own no agents in this workspace. Create one with `entrydesk agents create --name <name> …`, or browse `entrydesk marketplace`.");return}l(i),!e.all&&a&&console.log(`Next page: --next-key ${a}`);return}if(e.all){let i=[],a;for(let o=0;;o++){o>=100&&(console.error(`Reached maximum page limit (100). Use --limit and --next-key for manual pagination.`),process.exit(1));let s=await r.getAgents(t,n,{limit:e.limit??100,nextKey:a});if(i.push(...s.agents),a=s.nextKey,!a)break}if(e.json){console.log(JSON.stringify({agents:i}));return}if(i.length===0){console.log("No agents in this workspace yet. Create one with `entrydesk agents create`, or browse `entrydesk marketplace`.");return}c(i);return}let{agents:o,nextKey:s}=await r.getAgents(t,n,{limit:e.limit,nextKey:e.nextKey});if(e.json){console.log(JSON.stringify({agents:o,nextKey:s}));return}if(o.length===0){console.log("No agents in this workspace yet. Create one with `entrydesk agents create`, or browse `entrydesk marketplace`.");return}c(o),s&&console.log(`Next page: --next-key ${s}`)}async function f(e,t){let{accessToken:n,workspaceId:r}=await a(),o=await new i().getAgent(n,r,e);if(t.json){console.log(JSON.stringify(o));return}u(o)}async function p(e){let{accessToken:t,workspaceId:n}=await a(),r=await new i().createAgent(t,n,{name:e.name,description:e.description,systemPrompt:e.systemPrompt,modelId:e.modelId,connectorIds:e.connectorIds??[],capabilities:s(e.capabilities),conversationStarters:e.conversationStarters??[],tools:e.tools,iconId:e.iconId});if(e.json){console.log(JSON.stringify(r));return}console.log(`Created agent: ${r.name}`),console.log(` ID: ${r.id}`)}async function m(e,t){let{accessToken:n,workspaceId:r}=await a(),o=new i,c=await o.getAgent(n,r,e),l={name:t.name??c.name,description:t.description??c.description,systemPrompt:t.systemPrompt??c.systemPrompt??``,modelId:t.modelId??c.model?.id??``,connectorIds:t.connectorIds??c.connectors?.map(e=>e.id)??[],capabilities:t.capabilities?s(t.capabilities):c.capabilities??{},conversationStarters:t.conversationStarters??c.conversationStarters??[],tools:t.tools??c.tools??[],iconId:t.iconId??c.iconId};await o.updateAgent(n,r,e,l),console.log(`Updated agent: ${e}`)}async function h(e){let{accessToken:t,workspaceId:n}=await a();await new i().deleteAgent(t,n,e),console.log(`Deleted agent: ${e}`)}async function g(e,t){let{accessToken:n,workspaceId:r}=await a();if(await new i().publishAgent(n,r,e),t.json){console.log(JSON.stringify({id:e,published:!0}));return}console.log(`Published agent to the workspace: ${e}`)}async function _(e,t){let{accessToken:n,workspaceId:r}=await a(),s=new i;if(t.addUser){let i=await s.upsertAgentGrant(n,r,e,t.addUser,t.role);if(t.json){console.log(JSON.stringify(i));return}console.log(`Granted ${t.role} to user ${t.addUser}`);return}if(t.removeUser){if(await s.removeAgentGrant(n,r,e,t.removeUser),t.json){console.log(JSON.stringify({userId:t.removeUser,removed:!0}));return}console.log(`Revoked access for user ${t.removeUser}`);return}let c=await s.getAgentGrants(n,r,e);if(t.json){console.log(JSON.stringify(c));return}o(c)}export{p as createAgent,h as deleteAgent,d as listAgents,g as publishAgent,_ as shareAgent,f as showAgent,m as updateAgent};
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{Mt as e,Ot as t,b as n,dt as r,jt as i,u as a}from"./profile-storage-CuiJZpFD.js";import{t as o}from"./resource-grants-CtIINiDN.js";function s(n){return n?e([...new Set(n)]):t}function c(e){console.log(`Available agents (${e.length}):\n`);for(let t of e){if(console.log(` ${t.name} (${t.visibility})`),t.description){let e=t.description.length>80?`${t.description.slice(0,80)}…`:t.description;console.log(` ${e}`)}console.log(` ID: ${t.id}`),console.log(``)}}function l(e){console.log(`My agents (${e.length}):\n`);for(let t of e){let e=[];t.latestVersionNumber!=null&&e.push(`v${t.latestVersionNumber}`),t.hasUnpublishedChanges&&e.push(`unpublished changes`);let n=e.length>0?` (${e.join(` · `)})`:``;if(console.log(` ${t.name}${n}`),t.description){let e=t.description.length>80?`${t.description.slice(0,80)}…`:t.description;console.log(` ${e}`)}console.log(` ${t.myRole??`no-role`} · ID: ${t.id}`),console.log(``)}}function u(e){if(console.log(`${e.name}\n`),console.log(` ID: ${e.id}`),e.visibility&&console.log(` Visibility: ${e.visibility}`),e.model&&console.log(` Model: ${e.model.name}`),e.author&&console.log(` Author: ${e.author.name}${e.author.isMe?` (you)`:``}`),e.description&&console.log(` Description: ${e.description}`),e.capabilities){let t=i(e.capabilities).map(e=>r(e));t.length>0&&console.log(` Capabilities: ${t.join(`, `)}`)}e.connectors&&e.connectors.length>0&&console.log(` Connectors: ${e.connectors.map(e=>e.name).join(`, `)}`),e.tools&&e.tools.length>0&&console.log(` Tools: ${e.tools.length}`),e.conversationStarters&&e.conversationStarters.length>0&&console.log(` Starters: ${e.conversationStarters.length}`),e.systemPrompt&&console.log(`\n System prompt:\n${e.systemPrompt}`)}async function d(e){let{accessToken:t,workspaceId:r}=await a(),i=new n;if(e.mine){let n=[],a=e.all?void 0:e.nextKey;for(let o=0;;o++){o>=100&&(console.error(`Reached maximum page limit (100). Use --limit and --next-key for manual pagination.`),process.exit(1));let s=await i.getMyAgents(t,r,{limit:e.limit,nextKey:a});if(n.push(...s.agents),a=s.nextKey,!e.all||!a)break}if(e.json){console.log(JSON.stringify({agents:n,nextKey:a}));return}if(n.length===0){console.log("You own no agents in this workspace. Create one with `entrydesk agents create --name <name> …`, or browse `entrydesk marketplace`.");return}l(n),!e.all&&a&&console.log(`Next page: --next-key ${a}`);return}if(e.all){let n=[],a;for(let o=0;;o++){o>=100&&(console.error(`Reached maximum page limit (100). Use --limit and --next-key for manual pagination.`),process.exit(1));let s=await i.getAgents(t,r,{limit:e.limit??100,nextKey:a});if(n.push(...s.agents),a=s.nextKey,!a)break}if(e.json){console.log(JSON.stringify({agents:n}));return}if(n.length===0){console.log("No agents in this workspace yet. Create one with `entrydesk agents create`, or browse `entrydesk marketplace`.");return}c(n);return}let{agents:o,nextKey:s}=await i.getAgents(t,r,{limit:e.limit,nextKey:e.nextKey});if(e.json){console.log(JSON.stringify({agents:o,nextKey:s}));return}if(o.length===0){console.log("No agents in this workspace yet. Create one with `entrydesk agents create`, or browse `entrydesk marketplace`.");return}c(o),s&&console.log(`Next page: --next-key ${s}`)}async function f(e,t){let{accessToken:r,workspaceId:i}=await a(),o=await new n().getAgent(r,i,e);if(t.json){console.log(JSON.stringify(o));return}u(o)}async function p(e){let{accessToken:t,workspaceId:r}=await a(),i=await new n().createAgent(t,r,{name:e.name,description:e.description,systemPrompt:e.systemPrompt,modelId:e.modelId,connectorIds:e.connectorIds??[],capabilities:s(e.capabilities),conversationStarters:e.conversationStarters??[],tools:e.tools,iconId:e.iconId});if(e.json){console.log(JSON.stringify(i));return}console.log(`Created agent: ${i.name}`),console.log(` ID: ${i.id}`)}async function m(e,t){let{accessToken:r,workspaceId:i}=await a(),o=new n,c=await o.getAgent(r,i,e),l={name:t.name??c.name,description:t.description??c.description,systemPrompt:t.systemPrompt??c.systemPrompt??``,modelId:t.modelId??c.model?.id??``,connectorIds:t.connectorIds??c.connectors?.map(e=>e.id)??[],capabilities:t.capabilities?s(t.capabilities):c.capabilities??{},conversationStarters:t.conversationStarters??c.conversationStarters??[],tools:t.tools??c.tools??[],iconId:t.iconId??c.iconId};await o.updateAgent(r,i,e,l),console.log(`Updated agent: ${e}`)}async function h(e){let{accessToken:t,workspaceId:r}=await a();await new n().deleteAgent(t,r,e),console.log(`Deleted agent: ${e}`)}async function g(e,t){let{accessToken:r,workspaceId:i}=await a();if(await new n().publishAgent(r,i,e),t.json){console.log(JSON.stringify({id:e,published:!0}));return}console.log(`Published agent to the workspace: ${e}`)}async function _(e,t){let{accessToken:r,workspaceId:i}=await a(),s=new n;if(t.addUser){let n=await s.upsertAgentGrant(r,i,e,t.addUser,t.role);if(t.json){console.log(JSON.stringify(n));return}console.log(`Granted ${t.role} to user ${t.addUser}`);return}if(t.removeUser){if(await s.removeAgentGrant(r,i,e,t.removeUser),t.json){console.log(JSON.stringify({userId:t.removeUser,removed:!0}));return}console.log(`Revoked access for user ${t.removeUser}`);return}let c=await s.getAgentGrants(r,i,e);if(t.json){console.log(JSON.stringify(c));return}o(c)}export{p as createAgent,h as deleteAgent,d as listAgents,g as publishAgent,_ as shareAgent,f as showAgent,m as updateAgent};
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{b as e,u as t,v as n}from"./profile-storage-DlaupNlV.js";import{r}from"./format-C3tQC6LL.js";import{t as i}from"./paginate-DUu8qbek.js";function a(e){if(console.log(`Billing status: ${e.lifecycle.kind}`),e.subscription){let t=e.subscription,n=t.nextInvoiceDueAt?` · next invoice ${new Date(t.nextInvoiceDueAt).toLocaleDateString()}`:``;console.log(` Plan: ${t.planName} · ~${r(t.estimatedMonthlyChargeUsd)}/month${n}`)}else console.log(` Plan: (no active subscription)`);let t=e.seats;console.log(` Seats: pro ${t.assigned.pro}/${t.purchased.pro}, premium ${t.assigned.premium}/${t.purchased.premium} (assigned/purchased)`);let n=e.extraUsage;console.log(` Balance: ${r(n.balanceUsd)} extra usage`),console.log(` Spent: ${r(n.currentSpentUsd)} this period`),n.monthlyExtraUsageLimitUsd!=null&&console.log(` Limit: ${r(n.monthlyExtraUsageLimitUsd)} / month`)}function o(e){console.log(`Invoices (${e.length}):\n`);for(let t of e){let e=new Date(t.billingDate).toLocaleDateString();console.log(` ${e} · ${t.type} · ${t.status} · ${r(t.totalUsd)}`),t.hostedInvoiceUrl&&console.log(` ${t.hostedInvoiceUrl}`),console.log(` ID: ${t.id}`),console.log(``)}}async function s(){return n()&&(console.error("Billing requires an interactive login. A workspace PAT (ENTRYDESK_TOKEN) cannot read billing — run `entrydesk login`."),process.exit(1)),t()}async function c(t){let{accessToken:n,workspaceId:r}=await s(),i=await new e().getBillingOverview(n,r);if(t.json){console.log(JSON.stringify(i));return}a(i)}async function l(t){let{accessToken:n,workspaceId:r}=await s(),a=new e;if(t.all){let e=await i(async e=>{let i=await a.getBillingInvoices(n,r,{limit:t.limit??20,nextKey:e});return{items:i.invoices,nextKey:i.nextKey}});if(t.json){console.log(JSON.stringify({invoices:e}));return}if(e.length===0){console.log(`No invoices.`);return}o(e);return}let{invoices:c,nextKey:l}=await a.getBillingInvoices(n,r,{limit:t.limit,nextKey:t.nextKey});if(t.json){console.log(JSON.stringify({invoices:c,nextKey:l}));return}if(c.length===0){console.log(`No invoices.`);return}o(c),l&&console.log(`Next page: --next-key ${l}`)}export{l as listInvoices,c as showBillingStatus};
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{b as e,u as t,v as n}from"./profile-storage-CuiJZpFD.js";import{r}from"./format-DCvznP70.js";import{t as i}from"./paginate-C9ixtica.js";function a(e){if(console.log(`Billing status: ${e.lifecycle.kind}`),e.subscription){let t=e.subscription,n=t.nextInvoiceDueAt?` · next invoice ${new Date(t.nextInvoiceDueAt).toLocaleDateString()}`:``;console.log(` Plan: ${t.planName} · ~${r(t.estimatedMonthlyChargeUsd)}/month${n}`)}else console.log(` Plan: (no active subscription)`);let t=e.seats;console.log(` Seats: pro ${t.assigned.pro}/${t.purchased.pro}, premium ${t.assigned.premium}/${t.purchased.premium} (assigned/purchased)`);let n=e.extraUsage;console.log(` Balance: ${r(n.balanceUsd)} extra usage`),console.log(` Spent: ${r(n.currentSpentUsd)} this period`),n.monthlyExtraUsageLimitUsd!=null&&console.log(` Limit: ${r(n.monthlyExtraUsageLimitUsd)} / month`)}function o(e){console.log(`Invoices (${e.length}):\n`);for(let t of e){let e=new Date(t.billingDate).toLocaleDateString();console.log(` ${e} · ${t.type} · ${t.status} · ${r(t.totalUsd)}`),t.hostedInvoiceUrl&&console.log(` ${t.hostedInvoiceUrl}`),console.log(` ID: ${t.id}`),console.log(``)}}async function s(){return n()&&(console.error("Billing requires an interactive login. A workspace PAT (ENTRYDESK_TOKEN) cannot read billing — run `entrydesk login`."),process.exit(1)),t()}async function c(t){let{accessToken:n,workspaceId:r}=await s(),i=await new e().getBillingOverview(n,r);if(t.json){console.log(JSON.stringify(i));return}a(i)}async function l(t){let{accessToken:n,workspaceId:r}=await s(),a=new e;if(t.all){let e=await i(async e=>{let i=await a.getBillingInvoices(n,r,{limit:t.limit??20,nextKey:e});return{items:i.invoices,nextKey:i.nextKey}});if(t.json){console.log(JSON.stringify({invoices:e}));return}if(e.length===0){console.log(`No invoices.`);return}o(e);return}let{invoices:c,nextKey:l}=await a.getBillingInvoices(n,r,{limit:t.limit,nextKey:t.nextKey});if(t.json){console.log(JSON.stringify({invoices:c,nextKey:l}));return}if(c.length===0){console.log(`No invoices.`);return}o(c),l&&console.log(`Next page: --next-key ${l}`)}export{l as listInvoices,c as showBillingStatus};
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{b as e,u as t}from"./profile-storage-DlaupNlV.js";async function n(n){let{accessToken:r,workspaceId:i}=await t(),a=await new e().getBudget(r,i);if(n.json){console.log(JSON.stringify(a));return}if(a.budget===null){console.log(`No budget set for this workspace.`);return}console.log(`Current workspace budget: $${a.budget}`)}async function r(n,r){let{accessToken:i,workspaceId:a}=await t(),o=new e;if(await o.updateBudget(i,a,n),r.json){console.log(JSON.stringify(await o.getBudget(i,a)));return}console.log(`Budget updated: $${n}`)}async function i(n){let{accessToken:r,workspaceId:i}=await t(),a=new e;if(await a.updateBudget(r,i,null),n.json){console.log(JSON.stringify(await a.getBudget(r,i)));return}console.log(`Budget cleared.`)}export{i as clearBudget,r as setBudget,n as showBudget};
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{b as e,u as t}from"./profile-storage-CuiJZpFD.js";async function n(n){let{accessToken:r,workspaceId:i}=await t(),a=await new e().getBudget(r,i);if(n.json){console.log(JSON.stringify(a));return}if(a.budget===null){console.log(`No budget set for this workspace.`);return}console.log(`Current workspace budget: $${a.budget}`)}async function r(n,r){let{accessToken:i,workspaceId:a}=await t(),o=new e;if(await o.updateBudget(i,a,n),r.json){console.log(JSON.stringify(await o.getBudget(i,a)));return}console.log(`Budget updated: $${n}`)}async function i(n){let{accessToken:r,workspaceId:i}=await t(),a=new e;if(await a.updateBudget(r,i,null),n.json){console.log(JSON.stringify(await a.getBudget(r,i)));return}console.log(`Budget cleared.`)}export{i as clearBudget,r as setBudget,n as showBudget};
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{lt as e,mt as t,pt as n,ut as r}from"./profile-storage-CuiJZpFD.js";function i({allowedTools:e,disallowedTools:r}){if(!(!e?.length&&!r?.length))return[...t(e?.map(e=>({toolName:e,policy:n.ALWAYS_ALLOW})),r?.map(e=>({toolName:e,policy:n.BLOCK})))].map(([e,t])=>({toolName:e,policy:t}))}function a(e,r){let i=[...r].map(e=>({toolName:e,policy:n.ALWAYS_ALLOW}));return i.length===0?e:[...t(e,i)].map(([e,t])=>({toolName:e,policy:t}))}function o({agentId:t,model:n,projectId:i,connectorIds:a,clientTools:o,clientToolSystemPrompt:s,toolApprovalMode:c,toolPolicies:l}){return{...i?{projectId:i}:{},...t?{agentId:t}:{...n?{model:n}:{},...a?.length?{connectorIds:a}:{}},...o?{clientTools:r(o,e.DIRECT)}:{},...s?{clientToolSystemPrompt:s}:{},...c?{toolApprovalMode:c}:{},...l?.length?{toolPolicies:l}:{}}}export{i as n,a as r,o as t};
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{M as e}from"./profile-storage-CuiJZpFD.js";import{a as t,c as n,d as r,f as i,g as a,i as o,l as s,m as c,o as l,r as u,s as d,u as f}from"./paths-CZAS8cbS.js";import{t as p}from"./hash-CnSb1n2t.js";import{r as m}from"./installer-CKB3jBE-.js";import h from"node:path";import g from"node:fs/promises";const _=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;async function v(a,o,s){let c=a&&_.test(a)?a:s.workspaceId,l={workspaceId:c,apiUrl:await e()};if(t(),o.global)r(l),console.info(`Linked ${d()} → workspace ${c}`);else{let e=process.cwd();i(e,l),console.info(`Linked ${n(e)} → workspace ${c}`)}}function y(e){if(e.global){s()?console.info(`Unlinked ${d()}`):console.info(`No global link found.`);return}let t=l(process.cwd());t&&f(t)?console.info(`Unlinked ${n(t)}`):console.info(`No project link found.`)}async function b(e,t,n,r,i){let o=n.skillId;if(!o){let{skills:t}=await e.client.listAvailableSkills(e.accessToken,e.workspaceId),r=t.find(e=>e.name===n.name);if(!r)throw Error(`Skill not found in workspace: ${n.name}`);o=r.id}let{url:s,name:c}=await e.client.downloadSkillCurrent(e.accessToken,e.workspaceId,o),l=await fetch(s);if(!l.ok)throw Error(`Failed to download ${c}: ${l.status}`);let d=Buffer.from(await l.arrayBuffer()),f=u(t,c);await g.rm(f,{recursive:!0,force:!0}),await g.mkdir(f,{recursive:!0});let{default:_}=await import(`adm-zip`),v=h.resolve(f)+h.sep;for(let e of new _(d).getEntries()){if(e.isDirectory)continue;let t=h.resolve(f,e.entryName);if(!t.startsWith(v))throw Error(`Zip entry contains path traversal: ${e.entryName}`);await g.mkdir(h.dirname(t),{recursive:!0}),await g.writeFile(t,e.getData())}let y=p(f);a(t,c,{source:o,sourceType:`entrydesk`,skillId:o,localHash:y,lastPulledHash:y,mode:`symlink`});let b=m(f,c,t,`symlink`,i);return r||console.info(`✓ pulled ${c} (${y.slice(0,12)}) → agents: ${b.map(e=>e.agentId).join(`, `)}`),{name:c,hash:y}}async function x(e,t,n){let{rootDir:r,workspaceId:i}=await o(!!t.global,n.workspaceId),a={...n,workspaceId:i},s=!!t.json,l=[];if(e)l.push(_.test(e)?{skillId:e}:{name:e});else{let e=c(r).skills;for(let[t,n]of Object.entries(e))l.push({skillId:n.skillId,name:t});if(l.length===0){console.info(`Nothing to pull — no tracked skills. Try: entrydesk skills pull <name>`);return}}let u=[];for(let e of l)u.push(await b(a,r,e,s,t.agent));s&&console.info(JSON.stringify(u,null,2))}export{x as n,y as r,v as t};
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{r as e}from"./commands--5Ein-MI.js";export{e as runSkillsUnlink};
@@ -1,3 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import{M as e,j as t,t as n}from"./profile-storage-DlaupNlV.js";function r(e){try{let{pathname:t}=new URL(e);return t.replace(/\/+$/u,``).endsWith(`/api`)}catch{return!1}}function i(r){let i=e.getAll();if(r.json){console.log(JSON.stringify(i));return}let a=Object.entries(i);if(console.log(`Profile: ${n.getEffectiveProfileName()}`),a.length===0){console.log(`No configuration set.`),console.log(`Available keys: ${t.join(`, `)}`);return}console.log(`Configuration:
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{F as e,P as t,t as n}from"./profile-storage-CuiJZpFD.js";function r(e){try{let{pathname:t}=new URL(e);return t.replace(/\/+$/u,``).endsWith(`/api`)}catch{return!1}}function i(r){let i=e.getAll();if(r.json){console.log(JSON.stringify(i));return}let a=Object.entries(i);if(console.log(`Profile: ${n.getEffectiveProfileName()}`),a.length===0){console.log(`No configuration set.`),console.log(`Available keys: ${t.join(`, `)}`);return}console.log(`Configuration:
3
11
  `);for(let[e,t]of a)console.log(` ${e}=${t}`);console.log(`\nAvailable keys: ${t.join(`, `)}`)}function a(t,n){let r=e.get(t);n.json?console.log(JSON.stringify({[t]:r??null})):console.log(r||`Not set`)}function o(t,i){e.set(t,i),console.log(`Set ${t}=${i}`),console.error(`(profile: ${n.getEffectiveProfileName()})`),t===`apiUrl`&&r(i)&&console.error(`Warning: ${i} looks like a web app's "/api" browser proxy path. Such proxies usually strip the Authorization header, so CLI requests will fail with 401 missing_token — prefer the API server's own URL unless you know this proxy forwards Authorization.`)}function s(t){e.unset(t),console.log(`Unset ${t}`),console.error(`(profile: ${n.getEffectiveProfileName()})`)}export{a as getConfigValue,i as listConfig,o as setConfigValue,s as unsetConfigValue};
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{createInterface as e}from"node:readline/promises";async function t(t){let n=e({input:process.stdin,output:process.stdout});try{let e=await n.question(`${t} [y/N] `);return/^y(es)?$/i.test(e.trim())}finally{n.close()}}export{t};
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
10
+ import{Dt as e,K as t,W as n,X as r,Z as i,b as a,u as o}from"./profile-storage-CuiJZpFD.js";import{t as s}from"./confirm-Ct432t3K.js";function c(e,t){return t?r(t)?`Next: entrydesk connectors connect ${e} --oauth`:t===`credentials`?`Next: entrydesk connectors connect ${e} --username <username> --password <password>`:`Next: entrydesk connectors connect ${e} --token <token>`:`This connector needs no authorization — there is no connect step.`}async function l(e){let{accessToken:t,workspaceId:n}=await o(),{connectors:r,nextKey:i}=await new a().getConnectors(t,n,{connectionStatus:e.all?`all`:`connected`,search:e.search,limit:e.limit,nextKey:e.nextKey});if(e.json){console.log(JSON.stringify({connectors:r,nextKey:i}));return}if(r.length===0){console.log(e.all?`No connectors found.`:`No connected connectors. Use --all to browse connectable ones.`);return}let s=e.all?`Connectors`:`Connected connectors`;console.log(`${s} (${r.length}):\n`);for(let e of r){let t=e.connected?`connected`:`not connected`;console.log(` ${e.name} (${t})`),console.log(` Provider: ${e.provider}`),console.log(` ID: ${e.id}`),e.authorization?.type&&console.log(` Auth: ${e.authorization.type}`),console.log(``)}i&&console.log(`More results: --next-key ${i}`)}async function u(e,t){let{accessToken:n,workspaceId:r}=await o(),{tools:i}=await new a().getConnectorTools(n,r,e);if(t.json){console.log(JSON.stringify({tools:i}));return}if(i.length===0){console.log(`This connector exposes no tools.`);return}console.log(`Tools (${i.length}):\n`);for(let e of i)console.log(` ${e.name} [${e.policy}]`),e.description&&console.log(` ${e.description}`)}async function d(e,t){let{accessToken:n,workspaceId:r}=await o();await new a().syncConnectorTools(n,r,e),console.log(t.json?JSON.stringify({id:e,synced:!0}):`Synced tools for connector ${e}.`)}async function f(e,t){let{accessToken:n,workspaceId:r}=await o(),i=new a;if(t.oauth){let{url:a}=await i.getConnectorAuthUrl(n,r,e);if(t.json){console.log(JSON.stringify({url:a}));return}console.log(`Open this URL in your browser to authorize the connector:`),console.log(` ${a}`),console.log(`
11
+ After you approve, the connection is saved automatically — re-run`),console.log("`entrydesk connectors` to confirm it shows as connected.");return}let s;t.token?s={token:t.token}:t.username&&t.password?s={username:t.username,password:t.password}:(console.error(`Provide --token, or --username and --password, or --oauth to connect.`),process.exit(1)),await i.connectConnectorToken(n,r,e,s),console.log(t.json?JSON.stringify({id:e,connected:!0}):`Connected connector ${e}.`)}function p(e){let t=e.auth===`oauth`||e.auth===`google-iap`;if(t&&(!e.provider||!e.scope?.length)&&(console.error(`--auth ${e.auth} needs --provider and at least one --scope.`),process.exit(1)),!t&&(e.provider||e.scope?.length)&&(console.error(e.auth?`--provider and --scope apply only to --auth oauth and --auth google-iap, not --auth ${e.auth}.`:`--provider and --scope need --auth oauth or --auth google-iap.`),process.exit(1)),e.auth!==void 0)return e.auth===!1?null:{type:e.auth,...e.provider?{provider:e.provider}:{},...e.scope?.length?{scopes:e.scope}:{}}}async function m(r){let s=p(r),l=r.toolNamespace??r.toolPrefix,u=l??i(r.name),d=t(u);if(d){let e=n[d];console.error(l?`--tool-namespace ${e}.`:`The tool namespace derived from --name ("${u}") ${e}. Pass --tool-namespace explicitly.`),process.exit(1)}let{accessToken:f,workspaceId:m}=await o(),h=await new a().createCustomConnector(f,m,{type:e.CUSTOM_REMOTE_URL,name:r.name,description:r.description,transport:r.transport,url:r.url,toolNamespace:u,...s?{authorization:s}:{}});if(r.json){console.log(JSON.stringify(h));return}console.log(`Created connector ${h.name}.`),console.log(` ID: ${h.id}`),console.log(` URL: ${h.url}`),console.log(` Tool namespace: ${h.toolNamespace}`),console.log(`\n${c(h.id,r.auth)}`)}function h(e,t){return t===void 0?e:t===null||t.type!==e?.type?t:{...e,...t}}async function g(t,n){[n.name,n.url,n.description,n.transport,n.toolNamespace,n.auth,n.provider,n.scope].every(e=>e===void 0)&&(console.error(`Nothing to update. Pass at least one of --name, --url, --description, --transport, --tool-namespace, --auth or --no-auth.`),process.exit(1));let r=p(n),{accessToken:i,workspaceId:s}=await o(),c=new a,l=await c.getCustomConnector(i,s,t),u=await c.updateCustomConnector(i,s,t,{type:e.CUSTOM_REMOTE_URL,name:n.name??l.name,description:n.description??l.description,transport:n.transport??l.transport,url:n.url??l.url,toolNamespace:n.toolNamespace??l.toolNamespace,authorization:h(l.authorization,r)});if(n.json){console.log(JSON.stringify(u));return}console.log(`Updated connector ${u.name}.`),console.log(` ID: ${u.id}`),console.log(` URL: ${u.url}`),console.log(` Tool namespace: ${u.toolNamespace}`)}async function _(e,t){let{accessToken:n,workspaceId:r}=await o();if(!t.yes&&(process.stdin.isTTY||(console.error(`Disconnecting connector ${e} needs confirmation. Re-run with --yes.`),process.exit(1)),!await s(`Disconnect connector ${e}?`))){console.log(`Aborted.`);return}await new a().disconnectConnector(n,r,e),console.log(t.json?JSON.stringify({id:e,disconnected:!0}):`Disconnected connector ${e}.`)}export{f as connectConnector,m as createConnector,_ as disconnectConnector,u as listConnectorTools,l as listConnectors,d as syncConnectorTools,g as updateConnector};
@@ -1,4 +1,12 @@
1
1
  #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
2
10
  import e,{promises as t}from"node:fs";import n from"node:os";import r from"node:path";import{execFile as i}from"node:child_process";import a from"node:fs/promises";import{promisify as o}from"node:util";const s=o(i);async function c(){let t=r.join(n.tmpdir(),`entrydesk-clipboard-${Date.now()}.png`);try{let e=`
3
11
  set imageData to the clipboard as "PNGf"
4
12
  set fileRef to open for access POSIX file "${t}" with write permission
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
2
10
  function e(e){return`$${e.toFixed(2)}`}function t(e){if(e==null)return`—`;let t=Math.round(e),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=String(r).padStart(2,`0`),o=String(i).padStart(2,`0`);return n>0?`${n}:${a}:${o}`:`${r}:${o}`}function n(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()}function r(e,t){return`${e} ${t}${e===1?``:`s`}`}export{r as i,n,e as r,t};
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ var __entrydeskNodeFloor = 24;
3
+ if (parseInt(process.versions.node, 10) < __entrydeskNodeFloor) {
4
+ process.stderr.write(
5
+ 'entrydesk: Node.js ' + __entrydeskNodeFloor + ' or newer is required, but this is Node ' + process.versions.node + '.\n' +
6
+ 'Upgrade Node (https://nodejs.org/en/download), then reinstall @entrydesk/cli.\n'
7
+ );
8
+ process.exit(1);
9
+ }
2
10
  import e from"node:fs";import t from"node:path";import{createHash as n}from"node:crypto";const r=new Set([`.git`,`node_modules`,`__pycache__`,`.DS_Store`,`__MACOSX`]),i=`SKILL.md`;function a(n){let a=e.readdirSync(n,{withFileTypes:!0}).filter(e=>!r.has(e.name));if(a.some(e=>e.isFile()&&e.name===i))return n;let o=a.filter(e=>e.isDirectory());if(o.length===1){let r=t.join(n,o[0].name);if(e.existsSync(t.join(r,i)))return r}return n}function o(n,i,a){for(let s of e.readdirSync(i,{withFileTypes:!0})){if(r.has(s.name))continue;let e=t.join(i,s.name);s.isDirectory()?o(n,e,a):s.isFile()&&a.push({rel:t.relative(n,e).split(t.sep).join(`/`),abs:e})}}function s(t){let r=[];o(t,t,r),r.sort((e,t)=>e.rel<t.rel?-1:+(e.rel>t.rel));let i=n(`sha256`);for(let t of r){let r=n(`sha256`).update(e.readFileSync(t.abs)).digest(`hex`);i.update(t.rel).update(`\0`).update(r).update(`\0`)}return i.digest(`hex`)}function c(e){return s(a(e))}export{c as t};