{"_id":"@aiscenblue/squab","_rev":"20-0e9661e5163a8dd612c94dcf7f89d8cf","name":"@aiscenblue/squab","dist-tags":{"latest":"0.3.16"},"versions":{"0.1.0":{"name":"@aiscenblue/squab","version":"0.1.0","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.1.0","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"0bb9630fba92d80da9a9e3cdea0e108eda47775d","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.1.0.tgz","fileCount":8,"integrity":"sha512-dAApM3eUZ3baEJW9S7EDFGbnGfU4tD+Al9PyuL1JQij/FiMYGVCvpazZ/2yTXhYSOBwGTquh5TK15/Gw8Sar2Q==","signatures":[{"sig":"MEUCIQC9SeRE5ZMsIXHiMG8xeQTDwvR9SmUcdLm0IcKRSuSLAQIgBqhDdOqQw0WHG+blxE2lifEMMlp5bFOBZr4m9T6lb+o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53310161},"engines":{"node":">=18"},"gitHead":"c71179f7a87c2aceade10314b9f3d8e5a39d1fd3","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.1.0_1786934712467_0.170071986559162","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aiscenblue/squab","version":"0.2.0","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.2.0","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"6f6ab1eae824fb9bae5056cab0bbd53bcfe88eae","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.2.0.tgz","fileCount":8,"integrity":"sha512-xzM0N95samkzo4la7FEWEtvhUEz2Le643qeuX0xXWoBlDLnVeMxHfBPKGlrxkIwOobyK9u3rJNSnNIlSkvFXDg==","signatures":[{"sig":"MEUCID7uV1YyoD1Mhgi9rBo+gwsr6xciA1HxpaxfAO44N/pPAiEAyJKhdz30dW3piZ2YxcoeNN8NP8Foj/nUcdqLhC4bF/4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53571009},"engines":{"node":">=18"},"gitHead":"82d51594a2c5347dedbc1fc5593682f16d8ed266","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.2.0_1786936074793_0.018043422413888344","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aiscenblue/squab","version":"0.2.1","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.2.1","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"c89c34c8e2de7514dd9021829a4d93ba371164c5","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.2.1.tgz","fileCount":8,"integrity":"sha512-5ErYwVg9znsD3jRhvlUqphcEv99jxPTpCqui7Unj7jF4MtWHRHUtG8GEuq3n4ZByEDs6ni9xFdhXAaFLcWyr5w==","signatures":[{"sig":"MEYCIQCpBpj1t/6pDO0NW9sxhYHBuU8R8w8xMb87qhtjlZ63ZwIhAPMyxXQ+TKHerziWTmTvGp+oRdxYFS9s4b0pKL+jqegC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53576145},"engines":{"node":">=18"},"gitHead":"57179976c35a8c5cfdae9d6ac7d25213c84b1107","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.2.1_1786936833122_0.46162363267673445","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aiscenblue/squab","version":"0.3.0","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.0","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"7e2e76e923adb42b502548e1e1e11638789541eb","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.0.tgz","fileCount":8,"integrity":"sha512-TiejkGvntr9aBnJx9BJyTvV8/S/IIkv5YDlxUZNUqDdASLXX7oTxcKvOXm3VtxPCBLC1yQh5i/EL0AI2po+cUQ==","signatures":[{"sig":"MEUCIDIRJjq8GgFLdoLMQ/GkEalJjonjP0ZwqdTxgXefLkEQAiEAxiwJdebBwPijeCz+rPp/Z6jVYHHRe95qhw543ggZcHw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55390289},"engines":{"node":">=18"},"gitHead":"bfc83e4f3fffb67d30a1b4780cace3f159ca9bec","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.0_1786939035982_0.40383069299503704","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aiscenblue/squab","version":"0.3.1","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.1","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"e1892d98acb5a3b8c000849ec4a648bf7c13af08","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.1.tgz","fileCount":8,"integrity":"sha512-LN4G3NK3i/fELaFT3OPWnzxHxt8FVWa/cm37ulabG54gPpzwWsETn8eJtA/CoaI/iNTlYgoBKBYFBcUnPw1LpA==","signatures":[{"sig":"MEUCIQCo9uB9Au8FJ89YfinXz9qVBAV5Qs9XXcxckwxRKRWX9wIgIbW/aPQry/i3WIELQmN0slZ+m7dzEToUB9W6Zlotzec=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55516017},"engines":{"node":">=18"},"gitHead":"292457d773921a2319d2a76c6686fe18f3bc137d","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.1_1786939646761_0.7047413111575562","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aiscenblue/squab","version":"0.3.2","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.2","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"b5b0243bca32b2597efdef0c1fdccfa46f8052da","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.2.tgz","fileCount":8,"integrity":"sha512-HYuayd4bIpdfJqqnNXeCaamC4teEsoziQ3yaxuVijt63fEI+bUMjv6KhJhvi/uMmCO800opHWy5aI/pW6b3mpw==","signatures":[{"sig":"MEQCIG/KmomEBD0kiWlsUb6Gtk/VqOM3roJH0xt3iJVqNU4bAiBQJzzT88kVlJNQCxqR97y2d5K+M95Q2H8auqsTFNsgnA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55516073},"engines":{"node":">=18"},"gitHead":"55614fe379811bcae823ff2f08ff7d0032695647","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.2_1786940102357_0.3911760166494238","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"name":"@aiscenblue/squab","version":"0.3.3","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.3","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"bf4e3ea44fedd54330b43fa23829ae1d231ef782","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.3.tgz","fileCount":8,"integrity":"sha512-Ld6s3pvt+G70ZkUjWF/lLv3YqkLwtTXNpfSIRFm0Xu/YOPNmMSLv/romXOeZof5wgqrq/xzNJ/9fEFGyG+jBKw==","signatures":[{"sig":"MEYCIQCnU2AhclEixRqQJ9cECseVP5o48ymIfpUcV1c7dtaK+QIhAIeqcLB3l5SCsfwfrlg1ACtAlNrspMjwBr00a8gF9Bjt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55521705},"engines":{"node":">=18"},"gitHead":"891194af780f5a160ade20ef5e9ec7ad81dbf385","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.3_1786940861240_0.6817856241459923","host":"s3://npm-registry-packages-npm-production"}},"0.3.4":{"name":"@aiscenblue/squab","version":"0.3.4","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.4","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"ed044dfbf68834fb2a61ebc186b501dea702b18a","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.4.tgz","fileCount":8,"integrity":"sha512-XfIptVtem7oxtMvfzr+iRgVX+lkrRLIxh5NqVW1sx+ihaQ4MUY8e81oWBVOUFefa1zoCCYZOPA7GLcJrRzL8Vw==","signatures":[{"sig":"MEQCIE2NYY4ASfETB/wYfvSLDVNmsbQqzgZ5qH/7RHaTMEg3AiB5QYt509BCTbDWnKLuBFlKzqRGtrrh4K7b4VBzGxihCQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55510499},"engines":{"node":">=18"},"gitHead":"8e9506f41d65d041bd2c446e0cefd4b72c07b15c","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.4_1786942068830_0.9659643857967366","host":"s3://npm-registry-packages-npm-production"}},"0.3.5":{"name":"@aiscenblue/squab","version":"0.3.5","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.5","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"9c23330d68efe77df4ad8df66441faf9a7626373","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.5.tgz","fileCount":8,"integrity":"sha512-STmmBZ26GcuupUCWX2xaPGblCw3Gv5K8KXQTt/KwQK/0TcCNUOp1ADF4/WtzYiqXqQgfDwE2l6xAMeXqyViQzA==","signatures":[{"sig":"MEUCIQC+m92AeAawd0lhqDXCTrrhswPbHZlGSWe4sKWwJ3WM4AIgLfd+W+xhC4JZvAjOGiFS88WRqZfj8a7olM4oWhcTONs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55511539},"engines":{"node":">=18"},"gitHead":"68e1b4109d90e6319b2b73f20bc6e3ea287ccf5c","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.5_1786943128573_0.3371811743606521","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"@aiscenblue/squab","version":"0.3.6","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.6","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"29fbea8f5caf11776564ae66d0575a32d7b59115","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.6.tgz","fileCount":8,"integrity":"sha512-I3XRyFFTWLpWcEz7cA5NW0drLSkXTzZplgdtlTm2SDuCZ/r7xsCAbjhSiH3x8VeIskY62oj9Ger41g1H9NDj8w==","signatures":[{"sig":"MEUCIHBcmO2B+QQr99DjO2nzCnzj49+PS4Fk8YNnVi5WzZkCAiEA+yLIE/Uwizkx6nYQGE1Rdz+C7yDKkbVGLIJlikSNKuQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55520951},"engines":{"node":">=18"},"gitHead":"8ad1b1d3d6163781e9560f79e550ca9cc7721d37","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.6_1786944247667_0.2968871323620532","host":"s3://npm-registry-packages-npm-production"}},"0.3.7":{"name":"@aiscenblue/squab","version":"0.3.7","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.7","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"7032d916dcb8cd081300b7986563f776fd066981","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.7.tgz","fileCount":8,"integrity":"sha512-0O+nxsejmDlUejmSlIkDSouZRsxu4bEBcy9pnM9KoQ77NIh9DLt30TEFPwy6vtD8EztRSfnOlCjD/yOP4A+tUA==","signatures":[{"sig":"MEUCIQD10GfHl5N3bKtKX00vyuTHRg5j/ThIRT2AEdjV4izJSgIgAwyIa+yEqxEMg8hl41zPvmDLRrHyjKVNedCnS19fEV8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55529687},"engines":{"node":">=18"},"gitHead":"8dfb05168b7dcbb382bd4bc5fb89b7b79de0c49c","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.7_1786945549551_0.386291679843934","host":"s3://npm-registry-packages-npm-production"}},"0.3.8":{"name":"@aiscenblue/squab","version":"0.3.8","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.8","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"1f78febb347c6da5799c4bd4c5f4639d9de7a030","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.8.tgz","fileCount":8,"integrity":"sha512-w/VAGC9MZFWCRiiJQ+wQzIGL3hrKH7SnOZ19w1DvKHQtP4OtzxsyjcQGt+2XILnSkbCgAUb7ku8i2UFzoVTnqg==","signatures":[{"sig":"MEUCIQC/wWGjVtHxPUIYDAqhYEfuj0q5q9VUyPxDuNAL654XowIgRnSvt1ssSTkqMBckNOhBzWI6VfJoioz7BauaVtNgCqg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55534791},"engines":{"node":">=18"},"gitHead":"f9d22217e4fb2553ca6c0b8a173354d7a694a725","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.8_1786946738340_0.030203307159962556","host":"s3://npm-registry-packages-npm-production"}},"0.3.9":{"name":"@aiscenblue/squab","version":"0.3.9","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.9","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"d6e9b26e2cb7ce7ec52d693fbd87915e9faba182","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.9.tgz","fileCount":8,"integrity":"sha512-Uj4/5/dYllQ4tvSqqJY3IzkPzTK5VlIzpCo9SasXkwK6dihLD/npraM9QPy7HgN2D2vVbxRh6F6X6EtdQhlSDw==","signatures":[{"sig":"MEYCIQDDY7woWhtAYIVHQ8KUGCwdJi0WBhKxH2iruG7xftYCwgIhAOFYwQdzpsjDyzpt9Km1M8aJLaTX//iIi03L9PbX60E3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55534791},"engines":{"node":">=18"},"gitHead":"d9303be7be3ab19642b484311c6c75d8cf5bd8fb","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.9_1786946933449_0.34078751300038634","host":"s3://npm-registry-packages-npm-production"}},"0.3.10":{"name":"@aiscenblue/squab","version":"0.3.10","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.10","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"3eef27b09b8dd9a5cc99a34b2dd35a7baa22fe3c","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.10.tgz","fileCount":8,"integrity":"sha512-5Jlh9tqbWu0YfdXc1RPYOCp8OFZNiBONAW7vB8vvks/4cVLUFxSllR6+/O4z0zgqqxty0BuBSnlR1tofx02tRQ==","signatures":[{"sig":"MEQCIDZr7e7ph+YdTprng4pP3MGc5b5Gj6wUKHhXTW8idVL/AiAyXEuUypVHy9vh26f6c19uM8LqXUU9cTPhx1Fp6J58kQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55534579},"engines":{"node":">=18"},"gitHead":"24046b3fdd65e3ae5fd24c37fca792eaa1763973","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.10_1786947077163_0.2805331634315926","host":"s3://npm-registry-packages-npm-production"}},"0.3.11":{"name":"@aiscenblue/squab","version":"0.3.11","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.11","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"cae298e720df2ac78a3be4d2d6c86809ec30a363","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.11.tgz","fileCount":8,"integrity":"sha512-3e3uH6HoNkNooo1N2kniIpSaaB0StEq9dWyCF/EGKufZ64SyI/H8It/kDKyekwAZjIbKKkScxy7TM4Or5z319Q==","signatures":[{"sig":"MEUCIDB9+UCY9ZqeB4YgbP77ENSNyIsb65yJSJvLX42+HmugAiEAla1eu+NzFdUSr2+6bYDWxJXugweR2mkbef/2paMaFPI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55566309},"engines":{"node":">=18"},"gitHead":"ee092d3dbcaa4af594dbd05adeac5e8323a3fed2","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.11_1786966560836_0.4277368524343108","host":"s3://npm-registry-packages-npm-production"}},"0.3.12":{"name":"@aiscenblue/squab","version":"0.3.12","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.12","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"74a59539a1aa1ee85aae02acc0b4970f1e5f7c15","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.12.tgz","fileCount":8,"integrity":"sha512-JayQ/T15/Rujo8alGiG5ygEwDRbFAe36m68v2DabU5GQ6ErrO+KTweV3OlGfG+ehu30JXz/xHSZEyEtZT2KjIg==","signatures":[{"sig":"MEQCIBI32hrhppC3GDmGa3uODD0btb8us8hCdkiW3rJIH/m/AiBXcBHuCqeI71p+g26pV3FSpOjHEbWB809/qbZaOEf/cA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56080427},"engines":{"node":">=18"},"gitHead":"570dc3bce1b7b0a45bae3e65c8779c53673887a3","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.12_1787278690294_0.41490193817733756","host":"s3://npm-registry-packages-npm-production"}},"0.3.13":{"name":"@aiscenblue/squab","version":"0.3.13","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.13","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"b70425cffd649a53f75ae2d773bed58f0605f644","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.13.tgz","fileCount":8,"integrity":"sha512-ohLejCr5j9hoamI6Tpti6rzO+OLI67QWWl5k2uM2wqd2F6Xde53sC4meYtIeFzifeyqHIhViVVCDskVOZSniAQ==","signatures":[{"sig":"MEUCIQDeghTQ36y3j5KMGdflhhOzsMMJwdltmm6exfvUyPI/nAIgOXFXkZiQXPKmSY3/D+nzqMgbUy2UGzoL7Z51PQwbr6o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56115949},"engines":{"node":">=18"},"gitHead":"55161f174396f951e6326a2d21d9c974d8d18a19","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.13_1787279008719_0.33268586536868017","host":"s3://npm-registry-packages-npm-production"}},"0.3.14":{"name":"@aiscenblue/squab","version":"0.3.14","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.14","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"7ae2dc7dd073f9672c417b8b6f0dd8070ca77fdf","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.14.tgz","fileCount":8,"integrity":"sha512-1rRWNPfjT78gG3khgW91/AdJPFq56sObsFpdu9y7iFtyr/RaPg1MIi5A92iOK/Yr5lGl2Vhu/sJpRke6E3/wVQ==","signatures":[{"sig":"MEQCID4YLSW7ar1LGt1AWsuucPCS1pqdSqz3QyjQH7sY8Vu/AiA9RfR01PNXlae6Im600oEkevQpNV9FblhUw4REZxUuKQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56145095},"engines":{"node":">=18"},"gitHead":"90ad05544ce07a48c0702ea064373494e1ec3ff7","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.14_1787279724708_0.8612250462582398","host":"s3://npm-registry-packages-npm-production"}},"0.3.15":{"name":"@aiscenblue/squab","version":"0.3.15","keywords":["api","http","rest","tui","terminal","ssh","cli"],"license":"MIT","_id":"@aiscenblue/squab@0.3.15","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"homepage":"https://github.com/aiscenblue/squab","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"bin":{"squab":"bin/squab.js"},"dist":{"shasum":"b69786645c0b19898b314040e4394b679793eacd","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.15.tgz","fileCount":8,"integrity":"sha512-dmYwOhzKJ1GWhC1+i9UhCFxjbQ0rGYoRpeAAfbEri3TkXzgDjP+PnhcZkCU+zu5MPQbEoI5ZgQAsPwG3BMDzhA==","signatures":[{"sig":"MEQCIFCY12MUtYa7mx1gdq+yAUzfFgoiPVcUhJ67negEM4r0AiBoPv5StT8HeYBhWoYNM4oyOi5Pzp1oxaLFkO+wZqlPww==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56297114},"engines":{"node":">=18"},"gitHead":"a7dc611c16db3dbd38ca0b8ef3121355f068faf0","_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"repository":{"url":"git+https://github.com/aiscenblue/squab.git","type":"git"},"_npmVersion":"11.19.0","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","directories":{},"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/squab_0.3.15_1787279892552_0.29865989568585594","host":"s3://npm-registry-packages-npm-production"}},"0.3.16":{"name":"@aiscenblue/squab","version":"0.3.16","description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/aiscenblue/squab.git"},"homepage":"https://github.com/aiscenblue/squab","bin":{"squab":"bin/squab.js"},"publishConfig":{"access":"public"},"engines":{"node":">=18"},"keywords":["api","http","rest","tui","terminal","ssh","cli"],"gitHead":"062d89d5e222cda0ece829f5f43b13a41c83132f","_id":"@aiscenblue/squab@0.3.16","bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"_nodeVersion":"22.19.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-OvHACCPr84fengBApOxVsOigGgsnw68CUZmI6dQ+FlPwUWx8PSmyshAjWq9EmtFHRmJb031dXAT6g9Xkp7xCzQ==","shasum":"8bdf069cc11eba80b72888a4cfd4af2dca35e243","tarball":"https://registry.npmjs.org/@aiscenblue/squab/-/squab-0.3.16.tgz","fileCount":8,"unpackedSize":56300659,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICg4kjuMhXlxHlirjiQ9P9SfzT7Dqpqirq7Bf/IcoWEpAiEA+NDwOyvZH9nd6Luut9PBx1MCtFVRuNk3dqnkkVX4Kpw="}]},"_npmUser":{"name":"aiscenblue","email":"aiscenblue@gmail.com"},"directories":{},"maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/squab_0.3.16_1787281672466_0.6991268145308469"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-17T02:45:12.322Z","modified":"2026-08-21T03:07:53.499Z","0.1.0":"2026-08-17T02:45:12.889Z","0.2.0":"2026-08-17T03:07:55.188Z","0.2.1":"2026-08-17T03:20:33.527Z","0.3.0":"2026-08-17T03:57:16.443Z","0.3.1":"2026-08-17T04:07:27.479Z","0.3.2":"2026-08-17T04:15:02.770Z","0.3.3":"2026-08-17T04:27:41.634Z","0.3.4":"2026-08-17T04:47:49.264Z","0.3.5":"2026-08-17T05:05:29.034Z","0.3.6":"2026-08-17T05:24:08.072Z","0.3.7":"2026-08-17T05:45:49.985Z","0.3.8":"2026-08-17T06:05:38.786Z","0.3.9":"2026-08-17T06:08:53.836Z","0.3.10":"2026-08-17T06:11:17.596Z","0.3.11":"2026-08-17T11:36:01.221Z","0.3.12":"2026-08-21T02:18:10.716Z","0.3.13":"2026-08-21T02:23:29.194Z","0.3.14":"2026-08-21T02:35:25.152Z","0.3.15":"2026-08-21T02:38:12.980Z","0.3.16":"2026-08-21T03:07:53.358Z"},"bugs":{"url":"https://github.com/aiscenblue/squab/issues"},"license":"MIT","homepage":"https://github.com/aiscenblue/squab","keywords":["api","http","rest","tui","terminal","ssh","cli"],"repository":{"type":"git","url":"git+https://github.com/aiscenblue/squab.git"},"description":"An API workbench for the terminal — organise requests, send them, read the response, run the collection.","maintainers":[{"name":"aiscenblue","email":"aiscenblue@gmail.com"}],"readme":"```\n      __\n    ,'o `.     squab\n  =<      |    an api workbench you reach over ssh\n    `.___,'\n     ''  ''\n```\n\nA squab is a young pigeon. Pigeons carry messages; this one carries your\nrequests. Organise them, send them, read the response, run the whole collection\nwith assertions — in a terminal, over SSH.\n\nSee it running: **https://aiscenblue.github.io/squab**\n\n## Install\n\n```bash\nbunx @aiscenblue/squab\nnpm i -g @aiscenblue/squab\n```\n\nOr `go install github.com/aiscenblue/squab@latest`.\n\n## Run\n\n```bash\nsquab                    # the workbench, on your own collections\nsquab serve              # over SSH: every public key gets a workspace\nsquab run example        # headless, exits non-zero if an expectation fails\n```\n\n## Why\n\nCollection runners, environment sharing and enough request history to be useful\nare all paid features elsewhere. They are also not hard problems — a runner is\na for-loop with assertions, and an environment is a map. This is that, in a\nterminal, over SSH.\n\n## The workbench\n\n```\n squab                                                   local · default\n────────────────────────────────────────────────────────────────────────\n COLLECTIONS ────────│ REQUEST · example / get ──────────────────────────\n example             │  1 ### example · get\n ● GET    get        │  2 # @expect status 200\n   POST   post json  │  3 GET {{base}}/get?from=squab\n   GET    fails      │  4 Accept: application/json\n                     │────────────────────────────────────────────────────\n                     │ RESPONSE · 200 OK · 128ms · 688 B ─────────────────\n                     │ jq ▸ .headers.Accept\n                     │ [\"application/json\"]\n────────────────────────────────────────────────────────────────────────\n ✓ all 1 variables resolve      ^p find · ^s send · ^r run · ^e vars · ?\n```\n\n| key | what it does |\n|---|---|\n| `ctrl+p` or `/` | fuzzy-find any request in any collection |\n| `s` or `ctrl+s` | save the buffer and send it |\n| `ctrl+r` | run the collection with its expectations |\n| `i` in the runner | jump straight into the request that failed, ready to edit |\n| `r` in the runner | rerun only what failed |\n| `ctrl+e` | variables, with the scope each value comes from |\n| `e` | edit the jq filter over the response |\n| `H` | response headers |\n| `shift+J` / `shift+K` | move between panes — the red bar shows which one has focus |\n| `i` | start editing the request; `esc` stops |\n| `tab` | move between panes |\n| `?` | keys |\n\nThe request pane has two modes, like vim. It starts in normal mode, where letters\nare commands; press `i` to type, `esc` to stop. The pane title shows `INSERT`\nwhile you are editing.\n\nMost terminals treat `ctrl+s` as flow control and freeze the screen with it, which\nis why `s` sends too. Run `stty -ixon` if you would rather have `ctrl+s` back.\n\n## Requests are `.http` files\n\nA collection is a text file. It diffs, it reviews, and you can paste into it\nfrom a curl command or a docs page.\n\n```http\n### get an order\n# @expect status 200\n# @expect jq .status == \"paid\"\nGET {{base}}/v1/orders/42?expand=items\nAuthorization: Bearer {{token}}\n# @off X-Debug: 1\n\n### create one\n# @expect status 201\nPOST {{base}}/v1/orders\nContent-Type: application/json\n\n{\"sku\": \"A-19\", \"qty\": 2}\n```\n\n`###` separates requests and names them. `# @off` keeps a header without\nsending it, and `# @follow` chases redirects for that one request.\n\n## Testing\n\nA test is a `# @expect` line above the request it belongs to. There is no\nseparate test file and no scripting language — the assertions live with the\nrequest they check, and travel with it in git.\n\n### The four checks\n\n```http\n### the four kinds\n# @expect status 200\n# @expect jq .json.sku == \"A-19\"\n# @expect header content-type json\n# @expect contains \"qty\"\nPOST {{base}}/post\nContent-Type: application/json\n\n{\"sku\": \"A-19\", \"qty\": 2}\n```\n\n| check | asserts |\n|---|---|\n| `status <code>` | the response code, exactly |\n| `jq <filter> == <value>` | a value inside a JSON body |\n| `header <name> <text>` | that response header contains that text, case-insensitively |\n| `contains <text>` | the raw body contains that text |\n\nA request may carry as many as you like, and every one is evaluated — a run\nreports all the failures, not just the first.\n\n### Writing jq assertions\n\nThe filter is real [jq](https://jqlang.github.io/jq/), so nesting, indexing and\npipes all work:\n\n```http\n# @expect jq .json.user.id == 7\n# @expect jq .json.user.roles[0] == \"admin\"\n# @expect jq (.json.user.roles | length) == 2\n# @expect jq .items[-1].sku == \"B-04\"\n# @expect jq [.items[].qty] == [2,1]\n```\n\nThe right-hand side is **JSON**, which decides how you write it:\n\n| value | written as |\n|---|---|\n| string | `\"paid\"` — with the quotes |\n| number | `1999` — without |\n| boolean | `true` |\n| null | `null` |\n| array | `[2,1]` |\n| object | `{\"a\":1}` |\n\n`.status == paid` without quotes will not match a string, which is the usual\nfirst mistake.\n\n### Reading a failure\n\n```\n✗ one that fails so you can see the message   200 OK · 205ms\n    .json.sku = \"A-19\", expected \"B-99\"\n```\n\nFailures report the **actual value**, so you rarely have to go and look at the\nbody yourself. Each kind explains itself in its own terms:\n\n```\nexpected status 200, got 409 Conflict\n.json.user.id = 7, expected 8\nheader content-type = text/html; charset=utf-8, expected to contain \"json\"\nbody does not contain \"already_cancelled\"\n```\n\nA request that could not be sent at all says so instead of pretending to be an\nassertion failure:\n\n```\n✗ unreachable            could not resolve api.example.invalid\n✗ missing variable       {{token}} is not set — nothing was sent\n```\n\n### Chaining one request into the next\n\nA named request publishes its response into the runtime scope, so later requests\nin the same run can use it:\n\n```http\n### login\n# @expect status 200\nPOST {{base}}/login\n\n{\"user\": \"ada\", \"password\": \"{{password}}\"}\n\n### orders, using the session login returned\n# @expect status 200\nGET {{base}}/orders\nX-Prev-Status: {{login.status}}\n```\n\n`{{login.body}}` and `{{login.status}}` come from the request named `login`.\nCookies persist across a run too, so a login that sets a session cookie is\nfollowed by requests that carry it.\n\n### Values you do not have to invent\n\n```http\n### create an order with a fresh trace id\n# @expect status 201\nPOST {{base}}/orders\nX-Request-Id: {{$uuid}}\n\n{\"idempotency_key\": \"{{$uuid}}\", \"at\": {{$timestamp}}}\n```\n\nEach use generates a new value, so the header and the body get different UUIDs.\nThe full set:\n\n```\n{{$uuid}}         {{$guid}}           {{$timestamp}}        {{$epoch}}\n{{$isoTimestamp}} {{$randomInt}}      {{$randomBoolean}}    {{$randomAlphaNumeric}}\n{{$randomWord}}   {{$randomEmail}}    {{$randomFullName}}   {{$randomFirstName}}\n{{$randomLastName}} {{$randomIP}}     {{$randomPort}}       {{$randomHexColor}}\n```\n\nA name that is not on this list stays unresolved and is reported, so a typo like\n`{{$randomNmae}}` fails loudly instead of being sent as literal text.\n\n### Running them\n\n| where | how |\n|---|---|\n| the whole collection | `ctrl+r` in the workbench |\n| one request, with its checks | `s` — the status bar shows `✓ 2 of 2 asserts` |\n| a failure you want to fix | `i` on the red row jumps into that request |\n| only what failed | `r` in the runner |\n| headless | `squab run <collection>` |\n\n`squab run` exits non-zero when anything fails, which is what makes it usable in\na pipeline:\n\n```bash\nsquab run smoke -env staging\nsquab run smoke -reporter junit -reporter-export results.xml\nsquab run smoke -i \"login\" -i \"orders\"      # a subset\nsquab run smoke -env-var base=http://localhost:8080\nsquab run smoke -bail                        # stop at the first failure\n```\n\n### Keeping tests honest in review\n\nDeleting an assertion makes a suite pass by checking less, and that is invisible\nin a green build. `squab diff` names it:\n\n```\n  ~ get an order\n      - expect       jq .status == \"paid\"\n  ! weaker than HEAD: get an order\n```\n\n### What this deliberately does not do\n\nThere is no scripting: you cannot compute a value, loop, or branch inside an\nassertion. Postman gives you a JavaScript sandbox for that.\n\nIt is a trade rather than an omission. `# @expect jq .status == \"paid\"` is\nreadable by someone who does not write code, it diffs cleanly in a pull request,\nand `squab diff` can tell a reviewer when you removed it. A block of JavaScript\nbuys power and costs all three.\n\n## Fix a failure without leaving the runner\n\nA run leaves you looking at a list of results. Move to a red row and press `i`:\nsquab closes the runner, selects that request, drops you into the editor with the\nreason it failed still on screen, and `s` sends it again. `r` reruns only the\nfailures.\n\nThat loop — run, land on the break, fix, resend — is the reason to have a runner\nand an editor in the same program.\n\n## Review what changed in a pull request\n\nBecause a collection is text in your repo, squab can tell a reviewer what\nactually changed about your API tests — not what changed in a JSON blob:\n\n```bash\nsquab diff              # working tree against HEAD\nsquab diff main         # against a branch\nsquab diff main..HEAD   # between two revisions\n```\n\n```\norders.http\n  - cancel an order\n      - request      POST {{base}}/v1/orders/42/cancel\n  ~ get an order\n      ~ url          {{base}}/v1/orders/42  →  {{base}}/v1/orders/{{id}}\n      + header X-Trace {{$uuid}}\n      - expect       jq .status == \"paid\"\n  + list orders\n  ! weaker than HEAD: cancel an order, get an order\n\n3 change(s) since HEAD · 2 weakened\n```\n\nThe last line is the point. Dropping an assertion or deleting a request makes a\nsuite pass by checking less, and that is invisible in a green build. squab names\nit.\n\n## Variables have scopes, and the scope is visible\n\nPrecedence runs `runtime > secret > env > global`, and the variable table shows\nwhich layer won and how many others are shadowed — most variable bugs are a\nvalue arriving from a layer you forgot about.\n\nSecrets live in `secrets.json` at mode 0600, outside the collections directory,\nand render masked. If that file is ever found readable by anyone else — copied\nfrom a backup, checked out with loose permissions — squab tightens it on load\nrather than reading tokens off a world-readable file. A value of the form `$(command)` is resolved by shelling out\nat send time and never written to disk:\n\n```\ntoken = $(op read op://api/token)\n```\n\n## Over SSH\n\nThere is no hosted instance — this repository is source, not a server. You run\nthe server, then SSH into the machine running it. On one machine that is:\n\n```bash\n# terminal 1 — run the server\nsquab serve -addr localhost:23234\n\n# terminal 2 — connect to it\nssh -p 23234 localhost\n```\n\n`ssh` takes a host and a port, never a URL. To reach it from elsewhere, bind a\npublic interface (`-addr :23234`), open that port, and connect with\n`ssh -p 23234 you@your-host`.\n\nYou need an SSH key for the client to offer — the server accepts any key but\nauthenticates with keys only, so a machine with no key in `~/.ssh` will be\nturned away. `ssh-keygen -t ed25519` if you have none.\n\nThe public key is the account. A key that has not been seen before gets a\nworkspace derived from its fingerprint, seeded with a working example\ncollection — no password, no signup, no session store. Workspace directories\nare named by a hash of the fingerprint rather than the fingerprint itself, so a\ndirectory listing on the host does not enumerate anyone's keys.\n\n## In CI\n\n`run` exits non-zero when an expectation fails:\n\n```bash\nsquab run smoke -env staging\n```\n\nIt writes JUnit or JSON for whatever picks up your test results:\n\n```bash\nsquab run smoke -reporter junit -reporter-export results.xml\nsquab run smoke -reporter json  -reporter-export results.json\n```\n\nOther flags that matter in a pipeline: `-i \"one request\"` to run a subset,\n`-env-var key=value` to override a variable without editing a file, `-bail` to\nstop at the first failure, `-timeout-request`, `-delay-request` and `-insecure`.\n\n## Colour and motion\n\nColour comes from [CharmTone](https://github.com/charmbracelet/x/tree/main/exp/charmtone),\nbut it is only spent where it encodes something: the method, the status class,\npass or fail, the scope of a variable. Chrome and keybinds stay neutral. The\npalette is declared per colour profile, so a 16-colour terminal degrades on\npurpose rather than by accident, and light and dark are chosen from the\nterminal's actual background colour.\n\nMotion is [Harmonica](https://github.com/charmbracelet/harmonica) springs on\nanything that changes position, plus an ambient layer — a drifting gradient\nmasthead, breathing focus rules, a shimmer while a response streams in. Ambient\nmotion redraws constantly, which is worth thinking about over a network:\n\n```bash\nsquab --no-ambient   # keep the springs, drop the drift\nsquab --still        # no animation at all\n```\n\n## Layout\n\n```\n~/.squab/\n  collections/*.http    the requests — commit these\n  environments/*.json   per-environment variables\n  globals.json          variables shared across environments\n  secrets.json          masked values, mode 0600 — do not commit these\n```\n\n## Built with\n\n[Bubble Tea](https://github.com/charmbracelet/bubbletea) ·\n[Lip Gloss](https://github.com/charmbracelet/lipgloss) ·\n[Bubbles](https://github.com/charmbracelet/bubbles) ·\n[Wish](https://github.com/charmbracelet/wish) ·\n[Harmonica](https://github.com/charmbracelet/harmonica) ·\n[gojq](https://github.com/itchyny/gojq)\n\nCharm's v2 modules live under `charm.land`, not `github.com/charmbracelet`:\n\n```\ncharm.land/bubbletea/v2   charm.land/lipgloss/v2\ncharm.land/bubbles/v2     charm.land/wish/v2\n```\n\n## Build\n\n```bash\ngo build ./...\ngo test ./...\n```\n","readmeFilename":"README.md"}