agentix-cli 0.83.2 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/{App-3CNSN65B.js → App-HNQCK3BB.js} +2 -2
  2. package/dist/{ChatApp-6RBH5UEC.js → ChatApp-XPCAL4FP.js} +2 -2
  3. package/dist/{agent-C2DHSDPG.js → agent-TRQTWNYE.js} +2 -2
  4. package/dist/{board-dashboard-DJMGIUXC.js → board-dashboard-IDV5SYLW.js} +4 -4
  5. package/dist/{board-dashboard-DJMGIUXC.js.map → board-dashboard-IDV5SYLW.js.map} +1 -1
  6. package/dist/{chunk-TIO5O5KS.js → chunk-3D3B4NQ7.js} +2 -2
  7. package/dist/{chunk-SHYZJU73.js → chunk-3VP3UWNT.js} +2 -2
  8. package/dist/{chunk-DY4GWAG2.js → chunk-4GNAOJ7P.js} +2 -2
  9. package/dist/{chunk-XWON33RF.js → chunk-5DUPIMOI.js} +2 -2
  10. package/dist/{chunk-RMREPXEE.js → chunk-6NE2GLO6.js} +2 -2
  11. package/dist/{chunk-NCY5Z7Y5.js → chunk-AR7CGFAT.js} +171 -171
  12. package/dist/chunk-AR7CGFAT.js.map +1 -0
  13. package/dist/{chunk-SQAZ6XRV.js → chunk-AYHVNISD.js} +2 -2
  14. package/dist/{chunk-DGSLKE3Z.js → chunk-CDC76MRL.js} +2 -2
  15. package/dist/{chunk-J2OPXEID.js → chunk-DA2NTRUR.js} +2 -2
  16. package/dist/{chunk-AO73YQRI.js → chunk-FATAHJG3.js} +2 -2
  17. package/dist/{chunk-O2CQ6HIH.js → chunk-H4EGM4L7.js} +2 -2
  18. package/dist/{chunk-O2CQ6HIH.js.map → chunk-H4EGM4L7.js.map} +1 -1
  19. package/dist/{chunk-QMXRZ7NZ.js → chunk-JU3RIJDW.js} +2 -2
  20. package/dist/{chunk-SL4UN3MQ.js → chunk-MABFDA3G.js} +2 -2
  21. package/dist/{chunk-SL4UN3MQ.js.map → chunk-MABFDA3G.js.map} +1 -1
  22. package/dist/chunk-OFV34UZY.js +5 -0
  23. package/dist/{chunk-QD5HZPDN.js.map → chunk-OFV34UZY.js.map} +1 -1
  24. package/dist/{chunk-7UUPDBXP.js → chunk-QA4RTSKI.js} +11 -11
  25. package/dist/chunk-QA4RTSKI.js.map +1 -0
  26. package/dist/{chunk-TXPRTOON.js → chunk-QFF6ARGN.js} +3 -3
  27. package/dist/{chunk-TXPRTOON.js.map → chunk-QFF6ARGN.js.map} +1 -1
  28. package/dist/{chunk-F2BICD4J.js → chunk-WABEHPU5.js} +2 -2
  29. package/dist/chunk-XL7WTOP5.js +152 -0
  30. package/dist/chunk-XL7WTOP5.js.map +1 -0
  31. package/dist/{chunk-DJ57LID5.js → chunk-Y3C37PF5.js} +2 -2
  32. package/dist/chunk-ZJJJM7AR.js +5 -0
  33. package/dist/{chunk-7R6BHIPA.js.map → chunk-ZJJJM7AR.js.map} +1 -1
  34. package/dist/{chunk-VT7NIJVK.js → chunk-ZVUEJXCY.js} +2 -2
  35. package/dist/{chunk-VT7NIJVK.js.map → chunk-ZVUEJXCY.js.map} +1 -1
  36. package/dist/cli.js +1 -1
  37. package/dist/{client-CGZ3XXAA.js → client-4YL2RDDT.js} +2 -2
  38. package/dist/config-HY6CPDFH.js +2 -0
  39. package/dist/config-mutator-AKAUM6Q6.js +2 -0
  40. package/dist/{doctor-RGUJJURY.js → doctor-BHL44USQ.js} +2 -2
  41. package/dist/index.d.ts +55 -0
  42. package/dist/index.js +1 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/{program-QKNNDRP6.js → program-VSIDVWPL.js} +200 -183
  45. package/dist/program-VSIDVWPL.js.map +1 -0
  46. package/dist/{promote-7BCIFXE7.js → promote-ANCV5DLK.js} +2 -2
  47. package/dist/{query-QHUQDZ3P.js → query-DA65EPSF.js} +2 -2
  48. package/dist/{registry-QJVKEZV6.js → registry-77K6WP3H.js} +2 -2
  49. package/dist/{request-planner-LATURRJL.js → request-planner-IARLBD4R.js} +2 -2
  50. package/dist/{review-candidates-27LHBY44.js → review-candidates-3PML6UYA.js} +2 -2
  51. package/dist/{routing-O6PD6ULG.js → routing-2LKQW4XD.js} +2 -2
  52. package/dist/schedule-tool-P6AGRN5F.js +2 -0
  53. package/dist/scheduler-TJHXFDNW.js +2 -0
  54. package/dist/{seat-PUTTNNVU.js → seat-U4O3OOOZ.js} +2 -2
  55. package/dist/{select-APGSUM4S.js → select-ORDHPTI7.js} +2 -2
  56. package/dist/{set-enabled-5LLEUDTZ.js → set-enabled-4RHEXIE4.js} +2 -2
  57. package/dist/{tool-7JH2ZKED.js → tool-T4IYBXOT.js} +2 -2
  58. package/dist/{tool-DQICJQ6Z.js → tool-ZFXAIC4V.js} +2 -2
  59. package/dist/wiki-2EMSGMLC.js +2 -0
  60. package/package.json +1 -1
  61. package/dist/chunk-7R6BHIPA.js +0 -5
  62. package/dist/chunk-7UUPDBXP.js.map +0 -1
  63. package/dist/chunk-NCY5Z7Y5.js.map +0 -1
  64. package/dist/chunk-QD5HZPDN.js +0 -5
  65. package/dist/chunk-TH7O37GJ.js +0 -152
  66. package/dist/chunk-TH7O37GJ.js.map +0 -1
  67. package/dist/config-PTBPLRVQ.js +0 -2
  68. package/dist/config-mutator-QVETJAFD.js +0 -2
  69. package/dist/program-QKNNDRP6.js.map +0 -1
  70. package/dist/schedule-tool-FHWMYWVQ.js +0 -2
  71. package/dist/scheduler-BCLXHHPJ.js +0 -2
  72. package/dist/wiki-7ZTUI57I.js +0 -2
  73. /package/dist/{App-3CNSN65B.js.map → App-HNQCK3BB.js.map} +0 -0
  74. /package/dist/{ChatApp-6RBH5UEC.js.map → ChatApp-XPCAL4FP.js.map} +0 -0
  75. /package/dist/{agent-C2DHSDPG.js.map → agent-TRQTWNYE.js.map} +0 -0
  76. /package/dist/{chunk-TIO5O5KS.js.map → chunk-3D3B4NQ7.js.map} +0 -0
  77. /package/dist/{chunk-SHYZJU73.js.map → chunk-3VP3UWNT.js.map} +0 -0
  78. /package/dist/{chunk-DY4GWAG2.js.map → chunk-4GNAOJ7P.js.map} +0 -0
  79. /package/dist/{chunk-XWON33RF.js.map → chunk-5DUPIMOI.js.map} +0 -0
  80. /package/dist/{chunk-RMREPXEE.js.map → chunk-6NE2GLO6.js.map} +0 -0
  81. /package/dist/{chunk-SQAZ6XRV.js.map → chunk-AYHVNISD.js.map} +0 -0
  82. /package/dist/{chunk-DGSLKE3Z.js.map → chunk-CDC76MRL.js.map} +0 -0
  83. /package/dist/{chunk-J2OPXEID.js.map → chunk-DA2NTRUR.js.map} +0 -0
  84. /package/dist/{chunk-AO73YQRI.js.map → chunk-FATAHJG3.js.map} +0 -0
  85. /package/dist/{chunk-QMXRZ7NZ.js.map → chunk-JU3RIJDW.js.map} +0 -0
  86. /package/dist/{chunk-F2BICD4J.js.map → chunk-WABEHPU5.js.map} +0 -0
  87. /package/dist/{chunk-DJ57LID5.js.map → chunk-Y3C37PF5.js.map} +0 -0
  88. /package/dist/{client-CGZ3XXAA.js.map → client-4YL2RDDT.js.map} +0 -0
  89. /package/dist/{config-PTBPLRVQ.js.map → config-HY6CPDFH.js.map} +0 -0
  90. /package/dist/{config-mutator-QVETJAFD.js.map → config-mutator-AKAUM6Q6.js.map} +0 -0
  91. /package/dist/{doctor-RGUJJURY.js.map → doctor-BHL44USQ.js.map} +0 -0
  92. /package/dist/{promote-7BCIFXE7.js.map → promote-ANCV5DLK.js.map} +0 -0
  93. /package/dist/{query-QHUQDZ3P.js.map → query-DA65EPSF.js.map} +0 -0
  94. /package/dist/{registry-QJVKEZV6.js.map → registry-77K6WP3H.js.map} +0 -0
  95. /package/dist/{request-planner-LATURRJL.js.map → request-planner-IARLBD4R.js.map} +0 -0
  96. /package/dist/{review-candidates-27LHBY44.js.map → review-candidates-3PML6UYA.js.map} +0 -0
  97. /package/dist/{routing-O6PD6ULG.js.map → routing-2LKQW4XD.js.map} +0 -0
  98. /package/dist/{schedule-tool-FHWMYWVQ.js.map → schedule-tool-P6AGRN5F.js.map} +0 -0
  99. /package/dist/{scheduler-BCLXHHPJ.js.map → scheduler-TJHXFDNW.js.map} +0 -0
  100. /package/dist/{seat-PUTTNNVU.js.map → seat-U4O3OOOZ.js.map} +0 -0
  101. /package/dist/{select-APGSUM4S.js.map → select-ORDHPTI7.js.map} +0 -0
  102. /package/dist/{set-enabled-5LLEUDTZ.js.map → set-enabled-4RHEXIE4.js.map} +0 -0
  103. /package/dist/{tool-7JH2ZKED.js.map → tool-T4IYBXOT.js.map} +0 -0
  104. /package/dist/{tool-DQICJQ6Z.js.map → tool-ZFXAIC4V.js.map} +0 -0
  105. /package/dist/{wiki-7ZTUI57I.js.map → wiki-2EMSGMLC.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import{c as se,d as de,e as J,f as E,g as K,h as D}from"./chunk-O5U5NVLR.js";import{a as ie}from"./chunk-CL53UVOF.js";import{e as ae,g as re,n as oe,p as j}from"./chunk-XIYWXCNU.js";import{a as te,b as ne}from"./chunk-7R6BHIPA.js";import{a as ee}from"./chunk-DJ57LID5.js";import{K as Q,N as Te,X as F,Z,_ as U,ba as q,s as L,w as Ce}from"./chunk-7UUPDBXP.js";import{existsSync as M,readFileSync as fe,writeFileSync as he,appendFileSync as De,mkdirSync as Me}from"fs";import{dirname as Ne,resolve as P}from"path";import{fileURLToPath as Ue}from"url";import{hostname as We}from"os";import{spawn as Oe}from"child_process";q();import{existsSync as ce,readFileSync as le,writeFileSync as Y,copyFileSync as Re}from"fs";import{resolve as pe}from"path";function W(e,t={}){let n=t.configPath||pe(process.cwd(),"agentx.json");if(!ce(n))throw new Error(`agentx.json not found at ${n}`);let a=JSON.parse(le(n,"utf-8")),r=e(a),o=typeof r=="string"?{summary:r}:r,s=JSON.stringify(a,null,2)+`
1
+ import{c as se,d as de,e as J,f as E,g as K,h as D}from"./chunk-O5U5NVLR.js";import{a as ie}from"./chunk-CL53UVOF.js";import{e as ae,g as re,n as oe,p as j}from"./chunk-XIYWXCNU.js";import{a as te,b as ne}from"./chunk-ZJJJM7AR.js";import{a as ee}from"./chunk-Y3C37PF5.js";import{$ as Z,K as Q,P as Te,Z as F,aa as U,da as q,s as L,w as Ce}from"./chunk-QA4RTSKI.js";import{existsSync as M,readFileSync as fe,writeFileSync as he,appendFileSync as De,mkdirSync as Me}from"fs";import{dirname as Ne,resolve as P}from"path";import{fileURLToPath as Ue}from"url";import{hostname as We}from"os";import{spawn as Oe}from"child_process";q();import{existsSync as ce,readFileSync as le,writeFileSync as Y,copyFileSync as Re}from"fs";import{resolve as pe}from"path";function W(e,t={}){let n=t.configPath||pe(process.cwd(),"agentx.json");if(!ce(n))throw new Error(`agentx.json not found at ${n}`);let a=JSON.parse(le(n,"utf-8")),r=e(a),o=typeof r=="string"?{summary:r}:r,s=JSON.stringify(a,null,2)+`
2
2
  `,l=n+".tmp";Y(l,s,"utf-8");try{JSON.parse(le(l,"utf-8"))}catch(p){throw new Error(`config did not round-trip cleanly: ${p.message}`)}let i;return t.skipBackup||(i=`${n}.bak.${Date.now()}`,Re(n,i)),Y(n,s,"utf-8"),t.skipReload||Pe().catch(()=>{}),{summary:o.summary,payload:o.payload,backupPath:i}}function ge(e,t={}){let n=t.configPath||pe(process.cwd(),"agentx.json");if(ce(n)&&!t.overwrite)throw new Error(`agentx.json already exists at ${n}. Pass overwrite=true to replace it.`);return Y(n,JSON.stringify(e,null,2)+`
3
3
  `,"utf-8"),{file:n}}async function Pe(){try{let t=U().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";await fetch(`${t}/reload`,{method:"POST"}).catch(()=>null)}catch{}}function me(e,t){let n=e.configExists?e.agentCount===0?"Add your first agent":"Add another agent":"Set up your team",a=`<header class="ax-topbar">
4
4
  <div class="ax-topbar__left">
@@ -740,5 +740,5 @@ tr:hover td { background: var(--bg-hover); }
740
740
  WHERE person = ? AND (channel IS NULL OR channel != 'a2a')
741
741
  ORDER BY started_at DESC LIMIT ?`).all(t,Math.max(1,Math.min(n,500))).map(r=>({taskId:r.task_id,agentId:r.agent_id,channel:r.channel,chatId:r.chat_id,status:r.status,startedAt:r.started_at,messagePreview:r.message_preview}))}function nn(e,t){return e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'requests'").get()?e.prepare("PRAGMA table_info(requests)").all().some(o=>o.name==="person")?e.prepare(`SELECT id, state, channel, agent_id, text, created_at FROM requests
742
742
  WHERE person = ? AND state IN (${L.map(()=>"?").join(",")})
743
- ORDER BY created_at`).all(t,...L).map(o=>({id:o.id,state:o.state,channel:o.channel,agentId:o.agent_id,text:o.text,createdAt:o.created_at})):[]:[]}Te();var V="member:",it=90,st="members",dt="tailscale-user-login",lt=400,ct=60*60*1e3;function pt(e){let t=e.scopes.find(n=>n.startsWith(V));return t?t.slice(V.length):null}function we(e,t){if(!e)return null;let n=t.verify(e),a=n?pt(n):null;return n&&a?{rec:n,personId:a}:null}function ln(e,t){let n=e.people().find(l=>l.id===t);if(!n)return{ok:!1,error:`No person "${t}". Add them first: agentx people add ${t} --name "\u2026"`};let{token:a,record:r}=e.tokens.create({name:`${n.name} (machine not paired yet)`,scopes:[`${V}${n.id}`],expiresInDays:it}),{code:o,expiresAt:s}=e.codes.create({token:a,tokenId:r.id,name:n.id});return e.members.log({person:n.id,device:r.id,event:"invited"}),{ok:!0,code:o,expiresAt:s,tokenId:r.id,person:n}}var gt="The private network says someone else is connecting from this machine. Ask the owner for a new code.",mt="Too many machines are waiting for the owner's answer. Try again later.",$e=(e,t)=>{let n=e.headers[t];return(Array.isArray(n)?n[0]:n||"").trim()};function Ae(e){let t=e.socket?.remoteAddress||"";return t==="127.0.0.1"||t==="::1"||t==="::ffff:127.0.0.1"}function ut(e){if(!Ae(e))return null;let t=$e(e,dt).toLowerCase();return t?t.slice(0,80):null}function ft(e){let t=e.socket?.remoteAddress||"unknown";if(!Ae(e))return t;let n=$e(e,"x-forwarded-for").split(",")[0].trim();return/^[0-9a-fA-F:.]{2,45}$/.test(n)?n:t}function ht(e){return typeof e=="string"?e.replace(/[^\p{L}\p{N} ._'()-]/gu," ").replace(/\s+/g," ").trim().slice(0,60):""}function vt(e){return e.identities.map(Q).filter(t=>!!t&&t.channel==="tailscale").map(t=>t.value)}async function cn(e,t){let n=Date.now(),a=t.now??Date.now,r=t.log??(m=>console.log(m)),o=ft(e),s=t.limiter.retryAfter(o);if(s>0)return r(`[member] pair-code refused from ${o}: locked out for ${s}s more`),{status:429,body:{error:"too many attempts",retryAfter:s},retryAfter:s};let l=null,i="";try{let m=await oe(e,2048);l=m.code,i=ht(m.machine)}catch{}let p=t.codes.redeem(l),g=p?we(p.token,t.tokens):null;if(await xt(n,t.minMs??lt),!p||!g)return t.limiter.fail(o),r(`[member] pair-code failed from ${o}`),{status:401,body:{error:j}};t.limiter.succeed(o);let{rec:f,personId:d}=g,h=t.people().find(m=>m.id===d);if(!h)return t.tokens.revoke(f.id),t.members.log({person:d,device:f.id,event:"refused",address:o,detail:"person no longer listed"}),r(`[member] pair-code for ${d} refused from ${o}: person no longer listed`),{status:403,body:{error:j}};let u=ut(e),A=vt(h);if(A.length&&(!u||!A.includes(u)))return t.tokens.revoke(f.id),t.members.log({person:d,device:f.id,event:"refused",address:o,detail:`network login ${u??"missing"}; expected ${A.join(" or ")}`}),r(`[member] ${d}: pairing from ${o} refused: the network says "${u??"nobody"}", expected ${A.join(" or ")}`),{status:403,body:{error:gt}};let x=i||"Unnamed machine",y=h.name.slice(0,40),v=re(t.root,{title:`New machine for ${y}`,ask:`From ${o}, ${u?`network login ${u}`:"no network login reported"}. Machine name, as typed there: "${x}". Let it see ${y}'s own work?`,recommend:`Yes if ${y} told you they just paired this machine. No if you did not expect it.`,if_silent:"discard",raised_by:st},{now:a()});return v.ok?(t.members.add({tokenId:f.id,personId:d,name:x,state:"pending",cardId:v.card.id,address:o,...u?{network:u}:{},createdAt:new Date(a()).toISOString()}),t.members.log({person:d,device:f.id,event:"paired",address:o,detail:x}),r(`[member] ${d} paired "${x}" from ${o}; waiting for the owner (card ${v.card.id})`),{status:200,body:{person:d,name:x,state:"pending"},token:p.token}):(t.tokens.revoke(f.id),t.members.log({person:d,device:f.id,event:"refused",address:o,detail:v.error}),r(`[member] ${d}: pairing from ${o} refused: ${v.error}`),{status:503,body:{error:mt}})}var H="this machine is not paired",bt="waiting for the owner to approve this machine";function pn(e,t,n){let a=t.now??Date.now,r=t.log??(g=>console.log(g)),o=we(e,t.tokens);if(!o)return{ok:!1,status:401,error:H};let{rec:s,personId:l}=o,i=t.members.byToken(s.id);if(!i||i.state==="removed"||i.personId!==l)return{ok:!1,status:401,error:H};if(t.people&&!t.people().some(g=>g.id===l))return Se(t,s.id,"person no longer listed"),r(`[member] ${l}: "${i.name}" ended: person no longer listed`),{ok:!1,status:401,error:H};if(i.state==="pending"){let g=i.cardId?ae(t.root,i.cardId):null,f=g?g.status==="decided"?g.verdict:g.status==="expired"?"no":null:null;if(f==="yes")i=t.members.update(s.id,{state:"active",approvedAt:new Date(a()).toISOString()})??i,t.members.log({person:l,device:s.id,event:"approved",detail:g?.decided_by}),r(`[member] ${l}: "${i.name}" approved`);else if(f==="no"){let d=g?.status==="expired"?"the owner did not answer in time":"the owner said no";return t.tokens.revoke(s.id),t.members.update(s.id,{state:"removed",removedAt:new Date(a()).toISOString(),removedReason:d}),t.members.log({person:l,device:s.id,event:"refused",detail:d}),r(`[member] ${l}: "${i.name}" refused: ${d}`),{ok:!1,status:401,error:H}}else return{ok:!1,status:403,error:bt,waiting:!0}}let p=i.lastSeenAt?Date.parse(i.lastSeenAt):0;return n&&(a()-p>=ct||i.lastAddress!==n)&&(i=t.members.update(s.id,{lastSeenAt:new Date(a()).toISOString(),lastAddress:n})??i,t.members.log({person:l,device:s.id,event:"signed-in",address:n})),{ok:!0,device:i,personId:l,rec:s}}function Se(e,t,n="removed by the owner"){let a=e.members.byToken(t);if(!a)return null;e.tokens.revoke(t);let r=e.members.update(t,{state:"removed",removedAt:new Date((e.now??Date.now)()).toISOString(),removedReason:n});return e.members.log({person:a.personId,device:t,event:"removed",detail:n}),r}function gn(e,t){return e.members.devices(t).filter(n=>n.state!=="removed").map(n=>Se(e,n.tokenId,"person removed by the owner")).filter(n=>!!n)}async function xt(e,t){let n=e+t-Date.now();n>0&&await new Promise(a=>setTimeout(a,n))}var Ie=["gitlab","github"];function yt(e,t,n){let a=String(t||"").trim().toLowerCase();if(!Ie.includes(a))throw new Error(`Request status works on ${Ie.join(" and ")}, not on "${t}".`);e.requestStatus=e.requestStatus&&typeof e.requestStatus=="object"?e.requestStatus:{};let r=Array.isArray(e.requestStatus.channels)?e.requestStatus.channels.map(o=>String(o).toLowerCase()):[];return e.requestStatus.channels=n?[...new Set([...r,a])]:r.filter(o=>o!==a),`request status on ${a} is ${n?"on":"off"}`}function fn(e){return Array.isArray(e?.requestStatus?.channels)?e.requestStatus.channels.map(t=>String(t).toLowerCase()):[]}function hn(e){let{summary:t}=W(n=>yt(n,e?.channel,!!e?.enabled));return{summary:t}}var kt="https://ntfy.sh";function bn(e){return{enabled:!!e?.enabled,server:e?.server||kt,topicSet:!!e?.topic,tokenSet:!!e?.token}}function xn(e,t){let n={...e??{}};if("enabled"in t&&(n.enabled=!!t.enabled),"server"in t){let a=String(t.server).trim().replace(/\/+$/,"");if(!/^https?:\/\/\S+$/.test(a))throw new Error("ntfy server must be an http(s) URL");n.server=a}if("topic"in t){let a=String(t.topic).trim();if(!a)throw new Error("ntfy topic cannot be empty");n.topic=a}if("token"in t){let a=String(t.token??"").trim();a?n.token=a:delete n.token}if(n.enabled&&!n.topic)throw new Error("set a topic before enabling ntfy");return n}export{W as a,ve as b,Nt as c,Ut as d,Wt as e,Ft as f,qt as g,jt as h,tn as i,nn as j,it as k,ln as l,ft as m,cn as n,pn as o,Se as p,gn as q,Ie as r,yt as s,fn as t,hn as u,bn as v,xn as w,rt as x,Qt as y};
744
- //# sourceMappingURL=chunk-TXPRTOON.js.map
743
+ ORDER BY created_at`).all(t,...L).map(o=>({id:o.id,state:o.state,channel:o.channel,agentId:o.agent_id,text:o.text,createdAt:o.created_at})):[]:[]}Te();var V="member:",it=90,st="members",dt="tailscale-user-login",lt=400,ct=60*60*1e3;function pt(e){let t=e.scopes.find(n=>n.startsWith(V));return t?t.slice(V.length):null}function we(e,t){if(!e)return null;let n=t.verify(e),a=n?pt(n):null;return n&&a?{rec:n,personId:a}:null}function ln(e,t){let n=e.people().find(l=>l.id===t);if(!n)return{ok:!1,error:`No person "${t}". Add them first: agentx people add ${t} --name "\u2026"`};let{token:a,record:r}=e.tokens.create({name:`${n.name} (machine not paired yet)`,scopes:[`${V}${n.id}`],expiresInDays:it}),{code:o,expiresAt:s}=e.codes.create({token:a,tokenId:r.id,name:n.id});return e.members.log({person:n.id,device:r.id,event:"invited"}),{ok:!0,code:o,expiresAt:s,tokenId:r.id,person:n}}var gt="The private network says someone else is connecting from this machine. Ask the owner for a new code.",mt="Too many machines are waiting for the owner's answer. Try again later.",$e=(e,t)=>{let n=e.headers[t];return(Array.isArray(n)?n[0]:n||"").trim()};function Ae(e){let t=e.socket?.remoteAddress||"";return t==="127.0.0.1"||t==="::1"||t==="::ffff:127.0.0.1"}function ut(e){if(!Ae(e))return null;let t=$e(e,dt).toLowerCase();return t?t.slice(0,80):null}function ft(e){let t=e.socket?.remoteAddress||"unknown";if(!Ae(e))return t;let n=$e(e,"x-forwarded-for").split(",").pop().trim();return/^[0-9a-fA-F:.]{2,45}$/.test(n)?n:t}function ht(e){return typeof e=="string"?e.replace(/[^\p{L}\p{N} ._'()-]/gu," ").replace(/\s+/g," ").trim().slice(0,60):""}function vt(e){return e.identities.map(Q).filter(t=>!!t&&t.channel==="tailscale").map(t=>t.value)}async function cn(e,t){let n=Date.now(),a=t.now??Date.now,r=t.log??(m=>console.log(m)),o=ft(e),s=t.limiter.retryAfter(o);if(s>0)return r(`[member] pair-code refused from ${o}: locked out for ${s}s more`),{status:429,body:{error:"too many attempts",retryAfter:s},retryAfter:s};let l=null,i="";try{let m=await oe(e,2048);l=m.code,i=ht(m.machine)}catch{}let p=t.codes.redeem(l),g=p?we(p.token,t.tokens):null;if(await xt(n,t.minMs??lt),!p||!g)return t.limiter.fail(o),r(`[member] pair-code failed from ${o}`),{status:401,body:{error:j}};t.limiter.succeed(o);let{rec:f,personId:d}=g,h=t.people().find(m=>m.id===d);if(!h)return t.tokens.revoke(f.id),t.members.log({person:d,device:f.id,event:"refused",address:o,detail:"person no longer listed"}),r(`[member] pair-code for ${d} refused from ${o}: person no longer listed`),{status:403,body:{error:j}};let u=ut(e),A=vt(h);if(A.length&&(!u||!A.includes(u)))return t.tokens.revoke(f.id),t.members.log({person:d,device:f.id,event:"refused",address:o,detail:`network login ${u??"missing"}; expected ${A.join(" or ")}`}),r(`[member] ${d}: pairing from ${o} refused: the network says "${u??"nobody"}", expected ${A.join(" or ")}`),{status:403,body:{error:gt}};let x=i||"Unnamed machine",y=h.name.slice(0,40),v=re(t.root,{title:`New machine for ${y}`,ask:`From ${o}, ${u?`network login ${u}`:"no network login reported"}. Machine name, as typed there: "${x}". Let it see ${y}'s own work?`,recommend:`Yes if ${y} told you they just paired this machine. No if you did not expect it.`,if_silent:"discard",raised_by:st},{now:a()});return v.ok?(t.members.add({tokenId:f.id,personId:d,name:x,state:"pending",cardId:v.card.id,address:o,...u?{network:u}:{},createdAt:new Date(a()).toISOString()}),t.members.log({person:d,device:f.id,event:"paired",address:o,detail:x}),r(`[member] ${d} paired "${x}" from ${o}; waiting for the owner (card ${v.card.id})`),{status:200,body:{person:d,name:x,state:"pending"},token:p.token}):(t.tokens.revoke(f.id),t.members.log({person:d,device:f.id,event:"refused",address:o,detail:v.error}),r(`[member] ${d}: pairing from ${o} refused: ${v.error}`),{status:503,body:{error:mt}})}var H="this machine is not paired",bt="waiting for the owner to approve this machine";function pn(e,t,n){let a=t.now??Date.now,r=t.log??(g=>console.log(g)),o=we(e,t.tokens);if(!o)return{ok:!1,status:401,error:H};let{rec:s,personId:l}=o,i=t.members.byToken(s.id);if(!i||i.state==="removed"||i.personId!==l)return{ok:!1,status:401,error:H};if(t.people&&!t.people().some(g=>g.id===l))return Se(t,s.id,"person no longer listed"),r(`[member] ${l}: "${i.name}" ended: person no longer listed`),{ok:!1,status:401,error:H};if(i.state==="pending"){let g=i.cardId?ae(t.root,i.cardId):null,f=g?g.status==="decided"?g.verdict:g.status==="expired"?"no":null:null;if(f==="yes")i=t.members.update(s.id,{state:"active",approvedAt:new Date(a()).toISOString()})??i,t.members.log({person:l,device:s.id,event:"approved",detail:g?.decided_by}),r(`[member] ${l}: "${i.name}" approved`);else if(f==="no"){let d=g?.status==="expired"?"the owner did not answer in time":"the owner said no";return t.tokens.revoke(s.id),t.members.update(s.id,{state:"removed",removedAt:new Date(a()).toISOString(),removedReason:d}),t.members.log({person:l,device:s.id,event:"refused",detail:d}),r(`[member] ${l}: "${i.name}" refused: ${d}`),{ok:!1,status:401,error:H}}else return{ok:!1,status:403,error:bt,waiting:!0}}let p=i.lastSeenAt?Date.parse(i.lastSeenAt):0;return n&&(a()-p>=ct||i.lastAddress!==n)&&(i=t.members.update(s.id,{lastSeenAt:new Date(a()).toISOString(),lastAddress:n})??i,t.members.log({person:l,device:s.id,event:"signed-in",address:n})),{ok:!0,device:i,personId:l,rec:s}}function Se(e,t,n="removed by the owner"){let a=e.members.byToken(t);if(!a)return null;e.tokens.revoke(t);let r=e.members.update(t,{state:"removed",removedAt:new Date((e.now??Date.now)()).toISOString(),removedReason:n});return e.members.log({person:a.personId,device:t,event:"removed",detail:n}),r}function gn(e,t){return e.members.devices(t).filter(n=>n.state!=="removed").map(n=>Se(e,n.tokenId,"person removed by the owner")).filter(n=>!!n)}async function xt(e,t){let n=e+t-Date.now();n>0&&await new Promise(a=>setTimeout(a,n))}var Ie=["gitlab","github"];function yt(e,t,n){let a=String(t||"").trim().toLowerCase();if(!Ie.includes(a))throw new Error(`Request status works on ${Ie.join(" and ")}, not on "${t}".`);e.requestStatus=e.requestStatus&&typeof e.requestStatus=="object"?e.requestStatus:{};let r=Array.isArray(e.requestStatus.channels)?e.requestStatus.channels.map(o=>String(o).toLowerCase()):[];return e.requestStatus.channels=n?[...new Set([...r,a])]:r.filter(o=>o!==a),`request status on ${a} is ${n?"on":"off"}`}function fn(e){return Array.isArray(e?.requestStatus?.channels)?e.requestStatus.channels.map(t=>String(t).toLowerCase()):[]}function hn(e){let{summary:t}=W(n=>yt(n,e?.channel,!!e?.enabled));return{summary:t}}var kt="https://ntfy.sh";function bn(e){return{enabled:!!e?.enabled,server:e?.server||kt,topicSet:!!e?.topic,tokenSet:!!e?.token}}function xn(e,t){let n={...e??{}};if("enabled"in t&&(n.enabled=!!t.enabled),"server"in t){let a=String(t.server).trim().replace(/\/+$/,"");if(!/^https?:\/\/\S+$/.test(a))throw new Error("ntfy server must be an http(s) URL");n.server=a}if("topic"in t){let a=String(t.topic).trim();if(!a)throw new Error("ntfy topic cannot be empty");n.topic=a}if("token"in t){let a=String(t.token??"").trim();a?n.token=a:delete n.token}if(n.enabled&&!n.topic)throw new Error("set a topic before enabling ntfy");return n}export{W as a,ve as b,Nt as c,Ut as d,Wt as e,Ft as f,qt as g,jt as h,tn as i,nn as j,it as k,ln as l,ft as m,cn as n,pn as o,Se as p,gn as q,Ie as r,yt as s,fn as t,hn as u,bn as v,xn as w,rt as x,Qt as y};
744
+ //# sourceMappingURL=chunk-QFF6ARGN.js.map