slack-term 1.30.0 → 1.30.2

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/cli.js CHANGED
@@ -149,7 +149,7 @@ Tailing/DMing people and listing users need a user session, not a bot token.
149
149
  Or import your Slack desktop session: slack auth login`);throw Error(`Slack error on ${t}: ${a}`)}return o}async function zl(e,t,n,i){let s={};if(i)s.Cookie=`d=${i}`;let r=await fetch(`${Oi()}/${t}`,{...n,headers:{...n.headers??{},Authorization:`Bearer ${e}`,...s}});if(r.status===429){let a=parseInt(r.headers.get("retry-after")??"60",10);throw new qt(isNaN(a)?60:a)}let o=await r.json();if(o.ok!==!0){let a=o.error??"unknown";if(a==="ratelimited")throw new qt(60);if((a==="invalid_auth"||a==="not_authed")&&!e.startsWith("xoxc-"))throw Error(`The draft API requires a desktop app session token (xoxc-).
150
150
  Import from Slack desktop: slack auth login`);if((a==="invalid_auth"||a==="not_authed")&&!i)throw Error(`drafts.list also requires the xoxd session cookie.
151
151
  Attach it with: slack auth chrome (macOS) or slack auth firefox`);throw Error(`Slack error on ${t}: ${a}`)}return o}function Pt(e,t,n={},i){let s=new URLSearchParams({token:e,...n});return zl(e,t,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},i)}function oe(e,t,n,i){let s=new URLSearchParams(n).toString();return ja(e,`${t}?${s}`,{method:"GET"},i)}function Je(e,t,n,i){return ja(e,t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},i)}async function La(e,t){let n=await oe(e,"auth.test",{},t);return{team:n.team??"",teamId:n.team_id??"",url:n.url??"",user:n.user??"",userId:n.user_id??""}}async function Wa(e,t){let n={Authorization:`Bearer ${e}`};if(t)n.Cookie=`d=${t}`;let i=await fetch(`${Oi()}/auth.test`,{method:"GET",headers:n});if(i.status===429){let o=parseInt(i.headers.get("retry-after")??"60",10);throw new qt(isNaN(o)?60:o)}let s=i.headers.get("x-oauth-scopes")??"",r=await i.json();if(r.ok!==!0)throw Error(`Slack error on auth.test: ${r.error??"unknown"}`);return{userId:r.user_id??"",user:r.user??"",botId:r.bot_id??"",team:r.team??"",url:r.url??"",scopes:s.split(",").map((o)=>o.trim()).filter(Boolean)}}async function Qe(e,t,n=20,i,s,r,o){let a={channel:t,limit:String(n)};if(i!==void 0)a.oldest=i;if(s!==void 0)a.cursor=s;if(o)a.inclusive="true";return oe(e,"conversations.history",a,r)}async function Ke(e,t,n,i=50,s){return oe(e,"conversations.replies",{channel:t,ts:n,limit:String(i)},s)}async function Ua(e,t,n){return oe(e,"files.info",{file:t},n)}async function Ja(e,t={},n){let i={count:String(Math.min(Math.max(t.count??100,1),200)),page:String(Math.max(t.page??1,1))};if(t.types)i.types=t.types;if(t.channel)i.channel=t.channel;if(t.user)i.user=t.user;return oe(e,"files.list",i,n)}async function Ka(e,t,n={},i){let s={list_id:t};if(n.limit)s.limit=String(n.limit);if(n.cursor)s.cursor=n.cursor;return Pt(e,"lists.records.list",s,i)}async function za(e,t,n,i,s){return oe(e,"search.messages",{query:t,sort:"timestamp",sort_dir:"desc",count:String(Math.min(Math.max(n,1),100)),page:String(Math.max(i,1))},s)}async function Ha(e,t,n){return za(e,t,100,1,n)}async function Ii(e,t,n,i){let r=1,o=[],a={ok:!0,messages:{}};while(!0){let u=await za(e,t,100,r,i),f=un(u,["messages","matches"]),l=Array.isArray(f)?f:[];o.push(...l);let d=Number(un(u,["messages","paging","pages"])??1);if(a=u,l.length===0||r>=d||o.length>=n)break;r+=1}let c=a;if(!c.messages)c.messages={};return c.messages.matches=o.slice(0,n),c}async function os(e,t,n,i,s,r,o){let a=o?{channel:t,text:n}:{channel:t,text:n,blocks:[{type:"markdown",text:n}]};if(i!==void 0)a.thread_ts=i;if(s&&i!==void 0)a.reply_broadcast=!0;return(await Je(e,"chat.postMessage",a,r)).ts??""}async function qa(e,t,n,i,s,r){let o={channel:t,text:n,post_at:i,blocks:[{type:"markdown",text:n}]};if(s!==void 0)o.thread_ts=s;return(await Je(e,"chat.scheduleMessage",o,r)).scheduled_message_id??""}async function Ya(e,t,n){let i={};if(t)i.channel=t;return oe(e,"chat.scheduledMessages.list",i,n)}async function Xa(e,t,n,i){await Je(e,"chat.deleteScheduledMessage",{channel:t,scheduled_message_id:n},i)}async function ln(e,t,n,i){return(await oe(e,"chat.getPermalink",{channel:t,message_ts:n},i)).permalink??""}async function Yt(e,t,n,i,s,r){return(await Je(e,"chat.update",r?{channel:t,ts:n,text:i}:{channel:t,ts:n,text:i,blocks:[{type:"markdown",text:i}]},s)).ts??n}async function Ga(e,t,n,i){await Je(e,"chat.delete",{channel:t,ts:n},i)}async function ut(e,t,n,i,s){await Je(e,"reactions.add",{channel:t,timestamp:n,name:i},s)}async function Va(e,t,n,i){return((await oe(e,"reactions.get",{channel:t,timestamp:n,full:"true"},i)).message?.reactions??[]).map((r)=>({name:String(r.name??""),users:Array.isArray(r.users)?r.users.map(String):[]}))}async function fn(e,t,n,i,s){await Je(e,"reactions.remove",{channel:t,timestamp:n,name:i},s)}async function Za(e,t,n=!1,i){let s=await Je(e,"conversations.create",{name:t,is_private:n},i);return{id:s.channel?.id??"",name:s.channel?.name??t}}async function Qa(e,t,n,i){await Je(e,"conversations.invite",{channel:t,users:n.join(",")},i)}async function dn(e,t){let n=[],i="";while(!0){let s={limit:"200",types:"public_channel,private_channel,im,mpim"};if(i)s.cursor=i;let r=await oe(e,"conversations.list",s,t);if(n.push(...r.channels??[]),i=r.response_metadata?.next_cursor??"",!i)break}return{channels:n}}async function Rt(e,t,n){let s=(await Je(e,"conversations.open",{users:t},n)).channel?.id;if(!s)throw Error(`Failed to open DM with user ${t}`);return s}function Ze(e){return e.toLowerCase().replace(/[-_\s]/g,"")}async function pn(e,t,n){if(!t.startsWith("@")){if(/^[UW][A-Za-z0-9]{6,}$/.test(t))return t;throw Error(`Expected @user or a user ID, got: ${t}`)}let i=Ze(t.slice(1)),s=await oe(e,"auth.test",{},n);if(i==="you"||i==="me"||Ze(s.user??"")===i){if(!s.user_id)throw Error("auth.test did not return user_id");return s.user_id}let r="";while(!0){let o={limit:"200"};if(r)o.cursor=r;let a=await oe(e,"users.list",o,n);for(let c of a.members??[]){let u=Ze(c.name??""),f=Ze(c.real_name??""),l=Ze(c.profile?.display_name??"");if(u===i||f===i||l&&l===i)return c.id??""}if(r=a.response_metadata?.next_cursor??"",!r)break}throw Error(`User not found: ${t}`)}function Mt(e){let t=e.match(/(?:app\.slack\.com\/client\/T[A-Za-z0-9]+|[A-Za-z0-9-]+\.slack\.com\/archives)\/([A-Za-z0-9]+)(?:\/p(\d{10})(\d{6}))?/);if(!t)return;let n=t[1],i=t[2]&&t[3]?`${t[2]}.${t[3]}`:void 0,s=e.indexOf("?"),r=s>=0?new URLSearchParams(e.slice(s)):void 0,o=r?.get("thread_ts")??void 0,u={channel:r?.get("cid")??void 0??n};if(i)u.ts=i;if(o)u.threadTs=o;return u}function Hl(e){return Mt(e)?.channel}function va(e){return/^[CDG][A-Z0-9]{8,}$/.test(e)}async function ye(e,t,n){let i=Hl(t);if(i)return i;if(!t.startsWith("@")&&!t.startsWith("#")){if(va(t))return t;throw Error(`Target must start with # or @ (or be a Slack URL/ID), got: ${t}`)}if(t.startsWith("#")&&va(t.slice(1)))return t.slice(1);let s=t.startsWith("@"),r=t.slice(1),o=Ze(r);if(s){let u=await oe(e,"auth.test",{},n);if(o==="you"||o==="me"||Ze(u.user??"")===o){let m=u.user_id;if(!m)throw Error("auth.test did not return user_id");let y=((await oe(e,"conversations.list",{types:"im",limit:"200"},n)).channels??[]).find((C)=>C.user===m);if(y?.id)return String(y.id);return Rt(e,m,n)}let l="",d="";while(!0){let m={limit:"200"};if(d)m.cursor=d;let p=await oe(e,"users.list",m,n);for(let y of p.members??[]){let C=Ze(y.name??""),F=Ze(y.real_name??""),k=Ze(y.profile?.display_name??"");if(C===o||F===o||k&&k===o){l=y.id??"";break}}if(l)break;if(d=p.response_metadata?.next_cursor??"",!d)break}if(!l)throw Error(`User not found: ${t}`);let h="";while(!0){let m={types:"im",limit:"200"};if(h)m.cursor=h;let p=await oe(e,"conversations.list",m,n);for(let y of p.channels??[])if(y.user===l)return String(y.id??"");if(h=p.response_metadata?.next_cursor??"",!h)break}throw Error(`No existing DM with ${t} (${l}). Open it once in Slack first.`)}let a=r.toLowerCase(),c="";while(!0){let u={limit:"200",types:"public_channel,private_channel",exclude_archived:"true"};if(c)u.cursor=c;let f=await oe(e,"conversations.list",u,n);for(let l of f.channels??[])if(String(l.name??"").toLowerCase()===a)return String(l.id??"");if(c=f.response_metadata?.next_cursor??"",!c)break}throw Error(`channel not found: ${t}`)}async function hn(e,t,n){try{let i=await oe(e,"users.info",{user:t},n),s=i.user?.profile?.display_name,r=s&&s.length>0?s:i.user?.real_name??i.user?.name??t,o=i.user?.name??t;return[r,o]}catch{return[t,t]}}async function ze(e,t,n){try{let i=await oe(e,"users.info",{user:t},n),s=i.user?.profile?.display_name;if(s&&s.length>0)return s;return i.user?.real_name??i.user?.name??t}catch{return t}}async function Ti(e,t){let n=[],i="";while(!0){let s={limit:"200"};if(i)s.cursor=i;let r=await oe(e,"users.list",s,t);if(n.push(...r.members??[]),i=r.response_metadata?.next_cursor??"",!i)break}return{members:n}}async function ec(e,t,n){let i=[],s="";while(!0){let r={channel:t,limit:"200"};if(s)r.cursor=s;let o=await oe(e,"conversations.members",r,n);if(i.push(...o.members??[]),s=o.response_metadata?.next_cursor??"",!s)break}return i}async function gn(e,t){return Pt(e,"drafts.list",{},t)}async function tc(e,t,n,i){let{randomUUID:s}=await import("node:crypto"),r=JSON.stringify([{type:"rich_text",elements:[{type:"rich_text_section",elements:[{type:"text",text:n}]}]}]);return Pt(e,"drafts.create",{client_msg_id:s(),destinations:JSON.stringify([{channel_id:t}]),blocks:r,file_ids:JSON.stringify([]),is_from_composer:"true"},i)}async function nc(e,t,n,i,s){let r=JSON.stringify([{type:"rich_text",elements:[{type:"rich_text_section",elements:[{type:"text",text:i}]}]}]),o=(Date.now()/1000).toFixed(6);return Pt(e,"drafts.update",{draft_id:t,client_last_updated_ts:o,destinations:JSON.stringify([{channel_id:n}]),blocks:r,file_ids:JSON.stringify([])},s)}async function sc(e,t,n){return Pt(e,"conversations.info",{channel:t},n)}async function mn(e,t,n){return oe(e,"users.info",{user:t},n)}async function Dn(e,t,n){return oe(e,"conversations.info",{channel:t},n)}async function ic(e,t,n){let i=(Date.now()/1000).toFixed(6);return Pt(e,"drafts.delete",{draft_id:t,client_last_updated_ts:i},n)}async function Pi(e,t){let n=await Pt(e,"auth.test",{},t);return{userId:String(n.user_id??""),teamId:String(n.team_id??"")}}async function rc(e,t,n,i={},s){let{statSync:r,readFileSync:o}=await import("node:fs"),{basename:a}=await import("node:path"),c=r(n),u=a(n),f=await oe(e,"files.getUploadURLExternal",{filename:u,length:String(c.size)},s),l=f.upload_url,d=f.file_id;if(!l||!d)throw Error("files.getUploadURLExternal returned no upload_url/file_id");let h=o(n),m=await fetch(l,{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:h});if(!m.ok)throw Error(`Upload PUT failed: ${m.status} ${m.statusText}`);let p={files:[{id:d,title:i.title??u}],channel_id:t};if(i.threadTs)p.thread_ts=i.threadTs;if(i.initialComment)p.initial_comment=i.initialComment;let y=await Je(e,"files.completeUploadExternal",p,s),C={fileId:d},F=y.files?.[0]?.permalink;if(F)C.permalink=F;return C}function un(e,t){let n=e;for(let i of t){if(n===void 0||n===null)return;if(typeof i==="number"){if(!Array.isArray(n))return;n=n[i]??void 0}else{if(typeof n!=="object"||Array.isArray(n))return;n=n[i]}}return n}import{existsSync as nf,readFileSync as sf}from"node:fs";import{homedir as rf}from"node:os";import{join as of}from"node:path";import{existsSync as ql,mkdirSync as Yl,readFileSync as Xl,writeFileSync as Gl}from"node:fs";import{homedir as Vl}from"node:os";import{dirname as Zl,join as Ql}from"node:path";var ef=3600000,as={now:()=>Date.now(),path:()=>Ql(process.env.HOME||Vl(),".config","slack-cli","cache.json")},cs=!0,lt;function oc(){return{channels:{},users:{}}}function Ri(){if(lt)return lt;if(lt=oc(),!cs)return lt;try{let e=as.path();if(!ql(e))return lt;let t=JSON.parse(Xl(e,"utf8"));for(let n of["channels","users"]){let i=t?.[n];if(!i||typeof i!=="object"||Array.isArray(i))continue;for(let[s,r]of Object.entries(i))if(r&&typeof r==="object"&&typeof r.value==="string"&&typeof r.expires==="number")lt[n][s]={value:r.value,expires:r.expires}}}catch{lt=oc()}return lt}function tf(e){if(!cs)return;try{let t=as.path();Yl(Zl(t),{recursive:!0}),Gl(t,JSON.stringify(e,null,2)+`
