Raw JSON report machine-readable
{
"data": {
"repo": {
"topics": [
"nostr"
],
"is_fork": false,
"size_kb": 1217,
"has_wiki": false,
"homepage": null,
"languages": {
"Just": 764,
"Dockerfile": 479,
"JavaScript": 1248,
"TypeScript": 496697
},
"pushed_at": "2026-07-20T16:21:17Z",
"created_at": "2021-01-04T17:15:39Z",
"owner_type": "Organization",
"updated_at": "2026-07-20T16:22:16Z",
"description": "Tools for developing Nostr clients.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Unlicense",
"default_branch": "master",
"license_spdx_raw": "Unlicense",
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript"
]
},
"owner": {
"blog": "https://nbd.wtf",
"name": "nbd",
"type": "Organization",
"login": "nbd-wtf",
"company": null,
"location": "United States of America",
"followers": 183,
"avatar_url": "https://avatars.githubusercontent.com/u/105998108?v=4",
"created_at": "2022-05-22T00:31:06Z",
"is_verified": null,
"public_repos": 34,
"account_age_days": 1523
},
"license": {
"state": "standard",
"spdx_id": "Unlicense",
"raw_spdx": "Unlicense",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v2.0.0",
"kind": "major",
"published_at": "2023-12-19T17:33:31Z"
}
],
"recent_commits": [
{
"oid": "bd02fc3287987287c796edc6bab7ea038858946d",
"body": "…implemented.",
"is_bot": false,
"headline": "pass the relay URL to verifyEvent() so trusted-relay policies can be …",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-20T16:01:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c66469dc7545d1944b12a2b6ffe5ecef74c3669f",
"body": null,
"is_bot": false,
"headline": "declare a missing type.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-17T23:55:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "05c2836218ba2cf2dd45cfd9916576e733140b33",
"body": null,
"is_bot": false,
"headline": "add favorite follow sets kind.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-17T00:08:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fa21fd66711920eb1aaaf80be5850309fe24290d",
"body": null,
"is_bot": false,
"headline": "replace ad-hoc regexes with isHex32().",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-16T23:24:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "585258516b650506361ba19a6e6d992c52ad3d96",
"body": null,
"is_bot": false,
"headline": "blossom: optimize hash extraction from url.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-16T23:24:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cbb1b9688d4b8646c437e7a47116adeb2db5573c",
"body": "…reason[].",
"is_bot": false,
"headline": "subscribeMap's onClose is now called with {url, reason}[] instead of …",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-14T16:17:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b1406da48ee5bf0e4f26bfaa2f140b06b5a0d09d",
"body": null,
"is_bot": false,
"headline": "blossom: send content-type header when uploading.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-14T01:28:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "514678b1024ec8e1c5b0284adac26a2d98c54ff2",
"body": null,
"is_bot": false,
"headline": "automatically closed unused relay connections after a while.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-13T14:24:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21d11f149653ac7c61b9dfb0bfc9f2c078da341b",
"body": null,
"is_bot": false,
"headline": "export new modules to jsr.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-01T03:49:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "08b676a8a488a9b13af194252ed6e6ad65e9f444",
"body": null,
"is_bot": false,
"headline": "nip45 helpers and pool.countMany() with HLL.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-01T03:17:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e07ed919c5e638d6f6ea10ef63b624f7e2cf98fd",
"body": null,
"is_bot": false,
"headline": "relay.countWithHLL()",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-07-01T02:43:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf1c218bfcc79225491551467a491caf28a25c92",
"body": null,
"is_bot": false,
"headline": "add a nipb0.ts with blossom helpers.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-26T22:00:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "73ff3660aceed1b8dc4990e4b63142d2c8094792",
"body": null,
"is_bot": false,
"headline": "add a bunch of kind numbers.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-26T21:59:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c5f7f3cbe10c316c5385e7ca05e9bdc9f1326d65",
"body": null,
"is_bot": false,
"headline": "catch EVENT/COUNT sending errors.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-26T01:20:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e9b40dca7c0bb3d19317ddf166c09e01c24ed8a8",
"body": null,
"is_bot": false,
"headline": "nip46: support client metadata for the bunker:// flow.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-23T12:16:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dab630de34c0458457798f65d7321020674c02bc",
"body": null,
"is_bot": false,
"headline": "nip10/nip22: guard against malformed tags.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-23T00:20:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "455124eecd01d2c8792b29fa3b4eb75cd31fef9c",
"body": "…ed reconnect attempt\n\nA single failed reconnect attempt (`ws.onerror` or connect timeout)\nset `skipReconnection = true`, which made `handleHardClose` close\nevery subscription on the relay and remove it from the pool. The\nintent of fb7de7f was to give up on the *initial* connect failure\n(a relay tha\n[…]\n Only `skipReconnection` on\nthe first attempt (`reconnectAttempts === 0`), so retries fall\nthrough to `handleHardClose` and schedule another attempt as the\n`resubscribeBackoff` array clearly intended.",
"is_bot": false,
"headline": "fix(reconnect): don't permanently kill subscriptions on a single fail…",
"author_name": "hoppe",
"author_login": "tajava2006",
"committed_at": "2026-06-20T16:40:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "35753681761778e44ef272612a380849bbd90fd5",
"body": "probably fixes https://github.com/nbd-wtf/nostr-tools/issues/223",
"is_bot": false,
"headline": "nip19: TLV infinite loop again.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-15T21:22:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e17366cd2e00e2009e23c09f77a33082ae7452c7",
"body": "fixes https://github.com/nbd-wtf/nostr-tools/issues/537",
"is_bot": false,
"headline": "add AUTH recommendations to README.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-06-11T01:09:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7b1574d45c1ae72755ac7bad4fb93a61018ad19c",
"body": null,
"is_bot": false,
"headline": "Fix linting",
"author_name": "hzrd149",
"author_login": "hzrd149",
"committed_at": "2026-06-11T00:47:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3defeeb7967d8aa914469c833853d24b991a1d29",
"body": null,
"is_bot": false,
"headline": "nip46: add logout method",
"author_name": "hzrd149",
"author_login": "hzrd149",
"committed_at": "2026-06-11T00:47:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5de4f4549b41be05d30d85cbb40e8adb3ec75084",
"body": null,
"is_bot": false,
"headline": "fix jsr export.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-05-19T00:11:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ed47ef8ef73d78c338fbaf530e48be0fd4282194",
"body": null,
"is_bot": false,
"headline": "bump version.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-05-18T23:52:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9e89e16e33b8e393f10eb0d2f83050c418cc27c",
"body": null,
"is_bot": false,
"headline": "nip22: like nip10, but for kind:1111 and adjacent kinds.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-05-18T23:52:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3cd26d7d76605a1d7fb123ba8515ef019b0d1805",
"body": null,
"is_bot": false,
"headline": "nip44: fix test sha256.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-05-18T23:52:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e1f3ffdece5e7899e9b96015cacb30897b5e99a6",
"body": null,
"is_bot": false,
"headline": "fix: format pool.test.ts and relay.test.ts (pre-existing)",
"author_name": "Kai",
"author_login": "kai-familiar",
"committed_at": "2026-04-25T16:41:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1f2c967b042e2972fe29cc4ad42ef5928e2ff33e",
"body": "NIP-47 connection strings can specify multiple relay params, but\nparseConnectionString only returned the first one.\n\nAdds a 'relays' field (string[]) to NWCConnection while keeping the\nexisting 'relay' field (deprecated) for backward compatibility.\n\nFixes #494",
"is_bot": false,
"headline": "feat(nip47): support multiple relays in parseConnectionString",
"author_name": "Kai",
"author_login": "kai-familiar",
"committed_at": "2026-04-25T16:41:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b8c24228228f6a1eb49d5fe082388b5dc2034eb",
"body": "Fixes #531. When automaticallyAuth is configured and a relay closes the\nconnection between sending the AUTH challenge and the client sending\nthe signed response, the SendingOnClosedConnection error was propagating\nas an unhandled promise rejection.\n\nThis is a race condition that commonly occurs with\n[…]\nnection before the client can respond.\n\nThe fix catches the SendingOnClosedConnection error specifically in the\nAUTH case handler, preventing unhandled rejections while still propagating\nother errors.",
"is_bot": false,
"headline": "fix(nip42): catch SendingOnClosedConnection during automatic AUTH",
"author_name": "Kai",
"author_login": null,
"committed_at": "2026-04-14T11:24:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8260e6245d17c3900a940d573682737a5911c819",
"body": "* nip44: support encryption of payloads larger than 65535 bytes\n\nImplement the extended prefix format from nostr-protocol/nips#1907\nwith bug fixes:\n\n- When plaintext length >= 65536, pad with a 6-byte prefix (2 zero\n sentinel bytes + 4-byte u32 BE length) instead of the 2-byte u16\n- Detect the sent\n[…]\nated extended prefix buffer\n- calcPaddedLen at 2^30+1, 2^31, and 2^32-1\n- Multi-byte UTF-8 at the 65536 byte boundary (pad/unpad + e2e)\n- Spec test vectors with SHA-256 checksums for 65535/65536/65537",
"is_bot": false,
"headline": "nip44: support encryption of payloads larger than 65535 bytes (#527)",
"author_name": "Alex Gleason",
"author_login": "alexgleason",
"committed_at": "2026-04-11T02:21:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "007e0b41d07ed942b326b84152dd52ff22d70ed8",
"body": "Adds a skipSwitchRelays option that prevents automatic switchRelays()\ncall in fromURI. This is useful when users want to call switchRelays\nmanually at their own pace, avoiding race conditions when making\nimmediate RPC calls after connection.\n\nFixes #526",
"is_bot": false,
"headline": "feat(nip46): add skipSwitchRelays option to BunkerSignerParams",
"author_name": "Kai",
"author_login": null,
"committed_at": "2026-03-28T13:14:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8be6d08a43ae00a2ba11bbed3bb532672522ad48",
"body": "Addresses #494. The NIP-47 spec allows multiple relay parameters in\nconnection strings, but parseConnectionString only returned the first one.\n\nChanges:\n- Add 'relays' field to NWCConnection interface (string array)\n- Use searchParams.getAll('relay') to capture all relays\n- Keep 'relay' field for ba\n[…]\ncompatibility (returns first relay)\n\nThis is backwards compatible - existing code using connection.relay\nwill continue to work, while new code can use connection.relays to\naccess all specified relays.",
"is_bot": false,
"headline": "fix(nip47): support multiple relays in parseConnectionString",
"author_name": "Kai",
"author_login": "kai-familiar",
"committed_at": "2026-03-27T10:02:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1b955bdbcb7775833930836930b44e88949101cd",
"body": null,
"is_bot": false,
"headline": "fix: window.printer is undefined in AbstractRelay._onmessage",
"author_name": "d3vv3",
"author_login": "d3vv3",
"committed_at": "2026-02-28T04:01:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1c1e2cc51a6f93a0f26a5e7cc7804b6a513e57b6",
"body": null,
"is_bot": false,
"headline": "verify event should catch exceptions from basic validation.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-26T21:10:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "54199504a77882bc75176ffcbd3c349afbe195d2",
"body": null,
"is_bot": false,
"headline": "oninvalidevent",
"author_name": "arthurfranca",
"author_login": "arthurfranca",
"committed_at": "2026-02-26T21:08:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e45a9987e2cbbbb38d0778e7e6e1ea1946e8c145",
"body": null,
"is_bot": false,
"headline": "pool: prevent edge case with undefined subcloser.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-12T18:08:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0c2c2cd4d871dfb47ae5f5d0add758dffb57d214",
"body": null,
"is_bot": false,
"headline": "nip13: improve mining by skipping hex.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-08T04:06:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "28f7553187d201088c8a1009365db4ecbe03e568",
"body": null,
"is_bot": false,
"headline": "fix a type so jsr is happy.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T21:49:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca29d9b515f86436d857a7621bd42be81d8fa977",
"body": null,
"is_bot": false,
"headline": "ok, we need the prepareSubscription method.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T21:46:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ab802c8dbe35d29feb732ba54e82a346c21c32e2",
"body": "… so they can be pruned.",
"is_bot": false,
"headline": "automatic prune broken relay objects and keep track of relay idleness…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T21:44:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9db705d86c0798eb945e97a0d1c45326d5da680d",
"body": null,
"is_bot": false,
"headline": "delete queue test since we don't have queues anymore.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T20:01:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "be9b91318fea6a0cb154b8734a15b50a4c1e7638",
"body": null,
"is_bot": false,
"headline": "relay: get rid of the message queue, because js is single-threaded.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T12:06:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c2423f7f31853d97fef2e3d649204cec328e81d5",
"body": null,
"is_bot": false,
"headline": "nip27: fix hashtag parsing after newline or other characters.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T11:56:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "05b1fba5113182ac0aa3c72d1f511cd956a7c139",
"body": "…aries better.",
"is_bot": false,
"headline": "export source files so they can be imported by other ts apps and libr…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-02T03:38:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2d1345096bcd58ba08e382f3279ef19a3df7c25b",
"body": "…beEose.",
"is_bot": false,
"headline": "subscribeMany and subscribeManyEose are the same as subscribe/subscri…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-01T20:19:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6fc7788a4fb9b4df6285160096a36b251d7db4dd",
"body": null,
"is_bot": false,
"headline": "utils: merging two (reverse) sorted lists of events.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-02-01T11:44:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2180c7a1fe7943bbf6870c6e037b227768179c6b",
"body": null,
"is_bot": false,
"headline": "add onRelayConnectionSuccess to pair with onRelayConnectionFailure.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-31T22:27:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b4bec2097d78ee2273811e2c6be1a6250ecb070f",
"body": "…r all.",
"is_bot": false,
"headline": "finally stop reconnecting when the first connection fails once and fo…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-31T22:27:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fb7de7f1aa94adf7f35952f83df402acad4f0c56",
"body": null,
"is_bot": false,
"headline": "prevent reconnections when initial connection fails.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-31T16:57:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ccb9641fb94ed7fbe5424f06b3916da48ed1da99",
"body": "this was so obvious.",
"is_bot": false,
"headline": "pool: maxWaitForConnection parameter.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-31T03:27:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b624ad4059bf5f035978ea20239a93f3dac879b0",
"body": "… a connection should be attempted.",
"is_bot": false,
"headline": "pool: hooks to notify when a relay fails to connect, then ask whether…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-30T20:35:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b3d314643a6d39b5e760d29bda2b117d2299b585",
"body": null,
"is_bot": false,
"headline": "make everything dependent on npm again.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-30T10:16:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30ac8a02c2cb05736d233dd47c1516373b09f875",
"body": null,
"is_bot": false,
"headline": "readme to point only to jsr because npm is awful.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-28T20:28:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "42c9c7554dd5e0cd7a7c8e986d3a71fd4a973bf8",
"body": null,
"is_bot": false,
"headline": "migrate to jsr dependencies for @noble and @scure.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-28T02:54:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3588d300447d0708321bc360dbf7dcb833d24609",
"body": null,
"is_bot": false,
"headline": "do the same for @noble/ciphers and @scure packages.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-28T01:43:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b40f59af74766a70e1a636b6c0acdf5d54060a12",
"body": "This commit upgrades the noble cryptography dependencies to v2.0.1, which includes:\n\nBreaking changes addressed:\n- Updated all @noble imports to include .js extensions (required by v2 ESM-only API)\n- Changed @noble/hashes/sha256 to @noble/hashes/sha2.js across 8 files\n- Fixed secp256k1 API changes: \n[…]\n security updates from audited noble libraries\n- Smaller bundle sizes from v2 optimizations\n- Future-proof ESM-only compatibility\n- All tests passing\n\nCo-authored-by: OpenCode <opencode@anomalyco.com>",
"is_bot": false,
"headline": "Upgrade to @noble/curves ^2.0.1 and @noble/hashes ^2.0.1",
"author_name": "lemonknowsall",
"author_login": "happylemonprogramming",
"committed_at": "2026-01-24T12:41:15Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bfa40da3162d630b7e38aa32b0276cf7ba092c0e",
"body": null,
"is_bot": false,
"headline": "nip46: improve fromURI() and implement \"switch_relays\".",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-23T00:50:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9078f45a64abc205d47212d2fa9c7498ff9fa973",
"body": null,
"is_bot": false,
"headline": "optionally take an AbortSignal on subscriptions.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2026-01-23T00:49:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6ebe59f1239176598140ceae6b3277edca77ecc4",
"body": null,
"is_bot": false,
"headline": "nip27: support note1 entities for now, but treat them like nevent.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-17T20:48:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0235b490fa54f81da2dfac91b147abc1ac953e69",
"body": null,
"is_bot": false,
"headline": "nip27: fix trailing / in urls.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-12T00:23:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e290f98a86a6587e67b1cb0c094d39c4f0e5ffad",
"body": null,
"is_bot": false,
"headline": "label forced ping subscription.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-11T00:06:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7a50d9328d1577fd07cfc37cd59b30808f08bdec",
"body": null,
"is_bot": false,
"headline": "add some more kinds.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-09T13:56:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "65412e5b85f9634ad359d2ab4674b0ec32cc4930",
"body": null,
"is_bot": false,
"headline": "NostrEvent > Event.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-06T15:21:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca36ae9530d54d24fa8b724f257452d19c166bad",
"body": null,
"is_bot": false,
"headline": "update README with new enableReconnect() behavior.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-06T00:59:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0b6543e1a825697dd4bd87eb9bf6f97e62c9ce53",
"body": "prevent call stacks from building up",
"is_bot": false,
"headline": "use setInterval() instead of nested setTimeout()s for pingpong.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-06T00:46:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "693b262b7c3c56a9d05a6b5ded21ff5a31a547c6",
"body": null,
"is_bot": false,
"headline": "CLOSED answers to dummyReq are also ok.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-06T00:03:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "85c964be3d227a5d43e1374a831db114f7c715e0",
"body": "…eceived event on each subscription.",
"is_bot": false,
"headline": "enableReconnect() always update the filters to the time of the last r…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-05T16:24:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "de7d459f6fa0d70523b345f6fa0f97012fe85852",
"body": "…onnecting.",
"is_bot": false,
"headline": "only transform filters with enableReconnect() when we're actually rec…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-05T12:22:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21ec5bb2dcab86f555ce674b89efb2f94ff5de18",
"body": null,
"is_bot": false,
"headline": "allow automatically performing AUTH against all relays.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-12-05T12:12:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e959409c14e7e00a85a37a3c353fe5a51e92b297",
"body": null,
"is_bot": false,
"headline": "fix classifyKind() test.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-26T01:21:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8a76c4e3293570c905d126a432132b6aab99dc8c",
"body": null,
"is_bot": false,
"headline": "fix normalizeUrl to make websocket urls out of http urls.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-26T01:20:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "34a1d8db47352227642c19d4c5ce703c950b22ea",
"body": null,
"is_bot": false,
"headline": "kinds: more reliable regular/replaceable kind figuring.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-24T23:08:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d3ddd490c233986f1e858b5d079d7c218d3d76ba",
"body": null,
"is_bot": false,
"headline": "nip27: test emoji behavior when no tags.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-23T01:23:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7730e321a58d808f2610c7c08606f1d0c4034524",
"body": null,
"is_bot": false,
"headline": "nip27: support more image, audio and video extensions.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-22T23:36:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "400d132612b9f6f3c928073e6c9fba3690f73788",
"body": null,
"is_bot": false,
"headline": "nip77: negentropy tests and small fixes.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-21T22:51:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "01880b6fb5a65c49cb144b7c0f170bf7f704deeb",
"body": null,
"is_bot": false,
"headline": "nip27: parse emoji shortcodes and hashtags too.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-21T03:37:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e87ffc433cebf4b4772f8c0b1999d300b6c8a02e",
"body": null,
"is_bot": false,
"headline": "build \"core\" although we shouldn't.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-21T03:37:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c45e86149326a0524a06a3ca41ede8787f2c6998",
"body": "this was broken during the negentropy stuff.\n\nfixes https://github.com/nbd-wtf/nostr-tools/issues/517",
"is_bot": false,
"headline": "fire subscriptions.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-19T17:53:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "66cc55c7f0f6c7d1466cfa9cefc97b6846e3009a",
"body": "supersedes https://github.com/nbd-wtf/nostr-tools/pull/516",
"is_bot": false,
"headline": "nip77: negentropy implementation and nip77 interface.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-18T12:33:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5841b0936beed868baad79438aaa162b8f541188",
"body": "fixes https://github.com/nbd-wtf/nostr-tools/pull/497",
"is_bot": false,
"headline": "throw when subscription is created without filters.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-11-18T11:09:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f5d0c0eb0fea46a59eabf14961d79d33ea46b9fd",
"body": null,
"is_bot": false,
"headline": "fix prettier checks on nip77 related *ts files",
"author_name": "max-gy",
"author_login": null,
"committed_at": "2025-11-18T11:06:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e19db61bec2c8a4d7fee32904a4ce7d0ea74aeab",
"body": "…geChannel",
"is_bot": false,
"headline": "nip77: adds wrapper for negentropy and fallback for yieldThread Messa…",
"author_name": "max-gy",
"author_login": null,
"committed_at": "2025-11-18T11:06:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1e0f3932687a4cdbce703ee734d46d4fc2992994",
"body": null,
"is_bot": false,
"headline": "Fix subscribeMap EOSE grouping. Fixes #514",
"author_name": "Chris McCormick",
"author_login": "chr15m",
"committed_at": "2025-10-29T11:18:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1bec9fa3650ed8526c2eda460fd0f2f7bad73128",
"body": "* New test for pingpong memory leak (failing).\n\n* Shim once in relay ping mem test.\n\n* Fix pong memory leak with .once.\n\nFixes #511.\n\n* Fix missing global WebSocket on Node.\n\n* Lint fix.\n\n* Remove overkill WebSocket impl check.",
"is_bot": false,
"headline": "Ping pong memory leak fix for #511 (#512)",
"author_name": "Chris McCormick",
"author_login": "chr15m",
"committed_at": "2025-10-27T02:33:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e8927d78e6281c4000384beefdac6d7da5ad8330",
"body": null,
"is_bot": false,
"headline": "nip57: lud16 must take precedence over lud06",
"author_name": "雪猫",
"author_login": "SnowCait",
"committed_at": "2025-10-12T14:01:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bc1294e4e6ed30d1056cace7378aa08b9419b7bd",
"body": "https://github.com/nbd-wtf/nostr-tools/pull/507",
"is_bot": false,
"headline": "Reconnect with exponential backoff flag: `enableReconnect` (#507)",
"author_name": "Chris McCormick",
"author_login": "chr15m",
"committed_at": "2025-09-30T13:01:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "226d7d07e286ac4b67f554a68cb0e8a8aa1f5a2f",
"body": "https://github.com/nbd-wtf/nostr-tools/pull/506",
"is_bot": false,
"headline": "Improvements to enablePing() & tests (#506)",
"author_name": "Chris McCormick",
"author_login": "chr15m",
"committed_at": "2025-09-29T13:41:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c9ff51e2782813d1c2f908374d3e030f6d96beee",
"body": "…me REQ.\n\nbecause the initiative to get rid of multiple filters went down.",
"is_bot": false,
"headline": "subscribeMap() now sends multiple filters to the same relay in the sa…",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-09-20T19:54:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "23aebbd341473a00da5fd535dcae2932a150e33c",
"body": null,
"is_bot": false,
"headline": "update NIP-27 example in README",
"author_name": "Anderson Juhasc",
"author_login": "Anderson-Juhasc",
"committed_at": "2025-08-27T13:32:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a3fcd795451e35c4799b6cb36ea42ebe1e9849de",
"body": null,
"is_bot": false,
"headline": "ensures consistency for .jpg/.JPG, .mp4/.MP4, etc",
"author_name": "Anderson Juhasc",
"author_login": "Anderson-Juhasc",
"committed_at": "2025-08-27T13:32:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0e6e7af934750edf4774a2a66ff35d354739d463",
"body": null,
"is_bot": false,
"headline": "chore: Bump version and document NIP-46 usage",
"author_name": "tajava2006",
"author_login": "tajava2006",
"committed_at": "2025-08-25T14:00:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8866042edf21262715b0585311d6473aa31520c8",
"body": null,
"is_bot": false,
"headline": "relay: ensure onclose callback is triggered",
"author_name": "codytseng",
"author_login": "CodyTseng",
"committed_at": "2025-08-25T01:22:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ebe7df7b9ed047ec9b362cf7f9c746ff0313354f",
"body": "…gner (#502)\n\n* add: nostrconnect\n\n* fix: typo",
"is_bot": false,
"headline": "feat(nip46): Add support for client-initiated connections in BunkerSi…",
"author_name": "hoppe",
"author_login": "tajava2006",
"committed_at": "2025-08-24T18:53:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "86235314c4bcff41ff6ddffafaeb4c9e838cc895",
"body": null,
"is_bot": false,
"headline": "deduplicate relay URLs in pool.subscribe() and pool.subscribeMany()",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-08-06T13:37:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b39dac3551d21a48f08800463e1843844dd51c92",
"body": null,
"is_bot": false,
"headline": "nip57: include \"e\" tag.",
"author_name": "Don",
"author_login": "nikolat",
"committed_at": "2025-08-04T18:23:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "929d62bbbb7f3c5d65405be8cfde9531bea3f16e",
"body": null,
"is_bot": false,
"headline": "nip57: cleanup useless tests.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-08-01T23:28:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b575e478443eae7d704f9e5f60bce2f63be6b696",
"body": null,
"is_bot": false,
"headline": "nip57: include \"k\" tag.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-08-01T22:38:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b076c34a2f3a543e419d410ccb37bbf9dc092ef2",
"body": null,
"is_bot": false,
"headline": "tag new minor because of the pingpong stuff.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-08-01T17:12:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4bb3eb2d40766bdf1f4f3eb8c8aed125b82a2d1b",
"body": null,
"is_bot": false,
"headline": "remove unnecessary normalizeURL() call that can throw sometimes.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-08-01T17:11:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "87f2c74bb33f984658611456b97c1110bda3cf22",
"body": null,
"is_bot": false,
"headline": "Get pingpong working in the browser with dummy REQ (#499)",
"author_name": "Chris McCormick",
"author_login": "chr15m",
"committed_at": "2025-07-24T14:22:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4b6cc19b9c75daea9d52af1d8a770815592837c5",
"body": null,
"is_bot": false,
"headline": "cleanup.",
"author_name": "fiatjaf",
"author_login": "fiatjaf",
"committed_at": "2025-07-23T19:22:25Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 1,
"commits_last_year": 99,
"latest_release_at": "2023-12-19T17:33:31Z",
"latest_release_tag": "v2.0.0",
"releases_from_tags": false,
"days_since_last_push": 2,
"active_weeks_last_year": 27,
"days_since_latest_release": 946,
"mean_days_between_releases": null
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 37,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "nostr-tools",
"exists": true,
"license": "Unlicense",
"keywords": [
"decentralization",
"social",
"censorship-resistance",
"client",
"nostr"
],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/nostr-tools",
"is_deprecated": false,
"latest_version": "2.24.1",
"repository_url": "https://github.com/nbd-wtf/nostr-tools",
"versions_count": 201,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 3042179,
"first_published_at": "2021-01-04T17:15:16.394000Z",
"latest_published_at": "2026-07-21T17:46:18.983000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 1
}
]
},
"popularity": {
"forks": 223,
"stars": 849,
"watchers": 25,
"fork_history": {
"days": [
{
"date": "2021-01-06",
"count": 1
},
{
"date": "2021-01-13",
"count": 1
},
{
"date": "2022-02-02",
"count": 1
},
{
"date": "2022-04-10",
"count": 1
},
{
"date": "2022-05-14",
"count": 1
},
{
"date": "2022-07-07",
"count": 1
},
{
"date": "2022-09-05",
"count": 1
},
{
"date": "2022-09-06",
"count": 1
},
{
"date": "2022-09-08",
"count": 1
},
{
"date": "2022-09-24",
"count": 1
},
{
"date": "2022-10-24",
"count": 1
},
{
"date": "2022-11-18",
"count": 1
},
{
"date": "2022-11-21",
"count": 1
},
{
"date": "2022-11-26",
"count": 1
},
{
"date": "2022-12-16",
"count": 1
},
{
"date": "2022-12-18",
"count": 1
},
{
"date": "2022-12-20",
"count": 2
},
{
"date": "2022-12-21",
"count": 2
},
{
"date": "2022-12-23",
"count": 3
},
{
"date": "2022-12-25",
"count": 1
},
{
"date": "2022-12-27",
"count": 2
},
{
"date": "2022-12-28",
"count": 2
},
{
"date": "2022-12-30",
"count": 1
},
{
"date": "2023-01-03",
"count": 1
},
{
"date": "2023-01-09",
"count": 1
},
{
"date": "2023-01-11",
"count": 1
},
{
"date": "2023-01-13",
"count": 1
},
{
"date": "2023-01-14",
"count": 2
},
{
"date": "2023-01-16",
"count": 1
},
{
"date": "2023-01-17",
"count": 1
},
{
"date": "2023-01-18",
"count": 1
},
{
"date": "2023-01-21",
"count": 1
},
{
"date": "2023-01-22",
"count": 1
},
{
"date": "2023-01-30",
"count": 1
},
{
"date": "2023-01-31",
"count": 1
},
{
"date": "2023-02-03",
"count": 1
},
{
"date": "2023-02-04",
"count": 1
},
{
"date": "2023-02-07",
"count": 2
},
{
"date": "2023-02-10",
"count": 1
},
{
"date": "2023-02-11",
"count": 2
},
{
"date": "2023-02-12",
"count": 2
},
{
"date": "2023-02-16",
"count": 1
},
{
"date": "2023-02-17",
"count": 1
},
{
"date": "2023-02-22",
"count": 1
},
{
"date": "2023-02-24",
"count": 1
},
{
"date": "2023-02-26",
"count": 3
},
{
"date": "2023-02-27",
"count": 2
},
{
"date": "2023-03-02",
"count": 1
},
{
"date": "2023-03-04",
"count": 2
},
{
"date": "2023-03-07",
"count": 1
},
{
"date": "2023-03-12",
"count": 2
},
{
"date": "2023-03-13",
"count": 1
},
{
"date": "2023-03-14",
"count": 2
},
{
"date": "2023-03-15",
"count": 1
},
{
"date": "2023-03-18",
"count": 1
},
{
"date": "2023-03-23",
"count": 2
},
{
"date": "2023-03-24",
"count": 1
},
{
"date": "2023-03-27",
"count": 1
},
{
"date": "2023-03-31",
"count": 1
},
{
"date": "2023-04-04",
"count": 1
},
{
"date": "2023-04-06",
"count": 1
},
{
"date": "2023-04-08",
"count": 1
},
{
"date": "2023-04-09",
"count": 2
},
{
"date": "2023-04-13",
"count": 1
},
{
"date": "2023-04-14",
"count": 1
},
{
"date": "2023-04-15",
"count": 1
},
{
"date": "2023-04-16",
"count": 1
},
{
"date": "2023-04-18",
"count": 1
},
{
"date": "2023-04-19",
"count": 1
},
{
"date": "2023-04-20",
"count": 1
},
{
"date": "2023-04-23",
"count": 1
},
{
"date": "2023-04-26",
"count": 1
},
{
"date": "2023-04-28",
"count": 1
},
{
"date": "2023-05-02",
"count": 1
},
{
"date": "2023-05-03",
"count": 1
},
{
"date": "2023-05-05",
"count": 1
},
{
"date": "2023-05-08",
"count": 1
},
{
"date": "2023-05-10",
"count": 1
},
{
"date": "2023-05-26",
"count": 1
},
{
"date": "2023-06-06",
"count": 1
},
{
"date": "2023-06-11",
"count": 1
},
{
"date": "2023-06-14",
"count": 1
},
{
"date": "2023-06-19",
"count": 1
},
{
"date": "2023-07-04",
"count": 1
},
{
"date": "2023-07-06",
"count": 1
},
{
"date": "2023-07-10",
"count": 2
},
{
"date": "2023-07-13",
"count": 1
},
{
"date": "2023-07-15",
"count": 1
},
{
"date": "2023-07-19",
"count": 2
},
{
"date": "2023-07-20",
"count": 1
},
{
"date": "2023-07-23",
"count": 2
},
{
"date": "2023-07-31",
"count": 1
},
{
"date": "2023-08-02",
"count": 1
},
{
"date": "2023-08-05",
"count": 1
},
{
"date": "2023-08-08",
"count": 1
},
{
"date": "2023-08-09",
"count": 1
},
{
"date": "2023-08-12",
"count": 2
},
{
"date": "2023-08-14",
"count": 1
},
{
"date": "2023-08-22",
"count": 1
},
{
"date": "2023-08-23",
"count": 1
},
{
"date": "2023-08-30",
"count": 1
},
{
"date": "2023-09-11",
"count": 2
},
{
"date": "2023-09-17",
"count": 1
},
{
"date": "2023-09-19",
"count": 1
},
{
"date": "2023-09-26",
"count": 1
},
{
"date": "2023-10-21",
"count": 1
},
{
"date": "2023-10-28",
"count": 1
},
{
"date": "2023-11-07",
"count": 1
},
{
"date": "2023-11-13",
"count": 2
},
{
"date": "2023-11-21",
"count": 1
},
{
"date": "2023-11-28",
"count": 1
},
{
"date": "2023-12-02",
"count": 1
},
{
"date": "2023-12-11",
"count": 1
},
{
"date": "2023-12-14",
"count": 1
},
{
"date": "2023-12-20",
"count": 2
},
{
"date": "2023-12-28",
"count": 1
},
{
"date": "2023-12-29",
"count": 1
},
{
"date": "2024-01-03",
"count": 1
},
{
"date": "2024-01-12",
"count": 1
},
{
"date": "2024-02-04",
"count": 1
},
{
"date": "2024-02-06",
"count": 1
},
{
"date": "2024-02-26",
"count": 1
},
{
"date": "2024-02-28",
"count": 1
},
{
"date": "2024-03-11",
"count": 1
},
{
"date": "2024-03-16",
"count": 1
},
{
"date": "2024-03-23",
"count": 1
},
{
"date": "2024-04-01",
"count": 1
},
{
"date": "2024-04-19",
"count": 1
},
{
"date": "2024-05-24",
"count": 1
},
{
"date": "2024-06-09",
"count": 1
},
{
"date": "2024-06-19",
"count": 1
},
{
"date": "2024-06-30",
"count": 1
},
{
"date": "2024-07-12",
"count": 1
},
{
"date": "2024-07-15",
"count": 1
},
{
"date": "2024-07-20",
"count": 1
},
{
"date": "2024-08-04",
"count": 1
},
{
"date": "2024-08-11",
"count": 1
},
{
"date": "2024-08-18",
"count": 1
},
{
"date": "2024-08-21",
"count": 2
},
{
"date": "2024-08-26",
"count": 1
},
{
"date": "2024-09-06",
"count": 1
},
{
"date": "2024-09-10",
"count": 2
},
{
"date": "2024-09-21",
"count": 1
},
{
"date": "2024-09-24",
"count": 1
},
{
"date": "2024-10-11",
"count": 1
},
{
"date": "2024-10-17",
"count": 1
},
{
"date": "2024-10-20",
"count": 1
},
{
"date": "2024-10-31",
"count": 1
},
{
"date": "2024-11-02",
"count": 1
},
{
"date": "2024-12-03",
"count": 1
},
{
"date": "2024-12-05",
"count": 1
},
{
"date": "2024-12-29",
"count": 1
},
{
"date": "2025-01-08",
"count": 1
},
{
"date": "2025-02-09",
"count": 1
},
{
"date": "2025-02-17",
"count": 1
},
{
"date": "2025-02-25",
"count": 2
},
{
"date": "2025-02-26",
"count": 1
},
{
"date": "2025-03-17",
"count": 1
},
{
"date": "2025-03-20",
"count": 1
},
{
"date": "2025-04-22",
"count": 1
},
{
"date": "2025-06-20",
"count": 1
},
{
"date": "2025-06-21",
"count": 1
},
{
"date": "2025-06-27",
"count": 1
},
{
"date": "2025-07-05",
"count": 1
},
{
"date": "2025-07-08",
"count": 1
},
{
"date": "2025-07-19",
"count": 2
},
{
"date": "2025-07-20",
"count": 1
},
{
"date": "2025-07-22",
"count": 1
},
{
"date": "2025-08-02",
"count": 1
},
{
"date": "2025-08-04",
"count": 1
},
{
"date": "2025-08-25",
"count": 1
},
{
"date": "2025-10-12",
"count": 1
},
{
"date": "2025-10-14",
"count": 1
},
{
"date": "2025-11-10",
"count": 1
},
{
"date": "2025-12-03",
"count": 1
},
{
"date": "2026-01-10",
"count": 1
},
{
"date": "2026-01-14",
"count": 1
},
{
"date": "2026-01-20",
"count": 1
},
{
"date": "2026-01-24",
"count": 1
},
{
"date": "2026-01-26",
"count": 1
},
{
"date": "2026-01-30",
"count": 1
},
{
"date": "2026-02-10",
"count": 1
},
{
"date": "2026-02-11",
"count": 1
},
{
"date": "2026-02-17",
"count": 1
},
{
"date": "2026-02-27",
"count": 1
},
{
"date": "2026-03-03",
"count": 2
},
{
"date": "2026-03-27",
"count": 1
},
{
"date": "2026-05-12",
"count": 1
},
{
"date": "2026-05-20",
"count": 1
},
{
"date": "2026-06-04",
"count": 1
}
],
"complete": true,
"collected": 220,
"total_forks": 223
},
"star_history": null,
"open_issues_and_prs": 22
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": false,
"bootstrap_files": [
"justfile"
],
"api_schema_files": [],
"has_devcontainer": true,
"typecheck_configs": [
"tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 23037,
"source_files_sampled": 97,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"package.json"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "esbuild",
"direct": false,
"version": "0.16.9",
"severity": "moderate",
"ecosystem": "npm",
"cvss_score": 5.3,
"advisory_ids": [
"GHSA-67mh-4wv8-2f99"
],
"fixed_version": "0.25.0",
"advisory_count": 1,
"oldest_advisory_days": 527
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"moderate": 1
},
"advisory_count": 1,
"affected_count": 1,
"assessed_count": 8,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 13,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [
{
"name": "@noble/ciphers",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "2.1.1"
},
{
"name": "@noble/curves",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "2.0.1"
},
{
"name": "@noble/hashes",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "2.0.1"
},
{
"name": "@scure/base",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "2.0.0"
},
{
"name": "@scure/bip32",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "2.0.1"
},
{
"name": "@scure/bip39",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "2.0.1"
},
{
"name": "nostr-wasm",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "0.1.0"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "@noble/ciphers",
"direct": true,
"version": "2.1.1",
"ecosystem": "npm"
},
{
"name": "@noble/curves",
"direct": true,
"version": "2.0.1",
"ecosystem": "npm"
},
{
"name": "@noble/hashes",
"direct": true,
"version": "2.0.1",
"ecosystem": "npm"
},
{
"name": "@scure/base",
"direct": true,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "@scure/bip32",
"direct": true,
"version": "2.0.1",
"ecosystem": "npm"
},
{
"name": "@scure/bip39",
"direct": true,
"version": "2.0.1",
"ecosystem": "npm"
},
{
"name": "nostr-wasm",
"direct": true,
"version": "0.1.0",
"ecosystem": "npm"
},
{
"name": "@types/node",
"direct": false,
"version": "^18.13.0",
"ecosystem": "npm"
},
{
"name": "@types/node-fetch",
"direct": false,
"version": "^2.6.3",
"ecosystem": "npm"
},
{
"name": "@typescript-eslint/eslint-plugin",
"direct": false,
"version": "^6.5.0",
"ecosystem": "npm"
},
{
"name": "@typescript-eslint/parser",
"direct": false,
"version": "^6.5.0",
"ecosystem": "npm"
},
{
"name": "bun-types",
"direct": false,
"version": "^1.0.18",
"ecosystem": "npm"
},
{
"name": "esbuild",
"direct": false,
"version": "0.16.9",
"ecosystem": "npm"
},
{
"name": "eslint",
"direct": false,
"version": "^8.56.0",
"ecosystem": "npm"
},
{
"name": "eslint-config-prettier",
"direct": false,
"version": "^9.0.0",
"ecosystem": "npm"
},
{
"name": "events",
"direct": false,
"version": "^3.3.0",
"ecosystem": "npm"
},
{
"name": "mitata",
"direct": false,
"version": "^0.1.6",
"ecosystem": "npm"
},
{
"name": "mock-socket",
"direct": false,
"version": "^9.3.1",
"ecosystem": "npm"
},
{
"name": "node-fetch",
"direct": false,
"version": "^2.6.9",
"ecosystem": "npm"
},
{
"name": "prettier",
"direct": false,
"version": "^3.0.3",
"ecosystem": "npm"
},
{
"name": "typescript",
"direct": false,
"version": "^5.8.2",
"ecosystem": "npm"
}
],
"collected": true,
"truncated": false,
"total_count": 21,
"direct_count": 7,
"indirect_count": 14
}
},
"maintainership": {
"issues": {
"open_prs": 4,
"merged_prs": 271,
"open_issues": 18,
"closed_ratio": 0.91,
"closed_issues": 182,
"closed_unmerged_prs": 60
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "fiatjaf",
"commits": 467,
"avatar_url": "https://avatars.githubusercontent.com/u/1653275?v=4"
},
{
"type": "User",
"login": "alexgleason",
"commits": 98,
"avatar_url": "https://avatars.githubusercontent.com/u/3639540?v=4"
},
{
"type": "User",
"login": "sepehr-safari",
"commits": 36,
"avatar_url": "https://avatars.githubusercontent.com/u/25853688?v=4"
},
{
"type": "User",
"login": "AsaiToshiya",
"commits": 16,
"avatar_url": "https://avatars.githubusercontent.com/u/18229040?v=4"
},
{
"type": "User",
"login": "Egge21M",
"commits": 12,
"avatar_url": "https://avatars.githubusercontent.com/u/80262989?v=4"
},
{
"type": "User",
"login": "BilligsterUser",
"commits": 12,
"avatar_url": "https://avatars.githubusercontent.com/u/49797107?v=4"
},
{
"type": "User",
"login": "antonioconselheiro",
"commits": 11,
"avatar_url": "https://avatars.githubusercontent.com/u/91137293?v=4"
},
{
"type": "User",
"login": "futpib",
"commits": 11,
"avatar_url": "https://avatars.githubusercontent.com/u/4330357?v=4"
},
{
"type": "User",
"login": "Anderson-Juhasc",
"commits": 10,
"avatar_url": "https://avatars.githubusercontent.com/u/423705?v=4"
},
{
"type": "User",
"login": "arejula27",
"commits": 8,
"avatar_url": "https://avatars.githubusercontent.com/u/46299278?v=4"
}
],
"contributors_sampled": 91,
"top_contributor_share": 0.557
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"test.yml"
],
"has_docs_dir": false,
"linter_configs": [
".eslintrc.json"
],
"has_editorconfig": true,
"has_linter_config": true,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 0,
"reason": "0 out of 6 merged PRs checked by a CI test -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 2,
"reason": "Found 6/28 approved changesets -- score normalized to 2",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 16 contributing companies or organizations",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "27 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "bd02fc3287987287c796edc6bab7ea038858946d",
"ran_at": "2026-07-23T16:16:25Z",
"aggregate_score": 4.2,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-20T16:23:01Z",
"oldest_open_prs": [
{
"number": 412,
"created_at": "2024-06-09T03:53:22Z",
"last_comment_at": "2024-06-10T13:06:03Z",
"last_comment_author": "patrickReiis"
},
{
"number": 505,
"created_at": "2025-08-29T13:18:58Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 518,
"created_at": "2025-11-20T15:08:34Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 534,
"created_at": "2026-04-23T10:08:25Z",
"last_comment_at": "2026-04-25T10:03:10Z",
"last_comment_author": "kai-familiar"
}
],
"last_merged_pr_at": "2026-06-20T16:40:05Z",
"ci_last_conclusion": "FAILURE",
"oldest_open_issues": [
{
"number": 80,
"created_at": "2023-01-07T19:46:14Z",
"last_comment_at": "2023-12-29T18:53:58Z",
"last_comment_author": "Egge21M"
},
{
"number": 93,
"created_at": "2023-01-20T16:23:05Z",
"last_comment_at": "2023-04-11T11:31:16Z",
"last_comment_author": "bilalanees98"
},
{
"number": 238,
"created_at": "2023-06-28T18:26:25Z",
"last_comment_at": "2023-08-31T11:50:16Z",
"last_comment_author": "Egge21M"
},
{
"number": 296,
"created_at": "2023-09-15T15:34:06Z",
"last_comment_at": "2023-09-26T21:41:57Z",
"last_comment_author": "franzaps"
},
{
"number": 339,
"created_at": "2023-12-30T21:57:33Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 342,
"created_at": "2024-01-06T02:00:59Z",
"last_comment_at": "2024-01-06T14:52:32Z",
"last_comment_author": "morrisonbrett"
},
{
"number": 363,
"created_at": "2024-02-02T10:57:48Z",
"last_comment_at": "2024-02-02T14:56:24Z",
"last_comment_author": "fiatjaf"
},
{
"number": 369,
"created_at": "2024-02-15T23:41:24Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 376,
"created_at": "2024-03-06T17:31:56Z",
"last_comment_at": "2024-03-06T18:07:49Z",
"last_comment_author": "alexgleason"
},
{
"number": 388,
"created_at": "2024-03-18T11:53:26Z",
"last_comment_at": "2024-03-18T18:24:32Z",
"last_comment_author": "alexgleason"
},
{
"number": 390,
"created_at": "2024-03-26T09:56:59Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 396,
"created_at": "2024-04-10T02:04:36Z",
"last_comment_at": "2024-04-11T02:16:34Z",
"last_comment_author": "jimtracy1007"
},
{
"number": 422,
"created_at": "2024-07-29T10:29:13Z",
"last_comment_at": "2024-07-31T10:07:36Z",
"last_comment_author": "jimwjl666"
},
{
"number": 431,
"created_at": "2024-09-16T06:57:39Z",
"last_comment_at": "2025-06-01T17:45:02Z",
"last_comment_author": "fiatjaf"
},
{
"number": 469,
"created_at": "2025-01-17T16:32:50Z",
"last_comment_at": "2025-01-18T00:29:47Z",
"last_comment_author": "fiatjaf"
},
{
"number": 484,
"created_at": "2025-04-14T16:57:40Z",
"last_comment_at": "2025-04-15T01:16:59Z",
"last_comment_author": "fiatjaf"
},
{
"number": 509,
"created_at": "2025-10-03T14:18:08Z",
"last_comment_at": "2025-10-03T17:30:31Z",
"last_comment_author": "fiatjaf"
},
{
"number": 513,
"created_at": "2025-10-28T16:08:40Z",
"last_comment_at": "2026-05-14T12:28:41Z",
"last_comment_author": "rolznz"
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/nbd-wtf/nostr-tools",
"host": "github.com",
"name": "nostr-tools",
"owner": "nbd-wtf"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"security": 54,
"vitality": 67,
"community": 72,
"governance": 68,
"engineering": 62
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "moderate",
"name": "Vitality",
"value": 67,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 83,
"inputs": {
"commits_last_year": 99,
"human_commit_share": 1,
"days_since_last_push": 2,
"active_weeks_last_year": 27
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 2 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 2
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "27/52 weeks with commits",
"points": 18.7,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 27
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "99 commits in the last year",
"points": 18,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 99
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "27 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "at_risk",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 44,
"inputs": {
"releases_count": 1,
"latest_release_tag": "v2.0.0",
"releases_from_tags": false,
"days_since_latest_release": 946,
"mean_days_between_releases": null
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "1 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 1
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 946 days ago",
"points": 0,
"status": "missed",
"details": [
{
"code": "release_recency",
"params": {
"days": 946
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "cadence unknown (single release)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "release_cadence_unknown",
"params": {}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 3,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 3 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 3
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "good",
"name": "Community & Adoption",
"value": 72,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "good",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"forks": 223,
"stars": 849,
"watchers": 25,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "849 stars",
"points": 47.5,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 849
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "223 forks",
"points": 19.6,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 223
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "25 watchers",
"points": 7.7,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 25
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (Unlicense)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "Unlicense"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "excellent",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"packages": [
"nostr-tools"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 3042179
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "3,042,179 downloads/month across npm",
"points": 80,
"status": "met",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 3042179,
"ecosystems": "npm"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 68,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "at_risk",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 42,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 91,
"top_contributor_share": 0.557
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 56% of commits",
"points": 10,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 56
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "91 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 91
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 16 contributing companies or organizations",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 77,
"inputs": {
"merged_prs": 271,
"open_issues": 18,
"closed_issues": 182,
"issue_closed_ratio": 0.91,
"closed_unmerged_prs": 60
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "91% of issues closed",
"points": 42.5,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 91
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "271/331 decided PRs merged",
"points": 31.3,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 271,
"decided": 331
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 6/28 approved changesets -- score normalized to 2",
"points": 3,
"status": "partial",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 66,
"inputs": {
"followers": 183,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "nbd-wtf",
"public_repos": 34,
"account_age_days": 1523
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "183 followers of nbd-wtf",
"points": 16.3,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 183,
"login": "nbd-wtf"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "34 public repos, account ~4 yr old",
"points": 19.6,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 34
}
},
{
"code": "account_age_years",
"params": {
"years": 4
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"nostr-tools"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 1
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on npm",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "npm"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 1 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 1
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "201 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 201
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 62,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 70,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": true,
"has_linter_config": true,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "1 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 1
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": ".eslintrc.json",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".eslintrc.json"
}
}
],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 6.4,
"status": "met",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "0 out of 6 merged PRs checked by a CI test -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"topics": [
"nostr"
],
"has_wiki": false,
"homepage": null,
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "1 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 1
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 54,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"packaging",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 42,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 4.2
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "0 out of 6 merged PRs checked by a CI test -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 6/28 approved changesets -- score normalized to 2",
"points": 1.5,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 16 contributing companies or organizations",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "27 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 8 resolved dependencies against OSV; 13 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 8
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 13
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 1,
"affected_packages": 1,
"assessed_packages": 8,
"unassessed_packages": 13,
"affected_by_severity": "moderate 1",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "excellent",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 8,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 10
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 56,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "critical",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 14,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.26,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "26 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 13.9,
"status": "partial",
"details": [
{
"code": "legible_history",
"params": {
"legible": 26,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 72,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [
"justfile"
],
"has_devcontainer": true,
"has_linter_config": true,
"typecheck_configs": [
"tsconfig.json"
],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "justfile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "justfile"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": ".eslintrc.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".eslintrc.json"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "devcontainer, Dockerfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "devcontainer, Dockerfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "TypeScript",
"largest_source_bytes": 23037,
"source_files_sampled": 97,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "TypeScript (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "TypeScript"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/97 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 97,
"oversized": 0
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"deps.dev does not index npm:nostr-tools@2.24.1; advisories assessed against the repository dependency graph instead"
],
"report_type": "repository",
"generated_at": "2026-07-23T16:16:46.039377Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/n/nbd-wtf/nostr-tools.svg",
"full_name": "nbd-wtf/nostr-tools",
"license_state": "standard",
"license_spdx": "Unlicense"
}