@meeting-ai/cli 0.1.0 → 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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # meeting — CLI for Meeting.ai
2
2
 
3
- ![Meeting.ai CLI](https://assets.meeting.ai/cli/cli-screenshot.jpg)
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
- Beautiful, agent-friendly command-line interface for Meeting.ai. Wraps the Audyno REST API.
5
+ ![Meeting.ai CLI](https://raw.githubusercontent.com/bahasa-ai/meeting-cli/main/docs/cli-hero.png)
6
6
 
7
7
  ## Install
8
8
 
@@ -10,204 +10,80 @@ Beautiful, agent-friendly command-line interface for Meeting.ai. Wraps the Audyn
10
10
  npm install -g @meeting-ai/cli
11
11
  ```
12
12
 
13
- Or from source:
13
+ ## Get Started
14
14
 
15
15
  ```bash
16
- git clone <repo> && cd meeting-cli
17
- npm install && npm run build && npm link
16
+ meeting # Welcome screen + recent meetings
17
+ meeting auth login # Log in with email OTP
18
+ meeting list # Browse your recent meetings
19
+ meeting read <id> # Read full meeting notes & action items
18
20
  ```
19
21
 
20
- ## Quick Start
22
+ ## What You Can Do
21
23
 
22
- ```bash
23
- # Show welcome banner
24
- meeting
25
-
26
- # Log in
27
- meeting auth login
28
-
29
- # List recent meetings (pretty output)
30
- meeting list --limit 10
31
-
32
- # Same thing, JSON output (for agents/scripts)
33
- meeting list --limit 10 --json
34
- ```
35
-
36
- ## Authentication
37
-
38
- ```bash
39
- # Interactive login (email OTP) — beautiful styled prompts
40
- meeting auth login
24
+ ### 📖 Read Meeting Notes & Transcripts
41
25
 
42
- # Check who you're logged in as
43
- meeting auth whoami
44
- ```
45
-
46
- ## Usage
26
+ | Command | What it does |
27
+ |---------|-------------|
28
+ | `meeting read <id>` | Read notes, summary, speakers, and action items |
29
+ | `meeting read <url> --pin <pin>` | Read a shared meeting (from a Meeting.ai link) |
30
+ | `meeting search <query>` | Search across all your meetings |
31
+ | `meeting list` | List recent meetings with IDs |
32
+ | `meeting transcript <id>` | See speakers + AI-generated summary |
33
+ | `meeting transcript <id> --full` | Full word-by-word transcript with speaker names |
34
+ | `meeting transcript <id> --search "query"` | Find specific moments in a transcript |
47
35
 
48
- ### Meetings
49
-
50
- ```bash
51
- # List recent meetings — pretty card layout with emoji, duration, summaries
52
- meeting list --limit 10
36
+ ### 🤖 Record Meetings & Upload Recordings
53
37
 
54
- # Read meeting notes (own or shared via URL)
55
- meeting read <meeting_id>
38
+ | Command | What it does |
39
+ |---------|-------------|
40
+ | `meeting bot send --url <url>` | Send a Meeting.ai bot to join a Google Meet, Zoom, or Teams call |
41
+ | `meeting bot send --url <url> --wait` | Send bot and wait until notes are ready |
42
+ | `meeting upload recording.mp4` | Upload a local audio/video recording for transcription |
43
+ | `meeting upload <url>` | Upload a recording from a URL |
56
44
 
57
- # Search meetings
58
- meeting search "quarterly review"
45
+ ### 👥 Contacts & Calendar
59
46
 
60
- # Delete a meeting
61
- meeting delete <meeting_id>
62
- ```
47
+ | Command | What it does |
48
+ |---------|-------------|
49
+ | `meeting contacts list` | Browse contacts you've met with |
50
+ | `meeting contacts list --search "name"` | Find a specific contact |
51
+ | `meeting calendar events --upcoming` | See your upcoming meetings |
63
52
 
64
- **Human output:**
65
- ```
66
- Recent Meetings 42 total
53
+ ### 🔑 Account
67
54
 
68
- 📋 Q1 Product Roadmap Review
69
- Mar 17 · Google Meet · 45 min · 4 speakers
70
- Reviewed upcoming features, timeline adjustments, and resource allocation
55
+ | Command | What it does |
56
+ |---------|-------------|
57
+ | `meeting auth login` | Log in with email OTP (supports 2FA) |
58
+ | `meeting auth whoami` | Check who you're logged in as |
59
+ | `meeting update` | Update to the latest version |
71
60
 
72
- 🎯 Weekly Engineering Standup
73
- Mar 14 · Zoom · 30 min · 6 speakers
74
- Sprint progress, blockers, and deployment schedule...
75
- ```
61
+ ## Built for AI Agents
76
62
 
77
- **JSON output** (`--json`):
78
- ```json
79
- {
80
- "total_item": 42,
81
- "items_per_page": 10,
82
- "meeting": [
83
- { "id": "abc123", "title": "Q1 Product Roadmap Review", "status": "done", "..." : "..." }
84
- ]
85
- }
86
- ```
63
+ This CLI is built to be a tool for AI agents — [OpenClaw](https://openclaw.ai), Claude Code, Codex, or any AI agent that can run shell commands.
87
64
 
88
- ### Bot
65
+ Agents can use the Meeting.ai CLI to:
66
+ - **Read meeting notes** and answer questions about what was discussed
67
+ - **Pull key quotes and action items** from any meeting
68
+ - **Search across meetings** to find relevant context
69
+ - **Upload recordings** and wait for transcription
70
+ - **Share meeting notes** with a link + PIN
89
71
 
90
72
  ```bash
91
- # Send bot to a live meeting
92
- meeting bot send --url https://meet.google.com/abc-defg-hij
93
-
94
- # Send bot and wait for transcript
95
- meeting bot send --url <url> --wait --json
96
-
97
- # Check bot status
98
- meeting bot status <meeting_id>
99
-
100
- # Signal bot to leave
101
- meeting bot leave <meeting_id>
73
+ meeting help # Full agent skill guide (SKILL.md format)
74
+ meeting schema # Machine-readable command & parameter schemas
102
75
  ```
103
76
 
104
- ### Calendar
105
-
106
- ```bash
107
- # List upcoming events
108
- meeting calendar events --upcoming
109
-
110
- # List events in a date range
111
- meeting calendar events --from 2024-01-01 --to 2024-01-31
112
-
113
- # Trigger calendar sync
114
- meeting calendar sync
115
-
116
- # List connected accounts
117
- meeting calendar accounts
118
- ```
119
-
120
- ### Upload
121
-
122
- ```bash
123
- # Upload a local file
124
- meeting upload recording.mp4
125
-
126
- # Upload and wait for transcript
127
- meeting upload recording.mp4 --wait --json
128
-
129
- # Submit a URL
130
- meeting upload https://example.com/recording.mp4
131
- ```
77
+ Run `meeting help` to get a ready-to-use agent skill definition that any AI agent can adopt.
132
78
 
133
- ### Transcript
79
+ ## How It Works
134
80
 
135
- ```bash
136
- # Get AI-processed notes and transcript
137
- meeting transcript <meeting_id>
138
-
139
- # Show complete raw transcript
140
- meeting transcript <meeting_id> --full
141
-
142
- # Search within transcript
143
- meeting transcript <meeting_id> --search "action items"
144
-
145
- # Filter by speaker
146
- meeting transcript <meeting_id> --speaker "John"
147
-
148
- # Filter by time range (minutes)
149
- meeting transcript <meeting_id> --from-time 10 --to-time 30
150
- ```
151
-
152
- ### Contacts
153
-
154
- ```bash
155
- # List contacts — name, role, meeting count
156
- meeting contacts list
157
-
158
- # Search contacts
159
- meeting contacts list --search "John"
160
-
161
- # Get contact details
162
- meeting contacts get <contact_id>
163
-
164
- # List meetings with a contact
165
- meeting contacts meetings <contact_id>
166
- ```
167
-
168
- ### Schema Introspection
169
-
170
- ```bash
171
- # List all commands and their schemas
172
- meeting schema
173
-
174
- # Get schema for a specific command
175
- meeting schema meetings.list --json
176
- ```
177
-
178
- ## Agent-Friendly Features
179
-
180
- Every command supports:
181
-
182
- - **`--json`** — structured JSON output to stdout (auto-enabled when piped/non-TTY)
183
- - **`--fields`** — select specific fields: `meeting list --json --fields meeting,total_item`
184
- - **`--wait`** — poll async operations until complete (bot send, upload)
185
- - **`--wait-timeout`** — configurable timeout in seconds (default 300)
186
-
187
- ### Exit Codes
188
-
189
- | Code | Meaning |
190
- |------|---------|
191
- | 0 | Success |
192
- | 1 | General error |
193
- | 2 | Auth error |
194
- | 3 | Not found |
195
- | 4 | Validation error |
196
-
197
- ### Error Format (JSON mode)
198
-
199
- ```json
200
- {"error": true, "code": "AUTH_EXPIRED", "message": "Token expired, run meeting auth login", "exit_code": 2}
201
- ```
202
-
203
- ## Development
204
-
205
- ```bash
206
- npm install
207
- npm run build # type check + esbuild bundle -> dist/bin/meeting.js
208
- npm run dev # tsx watch
209
- ```
81
+ 1. **Log in** — `meeting auth login` sends a one-time code to your email
82
+ 2. **Browse** `meeting list` shows your recent meetings with IDs
83
+ 3. **Read** — `meeting read <id>` pulls the full notes, speakers, summary, and action items
84
+ 4. **Search** — `meeting search "topic"` finds meetings across notes and transcripts
85
+ 5. **Share** Every meeting includes a share URL and PIN in the output
210
86
 
211
87
  ## License
212
88
 
213
- MIT
89
+ Proprietary — © 2026 Meeting.ai. All rights reserved.
@@ -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.0";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(`
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.0"}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.0";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(`
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
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@meeting-ai/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Agent-friendly CLI for Meeting.ai — read meeting notes, search, upload, and manage meetings from the terminal.",
5
5
  "type": "module",
6
- "license": "MIT",
6
+ "license": "UNLICENSED",
7
7
  "author": "Meeting.ai <dev@meeting.ai>",
8
8
  "homepage": "https://meeting.ai",
9
9
  "keywords": [