152
- `)}catch{}}function ac(e,t){return e?`${e} ${t}`:void 0}function us(e,t,n){if(!cs)return;let i=ac(t,n);if(!i)return;let s=Ri()[e][i];if(!s)return;if(s.expires<=as.now()){delete Ri()[e][i];return}return s.value}function ls(e,t,n,i,s=ef){if(!cs)return;let r=ac(t,n);if(!r)return;let o=Ri();o[e][r]={value:i,expires:as.now()+s},tf(o)}var Mi={marker:"pushpin",progress:{done:"white_check_mark",dropped:"no_entry_sign",doing:"eyes",pending:"hourglass_flowing_sand"},flags:{alert:"exclamation","needs-discussion":"thinking_face",waiting:"speech_balloon",blocked:"lock"}},Xt=["done","dropped","doing","pending"],fc=["alert","needs-discussion","waiting","blocked"];function af(){return of(process.env.HOME||rf(),".config","slack-cli","todo.json")}function fs(e){return e.replace(/^:+|:+$/g,"")}function yn(e=af()){let t={marker:Mi.marker,progress:{...Mi.progress},flags:{...Mi.flags}};try{if(!nf(e))return t;let n=JSON.parse(sf(e,"utf8"));if(typeof n.marker==="string"&&n.marker.trim())t.marker=fs(n.marker.trim());for(let i of Xt){let s=n.progress?.[i];if(typeof s==="string"&&s.trim())t.progress[i]=fs(s.trim())}for(let i of fc){let s=n.flags?.[i];if(typeof s==="string"&&s.trim())t.flags[i]=fs(s.trim())}}catch{}return t}function cc(e,t,n=!1){return`${n?"-":""}${t?"has":"hasmy"}::${fs(e)}:`}function dc(e,t,n={}){let i=n.shared===!0,s=(a)=>cc(a,i),r=(a)=>cc(a,i,!0),o=[];if(e==="untriaged")o.push(s(t.marker),...Xt.map((a)=>r(t.progress[a])));else if(e==="stuck")o.push(s(t.marker),r(t.progress.done),r(t.progress.dropped),`(${fc.map((a)=>s(t.flags[a])).join(" OR ")})`);else if(e==="open")o.push(s(t.marker),r(t.progress.done),r(t.progress.dropped));else{let a=Xt.indexOf(e);o.push(s(t.progress[e]));for(let c of Xt.slice(0,a))o.push(r(t.progress[c]))}if(n.in){let a=n.in.startsWith("#")||n.in.startsWith("@")?n.in:`#${n.in}`;o.push(`in:${a}`)}if(n.from){let a=n.from==="me"||n.from.startsWith("@")?n.from:`@${n.from}`;o.push(`from:${a}`)}return o.join(" ")}var cf=3,uf={sleep:(e)=>new Promise((t)=>setTimeout(t,e))};async function _e(e,t,n=cf){for(let i=0;;i++)try{return await t()}catch(s){if(!(s instanceof Ve))throw s;if(i>=n)throw Error(`Slack rate limit hit on ${e} — gave up after ${n} retries. Try again in a minute.`);console.error(`Warning: Slack rate limit hit on ${e} — backing off for ${s.retryAfter}s`),await uf.sleep(s.retryAfter*1000)}}var uc=new Map;async function pc(e,t){let n=uc.get(e);if(n)return n;let i=await _e("auth.test",()=>zt(e,t)),s={userId:i.userId,teamId:i.teamId};return uc.set(e,s),s}async function hc(e,t){return(await pc(e,t)).userId}async function Bi(e,t){try{return(await pc(e,t)).teamId}catch{return""}}async function Ni(e,t,n,i){if(!t.startsWith("#"))return n(e,t,i);let s=await Bi(e,i),r=us("channels",s,t);if(r)return r;let o=await _e("resolveChannel",()=>n(e,t,i));return ls("channels",s,t,o),o}async function gc(e,t,n,i){let s=await Bi(e,i),r=us("users",s,t);if(r)return r;let o=await _e("users.info",()=>n(e,t,i));if(o&&o!==t)ls("users",s,t,o);return o}async function mc(e,t,n,i){let s=await Bi(e,i),r=us("users",s,`tz:${t}`);if(r)return r==="?"?null:r;let o=null;try{let a=await _e("users.info",()=>n(e,t,i));if(a?.user?.is_bot===!0)return lc(s,t,null);let c=a?.user?.tz;o=typeof c==="string"&&c?c:null}catch{return null}return lc(s,t,o)}function lc(e,t,n){return ls("users",e,`tz:${t}`,n??"?"),n}async function Dc(e,t,n,i,s,r){let o=s.progress[i],a=await hc(e,r),c=await _e("reactions.get",()=>zo(e,t,n,r)),u=new Set(c.filter((h)=>h.users.includes(a)).map((h)=>h.name)),f=Xt.map((h)=>s.progress[h]).filter((h)=>u.has(h));if(f.length===1&&f[0]===o)return{noop:!0,removed:[],leftover:[]};if(!u.has(o))await _e("reactions.add",()=>Un(e,t,n,o,r));let l=[],d=[];for(let h of f){if(h===o)continue;try{await _e("reactions.remove",()=>Jn(e,t,n,h,r)),l.push(h)}catch{d.push(h)}}return{noop:!1,added:i,removed:l,leftover:d}}async function yc(e,t,n,i,s,r,o){let a=s.flags[i];if(r)await _e("reactions.remove",()=>Jn(e,t,n,a,o));else await _e("reactions.add",()=>Un(e,t,n,a,o));return a}var vi=1000;async function wc(e,t,n,i={}){let s=i.limit??vi,r=i.cookie,o=await hc(e,r),a=Xt.map((d)=>n.progress[d]),c=[],u=0,f,l=!1;while(u<s){let d=Math.min(200,s-u),h=await _e("conversations.history",()=>on(e,t,d,void 0,f,r)),m=h.messages??[];u+=m.length;for(let p of m){let y=String(p.ts??"");if(!y)continue;let C=new Set((p.reactions??[]).filter((k)=>(k.users??[]).map(String).includes(o)).map((k)=>String(k.name??""))),F=a.filter((k)=>C.has(k));if(F.length<2)continue;c.push({ts:y,text:String(p.text??"").split(`
152
+ `)}catch{}}function ac(e,t){return e?`${e} ${t}`:void 0}function us(e,t,n){if(!cs)return;let i=ac(t,n);if(!i)return;let s=Ri()[e][i];if(!s)return;if(s.expires<=as.now()){delete Ri()[e][i];return}return s.value}function ls(e,t,n,i,s=ef){if(!cs)return;let r=ac(t,n);if(!r)return;let o=Ri();o[e][r]={value:i,expires:as.now()+s},tf(o)}var Mi={marker:"pushpin",progress:{done:"white_check_mark",dropped:"no_entry_sign",doing:"eyes",pending:"hourglass_flowing_sand"},flags:{alert:"exclamation","needs-discussion":"thinking_face",waiting:"speech_balloon",blocked:"lock"}},Xt=["done","dropped","doing","pending"],fc=["alert","needs-discussion","waiting","blocked"];function af(){return of(process.env.HOME||rf(),".config","slack-cli","todo.json")}function fs(e){return e.replace(/^:+|:+$/g,"")}function yn(e=af()){let t={marker:Mi.marker,progress:{...Mi.progress},flags:{...Mi.flags}};try{if(!nf(e))return t;let n=JSON.parse(sf(e,"utf8"));if(typeof n.marker==="string"&&n.marker.trim())t.marker=fs(n.marker.trim());for(let i of Xt){let s=n.progress?.[i];if(typeof s==="string"&&s.trim())t.progress[i]=fs(s.trim())}for(let i of fc){let s=n.flags?.[i];if(typeof s==="string"&&s.trim())t.flags[i]=fs(s.trim())}}catch{}return t}function cc(e,t,n=!1){return`${n?"-":""}${t?"has":"hasmy"}::${fs(e)}:`}function dc(e,t,n={}){let i=n.shared===!0,s=(a)=>cc(a,i),r=(a)=>cc(a,i,!0),o=[];if(e==="untriaged")o.push(s(t.marker),...Xt.map((a)=>r(t.progress[a])));else if(e==="stuck")o.push(s(t.marker),r(t.progress.done),r(t.progress.dropped),`(${fc.map((a)=>s(t.flags[a])).join(" OR ")})`);else if(e==="open")o.push(s(t.marker),r(t.progress.done),r(t.progress.dropped));else{let a=Xt.indexOf(e);o.push(s(t.progress[e]));for(let c of Xt.slice(0,a))o.push(r(t.progress[c]))}if(n.in){let a=n.in.startsWith("#")||n.in.startsWith("@")?n.in:`#${n.in}`;o.push(`in:${a}`)}if(n.from){let a=n.from==="me"||n.from.startsWith("@")?n.from:`@${n.from}`;o.push(`from:${a}`)}return o.join(" ")}var cf=3,uf={sleep:(e)=>new Promise((t)=>setTimeout(t,e))};async function _e(e,t,n=cf){for(let i=0;;i++)try{return await t()}catch(s){if(!(s instanceof Ve))throw s;if(i>=n)throw Error(`Slack rate limit hit on ${e} — gave up after ${n} retries. Try again in a minute.`);console.error(`Warning: Slack rate limit hit on ${e} — backing off for ${s.retryAfter}s`),await uf.sleep(s.retryAfter*1000)}}var uc=new Map;async function pc(e,t){let n=uc.get(e);if(n)return n;let i=await _e("auth.test",()=>zt(e,t)),s={userId:i.userId,teamId:i.teamId};return uc.set(e,s),s}async function hc(e,t){return(await pc(e,t)).userId}async function Bi(e,t){try{return(await pc(e,t)).teamId}catch{return""}}async function Ni(e,t,n,i){if(!t.startsWith("#"))return n(e,t,i);let s=await Bi(e,i),r=us("channels",s,t);if(r)return r;let o=await _e("resolveChannel",()=>n(e,t,i));return ls("channels",s,t,o),o}async function gc(e,t,n,i){let s=await Bi(e,i),r=us("users",s,t);if(r)return r;let o=await _e("users.info",()=>n(e,t,i));if(o&&o!==t)ls("users",s,t,o);return o}async function mc(e,t,n,i){let s=await Bi(e,i),r=us("users",s,`tz:${t}`);if(r)return r==="?"?null:r;let o=null;try{let a=await _e("users.info",()=>n(e,t,i));if(a?.user?.is_bot===!0||t==="USLACKBOT")return lc(s,t,null);let c=a?.user?.tz;o=typeof c==="string"&&c?c:null}catch{return null}return lc(s,t,o)}function lc(e,t,n){return ls("users",e,`tz:${t}`,n??"?"),n}async function Dc(e,t,n,i,s,r){let o=s.progress[i],a=await hc(e,r),c=await _e("reactions.get",()=>zo(e,t,n,r)),u=new Set(c.filter((h)=>h.users.includes(a)).map((h)=>h.name)),f=Xt.map((h)=>s.progress[h]).filter((h)=>u.has(h));if(f.length===1&&f[0]===o)return{noop:!0,removed:[],leftover:[]};if(!u.has(o))await _e("reactions.add",()=>Un(e,t,n,o,r));let l=[],d=[];for(let h of f){if(h===o)continue;try{await _e("reactions.remove",()=>Jn(e,t,n,h,r)),l.push(h)}catch{d.push(h)}}return{noop:!1,added:i,removed:l,leftover:d}}async function yc(e,t,n,i,s,r,o){let a=s.flags[i];if(r)await _e("reactions.remove",()=>Jn(e,t,n,a,o));else await _e("reactions.add",()=>Un(e,t,n,a,o));return a}var vi=1000;async function wc(e,t,n,i={}){let s=i.limit??vi,r=i.cookie,o=await hc(e,r),a=Xt.map((d)=>n.progress[d]),c=[],u=0,f,l=!1;while(u<s){let d=Math.min(200,s-u),h=await _e("conversations.history",()=>on(e,t,d,void 0,f,r)),m=h.messages??[];u+=m.length;for(let p of m){let y=String(p.ts??"");if(!y)continue;let C=new Set((p.reactions??[]).filter((k)=>(k.users??[]).map(String).includes(o)).map((k)=>String(k.name??""))),F=a.filter((k)=>C.has(k));if(F.length<2)continue;c.push({ts:y,text:String(p.text??"").split(`
153
153
  `)[0]??"",emoji:F,keep:F[0]})}if(f=h.response_metadata?.next_cursor||void 0,!f||m.length===0)break;if(u>=s){l=!0;break}}if(i.fix)for(let d of c)try{try{await _e("reactions.add",()=>Un(e,t,d.ts,d.keep,r))}catch(h){if(!(h instanceof Error)||!/already_reacted/.test(h.message))throw h}for(let h of d.emoji){if(h===d.keep)continue;await _e("reactions.remove",()=>Jn(e,t,d.ts,h,r))}d.fixed=!0}catch(h){d.fixed=!1,d.error=h instanceof Error?h.message:String(h)}return{scanned:u,findings:c,truncated:l}}var lf=!0,ff;function ji(e){if(lf=e,!e)ff=void 0}function Bt(e){return e.toLowerCase().replace(/[-_\s]/g,"")}function ft(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function df(e,t){let n=Bt(t),i=ft(e.profile);for(let r of[e.name,e.real_name,i.display_name,i.real_name])if(typeof r==="string"&&r&&Bt(r)===n)return!0;let s=typeof i.email==="string"?i.email.toLowerCase():"";return s!==""&&s===t.toLowerCase()}function pf(e){let t=ft(e.profile),n=new Set;for(let i of[t.display_name,e.real_name,e.name,t.real_name])if(typeof i==="string"&&i){let s=Bt(i);if(s.length>=2)n.add(s)}return[...n]}function hf(e,t){let n=Bt(e),i,s=!1;for(let r of t){let o=typeof r.id==="string"?r.id:"";if(!o)continue;for(let a of pf(r)){let c=-1;if(n===a)c=e.length;else for(let u of Fc)if(e.length>u.length&&e.endsWith(u)&&Bt(e.slice(0,e.length-u.length))===a){c=e.length-u.length;break}if(c<0)continue;if(!i||a.length>i.formLen)i={userId:o,matchLen:c,formLen:a.length,display:Ui(r)},s=!1;else if(a.length===i.formLen&&i.userId!==o)s=!0}}if(!i)return;return s?"ambiguous":{userId:i.userId,matchLen:i.matchLen,display:i.display}}async function Nt(e,t,n,i){let s=`[${Cc}ー]+`,r=`${s}(?:[._-]+${s})*`,o=new RegExp(`(?<![A-Za-z0-9._@<-])@(${r})`,"gu"),a=new Set;for(let F of t.matchAll(o))a.add(F[1]);if(a.size===0)return{text:t,resolved:[],unresolved:[]};let c=new Map;for(let F of a)c.set(F,{status:"pending"});let u=(F)=>{for(let k of a){if(c.get(k).status!=="pending")continue;if(Wi(k)){let S=hf(k,F);if(S==="ambiguous")c.set(k,{status:"ambiguous"});else if(S)c.set(k,{status:"resolved",userId:S.userId,matchLen:S.matchLen,display:S.display})}else{let S=F.filter((I)=>df(I,k)),A=new Set(S.map((I)=>typeof I.id==="string"?I.id:"").filter(Boolean));if(A.size===1){let I=S.find((W)=>typeof W.id==="string");c.set(k,{status:"resolved",userId:I.id,matchLen:k.length,display:Ui(I)})}else if(A.size>1)c.set(k,{status:"ambiguous"})}}},f=!1;try{let F=await Hn(e,i);u((F.members??[]).map(ft)),f=!0}catch{f=!1}let l=[...a].some((F)=>c.get(F).status==="pending"),d=!1,h=!0;if(l&&n){d=!0;try{let F=await ai(e,n,i),k=[];for(let S of F){let A=ft(await ci(e,S,i)),I=ft(A.user);if(typeof I.id!=="string")I.id=S;k.push(I)}u(k)}catch{h=!1}}let m=f&&(n?d&&h:!0),p=[],y=[];for(let F of a){let k=c.get(F);if(k.status==="resolved")p.push({surface:`@${F.slice(0,k.matchLen)}`,display:k.display,userId:k.userId});else if(k.status==="ambiguous")y.push({surface:`@${F}`,reason:"ambiguous"});else y.push({surface:`@${F}`,reason:m?"no-match":"unavailable"})}return{text:t.replace(o,(F,k)=>{let S=c.get(k);if(S&&S.status==="resolved")return`<@${S.userId}>${k.slice(S.matchLen)}`;return F}),resolved:p,unresolved:y}}function wn(e){let t=[],n=!1;for(let i of e)if(i.reason==="ambiguous")t.push(`${i.surface} matches multiple people — not tagged, sent as plain text (use <@USERID> to tag)`);else if(i.reason==="unavailable"){if(n)continue;t.push("could not fetch the user list (users:read missing or an API/connection error) — @mentions not tagged, sent as plain text"),n=!0}else t.push(`${i.surface} matched no one — not tagged, sent as plain text`);return t}async function bc(e,t,n,i={}){let s=i.warn??((o)=>process.stderr.write(`${o}
