@agentty-app/pair 2.7.12
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/README.md +24 -0
- package/bin/agentty-host.js +11 -0
- package/dist/cli.js +79 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# `@agentty-app/pair`
|
|
2
|
+
|
|
3
|
+
Small bootstrap CLI for pairing a host with AgenTTY.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx -y @agentty-app/pair
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Current commands:
|
|
12
|
+
|
|
13
|
+
- `pair` - create a pairing session, render a QR + short code, optionally offer the host's Tailscale MagicDNS hostname when Tailscale is installed, wait for AgenTTY to claim it, authorize the claimed SSH public key for the current user, collect the host SSH public keys from local `sshd`, provision the persistent AgenTTY relay connector when the backend offers a bootstrap token, then finalize the session with host metadata
|
|
14
|
+
- `doctor` - placeholder diagnostics entrypoint
|
|
15
|
+
- `repair` - placeholder repair entrypoint
|
|
16
|
+
- `unpair` - placeholder unpair entrypoint
|
|
17
|
+
|
|
18
|
+
## Local development
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm test
|
|
22
|
+
npm run build
|
|
23
|
+
node ./bin/agentty-host.js
|
|
24
|
+
```
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
var pt=Object.create;var me=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var ht=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var T=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var St=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of gt(t))!yt.call(e,o)&&o!==n&&me(e,o,{get:()=>t[o],enumerable:!(r=ft(t,o))||r.enumerable});return e};var Pt=(e,t,n)=>(n=e!=null?pt(ht(e)):{},St(t||!e||!e.__esModule?me(n,"default",{value:e,enumerable:!0}):n,e));var V=T((Fn,fe)=>{fe.exports={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8}});var ye=T((Kn,he)=>{var wt=V();function ge(e){this.mode=wt.MODE_8BIT_BYTE,this.data=e}ge.prototype={getLength:function(){return this.data.length},write:function(e){for(var t=0;t<this.data.length;t++)e.put(this.data.charCodeAt(t),8)}};he.exports=ge});var W=T(($n,Se)=>{var _={glog:function(e){if(e<1)throw new Error("glog("+e+")");return _.LOG_TABLE[e]},gexp:function(e){for(;e<0;)e+=255;for(;e>=256;)e-=255;return _.EXP_TABLE[e]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(g=0;g<8;g++)_.EXP_TABLE[g]=1<<g;var g;for(g=8;g<256;g++)_.EXP_TABLE[g]=_.EXP_TABLE[g-4]^_.EXP_TABLE[g-5]^_.EXP_TABLE[g-6]^_.EXP_TABLE[g-8];var g;for(g=0;g<255;g++)_.LOG_TABLE[_.EXP_TABLE[g]]=g;var g;Se.exports=_});var q=T((jn,Pe)=>{var I=W();function $(e,t){if(e.length===void 0)throw new Error(e.length+"/"+t);for(var n=0;n<e.length&&e[n]===0;)n++;this.num=new Array(e.length-n+t);for(var r=0;r<e.length-n;r++)this.num[r]=e[r+n]}$.prototype={get:function(e){return this.num[e]},getLength:function(){return this.num.length},multiply:function(e){for(var t=new Array(this.getLength()+e.getLength()-1),n=0;n<this.getLength();n++)for(var r=0;r<e.getLength();r++)t[n+r]^=I.gexp(I.glog(this.get(n))+I.glog(e.get(r)));return new $(t,0)},mod:function(e){if(this.getLength()-e.getLength()<0)return this;for(var t=I.glog(this.get(0))-I.glog(e.get(0)),n=new Array(this.getLength()),r=0;r<this.getLength();r++)n[r]=this.get(r);for(var o=0;o<e.getLength();o++)n[o]^=I.gexp(I.glog(e.get(o))+t);return new $(n,0).mod(e)}};Pe.exports=$});var ve=T((zn,we)=>{we.exports={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7}});var _e=T((Gn,Te)=>{var P=V(),Ee=q(),vt=W(),A=ve(),h={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(e){for(var t=e<<10;h.getBCHDigit(t)-h.getBCHDigit(h.G15)>=0;)t^=h.G15<<h.getBCHDigit(t)-h.getBCHDigit(h.G15);return(e<<10|t)^h.G15_MASK},getBCHTypeNumber:function(e){for(var t=e<<12;h.getBCHDigit(t)-h.getBCHDigit(h.G18)>=0;)t^=h.G18<<h.getBCHDigit(t)-h.getBCHDigit(h.G18);return e<<12|t},getBCHDigit:function(e){for(var t=0;e!==0;)t++,e>>>=1;return t},getPatternPosition:function(e){return h.PATTERN_POSITION_TABLE[e-1]},getMask:function(e,t,n){switch(e){case A.PATTERN000:return(t+n)%2===0;case A.PATTERN001:return t%2===0;case A.PATTERN010:return n%3===0;case A.PATTERN011:return(t+n)%3===0;case A.PATTERN100:return(Math.floor(t/2)+Math.floor(n/3))%2===0;case A.PATTERN101:return t*n%2+t*n%3===0;case A.PATTERN110:return(t*n%2+t*n%3)%2===0;case A.PATTERN111:return(t*n%3+(t+n)%2)%2===0;default:throw new Error("bad maskPattern:"+e)}},getErrorCorrectPolynomial:function(e){for(var t=new Ee([1],0),n=0;n<e;n++)t=t.multiply(new Ee([1,vt.gexp(n)],0));return t},getLengthInBits:function(e,t){if(1<=t&&t<10)switch(e){case P.MODE_NUMBER:return 10;case P.MODE_ALPHA_NUM:return 9;case P.MODE_8BIT_BYTE:return 8;case P.MODE_KANJI:return 8;default:throw new Error("mode:"+e)}else if(t<27)switch(e){case P.MODE_NUMBER:return 12;case P.MODE_ALPHA_NUM:return 11;case P.MODE_8BIT_BYTE:return 16;case P.MODE_KANJI:return 10;default:throw new Error("mode:"+e)}else if(t<41)switch(e){case P.MODE_NUMBER:return 14;case P.MODE_ALPHA_NUM:return 13;case P.MODE_8BIT_BYTE:return 16;case P.MODE_KANJI:return 12;default:throw new Error("mode:"+e)}else throw new Error("type:"+t)},getLostPoint:function(e){var t=e.getModuleCount(),n=0,r=0,o=0;for(r=0;r<t;r++)for(o=0;o<t;o++){for(var i=0,s=e.isDark(r,o),a=-1;a<=1;a++)if(!(r+a<0||t<=r+a))for(var l=-1;l<=1;l++)o+l<0||t<=o+l||a===0&&l===0||s===e.isDark(r+a,o+l)&&i++;i>5&&(n+=3+i-5)}for(r=0;r<t-1;r++)for(o=0;o<t-1;o++){var c=0;e.isDark(r,o)&&c++,e.isDark(r+1,o)&&c++,e.isDark(r,o+1)&&c++,e.isDark(r+1,o+1)&&c++,(c===0||c===4)&&(n+=3)}for(r=0;r<t;r++)for(o=0;o<t-6;o++)e.isDark(r,o)&&!e.isDark(r,o+1)&&e.isDark(r,o+2)&&e.isDark(r,o+3)&&e.isDark(r,o+4)&&!e.isDark(r,o+5)&&e.isDark(r,o+6)&&(n+=40);for(o=0;o<t;o++)for(r=0;r<t-6;r++)e.isDark(r,o)&&!e.isDark(r+1,o)&&e.isDark(r+2,o)&&e.isDark(r+3,o)&&e.isDark(r+4,o)&&!e.isDark(r+5,o)&&e.isDark(r+6,o)&&(n+=40);var d=0;for(o=0;o<t;o++)for(r=0;r<t;r++)e.isDark(r,o)&&d++;var p=Math.abs(100*d/t/t-50)/5;return n+=p*10,n}};Te.exports=h});var X=T((Yn,Ce)=>{Ce.exports={L:1,M:0,Q:3,H:2}});var Re=T((Qn,Le)=>{var j=X();function L(e,t){this.totalCount=e,this.dataCount=t}L.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];L.getRSBlocks=function(e,t){var n=L.getRsBlockTable(e,t);if(n===void 0)throw new Error("bad rs block @ typeNumber:"+e+"/errorCorrectLevel:"+t);for(var r=n.length/3,o=[],i=0;i<r;i++)for(var s=n[i*3+0],a=n[i*3+1],l=n[i*3+2],c=0;c<s;c++)o.push(new L(a,l));return o};L.getRsBlockTable=function(e,t){switch(t){case j.L:return L.RS_BLOCK_TABLE[(e-1)*4+0];case j.M:return L.RS_BLOCK_TABLE[(e-1)*4+1];case j.Q:return L.RS_BLOCK_TABLE[(e-1)*4+2];case j.H:return L.RS_BLOCK_TABLE[(e-1)*4+3];default:return}};Le.exports=L});var be=T((Jn,ke)=>{function Ae(){this.buffer=[],this.length=0}Ae.prototype={get:function(e){var t=Math.floor(e/8);return(this.buffer[t]>>>7-e%8&1)==1},put:function(e,t){for(var n=0;n<t;n++)this.putBit((e>>>t-n-1&1)==1)},getLengthInBits:function(){return this.length},putBit:function(e){var t=Math.floor(this.length/8);this.buffer.length<=t&&this.buffer.push(0),e&&(this.buffer[t]|=128>>>this.length%8),this.length++}};ke.exports=Ae});var He=T((Vn,Ne)=>{var Et=ye(),k=_e(),Tt=q(),De=Re(),Ie=be();function R(e,t){this.typeNumber=e,this.errorCorrectLevel=t,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}R.prototype={addData:function(e){var t=new Et(e);this.dataList.push(t),this.dataCache=null},isDark:function(e,t){if(e<0||this.moduleCount<=e||t<0||this.moduleCount<=t)throw new Error(e+","+t);return this.modules[e][t]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var e=1;for(e=1;e<40;e++){for(var t=De.getRSBlocks(e,this.errorCorrectLevel),n=new Ie,r=0,o=0;o<t.length;o++)r+=t[o].dataCount;for(var i=0;i<this.dataList.length;i++){var s=this.dataList[i];n.put(s.mode,4),n.put(s.getLength(),k.getLengthInBits(s.mode,e)),s.write(n)}if(n.getLengthInBits()<=r*8)break}this.typeNumber=e}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(e,t){this.moduleCount=this.typeNumber*4+17,this.modules=new Array(this.moduleCount);for(var n=0;n<this.moduleCount;n++){this.modules[n]=new Array(this.moduleCount);for(var r=0;r<this.moduleCount;r++)this.modules[n][r]=null}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(e,t),this.typeNumber>=7&&this.setupTypeNumber(e),this.dataCache===null&&(this.dataCache=R.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,t)},setupPositionProbePattern:function(e,t){for(var n=-1;n<=7;n++)if(!(e+n<=-1||this.moduleCount<=e+n))for(var r=-1;r<=7;r++)t+r<=-1||this.moduleCount<=t+r||(0<=n&&n<=6&&(r===0||r===6)||0<=r&&r<=6&&(n===0||n===6)||2<=n&&n<=4&&2<=r&&r<=4?this.modules[e+n][t+r]=!0:this.modules[e+n][t+r]=!1)},getBestMaskPattern:function(){for(var e=0,t=0,n=0;n<8;n++){this.makeImpl(!0,n);var r=k.getLostPoint(this);(n===0||e>r)&&(e=r,t=n)}return t},createMovieClip:function(e,t,n){var r=e.createEmptyMovieClip(t,n),o=1;this.make();for(var i=0;i<this.modules.length;i++)for(var s=i*o,a=0;a<this.modules[i].length;a++){var l=a*o,c=this.modules[i][a];c&&(r.beginFill(0,100),r.moveTo(l,s),r.lineTo(l+o,s),r.lineTo(l+o,s+o),r.lineTo(l,s+o),r.endFill())}return r},setupTimingPattern:function(){for(var e=8;e<this.moduleCount-8;e++)this.modules[e][6]===null&&(this.modules[e][6]=e%2===0);for(var t=8;t<this.moduleCount-8;t++)this.modules[6][t]===null&&(this.modules[6][t]=t%2===0)},setupPositionAdjustPattern:function(){for(var e=k.getPatternPosition(this.typeNumber),t=0;t<e.length;t++)for(var n=0;n<e.length;n++){var r=e[t],o=e[n];if(this.modules[r][o]===null)for(var i=-2;i<=2;i++)for(var s=-2;s<=2;s++)Math.abs(i)===2||Math.abs(s)===2||i===0&&s===0?this.modules[r+i][o+s]=!0:this.modules[r+i][o+s]=!1}},setupTypeNumber:function(e){for(var t=k.getBCHTypeNumber(this.typeNumber),n,r=0;r<18;r++)n=!e&&(t>>r&1)===1,this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=n;for(var o=0;o<18;o++)n=!e&&(t>>o&1)===1,this.modules[o%3+this.moduleCount-8-3][Math.floor(o/3)]=n},setupTypeInfo:function(e,t){for(var n=this.errorCorrectLevel<<3|t,r=k.getBCHTypeInfo(n),o,i=0;i<15;i++)o=!e&&(r>>i&1)===1,i<6?this.modules[i][8]=o:i<8?this.modules[i+1][8]=o:this.modules[this.moduleCount-15+i][8]=o;for(var s=0;s<15;s++)o=!e&&(r>>s&1)===1,s<8?this.modules[8][this.moduleCount-s-1]=o:s<9?this.modules[8][15-s-1+1]=o:this.modules[8][15-s-1]=o;this.modules[this.moduleCount-8][8]=!e},mapData:function(e,t){for(var n=-1,r=this.moduleCount-1,o=7,i=0,s=this.moduleCount-1;s>0;s-=2)for(s===6&&s--;;){for(var a=0;a<2;a++)if(this.modules[r][s-a]===null){var l=!1;i<e.length&&(l=(e[i]>>>o&1)===1);var c=k.getMask(t,r,s-a);c&&(l=!l),this.modules[r][s-a]=l,o--,o===-1&&(i++,o=7)}if(r+=n,r<0||this.moduleCount<=r){r-=n,n=-n;break}}}};R.PAD0=236;R.PAD1=17;R.createData=function(e,t,n){for(var r=De.getRSBlocks(e,t),o=new Ie,i=0;i<n.length;i++){var s=n[i];o.put(s.mode,4),o.put(s.getLength(),k.getLengthInBits(s.mode,e)),s.write(o)}for(var a=0,l=0;l<r.length;l++)a+=r[l].dataCount;if(o.getLengthInBits()>a*8)throw new Error("code length overflow. ("+o.getLengthInBits()+">"+a*8+")");for(o.getLengthInBits()+4<=a*8&&o.put(0,4);o.getLengthInBits()%8!==0;)o.putBit(!1);for(;!(o.getLengthInBits()>=a*8||(o.put(R.PAD0,8),o.getLengthInBits()>=a*8));)o.put(R.PAD1,8);return R.createBytes(o,r)};R.createBytes=function(e,t){for(var n=0,r=0,o=0,i=new Array(t.length),s=new Array(t.length),a=0;a<t.length;a++){var l=t[a].dataCount,c=t[a].totalCount-l;r=Math.max(r,l),o=Math.max(o,c),i[a]=new Array(l);for(var d=0;d<i[a].length;d++)i[a][d]=255&e.buffer[d+n];n+=l;var p=k.getErrorCorrectPolynomial(c),v=new Tt(i[a],p.getLength()-1),u=v.mod(p);s[a]=new Array(p.getLength()-1);for(var f=0;f<s[a].length;f++){var D=f+u.getLength()-s[a].length;s[a][f]=D>=0?u.get(D):0}}for(var U=0,O=0;O<t.length;O++)U+=t[O].totalCount;for(var E=new Array(U),de=0,B=0;B<r;B++)for(var M=0;M<t.length;M++)B<i[M].length&&(E[de++]=i[M][B]);for(var F=0;F<o;F++)for(var K=0;K<t.length;K++)F<s[K].length&&(E[de++]=s[K][F]);return E};Ne.exports=R});var Oe=T((Wn,xe)=>{var _t=He(),Ue=X(),Ct="\x1B[40m \x1B[0m",z="\x1B[47m \x1B[0m",Lt=function(e){return e?Ct:z},Z=function(e){return{times:function(t){return new Array(t).join(e)}}},Rt=function(e,t){for(var n=new Array(e),r=0;r<e;r++)n[r]=t;return n};xe.exports={error:Ue.L,generate:function(e,t,n){typeof t=="function"&&(n=t,t={});var r=new _t(-1,this.error);r.addData(e),r.make();var o="";if(t&&t.small){var i=!0,s=!1,a=r.getModuleCount(),l=r.modules.slice(),c=a%2===1;c&&l.push(Rt(a,s));var d={WHITE_ALL:"\u2588",WHITE_BLACK:"\u2580",BLACK_WHITE:"\u2584",BLACK_ALL:" "},p=Z(d.BLACK_WHITE).times(a+3),v=Z(d.WHITE_BLACK).times(a+3);o+=p+`
|
|
2
|
+
`;for(var u=0;u<a;u+=2){o+=d.WHITE_ALL;for(var f=0;f<a;f++)l[u][f]===s&&l[u+1][f]===s?o+=d.WHITE_ALL:l[u][f]===s&&l[u+1][f]===i?o+=d.WHITE_BLACK:l[u][f]===i&&l[u+1][f]===s?o+=d.BLACK_WHITE:o+=d.BLACK_ALL;o+=d.WHITE_ALL+`
|
|
3
|
+
`}c||(o+=v)}else{var D=Z(z).times(r.getModuleCount()+3);o+=D+`
|
|
4
|
+
`,r.modules.forEach(function(U){o+=z,o+=U.map(Lt).join(""),o+=z+`
|
|
5
|
+
`}),o+=D}n?n(o):console.log(o)},setErrorLevel:function(e){this.error=Ue[e]||this.error}}});async function pe(e,t){return t.stdout.write(`AgenTTY Host doctor is not implemented yet.
|
|
6
|
+
`),0}var ct=Pt(Oe(),1);import{createInterface as kn}from"node:readline/promises";import{promises as At}from"node:fs";import kt from"node:os";import Me from"node:path";function G(e,t){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code===t}function Be(e){return typeof e=="object"&&e!==null&&"stdout"in e&&typeof e.stdout=="string"?e.stdout:""}async function Fe(e,{fsImpl:t=At,homeDirectory:n=kt.homedir()}={}){let r=bt(e),o=ee(r),i=Me.join(n,".ssh"),s=Me.join(i,"authorized_keys");await t.mkdir(i,{recursive:!0,mode:448}),await t.chmod(i,448);let a="";try{a=await t.readFile(s,"utf8")}catch(c){if(!G(c,"ENOENT"))throw c;await t.writeFile(s,"",{mode:384})}let l=a.split(/\r?\n/u).map(c=>c.trim()).filter(Boolean).some(c=>{try{return ee(c)===o}catch{return!1}});if(!l){let c=a.length===0||a.endsWith(`
|
|
7
|
+
`)?"":`
|
|
8
|
+
`;await t.appendFile(s,`${c}${r}
|
|
9
|
+
`,"utf8")}return await t.chmod(s,384),{authorizedKeysPath:s,alreadyPresent:l}}function bt(e){let t=e.trim();if(!t)throw new Error("Pairing response did not include a public key.");let n=t.split(/\r?\n/u).map(o=>o.trim()).filter(Boolean);if(n.length!==1)throw new Error("Pairing response contained an invalid public key.");let[r]=n;if(!r)throw new Error("Pairing response contained an invalid public key.");return ee(r),r}function ee(e){let t=e.trim().split(/\s+/u);if(t.length<2)throw new Error("Invalid OpenSSH public key.");let[n,r]=t;if(!n||!r||!Dt(n))throw new Error("Invalid OpenSSH public key.");return r}function Dt(e){return e.startsWith("ssh-")||e.startsWith("ecdsa-")||e.startsWith("sk-")}var It="https://agentty.esmadil.se",te="AGENTTY_BACKEND_URL",Nt="AGENTTY_NOTIFY_RELAY_URL";function Ke(e=process.env){let t=e[te]??e[Nt];if(!t)return new URL(It);let n;try{n=new URL(t)}catch{throw new Error(`Invalid ${te} value.`)}if(!Ht(n))throw new Error(`Invalid ${te} value.`);return n}function Ht(e){let t=e.hostname.toLowerCase();return t?e.protocol==="https:"?!0:e.protocol==="http:"&&(t==="localhost"||t==="127.0.0.1"||t==="::1"):!1}import{execFile as xt}from"node:child_process";import{promisify as Ot}from"node:util";var $e="@agentty-app/pair",Ut="2.7.12"?.trim(),je="929f2b514322"?.trim(),or="2.7.12"?.trim(),Y=Ut||je||"dev",ne=je||Y;var ze=22,x={linux:"linux",macos:"macos"},b={accountLookup:"account_lookup",envUser:"env_user",idCommand:"id_command",whoamiCommand:"whoami_command"},re={container:"container",wsl:"wsl"},C={fqdn:"fqdn",localDomain:"local_domain",singleLabel:"single_label",tailscaleFQDN:"tailscale_fqdn",tailscaleShort:"tailscale_short"},S={envHostname:"env_hostname",hostname:"hostname",hostnameFQDN:"hostname_fqdn",legacyHostnameCandidates:"legacy_hostname_candidates",osHostname:"os_hostname",scutilHostname:"scutil_hostname",scutilLocalhostname:"scutil_localhostname",tailscaleMagicDNS:"tailscale_magicdns",tailscaleShort:"tailscale_short"},w={claimed:"claimed",completed:"completed",expired:"expired",failed:"failed",pending:"pending"};function Q(e){let t=e.toLowerCase();return t.endsWith(".ts.net")&&t.includes(".")}function Ge(e){return e.endsWith(".local")||e.endsWith(".localdomain")}function Ye(e){return e.includes(".")}function Qe(e){let t=e?.trim();return t?t.endsWith(".")?t.slice(0,-1):t:null}function Je(e){if(!e)return null;if(!Q(e))return e;let[t]=e.split(".",1);return t?.trim()||e}var Bt=Ot(xt),Mt=new Set(["id","user","username"]),Ve={[C.tailscaleShort]:0,[C.tailscaleFQDN]:1,[C.fqdn]:2,[C.localDomain]:3,[C.singleLabel]:4};async function Xe({env:e=process.env,execFileImpl:t=Bt,hostname:n,platform:r=process.platform}={}){let o=Ft(r),i=await Kt({env:e,execFileImpl:t,platform:o}),s=await $t({env:e,execFileImpl:t,hostname:n,platform:o}),a=zt(e,o);return{detectedUsername:i.value,detectedUsernameSource:i.source,detectedUsernameSuspicious:i.suspicious,hostCandidates:s,hostEnvironmentFlags:a,hostnameCandidates:s.map(l=>l.value),platform:o,port:ze}}function ie(e){let t=[],n=new Set;for(let o of e){let i=Ze(typeof o=="string"?o:o?.value);if(!i)continue;let s=i.toLowerCase();n.has(s)||(n.add(s),t.push({value:i,source:typeof o=="string"?null:o?.source??null}))}let r=new Set(t.map(o=>o.value).filter(Q).map(o=>o.split(".",1)[0]?.trim()?.toLowerCase()).filter(o=>!!o));return t.map((o,i)=>({...o,index:i,kind:Qt(o,r)})).sort((o,i)=>{let s=Ve[o.kind]-Ve[i.kind];return s!==0?s:o.index-i.index}).map((o,i)=>({value:o.value,kind:o.kind,source:o.source,rank:i+1}))}function Ft(e){switch(e){case"darwin":return x.macos;case"linux":return x.linux;default:throw new Error("@agentty-app/pair only supports macOS and Linux.")}}async function Kt({env:e,execFileImpl:t,platform:n}){let r=await Gt(t),o=r?await Yt({execFileImpl:t,platform:n,uid:r}):null,i=await qe(t,"id",["-un"]),s=await qe(t,"whoami",[]),a=et(e.USER),l=new Set([o,i.value,s.value,a.value].filter(d=>!!d).map(d=>d.toLowerCase())),c=null;if(o&&(c={value:o,source:b.accountLookup,suspicious:!1}),c==null&&i.value&&s.value&&i.value===s.value&&(c={value:i.value,source:b.idCommand,suspicious:!1}),c==null&&i.value&&a.value&&i.value===a.value&&(c={value:i.value,source:b.idCommand,suspicious:!1}),c==null&&s.value&&a.value&&s.value===a.value&&(c={value:s.value,source:b.whoamiCommand,suspicious:!1}),c==null&&i.value&&(c={value:i.value,source:b.idCommand,suspicious:!0}),c==null&&s.value&&(c={value:s.value,source:b.whoamiCommand,suspicious:!0}),c==null&&a.value&&(c={value:a.value,source:b.envUser,suspicious:!0}),c==null)throw new Error("Failed to detect the current username.");return l.size>1||i.discardedSuspiciousValue||s.discardedSuspiciousValue||a.discardedSuspiciousValue?{...c,suspicious:!0}:c}async function $t({env:e,execFileImpl:t,hostname:n,platform:r}){let o=[];oe(o,n,S.osHostname),oe(o,e.HOSTNAME,S.envHostname);for(let i of jt(r))try{let{stdout:s}=await t(i.command,i.args);oe(o,s,i.source)}catch{continue}return ie(o)}function jt(e){return e===x.macos?[{command:"scutil",args:["--get","HostName"],source:S.scutilHostname},{command:"scutil",args:["--get","LocalHostName"],source:S.scutilLocalhostname},{command:"hostname",args:["-f"],source:S.hostnameFQDN},{command:"hostname",args:[],source:S.hostname}]:[{command:"hostname",args:["-f"],source:S.hostnameFQDN},{command:"hostname",args:[],source:S.hostname}]}function oe(e,t,n){let r=Ze(t);r&&e.push({value:r,source:n})}function Ze(e){return e?.trim()||null}function et(e){let t=e?.trim();return t?Mt.has(t.toLowerCase())?{discardedSuspiciousValue:!0,value:null}:{discardedSuspiciousValue:!1,value:t}:{discardedSuspiciousValue:!1,value:null}}function zt(e,t){let n=[];return t===x.linux&&(typeof e.WSL_DISTRO_NAME=="string"||typeof e.WSL_INTEROP=="string")&&n.push(re.wsl),(typeof e.CONTAINER=="string"||typeof e.container=="string")&&n.push(re.container),n}async function Gt(e){try{let{stdout:t}=await e("id",["-u"]);return t.trim()||null}catch{return null}}async function Yt({execFileImpl:e,platform:t,uid:n}){try{if(t===x.linux){let{stdout:o}=await e("getent",["passwd",n]);return We(o)}let{stdout:r}=await e("dscl",[".","-search","/Users","UniqueID",n]);return We(r)}catch{return null}}function We(e){let t=e.split(/\r?\n/u).map(r=>r.trim()).find(r=>r.length>0);if(!t)return null;if(t.includes(":")){let[r]=t.split(":",1);return r?.trim()||null}let[n]=t.split(/\s+/u,1);return n?.trim()||null}async function qe(e,t,n){try{let{stdout:r}=await e(t,n);return et(r)}catch{return{discardedSuspiciousValue:!1,value:null}}}function Qt(e,t){let n=e.value.toLowerCase(),r=e.source;return r===S.tailscaleShort||t.has(n)?C.tailscaleShort:r===S.tailscaleMagicDNS||Q(e.value)?C.tailscaleFQDN:Ge(n)?C.localDomain:Ye(e.value)?C.fqdn:C.singleLabel}async function tt({baseUrl:e},{fetchImpl:t=fetch}={}){let n=await t(new URL("/v1/pairing-sessions",e),{method:"POST"}),r=await ae(n,"Failed to create pairing session.");return Wt(r)}async function nt({baseUrl:e,hostToken:t,sessionId:n},{fetchImpl:r=fetch}={}){let o=await r(new URL(`/v1/pairing-sessions/${n}/host-status`,e),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({host_token:t})}),i=await ae(o,"Failed to load pairing session status.");return qt(i)}async function se({baseUrl:e,hostToken:t,metadata:n,sessionId:r},{fetchImpl:o=fetch}={}){let i=await Vt({baseUrl:e,body:Jt(t,n),sessionId:r},o);return ae(i,"Failed to complete pairing session.")}function Jt(e,t){let n={host_token:e};return t.detectedUsername!==void 0&&(n.detected_username=t.detectedUsername),t.detectedUsernameSource!==void 0&&(n.detected_username_source=t.detectedUsernameSource),t.detectedUsernameSuspicious!==void 0&&(n.detected_username_suspicious=t.detectedUsernameSuspicious),t.hostCandidates!==void 0&&(n.host_candidates=t.hostCandidates),t.hostEnvironmentFlags!==void 0&&(n.host_environment_flags=t.hostEnvironmentFlags),t.hostnameCandidates!==void 0&&(n.hostname_candidates=t.hostnameCandidates),t.usesTailscale!==void 0&&(n.uses_tailscale=t.usesTailscale),t.relayCapable!==void 0&&(n.relay_capable=t.relayCapable),t.relayHostId!==void 0&&(n.relay_host_id=t.relayHostId),t.sshHostPublicKeys!==void 0&&(n.ssh_host_public_keys=t.sshHostPublicKeys),t.port!==void 0&&(n.port=t.port),t.platform!==void 0&&(n.platform=t.platform),t.errorMessage!==void 0&&(n.error_message=t.errorMessage),n}async function Vt({baseUrl:e,body:t,sessionId:n},r){return r(new URL(`/v1/pairing-sessions/${n}/complete`,e),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async function ae(e,t){let n=null;try{n=await e.json()}catch{n=null}if(e.ok)return n;let r=tn(n);throw new Error(r??t)}function Wt(e){let t=J(e,"Failed to create pairing session.");return{sessionId:N(t.session_id,"Pairing session did not include a session ID."),pairingCode:N(t.pairing_code,"Pairing session did not include a pairing code."),qrPayload:N(t.qr_payload,"Pairing session did not include a QR payload."),hostToken:N(t.host_token,"Pairing session did not include a host token."),expiresAtEpochSeconds:le(t.expires_at_epoch_seconds,"Pairing session did not include a valid expiration time.")}}function qt(e){let t=J(e,"Failed to load pairing session status.");return{sessionId:N(t.session_id,"Pairing session status did not include a session ID."),status:en(t.status),publicKey:rt(t.public_key),completion:Xt(t.completion),connectorBootstrap:Zt(t.connector_bootstrap),expiresAtEpochSeconds:le(t.expires_at_epoch_seconds,"Pairing session status did not include a valid expiration time.")}}function Xt(e){if(e==null)return null;let t=J(e,"Pairing session completion payload was invalid.");return{errorMessage:rt(t.error_message)}}function Zt(e){if(e==null)return null;let t=J(e,"Pairing session connector bootstrap was invalid.");return{token:N(t.token,"Pairing session connector bootstrap did not include a token."),expiresAtEpochSeconds:le(t.expires_at_epoch_seconds,"Pairing session connector bootstrap did not include a valid expiration time.")}}function en(e){let t=N(e,"Pairing session status was invalid.");switch(t){case w.pending:case w.claimed:case w.completed:case w.failed:case w.expired:return t;default:throw new Error(`Unexpected pairing session status: ${t}`)}}function tn(e){return typeof e!="object"||e===null?null:"detail"in e&&typeof e.detail=="string"?e.detail:"error"in e&&typeof e.error=="string"?e.error:"message"in e&&typeof e.message=="string"?e.message:null}function J(e,t){if(typeof e!="object"||e===null)throw new Error(t);return e}function N(e,t){if(typeof e!="string"||!e)throw new Error(t);return e}function rt(e){return typeof e=="string"&&e?e:null}function le(e,t){if(typeof e!="number"||!Number.isFinite(e))throw new Error(t);return e}import{createHash as nn,randomUUID as rn}from"node:crypto";import{spawn as on}from"node:child_process";import{promises as m}from"node:fs";import ce from"node:os";import y from"node:path";var sn="https://agentty-assets.esmadil.se/host-runtime",an="AGENTTY_HOST_RUNTIME_ASSET_BASE_URL";async function ot(e){let t=e.homeDirectory??ce.homedir();if(!t)throw new Error("Unable to resolve the current home directory.");let n=await ln(t),r=await cn({baseUrl:e.baseUrl,bootstrapToken:e.bootstrapToken,machineID:n,metadata:e.metadata}),o=await un({homeDirectory:t,metadata:e.metadata,platform:e.platform??process.platform}),i=y.join(t,".agentty","libexec","agentty-host-connector"),s=y.join(t,".agentty","config","host-connector.json"),a=y.join(t,".agentty","logs");await m.mkdir(y.dirname(i),{recursive:!0}),await m.mkdir(y.dirname(s),{recursive:!0}),await m.mkdir(y.join(t,".agentty","state"),{recursive:!0}),await m.mkdir(a,{recursive:!0}),await m.writeFile(i,o),await m.chmod(i,448);let l={connector_id:r.connector_id,connector_secret:r.connector_secret,public_base_url:e.baseUrl.origin,relay_host_id:r.relay_host_id,ssh_port:e.metadata.port};return await m.writeFile(s,JSON.stringify(l,null,2)+`
|
|
10
|
+
`,{mode:384}),await m.chmod(s,384),await fn({connectorBinaryPath:i,connectorConfigPath:s,homeDirectory:t,logDirectory:a,platform:e.platform??process.platform,username:e.metadata.detectedUsername}),e.io.stdout.write(["Installed AgenTTY relay connector service.",`Relay host ID: ${r.relay_host_id}`].join(`
|
|
11
|
+
`)+`
|
|
12
|
+
`),{relayHostId:r.relay_host_id}}async function ln(e){let t=y.join(e,".agentty","state","relay-machine-id");try{let r=(await m.readFile(t,"utf8")).trim();if(r)return r}catch{}await m.mkdir(y.dirname(t),{recursive:!0});let n=rn().toLowerCase();return await m.writeFile(t,n+`
|
|
13
|
+
`,{mode:384}),await m.chmod(t,384),n}async function cn({baseUrl:e,bootstrapToken:t,machineID:n,metadata:r}){let o=await fetch(new URL("/v1/connectors/register",e),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({bootstrap_token:t,machine_id:n,ssh_username:r.detectedUsername,platform:r.platform,port:r.port})});if(!o.ok){let s=await yn(o);throw new Error(s??"Failed to register the AgenTTY relay connector.")}let i=await o.json();if(!i.connector_id||!i.connector_secret||!i.relay_host_id)throw new Error("Relay connector registration returned an invalid payload.");return i}async function un({homeDirectory:e,metadata:t,platform:n}){let r=mn(t.platform,n,process.arch),o=dn(),i=new URL("latest.json",o.endsWith("/")?o:`${o}/`),s=await fetch(i);if(!s.ok)throw new Error(`Failed to fetch host runtime manifest (${s.status}).`);let a=await s.json(),c=a.targets?.[r]?.agentty_host_connector;if(!c)throw new Error(`Host runtime manifest does not contain an AgenTTY relay connector for ${r}.`);let d=await fetch(c.url);if(!d.ok)throw new Error(`Failed to fetch the AgenTTY relay connector binary (${d.status}).`);let p=Buffer.from(await d.arrayBuffer());if(nn("sha256").update(p).digest("hex")!==c.sha256)throw new Error("Relay connector checksum mismatch.");let u=y.join(e,".agentty","state",`relay-connector-${a.runtime_version}-${r}`);return await m.mkdir(y.dirname(u),{recursive:!0}),await m.writeFile(u,p),await m.chmod(u,448),p}function dn(){return process.env[an]?.trim()||sn}function mn(e,t,n){let r=e==="macos"?"darwin":e==="linux"?"linux":pn(t),o=n==="arm64"?"arm64":n==="x64"?"x86_64":n;switch(`${r}-${o}`){case"darwin-arm64":case"darwin-x86_64":case"linux-arm64":case"linux-x86_64":return`${r}-${o}`;default:throw new Error(`Unsupported host runtime target ${r}-${o}.`)}}function pn(e){switch(e){case"darwin":return"darwin";case"linux":return"linux";default:throw new Error(`Unsupported platform ${e}.`)}}async function fn({connectorBinaryPath:e,connectorConfigPath:t,homeDirectory:n,logDirectory:r,platform:o,username:i}){switch(o){case"darwin":await gn({connectorBinaryPath:e,connectorConfigPath:t,logDirectory:r,username:i});return;case"linux":await hn({connectorBinaryPath:e,connectorConfigPath:t,homeDirectory:n,username:i});return;default:throw new Error(`Unsupported platform ${o}.`)}}async function gn({connectorBinaryPath:e,connectorConfigPath:t,logDirectory:n,username:r}){let o=it(r),i=`/Library/LaunchDaemons/${o}.plist`,s=await m.mkdtemp(y.join(ce.tmpdir(),"agentty-host-connector-")),a=y.join(s,`${o}.plist`),l=`<?xml version="1.0" encoding="UTF-8"?>
|
|
14
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
15
|
+
<plist version="1.0">
|
|
16
|
+
<dict>
|
|
17
|
+
<key>Label</key>
|
|
18
|
+
<string>${o}</string>
|
|
19
|
+
<key>ProgramArguments</key>
|
|
20
|
+
<array>
|
|
21
|
+
<string>${e}</string>
|
|
22
|
+
<string>--config</string>
|
|
23
|
+
<string>${t}</string>
|
|
24
|
+
</array>
|
|
25
|
+
<key>RunAtLoad</key>
|
|
26
|
+
<true/>
|
|
27
|
+
<key>KeepAlive</key>
|
|
28
|
+
<true/>
|
|
29
|
+
<key>UserName</key>
|
|
30
|
+
<string>${r}</string>
|
|
31
|
+
<key>StandardOutPath</key>
|
|
32
|
+
<string>${y.join(n,"host-connector.stdout.log")}</string>
|
|
33
|
+
<key>StandardErrorPath</key>
|
|
34
|
+
<string>${y.join(n,"host-connector.stderr.log")}</string>
|
|
35
|
+
</dict>
|
|
36
|
+
</plist>
|
|
37
|
+
`;await m.writeFile(a,l,"utf8");try{await H("sudo",["install","-m","644",a,i]),await H("sudo",["launchctl","bootout","system",i]).catch(()=>{}),await H("sudo",["launchctl","bootstrap","system",i]),await H("sudo",["launchctl","kickstart","-k",`system/${o}`])}finally{await m.rm(s,{recursive:!0,force:!0})}}async function hn({connectorBinaryPath:e,connectorConfigPath:t,homeDirectory:n,username:r}){let i=`${it(r)}.service`,s=`/etc/systemd/system/${i}`,a=await m.mkdtemp(y.join(ce.tmpdir(),"agentty-host-connector-")),l=y.join(a,i),c=`[Unit]
|
|
38
|
+
Description=AgenTTY host connector
|
|
39
|
+
After=network-online.target
|
|
40
|
+
Wants=network-online.target
|
|
41
|
+
|
|
42
|
+
[Service]
|
|
43
|
+
Type=simple
|
|
44
|
+
User=${r}
|
|
45
|
+
ExecStart=${e} --config ${t}
|
|
46
|
+
Restart=always
|
|
47
|
+
RestartSec=2
|
|
48
|
+
WorkingDirectory=${n}
|
|
49
|
+
|
|
50
|
+
[Install]
|
|
51
|
+
WantedBy=multi-user.target
|
|
52
|
+
`;await m.writeFile(l,c,"utf8");try{await H("sudo",["install","-m","644",l,s]),await H("sudo",["systemctl","daemon-reload"]),await H("sudo",["systemctl","enable","--now",i])}finally{await m.rm(a,{recursive:!0,force:!0})}}function it(e){return`se.esmadil.agentty-host-connector.${e.replace(/[^a-z0-9]+/giu,"-").toLowerCase()}`}async function H(e,t){await new Promise((n,r)=>{let o=on(e,t,{stdio:"inherit"});o.on("error",r),o.on("exit",i=>{if(i===0){n();return}r(new Error(`${e} ${t.join(" ")} exited with status ${i??"unknown"}.`))})})}async function yn(e){try{let t=await e.json();return t.detail??t.error??t.message??null}catch{return null}}import{execFile as Sn}from"node:child_process";import{promisify as Pn}from"node:util";var wn=Pn(Sn),vn=5,En="rsa,ecdsa,ed25519";async function st(e,t=Tn){let r=(await t("ssh-keyscan",["-T",String(vn),"-p",String(e),"-t",En,"127.0.0.1"])).stdout.split(/\r?\n/u).map(i=>i.trim()).filter(i=>i.length>0&&!i.startsWith("#")).map(i=>{let s=i.split(/\s+/u);return s.length>=3?`${s[1]} ${s[2]}`:null}).filter(i=>i!==null),o=Array.from(new Set(r));if(o.length===0)throw new Error("Failed to collect the host SSH public keys from local sshd.");return o}async function Tn(e,t){let n=await wn(e,t);return{stdout:n.stdout,stderr:n.stderr}}import{execFile as _n}from"node:child_process";import{promisify as Cn}from"node:util";var Ln=Cn(_n);async function lt({execFileImpl:e=Ln}={}){try{let{stdout:t}=await e("tailscale",["status","--json"]);return at(t,!0)}catch(t){return G(t,"ENOENT")?{installed:!1,magicDNSName:null,shortHostname:null}:at(Be(t),!0)}}function at(e,t){let n=Rn(e),r=Qe(n?.Self?.DNSName);return{installed:t,magicDNSName:r,shortHostname:Je(r)}}function Rn(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return An(n)?n:null}catch{return null}}function An(e){if(typeof e!="object"||e===null)return!1;if(!("Self"in e)||e.Self===void 0)return!0;let t=e.Self;return typeof t!="object"||t===null?!1:!("DNSName"in t)||typeof t.DNSName=="string"}async function ue(e,t,n={}){let{connectorProvisioner:r=ot,fetchImpl:o=fetch,promptImpl:i=Hn,qrRenderer:s=Dn,sleepImpl:a=In}=n;try{if(e.length>0)throw new Error("@agentty-app/pair does not accept extra arguments.");let l=Ke(n.env??process.env),c=Xe({env:n.env??process.env,execFileImpl:n.execFileImpl,hostname:n.hostname,platform:n.platform??process.platform});c.catch(()=>{});let d=lt({execFileImpl:n.execFileImpl});d.catch(()=>{}),t.stdout.write(`Creating pairing session via ${l.origin}...
|
|
53
|
+
`);let p=await tt({baseUrl:l},{fetchImpl:o});for(t.stdout.write(`
|
|
54
|
+
Scan this QR code with AgenTTY:
|
|
55
|
+
|
|
56
|
+
`),await s(p.qrPayload,t.stdout),t.stdout.write(`
|
|
57
|
+
Manual code: ${p.pairingCode}
|
|
58
|
+
`),t.stdout.write(`Waiting for AgenTTY to claim this host...
|
|
59
|
+
`),await a(1e3);;){let v=await nt({baseUrl:l,hostToken:p.hostToken,sessionId:p.sessionId},{fetchImpl:o});switch(v.status){case w.pending:await a(1e3);continue;case w.claimed:{if(!v.publicKey)throw new Error("Pairing session was claimed without a public key.");let u;try{let f=Nn({io:t,metadata:await c,promptImpl:i,tailscale:await d}),D=c.then(E=>st(E.port,n.execFileImpl)),U=Fe(v.publicKey,{fsImpl:n.fsImpl,homeDirectory:n.homeDirectory});u=await f,u={...u,sshHostPublicKeys:await D};let O=await U;if(t.stdout.write(O.alreadyPresent?`Public key was already authorized for this user.
|
|
60
|
+
`:`Authorized the AgenTTY public key for this user.
|
|
61
|
+
`),v.connectorBootstrap)try{let E=await r({baseUrl:l,bootstrapToken:v.connectorBootstrap.token,homeDirectory:n.homeDirectory,io:t,metadata:u,platform:n.platform??process.platform});u={...u,relayCapable:!0,relayHostId:E.relayHostId}}catch(E){u={...u,relayCapable:!1},t.stdout.write(["Remote relay access is unavailable for now. Direct SSH pairing still succeeded.",E instanceof Error?E.message:String(E)].join(`
|
|
62
|
+
`)+`
|
|
63
|
+
`)}return await se({baseUrl:l,hostToken:p.hostToken,metadata:u,sessionId:p.sessionId},{fetchImpl:o}),t.stdout.write(["Pairing complete.",`Detected user: ${u.detectedUsername}`,`Hostname candidates: ${u.hostnameCandidates.join(", ")||"none"}`,`Platform: ${u.platform}`,u.relayCapable&&u.relayHostId?`Relay host ID: ${u.relayHostId}`:"Relay access: direct SSH only"].join(`
|
|
64
|
+
`)+`
|
|
65
|
+
`),0}catch(f){throw await bn({baseUrl:l,hostToken:p.hostToken,metadata:u,sessionId:p.sessionId},o,f instanceof Error?f.message:String(f)),f}}case w.completed:throw new Error("Pairing session completed before the host finished setup locally.");case w.failed:throw new Error(v.completion?.errorMessage??"Pairing failed.");case w.expired:throw new Error("Pairing code expired.")}}}catch(l){return t.stderr.write(`${l instanceof Error?l.message:String(l)}
|
|
66
|
+
`),1}}async function bn(e,t,n){try{await se({baseUrl:e.baseUrl,hostToken:e.hostToken,metadata:{...e.metadata,errorMessage:n},sessionId:e.sessionId},{fetchImpl:t})}catch{return}}function Dn(e,t){return new Promise(n=>{ct.default.generate(e,{small:!0},r=>{t.write(`${r}
|
|
67
|
+
`),n()})})}function In(e){return new Promise(t=>{setTimeout(t,e)})}async function Nn({io:e,metadata:t,promptImpl:n,tailscale:r}){let o=r.shortHostname??r.magicDNSName;if(!r.installed)return{...t,sshHostPublicKeys:[],usesTailscale:!1};if(!r.magicDNSName||!o)return e.stdout.write(["Tailscale is installed, but AgenTTY could not determine a usable MagicDNS hostname right now.","Continuing with the host's normal hostname candidates.","If you want to pair over Tailscale, connect this host to Tailscale and run the pair command again."].join(`
|
|
68
|
+
`)+`
|
|
69
|
+
`),{...t,sshHostPublicKeys:[],usesTailscale:!1};if(!await n({io:e,preferredHostname:o}))return{...t,sshHostPublicKeys:[],usesTailscale:!1};e.stdout.write([`Using Tailscale hostname: ${o}`,"Make sure Tailscale is installed and connected on the iPhone running AgenTTY, or the SSH connection will not work."].join(`
|
|
70
|
+
`)+`
|
|
71
|
+
`);let s=ie([{value:o,source:S.tailscaleShort},{value:r.magicDNSName,source:S.tailscaleMagicDNS},...t.hostCandidates]);return{...t,hostCandidates:s,hostnameCandidates:s.map(a=>a.value),sshHostPublicKeys:[],usesTailscale:!0}}async function Hn({io:e,preferredHostname:t}){let n=e.stdin,r=e.stdout;if(!n?.isTTY)return r.write(`Tailscale is installed, but this session is not interactive. Continuing without Tailscale.
|
|
72
|
+
`),!1;let o=["Detected Tailscale on this host.","AgenTTY works especially well over Tailscale because it gives your devices a simple, secure, and reliable way to reach this host.",`Detected Tailscale hostname: ${t}`,"Use Tailscale for this pairing? [Y/n] "],i=kn({input:n,output:r});try{let s=await i.question(o.join(`
|
|
73
|
+
`));return!/^(n|no)$/iu.test(s.trim())}finally{i.close()}}async function ut(e,t){return t.stdout.write(`AgenTTY Host repair is not implemented yet.
|
|
74
|
+
`),0}async function dt(e,t){return t.stdout.write(`AgenTTY Host unpair is not implemented yet.
|
|
75
|
+
`),0}var Un=new Map([["pair",ue],["doctor",pe],["repair",ut],["unpair",dt]]);async function Gr(e,t){let[n,...r]=e;if(!n)return ue([],t);if(xn(n))return mt(t.stdout),0;if(On(n)){let i=Y===ne?"":` (${ne})`;return t.stdout.write(`${$e} ${Y}${i}
|
|
76
|
+
`),0}let o=Un.get(n);return o?o(r,t):(t.stderr.write(`Unknown command: ${n}
|
|
77
|
+
|
|
78
|
+
`),mt(t.stderr),1)}function xn(e){return e==="help"||e==="--help"||e==="-h"}function On(e){return e==="--version"||e==="-v"}function mt(e){e.write(["Usage: agentty-pair [command]","Usage: npx -y @agentty-app/pair","","Commands:"," pair Start the host pairing flow"," doctor Run host diagnostics"," repair Repair a broken host setup"," unpair Remove AgenTTY host pairing","","Examples:"," npx -y @agentty-app/pair"," npx -y @agentty-app/pair doctor",""].join(`
|
|
79
|
+
`))}export{Gr as runCli};
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agentty-app/pair",
|
|
3
|
+
"version": "2.7.12",
|
|
4
|
+
"description": "Pairing CLI for connecting a computer to AgenTTY.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agentty-pair": "bin/agentty-host.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "npm run typecheck && node ./scripts/build.mjs",
|
|
11
|
+
"prepack": "npm run build",
|
|
12
|
+
"test": "npm run typecheck && tsx --test src/**/*.test.ts",
|
|
13
|
+
"typecheck": "tsc --noEmit"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"qrcode-terminal": "^0.12.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^24.7.2",
|
|
20
|
+
"esbuild": "^0.25.11",
|
|
21
|
+
"tsx": "^4.20.6",
|
|
22
|
+
"typescript": "^5.9.3"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"bin",
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"license": "UNLICENSED"
|
|
36
|
+
}
|