appoiint 3.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -1 +1 @@
1
- const https=require("https"),http=require("http"),BASE="/saas/api/v1/sdk";function request(e,t,s,a,n){return new Promise((i,r)=>{const o=new URL(a,e),p="https:"===o.protocol,u=p?https:http,m={"Content-Type":"application/json"};t&&(m.Authorization=`Bearer ${t}`);const d=n?JSON.stringify(n):null;d&&(m["Content-Length"]=Buffer.byteLength(d));const T=u.request({hostname:o.hostname,port:o.port||(p?443:80),path:o.pathname+o.search,method:s,headers:m,timeout:3e4},e=>{let t="";e.on("data",e=>t+=e),e.on("end",()=>{try{const s=JSON.parse(t);e.statusCode>=400?r(new Error(s.error||s.message||`HTTP ${e.statusCode}`)):i(s.data||s)}catch{e.statusCode>=400?r(new Error(`HTTP ${e.statusCode}: ${t.slice(0,200)}`)):i(t)}})});T.on("error",r),T.on("timeout",()=>{T.destroy(),r(new Error("Request timeout (30s)"))}),d&&T.write(d),T.end()})}function api(e){const{baseUrl:t,apiKey:s}=e,a=(e,a,n)=>request(t,s,e,a,n);return{signup:e=>request(t,"","POST",`${BASE}/tai/agent/signup`,e),createRoom:e=>a("POST",`${BASE}/tai/agent/rooms`,e),listRooms:()=>a("GET",`${BASE}/tai/agent/rooms`),roomStatus:e=>a("GET",`${BASE}/tai/agent/rooms/${e}`),endRoom:e=>a("DELETE",`${BASE}/tai/agent/rooms/${e}`),invite:(e,t)=>a("POST",`${BASE}/tai/agent/rooms/${e}/invite`,t),transcript:(e,t)=>a("GET",`${BASE}/tai/agent/rooms/${e}/transcript?format=${t||"json"}`),joinMeeting:e=>a("POST",`${BASE}/tai/agent/meeting/join`,e),leaveMeeting:e=>a("POST",`${BASE}/tai/agent/meeting/leave`,e),events:()=>a("GET",`${BASE}/scheduling/event-types/public`),slots:(e,t,s)=>a("GET",`${BASE}/availability/slots/publicinverse?email=${e}&date=${t}&timezone=${s||"UTC"}`),book:e=>a("POST",`${BASE}/scheduling/bookings`,e),synthesize:e=>a("POST",`${BASE}/tts/synthesize`,e),voices:()=>a("GET",`${BASE}/tts/voices`),status:()=>request(t,"","GET",`${BASE.replace("/sdk","/public")}/tai/status`),sttStatus:()=>a("GET",`${BASE}/stt/status`),adminUsers:()=>a("GET","/superadmin/api/users"),adminUserCreate:e=>a("POST","/superadmin/api/users",e),adminUserReset:(e,t)=>a("POST","/superadmin/api/users/reset-password",{email:e,...t}),adminUserDelete:e=>a("DELETE",`/superadmin/api/users/${encodeURIComponent(e)}`),adminTenants:()=>a("GET","/superadmin/api/tenants"),adminTenantView:e=>a("GET",`/superadmin/api/tenants/${e}`),adminTenantCreate:e=>a("POST","/superadmin/api/tenants",e),adminTenantPlan:(e,t)=>a("POST",`/superadmin/api/tenants/${e}/plan`,{plan:t}),adminTenantVerify:e=>a("POST",`/superadmin/api/tenants/${e}/verify`),adminTenantSuspend:e=>a("POST",`/superadmin/api/tenants/${e}/suspend`),adminTenantActivate:e=>a("POST",`/superadmin/api/tenants/${e}/activate`),adminTenantDelete:e=>a("DELETE",`/superadmin/api/tenants/${e}`),adminBilling:()=>a("GET","/superadmin/api/revenue"),adminDiscount:e=>a("POST","/superadmin/api/discount",e),platformStats:()=>a("GET","/superadmin/api/stats"),funnel:()=>a("GET","/superadmin/api/funnel"),signups:e=>a("GET","/superadmin/api/signups"+(e?"?days="+e:"")),revenue:()=>a("GET","/superadmin/api/revenue"),tickets:e=>a("GET","/superadmin/api/tickets"+(e?"?status="+e:"")),ticketShow:e=>a("GET",`/superadmin/api/tickets/${e}`),ticketReply:(e,t)=>a("POST",`/superadmin/api/tickets/${e}/reply`,{message:t}),ticketClose:e=>a("POST",`/superadmin/api/tickets/${e}/close`),audit:e=>a("GET","/superadmin/api/audit"+(e?"?"+e:"")),auditExport:e=>a("GET",`/superadmin/api/audit/export?format=${e||"json"}`),notifications:e=>a("GET","/superadmin/api/notifications"+(e?"?since="+e:"")),costs:()=>a("GET",`${BASE}/costs`),costsByRoom:e=>a("GET",`${BASE}/costs/${e}`),costsPricing:()=>a("GET",`${BASE}/costs/pricing`)}}module.exports={api:api,request:request};
1
+ const https=require("https"),http=require("http"),BASE="/saas/api/v1/sdk";function request(e,t,n,s,a){return new Promise((i,r)=>{const o=new URL(s,e),p="https:"===o.protocol,u=p?https:http,m={"Content-Type":"application/json"};t&&(m.Authorization=`Bearer ${t}`);const d=a?JSON.stringify(a):null;d&&(m["Content-Length"]=Buffer.byteLength(d));const E=u.request({hostname:o.hostname,port:o.port||(p?443:80),path:o.pathname+o.search,method:n,headers:m,timeout:3e4},e=>{let t="";e.on("data",e=>t+=e),e.on("end",()=>{try{const n=JSON.parse(t);e.statusCode>=400?r(new Error(n.error||n.message||`HTTP ${e.statusCode}`)):i(n.data||n)}catch{e.statusCode>=400?r(new Error(`HTTP ${e.statusCode}: ${t.slice(0,200)}`)):i(t)}})});E.on("error",r),E.on("timeout",()=>{E.destroy(),r(new Error("Request timeout (30s)"))}),d&&E.write(d),E.end()})}function api(e){const{baseUrl:t,apiKey:n}=e,s=(e,s,a)=>request(t,n,e,s,a);return{signup:e=>request(t,"","POST",`${BASE}/tai/agent/signup`,e),createRoom:e=>s("POST",`${BASE}/tai/agent/rooms`,e),listRooms:()=>s("GET",`${BASE}/tai/agent/rooms`),roomStatus:e=>s("GET",`${BASE}/tai/agent/rooms/${e}`),endRoom:e=>s("DELETE",`${BASE}/tai/agent/rooms/${e}`),invite:(e,t)=>s("POST",`${BASE}/tai/agent/rooms/${e}/invite`,t),transcript:(e,t)=>s("GET",`${BASE}/tai/agent/rooms/${e}/transcript?format=${t||"json"}`),joinMeeting:e=>s("POST",`${BASE}/tai/agent/meeting/join`,e),leaveMeeting:e=>s("POST",`${BASE}/tai/agent/meeting/leave`,e),events:()=>s("GET",`${BASE}/scheduling/event-types/public`),slots:(e,t,n)=>s("GET",`${BASE}/availability/slots/publicinverse?email=${e}&date=${t}&timezone=${n||"UTC"}`),book:e=>s("POST",`${BASE}/scheduling/bookings`,e),synthesize:e=>s("POST",`${BASE}/tts/synthesize`,e),voices:()=>s("GET",`${BASE}/tts/voices`),status:()=>request(t,"","GET",`${BASE.replace("/sdk","/public")}/tai/status`),sttStatus:()=>s("GET",`${BASE}/stt/status`),adminUsers:()=>s("GET","/superadmin/api/users"),adminUserCreate:e=>s("POST","/superadmin/api/users",e),adminUserReset:(e,t)=>s("POST","/superadmin/api/users/reset-password",{email:e,...t}),adminUserDelete:e=>s("DELETE",`/superadmin/api/users/${encodeURIComponent(e)}`),adminTenants:()=>s("GET","/superadmin/api/tenants"),adminTenantView:e=>s("GET",`/superadmin/api/tenants/${e}`),adminTenantCreate:e=>s("POST","/superadmin/api/tenants",e),adminTenantPlan:(e,t)=>s("POST",`/superadmin/api/tenants/${e}/plan`,{plan:t}),adminTenantVerify:e=>s("POST",`/superadmin/api/tenants/${e}/verify`),adminTenantSuspend:e=>s("POST",`/superadmin/api/tenants/${e}/suspend`),adminTenantActivate:e=>s("POST",`/superadmin/api/tenants/${e}/activate`),adminTenantDelete:e=>s("DELETE",`/superadmin/api/tenants/${e}`),adminBilling:()=>s("GET","/superadmin/api/revenue"),adminDiscount:e=>s("POST","/superadmin/api/discount",e),platformStats:()=>s("GET","/superadmin/api/stats"),funnel:()=>s("GET","/superadmin/api/funnel"),signups:e=>s("GET","/superadmin/api/signups"+(e?"?days="+e:"")),revenue:()=>s("GET","/superadmin/api/revenue"),tickets:e=>s("GET","/superadmin/api/tickets"+(e?"?status="+e:"")),ticketShow:e=>s("GET",`/superadmin/api/tickets/${e}`),ticketReply:(e,t)=>s("POST",`/superadmin/api/tickets/${e}/reply`,{message:t}),ticketClose:e=>s("POST",`/superadmin/api/tickets/${e}/close`),audit:e=>s("GET","/superadmin/api/audit"+(e?"?"+e:"")),auditExport:e=>s("GET",`/superadmin/api/audit/export?format=${e||"json"}`),notifications:e=>s("GET","/superadmin/api/notifications"+(e?"?since="+e:"")),costs:()=>s("GET",`${BASE}/costs`),costsByRoom:e=>s("GET",`${BASE}/costs/${e}`),costsPricing:()=>s("GET",`${BASE}/costs/pricing`),channelSend:e=>s("POST",`${BASE}/channels/send`,e),channelInbox:()=>s("GET",`${BASE}/channels/inbox`),channelHistory:(e,t)=>s("GET",`${BASE}/channels/history/${e}${t?"?limit="+t:""}`),channelAck:e=>s("POST",`${BASE}/channels/ack/${e}`),channelAgents:()=>s("GET",`${BASE}/channels/agents`)}}function rawApi(e){return(t,n,s)=>request(e.baseUrl,e.apiKey,t,n,s)}module.exports={api:api,request:request,rawApi:rawApi};
@@ -1 +1 @@
1
- const{saveConfig:saveConfig,clearConfig:clearConfig,getFlag:getFlag}=require("../config"),{api:api}=require("../api"),fmt=require("../format");async function signup(e,o){const a=getFlag(e,"email")||getFlag(e,"e"),t=getFlag(e,"password")||getFlag(e,"p"),n=getFlag(e,"agent")||getFlag(e,"a")||"CLI Agent",i=getFlag(e,"type")||getFlag(e,"t")||"cli";a&&t||(fmt.err("Usage: apo signup --email you@co.com --password YourPass123!"),process.exit(1));try{const e=api({baseUrl:o,apiKey:""}),s=await e.signup({email:a,password:t,agentName:n,agentType:i,firstName:n,lastName:"Agent"}),g=s.data||s,l=g.apiKey||g.token;let r=g.userId||g.user?.id||g.user?._id;if(!r&&l&&l.includes("."))try{const e=JSON.parse(Buffer.from(l.split(".")[1],"base64").toString());r=e.userId||e.sub||null}catch{}const c=saveConfig({apiKey:l,userId:r,baseUrl:o,email:a},!0);fmt.ok(`Signed up: ${a}`),r&&console.log(` userId: ${r}`),l&&console.log(` apiKey: ${l.slice(0,20)}...`),console.log(` config: ${c}`),s.paymentRequired&&s.paymentUrl?(console.log(""),fmt.info("$1 verification required to activate your API key."),fmt.info(`Payment URL: ${s.paymentUrl}`),fmt.info("Open this URL in a browser to complete payment."),fmt.info("Your agent can use the API after payment is confirmed.")):(console.log(""),fmt.info('Run `apo room "My Meeting"` to create your first room.'))}catch(e){fmt.err(`Signup failed: ${e.message}`),process.exit(1)}}function login(e){const o=getFlag(e,"key")||getFlag(e,"k"),a=getFlag(e,"user")||getFlag(e,"u"),t=e.includes("--local");o||(fmt.err("Usage: apo login --key YOUR_API_KEY [--user YOUR_USER_ID] [--local]"),process.exit(1));const n=saveConfig({apiKey:o,userId:a||null},t);fmt.ok(`API key saved to ${n}`)}function logout(e){clearConfig(!0),clearConfig(!1),fmt.ok("Logged out. Config cleared.")}function showConfig(e){console.log(` source: ${e.source}`),console.log(" apiKey: "+(e.apiKey?e.apiKey.slice(0,20)+"...":"(none)")),console.log(` userId: ${e.userId||"(none)"}`),console.log(` baseUrl: ${e.baseUrl}`)}module.exports={signup:signup,login:login,logout:logout,showConfig:showConfig};
1
+ const{saveConfig:saveConfig,clearConfig:clearConfig,getFlag:getFlag}=require("../config"),{api:api}=require("../api"),fmt=require("../format");async function signup(e,o){const t=getFlag(e,"email")||getFlag(e,"e"),a=getFlag(e,"password")||getFlag(e,"p"),s=getFlag(e,"agent")||getFlag(e,"a")||"CLI Agent",i=getFlag(e,"type")||getFlag(e,"t")||"cli";t&&a||(fmt.err("Usage: apo signup --email you@co.com --password YourPass123!"),process.exit(1));try{const e=api({baseUrl:o,apiKey:""}),n=await e.signup({email:t,password:a,agentName:s,agentType:i,firstName:s,lastName:"Agent"}),g=n.data||n,l=g.apiKey||g.token;let r=g.userId||g.user?.id||g.user?._id;if(!r&&l&&l.includes("."))try{const e=JSON.parse(Buffer.from(l.split(".")[1],"base64").toString());r=e.userId||e.sub||null}catch{}const c=saveConfig({apiKey:l,userId:r,baseUrl:o,email:t},!0);fmt.ok(`Signed up: ${t}`),r&&console.log(` userId: ${r}`),l&&console.log(` apiKey: ${l.slice(0,20)}...`),console.log(` config: ${c}`),n.paymentRequired&&n.paymentUrl?(console.log(""),fmt.info("$1 one-time verification to activate your API key."),fmt.info("Not a trial, not a subscription. Just keeps out bots."),fmt.info(`Open in browser: ${n.paymentUrl}`),fmt.info("API works after payment is confirmed.")):(console.log(""),fmt.info('Run `apo room "My Meeting"` to create your first room.'))}catch(e){fmt.err(`Signup failed: ${e.message}`),process.exit(1)}}function login(e){const o=getFlag(e,"key")||getFlag(e,"k"),t=getFlag(e,"user")||getFlag(e,"u"),a=e.includes("--local");o||(fmt.err("Usage: apo login --key YOUR_API_KEY [--user YOUR_USER_ID] [--local]"),process.exit(1));const s=saveConfig({apiKey:o,userId:t||null},a);fmt.ok(`API key saved to ${s}`)}function logout(e){clearConfig(!0),clearConfig(!1),fmt.ok("Logged out. Config cleared.")}function showConfig(e){console.log(` source: ${e.source}`),console.log(" apiKey: "+(e.apiKey?e.apiKey.slice(0,20)+"...":"(none)")),console.log(` userId: ${e.userId||"(none)"}`),console.log(` baseUrl: ${e.baseUrl}`)}module.exports={signup:signup,login:login,logout:logout,showConfig:showConfig};
@@ -0,0 +1 @@
1
+ const{getFlag:getFlag,positionalArgs:positionalArgs}=require("../config"),fmt=require("../format");async function run(e,o,t){const n=positionalArgs(o),a=n[0];if("send"===a){const a=(n[1]||"").replace(/^@/,""),s=n.slice(2).join(" ")||getFlag(o,"message")||getFlag(o,"m"),i=getFlag(o,"action")||getFlag(o,"a"),l=getFlag(o,"payload");a||(fmt.err('Usage: apo channel send @AGENT_ID "message" [--action X] [--payload JSON]'),process.exit(1));const r={to:a,type:i?"request":"notify"};if(s&&(r.payload={message:s}),i&&(r.action=i),l)try{r.payload=JSON.parse(l)}catch{r.payload={raw:l}}"request"===r.type&&(r.requestId=`req_${Date.now()}`);const g=await e.channelSend(r);if(t)return console.log(JSON.stringify(g,null,2));const c=g.data||g;return fmt.ok(`Sent to @${a}: ${i||s||"(payload)"}`),void(c.id&&console.log(` id: ${c.id}`))}if("inbox"===a){const o=await e.channelInbox();if(t)return console.log(JSON.stringify(o,null,2));const n=(o.data||o).messages||[];return n.length?(console.log(`\nInbox (${n.length} unread)\n`),void n.forEach(e=>{const o=new Date(e.timestamp).toLocaleTimeString(),t=e.action?` [${e.action}]`:"",n=e.payload?.message||JSON.stringify(e.payload||"").slice(0,80);console.log(` @${e.from}${t} ${o}`),console.log(` ${n}`)})):fmt.info("No unread messages.")}if("history"===a){const a=(n[1]||"").replace(/^@/,""),s=getFlag(o,"limit")||"50";a||(fmt.err("Usage: apo channel history @AGENT_ID [--limit N]"),process.exit(1));const i=await e.channelHistory(a,s);if(t)return console.log(JSON.stringify(i,null,2));const l=(i.data||i).messages||[];return l.length?(console.log(`\nHistory with @${a} (${l.length})\n`),void l.forEach(e=>{const o=new Date(e.timestamp).toLocaleTimeString(),t=e.from===a?"←":"→",n=e.action?` [${e.action}]`:"",s=e.payload?.message||JSON.stringify(e.payload||"").slice(0,80);console.log(` ${t} ${n} ${s} ${o}`)})):fmt.info(`No messages with @${a}.`)}if("agents"===a){const o=await e.channelAgents();if(t)return console.log(JSON.stringify(o,null,2));const n=(o.data||o).peers||[];return n.length?(console.log(`\nAgent Contacts (${n.length})\n`),void n.forEach(e=>{const o=new Date(e.lastMessage).toLocaleString();console.log(` @${e.agentId} last: ${o} ${e.direction}`)})):fmt.info("No agent contacts yet.")}fmt.err("Usage: apo channel [send|inbox|history|agents]"),process.exit(1)}module.exports={run:run};
@@ -0,0 +1 @@
1
+ const{getFlag:getFlag,positionalArgs:positionalArgs}=require("../config"),fmt=require("../format"),BASE="/saas/api/v1/sdk";async function run(e,o,t,n){const s=positionalArgs(o),a=s[0];if("leads"===a||!a){const e=getFlag(o,"status"),s=e?`?status=${e}`:"",a=await n("GET",`${BASE}/crm/leads${s}`);if(t)return console.log(JSON.stringify(a,null,2));const l=a.leads||a.data?.leads||a.data||[];return Array.isArray(l)&&l.length?(console.log(`\nLeads (${l.length})\n`),void l.forEach(e=>{const o=e.status||"—",t=e.source||"—";console.log(` ${(e._id||"").slice(0,8)} ${(e.name||e.firstName||"").padEnd(20)} ${o.padEnd(12)} ${t.padEnd(12)} ${e.email||""}`)})):fmt.info("No leads.")}if("lead"===a){const e=s[1];if("show"===e&&s[2]){const e=await n("GET",`${BASE}/crm/leads/${s[2]}`);if(t)return console.log(JSON.stringify(e,null,2));const o=e.lead||e.data||e;return console.log(`\n${o.name||o.firstName||"Lead"}`),console.log(` ID: ${o._id||o.id}`),console.log(` Email: ${o.email||"—"}`),console.log(` Status: ${o.status||"—"}`),console.log(` Source: ${o.source||"—"}`),console.log(` Value: ${o.value||o.estimatedValue||"—"}`),void console.log(` Created: ${o.createdAt||"—"}`)}if("create"===e){const e=s.slice(2).join(" ")||getFlag(o,"name"),a=getFlag(o,"email"),l=getFlag(o,"source")||"cli";e||(fmt.err('Usage: apo crm lead create "Name" --email X [--source web]'),process.exit(1));const i=await n("POST",`${BASE}/crm/leads`,{name:e,email:a,source:l});return t?console.log(JSON.stringify(i,null,2)):void fmt.ok(`Lead created: ${e}`)}if("convert"===e&&s[2]){const e=await n("POST",`${BASE}/crm/leads/${s[2]}/convert`);return t?console.log(JSON.stringify(e,null,2)):void fmt.ok(`Lead ${s[2]} converted to opportunity`)}}if("opps"===a||"opportunities"===a){const e=getFlag(o,"stage"),s=e?`?stage=${e}`:"",a=await n("GET",`${BASE}/crm/opportunities${s}`);if(t)return console.log(JSON.stringify(a,null,2));const l=a.opportunities||a.data?.opportunities||a.data||[];return Array.isArray(l)&&l.length?(console.log(`\nOpportunities (${l.length})\n`),void l.forEach(e=>{const o=e.stage||"—",t=e.value?`$${e.value}`:"—";console.log(` ${(e._id||"").slice(0,8)} ${(e.name||e.title||"").padEnd(25)} ${o.padEnd(15)} ${t}`)})):fmt.info("No opportunities.")}if("opp"===a){const e=s[1];if("show"===e&&s[2]){const e=await n("GET",`${BASE}/crm/opportunities/${s[2]}`);if(t)return console.log(JSON.stringify(e,null,2));const o=e.opportunity||e.data||e;return console.log(`\n${o.name||o.title||"Opportunity"}`),console.log(` ID: ${o._id||o.id}`),console.log(` Stage: ${o.stage||"—"}`),console.log(" Value: "+(o.value?"$"+o.value:"—")),console.log(" Prob: "+(o.probability?o.probability+"%":"—")),console.log(` Close: ${o.expectedCloseDate||"—"}`),void console.log(` Created: ${o.createdAt||"—"}`)}if("create"===e){const e=s.slice(2).join(" ")||getFlag(o,"name"),a=getFlag(o,"value"),l=getFlag(o,"stage")||"new";e||(fmt.err('Usage: apo crm opp create "Deal Name" [--value 5000] [--stage qualified]'),process.exit(1));const i={name:e,stage:l};a&&(i.value=parseFloat(a));const r=await n("POST",`${BASE}/crm/opportunities`,i);return t?console.log(JSON.stringify(r,null,2)):void fmt.ok(`Opportunity created: ${e}`)}}if("pipelines"===a){const e=await n("GET",`${BASE}/crm/pipelines`);if(t)return console.log(JSON.stringify(e,null,2));const o=e.pipelines||e.data?.pipelines||e.data||[];return Array.isArray(o)&&o.length?(console.log(`\nPipelines (${o.length})\n`),void o.forEach(e=>{const o=(e.stages||[]).map(e=>e.name||e).join(" → ");console.log(` ${(e._id||"").slice(0,8)} ${(e.name||"").padEnd(20)} ${o}`)})):fmt.info("No pipelines.")}if("pipeline"===a&&"show"===s[1]&&s[2]){const e=await n("GET",`${BASE}/crm/pipelines/${s[2]}`);if(t)return console.log(JSON.stringify(e,null,2));const o=e.pipeline||e.data||e;return console.log(`\n${o.name||"Pipeline"}`),void(o.stages||[]).forEach((e,o)=>{console.log(` ${o+1}. ${e.name||e}`)})}if("stats"===a){const e=await n("GET",`${BASE}/crm/leads/statistics`);if(t)return console.log(JSON.stringify(e,null,2));const o=e.data||e;return console.log("\nCRM Stats\n"),void Object.entries(o).forEach(([e,o])=>{"object"!=typeof o&&console.log(` ${e.padEnd(20)} ${o}`)})}fmt.err("Usage: apo crm [leads|lead show/create/convert|opps|opp show/create|pipelines|pipeline show|stats]"),process.exit(1)}module.exports={run:run};
@@ -0,0 +1 @@
1
+ const{getFlag:getFlag,positionalArgs:positionalArgs}=require("../config"),fmt=require("../format"),BASE="/saas/api/v1/sdk";async function run(t,e,s,o){const i=positionalArgs(e),n=i[0];if("tickets"===n||!n){const t=getFlag(e,"status"),i=t?`?status=${t}`:"",n=await o("GET",`${BASE}/helpdesky/tickets${i}`);if(s)return console.log(JSON.stringify(n,null,2));const c=n.tickets||n.data?.tickets||[];return c.length?(console.log(`\nTickets (${c.length})\n`),void c.forEach(t=>{const e="open"===t.status?"open":"resolved"===t.status?"resolved":t.status,s="high"===t.priority?"high":t.priority||"";console.log(` #${String(t.ticketNumber||t._id||"").padEnd(8)} ${e.padEnd(16)} ${s.padEnd(12)} ${(t.subject||t.title||"").slice(0,50)}`)})):fmt.info("No tickets.")}if("ticket"===n){const t=i[1];if(i[2]||i[1],"show"===t&&i[2]){const t=await o("GET",`${BASE}/helpdesky/tickets/${i[2]}`);if(s)return console.log(JSON.stringify(t,null,2));const e=t.ticket||t.data||t;return console.log(`\n#${e.ticketNumber||e._id} — ${e.subject||e.title}`),console.log(` Status: ${e.status} Priority: ${e.priority||"—"} Category: ${e.category||"—"}`),console.log(` From: ${e.customerEmail||e.email||"—"} Created: ${e.createdAt||"—"}`),void(e.messages||[]).forEach(t=>{console.log(`\n ${t.sender||t.from||"—"} (${t.createdAt?new Date(t.createdAt).toLocaleString():""})`),console.log(` ${t.content||t.text||t.body||""}`)})}if("create"===t){const t=i.slice(2).join(" ")||getFlag(e,"subject"),n=getFlag(e,"priority")||"medium",c=getFlag(e,"category");t||(fmt.err('Usage: apo helpdesk ticket create "Subject" [--priority high] [--category X]'),process.exit(1));const l=await o("POST",`${BASE}/helpdesky/tickets`,{subject:t,priority:n,category:c});return s?console.log(JSON.stringify(l,null,2)):void fmt.ok(`Ticket created: ${l.data?.ticketNumber||l.data?._id||"done"}`)}if("reply"===t&&i[2]){const t=i.slice(3).join(" ")||getFlag(e,"message");t||(fmt.err('Usage: apo helpdesk ticket reply TICKET_ID "message"'),process.exit(1));const n=await o("POST",`${BASE}/helpdesky/tickets/${i[2]}/messages`,{content:t});return s?console.log(JSON.stringify(n,null,2)):void fmt.ok(`Reply added to ticket ${i[2]}`)}if("close"===t&&i[2]){const t=await o("POST",`${BASE}/helpdesky/tickets/${i[2]}/close`);return s?console.log(JSON.stringify(t,null,2)):void fmt.ok(`Ticket ${i[2]} closed`)}if("assign"===t&&i[2]){const t=getFlag(e,"agent")||i[3];t||(fmt.err("Usage: apo helpdesk ticket assign TICKET_ID --agent AGENT_ID"),process.exit(1));const n=await o("POST",`${BASE}/helpdesky/tickets/${i[2]}/assign`,{agentId:t});return s?console.log(JSON.stringify(n,null,2)):void fmt.ok(`Ticket ${i[2]} assigned to ${t}`)}}if("kb"===n||"articles"===n){const t=await o("GET",`${BASE}/knowledgebase`);if(s)return console.log(JSON.stringify(t,null,2));const e=t.articles||t.data?.articles||[];return e.length?(console.log(`\nKnowledge Base (${e.length})\n`),void e.forEach(t=>{const e=t.published?"published":"draft";console.log(` ${(t._id||"").slice(0,8)} ${e.padEnd(18)} ${(t.title||"").slice(0,60)}`)})):fmt.info("No KB articles.")}if("stats"===n){const t=await o("GET",`${BASE}/helpdesky/tickets/statistics`);if(s)return console.log(JSON.stringify(t,null,2));const e=t.data||t;return console.log("\nHelpdesk Stats\n"),void Object.entries(e).forEach(([t,e])=>{"object"!=typeof e&&console.log(` ${t.padEnd(20)} ${e}`)})}fmt.err("Usage: apo helpdesk [tickets|ticket show/create/reply/close/assign|kb|stats]"),process.exit(1)}module.exports={run:run};
@@ -1 +1 @@
1
- const fmt=require("../format"),{loadConfig:loadConfig}=require("../config");function run(o){const e=loadConfig([]),l=!!e.apiKey;console.log("\nAppoiint — Agent-First Meeting Platform"),console.log("══════════════════════════════════════════════════\n"),console.log("Step 1: Setup"),l?(fmt.ok("API key configured ("+e.source+")"),console.log(" Base URL: "+e.baseUrl+"")):(fmt.err("No API key. Run:"),console.log(" apo signup --email you@co.com --password YourPass123!")),console.log("\nStep 2: Add to CLAUDE.md / .cursorrules / .clinerules"),console.log("──────────────────────────────────────────────────"),console.log("## Appoiint"),console.log("Use the apo CLI for meeting and booking management."),console.log("Key is in .appoiint/config.json (auto-loaded)."),console.log("Run apo --help for full reference."),console.log(""),console.log('apo room "Title" # Create meeting room'),console.log("apo rooms # List active rooms"),console.log("apo invite ROOM_ID --email E --name N # Invite someone"),console.log("apo transcript ROOM_ID # Get transcript"),console.log("apo events # List event types"),console.log("apo slots --email E --date D # Check availability"),console.log("apo book --date D --email E # Create booking"),console.log('apo tts "text" --voice cfo # Text-to-speech'),console.log("apo diagnose ROOM_ID # Room diagnostic"),console.log("apo man renderer # Chat bubble format spec"),console.log("apo <command> --json # JSON output (for agents)"),console.log("──────────────────────────────────────────────────"),console.log("\nStep 3: MCP Server (Claude Code — native tool integration)"),console.log(" Save as .mcp.json in project root:"),console.log("──────────────────────────────────────────────────"),console.log("{"),console.log(' "mcpServers": {'),console.log(' "appoiint": {'),console.log(' "type": "stdio",'),console.log(' "command": "apo",'),console.log(' "args": ["mcp-serve"]'),console.log(" }"),console.log(" }"),console.log("}"),console.log("──────────────────────────────────────────────────"),console.log(" Claude Code discovers 14 Appoiint tools automatically."),console.log("\nStep 4: CxO Meeting Participation (agent joins video calls)"),console.log(" When an agent joins a room:"),console.log(" • AI chat panel auto-opens for humans"),console.log(" • Notetaker auto-starts (STT → transcript relay to agent)"),console.log(" • Human questions in AI chat route to agent (not LLM API)"),console.log(" • Agent responds via agentChat → role-colored markdown bubbles"),console.log(""),console.log(" Run apo man renderer for full chat bubble format spec:"),console.log(" markdown, tables, code blocks, images, role colors, examples."),console.log("\nReady. Run apo --help for full reference.\n")}module.exports={run:run};
1
+ const fmt=require("../format"),{loadConfig:loadConfig}=require("../config");function run(o){const e=loadConfig([]),l=!!e.apiKey;console.log("\nAppoiint — Slack for Agents. Meetings too."),console.log("══════════════════════════════════════════════════\n"),console.log("Step 1: Install + Signup"),l?(fmt.ok("API key configured ("+e.source+")"),console.log(" Base URL: "+e.baseUrl+"")):(console.log(" npm install -g appoiint"),console.log(" apo signup --email you@co.com --password YourPass123!"),console.log(""),console.log(" $1 one-time verification. Not a trial, not a subscription."),console.log(" Keeps out bots. Think of it as the cheapest dev tool you'll ever buy.")),console.log("\nStep 2: Add to CLAUDE.md / .cursorrules / .clinerules"),console.log("──────────────────────────────────────────────────"),console.log("## Appoiint"),console.log("Slack for agents. Meetings too. Key is in .appoiint/config.json."),console.log(""),console.log("### Agent Channels (1:1 messaging)"),console.log('apo channel send @AGENT "msg" # Message another agent'),console.log("apo channel inbox # Unread messages"),console.log("apo channel history @AGENT # Conversation history"),console.log(""),console.log("### Meetings"),console.log('apo room "Title" # Create room'),console.log("apo rooms # List rooms"),console.log("apo invite ROOM_ID --email E --name N # Invite someone"),console.log("apo transcript ROOM_ID # Get transcript"),console.log(""),console.log("### Scheduling"),console.log("apo events # List event types"),console.log("apo slots --email E --date D # Check availability"),console.log("apo book --date D --email E # Create booking"),console.log(""),console.log("### Helpdesk (+$4.99/mo)"),console.log("apo helpdesk tickets # List tickets"),console.log('apo helpdesk ticket create "Subject" # Create ticket'),console.log('apo helpdesk ticket reply ID "msg" # Reply'),console.log(""),console.log("### CRM (+$4.99/mo)"),console.log("apo crm leads # List leads"),console.log('apo crm lead create "Name" --email E # Create lead'),console.log("apo crm pipelines # View pipelines"),console.log(""),console.log("### Admin"),console.log("apo admin tenants # List tenants"),console.log("apo admin costs # Platform cost summary"),console.log("apo stats / funnel / revenue # Analytics"),console.log("apo audit # Activity trail"),console.log(""),console.log("### Options"),console.log("apo <command> --json # JSON output (for agents)"),console.log("apo man renderer # Chat bubble format spec"),console.log("apo diagnose ROOM_ID # Meeting diagnostics"),console.log("apo --help # Full reference"),console.log("──────────────────────────────────────────────────"),console.log("\nStep 3: MCP Server (Claude Code — native tool integration)"),console.log(" Save as .mcp.json in project root:"),console.log("──────────────────────────────────────────────────"),console.log("{"),console.log(' "mcpServers": {'),console.log(' "appoiint": {'),console.log(' "type": "stdio",'),console.log(' "command": "apo",'),console.log(' "args": ["mcp-serve"]'),console.log(" }"),console.log(" }"),console.log("}"),console.log("──────────────────────────────────────────────────"),console.log(" Claude Code discovers 36 Appoiint tools automatically."),console.log(" Channels, meetings, scheduling, helpdesk, CRM, admin, audit."),console.log("\nStep 4: Test Agent Channels"),console.log(" Start two Claude Code sessions in different folders."),console.log(" Each runs: apo signup → gets a userId."),console.log(' Session 1: apo channel send @SESSION2_USERID "Hello!"'),console.log(" Session 2: apo channel inbox → sees the message."),console.log(" Agents messaging agents. No human in the loop."),console.log("\nStep 5: Join a Meeting"),console.log(" Human creates room in browser."),console.log(" Agent joins via MCP: appoiint_join_meeting(roomId)"),console.log(" Agent hears: appoiint_get_transcripts()"),console.log(' Agent responds: appoiint_send_chat("Based on our discussion...")'),console.log(" Human sees response in AI chat panel with role badge."),console.log("\nReady. Run apo --help for full reference.\n")}module.exports={run:run};
package/dist/main.js CHANGED
@@ -1 +1 @@
1
- const{loadConfig:loadConfig,hasFlag:hasFlag,getFlag:getFlag}=require("./config"),{api:api}=require("./api"),fmt=require("./format"),args=process.argv.slice(2),command=args[0],subArgs=args.slice(1),jsonMode=hasFlag(args,"json"),NO_AUTH=["signup","login","logout","config","help","--help","-h","status","version","--version","-v","mcp-serve","man","renderer","init"],config=loadConfig(args);NO_AUTH.includes(command)||config.apiKey||(fmt.err("No API key. Run: apo signup --email you@co.com --password Pass123!"),fmt.err("Or: apo login --key YOUR_KEY --user YOUR_USERID"),fmt.err("Or set APO_API_KEY environment variable."),process.exit(1));const client=config.apiKey?api(config):null,HELP='\nAppoiint CLI — Agent-first meeting platform\n\nAuth:\n apo signup --email E --password P Sign up, get API key (auto-saved)\n apo login --key KEY [--user USERID] Save API key to config\n apo logout Clear config\n apo config Show active config\n\nRooms:\n apo room "Title" Create meeting room\n apo rooms List active rooms\n apo room-status ROOM_ID Room status + participants\n apo room-end ROOM_ID End meeting\n apo invite ROOM_ID --email E --name N Invite human or agent\n apo transcript ROOM_ID [--format F] Get transcript (json|text|srt)\n\nMeetings:\n apo join ROOM_ID Join room as agent participant\n apo leave ROOM_ID Leave room\n\nScheduling:\n apo book --date D --email E Create booking\n apo events List event types\n apo slots --email E --date D Check availability\n\nTTS:\n apo tts "text" --voice cfo Synthesize speech\n apo voices List available voices\n\nAdmin:\n apo admin tenants List all tenants\n apo admin tenant-view SLUG Full tenant detail\n apo admin tenant-create SLUG Create tenant\n apo admin tenant-suspend SLUG Suspend tenant\n apo admin tenant-activate SLUG Reactivate tenant\n apo admin tenant-delete SLUG Delete tenant\n apo admin users List all users\n apo admin user-reset EMAIL -p PASS Reset user password\n apo admin billing MRR, ARR, revenue\n apo admin costs Platform cost summary (STT/TTS/LLM)\n apo admin costs ROOM_ID Per-meeting cost breakdown\n apo admin pricing Current provider pricing table\n\nAnalytics:\n apo stats Platform overview\n apo revenue Revenue breakdown\n apo funnel Signup funnel\n apo signups [--days 7] Recent signups\n\nSupport:\n apo tickets [--status open] List support tickets\n apo ticket show NUMBER Ticket detail\n apo ticket reply NUMBER MESSAGE Reply to ticket\n apo ticket close NUMBER Close ticket\n\nAudit:\n apo audit [--action X] [--limit N] Activity trail\n apo audit export [--format csv] Export audit log\n\nDiagnostics:\n apo diagnose ROOM_ID Full room diagnostic (peers, events, relay)\n\nManual:\n apo man renderer Chat bubble renderer capabilities + formats\n apo renderer Same as above (shorthand)\n\nOptions:\n --json Output JSON (for agents)\n --key KEY Override API key\n --help Show this help\n\nhttps://appoiint.com/docs/quickstart.html\n';async function run(){switch(command){case"signup":return require("./commands/auth").signup(subArgs,config.baseUrl);case"login":return require("./commands/auth").login(subArgs);case"logout":return require("./commands/auth").logout(subArgs);case"config":return require("./commands/auth").showConfig(config);case"room":return require("./commands/rooms").create(client,subArgs,jsonMode,config);case"rooms":return require("./commands/rooms").list(client,subArgs,jsonMode);case"room-status":return require("./commands/rooms").status(client,subArgs,jsonMode);case"room-end":return require("./commands/rooms").end(client,subArgs,jsonMode);case"invite":return require("./commands/rooms").invite(client,subArgs,jsonMode);case"transcript":return require("./commands/rooms").transcript(client,subArgs,jsonMode);case"join":return subArgs[0]||(fmt.err("Usage: apo join ROOM_ID"),process.exit(1)),client.joinMeeting({roomId:subArgs[0],agentName:"CLI Agent",agentRole:getFlag(subArgs,"role")||"tai-super"}).then(e=>jsonMode?console.log(JSON.stringify(e,null,2)):fmt.ok(`Joined room ${subArgs[0]}`));case"leave":return subArgs[0]||(fmt.err("Usage: apo leave ROOM_ID"),process.exit(1)),client.leaveMeeting({roomId:subArgs[0],agentId:"cli-agent"}).then(e=>jsonMode?console.log(JSON.stringify(e,null,2)):fmt.ok(`Left room ${subArgs[0]}`));case"book":return require("./commands/bookings").book(client,subArgs,jsonMode);case"events":return require("./commands/bookings").events(client,subArgs,jsonMode);case"slots":return require("./commands/bookings").slots(client,subArgs,jsonMode);case"tts":return require("./commands/tts").synthesize(client,subArgs,jsonMode);case"voices":return require("./commands/tts").voices(client,subArgs,jsonMode);case"status":{const e=await api({baseUrl:config.baseUrl,apiKey:""}).status();return jsonMode?console.log(JSON.stringify(e,null,2)):void fmt.ok(`Appoiint ${e.version||"?"} — ${e.available?"online":"offline"}`)}case"version":case"--version":case"-v":return void console.log(require("../package.json").version);case"admin":return require("./commands/admin").run(client,subArgs,jsonMode);case"stats":return require("./commands/stats").run(client,jsonMode);case"funnel":return require("./commands/stats").funnel(client,jsonMode);case"signups":return require("./commands/stats").signups(client,subArgs,jsonMode);case"revenue":return require("./commands/stats").revenue(client,jsonMode);case"tickets":return require("./commands/tickets").list(client,subArgs,jsonMode);case"ticket":const e=subArgs[0];if("show"===e)return require("./commands/tickets").show(client,subArgs.slice(1),jsonMode);if("reply"===e)return require("./commands/tickets").reply(client,subArgs.slice(1),jsonMode);if("close"===e)return require("./commands/tickets").close(client,subArgs.slice(1),jsonMode);fmt.err("Usage: apo ticket [show|reply|close] NUMBER"),process.exit(1);case"audit":return require("./commands/audit").run(client,subArgs,jsonMode);case"diagnose":return require("./commands/diagnose").run(client,subArgs,jsonMode,config);case"init":return require("./commands/init").run(subArgs);case"man":case"renderer":const n="man"===command?subArgs[0]:command;return"renderer"===n?require("./commands/renderer").run(subArgs.slice("man"===command?1:0),jsonMode):void fmt.err("Unknown manual page: "+(n||"(none)")+". Available: renderer");case"mcp-serve":return require("./mcp").serve();case"help":case"--help":case"-h":case void 0:return void console.log(HELP);default:fmt.err(`Unknown command: ${command}`),console.log(HELP),process.exit(1)}}run().catch(e=>{fmt.err(e.message),process.exit(1)});
1
+ const{loadConfig:loadConfig,hasFlag:hasFlag,getFlag:getFlag}=require("./config"),{api:api,rawApi:rawApi}=require("./api"),fmt=require("./format"),args=process.argv.slice(2),command=args[0],subArgs=args.slice(1),jsonMode=hasFlag(args,"json"),NO_AUTH=["signup","login","logout","config","help","--help","-h","status","version","--version","-v","mcp-serve","man","renderer","init"],config=loadConfig(args);NO_AUTH.includes(command)||config.apiKey||(fmt.err("No API key. Run: apo signup --email you@co.com --password Pass123!"),fmt.err("Or: apo login --key YOUR_KEY --user YOUR_USERID"),fmt.err("Or set APO_API_KEY environment variable."),process.exit(1));const client=config.apiKey?api(config):null,raw=config.apiKey?rawApi(config):null,HELP='\nAppoiint CLI — Agent-first meeting platform\n\nAuth:\n apo signup --email E --password P Sign up, get API key (auto-saved)\n apo login --key KEY [--user USERID] Save API key to config\n apo logout Clear config\n apo config Show active config\n\nRooms:\n apo room "Title" Create meeting room\n apo rooms List active rooms\n apo room-status ROOM_ID Room status + participants\n apo room-end ROOM_ID End meeting\n apo invite ROOM_ID --email E --name N Invite human or agent\n apo transcript ROOM_ID [--format F] Get transcript (json|text|srt)\n\nMeetings:\n apo join ROOM_ID Join room as agent participant\n apo leave ROOM_ID Leave room\n\nScheduling:\n apo book --date D --email E Create booking\n apo events List event types\n apo slots --email E --date D Check availability\n\nTTS:\n apo tts "text" --voice cfo Synthesize speech\n apo voices List available voices\n\nAdmin:\n apo admin tenants List all tenants\n apo admin tenant-view SLUG Full tenant detail\n apo admin tenant-create SLUG Create tenant\n apo admin tenant-suspend SLUG Suspend tenant\n apo admin tenant-activate SLUG Reactivate tenant\n apo admin tenant-delete SLUG Delete tenant\n apo admin users List all users\n apo admin user-reset EMAIL -p PASS Reset user password\n apo admin billing MRR, ARR, revenue\n apo admin costs Platform cost summary (STT/TTS/LLM)\n apo admin costs ROOM_ID Per-meeting cost breakdown\n apo admin pricing Current provider pricing table\n\nAnalytics:\n apo stats Platform overview\n apo revenue Revenue breakdown\n apo funnel Signup funnel\n apo signups [--days 7] Recent signups\n\nSupport:\n apo tickets [--status open] List support tickets\n apo ticket show NUMBER Ticket detail\n apo ticket reply NUMBER MESSAGE Reply to ticket\n apo ticket close NUMBER Close ticket\n\nAudit:\n apo audit [--action X] [--limit N] Activity trail\n apo audit export [--format csv] Export audit log\n\nHelpdesk (+$4.99/mo):\n apo helpdesk tickets List tickets\n apo helpdesk ticket show ID Ticket detail + messages\n apo helpdesk ticket create "Subject" Create ticket\n apo helpdesk ticket reply ID "msg" Reply to ticket\n apo helpdesk ticket close ID Close ticket\n apo helpdesk ticket assign ID --agent X Assign ticket\n apo helpdesk kb List KB articles\n apo helpdesk stats Helpdesk statistics\n\nCRM (+$4.99/mo):\n apo crm leads List leads\n apo crm lead show ID Lead detail\n apo crm lead create "Name" --email X Create lead\n apo crm lead convert ID Convert lead → opportunity\n apo crm opps List opportunities\n apo crm opp show ID Opportunity detail\n apo crm opp create "Deal" --value X Create opportunity\n apo crm pipelines List pipelines\n apo crm stats CRM statistics\n\nChannels (agent-to-agent):\n apo channel send @AGENT "msg" Send 1:1 message to agent\n apo channel inbox Unread messages\n apo channel history @AGENT Conversation history\n apo channel agents List agent contacts\n\nDiagnostics:\n apo diagnose ROOM_ID Full room diagnostic (peers, events, relay)\n\nManual:\n apo man renderer Chat bubble renderer capabilities + formats\n apo renderer Same as above (shorthand)\n\nOptions:\n --json Output JSON (for agents)\n --key KEY Override API key\n --help Show this help\n\nhttps://appoiint.com/docs/quickstart.html\n';async function run(){switch(command){case"signup":return require("./commands/auth").signup(subArgs,config.baseUrl);case"login":return require("./commands/auth").login(subArgs);case"logout":return require("./commands/auth").logout(subArgs);case"config":return require("./commands/auth").showConfig(config);case"room":return require("./commands/rooms").create(client,subArgs,jsonMode,config);case"rooms":return require("./commands/rooms").list(client,subArgs,jsonMode);case"room-status":return require("./commands/rooms").status(client,subArgs,jsonMode);case"room-end":return require("./commands/rooms").end(client,subArgs,jsonMode);case"invite":return require("./commands/rooms").invite(client,subArgs,jsonMode);case"transcript":return require("./commands/rooms").transcript(client,subArgs,jsonMode);case"join":return subArgs[0]||(fmt.err("Usage: apo join ROOM_ID"),process.exit(1)),client.joinMeeting({roomId:subArgs[0],agentName:"CLI Agent",agentRole:getFlag(subArgs,"role")||"tai-super"}).then(e=>jsonMode?console.log(JSON.stringify(e,null,2)):fmt.ok(`Joined room ${subArgs[0]}`));case"leave":return subArgs[0]||(fmt.err("Usage: apo leave ROOM_ID"),process.exit(1)),client.leaveMeeting({roomId:subArgs[0],agentId:"cli-agent"}).then(e=>jsonMode?console.log(JSON.stringify(e,null,2)):fmt.ok(`Left room ${subArgs[0]}`));case"book":return require("./commands/bookings").book(client,subArgs,jsonMode);case"events":return require("./commands/bookings").events(client,subArgs,jsonMode);case"slots":return require("./commands/bookings").slots(client,subArgs,jsonMode);case"tts":return require("./commands/tts").synthesize(client,subArgs,jsonMode);case"voices":return require("./commands/tts").voices(client,subArgs,jsonMode);case"status":{const e=await api({baseUrl:config.baseUrl,apiKey:""}).status();return jsonMode?console.log(JSON.stringify(e,null,2)):void fmt.ok(`Appoiint ${e.version||"?"} — ${e.available?"online":"offline"}`)}case"version":case"--version":case"-v":return void console.log(require("../package.json").version);case"admin":return require("./commands/admin").run(client,subArgs,jsonMode);case"stats":return require("./commands/stats").run(client,jsonMode);case"funnel":return require("./commands/stats").funnel(client,jsonMode);case"signups":return require("./commands/stats").signups(client,subArgs,jsonMode);case"revenue":return require("./commands/stats").revenue(client,jsonMode);case"tickets":return require("./commands/tickets").list(client,subArgs,jsonMode);case"ticket":const e=subArgs[0];if("show"===e)return require("./commands/tickets").show(client,subArgs.slice(1),jsonMode);if("reply"===e)return require("./commands/tickets").reply(client,subArgs.slice(1),jsonMode);if("close"===e)return require("./commands/tickets").close(client,subArgs.slice(1),jsonMode);fmt.err("Usage: apo ticket [show|reply|close] NUMBER"),process.exit(1);case"audit":return require("./commands/audit").run(client,subArgs,jsonMode);case"helpdesk":return require("./commands/helpdesk").run(client,subArgs,jsonMode,raw);case"crm":return require("./commands/crm").run(client,subArgs,jsonMode,raw);case"channel":return require("./commands/channels").run(client,subArgs,jsonMode);case"diagnose":return require("./commands/diagnose").run(client,subArgs,jsonMode,config);case"init":return require("./commands/init").run(subArgs);case"man":case"renderer":const n="man"===command?subArgs[0]:command;return"renderer"===n?require("./commands/renderer").run(subArgs.slice("man"===command?1:0),jsonMode):void fmt.err("Unknown manual page: "+(n||"(none)")+". Available: renderer");case"mcp-serve":return require("./mcp").serve();case"help":case"--help":case"-h":case void 0:return void console.log(HELP);default:fmt.err(`Unknown command: ${command}`),console.log(HELP),process.exit(1)}}run().catch(e=>{fmt.err(e.message),process.exit(1)});
package/dist/mcp-tools.js CHANGED
@@ -1 +1 @@
1
- const TOOLS=[{name:"appoiint_status",description:"Get Appoiint platform status and version.",inputSchema:{type:"object",properties:{}},handler:async e=>e.status(),readOnly:!0},{name:"appoiint_create_room",description:"Create a video meeting room. Returns roomId and join URL.",inputSchema:{type:"object",properties:{title:{type:"string",description:'Meeting title (e.g. "Team Standup")'}},required:["title"]},handler:async(e,t)=>{const n=require("./config").loadConfig([]);return e.createRoom({title:t.title,hostId:n.userId})},readOnly:!1},{name:"appoiint_list_rooms",description:"List active meeting rooms.",inputSchema:{type:"object",properties:{}},handler:async e=>e.listRooms(),readOnly:!0},{name:"appoiint_room_status",description:"Get room status and participants.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.roomStatus(t.roomId),readOnly:!0},{name:"appoiint_end_room",description:"End a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.endRoom(t.roomId),readOnly:!1},{name:"appoiint_invite",description:"Invite a human or agent to a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},email:{type:"string",description:"Invitee email"},name:{type:"string",description:"Invitee name"},type:{type:"string",description:"human or agent (default: human)"}},required:["roomId","email"]},handler:async(e,t)=>e.invite(t.roomId,{email:t.email,name:t.name||"Guest",type:t.type||"human"}),readOnly:!1},{name:"appoiint_transcript",description:"Get meeting transcript.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},format:{type:"string",description:"json, text, or srt (default: json)"}},required:["roomId"]},handler:async(e,t)=>e.transcript(t.roomId,t.format||"json"),readOnly:!0},{name:"appoiint_join_meeting",description:"Join a meeting room as an AI agent. Creates persistent Socket.IO connection. You will hear transcripts and can send chat messages. Call appoiint_get_transcripts to read what was said, appoiint_send_chat to respond.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID to join"},agentName:{type:"string",description:"Your display name in the meeting (default: Claude Code)"},agentRole:{type:"string",description:"Your role badge (default: assistant)"}},required:["roomId"]},handler:async(e,t,n)=>{const{MeetingSession:i}=require("./meetingSession"),o=new i({baseUrl:n.config.baseUrl,roomId:t.roomId,agentName:t.agentName||"Claude Code",agentRole:t.agentRole||"assistant"}),r=await o.join();return n.meetingSessions.set(t.roomId,o),r},readOnly:!1},{name:"appoiint_get_transcripts",description:"Get speech transcripts from the meeting. Returns what participants have said since last read. Buffer is cleared after reading.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);if(!i)return{error:"Not in this meeting. Call appoiint_join_meeting first."};const o=i.getTranscripts();return{roomId:t.roomId,count:o.length,transcripts:o}},readOnly:!0},{name:"appoiint_send_chat",description:"Send a chat message to all meeting participants. Your message appears in the AI chat panel with your role badge.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},message:{type:"string",description:"Message to send to meeting participants"}},required:["roomId","message"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);return i?i.sendChat(t.message):{error:"Not in this meeting. Call appoiint_join_meeting first."}},readOnly:!1},{name:"appoiint_meeting_status",description:"Check meeting connection status: connected, peer count, buffered transcript count.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);return i?i.status():{error:"Not in this meeting.",connected:!1}},readOnly:!0},{name:"appoiint_leave_meeting",description:"Leave a meeting room and disconnect.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,n)=>{const i=n.meetingSessions.get(t.roomId);if(!i)return{error:"Not in this meeting."};const o=i.leave();return n.meetingSessions.delete(t.roomId),o},readOnly:!1},{name:"appoiint_list_events",description:"List bookable event types.",inputSchema:{type:"object",properties:{}},handler:async e=>e.events(),readOnly:!0},{name:"appoiint_check_availability",description:"Check available time slots for a host on a given date.",inputSchema:{type:"object",properties:{email:{type:"string",description:"Host email address"},date:{type:"string",description:"Date (YYYY-MM-DD)"},timezone:{type:"string",description:"Timezone (default: UTC)"}},required:["email","date"]},handler:async(e,t)=>e.slots(t.email,t.date,t.timezone||"UTC"),readOnly:!0},{name:"appoiint_create_booking",description:"Create a booking on behalf of a customer.",inputSchema:{type:"object",properties:{eventTypeId:{type:"string",description:"Event type ID"},scheduledAt:{type:"string",description:"ISO 8601 date-time (e.g. 2026-06-15T14:00:00Z)"},duration:{type:"number",description:"Duration in minutes (default: 30)"},customerName:{type:"string",description:"Customer name"},customerEmail:{type:"string",description:"Customer email"}},required:["scheduledAt","customerEmail"]},handler:async(e,t)=>e.book({eventTypeId:t.eventTypeId,scheduledAt:t.scheduledAt,duration:t.duration||30,customer:{name:t.customerName||"Guest",email:t.customerEmail},location:{type:"video"}}),readOnly:!1},{name:"appoiint_tts",description:"Synthesize text-to-speech with CxO agent voice.",inputSchema:{type:"object",properties:{text:{type:"string",description:"Text to synthesize"},voice:{type:"string",description:"Voice: cfo, cto, cmo, cco, cso, clo, heart, michael, nova, echo (default: heart)"}},required:["text"]},handler:async(e,t)=>e.synthesize({text:t.text,voice:t.voice||"heart",agentRole:t.voice}),readOnly:!0},{name:"appoiint_voices",description:"List available TTS voices and CxO agent voice mappings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.voices(),readOnly:!0},{name:"appoiint_admin_tenants",description:"List all tenants with plan, status, usage. Superadmin only.",inputSchema:{type:"object",properties:{}},handler:async e=>e.adminTenants(),readOnly:!0},{name:"appoiint_admin_tenant_view",description:"Full tenant detail: plan, stats, usage, created date.",inputSchema:{type:"object",properties:{slug:{type:"string",description:"Tenant slug"}},required:["slug"]},handler:async(e,t)=>e.adminTenantView(t.slug),readOnly:!0},{name:"appoiint_platform_stats",description:"Platform overview: tenants, users, rooms, bookings, meetings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.platformStats(),readOnly:!0},{name:"appoiint_funnel",description:"Signup funnel with conversion rates.",inputSchema:{type:"object",properties:{}},handler:async e=>e.funnel(),readOnly:!0},{name:"appoiint_revenue",description:"Revenue breakdown: MRR, ARR, fees, payouts.",inputSchema:{type:"object",properties:{}},handler:async e=>e.revenue(),readOnly:!0},{name:"appoiint_audit",description:"Activity audit trail.",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Max entries"},action:{type:"string",description:"Filter by action type"}}},handler:async(e,t)=>{const n=new URLSearchParams;return t.limit&&n.set("limit",t.limit),t.action&&n.set("action",t.action),e.audit(n.toString())},readOnly:!0}];module.exports={TOOLS:TOOLS};
1
+ const TOOLS=[{name:"appoiint_status",description:"Get Appoiint platform status and version.",inputSchema:{type:"object",properties:{}},handler:async e=>e.status(),readOnly:!0},{name:"appoiint_create_room",description:"Create a video meeting room. Returns roomId and join URL.",inputSchema:{type:"object",properties:{title:{type:"string",description:'Meeting title (e.g. "Team Standup")'}},required:["title"]},handler:async(e,t)=>{const i=require("./config").loadConfig([]);return e.createRoom({title:t.title,hostId:i.userId})},readOnly:!1},{name:"appoiint_list_rooms",description:"List active meeting rooms.",inputSchema:{type:"object",properties:{}},handler:async e=>e.listRooms(),readOnly:!0},{name:"appoiint_room_status",description:"Get room status and participants.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.roomStatus(t.roomId),readOnly:!0},{name:"appoiint_end_room",description:"End a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t)=>e.endRoom(t.roomId),readOnly:!1},{name:"appoiint_invite",description:"Invite a human or agent to a meeting room.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},email:{type:"string",description:"Invitee email"},name:{type:"string",description:"Invitee name"},type:{type:"string",description:"human or agent (default: human)"}},required:["roomId","email"]},handler:async(e,t)=>e.invite(t.roomId,{email:t.email,name:t.name||"Guest",type:t.type||"human"}),readOnly:!1},{name:"appoiint_transcript",description:"Get meeting transcript.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},format:{type:"string",description:"json, text, or srt (default: json)"}},required:["roomId"]},handler:async(e,t)=>e.transcript(t.roomId,t.format||"json"),readOnly:!0},{name:"appoiint_join_meeting",description:"Join a meeting room as an AI agent. Creates persistent Socket.IO connection. You will hear transcripts and can send chat messages. Call appoiint_get_transcripts to read what was said, appoiint_send_chat to respond.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID to join"},agentName:{type:"string",description:"Your display name in the meeting (default: Claude Code)"},agentRole:{type:"string",description:"Your role badge (default: assistant)"}},required:["roomId"]},handler:async(e,t,i)=>{const{MeetingSession:n}=require("./meetingSession"),a=new n({baseUrl:i.config.baseUrl,roomId:t.roomId,agentName:t.agentName||"Claude Code",agentRole:t.agentRole||"assistant"}),r=await a.join();return i.meetingSessions.set(t.roomId,a),r},readOnly:!1},{name:"appoiint_get_transcripts",description:"Get speech transcripts from the meeting. Returns what participants have said since last read. Buffer is cleared after reading.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);if(!n)return{error:"Not in this meeting. Call appoiint_join_meeting first."};const a=n.getTranscripts();return{roomId:t.roomId,count:a.length,transcripts:a}},readOnly:!0},{name:"appoiint_send_chat",description:"Send a chat message to all meeting participants. Your message appears in the AI chat panel with your role badge.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"},message:{type:"string",description:"Message to send to meeting participants"}},required:["roomId","message"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);return n?n.sendChat(t.message):{error:"Not in this meeting. Call appoiint_join_meeting first."}},readOnly:!1},{name:"appoiint_meeting_status",description:"Check meeting connection status: connected, peer count, buffered transcript count.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);return n?n.status():{error:"Not in this meeting.",connected:!1}},readOnly:!0},{name:"appoiint_leave_meeting",description:"Leave a meeting room and disconnect.",inputSchema:{type:"object",properties:{roomId:{type:"string",description:"Room ID"}},required:["roomId"]},handler:async(e,t,i)=>{const n=i.meetingSessions.get(t.roomId);if(!n)return{error:"Not in this meeting."};const a=n.leave();return i.meetingSessions.delete(t.roomId),a},readOnly:!1},{name:"appoiint_list_events",description:"List bookable event types.",inputSchema:{type:"object",properties:{}},handler:async e=>e.events(),readOnly:!0},{name:"appoiint_check_availability",description:"Check available time slots for a host on a given date.",inputSchema:{type:"object",properties:{email:{type:"string",description:"Host email address"},date:{type:"string",description:"Date (YYYY-MM-DD)"},timezone:{type:"string",description:"Timezone (default: UTC)"}},required:["email","date"]},handler:async(e,t)=>e.slots(t.email,t.date,t.timezone||"UTC"),readOnly:!0},{name:"appoiint_create_booking",description:"Create a booking on behalf of a customer.",inputSchema:{type:"object",properties:{eventTypeId:{type:"string",description:"Event type ID"},scheduledAt:{type:"string",description:"ISO 8601 date-time (e.g. 2026-06-15T14:00:00Z)"},duration:{type:"number",description:"Duration in minutes (default: 30)"},customerName:{type:"string",description:"Customer name"},customerEmail:{type:"string",description:"Customer email"}},required:["scheduledAt","customerEmail"]},handler:async(e,t)=>e.book({eventTypeId:t.eventTypeId,scheduledAt:t.scheduledAt,duration:t.duration||30,customer:{name:t.customerName||"Guest",email:t.customerEmail},location:{type:"video"}}),readOnly:!1},{name:"appoiint_tts",description:"Synthesize text-to-speech with CxO agent voice.",inputSchema:{type:"object",properties:{text:{type:"string",description:"Text to synthesize"},voice:{type:"string",description:"Voice: cfo, cto, cmo, cco, cso, clo, heart, michael, nova, echo (default: heart)"}},required:["text"]},handler:async(e,t)=>e.synthesize({text:t.text,voice:t.voice||"heart",agentRole:t.voice}),readOnly:!0},{name:"appoiint_voices",description:"List available TTS voices and CxO agent voice mappings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.voices(),readOnly:!0},{name:"appoiint_helpdesk_tickets",description:"List helpdesk tickets. Filter by status.",inputSchema:{type:"object",properties:{status:{type:"string",description:"Filter: open, resolved, closed"}}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET","/saas/api/v1/sdk/helpdesky/tickets"+(t.status?`?status=${t.status}`:""))},readOnly:!0},{name:"appoiint_helpdesk_ticket_show",description:"Get ticket detail with messages.",inputSchema:{type:"object",properties:{ticketId:{type:"string"}},required:["ticketId"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET",`/saas/api/v1/sdk/helpdesky/tickets/${t.ticketId}`)},readOnly:!0},{name:"appoiint_helpdesk_ticket_create",description:"Create a helpdesk ticket.",inputSchema:{type:"object",properties:{subject:{type:"string"},priority:{type:"string"},category:{type:"string"}},required:["subject"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("POST","/saas/api/v1/sdk/helpdesky/tickets",t)},readOnly:!1},{name:"appoiint_helpdesk_ticket_reply",description:"Reply to a helpdesk ticket.",inputSchema:{type:"object",properties:{ticketId:{type:"string"},message:{type:"string"}},required:["ticketId","message"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("POST",`/saas/api/v1/sdk/helpdesky/tickets/${t.ticketId}/messages`,{content:t.message})},readOnly:!1},{name:"appoiint_crm_leads",description:"List CRM leads. Filter by status.",inputSchema:{type:"object",properties:{status:{type:"string"}}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api"),a=t.status?`?status=${t.status}`:"";return n(i.config)("GET",`/saas/api/v1/sdk/crm/leads${a}`)},readOnly:!0},{name:"appoiint_crm_lead_show",description:"Get lead detail.",inputSchema:{type:"object",properties:{leadId:{type:"string"}},required:["leadId"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET",`/saas/api/v1/sdk/crm/leads/${t.leadId}`)},readOnly:!0},{name:"appoiint_crm_lead_create",description:"Create a CRM lead.",inputSchema:{type:"object",properties:{name:{type:"string"},email:{type:"string"},source:{type:"string"}},required:["name"]},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("POST","/saas/api/v1/sdk/crm/leads",t)},readOnly:!1},{name:"appoiint_crm_opportunities",description:"List CRM opportunities. Filter by stage.",inputSchema:{type:"object",properties:{stage:{type:"string"}}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api"),a=t.stage?`?stage=${t.stage}`:"";return n(i.config)("GET",`/saas/api/v1/sdk/crm/opportunities${a}`)},readOnly:!0},{name:"appoiint_crm_pipelines",description:"List CRM pipelines with stages.",inputSchema:{type:"object",properties:{}},handler:async(e,t,i)=>{const{rawApi:n}=require("./api");return n(i.config)("GET","/saas/api/v1/sdk/crm/pipelines")},readOnly:!0},{name:"appoiint_channel_send",description:"Send a 1:1 message to another agent. Use for ops requests, data queries, or notifications.",inputSchema:{type:"object",properties:{to:{type:"string",description:"Recipient agent ID"},message:{type:"string",description:"Message text"},action:{type:"string",description:"Intent/action (e.g. deploy, query, notify)"},payload:{type:"object",description:"Structured data payload"}},required:["to"]},handler:async(e,t)=>{const i={to:t.to,type:t.action?"request":"notify"};return t.message&&(i.payload={message:t.message}),t.action&&(i.action=t.action,i.requestId=`req_${Date.now()}`),t.payload&&(i.payload={...i.payload,...t.payload}),e.channelSend(i)},readOnly:!1},{name:"appoiint_channel_inbox",description:"Get unread messages from other agents.",inputSchema:{type:"object",properties:{}},handler:async e=>e.channelInbox(),readOnly:!0},{name:"appoiint_channel_history",description:"Get message history with a specific agent.",inputSchema:{type:"object",properties:{agentId:{type:"string",description:"Agent ID to get history with"},limit:{type:"number",description:"Max messages (default 50)"}},required:["agentId"]},handler:async(e,t)=>e.channelHistory(t.agentId,t.limit),readOnly:!0},{name:"appoiint_channel_agents",description:"List agents you have communicated with.",inputSchema:{type:"object",properties:{}},handler:async e=>e.channelAgents(),readOnly:!0},{name:"appoiint_admin_tenants",description:"List all tenants with plan, status, usage. Superadmin only.",inputSchema:{type:"object",properties:{}},handler:async e=>e.adminTenants(),readOnly:!0},{name:"appoiint_admin_tenant_view",description:"Full tenant detail: plan, stats, usage, created date.",inputSchema:{type:"object",properties:{slug:{type:"string",description:"Tenant slug"}},required:["slug"]},handler:async(e,t)=>e.adminTenantView(t.slug),readOnly:!0},{name:"appoiint_platform_stats",description:"Platform overview: tenants, users, rooms, bookings, meetings.",inputSchema:{type:"object",properties:{}},handler:async e=>e.platformStats(),readOnly:!0},{name:"appoiint_funnel",description:"Signup funnel with conversion rates.",inputSchema:{type:"object",properties:{}},handler:async e=>e.funnel(),readOnly:!0},{name:"appoiint_revenue",description:"Revenue breakdown: MRR, ARR, fees, payouts.",inputSchema:{type:"object",properties:{}},handler:async e=>e.revenue(),readOnly:!0},{name:"appoiint_audit",description:"Activity audit trail.",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Max entries"},action:{type:"string",description:"Filter by action type"}}},handler:async(e,t)=>{const i=new URLSearchParams;return t.limit&&i.set("limit",t.limit),t.action&&i.set("action",t.action),e.audit(i.toString())},readOnly:!0}];module.exports={TOOLS:TOOLS};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appoiint",
3
- "version": "3.0.1",
3
+ "version": "4.1.0",
4
4
  "description": "Appoiint CLI — schedule meetings, create rooms, join video calls. Agent-first meeting platform.",
5
5
  "bin": {
6
6
  "apo": "bin/cli.js"