154
154
  `)),r=await Nt(e,t,n,i.cookie);for(let o of wn(r.unresolved))s(`warn: ${o}`);return r.text}var Fc=["さん","さま","様","君","くん","ちゃん","氏","先生","先輩","殿","老师","老師","兄","姐","哥","姐妹"],Cc="\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}A-Za-z0-9";function Wi(e){return/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u.test(e)}function gf(e){let t=[],n=new RegExp(`([${Cc}]{1,12})(${Fc.join("|")})`,"gu");for(let i of e.matchAll(n))t.push({ref:i[1],honorific:i[2]});for(let i of e.matchAll(/\b(?:dear|hi|hello|hey)\b[ \t]+([A-Z][A-Za-z'’-]{1,20})/gi))t.push({ref:i[1],honorific:""});for(let i of e.matchAll(/(?:^|\n)[ \t]*([A-Z][A-Za-z'’-]{1,20}),/g))t.push({ref:i[1],honorific:""});return t}function mf(e){let t=ft(e.profile),n=new Set;for(let i of[e.name,e.real_name,t.display_name,t.real_name]){if(typeof i!=="string"||!i)continue;for(let s of[i,...i.split(/\s+/)]){let r=Bt(s);if(r.length>=2)n.add(r)}}return[...n]}function Df(e,t){let n=Bt(e);if(n.length<2)return;for(let i of t)if(n===i)return i;if(Wi(e)){for(let i of t)if(n.includes(i)||i.includes(n))return i}return}function Ui(e){return[ft(e.profile).display_name,e.real_name,e.name].filter((i)=>typeof i==="string"&&i!=="")[0]??String(e.id??"?")}async function Ec(e,t,n){let i=gf(t);if(i.length===0)return[];let s=new Set;for(let u of t.matchAll(/<@([A-Z0-9]+)(?:\|[^>]*)?>/g))s.add(u[1]);let o=((await Hn(e,n)).members??[]).map(ft).filter((u)=>u.deleted!==!0&&u.is_bot!==!0&&u.id!=="USLACKBOT").map((u)=>({id:typeof u.id==="string"?u.id:"",forms:mf(u),display:Ui(u)})).filter((u)=>u.id!==""),a=[],c=new Set;for(let{ref:u,honorific:f}of i)for(let l of o){let d=Df(u,l.forms);if(!d)continue;if(s.has(l.id)||c.has(l.id))break;c.add(l.id),a.push({surface:Wi(u)?`${d}${f}`:u,display:l.display,userId:l.id});break}return a}async function Gt(e,t,n,i){let s=t,r=[],o=s,a=0;while(!0){let c=o.indexOf("<@U",a);if(c===-1)break;let u=o.slice(c+2),f=u.search(/[>|]/),l=f===-1?u:u.slice(0,f);if(l.length>=9)r.push(l);a=c+1}for(let c of r){if(!n.has(c))n.set(c,await zn(e,c,i));let u=n.get(c)??c;s=s.replaceAll(`<@${c}>`,`@${u}`),s=s.replace(new RegExp(`<@${c}\\|[^>]*>`,"g"),`@${u}`)}return s}function bn(e){return e.replace(/<!date\^(\d+)\^[^|>]*(?:\|([^>]*))?>/g,(t,n,i)=>{let s=Number(n);if(!Number.isFinite(s))return i??"date";let r=new Date(s*1000);if(Number.isNaN(r.getTime()))return i??"date";let o=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],a=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],c=o[r.getUTCDay()]??"",u=a[r.getUTCMonth()]??"";return`${c}, ${u} ${String(r.getUTCDate()).padStart(2,"0")}, ${r.getUTCFullYear()}`})}function xc(e,t=new Date){let n=new Date(e*1000),i=Li(t),s=Li(new Date(t.getTime()-86400000)),r=Li(n);if(r===i)return"Today";if(r===s)return"Yesterday";let o=n.toLocaleDateString("en-US",{weekday:"long"}),a=n.toLocaleDateString("en-US",{month:"short"});return`${o}, ${a} ${String(n.getDate()).padStart(2,"0")}`}function Li(e){return`${e.getFullYear()}-${e.getMonth()}-${e.getDate()}`}function _c(e){let t=new Date(e*1000),n=t.getFullYear(),i=String(t.getMonth()+1).padStart(2,"0"),s=String(t.getDate()).padStart(2,"0"),r=String(t.getHours()).padStart(2,"0"),o=String(t.getMinutes()).padStart(2,"0");return`${n}-${i}-${s} ${r}:${o}`}function Sc(e=new Date,t){let n=process.env.SLACK_QUIET_TZ??"Asia/Tokyo",i=!!t&&yf(t),s=i?t:n,r=Number(process.env.SLACK_QUIET_START??23),o=Number(process.env.SLACK_QUIET_END??8),a,c;try{let h=new Intl.DateTimeFormat("en-GB",{timeZone:s,hour12:!1,weekday:"short",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"});c=h.format(e),a=Number(h.formatToParts(e).find((m)=>m.type==="hour")?.value??"12")}catch{return null}let u=r>o?a>=r||a<o:a>=r&&a<o,f=i?`${s}, recipient`:`${s}, sender — recipient's timezone unknown`,l=`\uD83D\uDD50 ${c} (${f})`;if(!u)return l;return`${l}
