slack-term 1.19.0 → 1.19.1

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
@@ -120,7 +120,7 @@ Replace it with an xoxp- user token:
120
120
  slack workspace set-token <name> <xoxp-token>`);throw Error(`Slack error on ${u}: ${z}`)}return $}async function d6(D,u,F,E){let C={};if(E)C.Cookie=`d=${E}`;let B=await fetch(`${J1()}/${u}`,{...F,headers:{...F.headers??{},Authorization:`Bearer ${D}`,...C}});if(B.status===429){let z=parseInt(B.headers.get("retry-after")??"60",10);throw new Iu(isNaN(z)?60:z)}let $=await B.json();if($.ok!==!0){let z=$.error??"unknown";if(z==="ratelimited")throw new Iu(60);if((z==="invalid_auth"||z==="not_authed")&&!D.startsWith("xoxc-"))throw Error(`The draft API requires a desktop app session token (xoxc-).
121
121
  Import from Slack desktop: slack workspace import`);if((z==="invalid_auth"||z==="not_authed")&&!E)throw Error(`drafts.list also requires the xoxd session cookie.
122
122
  Set it with: slack workspace set-cookie <workspace-name> <xoxd-value>
123
- `+"Get xoxd from browser: DevTools → Application → Cookies → slack.com → d");throw Error(`Slack error on ${u}: ${z}`)}return $}function Ku(D,u,F={},E){let C=new URLSearchParams({token:D,...F});return d6(D,u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:C.toString()},E)}function BD(D,u,F,E){let C=new URLSearchParams(F).toString();return X1(D,`${u}?${C}`,{method:"GET"},E)}function hD(D,u,F){return X1(D,u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(F)})}async function Q1(D){let u=await BD(D,"auth.test",{});return{team:u.team??"",teamId:u.team_id??"",url:u.url??"",user:u.user??"",userId:u.user_id??""}}async function fu(D,u,F=20,E,C){let B={channel:u,limit:String(F)};if(E!==void 0)B.oldest=E;if(C!==void 0)B.cursor=C;return BD(D,"conversations.history",B)}async function ju(D,u,F,E=50){return BD(D,"conversations.replies",{channel:u,ts:F,limit:String(E)})}async function O1(D,u,F,E){return BD(D,"search.messages",{query:u,sort:"timestamp",sort_dir:"desc",count:String(Math.min(Math.max(F,1),100)),page:String(Math.max(E,1))})}async function Y1(D,u){return O1(D,u,100,1)}async function W1(D,u,F){let C=1,B=[],$={ok:!0,messages:{}};while(!0){let Z=await O1(D,u,100,C),G=bu(Z,["messages","matches"]),Q=Array.isArray(G)?G:[];B.push(...Q);let J=Number(bu(Z,["messages","paging","pages"])??1);if($=Z,Q.length===0||C>=J||B.length>=F)break;C+=1}let z=$;if(!z.messages)z.messages={};return z.messages.matches=B.slice(0,F),z}async function H1(D,u,F,E,C){let B={channel:u,text:F,blocks:[{type:"markdown",text:F}]};if(E!==void 0)B.thread_ts=E;if(C&&E!==void 0)B.reply_broadcast=!0;return(await hD(D,"chat.postMessage",B)).ts??""}async function V1(D,u,F,E,C){let B={channel:u,text:F,post_at:E,blocks:[{type:"markdown",text:F}]};if(C!==void 0)B.thread_ts=C;return(await hD(D,"chat.scheduleMessage",B)).scheduled_message_id??""}async function M1(D,u){let F={};if(u)F.channel=u;return BD(D,"chat.scheduledMessages.list",F)}async function U1(D,u,F){await hD(D,"chat.deleteScheduledMessage",{channel:u,scheduled_message_id:F})}async function q1(D,u,F){return(await BD(D,"chat.getPermalink",{channel:u,message_ts:F})).permalink??""}async function _1(D,u,F,E){return(await hD(D,"chat.update",{channel:u,ts:F,text:E,blocks:[{type:"markdown",text:E}]})).ts??F}async function K1(D,u,F){await hD(D,"chat.delete",{channel:u,ts:F})}async function j1(D,u,F=!1){let E=await hD(D,"conversations.create",{name:u,is_private:F});return{id:E.channel?.id??"",name:E.channel?.name??u}}async function A1(D,u,F){await hD(D,"conversations.invite",{channel:u,users:F.join(",")})}async function qF(D){let u=[],F="";while(!0){let E={limit:"200",types:"public_channel,private_channel,im,mpim"};if(F)E.cursor=F;let C=await BD(D,"conversations.list",E);if(u.push(...C.channels??[]),F=C.response_metadata?.next_cursor??"",!F)break}return{channels:u}}async function hu(D,u){let E=(await hD(D,"conversations.open",{users:u})).channel?.id;if(!E)throw Error(`Failed to open DM with user ${u}`);return E}function xD(D){return D.toLowerCase().replace(/[-_\s]/g,"")}async function N0(D,u,F){if(!u.startsWith("@")){if(/^[UW][A-Za-z0-9]{6,}$/.test(u))return u;throw Error(`Expected @user or a user ID, got: ${u}`)}let E=xD(u.slice(1)),C=await BD(D,"auth.test",{},F);if(E==="you"||E==="me"||xD(C.user??"")===E){if(!C.user_id)throw Error("auth.test did not return user_id");return C.user_id}let B="";while(!0){let $={limit:"200"};if(B)$.cursor=B;let z=await BD(D,"users.list",$,F);for(let Z of z.members??[]){let G=xD(Z.name??""),Q=xD(Z.real_name??""),J=xD(Z.profile?.display_name??"");if(G===E||Q===E||J&&J===E)return Z.id??""}if(B=z.response_metadata?.next_cursor??"",!B)break}throw Error(`User not found: ${u}`)}function vu(D){let u=D.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(!u)return;let F=u[1],E=u[2]&&u[3]?`${u[2]}.${u[3]}`:void 0,C=D.indexOf("?"),B=C>=0?new URLSearchParams(D.slice(C)):void 0,$=B?.get("thread_ts")??void 0,G={channel:B?.get("cid")??void 0??F};if(E)G.ts=E;if($)G.threadTs=$;return G}function i6(D){return vu(D)?.channel}async function ND(D,u,F){let E=i6(u);if(E)return E;if(!u.startsWith("@")&&!u.startsWith("#")){if(/^[A-Za-z0-9]{9,}$/.test(u))return u;throw Error(`Target must start with # or @ (or be a Slack URL/ID), got: ${u}`)}let C=u.startsWith("@"),B=u.slice(1),$=xD(B);if(C){let G=await BD(D,"auth.test",{},F);if($==="you"||$==="me"||xD(G.user??"")===$){let H=G.user_id;if(!H)throw Error("auth.test did not return user_id");let q=((await BD(D,"conversations.list",{types:"im",limit:"200"},F)).channels??[]).find((j)=>j.user===H);if(q?.id)return String(q.id);return hu(D,H)}let J="",O="";while(!0){let H={limit:"200"};if(O)H.cursor=O;let Y=await BD(D,"users.list",H,F);for(let q of Y.members??[]){let j=xD(q.name??""),N=xD(q.real_name??""),k=xD(q.profile?.display_name??"");if(j===$||N===$||k&&k===$){J=q.id??"";break}}if(J)break;if(O=Y.response_metadata?.next_cursor??"",!O)break}if(!J)throw Error(`User not found: ${u}`);let W="";while(!0){let H={types:"im",limit:"200"};if(W)H.cursor=W;let Y=await BD(D,"conversations.list",H,F);for(let q of Y.channels??[])if(q.user===J)return String(q.id??"");if(W=Y.response_metadata?.next_cursor??"",!W)break}throw Error(`No existing DM with ${u} (${J}). Open it once in Slack first.`)}let z=B.toLowerCase(),Z="";while(!0){let G={limit:"200",types:"public_channel,private_channel",exclude_archived:"true"};if(Z)G.cursor=Z;let Q=await BD(D,"conversations.list",G,F);for(let J of Q.channels??[])if(String(J.name??"").toLowerCase()===z)return String(J.id??"");if(Z=Q.response_metadata?.next_cursor??"",!Z)break}throw Error(`channel not found: ${u}`)}async function pu(D,u){try{let F=await BD(D,"users.info",{user:u}),E=F.user?.profile?.display_name,C=E&&E.length>0?E:F.user?.real_name??F.user?.name??u,B=F.user?.name??u;return[C,B]}catch{return[u,u]}}async function mu(D,u){try{let F=await BD(D,"users.info",{user:u}),E=F.user?.profile?.display_name;if(E&&E.length>0)return E;return F.user?.real_name??F.user?.name??u}catch{return u}}async function R0(D){let u=[],F="";while(!0){let E={limit:"200"};if(F)E.cursor=F;let C=await BD(D,"users.list",E);if(u.push(...C.members??[]),F=C.response_metadata?.next_cursor??"",!F)break}return{members:u}}async function yu(D,u){return Ku(D,"drafts.list",{},u)}async function L1(D,u,F,E){let{randomUUID:C}=await import("node:crypto"),B=JSON.stringify([{type:"rich_text",elements:[{type:"rich_text_section",elements:[{type:"text",text:F}]}]}]);return Ku(D,"drafts.create",{client_msg_id:C(),destinations:JSON.stringify([{channel_id:u}]),blocks:B,file_ids:JSON.stringify([]),is_from_composer:"true"},E)}async function N1(D,u,F,E,C){let B=JSON.stringify([{type:"rich_text",elements:[{type:"rich_text_section",elements:[{type:"text",text:E}]}]}]),$=(Date.now()/1000).toFixed(6);return Ku(D,"drafts.update",{draft_id:u,client_last_updated_ts:$,destinations:JSON.stringify([{channel_id:F}]),blocks:B,file_ids:JSON.stringify([])},C)}async function R1(D,u,F){return Ku(D,"conversations.info",{channel:u},F)}async function T1(D,u){return BD(D,"users.info",{user:u})}async function T0(D,u){return BD(D,"conversations.info",{channel:u})}async function S1(D,u,F){let E=(Date.now()/1000).toFixed(6);return Ku(D,"drafts.delete",{draft_id:u,client_last_updated_ts:E},F)}async function S0(D,u){let F=await Ku(D,"auth.test",{},u);return{userId:String(F.user_id??""),teamId:String(F.team_id??"")}}async function P1(D,u,F,E={}){let{statSync:C,readFileSync:B}=await import("node:fs"),{basename:$}=await import("node:path"),z=C(F),Z=$(F),G=await BD(D,"files.getUploadURLExternal",{filename:Z,length:String(z.size)}),Q=G.upload_url,J=G.file_id;if(!Q||!J)throw Error("files.getUploadURLExternal returned no upload_url/file_id");let O=B(F),W=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:O});if(!W.ok)throw Error(`Upload PUT failed: ${W.status} ${W.statusText}`);let H={files:[{id:J,title:E.title??Z}],channel_id:u};if(E.threadTs)H.thread_ts=E.threadTs;if(E.initialComment)H.initial_comment=E.initialComment;let Y=await hD(D,"files.completeUploadExternal",H),q={fileId:J},j=Y.files?.[0]?.permalink;if(j)q.permalink=j;return q}function bu(D,u){let F=D;for(let E of u){if(F===void 0||F===null)return;if(typeof E==="number"){if(!Array.isArray(F))return;F=F[E]??void 0}else{if(typeof F!=="object"||Array.isArray(F))return;F=F[E]}}return F}function w1(){return/(?<![A-Za-z0-9._@-])@([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*)/g}function x1(D){return D.toLowerCase().replace(/[-_\s]/g,"")}function _F(D){return D&&typeof D==="object"&&!Array.isArray(D)?D:{}}function I1(D,u){let F=x1(u),E=_F(D.profile);for(let B of[D.name,D.real_name,E.display_name,E.real_name])if(typeof B==="string"&&B&&x1(B)===F)return!0;let C=typeof E.email==="string"?E.email.toLowerCase():"";return C!==""&&C===u.toLowerCase()}async function w0(D,u,F,E={}){let C=E.warn??((Q)=>process.stderr.write(`${Q}
123
+ `+"Get xoxd from browser: DevTools → Application → Cookies → slack.com → d");throw Error(`Slack error on ${u}: ${z}`)}return $}function Ku(D,u,F={},E){let C=new URLSearchParams({token:D,...F});return d6(D,u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:C.toString()},E)}function BD(D,u,F,E){let C=new URLSearchParams(F).toString();return X1(D,`${u}?${C}`,{method:"GET"},E)}function hD(D,u,F){return X1(D,u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(F)})}async function Q1(D){let u=await BD(D,"auth.test",{});return{team:u.team??"",teamId:u.team_id??"",url:u.url??"",user:u.user??"",userId:u.user_id??""}}async function fu(D,u,F=20,E,C){let B={channel:u,limit:String(F)};if(E!==void 0)B.oldest=E;if(C!==void 0)B.cursor=C;return BD(D,"conversations.history",B)}async function ju(D,u,F,E=50){return BD(D,"conversations.replies",{channel:u,ts:F,limit:String(E)})}async function O1(D,u,F,E){return BD(D,"search.messages",{query:u,sort:"timestamp",sort_dir:"desc",count:String(Math.min(Math.max(F,1),100)),page:String(Math.max(E,1))})}async function Y1(D,u){return O1(D,u,100,1)}async function W1(D,u,F){let C=1,B=[],$={ok:!0,messages:{}};while(!0){let Z=await O1(D,u,100,C),G=bu(Z,["messages","matches"]),Q=Array.isArray(G)?G:[];B.push(...Q);let J=Number(bu(Z,["messages","paging","pages"])??1);if($=Z,Q.length===0||C>=J||B.length>=F)break;C+=1}let z=$;if(!z.messages)z.messages={};return z.messages.matches=B.slice(0,F),z}async function H1(D,u,F,E,C){let B={channel:u,text:F,blocks:[{type:"markdown",text:F}]};if(E!==void 0)B.thread_ts=E;if(C&&E!==void 0)B.reply_broadcast=!0;return(await hD(D,"chat.postMessage",B)).ts??""}async function V1(D,u,F,E,C){let B={channel:u,text:F,post_at:E,blocks:[{type:"markdown",text:F}]};if(C!==void 0)B.thread_ts=C;return(await hD(D,"chat.scheduleMessage",B)).scheduled_message_id??""}async function M1(D,u){let F={};if(u)F.channel=u;return BD(D,"chat.scheduledMessages.list",F)}async function U1(D,u,F){await hD(D,"chat.deleteScheduledMessage",{channel:u,scheduled_message_id:F})}async function q1(D,u,F){return(await BD(D,"chat.getPermalink",{channel:u,message_ts:F})).permalink??""}async function _1(D,u,F,E){return(await hD(D,"chat.update",{channel:u,ts:F,text:E,blocks:[{type:"markdown",text:E}]})).ts??F}async function K1(D,u,F){await hD(D,"chat.delete",{channel:u,ts:F})}async function j1(D,u,F=!1){let E=await hD(D,"conversations.create",{name:u,is_private:F});return{id:E.channel?.id??"",name:E.channel?.name??u}}async function A1(D,u,F){await hD(D,"conversations.invite",{channel:u,users:F.join(",")})}async function qF(D){let u=[],F="";while(!0){let E={limit:"200",types:"public_channel,private_channel,im,mpim"};if(F)E.cursor=F;let C=await BD(D,"conversations.list",E);if(u.push(...C.channels??[]),F=C.response_metadata?.next_cursor??"",!F)break}return{channels:u}}async function hu(D,u){let E=(await hD(D,"conversations.open",{users:u})).channel?.id;if(!E)throw Error(`Failed to open DM with user ${u}`);return E}function xD(D){return D.toLowerCase().replace(/[-_\s]/g,"")}async function N0(D,u,F){if(!u.startsWith("@")){if(/^[UW][A-Za-z0-9]{6,}$/.test(u))return u;throw Error(`Expected @user or a user ID, got: ${u}`)}let E=xD(u.slice(1)),C=await BD(D,"auth.test",{},F);if(E==="you"||E==="me"||xD(C.user??"")===E){if(!C.user_id)throw Error("auth.test did not return user_id");return C.user_id}let B="";while(!0){let $={limit:"200"};if(B)$.cursor=B;let z=await BD(D,"users.list",$,F);for(let Z of z.members??[]){let G=xD(Z.name??""),Q=xD(Z.real_name??""),J=xD(Z.profile?.display_name??"");if(G===E||Q===E||J&&J===E)return Z.id??""}if(B=z.response_metadata?.next_cursor??"",!B)break}throw Error(`User not found: ${u}`)}function vu(D){let u=D.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(!u)return;let F=u[1],E=u[2]&&u[3]?`${u[2]}.${u[3]}`:void 0,C=D.indexOf("?"),B=C>=0?new URLSearchParams(D.slice(C)):void 0,$=B?.get("thread_ts")??void 0,G={channel:B?.get("cid")??void 0??F};if(E)G.ts=E;if($)G.threadTs=$;return G}function i6(D){return vu(D)?.channel}async function ND(D,u,F){let E=i6(u);if(E)return E;if(!u.startsWith("@")&&!u.startsWith("#")){if(/^[A-Za-z0-9]{9,}$/.test(u))return u;throw Error(`Target must start with # or @ (or be a Slack URL/ID), got: ${u}`)}let C=u.startsWith("@"),B=u.slice(1),$=xD(B);if(C){let G=await BD(D,"auth.test",{},F);if($==="you"||$==="me"||xD(G.user??"")===$){let H=G.user_id;if(!H)throw Error("auth.test did not return user_id");let q=((await BD(D,"conversations.list",{types:"im",limit:"200"},F)).channels??[]).find((j)=>j.user===H);if(q?.id)return String(q.id);return hu(D,H)}let J="",O="";while(!0){let H={limit:"200"};if(O)H.cursor=O;let Y=await BD(D,"users.list",H,F);for(let q of Y.members??[]){let j=xD(q.name??""),N=xD(q.real_name??""),k=xD(q.profile?.display_name??"");if(j===$||N===$||k&&k===$){J=q.id??"";break}}if(J)break;if(O=Y.response_metadata?.next_cursor??"",!O)break}if(!J)throw Error(`User not found: ${u}`);let W="";while(!0){let H={types:"im",limit:"200"};if(W)H.cursor=W;let Y=await BD(D,"conversations.list",H,F);for(let q of Y.channels??[])if(q.user===J)return String(q.id??"");if(W=Y.response_metadata?.next_cursor??"",!W)break}throw Error(`No existing DM with ${u} (${J}). Open it once in Slack first.`)}let z=B.toLowerCase(),Z="";while(!0){let G={limit:"200",types:"public_channel,private_channel",exclude_archived:"true"};if(Z)G.cursor=Z;let Q=await BD(D,"conversations.list",G,F);for(let J of Q.channels??[])if(String(J.name??"").toLowerCase()===z)return String(J.id??"");if(Z=Q.response_metadata?.next_cursor??"",!Z)break}throw Error(`channel not found: ${u}`)}async function pu(D,u){try{let F=await BD(D,"users.info",{user:u}),E=F.user?.profile?.display_name,C=E&&E.length>0?E:F.user?.real_name??F.user?.name??u,B=F.user?.name??u;return[C,B]}catch{return[u,u]}}async function mu(D,u){try{let F=await BD(D,"users.info",{user:u}),E=F.user?.profile?.display_name;if(E&&E.length>0)return E;return F.user?.real_name??F.user?.name??u}catch{return u}}async function R0(D){let u=[],F="";while(!0){let E={limit:"200"};if(F)E.cursor=F;let C=await BD(D,"users.list",E);if(u.push(...C.members??[]),F=C.response_metadata?.next_cursor??"",!F)break}return{members:u}}async function yu(D,u){return Ku(D,"drafts.list",{},u)}async function L1(D,u,F,E){let{randomUUID:C}=await import("node:crypto"),B=JSON.stringify([{type:"rich_text",elements:[{type:"rich_text_section",elements:[{type:"text",text:F}]}]}]);return Ku(D,"drafts.create",{client_msg_id:C(),destinations:JSON.stringify([{channel_id:u}]),blocks:B,file_ids:JSON.stringify([]),is_from_composer:"true"},E)}async function N1(D,u,F,E,C){let B=JSON.stringify([{type:"rich_text",elements:[{type:"rich_text_section",elements:[{type:"text",text:E}]}]}]),$=(Date.now()/1000).toFixed(6);return Ku(D,"drafts.update",{draft_id:u,client_last_updated_ts:$,destinations:JSON.stringify([{channel_id:F}]),blocks:B,file_ids:JSON.stringify([])},C)}async function R1(D,u,F){return Ku(D,"conversations.info",{channel:u},F)}async function T1(D,u){return BD(D,"users.info",{user:u})}async function T0(D,u){return BD(D,"conversations.info",{channel:u})}async function S1(D,u,F){let E=(Date.now()/1000).toFixed(6);return Ku(D,"drafts.delete",{draft_id:u,client_last_updated_ts:E},F)}async function S0(D,u){let F=await Ku(D,"auth.test",{},u);return{userId:String(F.user_id??""),teamId:String(F.team_id??"")}}async function P1(D,u,F,E={}){let{statSync:C,readFileSync:B}=await import("node:fs"),{basename:$}=await import("node:path"),z=C(F),Z=$(F),G=await BD(D,"files.getUploadURLExternal",{filename:Z,length:String(z.size)}),Q=G.upload_url,J=G.file_id;if(!Q||!J)throw Error("files.getUploadURLExternal returned no upload_url/file_id");let O=B(F),W=await fetch(Q,{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:O});if(!W.ok)throw Error(`Upload PUT failed: ${W.status} ${W.statusText}`);let H={files:[{id:J,title:E.title??Z}],channel_id:u};if(E.threadTs)H.thread_ts=E.threadTs;if(E.initialComment)H.initial_comment=E.initialComment;let Y=await hD(D,"files.completeUploadExternal",H),q={fileId:J},j=Y.files?.[0]?.permalink;if(j)q.permalink=j;return q}function bu(D,u){let F=D;for(let E of u){if(F===void 0||F===null)return;if(typeof E==="number"){if(!Array.isArray(F))return;F=F[E]??void 0}else{if(typeof F!=="object"||Array.isArray(F))return;F=F[E]}}return F}function w1(){return/(?<![A-Za-z0-9._@<-])@([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*)/g}function x1(D){return D.toLowerCase().replace(/[-_\s]/g,"")}function _F(D){return D&&typeof D==="object"&&!Array.isArray(D)?D:{}}function I1(D,u){let F=x1(u),E=_F(D.profile);for(let B of[D.name,D.real_name,E.display_name,E.real_name])if(typeof B==="string"&&B&&x1(B)===F)return!0;let C=typeof E.email==="string"?E.email.toLowerCase():"";return C!==""&&C===u.toLowerCase()}async function w0(D,u,F,E={}){let C=E.warn??((Q)=>process.stderr.write(`${Q}
124
124
  `)),B=new Set;for(let Q of u.matchAll(w1()))B.add(Q[1]);if(B.size===0)return u;let $=new Map,Z=((await Q0(D)).members??[]).map(_F),G=[];for(let Q of B){let J=Z.find((W)=>I1(W,Q)),O=J&&typeof J.id==="string"?J.id:"";if(O)$.set(Q,O);else G.push(Q)}if(G.length>0&&F){let Q=await O0(D,F),J=[];for(let O of Q){let W=_F(await Y0(D,O)),H=_F(W.user);if(typeof H.id!=="string")H.id=O;J.push(H)}for(let O of G){let W=J.find((Y)=>I1(Y,O)),H=W&&typeof W.id==="string"?W.id:"";if(H)$.set(O,H)}}for(let Q of B)if(!$.has(Q))C(`warn: unresolved mention @${Q} (left as text)`);return u.replace(w1(),(Q,J)=>{let O=$.get(J);return O?`<@${O}>`:Q})}async function Au(D,u,F){let E=u,C=[],B=E,$=0;while(!0){let z=B.indexOf("<@U",$);if(z===-1)break;let Z=B.slice(z+2),G=Z.search(/[>|]/),Q=G===-1?Z:Z.slice(0,G);if(Q.length>=9)C.push(Q);$=z+1}for(let z of C){if(!F.has(z))F.set(z,await JF(D,z));let Z=F.get(z)??z;E=E.replaceAll(`<@${z}>`,`@${Z}`),E=E.replace(new RegExp(`<@${z}\\|[^>]*>`,"g"),`@${Z}`)}return E}function cu(D){return D.replace(/<!date\^(\d+)\^[^|>]*(?:\|([^>]*))?>/g,(u,F,E)=>{let C=Number(F);if(!Number.isFinite(C))return E??"date";let B=new Date(C*1000);if(Number.isNaN(B.getTime()))return E??"date";let $=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],z=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Z=$[B.getUTCDay()]??"",G=z[B.getUTCMonth()]??"";return`${Z}, ${G} ${String(B.getUTCDate()).padStart(2,"0")}, ${B.getUTCFullYear()}`})}function b1(D,u=new Date){let F=new Date(D*1000),E=P0(u),C=P0(new Date(u.getTime()-86400000)),B=P0(F);if(B===E)return"Today";if(B===C)return"Yesterday";let $=F.toLocaleDateString("en-US",{weekday:"long"}),z=F.toLocaleDateString("en-US",{month:"short"});return`${$}, ${z} ${String(F.getDate()).padStart(2,"0")}`}function P0(D){return`${D.getFullYear()}-${D.getMonth()}-${D.getDate()}`}function f1(D){let u=new Date(D*1000),F=u.getFullYear(),E=String(u.getMonth()+1).padStart(2,"0"),C=String(u.getDate()).padStart(2,"0"),B=String(u.getHours()).padStart(2,"0"),$=String(u.getMinutes()).padStart(2,"0");return`${F}-${E}-${C} ${B}:${$}`}function gu(D){if(!v1(D))return;let u=t6(D,"utf8");for(let F of u.split(`
