@foundingbot/cli 0.0.0 → 0.1.4
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/CHANGELOG.md +50 -0
- package/dist/main.mjs +4 -0
- package/package.json +21 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @foundingbot/cli
|
|
2
|
+
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#66](https://github.com/phuctm97/foundingbot/pull/66) [`dcd201f`](https://github.com/phuctm97/foundingbot/commit/dcd201fbfeceb4a59e4eeee91b882156a6ca3cfc) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Publish the CLI as both @foundingbot/cli and foundingbot on npm without source maps and on Verdaccio with source maps. Keep scoped Verdaccio publishing restricted; unscoped access is controlled by Verdaccio’s server permissions.
|
|
8
|
+
|
|
9
|
+
Build each CLI and utility release after preparing its final package manifest so bundled metadata matches the published package.
|
|
10
|
+
- Updated dependencies [[`dcd201f`](https://github.com/phuctm97/foundingbot/commit/dcd201fbfeceb4a59e4eeee91b882156a6ca3cfc)]:
|
|
11
|
+
- @foundingbot/util@0.1.6
|
|
12
|
+
|
|
13
|
+
## 0.1.3
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#62](https://github.com/phuctm97/foundingbot/pull/62) [`b970176`](https://github.com/phuctm97/foundingbot/commit/b97017643c9e66995f0b949015eb7b4ab4b12aeb) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Publish compiled CLI JavaScript and source maps to the private registry. Pack CLI and utility releases with Bun to resolve workspace dependencies automatically, keeping source manifests private until release.
|
|
18
|
+
- Updated dependencies [[`400c483`](https://github.com/phuctm97/foundingbot/commit/400c483f9b846e14ed034a6b36e5be7fbe8cdc52), [`b970176`](https://github.com/phuctm97/foundingbot/commit/b97017643c9e66995f0b949015eb7b4ab4b12aeb), [`d693770`](https://github.com/phuctm97/foundingbot/commit/d6937703e22ec1a697037d3ff8d965e3ed0a855d)]:
|
|
19
|
+
- @foundingbot/util@0.1.4
|
|
20
|
+
|
|
21
|
+
## 0.1.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- [#60](https://github.com/phuctm97/foundingbot/pull/60) [`101af22`](https://github.com/phuctm97/foundingbot/commit/101af22d72f610a4cddcf9408ae526f7289dc4d0) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Align the rebuild confirmation wording with bot removal.
|
|
26
|
+
- Updated dependencies [[`b459988`](https://github.com/phuctm97/foundingbot/commit/b4599888882634bf95079d48411765cf3245269e)]:
|
|
27
|
+
- @foundingbot/util@0.1.3
|
|
28
|
+
|
|
29
|
+
## 0.1.1
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- [#51](https://github.com/phuctm97/foundingbot/pull/51) [`0e93a4c`](https://github.com/phuctm97/foundingbot/commit/0e93a4c1d50a6f29bef1957205cc7e6c535bc66f) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Move environment configuration from shared utilities into the consuming packages.
|
|
34
|
+
Require service URLs to be configured explicitly, retaining the CLI's production default.
|
|
35
|
+
|
|
36
|
+
- [#55](https://github.com/phuctm97/foundingbot/pull/55) [`751c13b`](https://github.com/phuctm97/foundingbot/commit/751c13ba0a23da0d52adde4e65f2b7f4e4eea505) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Add a rebuild-bot command with explicit confirmation before deleting machine-local data.
|
|
37
|
+
- Updated dependencies [[`7e1e70a`](https://github.com/phuctm97/foundingbot/commit/7e1e70a95649dd9de166d81ae402e85ab1cdc57b), [`549a11a`](https://github.com/phuctm97/foundingbot/commit/549a11a9228e7523231fc01d4fa2fa32b56cb7a0), [`0e93a4c`](https://github.com/phuctm97/foundingbot/commit/0e93a4c1d50a6f29bef1957205cc7e6c535bc66f)]:
|
|
38
|
+
- @foundingbot/util@0.1.1
|
|
39
|
+
|
|
40
|
+
## 0.1.0
|
|
41
|
+
|
|
42
|
+
### Minor Changes
|
|
43
|
+
|
|
44
|
+
- [`c6cc606`](https://github.com/phuctm97/foundingbot/commit/c6cc6067602c6905c996698b60071949d9990bee) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Open Stripe Checkout from the CLI and activate bots after Checkout completes, safely canceling duplicate subscriptions.
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- [`64ba787`](https://github.com/phuctm97/foundingbot/commit/64ba7875eafce3b4862f81dc1178dba7529f096b) Thanks [@kittranofficial](https://github.com/kittranofficial)! - Update external dependencies to their latest releases.
|
|
49
|
+
- Updated dependencies [[`c6cc606`](https://github.com/phuctm97/foundingbot/commit/c6cc6067602c6905c996698b60071949d9990bee), [`64ba787`](https://github.com/phuctm97/foundingbot/commit/64ba7875eafce3b4862f81dc1178dba7529f096b)]:
|
|
50
|
+
- @foundingbot/util@0.1.0
|
package/dist/main.mjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import{defineCittyPlugin as e,defineCommand as t,runMain as n}from"citty";import{cancel as r,confirm as i,group as a,isCancel as o,log as s,note as c,outro as l,password as u,select as d,text as f}from"@clack/prompts";import{createAuthClient as p}from"better-auth/client";import{once as ee}from"node:events";import m from"open";import{z as h}from"zod";import{createORPCClient as g}from"@orpc/client";import{RPCLink as _}from"@orpc/client/fetch";import{randomBytes as v}from"node:crypto";import{contract as y}from"@foundingbot/util";import{OpenAPILink as b}from"@orpc/openapi-client/fetch";var x=`0.1.4`,te=`Founding Bot CLI client`;const S=Bun.env.FOUNDINGBOT_SERVER_URL||`https://server.founding.bot`,C={service:`bot.founding.cli.auth.token`,name:S};async function w(){return await Bun.secrets.get(C)||void 0}function T(e){return Bun.secrets.set({...C,value:e})}function E(){return Bun.secrets.delete(C)}async function D(){let e=await w();return{authorization:e?`Bearer ${e}`:void 0}}async function O(e){throw await E(),Error(`Verify ${e} to continue. Check your inbox and any spam, junk, or other folders, or run the resend-verification command to request another verification email.`)}function k(e){let t=e instanceof Error?e.cause:void 0;return typeof t==`object`&&!!t&&`code`in t&&t.code===`EMAIL_NOT_VERIFIED`}var A=p({baseURL:new URL(`/auth`,S).href,fetchOptions:{throw:!0,auth:{token:w,type:`Bearer`},onSuccess:async({response:e})=>{let t=e.headers.get(`set-auth-token`);t&&await T(t)},customFetchImpl:(e,t)=>globalThis.fetch(e,t)}});const j=e({name:`require-signed-in`,setup:async e=>{let t=await A.getSession();if(!t)throw Error(`Not signed in. Run the sign-in command, then try again.`);t.user.emailVerified||await O(t.user.email),e.data=t}});function M(e){return t({...e,run:e.run,plugins:[j]})}const ne=e({name:`require-signed-out`,setup:async()=>{let e=await A.getSession();if(e)throw Error(`Already signed in as ${e.user.email}. Run the sign-out command, then try again.`)}});function N(e){return t({...e,plugins:[ne]})}function P(e){return h.string().refine(e=>e.trim().length>0,`${e} is required`)}const F=h.email(`Enter a valid email`);function I(e){return P(e).pipe(F)}function L(e){return P(e).min(8,`Password must be at least 8 characters`).max(128,`Password must be at most 128 characters`)}const R=P(`Confirm password`);function z(e){return R.refine(t=>t===e,`Passwords do not match`)}const B=P(`Name`),V=h.union([h.literal(``),h.url({error:`Enter a valid HTTP or HTTPS URL`,protocol:/^https?$/})]),H=I(`Email`),U=I(`New email`),W=P(`Token`),G=P(`Activation code`).regex(/^[a-f0-9]{64}$/,`Enter a valid activation code`),K=P(`Password`),q=P(`Current password`),J=L(`New password`),Y=L(`Password`);function X(e){r(e),process.exit(0)}async function Z(e){try{let t=await m(e);if(process.platform===`darwin`){t.ref();let[e]=await ee(t,`close`);if(e!==0)throw Error(`Browser launch failed`)}}catch{s.warn(`Couldn’t open your browser. Open the link above manually.`)}}const re=new _({url:new URL(`/rpc`,S),headers:D,fetch:(e,t)=>globalThis.fetch(e,t)});var Q=g(re),ie=M({meta:{name:`activate-bot`,description:`Activate your bot`},run:async()=>{let{activationCode:e}=await a({activationCode:()=>u({message:`Activation code`,validate:G,clearOnError:!0})},{onCancel:()=>X(`Bot activation canceled`)}),{url:t}=await Q.activateBot({activationCode:e});s.info(`Complete checkout in Stripe:\n${t}`),await Z(t),l(`Complete checkout to activate your bot.`)}}),ae=M({meta:{name:`change-email`,description:`Change your email`},run:async()=>{let{newEmail:e}=await a({newEmail:()=>f({message:`New email`,validate:U})},{onCancel:()=>X(`Email change canceled`)});await A.changeEmail({newEmail:e,callbackURL:`/cli/email-change`}),l(`Email change requested for ${e}`)}}),oe=M({meta:{name:`change-password`,description:`Change your password`},run:async()=>{let e=await a({currentPassword:()=>u({message:`Current password`,validate:q}),newPassword:()=>u({message:`New password`,validate:J,clearOnError:!0}),confirmPassword:({results:e})=>u({message:`Confirm password`,validate:z(e.newPassword||``),clearOnError:!0}),revokeOtherSessions:()=>i({message:`Revoke other sessions?`})},{onCancel:()=>X(`Password change canceled`)});await A.changePassword({currentPassword:e.currentPassword,newPassword:e.newPassword,revokeOtherSessions:e.revokeOtherSessions}),l(`Password change succeeded`)}}),se=M({meta:{name:`create-bot`,description:`Create your bot`},run:async()=>{let e=Bun.env.TELEGRAM_MANAGER_USERNAME;if(!e)throw Error(`TELEGRAM_MANAGER_USERNAME is not configured`);let t=Bun.env.TELEGRAM_BOT_TEMPLATE;if(!t)throw Error(`TELEGRAM_BOT_TEMPLATE is not configured`);if(t.split(`<random>`).length!==2)throw Error(`TELEGRAM_BOT_TEMPLATE must contain exactly one <random> placeholder`);let n=t.replace(`<random>`,v(8).toString(`hex`));if(n.length>32||/[^A-Za-z0-9_]/.test(n)||!n.toLowerCase().endsWith(`bot`))throw Error(`TELEGRAM_BOT_TEMPLATE must generate a username of at most 32 ASCII letters, digits, or underscores ending in bot`);let r=`https://t.me/newbot/${encodeURIComponent(e)}/${encodeURIComponent(n)}`;s.info(`Create your bot in Telegram:\n${r}`),await Z(r),l(`Finish creating your bot, then press Start or send /start to continue.`)}}),ce=N({meta:{name:`forgot-password`,description:`Request a password reset`},run:async()=>{let{email:e}=await a({email:()=>f({message:`Email`,validate:H})},{onCancel:()=>X(`Password reset request canceled`)});try{await A.requestPasswordReset({email:e,redirectTo:`/cli/password-reset`})}catch(t){throw Error(`Failed to request password reset for ${e}`,{cause:t})}l(`If an account exists for ${e}, password reset instructions have been sent`)}}),le=M({meta:{name:`list-bots`,description:`List your bots`},run:async()=>{let e=await Q.listBots();if(e.length===0){console.log(`No bots`);return}e.forEach((e,t)=>{c(`Name: ${e.name}\nTelegram bot username: @${e.telegramBotUsername}\nTelegram bot ID: ${e.telegramBotId}`,`Bot ${t+1}`)})}}),ue=M({meta:{name:`list-sessions`,description:`List your active sessions`},run:async({data:e})=>{let t=await A.listSessions();if(t.length===0){console.log(`No active sessions`);return}t.forEach((t,n)=>{c([`IP address: ${t.ipAddress||`(None)`}`,`User agent: ${t.userAgent||`(None)`}`,`ID: ${t.id}`,`Created: ${t.createdAt.toISOString()}`,`Updated: ${t.updatedAt.toISOString()}`,`Expires: ${t.expiresAt.toISOString()}`].join(`
|
|
3
|
+
`),`Session ${n+1}${t.id===e.session.id?` (Current)`:``}`)})}}),de=M({meta:{name:`manage-billing`,description:`Manage your billing`},run:async()=>{let{url:e}=await Q.manageBilling();s.info(`Manage your billing in Stripe:\n${e}`),await Z(e),l(`Continue in your browser.`)}});const fe=new b(y,{url:new URL(`/api`,S),headers:D,fetch:(e,t)=>globalThis.fetch(e,t)});var pe=g(fe),me=t({meta:{name:`ping`,description:`Run health checks`},run:async()=>{let e=await fetch(new URL(`/health`,S));if(!e.ok)throw Error(`Server health check failed`);console.log(`Server health:`,e.statusText||`OK`);let t=await fetch(new URL(`/auth/ok`,S));if(!t.ok)throw Error(`Auth health check failed`);console.log(`Auth health:`,t.statusText||`OK`);let n=await Q.ping();console.log(`RPC ping:`,n);let r=await pe.ping();console.log(`API ping:`,r)}}),he=M({meta:{name:`rebuild-bot`,description:`Rebuild your bot`},run:async()=>{let e=await Q.listBots();if(e.length===0){console.log(`No bots`);return}let t=()=>X(`Bot rebuild canceled`),{index:n,confirmed:r}=await a({index:()=>d({message:`Bot`,options:e.map((e,t)=>({value:t,label:`${e.name} (@${e.telegramBotUsername})`}))}),confirmed:()=>i({message:`Rebuild this bot and permanently delete its data?`,initialValue:!1})},{onCancel:t});r||t();let o=e[n];if(!o)throw Error(`Bot not found`);await Q.rebuildBot({telegramBotId:o.telegramBotId}),l(`Bot rebuilt`)}}),ge=M({meta:{name:`remove-bot`,description:`Remove your bot`},run:async()=>{let e=await Q.listBots();if(e.length===0){console.log(`No bots`);return}let t=()=>X(`Bot removal canceled`),{index:n,confirmed:r}=await a({index:()=>d({message:`Bot`,options:e.map((e,t)=>({value:t,label:`${e.name} (@${e.telegramBotUsername})`}))}),confirmed:()=>i({message:`Remove this bot and permanently delete its data?`,initialValue:!1})},{onCancel:t});r||t();let c=e[n];if(!c)throw Error(`Bot not found`);await Q.removeBot({telegramBotId:c.telegramBotId}),s.success(`Bot removed`);let u=`${c.name} (@${c.telegramBotUsername})`,f=await i({message:`Also delete ${u} from Telegram?`,initialValue:!0});if(o(f)||!f){l(`${u} remains on Telegram. To reconnect it to your account, send /start to it and follow the instructions.`);return}let p=new URL(`https://t.me/BotFather`);p.searchParams.set(`start`,`deletebot`),s.info(`Continue deleting ${u} from Telegram:\n${p}`),await Z(p.href),l(`Select @${c.telegramBotUsername} in BotFather and follow the instructions.`)}}),_e=M({meta:{name:`repair-bot`,description:`Check and repair your bot`},run:async()=>{let e=await Q.listBots();if(e.length===0){console.log(`No bots`);return}let{index:t}=await a({index:()=>d({message:`Bot`,options:e.map((e,t)=>({value:t,label:`${e.name} (@${e.telegramBotUsername})`}))})},{onCancel:()=>X(`Bot repair canceled`)}),n=e[t];if(!n)throw Error(`Bot not found`);await Q.repairBot({telegramBotId:n.telegramBotId}),l(`Bot repaired`)}}),ve=N({meta:{name:`resend-verification`,description:`Request another verification email`},run:async()=>{let{email:e}=await a({email:()=>f({message:`Email`,validate:H})},{onCancel:()=>X(`Verification email request canceled`)});try{await A.sendVerificationEmail({email:e,callbackURL:`/cli/email-verification`})}catch(t){throw Error(`Failed to request verification email for ${e}`,{cause:t})}l(`Verification email requested for ${e}`)}}),ye=N({meta:{name:`reset-password`,description:`Reset your password`},run:async()=>{let e=await a({token:()=>u({message:`Token`,validate:W,clearOnError:!0}),newPassword:()=>u({message:`New password`,validate:J,clearOnError:!0}),confirmPassword:({results:e})=>u({message:`Confirm password`,validate:z(e.newPassword||``),clearOnError:!0})},{onCancel:()=>X(`Password reset canceled`)});await A.resetPassword({token:e.token,newPassword:e.newPassword}),l(`Password reset succeeded. Run the sign-in command to continue.`)}}),be=M({meta:{name:`reset-usage`,description:`Reset your bot’s usage limits`},run:async()=>{let e=await Q.listBots();if(e.length===0){console.log(`No bots`);return}let t=()=>X(`Usage reset canceled`),{index:n,confirmed:r}=await a({index:()=>d({message:`Bot`,options:e.map((e,t)=>({value:t,label:`${e.name} (@${e.telegramBotUsername})`}))}),confirmed:()=>i({message:`Use an available reset for this bot?`,initialValue:!1})},{onCancel:t});r||t();let o=e[n];if(!o)throw Error(`Bot not found`);await Q.resetUsage({telegramBotId:o.telegramBotId}),l(`Usage limits reset`)}}),$=M({meta:{name:`revoke-session`,description:`Revoke an active session`},run:async({data:e})=>{let t=await A.listSessions();if(t.length===0){console.log(`No active sessions`);return}let{index:n}=await a({index:()=>d({message:`Session`,options:t.map((t,n)=>({value:n,label:`Session ${n+1}${t.id===e.session.id?` (Current)`:``}`,hint:`Created: ${t.createdAt.toISOString()} · User agent: ${t.userAgent||`(None)`} · IP address: ${t.ipAddress||`(None)`}`}))})},{onCancel:()=>X(`Session revocation canceled`)}),r=t[n];if(!r)throw Error(`Session not found`);await A.revokeSession({token:r.token}),r.id===e.session.id&&await E(),l(`Session revoked`)}}),xe=N({meta:{name:`sign-in`,description:`Sign in`},run:async()=>{let e=await a({email:()=>f({message:`Email`,validate:H}),password:()=>u({message:`Password`,validate:K})},{onCancel:()=>X(`Sign-in canceled`)}),t;try{({user:t}=await A.signIn.email(e))}catch(t){throw k(t)&&await O(e.email),t}t.emailVerified||await O(t.email),l(`Signed in as ${t.email}`)}}),Se=t({meta:{name:`sign-out`,description:`Sign out`},run:async()=>{await A.signOut(),await E(),l(`Signed out`)}}),Ce=N({meta:{name:`sign-up`,description:`Create an account`},run:async()=>{let e=await a({name:()=>f({message:`Name`,validate:B}),email:()=>f({message:`Email`,validate:H}),password:()=>u({message:`Password`,validate:Y,clearOnError:!0})},{onCancel:()=>X(`Sign-up canceled`)}),t=await A.signUp.email({...e,callbackURL:`/cli/email-verification`});t.user.emailVerified||await O(t.user.email),l(`Signed up as ${t.user.email}`)}}),we=M({meta:{name:`update-profile`,description:`Update your profile`},run:async({data:e})=>{let{name:t,avatar:n}=await a({name:()=>f({message:`Name`,initialValue:e.user.name,validate:B}),avatar:()=>f({message:`Avatar`,initialValue:e.user.image||void 0,placeholder:`Optional URL`,validate:V})},{onCancel:()=>X(`Profile update canceled`)});await A.updateUser({name:t,image:n||null}),l(`Profile update succeeded`)}}),Te=M({meta:{name:`view-usage`,description:`View your bot’s usage details`},run:async()=>{let e=await Q.listBots();if(e.length===0){console.log(`No bots`);return}let{index:t}=await a({index:()=>d({message:`Bot`,options:e.map((e,t)=>({value:t,label:`${e.name} (@${e.telegramBotUsername})`}))})},{onCancel:()=>X(`Usage check canceled`)}),n=e[t];if(!n)throw Error(`Bot not found`);let r=await Q.viewUsage({telegramBotId:n.telegramBotId}),i=`Subscription: (None)`;if(r.subscription){let{plan:e,price:t,usage:n}=r.subscription,a=new Intl.NumberFormat(`en-US`,{style:`currency`,currency:t.currency}),o=10**(a.resolvedOptions().maximumFractionDigits??2),s=t.duration.count===1?t.duration.unit:`${t.duration.count} ${t.duration.unit}s`;i=`Subscription:\n Plan: ${e}\n Price: ${a.format(t.amount/o)}\n Billing: Every ${s}\n Usage:\n Five-hour used: ${n.fiveHourUsedPercent}%\n Weekly used: ${n.weeklyUsedPercent}%\n Available resets: ${n.availableResets}`}c(`Status: ${r.status||`(None)`}\n${i}`,`${n.name} (@${n.telegramBotUsername})`)}}),Ee=M({meta:{name:`whoami`,description:`Show the current user`},run:({data:e})=>{c([`Name: ${e.user.name}`,`Email: ${e.user.email}`,`Avatar: ${e.user.image||`(None)`}`,`ID: ${e.user.id}`,`Created: ${e.user.createdAt.toISOString()}`,`Updated: ${e.user.updatedAt.toISOString()}`].join(`
|
|
4
|
+
`),`Current user`)}});const De=t({meta:{name:`foundingbot`,version:x,description:te},subCommands:{"sign-up":Ce,"resend-verification":ve,"sign-in":xe,"sign-out":Se,"forgot-password":ce,"reset-password":ye,whoami:Ee,"update-profile":we,"change-email":ae,"change-password":oe,"list-sessions":ue,"revoke-session":$,"create-bot":se,"activate-bot":ie,"list-bots":le,"repair-bot":_e,"rebuild-bot":he,"remove-bot":ge,"view-usage":Te,"reset-usage":be,"manage-billing":de,ping:me}});await n(De);export{};
|
package/package.json
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foundingbot/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Founding Bot CLI",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "Founding Bot CLI client",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/main.mjs",
|
|
7
|
+
"bin": {
|
|
8
|
+
"foundingbot": "./dist/main.mjs"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@clack/prompts": "^1.8.1",
|
|
12
|
+
"@foundingbot/util": "^0.1.6",
|
|
13
|
+
"@orpc/client": "^1.15.4",
|
|
14
|
+
"@orpc/openapi-client": "^1.15.4",
|
|
15
|
+
"better-auth": "^1.7.7",
|
|
16
|
+
"citty": "^0.2.2",
|
|
17
|
+
"open": "^11.0.4",
|
|
18
|
+
"zod": "^4.6.5"
|
|
19
|
+
},
|
|
5
20
|
"repository": {
|
|
6
21
|
"type": "git",
|
|
7
22
|
"url": "git+https://github.com/phuctm97/foundingbot.git",
|
|
8
23
|
"directory": "packages/cli"
|
|
9
24
|
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"CHANGELOG.md"
|
|
28
|
+
],
|
|
10
29
|
"publishConfig": {
|
|
11
30
|
"registry": "https://registry.npmjs.org",
|
|
12
31
|
"access": "public"
|