155
155
  ⚠ QUIET HOURS (${r}:00-${o}:00) — this will buzz a phone.${i?"":" Their local time may differ."} Send only for a production incident; otherwise hold it until morning.`}function yf(e){try{return new Intl.DateTimeFormat("en-GB",{timeZone:e}),!0}catch{return!1}}function Fn(e){if(!Tc(e))return;let t=bf(e,"utf8");for(let n of t.split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slack-term",
3
- "version": "1.30.0",
3
+ "version": "1.30.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/snomiao/slack-term.git"
package/ts/todo.ts CHANGED
@@ -324,9 +324,17 @@ export async function userTzCached(
324
324
  { user?: { tz?: unknown; is_bot?: unknown } };
325
325
  // A bot reports America/Los_Angeles (Slack's own default) and has no phone
326
326
  // to buzz, so its "timezone" is a false signal — treat it as unknown rather
327
- // than warn about the middle of the night in California. Measured on this
328
- // workspace's bot user, and the same bogus value shows up in users.list.
329
- if (resp?.user?.is_bot === true) return cacheThen(scope, userId, null);
327
+ // than warn about the middle of the night in California. Measured: 12 of
328
+ // this workspace's 14 bots report exactly that, so it is Slack's default
329
+ // rather than one app's misconfiguration.
330
+ //
331
+ // USLACKBOT needs naming separately because it reports `is_bot: false`
332
+ // while carrying the same bogus zone — the one account where the flag and
333
+ // the reality disagree. `format.ts` and the `user ls` filter already
334
+ // special-case it for the same reason.
335
+ if (resp?.user?.is_bot === true || userId === "USLACKBOT") {
336
+ return cacheThen(scope, userId, null);
337
+ }
330
338
  const raw = resp?.user?.tz;
331
339
  tz = typeof raw === "string" && raw ? raw : null;
332
340
  } catch {