savethis
Version:
CLI tool to download and organize Gmail attachments with AI document summarization
260 lines (220 loc) • 72.9 kB
JavaScript
#!/usr/bin/env node
import {fileURLToPath}from'url';import he from'path';import {Command}from'commander';import {google}from'googleapis';import _ from'node:fs';import Go from'node:os';import R,{extname}from'node:path';import He from'inquirer';import E from'ansi-colors';import {tool,generateText,generateObject}from'ai';import $,{z as z$1}from'zod';import {createGoogleGenerativeAI}from'@ai-sdk/google';import ht,{promises,existsSync}from'fs';import Jo from'iconv-lite';import tn from'mammoth';import Qo from'turndown';import {gfm}from'turndown-plugin-gfm';import on from'exifreader';import rn from'scribe.js-ocr';import cn from'@opendocsg/pdf2md';import {PPTXInHTMLOut}from'pptx-in-html-out';import*as pe from'xlsx';import dt from'fs/promises';import bn from'better-sqlite3';import uo from'console';import Se from'process';import gr from'@elysiajs/html';import hr from'elysia';import {url}from'inspector';import Tr from'open';var ko=Object.create;var Ye=Object.defineProperty;var _o=Object.getOwnPropertyDescriptor;var Ro=Object.getOwnPropertyNames;var Ao=Object.getPrototypeOf,Mo=Object.prototype.hasOwnProperty;var J=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,o)=>(typeof require<"u"?require:t)[o]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Do=(e,t)=>()=>(e&&(t=e(e=0)),t);var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var No=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ro(t))!Mo.call(e,r)&&r!==o&&Ye(e,r,{get:()=>t[r],enumerable:!(n=_o(t,r))||n.enumerable});return e};var Q=(e,t,o)=>(o=e!=null?ko(Ao(e)):{},No(Ye(o,"default",{value:e,enumerable:true}),e));var jo,Lo,u,l=Do(()=>{jo=()=>fileURLToPath(import.meta.url),Lo=()=>he.dirname(jo()),u=Lo();});var wt=I((ii,xt)=>{l();xt.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};});var Re=I((li,vt)=>{l();var ne=wt(),Tt={};for(let e of Object.keys(ne))Tt[ne[e]]=e;var d={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};vt.exports=d;for(let e of Object.keys(d)){if(!("channels"in d[e]))throw new Error("missing channels property: "+e);if(!("labels"in d[e]))throw new Error("missing channel labels property: "+e);if(d[e].labels.length!==d[e].channels)throw new Error("channel and label counts mismatch: "+e);let{channels:t,labels:o}=d[e];delete d[e].channels,delete d[e].labels,Object.defineProperty(d[e],"channels",{value:t}),Object.defineProperty(d[e],"labels",{value:o});}d.rgb.hsl=function(e){let t=e[0]/255,o=e[1]/255,n=e[2]/255,r=Math.min(t,o,n),a=Math.max(t,o,n),s=a-r,i,c;a===r?i=0:t===a?i=(o-n)/s:o===a?i=2+(n-t)/s:n===a&&(i=4+(t-o)/s),i=Math.min(i*60,360),i<0&&(i+=360);let m=(r+a)/2;return a===r?c=0:m<=.5?c=s/(a+r):c=s/(2-a-r),[i,c*100,m*100]};d.rgb.hsv=function(e){let t,o,n,r,a,s=e[0]/255,i=e[1]/255,c=e[2]/255,m=Math.max(s,i,c),p=m-Math.min(s,i,c),g=function(C){return (m-C)/6/p+1/2};return p===0?(r=0,a=0):(a=p/m,t=g(s),o=g(i),n=g(c),s===m?r=n-o:i===m?r=1/3+t-n:c===m&&(r=2/3+o-t),r<0?r+=1:r>1&&(r-=1)),[r*360,a*100,m*100]};d.rgb.hwb=function(e){let t=e[0],o=e[1],n=e[2],r=d.rgb.hsl(e)[0],a=1/255*Math.min(t,Math.min(o,n));return n=1-1/255*Math.max(t,Math.max(o,n)),[r,a*100,n*100]};d.rgb.cmyk=function(e){let t=e[0]/255,o=e[1]/255,n=e[2]/255,r=Math.min(1-t,1-o,1-n),a=(1-t-r)/(1-r)||0,s=(1-o-r)/(1-r)||0,i=(1-n-r)/(1-r)||0;return [a*100,s*100,i*100,r*100]};function Sn(e,t){return (e[0]-t[0])**2+(e[1]-t[1])**2+(e[2]-t[2])**2}d.rgb.keyword=function(e){let t=Tt[e];if(t)return t;let o=1/0,n;for(let r of Object.keys(ne)){let a=ne[r],s=Sn(e,a);s<o&&(o=s,n=r);}return n};d.keyword.rgb=function(e){return ne[e]};d.rgb.xyz=function(e){let t=e[0]/255,o=e[1]/255,n=e[2]/255;t=t>.04045?((t+.055)/1.055)**2.4:t/12.92,o=o>.04045?((o+.055)/1.055)**2.4:o/12.92,n=n>.04045?((n+.055)/1.055)**2.4:n/12.92;let r=t*.4124+o*.3576+n*.1805,a=t*.2126+o*.7152+n*.0722,s=t*.0193+o*.1192+n*.9505;return [r*100,a*100,s*100]};d.rgb.lab=function(e){let t=d.rgb.xyz(e),o=t[0],n=t[1],r=t[2];o/=95.047,n/=100,r/=108.883,o=o>.008856?o**(1/3):7.787*o+16/116,n=n>.008856?n**(1/3):7.787*n+16/116,r=r>.008856?r**(1/3):7.787*r+16/116;let a=116*n-16,s=500*(o-n),i=200*(n-r);return [a,s,i]};d.hsl.rgb=function(e){let t=e[0]/360,o=e[1]/100,n=e[2]/100,r,a,s;if(o===0)return s=n*255,[s,s,s];n<.5?r=n*(1+o):r=n+o-n*o;let i=2*n-r,c=[0,0,0];for(let m=0;m<3;m++)a=t+1/3*-(m-1),a<0&&a++,a>1&&a--,6*a<1?s=i+(r-i)*6*a:2*a<1?s=r:3*a<2?s=i+(r-i)*(2/3-a)*6:s=i,c[m]=s*255;return c};d.hsl.hsv=function(e){let t=e[0],o=e[1]/100,n=e[2]/100,r=o,a=Math.max(n,.01);n*=2,o*=n<=1?n:2-n,r*=a<=1?a:2-a;let s=(n+o)/2,i=n===0?2*r/(a+r):2*o/(n+o);return [t,i*100,s*100]};d.hsv.rgb=function(e){let t=e[0]/60,o=e[1]/100,n=e[2]/100,r=Math.floor(t)%6,a=t-Math.floor(t),s=255*n*(1-o),i=255*n*(1-o*a),c=255*n*(1-o*(1-a));switch(n*=255,r){case 0:return [n,c,s];case 1:return [i,n,s];case 2:return [s,n,c];case 3:return [s,i,n];case 4:return [c,s,n];case 5:return [n,s,i]}};d.hsv.hsl=function(e){let t=e[0],o=e[1]/100,n=e[2]/100,r=Math.max(n,.01),a,s;s=(2-o)*n;let i=(2-o)*r;return a=o*r,a/=i<=1?i:2-i,a=a||0,s/=2,[t,a*100,s*100]};d.hwb.rgb=function(e){let t=e[0]/360,o=e[1]/100,n=e[2]/100,r=o+n,a;r>1&&(o/=r,n/=r);let s=Math.floor(6*t),i=1-n;a=6*t-s,(s&1)!==0&&(a=1-a);let c=o+a*(i-o),m,p,g;switch(s){default:case 6:case 0:m=i,p=c,g=o;break;case 1:m=c,p=i,g=o;break;case 2:m=o,p=i,g=c;break;case 3:m=o,p=c,g=i;break;case 4:m=c,p=o,g=i;break;case 5:m=i,p=o,g=c;break}return [m*255,p*255,g*255]};d.cmyk.rgb=function(e){let t=e[0]/100,o=e[1]/100,n=e[2]/100,r=e[3]/100,a=1-Math.min(1,t*(1-r)+r),s=1-Math.min(1,o*(1-r)+r),i=1-Math.min(1,n*(1-r)+r);return [a*255,s*255,i*255]};d.xyz.rgb=function(e){let t=e[0]/100,o=e[1]/100,n=e[2]/100,r,a,s;return r=t*3.2406+o*-1.5372+n*-0.4986,a=t*-0.9689+o*1.8758+n*.0415,s=t*.0557+o*-0.204+n*1.057,r=r>.0031308?1.055*r**(1/2.4)-.055:r*12.92,a=a>.0031308?1.055*a**(1/2.4)-.055:a*12.92,s=s>.0031308?1.055*s**(1/2.4)-.055:s*12.92,r=Math.min(Math.max(0,r),1),a=Math.min(Math.max(0,a),1),s=Math.min(Math.max(0,s),1),[r*255,a*255,s*255]};d.xyz.lab=function(e){let t=e[0],o=e[1],n=e[2];t/=95.047,o/=100,n/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,o=o>.008856?o**(1/3):7.787*o+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;let r=116*o-16,a=500*(t-o),s=200*(o-n);return [r,a,s]};d.lab.xyz=function(e){let t=e[0],o=e[1],n=e[2],r,a,s;a=(t+16)/116,r=o/500+a,s=a-n/200;let i=a**3,c=r**3,m=s**3;return a=i>.008856?i:(a-16/116)/7.787,r=c>.008856?c:(r-16/116)/7.787,s=m>.008856?m:(s-16/116)/7.787,r*=95.047,a*=100,s*=108.883,[r,a,s]};d.lab.lch=function(e){let t=e[0],o=e[1],n=e[2],r;r=Math.atan2(n,o)*360/2/Math.PI,r<0&&(r+=360);let s=Math.sqrt(o*o+n*n);return [t,s,r]};d.lch.lab=function(e){let t=e[0],o=e[1],r=e[2]/360*2*Math.PI,a=o*Math.cos(r),s=o*Math.sin(r);return [t,a,s]};d.rgb.ansi16=function(e,t=null){let[o,n,r]=e,a=t===null?d.rgb.hsv(e)[2]:t;if(a=Math.round(a/50),a===0)return 30;let s=30+(Math.round(r/255)<<2|Math.round(n/255)<<1|Math.round(o/255));return a===2&&(s+=60),s};d.hsv.ansi16=function(e){return d.rgb.ansi16(d.hsv.rgb(e),e[2])};d.rgb.ansi256=function(e){let t=e[0],o=e[1],n=e[2];return t===o&&o===n?t<8?16:t>248?231:Math.round((t-8)/247*24)+232:16+36*Math.round(t/255*5)+6*Math.round(o/255*5)+Math.round(n/255*5)};d.ansi16.rgb=function(e){let t=e%10;if(t===0||t===7)return e>50&&(t+=3.5),t=t/10.5*255,[t,t,t];let o=(~~(e>50)+1)*.5,n=(t&1)*o*255,r=(t>>1&1)*o*255,a=(t>>2&1)*o*255;return [n,r,a]};d.ansi256.rgb=function(e){if(e>=232){let a=(e-232)*10+8;return [a,a,a]}e-=16;let t,o=Math.floor(e/36)/5*255,n=Math.floor((t=e%36)/6)/5*255,r=t%6/5*255;return [o,n,r]};d.rgb.hex=function(e){let o=(((Math.round(e[0])&255)<<16)+((Math.round(e[1])&255)<<8)+(Math.round(e[2])&255)).toString(16).toUpperCase();return "000000".substring(o.length)+o};d.hex.rgb=function(e){let t=e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!t)return [0,0,0];let o=t[0];t[0].length===3&&(o=o.split("").map(i=>i+i).join(""));let n=parseInt(o,16),r=n>>16&255,a=n>>8&255,s=n&255;return [r,a,s]};d.rgb.hcg=function(e){let t=e[0]/255,o=e[1]/255,n=e[2]/255,r=Math.max(Math.max(t,o),n),a=Math.min(Math.min(t,o),n),s=r-a,i,c;return s<1?i=a/(1-s):i=0,s<=0?c=0:r===t?c=(o-n)/s%6:r===o?c=2+(n-t)/s:c=4+(t-o)/s,c/=6,c%=1,[c*360,s*100,i*100]};d.hsl.hcg=function(e){let t=e[1]/100,o=e[2]/100,n=o<.5?2*t*o:2*t*(1-o),r=0;return n<1&&(r=(o-.5*n)/(1-n)),[e[0],n*100,r*100]};d.hsv.hcg=function(e){let t=e[1]/100,o=e[2]/100,n=t*o,r=0;return n<1&&(r=(o-n)/(1-n)),[e[0],n*100,r*100]};d.hcg.rgb=function(e){let t=e[0]/360,o=e[1]/100,n=e[2]/100;if(o===0)return [n*255,n*255,n*255];let r=[0,0,0],a=t%1*6,s=a%1,i=1-s,c=0;switch(Math.floor(a)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=i,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=i,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=i;}return c=(1-o)*n,[(o*r[0]+c)*255,(o*r[1]+c)*255,(o*r[2]+c)*255]};d.hcg.hsv=function(e){let t=e[1]/100,o=e[2]/100,n=t+o*(1-t),r=0;return n>0&&(r=t/n),[e[0],r*100,n*100]};d.hcg.hsl=function(e){let t=e[1]/100,n=e[2]/100*(1-t)+.5*t,r=0;return n>0&&n<.5?r=t/(2*n):n>=.5&&n<1&&(r=t/(2*(1-n))),[e[0],r*100,n*100]};d.hcg.hwb=function(e){let t=e[1]/100,o=e[2]/100,n=t+o*(1-t);return [e[0],(n-t)*100,(1-n)*100]};d.hwb.hcg=function(e){let t=e[1]/100,n=1-e[2]/100,r=n-t,a=0;return r<1&&(a=(n-r)/(1-r)),[e[0],r*100,a*100]};d.apple.rgb=function(e){return [e[0]/65535*255,e[1]/65535*255,e[2]/65535*255]};d.rgb.apple=function(e){return [e[0]/255*65535,e[1]/255*65535,e[2]/255*65535]};d.gray.rgb=function(e){return [e[0]/100*255,e[0]/100*255,e[0]/100*255]};d.gray.hsl=function(e){return [0,0,e[0]]};d.gray.hsv=d.gray.hsl;d.gray.hwb=function(e){return [0,100,e[0]]};d.gray.cmyk=function(e){return [0,0,0,e[0]]};d.gray.lab=function(e){return [e[0],0,0]};d.gray.hex=function(e){let t=Math.round(e[0]/100*255)&255,n=((t<<16)+(t<<8)+t).toString(16).toUpperCase();return "000000".substring(n.length)+n};d.rgb.gray=function(e){return [(e[0]+e[1]+e[2])/3/255*100]};});var Ct=I((ui,St)=>{l();var ye=Re();function Cn(){let e={},t=Object.keys(ye);for(let o=t.length,n=0;n<o;n++)e[t[n]]={distance:-1,parent:null};return e}function In(e){let t=Cn(),o=[e];for(t[e].distance=0;o.length;){let n=o.pop(),r=Object.keys(ye[n]);for(let a=r.length,s=0;s<a;s++){let i=r[s],c=t[i];c.distance===-1&&(c.distance=t[n].distance+1,c.parent=n,o.unshift(i));}}return t}function On(e,t){return function(o){return t(e(o))}}function kn(e,t){let o=[t[e].parent,e],n=ye[t[e].parent][e],r=t[e].parent;for(;t[r].parent;)o.unshift(t[r].parent),n=On(ye[t[r].parent][r],n),r=t[r].parent;return n.conversion=o,n}St.exports=function(e){let t=In(e),o={},n=Object.keys(t);for(let r=n.length,a=0;a<r;a++){let s=n[a];t[s].parent!==null&&(o[s]=kn(s,t));}return o};});var Ot=I((fi,It)=>{l();var Ae=Re(),_n=Ct(),U={},Rn=Object.keys(Ae);function An(e){let t=function(...o){let n=o[0];return n==null?n:(n.length>1&&(o=n),e(o))};return "conversion"in e&&(t.conversion=e.conversion),t}function Mn(e){let t=function(...o){let n=o[0];if(n==null)return n;n.length>1&&(o=n);let r=e(o);if(typeof r=="object")for(let a=r.length,s=0;s<a;s++)r[s]=Math.round(r[s]);return r};return "conversion"in e&&(t.conversion=e.conversion),t}Rn.forEach(e=>{U[e]={},Object.defineProperty(U[e],"channels",{value:Ae[e].channels}),Object.defineProperty(U[e],"labels",{value:Ae[e].labels});let t=_n(e);Object.keys(t).forEach(n=>{let r=t[n];U[e][n]=Mn(r),U[e][n].raw=An(r);});});It.exports=U;});var Dt=I((gi,Mt)=>{l();var kt=(e,t)=>(...o)=>`\x1B[${e(...o)+t}m`,_t=(e,t)=>(...o)=>{let n=e(...o);return `\x1B[${38+t};5;${n}m`},Rt=(e,t)=>(...o)=>{let n=e(...o);return `\x1B[${38+t};2;${n[0]};${n[1]};${n[2]}m`},be=e=>e,At=(e,t,o)=>[e,t,o],H=(e,t,o)=>{Object.defineProperty(e,t,{get:()=>{let n=o();return Object.defineProperty(e,t,{value:n,enumerable:true,configurable:true}),n},enumerable:true,configurable:true});},Me,X=(e,t,o,n)=>{Me===void 0&&(Me=Ot());let r=n?10:0,a={};for(let[s,i]of Object.entries(Me)){let c=s==="ansi16"?"ansi":s;s===t?a[c]=e(o,r):typeof i=="object"&&(a[c]=e(i[t],r));}return a};function Dn(){let e=new Map,t={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};t.color.gray=t.color.blackBright,t.bgColor.bgGray=t.bgColor.bgBlackBright,t.color.grey=t.color.blackBright,t.bgColor.bgGrey=t.bgColor.bgBlackBright;for(let[o,n]of Object.entries(t)){for(let[r,a]of Object.entries(n))t[r]={open:`\x1B[${a[0]}m`,close:`\x1B[${a[1]}m`},n[r]=t[r],e.set(a[0],a[1]);Object.defineProperty(t,o,{value:n,enumerable:false});}return Object.defineProperty(t,"codes",{value:e,enumerable:false}),t.color.close="\x1B[39m",t.bgColor.close="\x1B[49m",H(t.color,"ansi",()=>X(kt,"ansi16",be,false)),H(t.color,"ansi256",()=>X(_t,"ansi256",be,false)),H(t.color,"ansi16m",()=>X(Rt,"rgb",At,false)),H(t.bgColor,"ansi",()=>X(kt,"ansi16",be,true)),H(t.bgColor,"ansi256",()=>X(_t,"ansi256",be,true)),H(t.bgColor,"ansi16m",()=>X(Rt,"rgb",At,true)),t}Object.defineProperty(Mt,"exports",{enumerable:true,get:Dn});});var $t=I((yi,Nt)=>{l();Nt.exports=(e,t=process.argv)=>{let o=e.startsWith("-")?"":e.length===1?"-":"--",n=t.indexOf(o+e),r=t.indexOf("--");return n!==-1&&(r===-1||n<r)};});var Lt=I((Ei,jt)=>{l();var Nn=J("os"),Ft=J("tty"),S=$t(),{env:x}=process,A;S("no-color")||S("no-colors")||S("color=false")||S("color=never")?A=0:(S("color")||S("colors")||S("color=true")||S("color=always"))&&(A=1);"FORCE_COLOR"in x&&(x.FORCE_COLOR==="true"?A=1:x.FORCE_COLOR==="false"?A=0:A=x.FORCE_COLOR.length===0?1:Math.min(parseInt(x.FORCE_COLOR,10),3));function De(e){return e===0?false:{level:e,hasBasic:true,has256:e>=2,has16m:e>=3}}function Ne(e,t){if(A===0)return 0;if(S("color=16m")||S("color=full")||S("color=truecolor"))return 3;if(S("color=256"))return 2;if(e&&!t&&A===void 0)return 0;let o=A||0;if(x.TERM==="dumb")return o;if(process.platform==="win32"){let n=Nn.release().split(".");return Number(n[0])>=10&&Number(n[2])>=10586?Number(n[2])>=14931?3:2:1}if("CI"in x)return ["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some(n=>n in x)||x.CI_NAME==="codeship"?1:o;if("TEAMCITY_VERSION"in x)return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(x.TEAMCITY_VERSION)?1:0;if(x.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in x){let n=parseInt((x.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(x.TERM_PROGRAM){case "iTerm.app":return n>=3?3:2;case "Apple_Terminal":return 2}}return /-256(color)?$/i.test(x.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(x.TERM)||"COLORTERM"in x?1:o}function $n(e){let t=Ne(e,e&&e.isTTY);return De(t)}jt.exports={supportsColor:$n,stdout:De(Ne(true,Ft.isatty(1))),stderr:De(Ne(true,Ft.isatty(2)))};});var zt=I((wi,Gt)=>{l();var Fn=(e,t,o)=>{let n=e.indexOf(t);if(n===-1)return e;let r=t.length,a=0,s="";do s+=e.substr(a,n-a)+t+o,a=n+r,n=e.indexOf(t,a);while(n!==-1);return s+=e.substr(a),s},jn=(e,t,o,n)=>{let r=0,a="";do{let s=e[n-1]==="\r";a+=e.substr(r,(s?n-1:n)-r)+t+(s?`\r
`:`
`)+o,r=n+1,n=e.indexOf(`
`,r);}while(n!==-1);return a+=e.substr(r),a};Gt.exports={stringReplaceAll:Fn,stringEncaseCRLFWithFirstIndex:jn};});var Ht=I((vi,Ut)=>{l();var Ln=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,Pt=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,Gn=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,zn=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,Pn=new Map([["n",`
`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e","\x1B"],["a","\x07"]]);function qt(e){let t=e[0]==="u",o=e[1]==="{";return t&&!o&&e.length===5||e[0]==="x"&&e.length===3?String.fromCharCode(parseInt(e.slice(1),16)):t&&o?String.fromCodePoint(parseInt(e.slice(2,-1),16)):Pn.get(e)||e}function Bn(e,t){let o=[],n=t.trim().split(/\s*,\s*/g),r;for(let a of n){let s=Number(a);if(!Number.isNaN(s))o.push(s);else if(r=a.match(Gn))o.push(r[2].replace(zn,(i,c,m)=>c?qt(c):m));else throw new Error(`Invalid Chalk template style argument: ${a} (in style '${e}')`)}return o}function qn(e){Pt.lastIndex=0;let t=[],o;for(;(o=Pt.exec(e))!==null;){let n=o[1];if(o[2]){let r=Bn(n,o[2]);t.push([n].concat(r));}else t.push([n]);}return t}function Bt(e,t){let o={};for(let r of t)for(let a of r.styles)o[a[0]]=r.inverse?null:a.slice(1);let n=e;for(let[r,a]of Object.entries(o))if(Array.isArray(a)){if(!(r in n))throw new Error(`Unknown Chalk style: ${r}`);n=a.length>0?n[r](...a):n[r];}return n}Ut.exports=(e,t)=>{let o=[],n=[],r=[];if(t.replace(Ln,(a,s,i,c,m,p)=>{if(s)r.push(qt(s));else if(c){let g=r.join("");r=[],n.push(o.length===0?g:Bt(e,o)(g)),o.push({inverse:i,styles:qn(c)});}else if(m){if(o.length===0)throw new Error("Found extraneous } in Chalk template literal");n.push(Bt(e,o)(r.join(""))),r=[],o.pop();}else r.push(p);}),n.push(r.join("")),o.length>0){let a=`Chalk template literal is missing ${o.length} closing bracket${o.length===1?"":"s"} (\`}\`)`;throw new Error(a)}return n.join("")};});var W=I((Ci,Jt)=>{l();var re=Dt(),{stdout:Fe,stderr:je}=Lt(),{stringReplaceAll:Un,stringEncaseCRLFWithFirstIndex:Hn}=zt(),{isArray:Ee}=Array,Yt=["ansi","ansi","ansi256","ansi16m"],Y=Object.create(null),Xn=(e,t={})=>{if(t.level&&!(Number.isInteger(t.level)&&t.level>=0&&t.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let o=Fe?Fe.level:0;e.level=t.level===void 0?o:t.level;},Le=class{constructor(t){return Wt(t)}},Wt=e=>{let t={};return Xn(t,e),t.template=(...o)=>Vt(t.template,...o),Object.setPrototypeOf(t,xe.prototype),Object.setPrototypeOf(t.template,t),t.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},t.template.Instance=Le,t.template};function xe(e){return Wt(e)}for(let[e,t]of Object.entries(re))Y[e]={get(){let o=we(this,Ge(t.open,t.close,this._styler),this._isEmpty);return Object.defineProperty(this,e,{value:o}),o}};Y.visible={get(){let e=we(this,this._styler,true);return Object.defineProperty(this,"visible",{value:e}),e}};var Kt=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let e of Kt)Y[e]={get(){let{level:t}=this;return function(...o){let n=Ge(re.color[Yt[t]][e](...o),re.color.close,this._styler);return we(this,n,this._isEmpty)}}};for(let e of Kt){let t="bg"+e[0].toUpperCase()+e.slice(1);Y[t]={get(){let{level:o}=this;return function(...n){let r=Ge(re.bgColor[Yt[o]][e](...n),re.bgColor.close,this._styler);return we(this,r,this._isEmpty)}}};}var Yn=Object.defineProperties(()=>{},{...Y,level:{enumerable:true,get(){return this._generator.level},set(e){this._generator.level=e;}}}),Ge=(e,t,o)=>{let n,r;return o===void 0?(n=e,r=t):(n=o.openAll+e,r=t+o.closeAll),{open:e,close:t,openAll:n,closeAll:r,parent:o}},we=(e,t,o)=>{let n=(...r)=>Ee(r[0])&&Ee(r[0].raw)?Xt(n,Vt(n,...r)):Xt(n,r.length===1?""+r[0]:r.join(" "));return Object.setPrototypeOf(n,Yn),n._generator=e,n._styler=t,n._isEmpty=o,n},Xt=(e,t)=>{if(e.level<=0||!t)return e._isEmpty?"":t;let o=e._styler;if(o===void 0)return t;let{openAll:n,closeAll:r}=o;if(t.indexOf("\x1B")!==-1)for(;o!==void 0;)t=Un(t,o.close,o.open),o=o.parent;let a=t.indexOf(`
`);return a!==-1&&(t=Hn(t,r,n,a)),n+t+r},$e,Vt=(e,...t)=>{let[o]=t;if(!Ee(o)||!Ee(o.raw))return t.join(" ");let n=t.slice(1),r=[o.raw[0]];for(let a=1;a<o.length;a++)r.push(String(n[a-1]).replace(/[{}\\]/g,"\\$&"),String(o.raw[a]));return $e===void 0&&($e=Ht()),$e(e,r.join(""))};Object.defineProperties(xe.prototype,Y);var Te=xe();Te.supportsColor=Fe;Te.stderr=xe({level:je?je.level:0});Te.stderr.supportsColor=je;Jt.exports=Te;});l();l();l();l();var ae=R.join(Go.homedir(),".savethis"),G=R.join(ae,"config.json"),v=ae,D=R.join(v,"tokens"),Z=R.join(v,"credentials.json"),We=["https://www.googleapis.com/auth/gmail.readonly","https://www.googleapis.com/auth/userinfo.email"],L={credentialsPath:Z,outputDir:"./attachments",model:"gemini-2.0-pro-exp-02-05",googleApiKey:""};function Ke(){try{let e=[R.join(u,"..","package.json"),R.join(u,"..","..","package.json"),R.join(u,"..","..","..","package.json"),R.join(u,"..","..","..","..","package.json")];for(let t of e)if(_.existsSync(t))return JSON.parse(_.readFileSync(t,"utf-8"));return {version:"0.1.0"}}catch(e){return e instanceof Error?console.warn("Could not read package.json, using default version:",e.message):console.warn("Could not read package.json, using default version"),{version:"0.1.0"}}}function se(){try{if(_.existsSync(ae)||_.mkdirSync(ae,{recursive:!0}),!_.existsSync(G))return _.writeFileSync(G,JSON.stringify(L,null,2)),{...L};let e=JSON.parse(_.readFileSync(G,"utf-8"));return {...L,...e}}catch(e){return console.warn("Config error, using defaults:",e),{...L}}}function T(e){let t=se();return t[e]===void 0?(console.warn(`No value set for ${e}, using default: ${L[e]}`),L[e]):t[e]}function Ve(e,t){let o=se();o[e]=t,_.writeFileSync(G,JSON.stringify(o,null,2));}l();function N(e){try{return _.existsSync(e)||_.mkdirSync(e,{recursive:!0}),!0}catch(t){return console.error(`Failed to create directory ${e}:`,t),false}}function Je(e){try{return _.existsSync(e)?JSON.parse(_.readFileSync(e,"utf-8")):null}catch(t){return console.warn(`Error parsing JSON from ${e}:`,t),null}}function Qe(e){if(e===0)return "0 Bytes";let t=1024,o=["Bytes","KB","MB","GB","TB"],n=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,n)).toFixed(2))+" "+o[n]}l();function Ie(){if(!_.existsSync(Z))throw zo(),new Error("Credentials not found");return JSON.parse(_.readFileSync(Z,"utf-8"))}function zo(){_.existsSync(v)||(_.mkdirSync(v,{recursive:true}),console.log(`Created directory: ${v}`));let{platform:e}=process;try{e==="win32"?J("child_process").exec(`explorer "${v}"`):e==="darwin"?J("child_process").exec(`open "${v}"`):e==="linux"&&J("child_process").exec(`xdg-open "${v}"`);}catch(t){console.error("Could not open folder:",t);}throw process.env.NODE_ENV!=="test"&&(console.log("No credentials found at",Z),console.log(`
Follow these steps to set up your credentials:`),console.log("1. Go to https://console.developers.google.com/apis/credentials"),console.log("2. Create an OAuth client ID (Application type: Desktop app)"),console.log("3. Download the JSON file and save it as credentials.json in",v),console.log(`
After saving the file, run this command again.`)),new Error("Credentials not found")}l();l();function Oe(e){let t=R.join(D,`${e}.json`);return Je(t)}function Ze(e,t){N(D);let o=R.join(D,`${e}.json`);return _.writeFileSync(o,JSON.stringify(t)),o}function z(){return _.existsSync(D)?_.readdirSync(D).filter(e=>e.endsWith(".json")).map(e=>R.basename(e,".json")):[]}function et(e){let t=R.join(D,`${e}.json`);return _.existsSync(t)?(_.unlinkSync(t),true):false}function ke(e){let{client_secret:t,client_id:o,redirect_uris:n}=e.installed||e.web||{client_secret:"",client_id:"",redirect_uris:[""]};return new google.auth.OAuth2(o,t,n[0])}async function me(e,t){let o=e.generateAuthUrl({access_type:"offline",scope:We,prompt:"select_account",include_granted_scopes:true});console.log("Authorize this app by visiting this URL:",o),console.log("(You will be prompted to select which Google account to use)");let{authCode:n}=await He.prompt([{type:"input",name:"authCode",message:"Enter the authorization code from the browser:",validate:i=>i.length>0?true:"Please enter a valid authorization code"}]),{tokens:r}=await e.getToken(n);e.setCredentials(r);let a;try{r.access_token&&(a=(await e.getTokenInfo(r.access_token)).email,console.log(`Authenticated as: ${a}`));}catch(i){console.warn("Could not get email from token info:",i);}a||(t?a=t:(a=`gmail-account-${Date.now()}`,console.log(`Could not determine email address, using generated name: ${a}`)));let s=Ze(a,r);return console.log(`Token for ${a} stored to ${s}`),e}function Uo(e){let t=Ie(),o=ke(t);if(e){let r=Oe(e);return r?(o.setCredentials(r),o):(console.warn(`Token not found for ${e}, creating a new one`),me(o,e))}let n=z();if(n.length>0){let r=n[0];if(r){let a=Oe(r);if(a)return o.setCredentials(a),o}}return me(o)}async function _e(e){try{return N(v),await Uo(e)}catch(t){throw console.error("Error during authentication:",t),t}}async function tt(){try{N(v);let e=Ie(),t=ke(e),o=`account-${Date.now()}`;return await me(t,o)}catch(e){throw console.error("Error during new account authentication:",e),e}}async function P(e){let t=await _e(e);return google.gmail({version:"v1",auth:t})}function ot(e){let t=e.command("accounts").description("Manage Gmail accounts").action(async()=>{let o=z();if(o.length===0){console.log(E.yellow("No authenticated accounts found.")),console.log(E.cyan("Starting authentication process..."));try{await _e(),console.log(E.green("\u2713 Authentication successful!")),console.log(E.gray('You can now start downloading attachments with the "download" command.')),process.exit(0);}catch(n){console.error(E.red("\u2717 Authentication failed:"),n),process.exit(1);}}else console.log(E.green(`\u2713 ${o.length} authenticated ${o.length===1?"account":"accounts"}:`)),o.forEach((n,r)=>{console.log(` ${E.cyan(`${r+1}.`)} ${E.white(n)}`);}),console.log(`
Commands:`),console.log(` ${E.cyan("savethis accounts add")} Add a new Gmail account`),console.log(` ${E.cyan("savethis accounts remove <email>")} Remove an authenticated account`),console.log(`
Run ${E.cyan('"savethis accounts --help"')} for more information.`),process.exit(0);});t.command("add").description("Add a new Gmail account (always prompts for a new account)").action(async()=>{try{console.log(E.cyan("Starting authentication for a new account...")),await tt(),console.log(E.green("\u2713 New account added successfully!")),console.log(E.gray('You can now start downloading attachments with the "download" command.')),process.exit(0);}catch(o){console.error(E.red("\u2717 Adding account failed:"),o),process.exit(1);}}),t.command("remove").description("Remove an authenticated account").argument("<email>","Email address of the account to remove").action(async o=>{let{confirm:n}=await He.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to remove the account ${o}?`,default:false}]);n&&(et(o)||(console.error(E.red(`\u2717 Account not found: ${o}`)),console.log(`Run ${E.cyan('"savethis accounts"')} to see all authenticated accounts.`),process.exit(1)),console.log(E.green(`\u2713 Successfully removed account: ${o}`))),process.exit(0);});}l();function nt(e){let t=e.command("config").description("Manage configuration settings").action(()=>{let o=se();console.log("Current configuration:"),console.log(JSON.stringify(o,null,2)),console.log(`
Configuration file: ${G}`),console.log(`
Use "savethis config set <key> <value>" to update settings.`),console.log("Example: savethis config set googleApiKey your-api-key-here");});t.command("set").description("Set a configuration value").argument("<key>","Configuration key (e.g., googleApiKey, openaiApiKey, defaultOutputDir)").argument("<value>","Configuration value").action((o,n)=>{try{Ve(o,n),console.log(`Configuration updated: ${o} = ${n}`);}catch(r){r instanceof Error?console.error(`Failed to update configuration: ${r.message}`):console.error(`Failed to update configuration: ${String(r)}`),process.exit(1);}}),t.command("get").description("Get a configuration value").argument("<key>","Configuration key (e.g., googleApiKey, defaultOutputDir)").action(o=>{let n=T(o);console.log(n===void 0?`No value set for ${o}`:`${o} = ${n}`);});}l();l();l();l();function O(e,t){return createGoogleGenerativeAI({apiKey:T("googleApiKey")})(e||T("model"))}function de(e,t){let o=O("gemini-2.0-flash-lite");return generateObject({model:o,temperature:.2,maxTokens:3072,schema:$.object({title:$.string().describe("A keyword-rich, benefit-focused title that includes the most valuable insight"),summary:$.string().describe("A concise summary emphasizing key metrics, findings, and searchable terms"),keywords:$.array($.string()).min(5).max(30).describe("Specific search keywords that someone might use to find this document"),categories:$.array($.string()).min(3).max(5).describe("Broader topic categories for organizing this document in a collection")}),prompt:`
Analyze this document specifically for search and retrieval:
DOCUMENT DETAILS:
Filename: ${e.filename}
${e.mimeType?`Type: ${e.mimeType}`:""}
${e.subject?`Context: ${e.subject}`:""}
CONTENT:
${e.text}
Create:
1. TITLE: Write a keyword-rich, benefit-focused title that includes terms people would search for. Include specific metrics or locations when relevant. (50-70 characters)
2. SUMMARY: Create a concise summary that:
- Includes high-value search terms naturally
- Highlights specific metrics, findings, or actionable insights
- Uses terms likely to match user search queries
(120-160 characters)
3. KEYWORDS: List 5-10 specific search terms someone might use to find this exact document. Include:
- Specific entities (names, places, products)
- Metrics with numbers when relevant
- Action-oriented phrases
- Industry-specific terminology
4. CATEGORIES: Provide 3-5 broader topic categories for organizing this document in a collection. These should be more general than keywords but more specific than generic terms like "data" or "image".
Focus on making this document highly discoverable through search.
`})}l();l();var Ko={".txt":"text/plain",".csv":"text/csv",".md":"text/markdown",".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".ts":"text/typescript",".jsx":"text/jsx",".tsx":"text/tsx",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".rtf":"application/rtf",".odt":"application/vnd.oasis.opendocument.text",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ods":"application/vnd.oasis.opendocument.spreadsheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".odp":"application/vnd.oasis.opendocument.presentation",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".json":"application/json",".xml":"application/xml",".yaml":"application/yaml",".yml":"application/yaml",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed",".tar":"application/x-tar",".gz":"application/gzip",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".flac":"audio/flac",".mp4":"video/mp4",".webm":"video/webm",".avi":"video/x-msvideo",".mov":"video/quicktime",".mkv":"video/x-matroska"};function B(e){if(!e)return "application/octet-stream";let t=extname(e).toLowerCase();return Ko[t]||"application/octet-stream"}l();var rt=async({fullPath:e})=>{let t=ht.readFileSync(e);return {text:Jo.decode(t,"utf16le"),metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0}}};l();l();var te=null;function fe(){return te||(te=new Qo({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-",emDelimiter:"_",strongDelimiter:"**"}),te.use(gfm),te.addRule("preserveLineBreaks",{filter:"br",replacement:()=>`
`})),te}var at=async({fullPath:e})=>{let t=ht.readFileSync(e),{value:o}=await tn.convertToHtml({buffer:t},{styleMap:["p[style-name='Heading 1'] => h1:fresh","p[style-name='Heading 2'] => h2:fresh","p[style-name='Heading 3'] => h3:fresh","p[style-name='Code'] => pre:fresh"],includeDefaultStyleMap:true,ignoreEmptyParagraphs:true});return {text:fe().turndown(o),metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0}}};l();l();async function st(e){try{let t=ht.readFileSync(e),o=await on.load(t,{expanded:!0}),n=[];if(o.gps&&o.gps.Latitude&&o.gps.Longitude&&n.push(`- **Location**: ${o.gps.Latitude}, ${o.gps.Longitude}`),o.exif&&o.exif.DateTimeOriginal&&n.push(`- **Date Taken**: ${o.exif.DateTimeOriginal.description||o.exif.DateTimeOriginal.value}`),o.exif&&o.exif.Make&&o.exif.Model){let r=o.exif.Make.description||o.exif.Make.value,a=o.exif.Model.description||o.exif.Model.value;n.push(`- **Camera**: ${r} ${a}`);}return o.exif&&o.exif.Software&&n.push(`- **Software**: ${o.exif.Software.description||o.exif.Software.value}`),n.length>0?`## Image Metadata
${n.join(`
`)}
`:""}catch{return ""}}l();async function it(e){try{let t=await rn.extractText([e],["eng"],"txt",{mode:"quality"});return typeof t=="string"?t.trim():""}catch(t){return console.error("OCR Error:",t),""}}var ct=async({fullPath:e,mimeType:t})=>{let o=ht.readFileSync(e),n=await st(e),r=await it(e),s=await generateText({model:O("gemini-2.0-flash-lite"),messages:[{role:"user",content:[{type:"text",text:`Image analysis:
1. What is this? Identify content, text, subject, and specific location/entities if recognizable.
2. Why it matters: Explain significance and relevant context.
Be concise, accurate, and insightful. Adapt detail to complexity.
If there is text, extract it in a structured format.
If there is no text, describe the image in detail.
`},{type:"file",data:o,mimeType:t}]}],temperature:1,maxTokens:4096}),i=n;return r&&(i+=`## OCR Text
${r}
`),i+=s.text,{text:i,metrics:{...s.usage,imageCount:1}}};l();var lt=async({fullPath:e})=>{let t;try{t=await promises.readFile(e);}catch(g){throw console.error("Failed to read PDF file:",g),g}let o="";try{o=await cn(t);}catch(g){console.error("PDF text extraction with pdf2md failed:",g);}let n=o.trim().length,r=t.length/1024,a=n/r,s=n>100&&a>5,c=`Analyze this PDF document and provide the following:
1. **DOCUMENT TYPE:** Identify what kind of document this is.
2. **KEY INFORMATION:** Extract all important information (such as dates, names, identifiers, key facts and more).
3. **SUMMARY:** Summarize the key information in a concise manner.
${s?`The text has already been extracted (${o.trim().length} characters).`:"4. **EXTRACTED TEXT:** Extract the text content from the document, preserving formatting where possible."}
Format your response in Markdown with clear headings for each section.`,m;try{m=await generateText({model:O("gemini-2.0-flash-lite"),messages:[{role:"user",content:[{type:"text",text:c},{type:"file",data:t,mimeType:"application/pdf"}]}],temperature:.2,maxTokens:8192});}catch(g){throw console.error("AI processing failed:",g),g}let p=m.text;return s&&!m.text.includes("## EXTRACTED TEXT")&&(p=`${m.text}
## EXTRACTED TEXT
${o}`),{text:p,metrics:{...m.usage,imageCount:0}}};l();var mt=async({fullPath:e})=>{let t=ht.readFileSync(e),n=await new PPTXInHTMLOut(t).toHTML({includeStyles:false});return {text:fe().turndown(n),metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0}}};l();var ut=async({fullPath:e})=>{try{let t=ht.readFileSync(e),o=pe.read(t,{type:"buffer"}),n="",r=o.SheetNames.length;o.SheetNames.forEach((s,i)=>{let c=o.Sheets[s];n+=`# ${s}
`;let m=pe.utils.sheet_to_json(c,{header:1});if(!m.length){n+=`Empty sheet
`;return}let p=1e4,g=m.length>p?[...m.slice(0,p/2),...m.slice(m.length-p/2)]:m;m.length>p&&(n+=`Note: Large sheet with ${m.length} rows. Showing sample of ${p} rows.
`),g.forEach(C=>{if(!C)return;let Ce=C.map(V=>{if(V==null)return "";let M=String(V);return M.includes(",")||M.includes('"')?`"${M.replace(/"/g,'""')}"`:M}).join(",");n+=Ce+`
`;}),n+=`
${m.length} rows \xD7 ${m[0]?.length||0} columns
`,i<r-1&&(n+=`---
`);});let a=t.length;return {text:n,metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0,fileSize:a,sheetCount:r}}}catch(t){return {text:`Error extracting XLSX content: ${t instanceof Error?t.message:String(t)}`,metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0,error:true}}}};async function ge({filename:e,fullPath:t,mimeType:o}){o=o||B(e);let n={fullPath:t,mimeType:o};return o==="text/csv"?rt(n):o.startsWith("image/")?await ct(n):o==="application/pdf"?lt(n):o==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?at(n):o==="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"?ut(n):o==="application/vnd.openxmlformats-officedocument.presentationml.presentation"?mt(n):o.startsWith("text/")?{text:ht.readFileSync(t,"utf8"),metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0}}:{text:`Unknown type: ${o} for file: ${e}`,metrics:{promptTokens:0,completionTokens:0,totalTokens:0,imageCount:0}}}function ft(e){let t=e.command("document").description("Document operations: summarize, analyze, and process files").action(()=>{console.log("Available document commands:"),console.log(" savethis document summarize - Generate AI summary for a document"),console.log(`
Run "savethis document <command> --help" for more information.`);});return t.command("summarize").description("Generate an AI summary for a document").argument("<filepath>","Path to the document file").option("-e, --show-extraction","Show the extracted text/OCR results",true).option("--max-extraction <lines>","Maximum lines of extraction to show","200").action(async(o,n)=>{try{let r=he.resolve(o);try{await dt.access(r);}catch{console.error(E.red(`Error: File not found: ${r}`)),process.exit(1);}console.log(E.cyan(`Summarizing document: ${he.basename(r)}`));let a=await dt.stat(r),s=B(r)||"application/octet-stream",i=await ge({filename:he.basename(r),fullPath:r,mimeType:s});if(n.showExtraction){console.log(`
`+E.yellow("Extracted Content:"));let m=parseInt(n.maxExtraction)||20,p=i.text.split(`
`);p.slice(0,m).forEach(C=>{console.log(E.gray(C));}),p.length>m&&console.log(E.gray(`... and ${p.length-m} more lines (use --max-extraction to show more)`)),i.metrics&&console.log(E.gray(`
Extraction metrics: ${JSON.stringify(i.metrics)}`)),console.log(`
`+E.cyan("Generating summary..."));}let c=await de({filename:he.basename(r),mimeType:s,text:i.text,subject:`File size: ${(a.size/1024).toFixed(2)} KB, Last modified: ${a.mtime.toISOString()}`});console.log(`
`+E.green("Summary:")),console.log(E.white(c.object.title)),console.log(`
`+E.cyan("Description:")),console.log(E.white(c.object.summary)),c.object.keywords&&c.object.keywords.length>0&&(console.log(`
`+E.cyan("Keywords:")),console.log(E.white(c.object.keywords.join(", ")))),console.log(`
`+E.cyan("Categories:")),c.object.categories.forEach(m=>{console.log(E.white(`- ${m}`));}),console.log(`
Summary generated successfully!`),process.exit(0);}catch(r){console.error(E.red("Error generating summary:"),r),process.exit(1);}}),t}l();l();l();function pt(e,t){e.prepare(`
INSERT INTO db_version (id, version)
VALUES (1, ?)
ON CONFLICT(id) DO UPDATE SET version = excluded.version
`).run(t);}function gn(e){return e.prepare("SELECT version FROM db_version").get()?.version||0}function gt(e){let t=gn(e);e.pragma("page_size = 8192"),e.pragma("mmap_size = 268435456"),e.pragma("cache_size = 5000"),e.pragma("synchronous = NORMAL"),e.pragma("temp_store = MEMORY"),e.exec("BEGIN TRANSACTION");try{t<1&&(hn(e),pt(e,1)),t<2&&(yn(e),pt(e,2)),e.exec("COMMIT");}catch(o){throw e.exec("ROLLBACK"),o}}function hn(e){e.exec(`
CREATE TABLE IF NOT EXISTS emails (
id INTEGER PRIMARY KEY AUTOINCREMENT,
account TEXT,
threadId TEXT,
messageId TEXT UNIQUE,
subject TEXT,
date TEXT,
sender TEXT,
recipient TEXT,
body TEXT
)
`),e.exec(`
CREATE TABLE IF NOT EXISTS attachments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email_id INTEGER,
filename TEXT UNIQUE,
size INTEGER,
mimeType TEXT,
title TEXT,
categories TEXT,
summary TEXT,
suggestedFilename TEXT,
contents TEXT,
analyzed BOOLEAN DEFAULT 0,
FOREIGN KEY (email_id) REFERENCES emails(id)
)
`),e.exec(`
CREATE VIRTUAL TABLE IF NOT EXISTS email_fts USING fts5(
account, subject, sender, recipient, body,
content='emails',
content_rowid='id'
)
`),e.exec(`
CREATE VIRTUAL TABLE IF NOT EXISTS attachment_fts USING fts5(
title, summary, categories, contents,
content='attachments',
content_rowid='id'
)
`),e.exec("CREATE INDEX IF NOT EXISTS idx_emails_threadId ON emails(threadId)"),e.exec("CREATE INDEX IF NOT EXISTS idx_emails_date ON emails(date)"),e.exec("CREATE INDEX IF NOT EXISTS idx_attachments_filename ON attachments(filename)");}function yn(e){e.exec("ALTER TABLE attachments ADD COLUMN keywords TEXT"),e.exec("DROP TABLE IF EXISTS attachment_fts"),e.exec(`
CREATE VIRTUAL TABLE IF NOT EXISTS attachment_fts USING fts5(
title, summary, categories, keywords, contents,
content='attachments',
content_rowid='id'
)
`),e.exec(`
INSERT INTO attachment_fts(rowid, title, summary, categories, keywords, contents)
SELECT id, title, summary, categories, keywords, contents FROM attachments
WHERE analyzed = 1
`);}function q(e){console.log("Opening database",e);try{let t=he.dirname(e);ht.existsSync(t)||ht.mkdirSync(t,{recursive:!0});let o=new bn(e,{verbose:process.env.NODE_ENV==="development"?console.log:void 0,fileMustExist:!1});return console.log("Database opened"),gt(o),o}catch(t){throw console.error(`Failed to open database at ${e}:`,t),new Error(`Database connection error: ${t.message}`)}}function yt(e){e.command("export").description("Export database contents to various formats").command("markdown").description("Export all emails and attachments to a markdown file").option("-o, --output <path>","Output file path (default: db-export.md)").action(async o=>{let n=T("outputDir"),r=q(he.resolve(n,"savethis.db"));try{let a=r.prepare(`
SELECT * FROM emails
ORDER BY date DESC
`).all(),s=r.prepare(`
SELECT
a.id,
a.email_id,
a.filename,
a.size,
a.mimeType,
a.title,
a.summary,
a.categories,
a.keywords,
a.suggestedFilename,
a.contents,
a.analyzed,
e.subject as email_subject,
e.date as email_date,
e.sender as email_sender
FROM attachments a
JOIN emails e ON a.email_id = e.id
ORDER BY e.date DESC
`).all(),i=`# Database Export
`;i+=`## Emails (${a.length})
`;for(let m of a)i+=`### Email: ${m.subject}
`,i+=`- **From:** ${m.sender}
`,i+=`- **To:** ${m.recipient}
`,i+=`- **Date:** ${m.date}
`,i+=`- **Account:** ${m.account}
`,i+=`- **Message ID:** ${m.messageId}
`,i+=`- **Thread ID:** ${m.threadId}
`,i+=`<email>
${m.body}
</email>
`;i+=`## Attachments (${s.length})
`;for(let m of s)i+=`### Attachment: ${m.filename}
`,i+=`- **Email:** ${m.email_subject}
`,i+=`- **From:** ${m.email_sender}
`,i+=`- **Date:** ${m.email_date}
`,i+=`- **Size:** ${Qe(m.size)}
`,i+=`- **MIME Type:** ${m.mimeType}
`,m.analyzed?(i+=`- **Title:** ${m.title||"N/A"}
`,i+=`- **Summary:** ${m.summary||"N/A"}
`,i+=`- **Categories:** ${m.categories||"N/A"}
`,i+=`- **Keywords:** ${m.keywords||"N/A"}
`,m.contents&&(i+=`
<attachment>
${m.contents}
</attachment>
`)):i+=`- **Status:** Not analyzed
`;let c=o.output||"db-export.md";ht.writeFileSync(c,i),console.log(`\u2705 Database exported to ${c} (${a.length} emails, ${s.length} attachments)`);}finally{r.close();}});}l();l();var oe=new Date().getFullYear(),vn=`
OPERATORS:
from:sender | to:recipient | subject:topic | has:attachment | filename:type | label:name
is:important/unread/starred/read/muted | in:anywhere/snoozed/trash | -in:spam (exclude)
category:primary/social/promotions/updates/forums | list:mailinglist | deliveredto:email
size:bytes | larger:5M | smaller:1M | after:YYYY/MM/DD | before:YYYY/MM/DD
has:youtube/drive/document/spreadsheet/presentation/userlabels/nouserlabels
+exactword | "exact phrase" | AROUND 5 | {OR condition} | -exclude
CRITICAL RULES:
- OR syntax: Use {term1 term2} not (term1 OR term2)
- With subject: {subject:project subject:meeting} NOT subject:{project meeting}
- Domains: Use @ symbol
- from:@google.com NOT from:google.com
- to:@yahoo.com NOT deliveredto:yahoo.com
- Subject terms:
- Together: subject:"project meeting"
- Alternatives: {subject:project subject:meeting}
- Time references:
- newer_than:Nd/w/m/y, older_than:Nd/w/m/y
- "last month" \u2192 newer_than:2m older_than:1m
- "last week" \u2192 newer_than:2w older_than:1w
- "yesterday" \u2192 newer_than:2d older_than:1d
- "this month" \u2192 newer_than:1m
- "last year" \u2192 newer_than:1y older_than:0y OR after:${oe-1}/01/01 before:${oe}/01/01
- "3 months" \u2192 newer_than:3m
- "${oe}" \u2192 after:${oe}/01/01 before:${oe+1}/01/01
- Star colors: has:yellow-star/red-star/blue-star/... and other color options
- Exact matching:
- Single word: +report (no quotes)
- Multiple words: "exact phrase"
- Word handling:
- Interpret contextual phrases based on likely intent
- Focus on key search terms rather than every word
`;function Et(e,t){let o=O("gemini-2.0-flash"),n=new Date().toISOString();return generateObject({model:o,temperature:.5,maxTokens:1024,schema:z$1.object({query:z$1.string()}),prompt:`
You are a Gmail search query generator. Current time: ${n}
${vn}
Convert the following user query to a Gmail search query: "${e}"
`})}l();var b=Q(W());l();l();var F=Q(W());var Vn=e=>e.prepare(`
SELECT
(SELECT COUNT(*) FROM emails) as email_count,
(SELECT COUNT(*) FROM attachments) as attachment_count,
(SELECT COUNT(*) FROM attachments WHERE analyzed = 1) as analyzed_count,
(SELECT MIN(date) FROM emails) as oldest_date,
(SELECT MAX(date) FROM emails) as newest_date
`).get(),Qt=e=>tool({description:"Get overview statistics and date ranges of the email database",parameters:z$1.object({}),execute:async()=>{console.log(F.default.green(`
\u{1F4CA} Getting