@meeting-ai/cli 0.1.2 → 0.1.3
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 +1 -1
- package/dist/bin/meeting.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Access your [Meeting.ai](https://meeting.ai) meetings from the command line. Read meeting notes, search transcripts, pull key quotes, upload recordings, and send bots to live meetings — so you and your AI agents always know what happened.
|
|
4
4
|
|
|
5
|
-

|
|
5
|
+

|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
package/dist/bin/meeting.js
CHANGED
|
@@ -3,7 +3,7 @@ var rt=Object.defineProperty;var st=(t,e)=>()=>(t&&(e=t(t=0)),e);var at=(t,e)=>{
|
|
|
3
3
|
`)}function ut(t){let e={error:!0,code:t.code||"UNKNOWN_ERROR",message:t.message,exit_code:t.exit_code||1};process.stderr.write(JSON.stringify(e)+`
|
|
4
4
|
`)}function J(t,e){if(t.length===0){console.log(g(" No results."));return}let n=e.map(r=>{let o=t.map(s=>Me(s[r.key],r.format).length);return Math.max(r.label.length,...o)}),i=e.map((r,o)=>U.bold(r.label.padEnd(n[o]))).join(" ");console.log(i),console.log(g("\u2500".repeat(i.length)));for(let r of t){let o=e.map((s,a)=>Me(r[s.key],s.format).padEnd(n[a])).join(" ");console.log(o)}}function Me(t,e){return e?e(t):t==null?"-":String(t)}function v(t){let e=Math.max(...Object.keys(t).map(n=>n.length));for(let[n,i]of Object.entries(t)){let r=U.bold(n.padEnd(e)),o=i==null?g("-"):String(i);console.log(` ${r} ${o}`)}}function b(t,e){let n=t,i=n.exit_code||1,r=n.message||"Unknown error",o=n.code||"UNKNOWN_ERROR";p(e)?ut({code:o,message:r,exit_code:i}):console.error(U.red(`Error: ${r}`)+" "+g(`(${o})`)),process.exit(i)}function E(t){if(!t||t<=0)return"-";let e=Math.floor(t/3600),n=Math.floor(t%3600/60);return e>0?`${e}h ${n}m`:`${n} min`}function P(t){return t?new Date(t).toLocaleDateString("en-US",{weekday:"short",month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"}):"-"}function re(t){return t?new Date(t).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"-"}function se(t){return{zoom:"\u{1F4F9}",gmeet:"\u{1F7E2}",teams:"\u{1F512}",webex:"\u{1F310}",upload:"\u{1F4E4}",livestream:"\u{1F30D}",record:"\u{1F399}\uFE0F"}[t?.toLowerCase()]||"\u{1F4CB}"}function W(t){return{"google meet":"gmeet",googlemeet:"gmeet",google:"gmeet",meet:"gmeet",gmeet:"gmeet",zoom:"zoom",teams:"teams","microsoft teams":"teams",msteams:"teams",webex:"webex",upload:"upload",livestream:"livestream",live:"livestream",record:"record",recording:"record"}[t.toLowerCase()]||t.toLowerCase()}function ae(t){return{zoom:"Zoom",gmeet:"Google Meet",teams:"Teams",webex:"Webex",upload:"Upload",livestream:"Livestream",record:"Recording"}[t?.toLowerCase()]||t||"-"}function q(t){let e=typeof t=="string"?parseInt(t,10):t;return isNaN(e)||e<5?5:e}import{Command as ft}from"commander";import A from"chalk";var ce=new Map;function k(t,e){ce.set(t,e)}function Re(){let t=new ft("schema").description("Introspect command schemas");return t.argument("[command]","Command name (e.g., meetings.list)").option("--json","Output as JSON").option("--fields <fields>","Select output fields").action((e,n)=>{try{if(!e){let r=Object.fromEntries(ce);if(p(n))w(r,n);else{console.log(A.bold(`Available commands:
|
|
5
5
|
`));for(let[o,s]of ce)console.log(` ${A.bold(o)} \u2014 ${s.description}`)}return}let i=ce.get(e);if(!i)throw Object.assign(new Error(`Unknown command: ${e}. Run 'meeting schema' to list all.`),{exit_code:3,code:"NOT_FOUND"});if(p(n))w({command:e,...i},n);else{if(console.log(A.bold(e)+" \u2014 "+i.description+`
|
|
6
|
-
`),Object.keys(i.params).length>0){console.log(A.bold("Parameters:"));for(let[r,o]of Object.entries(i.params)){let s=o.required?A.red("*"):"";console.log(` ${A.cyan(r)}${s} (${o.type}) \u2014 ${o.description}`)}console.log()}console.log(A.bold("Output schema:")),v(i.output)}}catch(i){b(i,n)}}),t}var le=I.hex("#22C55E");function Ee(){let t=new ht("auth").description("Authentication commands");return t.command("login").description("Log in with email OTP").option("--json","Output as JSON").option("--email <email>","Email address (skip prompt)").action(async e=>{try{p(e)||(console.log(),console.log(` ${h.bold("\u{1F511} Log in to meeting.ai")}`),console.log());let n=e.email||await R(` ${I.bold("Email:")} `);if(!n)throw Object.assign(new Error("Email is required"),{exit_code:4,code:"VALIDATION_ERROR"});ve(n);let i;if(p(e))i=await B(n);else{let a=(await import("ora")).default,c=a({text:"Sending OTP code...",color:"blue"}).start();i=await B(n),c.stop(),console.log(` ${le("\u2713")} OTP sent! Check your email`),console.log()}let r=3,o;for(let a=1;a<=r;a++){let c=!p(e)&&a>1?g(` (attempt ${a}/${r})`):"",l=await R(` ${I.bold("OTP Code:")}${c} `);if(!l){if(a<r){p(e)||console.log(` ${I.yellow("\u26A0")} OTP cannot be empty, try again`);continue}throw Object.assign(new Error("OTP code is required (max attempts exceeded)"),{exit_code:4,code:"VALIDATION_ERROR"})}try{o=await oe(n,l,i);break}catch(d){if(a<r){p(e)||console.log(` ${I.yellow("\u26A0")} Invalid OTP, try again`);continue}throw d}}let s;if(o.mfa_required){let a=o.mfa_type;if(a==="webauthn")throw Object.assign(new Error("WebAuthn/passkey 2FA is not supported in CLI. Please log in via the web app at https://meeting.ai"),{exit_code:1,code:"MFA_NOT_SUPPORTED"});let c;if(a==="totp")c=` ${I.bold("Authenticator code:")} `;else if(a==="password")c=` ${I.bold("Password:")} `;else{if(p(e))await z(o.mfa_id,o.session_id);else{let d=(await import("ora")).default,m=d({text:"Sending 2FA code to email...",color:"blue"}).start();await z(o.mfa_id,o.session_id),m.stop(),console.log(` ${le("\u2713")} 2FA code sent to your email`),console.log()}c=` ${I.bold("2FA code (check email):")} `}let l=await R(c);if(!l)throw Object.assign(new Error("2FA code is required"),{exit_code:4,code:"VALIDATION_ERROR"});s=await ie(o.challenge_id,l,o.session_id,a)}else s=o.tokens;te(n),p(e)?w({success:!0,email:n,expires_at:s.expires_at},e):(console.log(` ${le("\u2713")} Logged in as ${I.bold(n)}`),console.log(),console.log(g(" Your token is stored at ~/.config/meeting/config.json")),console.log())}catch(n){b(n,e)}}),t.command("whoami").description("Show current user info").option("--json","Output as JSON").option("--fields <fields>","Select output fields").action(async e=>{try{let n=await ne(),i=JSON.parse(Buffer.from(n.split(".")[1],"base64url").toString()),r={id:i.id,name:i.name,email:i.email||ee()||"unknown",session_id:i.sessionId,token_expires:new Date(i.exp*1e3).toISOString()};p(e)?w(r,e):(console.log(),console.log(` ${h.bold("\u{1F464} Current User")}`),console.log(),v({Id:r.id,Name:r.name,Email:r.email,"Token Expires":r.token_expires}),console.log())}catch(n){b(n,e)}}),t.command("logout").description("Clear stored tokens").option("--json","Output as JSON").action(e=>{Q(),p(e)?w({success:!0,message:"Logged out"},e):console.log(` ${le("\u2713")} Logged out successfully.`)}),k("auth.login",{description:"Log in with email OTP",params:{email:{type:"string",description:"Email address",required:!1}},output:{type:"object",properties:{success:{type:"boolean"},email:{type:"string"},expires_at:{type:"number"}}}}),k("auth.whoami",{description:"Show current user info (decoded from JWT)",params:{},output:{type:"object",properties:{id:{type:"string"},name:{type:"string"},email:{type:"string"},session_id:{type:"string"},token_expires:{type:"string",description:"ISO 8601 timestamp"}}}}),k("auth.logout",{description:"Clear stored tokens",params:{},output:{type:"object",properties:{success:{type:"boolean"},message:{type:"string"}}}}),t}import{Command as Ie}from"commander";import L from"chalk";var yt="cli-0.1.
|
|
6
|
+
`),Object.keys(i.params).length>0){console.log(A.bold("Parameters:"));for(let[r,o]of Object.entries(i.params)){let s=o.required?A.red("*"):"";console.log(` ${A.cyan(r)}${s} (${o.type}) \u2014 ${o.description}`)}console.log()}console.log(A.bold("Output schema:")),v(i.output)}}catch(i){b(i,n)}}),t}var le=I.hex("#22C55E");function Ee(){let t=new ht("auth").description("Authentication commands");return t.command("login").description("Log in with email OTP").option("--json","Output as JSON").option("--email <email>","Email address (skip prompt)").action(async e=>{try{p(e)||(console.log(),console.log(` ${h.bold("\u{1F511} Log in to meeting.ai")}`),console.log());let n=e.email||await R(` ${I.bold("Email:")} `);if(!n)throw Object.assign(new Error("Email is required"),{exit_code:4,code:"VALIDATION_ERROR"});ve(n);let i;if(p(e))i=await B(n);else{let a=(await import("ora")).default,c=a({text:"Sending OTP code...",color:"blue"}).start();i=await B(n),c.stop(),console.log(` ${le("\u2713")} OTP sent! Check your email`),console.log()}let r=3,o;for(let a=1;a<=r;a++){let c=!p(e)&&a>1?g(` (attempt ${a}/${r})`):"",l=await R(` ${I.bold("OTP Code:")}${c} `);if(!l){if(a<r){p(e)||console.log(` ${I.yellow("\u26A0")} OTP cannot be empty, try again`);continue}throw Object.assign(new Error("OTP code is required (max attempts exceeded)"),{exit_code:4,code:"VALIDATION_ERROR"})}try{o=await oe(n,l,i);break}catch(d){if(a<r){p(e)||console.log(` ${I.yellow("\u26A0")} Invalid OTP, try again`);continue}throw d}}let s;if(o.mfa_required){let a=o.mfa_type;if(a==="webauthn")throw Object.assign(new Error("WebAuthn/passkey 2FA is not supported in CLI. Please log in via the web app at https://meeting.ai"),{exit_code:1,code:"MFA_NOT_SUPPORTED"});let c;if(a==="totp")c=` ${I.bold("Authenticator code:")} `;else if(a==="password")c=` ${I.bold("Password:")} `;else{if(p(e))await z(o.mfa_id,o.session_id);else{let d=(await import("ora")).default,m=d({text:"Sending 2FA code to email...",color:"blue"}).start();await z(o.mfa_id,o.session_id),m.stop(),console.log(` ${le("\u2713")} 2FA code sent to your email`),console.log()}c=` ${I.bold("2FA code (check email):")} `}let l=await R(c);if(!l)throw Object.assign(new Error("2FA code is required"),{exit_code:4,code:"VALIDATION_ERROR"});s=await ie(o.challenge_id,l,o.session_id,a)}else s=o.tokens;te(n),p(e)?w({success:!0,email:n,expires_at:s.expires_at},e):(console.log(` ${le("\u2713")} Logged in as ${I.bold(n)}`),console.log(),console.log(g(" Your token is stored at ~/.config/meeting/config.json")),console.log())}catch(n){b(n,e)}}),t.command("whoami").description("Show current user info").option("--json","Output as JSON").option("--fields <fields>","Select output fields").action(async e=>{try{let n=await ne(),i=JSON.parse(Buffer.from(n.split(".")[1],"base64url").toString()),r={id:i.id,name:i.name,email:i.email||ee()||"unknown",session_id:i.sessionId,token_expires:new Date(i.exp*1e3).toISOString()};p(e)?w(r,e):(console.log(),console.log(` ${h.bold("\u{1F464} Current User")}`),console.log(),v({Id:r.id,Name:r.name,Email:r.email,"Token Expires":r.token_expires}),console.log())}catch(n){b(n,e)}}),t.command("logout").description("Clear stored tokens").option("--json","Output as JSON").action(e=>{Q(),p(e)?w({success:!0,message:"Logged out"},e):console.log(` ${le("\u2713")} Logged out successfully.`)}),k("auth.login",{description:"Log in with email OTP",params:{email:{type:"string",description:"Email address",required:!1}},output:{type:"object",properties:{success:{type:"boolean"},email:{type:"string"},expires_at:{type:"number"}}}}),k("auth.whoami",{description:"Show current user info (decoded from JWT)",params:{},output:{type:"object",properties:{id:{type:"string"},name:{type:"string"},email:{type:"string"},session_id:{type:"string"},token_expires:{type:"string",description:"ISO 8601 timestamp"}}}}),k("auth.logout",{description:"Clear stored tokens",params:{},output:{type:"object",properties:{success:{type:"boolean"},message:{type:"string"}}}}),t}import{Command as Ie}from"commander";import L from"chalk";var yt="cli-0.1.3";async function _(t,e={}){let{method:n="GET",body:i,query:r,headers:o={},auth:s=!0,multipart:a}=e,c=D(),l=new URL(t,c);if(r){for(let[f,y]of Object.entries(r))if(y!==void 0)if(Array.isArray(y))for(let $ of y)l.searchParams.append(f,$);else l.searchParams.set(f,String(y))}let d={"x-client-app-version":yt,...o};if(s)try{let f=await ne();d.Authorization=`Bearer ${f}`}catch(f){throw f instanceof F?Object.assign(f,{exit_code:2}):f}let m;a?m=a:i&&(d["Content-Type"]="application/json",m=JSON.stringify(i));let u=await fetch(l.toString(),{method:n,headers:d,body:m});if(!u.ok){let f=u.status,y;try{let S=await u.json(),T=C=>{if(typeof C=="string")return C;if(C&&typeof C=="object"&&"message"in C){let j=C.message;if(typeof j=="string")return j}};y=T(S.message)||T(S.error)||(S.message?JSON.stringify(S.message):void 0)||u.statusText}catch{y=u.statusText}let $=f===401||f===403?2:f===404?3:f===422?4:1,x=f===401?"AUTH_EXPIRED":f===403?"FORBIDDEN":f===404?"NOT_FOUND":f===422?"VALIDATION_ERROR":"API_ERROR",O=new Error(y);throw O.error=!0,O.code=x,O.message=y,O.exit_code=$,O}if(u.status!==204)return u.json()}V();function Y(t){return t.is_title_edited&&t.title?t.title:t.autogenerated_title||t.title||"(untitled)"}function ye(t){return t.autogenerated_title_emoji?t.autogenerated_title_emoji:se(t.integration)}function _t(t){return t.meeting_participants?.length?t.meeting_participants.length:t.speaker_count||0}function _e(t){return(t.meeting_participants||t.participants||[]).map(n=>n.name).filter(n=>!!n)}function we(t){return t.replace(/<em>(.*?)<\/em>/g,(e,n)=>L.bold.white(n))}function wt(t,e=200){let n=t.split(`
|
|
7
7
|
|
|
8
8
|
`)[0].trim();if(n.length<=e)return n;let i=n.slice(0,e),r=i.lastIndexOf(". ");if(r>e*.5)return i.slice(0,r+1);let o=i.lastIndexOf(" ");return o>e*.5?i.slice(0,o)+"...":i+"..."}function bt(t,e=4){let i=(t.meeting_participants||[]).filter(s=>s.name);return{names:[...i].sort((s,a)=>(a.speaking_seconds||0)-(s.speaking_seconds||0)).slice(0,e).map(s=>s.name).filter(s=>!!s),more:Math.max(0,i.length-e)}}function ge(t,e){let n=ye(t),i=Y(t),r=ae(t.integration),o=E(t.duration_in_seconds),s=P(t.started_at||t.created_at),a=_t(t),c=a?`${a} speaker${a>1?"s":""}`:"",l=[s,r,o,c].filter(Boolean).join(g(" \xB7 "));if(console.log(` ${n} ${L.bold(i)}`),console.log(` ${g(t.id)}`),t.status&&t.status!=="finished"){let y=L.yellow(`[${t.status}]`);console.log(` ${l} ${y}`)}else console.log(` ${l}`);t.role==="read"&&console.log(` ${L.cyan("[shared]")}`);let{names:d,more:m}=bt(t);if(d.length>0){let y=d.join(", ")+(m>0?` ${g(`+${m} more`)}`:"");console.log(` ${g(y)}`)}let u=t.meeting_section,f=Array.isArray(u)?u[0]?.text:u?.text;if(f){let y=wt(f);console.log(` ${g(L.italic(y))}`)}e&&e(),console.log()}function Le(){let t=new Ie("list").description("Show recent meetings").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--from <date>",'Filter from date (e.g. 2026-03-01, "last week")').option("--to <date>","Filter to date (e.g. 2026-03-18)").option("--after <date>","Alias for --from").option("--before <date>","Alias for --to").option("--role <role>","Filter by role (owner/read/all)").option("--integration <type>","Filter by integration (zoom/gmeet/teams/livestream/upload)").option("--speaker <name>","Filter by participant name").option("--sort <order>","Sort order (newest/oldest)","newest").option("--status <status>","Filter by status (finished/recording/processing)").option("--limit <n>","Items per page","10").option("--offset <n>","Cursor offset").action(async e=>{try{let n=e.from||e.after,i=e.to||e.before,r=q(e.limit),o;if(!p(e)){let a=(await import("ora")).default;o=a({text:"Loading meetings...",color:"blue"}).start()}let s=await _("/api/v1/meetings",{query:{start_date:n,end_date:i,role:e.role,integration:e.integration?W(e.integration):void 0,status:e.status,sort:e.sort==="oldest"?"asc":void 0,items_per_page:String(r),cursor:e.offset}});if(o?.stop(),p(e))w(s,e);else{let a=s.meeting||[];if(e.speaker){let c=e.speaker.toLowerCase();a=a.filter(l=>_e(l).some(m=>m.toLowerCase().includes(c)))}console.log(),console.log(` ${h.bold("Recent Meetings")}${g(` ${s.total_item.toLocaleString()} total`)}`),console.log();for(let c of a)ge(c);s.next_cursor&&(console.log(g(` More results available. Use --offset ${s.next_cursor}`)),console.log()),console.log(g(" Filters: --from, --to, --integration, --speaker, --role, --sort, --status")),console.log(g(` Search: ${h("meeting search <query>")}`)),console.log()}}catch(n){b(n,e)}});return k("list",{description:"List recent meetings",params:{from:{type:"string",description:"Filter from date (ISO 8601)",required:!1},to:{type:"string",description:"Filter to date (ISO 8601)",required:!1},role:{type:"string",description:"Filter by role (owner/read/all)",required:!1},integration:{type:"string",description:"Filter by integration (zoom/gmeet/teams/livestream/upload)",required:!1},speaker:{type:"string",description:"Filter by participant name (client-side)",required:!1},sort:{type:"string",description:"Sort order (newest/oldest)",required:!1},status:{type:"string",description:"Filter by status (finished/recording/processing)",required:!1},limit:{type:"number",description:"Items per page (default 10, min 5)",required:!1},offset:{type:"number",description:"Cursor offset",required:!1}},output:{type:"object",properties:{total_item:{type:"number"},items_per_page:{type:"number"},next_cursor:{type:"number"},prev_cursor:{type:"number"},meeting:{type:"array",items:{type:"object"}}}}}),t}function je(){let t=new Ie("delete").description("Delete a meeting").argument("[id]","Meeting ID").option("--json","Output as JSON").option("--yes","Skip confirmation prompt").action(async(e,n)=>{if(!e){let i=(await import("chalk")).default,r=i.hex("#2563EB"),o=i.hex("#6B7280");console.error(),console.error(i.red(" \u2717 Missing meeting ID.")),console.error(),console.error(` ${r("Usage:")} meeting delete ${o("<meeting_id>")}`),console.error(),console.error(` ${o("Example:")}`),console.error(` ${r("meeting delete")} 01abc...xyz`),console.error(),console.error(` ${o("\u{1F4A1} Run")} ${r("meeting list")} ${o("to see your meetings and their IDs.")}`),console.error(` ${o("\u26A0\uFE0F This action is permanent and cannot be undone.")}`),console.error(),process.exit(1)}try{if(N(e),!p(n)){let i=e;try{let r=await _(`/api/v1/meeting/${e}`);i=Y(r)}catch{}if(n.yes)console.log(L.yellow(" \u26A0\uFE0F Skipped confirmation via --yes flag"));else if(console.log(),console.log(L.yellow(` \u26A0\uFE0F Delete meeting "${i}" (${e})?`)),console.log(),console.log(" This action cannot be undone."),console.log(g(" If you are an AI agent, please ask your human to confirm this deletion.")),console.log(),await R(` Type ${L.bold("DELETE")} to confirm: `)!=="DELETE"){console.log(g(" Cancelled."));return}}await _(`/api/v1/meeting/${e}`,{method:"DELETE"}),p(n)?w({success:!0,id:e},n):console.log(L.hex("#22C55E")(` \u2713 Meeting ${e} deleted.`))}catch(i){b(i,n)}});return k("delete",{description:"Delete a meeting (soft delete)",params:{id:{type:"string",description:"Meeting ID",required:!0},yes:{type:"boolean",description:"Skip confirmation",required:!1}},output:{type:"object",properties:{success:{type:"boolean"},id:{type:"string"}}}}),t}import{Command as kt}from"commander";import K from"chalk";async function De(t){let e=[],n,r=0;for(;r<10;){let o={items_per_page:"100",cursor:n},s=await _(`/api/v1/meeting/${t}/transcript`,{query:o}),a=s.transcribe||[];if(e.push(...a),!s.next_cursor)break;n=String(s.next_cursor),r++}return e}function $t(t){let e=Math.floor(t/3600),n=Math.floor(t%3600/60),i=Math.floor(t%60);return e>0?`${e}:${String(n).padStart(2,"0")}:${String(i).padStart(2,"0")}`:`${n}:${String(i).padStart(2,"0")}`}function St(t,e){let n=new RegExp(`(${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")})`,"gi");return t.replace(n,(i,r)=>K.bold.yellow(r))}function Pe(){let t=new kt("search").description("Search meetings (notes & transcripts)").argument("[query]","Search keyword").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--transcript","Search within transcript text").option("--limit <n>","Items per page","10").option("--offset <n>","Cursor offset").option("--from <date>","Start from date").option("--to <date>","End before date").option("--integration <type>","Filter by integration (zoom/gmeet/teams/livestream/upload)").option("--role <role>","Filter by role (owner/read)").option("--speaker <name>","Filter by participant name").option("--no-highlight","Hide search highlights").action(async(e,n)=>{e||(console.error(),console.error(K.red(" \u2717 Missing search query.")),console.error(),console.error(` ${h("Usage:")} meeting search ${g("<query>")}`),console.error(),console.error(` ${g("Examples:")}`),console.error(` ${h("meeting search")} "quarterly review"`),console.error(` ${h("meeting search")} marketing`),console.error(),console.error(` ${g("\u{1F4A1} Search looks through meeting titles, notes, and transcripts.")}`),console.error(),process.exit(1));try{let i=q(n.limit),r;if(!p(n)){let a=(await import("ora")).default;r=a({text:`Searching "${e}"...`,color:"blue"}).start()}let o=await _("/api/v1/meetings/search",{query:{keyword:e,items_per_page:String(n.transcript?Math.min(i,5):i),cursor:n.offset,start_from_date:n.from,end_before_date:n.to,integration:n.integration?W(n.integration):void 0,role:n.role}});r?.stop();let s=o.meeting||[];if(n.speaker){let a=n.speaker.toLowerCase();s=s.filter(c=>_e(c).some(d=>d.toLowerCase().includes(a)))}if(n.transcript&&!p(n)){let a=s.slice(0,5);if(a.length===0){console.log(),console.log(g(" No meetings found.")),console.log();return}if(!p(n)){let d=(await import("ora")).default;r=d({text:`Searching transcripts (${a.length} meetings)...`,color:"blue"}).start()}let c=await Promise.allSettled(a.map(d=>De(d.id).then(m=>({meeting:d,transcript:m}))));r?.stop(),console.log(),console.log(` ${h.bold("\u{1F50D} Transcript Search")}${g(` "${e}"`)}`),console.log();let l=!1;for(let d of c){if(d.status!=="fulfilled")continue;let{meeting:m,transcript:u}=d.value;if(u.length===0)continue;let f=e.toLowerCase(),y=[];for(let S=0;S<u.length;S++)u[S].text.toLowerCase().includes(f)&&y.push(S);if(y.length===0)continue;l=!0;let $=ye(m),x=Y(m),O=P(m.started_at||m.created_at);console.log(` ${$} ${K.bold(x)} ${g(`(${O})`)}`);for(let S of y.slice(0,3)){let T=u[S],C=$t(T.start),j=St(T.text.length>200?T.text.slice(0,200)+"...":T.text,e);console.log(` ${g('"')}${j}${g('"')}`),console.log(` ${g(`\u2014 ${T.speaker}, ${C}`)}`)}y.length>3&&console.log(` ${g(`+${y.length-3} more matches`)}`),console.log()}l||(console.log(g(" No transcript matches found.")),console.log());return}if(n.transcript&&p(n)){let a=s.slice(0,5),c=[],l=await Promise.allSettled(a.map(d=>De(d.id).then(m=>({meeting:d,transcript:m}))));for(let d of l){if(d.status!=="fulfilled")continue;let{meeting:m,transcript:u}=d.value,f=e.toLowerCase(),y=u.filter($=>$.text.toLowerCase().includes(f)).map($=>({speaker:$.speaker,text:$.text,start:$.start}));y.length>0&&c.push({meeting_id:m.id,title:Y(m),matches:y})}w({query:e,results:c,total_meetings_searched:a.length},n);return}if(p(n))w(o,n);else{console.log(),console.log(` ${h.bold("Search Results")}${g(` ${o.total_item} total`)}`),console.log();for(let a of s)ge(a,()=>{if(n.highlight!==!1){let c=a.highlights||[];for(let l of c.slice(0,3)){let d=l.content||l.text||"";if(!d)continue;let m=d.replace(/\[\d+\|\d+\.\d+-\d+\.\d+\]\s*/g,""),u=we(m.length>200?m.slice(0,200)+"...":m),y={transcription:"\u{1F4DD} Transcript",notes:"\u{1F4CB} Notes",template_section:"\u{1F4CB} Notes",title:"\u{1F4CC} Title"}[l.field||""]||l.field||"Unknown",$=l.reference?.timestamp_start?` ${g(`at ${Math.floor(l.reference.timestamp_start/60)}:${String(Math.floor(l.reference.timestamp_start%60)).padStart(2,"0")}`)}`:"";console.log(` ${K.cyan(y)}${$}`),console.log(` ${g("\u2192")} ${u}`)}}});if(o.next_cursor){if(console.log(g(` Showing ${s.length} of ${o.total_item} results`)),console.log(),process.stdout.isTTY){let{prompt:a}=await Promise.resolve().then(()=>(V(),Te)),c=await a(` ${h("\u2192")} Show more results? ${g("(y/n)")} `);if(c?.toLowerCase()==="y"||c?.toLowerCase()==="yes"){let l=await _("/api/v1/meetings/search",{query:{keyword:e,items_per_page:String(i),cursor:String(o.next_cursor),start_from_date:n.from,end_before_date:n.to,integration:n.integration?W(n.integration):void 0,role:n.role}}),d=l.meeting||[];console.log();for(let m of d)ge(m,()=>{let u=m.highlights||[];for(let f of u.slice(0,3)){let y=f.content||f.text||"";if(!y)continue;let $=y.replace(/\[\d+\|\d+\.\d+-\d+\.\d+\]\s*/g,""),x=we($.length>200?$.slice(0,200)+"...":$),S={transcription:"\u{1F4DD} Transcript",notes:"\u{1F4CB} Notes",template_section:"\u{1F4CB} Notes",title:"\u{1F4CC} Title"}[f.field||""]||f.field||"Unknown";console.log(` ${K.cyan(S)}`),console.log(` ${g("\u2192")} ${x}`)}});l.next_cursor&&console.log(g(` More available. Use: meeting search "${e}" --offset ${l.next_cursor}`))}}else console.log(g(` Next page: meeting search "${e}" --offset ${o.next_cursor}`));console.log()}console.log(g(` Tip: Use ${h("--transcript")} to search within transcript text`)),console.log()}}catch(i){b(i,n)}});return k("search",{description:"Search meetings by keyword (notes & transcripts)",params:{query:{type:"string",description:"Search keyword",required:!0},transcript:{type:"boolean",description:"Search within transcript text",required:!1},limit:{type:"number",description:"Items per page",required:!1},offset:{type:"number",description:"Cursor offset",required:!1},from:{type:"string",description:"Start from date",required:!1},to:{type:"string",description:"End before date",required:!1},integration:{type:"string",description:"Filter by integration",required:!1},role:{type:"string",description:"Filter by role",required:!1},speaker:{type:"string",description:"Filter by participant name",required:!1}},output:{type:"object",properties:{total_item:{type:"number"},meeting:{type:"array",items:{type:"object"}}}}}),t}import{Command as Ot}from"commander";import Tt from"chalk";async function de(t,e,n={}){let{interval:i=3e3,timeout:r=3e5}=n,o=Date.now()+r;for(;;){let s=await t();if(e(s))return s;if(Date.now()+i>o)throw new Error(`Polling timed out after ${r/1e3}s`);await xt(i)}}function xt(t){return new Promise(e=>setTimeout(e,t))}var Ne=Tt.hex("#22C55E");function Ue(){let t=new Ot("bot").description("Meeting bot commands");return t.command("send").description("Send bot to a meeting URL").requiredOption("--url <url>","Meeting URL to join").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--wait","Wait until meeting is complete").option("--wait-timeout <seconds>","Wait timeout in seconds","300").action(async e=>{try{let n;if(!p(e)){let o=(await import("ora")).default;n=o({text:"Sending bot to meeting...",color:"blue"}).start()}let i=await _("/api/v1/meeting",{method:"POST",query:{device:"cli"},body:{meeting:{url:e.url,integration:vt(e.url),started_at:new Date().toISOString(),language:"auto",participants:[]}}}),r=i.meeting||i;if(await _(`/api/v1/meeting/${r.id}/record-meeting`,{method:"POST",body:{is_user_rejoin:!1}}),n?.stop(),e.wait){if(!p(e)){let s=(await import("ora")).default;n=s({text:"Waiting for meeting to complete...",color:"blue"}).start()}let o=await de(()=>_(`/api/v1/meeting/${r.id}`),s=>s.status==="done"||s.status==="failed",{timeout:parseInt(e.waitTimeout)*1e3});n?.stop(),p(e)?w(o,e):(console.log(),v({ID:o.id,Title:o.title,Status:o.status,URL:o.url}),console.log())}else p(e)?w(r,e):(console.log(` ${Ne("\u2713")} Bot sent successfully.`),console.log(),v({ID:r.id,Title:r.title||"(pending)",Status:r.status}),console.log())}catch(n){b(n,e)}}),t.command("status <meeting_id>").description("Check bot/meeting status").option("--json","Output as JSON").option("--fields <fields>","Select output fields").action(async(e,n)=>{try{N(e);let i;if(!p(n)){let o=(await import("ora")).default;i=o({text:"Checking status...",color:"blue"}).start()}let r=await _(`/api/v1/meeting/${e}/progress`);i?.stop(),p(n)?w(r,n):(console.log(),console.log(` ${h.bold("\u{1F916} Bot Status")}`),console.log(),v({ID:r.id||e,Title:r.title,Status:r.status,Integration:r.integration}),console.log())}catch(i){b(i,n)}}),t.command("leave <meeting_id>").description("Signal bot to leave meeting").option("--json","Output as JSON").action(async(e,n)=>{try{N(e),await _("/api/v1/recall/leave",{method:"POST",body:{id:e}}),p(n)?w({success:!0,meeting_id:e},n):console.log(` ${Ne("\u2713")} Bot leaving meeting ${g(e)}.`)}catch(i){b(i,n)}}),k("bot.send",{description:"Send bot to a meeting URL",params:{url:{type:"string",description:"Meeting URL to join",required:!0},wait:{type:"boolean",description:"Wait until complete",required:!1},"wait-timeout":{type:"number",description:"Wait timeout in seconds (default 300)",required:!1}},output:{type:"object",properties:{id:{type:"string"},title:{type:"string"},status:{type:"string"},url:{type:"string"}}}}),k("bot.status",{description:"Check bot/meeting status",params:{meeting_id:{type:"string",description:"Meeting ID",required:!0}},output:{type:"object",properties:{id:{type:"string"},title:{type:"string"},status:{type:"string"},integration:{type:"string"},url:{type:"string"}}}}),k("bot.leave",{description:"Signal bot to leave meeting",params:{meeting_id:{type:"string",description:"Meeting ID",required:!0}},output:{type:"object",properties:{success:{type:"boolean"},meeting_id:{type:"string"}}}}),t}function vt(t){return t.includes("zoom.us")?"zoom":t.includes("meet.google.com")?"gmeet":t.includes("teams.microsoft.com")?"teams":t.includes("webex.com")?"webex":"gmeet"}import{Command as Ct}from"commander";import Mt from"chalk";var Rt=Mt.hex("#22C55E");function qe(){let t=new Ct("calendar").description("Calendar commands");return t.command("events").description("List calendar events").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--upcoming","Show upcoming events from today").option("--from <date>","Start date (YYYY-MM-DD)").option("--to <date>","End date (YYYY-MM-DD)").option("--limit <n>","Items per page","50").option("--timezone <tz>","Timezone (default: local)",Intl.DateTimeFormat().resolvedOptions().timeZone).action(async e=>{try{let n;if(!p(e)){let o=(await import("ora")).default;n=o({text:"Loading events...",color:"blue"}).start()}let i={items_per_page:e.limit,timezone:e.timezone};e.upcoming?i.date=new Date().toISOString().split("T")[0]:e.from&&e.to?(i.start_date=e.from,i.end_date=e.to):e.from&&(i.date=e.from);let r=await _("/api/v1/calendar/calendar_events",{query:i});if(n?.stop(),p(e))w(r,e);else{let o=r.calendar_events||[];console.log(),console.log(` ${h.bold("\u{1F4C5} Calendar Events")}${g(` ${o.length} shown`)}`),console.log(),J(o,[{key:"title",label:"Title"},{key:"status",label:"Status"},{key:"start_time",label:"Start",format:s=>s?new Date(s).toLocaleString():"-"},{key:"end_time",label:"End",format:s=>s?new Date(s).toLocaleString():"-"}]),console.log()}}catch(n){b(n,e)}}),t.command("sync").description("Trigger calendar sync").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--from <date>","Start date").option("--to <date>","End date").action(async e=>{try{let n;if(!p(e)){let r=(await import("ora")).default;n=r({text:"Syncing calendar...",color:"blue"}).start()}let i=await _("/api/v1/calendar/sync",{method:"POST",query:{start_date:e.from,end_date:e.to}});n?.stop(),p(e)?w(i,e):console.log(` ${Rt("\u2713")} Sync status: ${i.sync_status}`)}catch(n){b(n,e)}}),t.command("accounts").description("List calendar accounts").option("--json","Output as JSON").option("--fields <fields>","Select output fields").action(async e=>{try{let n;if(!p(e)){let r=(await import("ora")).default;n=r({text:"Loading accounts...",color:"blue"}).start()}let i=await _("/api/v1/calendar/accounts");if(n?.stop(),p(e))w(i,e);else{let r=i.calendar_accounts||[];console.log(),console.log(` ${h.bold("\u{1F517} Calendar Accounts")}${g(` ${r.length} connected`)}`),console.log(),J(r,[{key:"email",label:"Email"},{key:"integration_id",label:"Integration"},{key:"status",label:"Status"}]),console.log()}}catch(n){b(n,e)}}),k("calendar.events",{description:"List calendar events",params:{upcoming:{type:"boolean",description:"Show upcoming events from today",required:!1},from:{type:"string",description:"Start date (YYYY-MM-DD)",required:!1},to:{type:"string",description:"End date (YYYY-MM-DD)",required:!1},limit:{type:"number",description:"Items per page (default 50)",required:!1},timezone:{type:"string",description:"Timezone (default: local)",required:!1}},output:{type:"object",properties:{calendar_events:{type:"array",items:{type:"object"}},next_cursor:{type:"string"}}}}),k("calendar.sync",{description:"Trigger calendar sync",params:{from:{type:"string",description:"Start date (YYYY-MM-DD)",required:!1},to:{type:"string",description:"End date (YYYY-MM-DD)",required:!1}},output:{type:"object",properties:{sync_status:{type:"string"},synced_accounts:{type:"array"}}}}),k("calendar.accounts",{description:"List connected calendar accounts",params:{},output:{type:"object",properties:{user_id:{type:"string"},calendar_accounts:{type:"array",items:{type:"object"}}}}}),t}import{Command as Et}from"commander";import H from"chalk";import{open as It,stat as Lt}from"fs/promises";import{basename as Ae,extname as jt}from"path";var be=H.hex("#22C55E"),me=5*1024*1024;function Dt(t){return t.startsWith("http://")||t.startsWith("https://")}function Pt(t){let e=jt(t).toLowerCase();return{".mp3":"audio/mpeg",".wav":"audio/wav",".m4a":"audio/mp4",".aac":"audio/aac",".ogg":"audio/ogg",".flac":"audio/flac",".wma":"audio/x-ms-wma",".mp4":"video/mp4",".webm":"video/webm",".mkv":"video/x-matroska",".avi":"video/x-msvideo",".mov":"video/quicktime",".wmv":"video/x-ms-wmv",".flv":"video/x-flv"}[e]||"audio/mpeg"}function Nt(t){return t.startsWith("video/")?"video":"audio"}function ke(t){return t<1024?`${t}B`:t<1024*1024?`${(t/1024).toFixed(0)}KB`:t<1024*1024*1024?`${(t/(1024*1024)).toFixed(1)}MB`:`${(t/(1024*1024*1024)).toFixed(1)}GB`}function Ut(t,e,n){let i=Math.round(e/n*100),r=20,o=Math.round(e/n*r),s="\u2588".repeat(o)+"\u2591".repeat(r-o),a=` \u2B06 Uploading ${t} ${s} ${i}% (${ke(e)} / ${ke(n)})`;process.stdout.write(`\r${a}`)}function Fe(){let t=new Et("upload").description("Upload recording for transcription").argument("[source]","Local file path or URL").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--title <title>","Meeting title").option("--language <lang>","Language code (default: auto-detect)","auto").option("--wait","Wait until transcription is complete").option("--wait-timeout <seconds>","Wait timeout in seconds","300").action(async(e,n)=>{e||(console.error(),console.error(H.red(" \u2717 Missing file path or URL.")),console.error(),console.error(` ${H.hex("#2563EB")("Usage:")} meeting upload ${g("<file_or_url>")}`),console.error(),console.error(` ${g("Examples:")}`),console.error(` ${H.hex("#2563EB")("meeting upload")} recording.mp4`),console.error(` ${H.hex("#2563EB")("meeting upload")} https://example.com/audio.mp3`),console.error(),console.error(` ${g("\u{1F4A1} Supported formats: mp3, mp4, m4a, wav, webm, ogg, mov, avi.")}`),console.error(` ${g("\u{1F4A1} Language is auto-detected. Override with --language en.")}`),console.error(),process.exit(1));try{let i;if(Dt(e)){let r;if(!p(n)){let s=(await import("ora")).default;r=s({text:"Submitting URL for transcription...",color:"blue"}).start()}let o=await _("/api/v1/meeting",{method:"POST",query:{device:"cli"},body:{meeting:{url:e,title:n.title,integration:"upload",language:n.language,started_at:new Date().toISOString(),participants:["CLI User"]}}});i="meeting"in o&&o.meeting?o.meeting:o,r?.stop(),!p(n)&&!n.wait&&(console.log(` ${be("\u2713")} URL submitted for transcription.`),console.log())}else{let o=(await Lt(e)).size,s=Ae(e),a=Pt(e),c=Nt(a),l=Math.ceil(o/me);p(n)||(console.log(),console.log(` ${g("File:")} ${s} ${g(ke(o))} ${g(a)}`),console.log());let d;if(!p(n)){let x=(await import("ora")).default;d=x({text:"Creating meeting...",color:"blue"}).start()}let m=await _("/api/v1/meeting",{method:"POST",query:{device:"cli"},body:{meeting:{participants:["CLI User"],started_at:new Date().toISOString(),language:n.language,integration:"upload",...n.title?{title:n.title}:{}}}});i="meeting"in m&&m.meeting?m.meeting:m,d?.stop();let u=i.id;if(!p(n)){let x=(await import("ora")).default;d=x({text:"Initializing upload...",color:"blue"}).start()}let f=await _(`/api/v1/meeting/${u}/media2`,{method:"POST",body:{media:{file_name:s,file_size:o,mime_type:a,total_part:l,type:c}}});d?.stop();let y=f.meeting_file.id,$=await It(e,"r");try{let x=Buffer.alloc(me),O=0;for(let S=0;S<l;S++){let T=S*me,C=Math.min(me,o-T),{bytesRead:j}=await $.read(x,0,C,T),ot=x.subarray(0,j),it=T+j-1,xe=new FormData;xe.append("upload",new Blob([new Uint8Array(ot)])),await _(`/api/v1/meeting/${u}/media/${y}`,{method:"POST",multipart:xe,headers:{"First-Byte":String(T),"Last-Byte":String(it),"Total-Byte":String(o),"Part-Number":String(S)}}),O+=j,p(n)||Ut(s,O,o)}}finally{await $.close()}await _(`/api/v1/meeting/${u}`,{method:"PATCH",body:{meeting:{finished_at:new Date().toISOString()}}}),p(n)||(process.stdout.write(`
|
|
9
9
|
`),console.log(` ${be("\u2713")} Upload complete \u2014 transcription started.`),console.log())}if(n.wait){let r;if(!p(n)){let s=(await import("ora")).default;r=s({text:"Processing transcription...",color:"blue"}).start()}let o=await de(()=>_(`/api/v1/meeting/${i.id}`),s=>s.status==="done"||s.status==="finished"||s.status==="failed",{timeout:parseInt(n.waitTimeout)*1e3});r?.stop(),p(n)?w(o,n):(console.log(),v({ID:o.id,Title:o.title,Status:o.status}),console.log())}else if(p(n))w(i,n);else{v({ID:i.id,Title:i.title||Ae(e),Status:i.status}),console.log();let r=i.status;r==="created"||r==="uploading"?console.log(" \u23F3 File uploaded. Processing will start shortly \u2014 you can close this now."):r==="processing_audio"||r==="processing"?console.log(" \u23F3 Transcription in progress \u2014 you can close this now. It will take a few minutes."):r==="finished"||r==="done"?console.log(` ${be("\u2713")} Transcription complete \u2014 notes are ready!`):r==="failed"&&console.log(" \u274C Processing failed."),console.log(),console.log(g(` Check status: meeting read ${i.id}`)),console.log()}}catch(i){b(i,n)}});return k("upload",{description:"Upload a local file or URL for transcription",params:{source:{type:"string",description:"Local file path or URL",required:!0},title:{type:"string",description:"Meeting title",required:!1},language:{type:"string",description:"Language code (default: auto-detect)",required:!1},wait:{type:"boolean",description:"Wait until complete",required:!1},"wait-timeout":{type:"number",description:"Wait timeout in seconds",required:!1}},output:{type:"object",properties:{id:{type:"string"},title:{type:"string"},status:{type:"string"}}}}),t}import{Command as qt}from"commander";import G from"chalk";async function Je(t){let e=[],n;for(;;){let i={items_per_page:"100"};n&&(i.cursor=n);let r=await _(`/api/v1/meeting/${t}/transcript`,{query:i}),s=(r.transcribe||r.transcript||[]).map(a=>({...a,start:typeof a.start=="string"?parseFloat(a.start):a.start,end:typeof a.end=="string"?parseFloat(a.end):a.end,speaker:a.speaker||a.meeting_participants?.[0]?.name||a.contacts?.[0]?.name||"Unknown Speaker"}));if(e.push(...s),r.next_cursor)n=String(r.next_cursor);else break}return e}function $e(t){let e=Math.floor(t/3600),n=Math.floor(t%3600/60),i=Math.floor(t%60);return e>0?`${e}:${String(n).padStart(2,"0")}:${String(i).padStart(2,"0")}`:`${n}:${String(i).padStart(2,"0")}`}function At(t,e){let n=new RegExp(`(${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")})`,"gi");return t.replace(n,(i,r)=>G.bold.yellow(r))}function Ft(t,e,n=5){let i=n*60,r=[];for(let c=0;c<t.length;c++)t[c].text.toLowerCase().includes(e.toLowerCase())&&r.push(c);if(r.length===0)return{sections:[],matchCount:0};let o=[];for(let c of r){let l=t[c].start;o.push({start:Math.max(0,l-i),end:l+i})}let s=[o[0]];for(let c=1;c<o.length;c++){let l=s[s.length-1];o[c].start<=l.end?l.end=Math.max(l.end,o[c].end):s.push(o[c])}let a=[];for(let c of s){let l=t.filter(d=>d.start>=c.start&&d.start<=c.end);l.length>0&&a.push(l)}return{sections:a,matchCount:r.length}}function Be(t,e){let n="";for(let i of t){i.speaker!==n&&(n&&console.log(),console.log(` ${G.bold(i.speaker)}`),console.log(g(" "+"\u2500".repeat(35))),n=i.speaker);let r=$e(i.start),o=e?At(i.text,e):i.text;console.log(` ${g(r)} ${o}`)}}function ze(){let t=new qt("transcript").description("Meeting transcript & speakers").argument("[meeting_id]","Meeting ID").option("--json","Output as JSON").option("--fields <fields>","Select output fields").option("--search <query>","Search within transcript (shows \xB15min context)").option("--full","Show complete raw transcript").option("--speaker <name>","Filter by speaker name").option("--from-time <minutes>","Start from time (minutes)").option("--to-time <minutes>","End at time (minutes)").action(async(e,n)=>{e||(console.error(),console.error(G.red(" \u2717 Missing meeting ID.")),console.error(),console.error(` ${h("Usage:")} meeting transcript ${g("<meeting_id>")}`),console.error(),console.error(` ${g("Examples:")}`),console.error(` ${h("meeting transcript")} 01abc...xyz`),console.error(` ${h("meeting transcript")} 01abc...xyz --full`),console.error(` ${h("meeting transcript")} 01abc...xyz --search "action items"`),console.error(),console.error(` ${g("\u{1F4A1} Without flags, shows speakers and AI summary.")}`),console.error(` ${g("\u{1F4A1} Use --full for the complete word-by-word transcript.")}`),console.error(),process.exit(1));try{if(N(e),n.search){let s;if(!p(n)){let m=(await import("ora")).default;s=m({text:`Searching transcript for "${n.search}"...`,color:"blue"}).start()}let a=await Je(e);s?.stop();let c=a;if(n.speaker){let m=n.speaker.toLowerCase();c=c.filter(u=>u.speaker.toLowerCase().includes(m))}let{sections:l,matchCount:d}=Ft(c,n.search);if(p(n))w({matchCount:d,sections:l.flat()},n);else if(console.log(),console.log(` ${h.bold("\u{1F50D} Transcript Search")}${g(` ${d} match${d!==1?"es":""} for "${n.search}"`)}`),console.log(),l.length===0)console.log(g(" No matches found.")),console.log();else for(let m=0;m<l.length;m++){m>0&&(console.log(g(" \xB7\xB7\xB7 ")),console.log());let u=l[m][0],f=l[m][l[m].length-1];console.log(g(` [${$e(u.start)} \u2013 ${$e(f.end||f.start)}]`)),console.log(),Be(l[m],n.search),console.log()}return}if(n.full){let s;if(!p(n)){let c=(await import("ora")).default;s=c({text:"Loading transcript...",color:"blue"}).start()}let a=await Je(e);if(s?.stop(),n.speaker){let c=n.speaker.toLowerCase();a=a.filter(l=>l.speaker.toLowerCase().includes(c))}if(n.fromTime||n.toTime){let c=n.fromTime?parseFloat(n.fromTime):void 0,l=n.toTime?parseFloat(n.toTime):void 0;a=a.filter(d=>{let m=d.start/60;return!(c!==void 0&&m<c||l!==void 0&&m>l)})}p(n)?w({transcript:a,total:a.length},n):(console.log(),console.log(` ${h.bold("\u{1F399}\uFE0F Full Transcript")}`),console.log(),Be(a),console.log());return}let i;if(!p(n)){let s=(await import("ora")).default;i=s({text:"Loading transcript summary...",color:"blue"}).start()}let[r,o]=await Promise.all([_(`/api/v1/meeting/${e}/sections-complete`),_(`/api/v1/meeting/${e}/contacts`).catch(()=>null)]);if(i?.stop(),p(n))w({sections:r,speakers:o},n);else{let s=o?Array.isArray(o)?o:o.contacts||[]:[];if(s.length>0){console.log(),console.log(` ${h.bold("\u{1F465} Speakers")}`),console.log();let c=[...s].sort((l,d)=>(d.total_talk_time||0)-(l.total_talk_time||0));for(let l of c){let d=l.total_talk_time?E(l.total_talk_time):"",m=[l.role,l.company].filter(Boolean).join(" @ "),u=[d,m].filter(Boolean).join(g(" \xB7 "));console.log(` ${G.bold(l.name||"(unknown)")}${u?" "+g(u):""}`)}}let a=r.meeting_sections||r.sections||[];if(a.length>0){console.log(),console.log(` ${h.bold("\u{1F4DD} Summary")}`),console.log();for(let c of a){if(console.log(` ${G.bold(c.title||"Untitled Section")}`),console.log(g(" "+"\u2500".repeat(40))),c.content){let l=c.content.split(`
|
|
@@ -75,7 +75,7 @@ meeting schema List all commands and params
|
|
|
75
75
|
## Adopt as Agent Skill
|
|
76
76
|
|
|
77
77
|
To use this as an agent skill, save the content above as SKILL.md in your skills directory.`;function He(){return new Kt("help").description("Full syntax and agent integration guide").action(()=>{process.stdout.write(Ht+`
|
|
78
|
-
`)})}import{Command as Gt}from"commander";import{execSync as Ge}from"child_process";function Ze(){return new Gt("update").description("Update meeting CLI to the latest version").action(async()=>{let e=(await import("chalk")).default,n=(await import("ora")).default,i=e.hex("#22C55E"),r=e.hex("#2563EB"),o=e.hex("#6B7280");console.log(),console.log(` ${r.bold("meeting update")}`),console.log();let s=n({text:"Checking for updates...",color:"blue"}).start();try{let a=Ge("npm update -g @meeting-ai/cli 2>&1",{encoding:"utf-8",timeout:6e4});s.stop();try{let c=Ge("npm list -g @meeting-ai/cli --depth=0 --json 2>/dev/null",{encoding:"utf-8",timeout:1e4}),d=JSON.parse(c).dependencies?.["@meeting-ai/cli"]?.version;console.log(d?` ${i("\u2713")} Updated to ${e.bold(`v${d}`)}`:` ${i("\u2713")} Up to date`)}catch{console.log(` ${i("\u2713")} Update complete`)}}catch{s.stop(),console.log(e.red(" \u2717 Update failed. Try manually:")),console.log(` ${r("npm update -g @meeting-ai/cli")}`)}console.log()})}var Zt=3600*1e3,Xt="https://registry.npmjs.org/@meeting-ai/cli/latest";function Qt(){return"0.1.
|
|
78
|
+
`)})}import{Command as Gt}from"commander";import{execSync as Ge}from"child_process";function Ze(){return new Gt("update").description("Update meeting CLI to the latest version").action(async()=>{let e=(await import("chalk")).default,n=(await import("ora")).default,i=e.hex("#22C55E"),r=e.hex("#2563EB"),o=e.hex("#6B7280");console.log(),console.log(` ${r.bold("meeting update")}`),console.log();let s=n({text:"Checking for updates...",color:"blue"}).start();try{let a=Ge("npm update -g @meeting-ai/cli 2>&1",{encoding:"utf-8",timeout:6e4});s.stop();try{let c=Ge("npm list -g @meeting-ai/cli --depth=0 --json 2>/dev/null",{encoding:"utf-8",timeout:1e4}),d=JSON.parse(c).dependencies?.["@meeting-ai/cli"]?.version;console.log(d?` ${i("\u2713")} Updated to ${e.bold(`v${d}`)}`:` ${i("\u2713")} Up to date`)}catch{console.log(` ${i("\u2713")} Update complete`)}}catch{s.stop(),console.log(e.red(" \u2717 Update failed. Try manually:")),console.log(` ${r("npm update -g @meeting-ai/cli")}`)}console.log()})}var Zt=3600*1e3,Xt="https://registry.npmjs.org/@meeting-ai/cli/latest";function Qt(){return"0.1.3"}function Xe(){return ue().get("update")}function en(t){ue().set("update",t)}function tn(t,e){let n=t.split(".").map(Number),i=e.split(".").map(Number);for(let r=0;r<3;r++){if((n[r]||0)>(i[r]||0))return!0;if((n[r]||0)<(i[r]||0))return!1}return!1}function Qe(){let t=Xe();t&&Date.now()-t.checked_at<Zt||fetch(Xt).then(e=>e.ok?e.json():null).then(e=>{e?.version&&en({latest_version:e.version,checked_at:Date.now()})}).catch(()=>{})}function pe(){let t=Xe();if(!t)return null;let e=Qt();return tn(t.latest_version,e)?`Update available: ${e} \u2192 ${t.latest_version} \u2014 run: npm update -g @meeting-ai/cli`:null}V();var nt="0.1.3";function on(){let t=new nn;return t.name("meeting").description("CLI for Meeting.ai \u2014 your meetings, at your fingertips").version(nt),t.addCommand(Pe()),t.addCommand(Le()),t.addCommand(Ke()),t.addCommand(ze()),t.addCommand(Fe()),t.addCommand(je()),t.addCommand(Ee()),t.addCommand(Ue()),t.addCommand(qe()),t.addCommand(We()),t.addCommand(Re()),t.addCommand(He()),t.addCommand(Ze()),t.command("logout").description("Log out and clear stored tokens").action(()=>{Q(),console.log(" \u2713 Logged out successfully.")}),t}async function et(t,e){console.log(` ${e("Commands:")}`),console.log(` ${t("meeting search")} ${e("<query>")} ${e("Search meetings (notes & transcripts)")}`),console.log(` ${t("meeting list")} ${e("Show 10 recent meetings")}`),console.log(` ${t("meeting read")} ${e("<url_or_id>")} ${e("Read meeting notes (URL, ID, or link)")}`),console.log(` ${t("meeting transcript")} ${e("<id>")} ${e("Meeting transcript & speakers")}`),console.log(` ${t("meeting upload")} ${e("<file|url>")} ${e("Upload recording for transcription")}`),console.log(` ${t("meeting bot send")} ${e("--url <url>")} ${e("Send bot to a meeting")}`),console.log(` ${t("meeting calendar events")} ${e("View calendar events")}`),console.log(` ${t("meeting contacts list")} ${e("Browse contacts")}`),console.log(` ${t("meeting delete")} ${e("<id>")} ${e("Delete a meeting")}`),pe()&&console.log(` ${t("meeting update")} ${e("Update CLI")}`),console.log(),console.log(` ${e("Run")} ${t("meeting help")} ${e("for full syntax and agent integration guide.")}`),console.log();try{let r=((await _("/api/v1/meetings",{query:{items_per_page:"5"}})).meeting||[]).slice(0,5);if(r.length>0){console.log(` ${e("Recent meetings:")}`);for(let o of r){let s=o.is_title_edited&&o.title?o.title:o.autogenerated_title||o.title||"(untitled)",a=o.autogenerated_title_emoji||"",c=o.started_at?new Date(o.started_at).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}):"",l=o.duration_in_seconds?o.duration_in_seconds>=3600?`${Math.floor(o.duration_in_seconds/3600)}h ${Math.floor(o.duration_in_seconds%3600/60)}m`:`${Math.floor(o.duration_in_seconds/60)} min`:"",d=o.integration==="gmeet"?"Google Meet":o.integration==="zoom"?"Zoom":o.integration==="livestream"?"In-person":o.integration==="upload"?"Upload":o.integration==="teams"?"Teams":o.integration||"",m=[c,d,l].filter(Boolean).join(" \xB7 ");console.log(` ${a?a+" ":""}${t(s)}`),console.log(` ${e(m)} ${e("ID:")} ${o.id}`)}console.log()}}catch{}}function rn(){let t=pe();t&&import("chalk").then(({default:e})=>{console.log(` ${e.hex("#F59E0B")(t)}`),console.log()}).catch(()=>{})}async function sn(){let t=(await import("chalk")).default,e=t.hex("#2563EB"),n=t.hex("#22C55E"),i=t.hex("#6B7280"),r=t.hex("#EA8232"),o=t.hex("#22C55E"),s=e.bold(`
|
|
79
79
|
\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
80
80
|
\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
|
|
81
81
|
\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557
|
package/package.json
CHANGED