{"_id":"claude-broker","_rev":"34-8bcac1661db3dcc33c1855d3bef7d461","name":"claude-broker","dist-tags":{"latest":"0.1.39"},"versions":{"0.1.0":{"name":"claude-broker","version":"0.1.0","_id":"claude-broker@0.1.0","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"f1ccbd27318780bb194e2f42365b4a6174c49450","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.0.tgz","fileCount":45,"integrity":"sha512-MhVBYH9wCRYZDGLbiMYFu7vGkNZfNxTKIIip6v3yRePG+JemV/n+lBsqX+Jg8lRY3lpgf/AV1EYZr7MTSiU79w==","signatures":[{"sig":"MEUCIQD0IBelPsC5slvesOPATAUnzAT1I4PvpIUnaA3/iWlRAQIgaMSEP1CJHXzY9ATm3vt4cip8XTO+AzK6B54Gtr42NC8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":305278},"engines":{"node":">=18"},"gitHead":"c6d2c23db914d879d41264ae75c7c6d8092b055b","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"hacctarr","email":"hacctarr@gmail.com"},"_npmVersion":"11.13.0","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"26.2.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.0_1785095535918_0.01560585833048811","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"claude-broker","version":"0.1.1","_id":"claude-broker@0.1.1","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"0abbca06af587a746735a0522a041090c616bc14","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.1.tgz","fileCount":45,"integrity":"sha512-MZG9ktR/11mA29sVOLMAJp3VWi+r3WI1v/Rjr0N1AWPnNuA3FvwcUc2FGrzK3PNaUbJJ7D7d0pGtfDqumD8mRg==","signatures":[{"sig":"MEUCIGxHd2wx5jIWjkm/1JHm1YSfdMcMQ1knENlXQzsmMWnZAiEA+tO6+ASLtC5usy3q99qqzui75Z93q/KH5KEN6qdGb8M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":319782},"engines":{"node":">=18"},"gitHead":"e6f029ff470024f893942836e272f578d30267ca","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"hacctarr","email":"hacctarr@gmail.com"},"_npmVersion":"11.13.0","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"26.2.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.1_1785104003003_0.9653221081643686","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"claude-broker","version":"0.1.2","_id":"claude-broker@0.1.2","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"960d6a53ca5728c400e9f161ae9537ffde43762c","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.2.tgz","fileCount":47,"integrity":"sha512-vB4q8f7+s8nyRJy+U/BjDCWb+xsXwPf7k+LfBIzkSCGVkuGXOPQuwRaTIYCUWbJHcHsRI/9uD6rHyw8JaBkkyA==","signatures":[{"sig":"MEQCIGedbqvLrgIOEs+7aZ4v3s4Yt4Hz7ewMSFInDLPqBw48AiA9lcI8Mrb6axq65DbQcHFhhPKYYyyAU8PD30BJECpeKQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":328021},"engines":{"node":">=18"},"gitHead":"a8b541d11b786a22ddc5175174ec6d982ada0a84","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"hacctarr","email":"hacctarr@gmail.com"},"_npmVersion":"11.13.0","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"26.2.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.2_1785106170224_0.5129799415303318","host":"s3://npm-registry-packages-npm-production"}},"0.1.9":{"name":"claude-broker","version":"0.1.9","_id":"claude-broker@0.1.9","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"47fda331f15e0c05f1104db1744989f74b2b1f4a","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.9.tgz","fileCount":17,"integrity":"sha512-qyS8eCxThZv1AYgi39fAWcrjCdYxS6lyntJJcMsG5dTN91V5Rl0FoakTSyc6XyuSUJ05eK2MGWf6YK3HiC0jfQ==","signatures":[{"sig":"MEUCIEL0/i1BYmDS4HRXyZRqQtsWOmZ0bubI1oGABqT/debKAiEA2aAMeO8G4hGNATCgzpGWEVYLccMbI3+Y9olLfrQrKkA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74479},"engines":{"node":">=18"},"gitHead":"126a26841cfdf213468227d27a7bfd50473c54f6","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.9_1785130427913_0.011798199297830436","host":"s3://npm-registry-packages-npm-production"}},"0.1.10":{"name":"claude-broker","version":"0.1.10","_id":"claude-broker@0.1.10","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"954e0396e347903bd25355a0e5aa4a8229d495e2","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.10.tgz","fileCount":17,"integrity":"sha512-9BVa9Bu+E/wEQAySb4b7zVcBCiJ+38hqfUJg7cvaYjJjJhDRKfcj1srg6BzOdHmccB6w0Qp8/v0F5fgix2jWqA==","signatures":[{"sig":"MEUCIQCMUIfKIeua6qov47U25H3KUJr3Z5OCMUFaagznipM1GAIgG8fTknahUgMQkZ95aR3rMZo/s9/A9Ic2Topi2Mvx4o4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77029},"engines":{"node":">=18"},"gitHead":"019fb0161db5be9090e23c922d3ec2ab9c049021","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.10_1785160028431_0.05271486696315053","host":"s3://npm-registry-packages-npm-production"}},"0.1.11":{"name":"claude-broker","version":"0.1.11","_id":"claude-broker@0.1.11","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"a9d11ca93f13494d139e1a9c883c2ddf8259c42c","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.11.tgz","fileCount":17,"integrity":"sha512-GBJlOMObKR5Dl+imZwYAJhaczfhjJcaArmTL8J9sim7KqNcf9uKrbc2fX0BJJEwP75s8F4wDtR343kh5EJpPzg==","signatures":[{"sig":"MEUCIQCCysKEQ8qPsY+hHLAIRlQ2MTxn4ogfFgsvnR+jDbKeRwIgb3UWhQIndoWI2Wq3gjf0itY/eGagkYNcyBncPb2X1Sk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78420},"engines":{"node":">=18"},"gitHead":"c3d17e02ad9096246bfe38d6c3b92bbce6d1abdd","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.11_1785166573667_0.28845836583657714","host":"s3://npm-registry-packages-npm-production"}},"0.1.12":{"name":"claude-broker","version":"0.1.12","_id":"claude-broker@0.1.12","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"aa07bfa2475003bd9f5c306651bc8693fc0e0469","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.12.tgz","fileCount":17,"integrity":"sha512-TZg4UX83KiTK1ArTOxt/q9+Db/D+GJxAr5IxadVfxjh6J8LT0MwQFdBXN9DYdYtT2+bLQAu2w986qOwYckC7eQ==","signatures":[{"sig":"MEYCIQC2/6JZZAD24xPSby7IqFlP/dwDGUlGU8h0As/lOgkLggIhAJtrBw7c5fISk+NHFH2HpTkkii9TDyZXH2q/nk6VHUGZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78420},"engines":{"node":">=18"},"gitHead":"e38f32720b7cd1930761476ed5a99f6938c7b31b","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.12_1785170682010_0.39309649695143367","host":"s3://npm-registry-packages-npm-production"}},"0.1.13":{"name":"claude-broker","version":"0.1.13","_id":"claude-broker@0.1.13","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"b9e842bf9e20ba95553b0744d156238d5ac114d0","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.13.tgz","fileCount":17,"integrity":"sha512-dOv6zdTswQI53lV5Ll1aYmTVnMescDiQouhZ8Uhv/teg3uEIs8+vtNXTcbC2XtrUnaZr52gEmfMtwKqdjXUoxw==","signatures":[{"sig":"MEUCIH23AG5FQsNfNbt7tzsOe2CmXoSvTmBO02Gr6K99T0wbAiEA1uaFD+beTFnSGXYBqviNGGsb6Xbd9c/LuONXpqafcHs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79985},"engines":{"node":">=18"},"gitHead":"55380780f6640a5b28f1662d5934a4ca9fda8116","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.13_1785173168464_0.2899835186235513","host":"s3://npm-registry-packages-npm-production"}},"0.1.14":{"name":"claude-broker","version":"0.1.14","_id":"claude-broker@0.1.14","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"427b67707d2cb344b88f1cd60bc290ad79582c43","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.14.tgz","fileCount":17,"integrity":"sha512-mcqIJrul01OKDSjSAmqZ1Xc6sn+/M0hNPfuex3QXCy4jsGwGvPWeCZoRgwEADmt4bNvtQ1fJRy0Scm3qkEYpXg==","signatures":[{"sig":"MEUCIBzYmredF0aYrzt8rw5IDOZ5lSWaLURyu3pUOK2jx67+AiEA8mtfOYu8g/qZT+iXqEPbf51kzSt6G0zBb3vNTUevn1U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82515},"engines":{"node":">=18"},"gitHead":"044e639bb79861d54ef6135c77e9a3b6f8917287","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.14_1785179842818_0.6962264027996781","host":"s3://npm-registry-packages-npm-production"}},"0.1.15":{"name":"claude-broker","version":"0.1.15","_id":"claude-broker@0.1.15","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"ecb433ca2850eb33da7ba5ef6506d0a419cfb548","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.15.tgz","fileCount":17,"integrity":"sha512-kWiBBrXjmA29v5LEjlfDUCigFRtU+WKc5KH66Yv7E11wMvhGYD39H+iCi4TDTlYN/xHQv9FGJYt8Ff3CEQrpRQ==","signatures":[{"sig":"MEYCIQDTMCHF52F/H0f1+9GuvffQeY10trzQ0yBIlR/Pw0rR+QIhAKkw+2zt6uoUbTsJq5q6MPiWrlubpmdXqo7flZiST+tU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84289},"engines":{"node":">=18"},"gitHead":"18db08f9b46c83a48090c5c982d235ad90c563d6","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.15_1785192507216_0.7483580342749889","host":"s3://npm-registry-packages-npm-production"}},"0.1.16":{"name":"claude-broker","version":"0.1.16","_id":"claude-broker@0.1.16","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"283354809b4f6c228c9daf5bbdb88ed8075492a5","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.16.tgz","fileCount":17,"integrity":"sha512-sN4c8gn3OKRIZIVaS64tH+q5QIDo0m0KrkAzM5mDttfQ7FlETMv3BpBxB3LpKob3l7J6bMNiNeOZ9TjCZuwM0g==","signatures":[{"sig":"MEUCIQD0xd1J0ewE96eO6nXN0RU2Zx9St8UkWCtTumsocunk4gIgFCF0p8QoYOFiTxRdBTi70Wyx4X0iVlYgWLy+QiaW9IE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85887},"engines":{"node":">=18"},"gitHead":"9f4f9c8d414f52ee6c4ec9d337e05c3dbea3edb6","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.16_1785196524703_0.8436629304351257","host":"s3://npm-registry-packages-npm-production"}},"0.1.17":{"name":"claude-broker","version":"0.1.17","_id":"claude-broker@0.1.17","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"438bc83a37bb6e056e6f5499c707ee8345985f25","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.17.tgz","fileCount":17,"integrity":"sha512-OJHb7Xoc276trhkszRWytaAwDTUaR/gKccHWFhoNqcrKLuGW1a5CU0h5rnJk8GxrbCE6yPKMa3BrokDEKu68TQ==","signatures":[{"sig":"MEQCIAIGBQ4saZeAXWjo6rimcVBnOWzjNyGkDF08XcPtqtyUAiAFlxvrW1ZA8aqmsqInh/lRchsVirSTV8aybgwkCr2fXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86339},"engines":{"node":">=18"},"gitHead":"8781b9ab7ca48779d5b193116bd4e350db74fce6","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.17_1785257858049_0.20642253300578295","host":"s3://npm-registry-packages-npm-production"}},"0.1.18":{"name":"claude-broker","version":"0.1.18","_id":"claude-broker@0.1.18","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"6cbeee43597e8ebffb00183349cd93c4c949086c","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.18.tgz","fileCount":17,"integrity":"sha512-sR8vFhbSpjrjDdsqlVCSJ0fxd2+6tk/eGOYPUM29wNdpU0+HrINM6hU9sfk7RjHuKN0TEoD1BI1C5vFrJuXnMg==","signatures":[{"sig":"MEYCIQC98Xsmwjs0qe9+O+cooQCOChexgC2ErSPl+MfxA/heBgIhAMIsk9MIWIChqJeQWCY4yldY5CXI74dYrvP4zxyCJEJx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87274},"engines":{"node":">=18"},"gitHead":"6f696f9feaf82f3b66e15e9bd5f3dad9d244e7c9","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.18_1785262509120_0.19861553492481998","host":"s3://npm-registry-packages-npm-production"}},"0.1.19":{"name":"claude-broker","version":"0.1.19","_id":"claude-broker@0.1.19","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"03c74d17f743775eb192b59da65e5e8e83ff6672","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.19.tgz","fileCount":17,"integrity":"sha512-z6b+60vDvPsaEp8n5O2aKpDyePzViTrGlNSP9OhUX9afBR51QgyUYXYEpPkmHXaTFyl1kM+5cFqqCEBQnJx20g==","signatures":[{"sig":"MEUCIQDO/IRJiJBAXu8Kcyn+Gcp3Mws11q2z3N5VII7ETUvTjgIgJi/akVT9LprI6YWNdQfdZ9kvrLnVKYK70QtpRPipdrs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89264},"engines":{"node":">=18"},"gitHead":"829727cb122ae30c033fe67ec41f1e3b1df62a20","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.1","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.19_1785263436474_0.5208679072242635","host":"s3://npm-registry-packages-npm-production"}},"0.1.20":{"name":"claude-broker","version":"0.1.20","_id":"claude-broker@0.1.20","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"593f2712f2ecbce5362e06af694b74fbb5484a18","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.20.tgz","fileCount":19,"integrity":"sha512-qbC3O5phLLNebmMLBUx8VYyjxMDQTzEOA6Md7UQi4HL/wlkYQlHsPaXuXUiuLqflzKmTrZNiU18hDqx6JEeBug==","signatures":[{"sig":"MEUCIQCU/1hlYZNhYVwP3rfaGzsqQ2k3bXlbSVu7Za+WDmATGQIgdoz2neASZzg2/nB7SmiEwZOZ365eh2HbklEUf7OxXc4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":106484},"engines":{"node":">=18"},"gitHead":"68b08bc31bba1e6572bb85fb6037311d12bd2bfb","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.20_1786161921663_0.2590741312874869","host":"s3://npm-registry-packages-npm-production"}},"0.1.21":{"name":"claude-broker","version":"0.1.21","_id":"claude-broker@0.1.21","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"2705e1849eef0313e83d7ff7801ce8b2b7a799ec","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.21.tgz","fileCount":19,"integrity":"sha512-N+hT7Vkt15vi0YMQh0d0GpPRJGkne4QLAPvNfnFR2H58mvylkxF3tyJ1b4GjyqakduC0kd2MuyMawBMfxV8cQQ==","signatures":[{"sig":"MEYCIQDuDvw5DTB+Y3nqjbp0INu1HweBkRIli8NqBNC6Q5h8TwIhAKlg2GrNq8Vkv+xk1uL5rpOMIMXtSzu+Ra6kmnnvfcf8","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110367},"engines":{"node":">=18"},"gitHead":"b151317b6113bdd0e4c29525c34a51fc0c5565ca","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.18.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.21_1786179099078_0.8589992308528234","host":"s3://npm-registry-packages-npm-production"}},"0.1.22":{"name":"claude-broker","version":"0.1.22","_id":"claude-broker@0.1.22","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"5d407ac4ebaf92987f80cf26083ff9c9668572c9","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.22.tgz","fileCount":19,"integrity":"sha512-5gNo4MinKLEx2q5/KDLDbkyxBWrCpae/87RHSgoL5z+P8g+zI/HpSo4I28tC0V08pD3DFlo3BY9hg/lIGyn2UA==","signatures":[{"sig":"MEUCIQDq0NVumOPFj2WMh+dE2Sm6FXB0JqTbLRAHIiuB+jVjXQIgMwAc+dkymMH0y/VjpFcYWcryCrqZJ2+t0qhiTXLm5Uc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":114355},"engines":{"node":">=18"},"gitHead":"2358f6f8cb51c4d9d8a255c2de3928f67af685e7","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.22_1786735620681_0.9968774589992284","host":"s3://npm-registry-packages-npm-production"}},"0.1.23":{"name":"claude-broker","version":"0.1.23","_id":"claude-broker@0.1.23","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"a3500f67f37043ced8f6bfd22d6bb43693ba551a","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.23.tgz","fileCount":19,"integrity":"sha512-52kl4qT07JLcUTVG52g/d6+Tf6ZJ7ohB5Re9AD/IxiM5BObu1n2Kgr8R6k0AFY5Dv4ukZLHGxFqvUAgplQiHJQ==","signatures":[{"sig":"MEYCIQCBl+1ejwe4A3T/Pga4mgV8i7tE5n6AKDC0+ILOzwM+DwIhAOrK7BcXS5p1BxcJ1xLveP/ctMvYxu+dWbLhiWWtjJfP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":117414},"engines":{"node":">=18"},"gitHead":"327468d7f347f7154954ecbe8b9c02d5fd7e5ac8","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.23_1786736053798_0.7664004997115101","host":"s3://npm-registry-packages-npm-production"}},"0.1.24":{"name":"claude-broker","version":"0.1.24","_id":"claude-broker@0.1.24","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"24810f1782499b55320a5685d6b45e043f93f1ed","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.24.tgz","fileCount":19,"integrity":"sha512-xa/HrOsMH8qEP5Q/z3Mib+sw/YeYoSM1Fuk7Ydo1ObmfUilDfTS4HdcDmZZNqbghvWLaIA4fw7Fz8X8luW7CJg==","signatures":[{"sig":"MEQCIFvxXqsbAtjkj/0feyxzOdB2YFNZHIlmAnf8jcHA72HaAiBElFdl4gl/iBLMkfbaZwi6RO2ng26DEVywsAedGj8hlQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119001},"engines":{"node":">=18"},"gitHead":"db2b66b25f84a28d5b176bc3c63a40dc038f020b","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.24_1786743342759_0.4835541729335924","host":"s3://npm-registry-packages-npm-production"}},"0.1.25":{"name":"claude-broker","version":"0.1.25","_id":"claude-broker@0.1.25","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"b067cf068bdf8eadbf02537be713e849c1ba6969","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.25.tgz","fileCount":19,"integrity":"sha512-lssPXiGLyyLUpImDWOcUMnIXgH1kPYnuQHuQwpYN/fiGjVv4wUQ3ooNyEMk0XrKAXUTa/gUrtAGNWmWS/hZpUQ==","signatures":[{"sig":"MEYCIQDWYxFSsSQD6CUsxrGmP7TLrosScQJY+xiSjawx7APpqwIhANzoeWFjSSxjlT7LpFeF5T8GvQUpH87ndvVSFocRIURI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119169},"engines":{"node":">=18"},"gitHead":"ff9d74898c0f5280461f11baa6abbc87f3f36015","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.25_1786743929957_0.15475018362948556","host":"s3://npm-registry-packages-npm-production"}},"0.1.26":{"name":"claude-broker","version":"0.1.26","_id":"claude-broker@0.1.26","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"d69f328a99012eb065fb5a1850ad44555fef8ce9","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.26.tgz","fileCount":20,"integrity":"sha512-ESIW7F6udlSy2Vr2vo1UMpckKYNsD5ctwq4dPRL+vnjPLnxNzGILBQDsmOfuuzBWv/1M2VERic6xS4nYZUVirw==","signatures":[{"sig":"MEUCIQDXGju6SDgYcq1gR/DxUvgmldCNCFbtqWiPyEIySEGXcQIgHTgDfDHJV0qivNEFs/QhWMCfKSnrvbkje64GZOqSAaE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123836},"engines":{"node":">=18"},"gitHead":"6c7448441e21835eded0a60266a152dcf619100b","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.26_1786745532417_0.34208932419071214","host":"s3://npm-registry-packages-npm-production"}},"0.1.27":{"name":"claude-broker","version":"0.1.27","_id":"claude-broker@0.1.27","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"d511f321eadd89da646d98553c75115f234f271f","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.27.tgz","fileCount":20,"integrity":"sha512-z3TLQryOjwu53UMeBqFbxNiFLitHvC8IQnl5Ue+RCvsZYPt5hVMbFLE3irgHj2fC7TwSRhn+8rxa83IoIGfsZw==","signatures":[{"sig":"MEUCIQCNTFNYbC51OiWlFOul/ghoRZK3PQSQ7kuSFKc7tnL+WAIgFLYhIOCCThYt67GOxn4AvdwJ/gDIC9+3dAEFH9ZmfOw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":130411},"engines":{"node":">=18"},"gitHead":"9ef8ac2c67aa0930db9e77b4040092fc9ce74638","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.27_1786747415747_0.20580709461865054","host":"s3://npm-registry-packages-npm-production"}},"0.1.28":{"name":"claude-broker","version":"0.1.28","_id":"claude-broker@0.1.28","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"74da63d049fbdca086fafeeeab85f8d714cf5975","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.28.tgz","fileCount":20,"integrity":"sha512-h4DW3QvbKdSOCGMJn4ZpXdnwdcCZ8HYkoxOX4BJOcOuDqhvda/l0tIyPfza1DRdIwP84kumlNVsI+Lu4+5NibQ==","signatures":[{"sig":"MEQCIBfv8hpHix8VQE61psSphcfrFfJszwigWWTdHILmqk1RAiB+BAXgs/hv8Rf/W8tM/QH9rMmWyiC+h3vqSg6NshlW9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":133461},"engines":{"node":">=18"},"gitHead":"269c74c4abbdda8bf8dfb5d5502a98e5ed072276","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.28_1786748624609_0.06349280855503703","host":"s3://npm-registry-packages-npm-production"}},"0.1.29":{"name":"claude-broker","version":"0.1.29","_id":"claude-broker@0.1.29","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"66b943804ddf86bf2f8bf9102c924cff9b10b08e","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.29.tgz","fileCount":20,"integrity":"sha512-dNM8apMy8Wy2oPJI+AVJCTPDwhfUT3z0t8aKkzqXm7bZmSvwJ1Yf81I5NMBDyfMDivaQ3+KxVJW3gxUxwrlIBQ==","signatures":[{"sig":"MEQCIHRbYDDTQkerr/zGtbDx6psjXHon609aavVwHyIEw7xiAiBJ7xZSL+tZowPP1TFKAryJKAWoE4eETpj6oQI5VdzDaA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135742},"engines":{"node":">=18"},"gitHead":"4584ac6924ca46949aa8eb0096f6e5af939589ad","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.29_1786772232813_0.8829273700060316","host":"s3://npm-registry-packages-npm-production"}},"0.1.30":{"name":"claude-broker","version":"0.1.30","_id":"claude-broker@0.1.30","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"149d82a7f66f9a1e07d360289739aa88fad6d8bf","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.30.tgz","fileCount":20,"integrity":"sha512-cxHu5wpBAXwuc4uNwoGOD9//1pWCzB9YIuxnJe53upPUHrdNJ3PJib4SaX3XMrs0c5shdy30dFreHnzWcuGn5w==","signatures":[{"sig":"MEUCIG6LdJlDw9IbieWMuxIw3avJQZKtStZMqjGd5mlTSLJWAiEAjSv6sLqSJJo3lgjd2xvfSYeyuIEBS53YQM3Nsw2xJDc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":137242},"engines":{"node":">=18"},"gitHead":"c33652a70871c8a72347efc291f6d1f8335a2b40","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.30_1786773061613_0.7437408090723143","host":"s3://npm-registry-packages-npm-production"}},"0.1.31":{"name":"claude-broker","version":"0.1.31","_id":"claude-broker@0.1.31","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"ef06b7574d10fc790efb09102fcbec1ff8c5027a","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.31.tgz","fileCount":20,"integrity":"sha512-HpK5F0UcQU/rIWaZuSPAmMZp+mHUhfJRd7wu/hDKcME2KeFjkzLsI5WeF6tu/mYMTTySzrw+55HO7o9/oBI8qw==","signatures":[{"sig":"MEUCIEzbyb4fbVMCD/nyYM70GclaUWYZnVCZ8qcWh3xQuD+OAiEAud5hgKiSBicCxEqLrsaygdEFEXkcabQQD7EFN0RRHD8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":138348},"engines":{"node":">=18"},"gitHead":"99a5bad92e569398cd53fbda420fb678de4fad9c","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.31_1786773460255_0.5389419799038142","host":"s3://npm-registry-packages-npm-production"}},"0.1.32":{"name":"claude-broker","version":"0.1.32","_id":"claude-broker@0.1.32","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"4a52a74c62657f5375799564a30431efe2e59af5","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.32.tgz","fileCount":21,"integrity":"sha512-fiC7YmjzG88RTdW+4Onv2wRIkUnhcW2X53qZkHjScsz0UIdl3SVdKxB5UwiFpLooLFVoIlT92Jn/VWoh39oRkQ==","signatures":[{"sig":"MEQCICWVkaIuABVUGSrLFCGc2NZ1vHrqUEjDLiI4M2oFlk34AiBqeRENZL67FM5u+/OyYEWuTG7QxpQz3ViGxcrS2/URDA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151598},"engines":{"node":">=18"},"gitHead":"a6cd5016c4dad5fdbbdaa1d0b408dc5e4ed3027c","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.32_1786774628736_0.25561067413372274","host":"s3://npm-registry-packages-npm-production"}},"0.1.33":{"name":"claude-broker","version":"0.1.33","_id":"claude-broker@0.1.33","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"d18886cefe51a8b68faa1557fec2229228fc1ef4","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.33.tgz","fileCount":21,"integrity":"sha512-QyWoMc6bSSp021UTcUdAxu9sIs2QAcaEh8umZL8c8szgHqSX35aL2OGESBV1rB25bVVE2J6tJnQmLb8pgnJD7g==","signatures":[{"sig":"MEYCIQC2gir1tWPUGuM2/DgBT9dC1rgW+g5gvpCMakZ7tVT50wIhAI4tRauC1j1DB0GcmZ0zvzQzRCSMWlZV/cuYhEB1mCvO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":152697},"engines":{"node":">=18"},"gitHead":"ff6de70e1ea00aa5e1fb3514edb406aff52cc434","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.33_1786774809438_0.06166244150023692","host":"s3://npm-registry-packages-npm-production"}},"0.1.34":{"name":"claude-broker","version":"0.1.34","_id":"claude-broker@0.1.34","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"a600de2260cc84850021b04ada4755c626be5a44","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.34.tgz","fileCount":21,"integrity":"sha512-3POXVKNDayTbxKaZbSVcB89Qfbyc6Zf2xD+dT4BX/ZhKvYCXBkhwf+hIisCbpGFYll+XMMkaQq7uNUktECUbdw==","signatures":[{"sig":"MEQCIF2lb84762/gKLJhhA1iXx2x0FcwVJAfMGYozcCUsY5+AiA5boa366dtuztXZo77NcEYLcIAUHFFquzomZ1WcgKUww==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":153702},"engines":{"node":">=18"},"gitHead":"e13da03166f0a6b2e6bedde75cc5468c68caf67c","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.34_1786775416588_0.4317614684874329","host":"s3://npm-registry-packages-npm-production"}},"0.1.35":{"name":"claude-broker","version":"0.1.35","_id":"claude-broker@0.1.35","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"188ceb3e00c8bb294897288532524b8fa48d0071","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.35.tgz","fileCount":21,"integrity":"sha512-Pr1LPQxVciEfPA7ar2Qjq5XlizxyqRG7+nmbF58GDxY5ubYMrVBVsaM7n2S6oic6+zoTgYncUxbc54fyvLtLFQ==","signatures":[{"sig":"MEQCICtMSh8OEG5JfwpJwKLEzGUXgivXkAxyshJn2idpVjSPAiBJdZ8QbLRI2gDiejcUSckUh3bFJUa1mLAoWFt53j5nbQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":155303},"engines":{"node":">=18"},"gitHead":"4309adb65efc1bbbdc996b87c555f7542cf2cf10","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.35_1786776548294_0.6948840314856342","host":"s3://npm-registry-packages-npm-production"}},"0.1.36":{"name":"claude-broker","version":"0.1.36","_id":"claude-broker@0.1.36","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"6dd6a7052321a8e18dd323ae2d03ced1000395c9","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.36.tgz","fileCount":21,"integrity":"sha512-ZxqMSyZ9mzcViakKIoE9ko5LzOLj6TyhgOhP8FsBTMtLDf43c5bOHqDw7KNBdaw0HVdvITYYnmm9jirlrtLp2A==","signatures":[{"sig":"MEUCIQDwZ/lreXVrxb0WqhPqtOUqzVCUfccBs0impQ49yCQ4aQIgFfnKN4PNxKdQiH1+7XpMaWykk3cRgE+OEouBO2AgCkE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":157100},"engines":{"node":">=18"},"gitHead":"8e6d4123456d5d3d6ca80cff0f0e8e5fbc09e866","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.36_1786778064612_0.7069463403173859","host":"s3://npm-registry-packages-npm-production"}},"0.1.37":{"name":"claude-broker","version":"0.1.37","_id":"claude-broker@0.1.37","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"e434a81ca946b777ac3dc35c0625057aaa0bc721","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.37.tgz","fileCount":21,"integrity":"sha512-ItjvlNnI+3kaSaPMPL9XKU2Z3l/KWxpdlsIPV/IBT0Q0AHmRF60rx68+LYQdc0BuUVlqYoEQ22kefok7+OpKEQ==","signatures":[{"sig":"MEYCIQChoPCBQ7T2f7t4heVL97q7lU0x/w9ZDySRkCSLDjZ/yAIhALcvyPH7wvKmBAiNbAALVbRGTsWZJJcmlSK3wPugX+WF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":158368},"engines":{"node":">=18"},"gitHead":"b6a535b47c779df7e731777d7c4d90238edb83c4","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.37_1786778408180_0.3220860247152426","host":"s3://npm-registry-packages-npm-production"}},"0.1.38":{"name":"claude-broker","version":"0.1.38","_id":"claude-broker@0.1.38","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"bin":{"broker":"bin/broker.js"},"dist":{"shasum":"afd21f40cd8ac899e1e1bf64ae39c589a018192e","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.38.tgz","fileCount":22,"integrity":"sha512-yfj7A/vEMKD9jnB+iR3PPf3bjNK2CWaDvZsqReLcvCe6vWZ0bR/9daZil4usCI2tVBuDF3VK3qkwH1C6Mp2llw==","signatures":[{"sig":"MEQCIB9PPPe0OJ4hr/pNheckGvqQaBPSWxCP/HGwAKTAlIXtAiBzlNqFtM4h9tnXiY+sHvigaZVvy8b8qLntTuftAdFWyg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":167710},"engines":{"node":">=18"},"gitHead":"f129d3505520c98cf8f3c4ca07e638d60e6a97b9","scripts":{"test":"node --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"_npmVersion":"12.0.2","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","directories":{},"_nodeVersion":"24.19.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/claude-broker_0.1.38_1786829331402_0.6813880977425997","host":"s3://npm-registry-packages-npm-production"}},"0.1.39":{"name":"claude-broker","version":"0.1.39","description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","bin":{"broker":"bin/broker.js"},"scripts":{"test":"node --test test/*.test.js"},"engines":{"node":">=18"},"dependencies":{},"gitHead":"928f28700d52dc444090deb167ff5aee58ed60c2","_id":"claude-broker@0.1.39","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-9o+usy5PpTGS573d4TB36c8hMZtbAcEg97loxluU55+tLKCFiPHnM4P10SJLra/EblInOkjJYkYrPqmMBpAf6w==","shasum":"a22db99ca53fccc104e38f68b5a036e23fb64407","tarball":"https://registry.npmjs.org/claude-broker/-/claude-broker-0.1.39.tgz","fileCount":22,"unpackedSize":171290,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCwFj3RcNAqEKiwjg8Gnu0ZHGXWReuXY02uLKcImzVVKwIhAO9JM48OFjnPteb4b7fnhZPWUXegCWrGzslo3a0uFujy"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a923c8bf-44da-4e96-9d77-7faf5c8886fd"}},"directories":{},"maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/claude-broker_0.1.39_1787892990876_0.9937386897039537"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-26T19:52:15.744Z","modified":"2026-08-28T04:56:31.152Z","0.1.0":"2026-07-26T19:52:16.066Z","0.1.1":"2026-07-26T22:13:23.127Z","0.1.2":"2026-07-26T22:49:30.364Z","0.1.9":"2026-07-27T05:33:48.065Z","0.1.10":"2026-07-27T13:47:08.589Z","0.1.11":"2026-07-27T15:36:13.823Z","0.1.12":"2026-07-27T16:44:42.134Z","0.1.13":"2026-07-27T17:26:08.602Z","0.1.14":"2026-07-27T19:17:22.969Z","0.1.15":"2026-07-27T22:48:27.368Z","0.1.16":"2026-07-27T23:55:24.872Z","0.1.17":"2026-07-28T16:57:38.180Z","0.1.18":"2026-07-28T18:15:09.268Z","0.1.19":"2026-07-28T18:30:36.630Z","0.1.20":"2026-08-08T04:05:21.852Z","0.1.21":"2026-08-08T08:51:39.221Z","0.1.22":"2026-08-14T19:27:00.826Z","0.1.23":"2026-08-14T19:34:13.947Z","0.1.24":"2026-08-14T21:35:42.890Z","0.1.25":"2026-08-14T21:45:30.105Z","0.1.26":"2026-08-14T22:12:12.556Z","0.1.27":"2026-08-14T22:43:35.889Z","0.1.28":"2026-08-14T23:03:44.768Z","0.1.29":"2026-08-15T05:37:13.134Z","0.1.30":"2026-08-15T05:51:01.768Z","0.1.31":"2026-08-15T05:57:40.394Z","0.1.32":"2026-08-15T06:17:08.881Z","0.1.33":"2026-08-15T06:20:09.600Z","0.1.34":"2026-08-15T06:30:16.725Z","0.1.35":"2026-08-15T06:49:08.447Z","0.1.36":"2026-08-15T07:14:24.742Z","0.1.37":"2026-08-15T07:20:08.345Z","0.1.38":"2026-08-15T21:28:51.558Z","0.1.39":"2026-08-28T04:56:31.021Z"},"description":"Encrypted git hub-and-spoke broker for cross-machine Claude Code messaging.","maintainers":[{"name":"hacctarr","email":"hacctarr@gmail.com"}],"readme":"# claude-broker\n\nEncrypted git hub-and-spoke broker that lets Claude Code instances on different\nmachines hold two-way, multi-turn conversations, with strict per-machine\nisolation, no inbound network reachability, and confidentiality from the\ntransport host (GitHub).\n\nThe personal Mac is the **hub**; each job laptop is a **spoke**. The hub can\ndispatch work to a specific laptop's Claude and read the reply; a laptop's\nClaude can initiate a thread back to the hub; either side can ask a question\nmid-work and have the other side answer, resuming the paused session. No laptop\ncan reach another laptop's traffic.\n\n## Why\n\nCorporate laptops sit behind NAT with no inbound reachability, and a shared\nTelegram account risks a ban. The broker needs a transport that works over\noutbound HTTPS only and keeps engagement content unreadable to whoever hosts\nit. A private git repo per laptop, holding only `age` ciphertext, satisfies all\nthree: reachable from anywhere, no inbound ports, and confidential end to end.\n\n## Architecture\n\nHub-and-spoke, one private GitHub repo per laptop used as an encrypted two-way\nmessage bus.\n\n```\n   Personal Mac (hub)\n        |  broker-runner x3 (one per repo)   +   broker CLI\n        |\n        |== repo: broker-work-a  ==  work laptop A  (runner, key: work-a only)\n        |== repo: broker-work-b  ==  work laptop B  (runner, key: work-b only)\n        |== repo: broker-work-c  ==  work laptop C  (runner, key: work-c only)\n```\n\nIsolation is enforced at three independent layers, so \"laptops cannot talk to\neach other\" is a property of access control, not convention:\n\n1. **Separate repos.** No shared repo, branch, or folder spans two laptops.\n2. **Per-laptop deploy keys.** A laptop's git credential reaches only its repo.\n3. **Per-runner config.** A laptop's runner knows only its own repo URL.\n\nThe same `broker-runner` process runs everywhere. The hub runs one instance per\nrepo; each laptop runs exactly one. Role differences (autonomous-with-escalation\non the hub, direct execution on a laptop) are configuration, not separate code.\n\n### Encryption\n\n`age`, point-to-point, one keypair per machine. Private keys never leave the\nmachine and never enter a repo. The hub holds every laptop's public key; each\nlaptop holds only the hub's. GitHub stores only ciphertext under opaque message\nids, so content, prompts, and results are unreadable to the transport host.\n\n### Message protocol\n\nEach repo has two directional inboxes: `to-hub/<id>.age` and\n`to-spoke/<id>.age`. A decrypted envelope carries a `thread_id`, an optional\n`in_reply_to`, and a `kind`:\n\n- `task`: do this work (opens or continues a thread expecting a result)\n- `question`: cannot proceed without an answer (the sender's session parks)\n- `answer`: reply to a question. Resumes the parked session, or reconstitutes a\n  fresh one from the question and the answer when that session is gone\n- `notice`: one-way information, no blocking reply expected\n- `result`: terminal message for a thread\n\nMulti-turn works by mapping each `thread_id` to a Claude Code session id: a new\nthread pre-mints a `--session-id`; a continuation resumes with `--resume`. The\nprocessed marker is written **last**, after the reply is pushed, so\nre-processing a completed thread is a no-op (crash-safe, idempotent).\n\n### Hub autonomy and escalation\n\nWhen a laptop writes to the hub, the hub's runner handles it autonomously under\na constrained permission mode. It escalates to Marc rather than guessing when it\nhits ambiguity it cannot resolve, or when an action is flagged sensitive\n(client push/merge, deletion, outbound communication, credentials). An\nescalation queues locally and notifies Marc; the laptop thread waits. Marc\nresolves it from any Mac session with `broker answer <thread_id> \"<decision>\"`.\n\n## Telegram visibility\n\nTwo optional lanes, hub-only, that reach Marc through the existing personal\nTelegram gateway bot (reusing its token and chat id; no new bot, no Telegram\nuser account):\n\n- **Escalations** ping the DM the moment they queue.\n- **Visibility** records broker events to a local activity log and, on a\n  throttled cadence, hands the recent slice to a cheap `claude -p` turn that\n  decides whether anything is worth surfacing and returns either a short note or\n  stays silent. `broker digest` forces one on demand, and clears the events it\n  summarised; `broker digest --preview` runs the same curation but sends nothing\n  and clears nothing, which is the safe way to look at what the broker has been\n  doing. The slice handed to the curator is capped, and anything past the cap is\n  dropped oldest-first, so a curator that stays broken cannot grow the log until\n  the prompt itself becomes the reason it keeps failing.\n\nDelivery is best-effort over built-in HTTPS: a missing gateway config or a\nfailed send is logged and never blocks message processing. The activity log\nholds only short body slices in local plaintext and is never pushed to any repo.\n\n## Kanban tracking\n\nOptional, hub-only. When a `kanban` config block maps targets to board files,\nthe broker upserts one card per thread onto the target machine's own board\n(an Obsidian Kanban markdown file), so every hub-and-spoke conversation is\nvisible and tracked where Marc already tracks machine dispatches.\n\nOne card per thread, keyed by `thread_id` and updated in place as the thread\nadvances: `open`, then `waiting` when it escalates, then flipped to a checked\n`done` card when a `result` arrives. Cards live in a tool-owned `## Broker`\ncolumn so they never collide with human-managed columns. A card for a target\nonly ever writes to that target's board, preserving the same per-target\nisolation as the message bus.\n\nWrites are local, atomic (temp file plus rename), and best-effort: a missing\nboard or a failed write is swallowed and never blocks message processing. The\nfeature is off unless `kanban.boards` is configured.\n\n## Observability\n\nOptional, per machine. When an `otlp` config block is present and enabled, the\nrunner exports metrics and traces to Grafana Cloud over OTLP/HTTP-JSON. There is\nno SDK: `lib/telemetry.js` speaks the wire protocol with the built-in `https`,\npreserving the zero-dependency rule. The OpenTelemetry auto-instrumentations\nwould not help here anyway, since the broker's work is `git`, `age` and\n`claude -p` subprocesses that they cannot see.\n\nMetrics (counters cumulative for the life of the runner):\n\n| Metric | Type | Labels |\n| --- | --- | --- |\n| `broker.messages` | counter | `target`, `kind`, `direction` |\n| `broker.escalations` | counter | `target`, `reason` |\n| `broker.poll_errors` | counter | `target` |\n| `broker.claude_turn_ms` | histogram | `target`, `outcome` |\n| `broker.tokens` | counter | `target`, `type`, `model` |\n| `broker.cost_usd` | counter | `target`, `model` |\n| `broker.up` / `broker.uptime_ms` | gauge | none |\n\nOnly bounded-cardinality fields become labels. Message bodies are never exported:\nthe closest thing is the escalation `reason`, which is a fixed code such as\n`sensitive:deploy`. `broker.up` is a per-flush heartbeat, so a stale series is the\nsignal that the runner died, which no event-driven counter can express.\n\n`broker.tokens` and `broker.cost_usd` come from the `usage` and `total_cost_usd`\nfields that `claude -p --output-format json` already returns on every turn. `type`\nis `input`, `output`, `cache_creation`, or `cache_read`, so cache-creation cost\n(usually the dominant driver) is visible on its own. `model` collapses the turn's\n`modelUsage` to one label: the single model id, `multi`, or `unknown`.\n\nTraces are one `broker.poll` span per sweep per target, with a\n`broker.claude_turn` child span per handled message carrying the turn `outcome`.\nA failing sweep marks its span as an error before rethrowing. The span buffer is\ncapped so an export outage drops the oldest spans instead of growing the heap,\nand a failed export is retried on the next flush rather than dropped.\n\nExport is best-effort and never throws into message processing. Flush happens\nonce per sweep, before the `restart.flag` check, so the sweep the runner exits on\nstill ships. `service.instance.id` (from `otlp.instance`) becomes the Prometheus\n`instance` label, keeping hub and spokes separate in one stack.\n\nHost metrics and log shipping are a separate concern handled by one Grafana Alloy\nagent per machine, not by this repo. See the runbook.\n\nImport `grafana/broker-dashboard.json` into your Grafana Cloud instance for the\ndashboard: runner liveness (`broker_up`), message flow by direction/kind/target,\nmean `claude -p` turn latency, poll errors, escalations, and the runner logs\npanel from Loki. On import, bind the `Metrics source` variable to your\nPrometheus datasource and `Logs source` to Loki; the `Instance` and `Target`\nselectors populate from the live label values. The logs panel reads the\n`{job=\"claude-broker\"}` stream that Grafana Alloy ships from the runner's\n`broker.log`. Metric names are OTel-normalized\nby Grafana's OTLP gateway (dots become underscores, counters gain `_total`), so\nthe panels query `broker_messages_total`, `broker_claude_turn_ms_*`, and friends.\n\n### The runner log\n\nlaunchd redirects both the runner's streams into `broker.log` and adds nothing of\nits own, so the runner stamps every line with an ISO-8601 UTC time as it writes.\nAlloy forwards those lines to Loki with no parsing stage, which means Loki's own\ntimestamp is when the tail caught up, not when the line was written; after an\noutage the two are hours apart, and the in-line stamp is the one that is true.\n\nNothing else prunes that file. When the runner exits for a restart it moves the\nlog aside to `broker.log.1` if it has passed `log_max_bytes` (default 5 MB, `0`\nto disable), keeping the pair bounded at twice the cap. Rotation happens at exit\nrather than at startup because launchd binds the log to the process at spawn: a\nrename while the runner is live leaves it writing into the archive.\n\n### Fleet staleness\n\nExporting telemetry proves nothing about whether it arrives. A machine can stop\nshipping for nine hours with every dashboard still rendering, because the panels\nplot what exists and a dark machine simply has no series to plot. `broker fleet`\nasks the inverse question: for each machine that is *expected* to report, how\nlong has it been since its last sample.\n\nThis is hub-only by construction. A spoke's Grafana credential is write-only, so\na machine cannot read back whether its own series are still arriving. It now says\nin its own log when an export fails, but that only covers a post it attempted: a\nrunner that has stopped, crashed or lost its config posts nothing and therefore\nreports nothing, which is the state this check exists to catch. The hub holds the\nread token, so the hub is the only place the question has an answer.\n\nTwo pipelines are checked independently, because one shipping fresh says nothing\nabout the other: `node` is Alloy's host metrics (`up{job=\"integrations/macos-node\"}`,\nkeyed on `instance`) and `broker` is this repo's OTLP export (`broker_up`, keyed\non `service_instance_id`). The expectation list is declared rather than derived:\na machine dark past the lookback window and a machine that was never configured\nboth produce no series, so absence is only meaningful against a list of what\nshould be there. A reporting machine missing from that list comes back as\n`unexpected`, which is the inverse failure nobody goes looking for.\n\n```json\n\"fleet\": {\n  \"enabled\": true,\n  \"credentials_file\": \"~/.claude-broker/observability-read.env\",\n  \"stale_after_s\": 900,\n  \"expect\": [\n    { \"instance\": \"personal-mac\",         \"paths\": [\"node\", \"broker\"] },\n    { \"instance\": \"work-a-laptop\",        \"paths\": [\"node\", \"broker\"] },\n    { \"instance\": \"work-b-laptop\",        \"paths\": [\"node\", \"broker\"], \"stale_after_s\": 43200 }\n  ]\n}\n```\n\n`credentials_file` is an env-style file holding `GRAFANA_READ_TOKEN`,\n`PROMETHEUS_READ_USER` and `PROMETHEUS_READ_URL` (the URL already ends in the\nAPI version segment). A missing variable names itself rather than sending an\nempty auth header, and every other silent-success path throws too: a non-success\nquery body, a non-200 response, and an enabled block with no expectations.\n`broker fleet` exits 1 when anything is stale, absent, unexpected, or\nunconfigured, so a LaunchAgent can key on the code instead of parsing the report.\n`--notify` sends that report over the Telegram lane, and only when the failing\nset has changed since the last `--notify` run: a machine dark for two days pages\nonce rather than once per scheduled check, deepening from stale to absent pages\nagain because it is a different fault, and recovery sends an all-clear naming\nwhat cleared. The last-seen set is kept in `<state_dir>/fleet-state.json`; a\nbare `broker fleet` neither reads nor writes it, so a human running the check by\nhand cannot consume a transition the scheduled run has not reported yet. An\nunwritable state file degrades to paging every run rather than to silence.\n\n## Install\n\nPer machine, deployed as a launchd LaunchAgent. Full runbook, including key\ngeneration and distribution and the `config.json` for each role, is in\n[deploy/KEY-DISTRIBUTION.md](deploy/KEY-DISTRIBUTION.md).\n\n```\nBROKER_DIR=<repo root> ./deploy/install-runner.sh\n```\n\nGraceful restart after a config or code change: `touch ~/.claude-broker/restart.flag`\n(never `launchctl kickstart`, which SIGKILLs the runner's own process group).\n\n## CLI\n\n```\nbroker send <target> <kind> \"<body>\" [--cwd DIR] [--thread ID]   # dispatch a message\nbroker answer <thread_id> \"<decision>\"                            # answer a question / resolve an escalation\nbroker read [<target>] [--thread ID]                              # print decrypted messages / a thread\nbroker threads                                                    # list threads and their sessions\nbroker digest                                                     # force a visibility note now, then clear those events\nbroker digest --preview                                           # same curation, sends nothing, clears nothing\nbroker fleet                                                      # age of each expected machine's last sample; exit 1 if any is failing\nbroker fleet --notify                                             # same check, and Telegram the report when the failing set changes\n```\n\n`<target>` is a short name (`work-a`, `work-b`, ...) resolved through the hub's\nconfig. The names are yours; the hub's `repos` map defines them.\n\n## Configuration\n\nPer-machine `~/.claude-broker/config.json` sets `role` (`hub`|`spoke`), the repo\nmap, the `age` identity and recipient public keys, `claude_path`, a\n`cwd_allowlist`, the escalation rule, the hub-only `notify` block for Telegram,\nand the hub-only `kanban` block for board tracking, plus the optional\n`permission_prompt` allow-list, the optional `otlp` block for Grafana Cloud\nexport, and the hub-only `fleet` block for the staleness check. See the runbook\nfor annotated examples of both roles.\n\n### Pinning the child MCP surface\n\n`child_mcp_servers` bounds the MCP servers a spawned `claude -p` turn loads. The\ntools array leads the cached prompt prefix, so a child that lets its servers\nconnect asynchronously grows that array mid-turn and invalidates the prefix; the\nconversation is then rewritten to cache at the 1h TTL, which bills at twice the\nbase input rate.\n\n    absent        inherit the machine's full MCP surface (the behavior before this key existed)\n    []            no MCP servers at all\n    [\"a\", \"b\"]    only these, resolved by name from the pool\n\nThe pool is the top-level `mcpServers` object of `~/.claude.json`, overridable\nwith `mcp_pool_file`. A name absent from the pool is reported once at startup and\nskipped, never silently dropped. Note the pool bounds only what can be *named*:\nwith a pinned array, `--strict-mcp-config` also excludes project-scoped and\nplugin-provided servers, which the pool never lists. This mirrors the telegram\ngateway's `CHILD_MCP_SERVERS` contract, so one mental model covers both spawn\npaths on a machine running both.\n\n### Bounding a thread's context\n\nA resumed thread re-reads its whole accumulated history every turn, and that\nre-read is the dominant cost: cache read measured 46% of spend on the machine\nthis was built for. `max_thread_turns` sets a ceiling. Past it, the next task on\nthat thread mints a fresh session instead of resuming, which is already a proven\npath since an expired session takes it and the envelope carries the question.\n\nUnset or `0` means never rotate, so a machine that has not opted in keeps exactly\nits previous behaviour. Every turn on the thread counts, including an answer\nresuming a parked session, since that turn re-reads the same history. An answer\nis never itself rotated: reaching the session holding the parked question is the\nwhole point of one. Reconstituting a thread restarts the count, because the fresh\nsession carries none of the dead one's history.\n\n### Answering permission prompts\n\nOutside `bypassPermissions`, the harness gates a sensitive path (anything under\n`~/.claude`, `~/.ssh`, and similar) by *asking*, not denying. A headless `claude -p`\nwith no way to answer that ask cannot proceed: the tool call is refused, and the\nturn reports work it never did. `permission_prompt` gives the spawned child an\nanswer route, so a machine whose policy forbids `bypassPermissions` can still take\nbroker work that touches those paths.\n\n```json\n\"permission_prompt\": {\n  \"enabled\": true,\n  \"audit_log\": \"~/.claude-broker/permission-audit.jsonl\",\n  \"allow\": [\n    { \"tool\": \"Write\", \"paths\": [\"/Users/you/.claude/settings.json\"] },\n    { \"tool\": \"Edit\",  \"paths\": [\"/Users/you/.claude/**\"] },\n    { \"tool\": \"Bash\",  \"commands\": [\"/Users/you/.claude/plugins/cache/*/*/*/scripts/config-sync.sh\"] }\n  ]\n}\n```\n\nDeny by default. A request is allowed only when a rule names its tool exactly and\nthe rule's own matcher accepts the request. A rule carries `paths` or `commands`,\nnever both.\n\n`paths` is matched against `input.file_path`. `**` spans separators and a single `*`\nstops at one, so a rule written for one directory does not silently cover the tree\nbelow it. Both sides are canonicalized through `realpath` before matching, so neither\n`..` nor a symlink out of an allowed directory widens a rule.\n\n`commands` is matched against `input.command`, as a glob over the command or any\nspace-delimited prefix of it: the named program alone, or that program followed by its\nown arguments. `*` works here too, which is what lets a rule name a path that moves,\nsuch as the version hash in an installed plugin's directory. Prefix matching a shell\nstring is where allow-lists get walked through, so any request containing `; & | < > `\nbacktick, `$`, parentheses or a newline is denied outright no matter what it starts\nwith, and a rule whose own text carries one of those is rejected at load. What a rule\ngrants is one program with its arguments, never a chain.\n\nWrite the program path unquoted in the rule. A matched pair of quotes wrapping the\nwhole program path comes off the request before matching, so a rule naming\n`/opt/bin/sync.sh` still covers `\"/opt/bin/sync.sh\" --apply`, which is the form a\nmodel produces when the command it is copying was written with quotes. The variable\nform is a different case and stays denied: `\"${PLUGIN_ROOT}/scripts/sync.sh\"` carries\na `$`, and text whose meaning depends on the environment is not something a rule can\nhave named. Dispatch prompts should spell the path out.\n\nA rule with no `tool`, or `tool: \"*\"`, is rejected when the config loads rather than\ncompiled, because a wildcard would be `bypassPermissions` by another name. For the\nsame reason a `Bash` rule must carry `commands`: for every other tool an absent\nmatcher is a defensible \"this tool, anywhere\", but for `Bash` it would be every\ncommand on the machine.\n\nEvery decision appends one JSON line to `audit_log` (defaults inside `state_dir`),\nand a denial tells the model to stop and put the request to the operator, which\narrives on the bus as a `NEEDS-INPUT` question rather than as a silent failure or an\nimprovised workaround.\n\nThis clears the permission layer only. A seatbelt sandbox is a separate gate: where\n`~/.claude` sits in a `denyWithinAllow` list, Bash there still returns `Operation not\npermitted` no matter what this allow-list says.\n\nString fields in the `otlp` block expand `${VAR}` references from the process\nenvironment, and the runner reads `~/.claude-broker/observability.env` (0600) at\nstartup. The access token therefore lives in exactly one file: not in this repo,\nnot in `config.json`, and not in the world-readable LaunchAgent plist. An unset\nreference is left verbatim so a missing secret fails visibly instead of becoming\nan empty credential.\n\n## Development\n\nZero runtime dependencies. Node >= 18. Tests use the built-in `node:test`\nrunner and run fully offline against local bare git remotes and throwaway `age`\nkeypairs, with the Telegram and `claude -p` seams injected (no real network or\nmodel calls).\n\n```\nnpm test          # node --test test/*.test.js\n```\n\nThe `age` and `age-keygen` binaries must be on PATH to run the encryption tests.\n\nLayout:\n\n- `lib/`: envelope, age, config, repo I/O, thread store, claude adapter,\n  escalation, runner, the permission allow-list (`permission`), the visibility\n  feature (`notify`, `activity`, `visibility`), and kanban board tracking\n  (`kanban`).\n- `bin/`: `broker.js` (CLI), `runner-main.js` (launchd entrypoint / loop), and\n  `permission-server.js` (the child's approval MCP server).\n- `deploy/` — LaunchAgent template, install script, key-distribution runbook.\n- `docs/` — design spec and implementation plan.\n\n## Status\n\nDeployed, carrying real traffic between the hub and its spokes. The defects that\ntraffic has surfaced, and what closed each one, are recorded in\n`.superpowers/sdd/progress.md`, along with the v1 follow-ups still open: the\ninert `broker send --timeout` and `threads --open` flags, and the `processed`\nlist every poll scans, which nothing prunes.\n","readmeFilename":"README.md"}