125
125
  `)){let E=F.trim();if(!E||E.startsWith("#"))continue;let C=E.indexOf("=");if(C===-1)continue;let B=E.slice(0,C).trim(),$=E.slice(C+1).trim();if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))$=$.slice(1,-1);if(!(B in process.env))process.env[B]=$}}function s6(D){l6(D,{recursive:!0});let u=Wu(D,".gitignore");if(!v1(u))o6(u,`*
126
126
  `)}function r6(){gu(Wu(h1(),".slack-cli",".env.local")),gu(Wu(h1(),".config/slack-cli",".env")),gu(Wu(process.cwd(),".slack-cli",".env.local")),gu(Wu(process.cwd(),".env.local")),gu(Wu(process.cwd(),".env"))}function a6(D){return n6("sha256").update(D).digest("hex")}function y(D){return D&&typeof D==="object"&&!Array.isArray(D)?D:{}}function a(D){return Array.isArray(D)?D:[]}function KF(D){return Number(D.ts??0)}async function p1(D,u,F){let E=u.user;if(typeof E==="string"){if(!F.has(E))F.set(E,await mu(D,E));return F.get(E)??E}return typeof u.username==="string"?u.username:"bot"}function x0(D){let u=new Date(D*1000),F=u.getUTCFullYear(),E=String(u.getUTCMonth()+1).padStart(2,"0"),C=String(u.getUTCDate()).padStart(2,"0"),B=String(u.getUTCHours()).padStart(2,"0"),$=String(u.getUTCMinutes()).padStart(2,"0"),z=String(u.getUTCSeconds()).padStart(2,"0");return`${F}-${E}-${C} ${B}:${$}:${z}`}function I0(D){let[u,F="000000"]=D.split("."),E=Number(u),C=new Date(E*1000),B=C.getUTCFullYear(),$=String(C.getUTCMonth()+1).padStart(2,"0"),z=String(C.getUTCDate()).padStart(2,"0"),Z=String(C.getUTCHours()).padStart(2,"0"),G=String(C.getUTCMinutes()).padStart(2,"0"),Q=String(C.getUTCSeconds()).padStart(2,"0"),J=F.padEnd(6,"0").slice(0,6);return`${B}-${$}-${z}T${Z}:${G}:${Q}.${J}`}function b0(D){let u=D.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\.(\d{6})$/);if(!u)throw Error(`Invalid message timestamp "${D}" \u2014 expected 2026-05-11T06:01:04.000100`);let F=Date.parse(u[1]+"Z");if(isNaN(F))throw Error(`Cannot parse date in "${D}"`);return`${Math.floor(F/1000)}.${u[2]}`}function e6(D){return/^\d{4}-\d{2}-\d{2}T/.test(D)?b0(D):D}async function AF(D,u,F,E){let C=typeof u.ts==="string"?u.ts:`${KF(u)}.000000`,B=I0(C),$="?";if(typeof u.user==="string"){let H=u.user,Y="@"+H;if(!F.has(Y)){let[,q]=await pu(D,H);F.set(Y,q)}$=F.get(Y)??H}else if(typeof u.username==="string")$=u.username;let z=typeof u.text==="string"?u.text:"",G=cu(await Au(D,z,F)).split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slack-term",
3
- "version": "1.19.0",
3
+ "version": "1.19.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/snomiao/slack-term.git"
package/ts/format.ts CHANGED
@@ -3,11 +3,13 @@
3
3
  import { listConversationMembers, listUsers, userInfo, userName, type Json } from "./slack.ts";
4
4
 
5
5
  /** Match an `@handle` token at a word boundary, capturing the handle.
6
- * - The negative lookbehind keeps `@` inside emails (`a@b.com`) from matching.
6
+ * - The negative lookbehind keeps `@` inside emails (`a@b.com`) from matching,
7
+ * and the `<` keeps already-encoded mentions (`<@U0123>`) from being picked up
8
+ * as a handle named after the user ID (Slack resolves those natively).
7
9
  * - Each `.` must be followed by more handle chars, so a trailing sentence dot
8
10
  * (`thanks @taku.`) is left out of the capture. */
9
11
  function mentionRe(): RegExp {
10
- return /(?<![A-Za-z0-9._@-])@([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*)/g;
12
+ return /(?<![A-Za-z0-9._@<-])@([A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*)/g;
11
13
  }
12
14
 
13
15
  /** Lowercase + strip hyphens/underscores/whitespace for loose handle matching. */