Compare commits

..

No commits in common. "4819805b3c8c39c81d1635860771a7e7326388d819d48f518c7c12d2a8aa9535" and "da66cf900168a9dac383a78687603286d0f3ba05939d16cf000322f0a93dfd4c" have entirely different histories.

20 changed files with 55 additions and 1136 deletions

835
package-lock.json generated
View file

@ -9,7 +9,6 @@
"version": "0.1.0", "version": "0.1.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@google/genai": "^1.34.0",
"matrix-js-sdk": "^39.4.0" "matrix-js-sdk": "^39.4.0"
}, },
"devDependencies": { "devDependencies": {
@ -40,44 +39,6 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@google/genai": {
"version": "1.34.0",
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.34.0.tgz",
"integrity": "sha512-vu53UMPvjmb7PGzlYu6Tzxso8Dfhn+a7eQFaS2uNemVtDZKwzSpJ5+ikqBbXplF7RGB1STcVDqCkPvquiwb2sw==",
"license": "Apache-2.0",
"dependencies": {
"google-auth-library": "^10.3.0",
"ws": "^8.18.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"@modelcontextprotocol/sdk": "^1.24.0"
},
"peerDependenciesMeta": {
"@modelcontextprotocol/sdk": {
"optional": true
}
}
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
"strip-ansi": "^7.0.1",
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
"wrap-ansi": "^8.1.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/resolve-uri": { "node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
@ -115,16 +76,6 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=14"
}
},
"node_modules/@tsconfig/node10": { "node_modules/@tsconfig/node10": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz",
@ -195,45 +146,12 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/agent-base": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
"integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/another-json": { "node_modules/another-json": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz", "resolved": "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz",
"integrity": "sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg==", "integrity": "sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg==",
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/ansi-styles": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@ -241,56 +159,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/base-x": { "node_modules/base-x": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz",
"integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/bignumber.js": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
"integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/bs58": { "node_modules/bs58": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz",
@ -300,30 +174,6 @@
"base-x": "^5.0.0" "base-x": "^5.0.0"
} }
}, },
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"license": "BSD-3-Clause"
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/content-type": { "node_modules/content-type": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
@ -340,46 +190,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/diff": { "node_modules/diff": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@ -390,27 +200,6 @@
"node": ">=0.3.1" "node": ">=0.3.1"
} }
}, },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"license": "MIT"
},
"node_modules/events": { "node_modules/events": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@ -420,174 +209,6 @@
"node": ">=0.8.x" "node": ">=0.8.x"
} }
}, },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"license": "MIT"
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/foreground-child": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"license": "MIT",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/gaxios": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz",
"integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==",
"license": "Apache-2.0",
"dependencies": {
"extend": "^3.0.2",
"https-proxy-agent": "^7.0.1",
"node-fetch": "^3.3.2",
"rimraf": "^5.0.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/gcp-metadata": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
"integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
"license": "Apache-2.0",
"dependencies": {
"gaxios": "^7.0.0",
"google-logging-utils": "^1.0.0",
"json-bigint": "^1.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/google-auth-library": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz",
"integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==",
"license": "Apache-2.0",
"dependencies": {
"base64-js": "^1.3.0",
"ecdsa-sig-formatter": "^1.0.11",
"gaxios": "^7.0.0",
"gcp-metadata": "^8.0.0",
"google-logging-utils": "^1.0.0",
"gtoken": "^8.0.0",
"jws": "^4.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/google-logging-utils": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
"integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
"license": "Apache-2.0",
"engines": {
"node": ">=14"
}
},
"node_modules/gtoken": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
"integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
"license": "MIT",
"dependencies": {
"gaxios": "^7.0.0",
"jws": "^4.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/https-proxy-agent": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
"license": "MIT",
"dependencies": {
"agent-base": "^7.1.2",
"debug": "4"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/is-network-error": { "node_modules/is-network-error": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz",
@ -600,57 +221,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/json-bigint": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
"license": "MIT",
"dependencies": {
"bignumber.js": "^9.0.0"
}
},
"node_modules/jwa": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
"integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
"license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "^1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
"license": "MIT",
"dependencies": {
"jwa": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jwt-decode": { "node_modules/jwt-decode": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
@ -673,12 +243,6 @@
"url": "https://tidelift.com/funding/github/npm/loglevel" "url": "https://tidelift.com/funding/github/npm/loglevel"
} }
}, },
"node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/make-error": { "node_modules/make-error": {
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
@ -727,74 +291,6 @@
"events": "^3.2.0" "events": "^3.2.0"
} }
}, },
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"deprecated": "Use your platform's native DOMException instead",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"license": "MIT",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/oidc-client-ts": { "node_modules/oidc-client-ts": {
"version": "3.4.1", "version": "3.4.1",
"resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.4.1.tgz", "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.4.1.tgz",
@ -822,72 +318,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0"
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
"integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
"license": "ISC",
"dependencies": {
"glob": "^10.3.7"
},
"bin": {
"rimraf": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/sdp-transform": { "node_modules/sdp-transform": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-3.0.0.tgz", "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-3.0.0.tgz",
@ -897,135 +327,6 @@
"sdp-verify": "checker.js" "sdp-verify": "checker.js"
} }
}, },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"license": "ISC",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/string-width-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/string-width-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ts-node": { "node_modules/ts-node": {
"version": "10.9.2", "version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
@ -1117,142 +418,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/yn": { "node_modules/yn": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",

View file

@ -1,6 +1,6 @@
{ {
"name": "aslobot-matrix", "name": "aslobot-matrix",
"version": "0.5.0", "version": "0.1.0",
"description": "", "description": "",
"license": "ISC", "license": "ISC",
"author": "", "author": "",
@ -16,7 +16,6 @@
"typescript": "^5.9.3" "typescript": "^5.9.3"
}, },
"dependencies": { "dependencies": {
"@google/genai": "^1.34.0",
"matrix-js-sdk": "^39.4.0" "matrix-js-sdk": "^39.4.0"
} }
} }

View file

@ -9,17 +9,11 @@
}, },
"app": { "app": {
"triggerPrefix": "!", "triggerPrefix": "!",
"bowlingRoomId": "",
"experience": { "experience": {
"gain": 5, "gain": 5,
"startingRequirement": 50, "startingRequirement": 50,
"multiplier": 1.25, "multiplier": 1.25,
"timeout": 60000 "timeout": 60000
},
"ai": {
"api": {
"key": ""
}
} }
} }
} }

View file

@ -1,4 +1,3 @@
import config from "./config.json" with { type: "json" }; import config from "./config.json" with { type: "json" };
import packageConfig from "../package.json" with { type: "json" };
export { config, packageConfig }; export { config };

View file

@ -1,7 +1,7 @@
import { config } from "./config.js"; import { config } from "./config.js";
import { state } from "./store/store.js"; import { state } from "./store/store.js";
import { type IUser, type TRole } from "./store/types.js"; import { type IUser, type TRole } from "./store/types.js";
import type { ILevel } from "./types.js"; import type { IRank } from "./types.js";
const getUserById = (userId: string): IUser => { const getUserById = (userId: string): IUser => {
return ( return (
@ -19,22 +19,22 @@ const checkRoles = (roles: TRole[], userId: string) => {
return roles.includes(user.role); return roles.includes(user.role);
}; };
const getLevel = (experience: number): ILevel => { const getRank = (experience: number): IRank => {
let tmpExperience = experience; let tmpExperience = experience;
let expToNextLevel = config.app.experience.startingRequirement; let expToNextRank = config.app.experience.startingRequirement;
let level = 0; let rank = 0;
while (tmpExperience >= expToNextLevel) { while (tmpExperience >= expToNextRank) {
level++; rank++;
tmpExperience -= expToNextLevel; tmpExperience -= expToNextRank;
expToNextLevel = expToNextLevel *= config.app.experience.multiplier; expToNextRank = expToNextRank *= config.app.experience.multiplier;
} }
return { return {
level: level, rank: rank,
experience: Math.floor(experience), experience: Math.floor(experience),
experienceInLevel: Math.floor(tmpExperience), experienceInRank: Math.floor(tmpExperience),
expToNextLevel: Math.floor(expToNextLevel), expToNextRank: Math.floor(expToNextRank),
}; };
}; };
@ -48,4 +48,4 @@ const getUserName = (user: IUser): string => {
return match.replaceAll("@", ""); return match.replaceAll("@", "");
}; };
export { getUserById, checkRoles, getLevel, getUserName }; export { getUserById, checkRoles, getRank, getUserName };

View file

@ -12,41 +12,35 @@ const registerModuleAdmin = (
client = matrixClient; client = matrixClient;
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}shutdown`], startCondition: `${config.app.triggerPrefix}shutdown`,
allowedRoles: ["ADMIN"], allowedRoles: ["ADMIN"],
callbackFunc: onShutdown, callbackFunc: onShutdown,
}); });
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}loaddata`], startCondition: `${config.app.triggerPrefix}loaddata`,
allowedRoles: ["MODERATOR", "ADMIN"], allowedRoles: ["MODERATOR", "ADMIN"],
callbackFunc: onLoadData, callbackFunc: onLoadData,
}); });
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}savedata`], startCondition: `${config.app.triggerPrefix}savedata`,
allowedRoles: ["MODERATOR", "ADMIN"], allowedRoles: ["MODERATOR", "ADMIN"],
callbackFunc: onSaveData, callbackFunc: onSaveData,
}); });
}; };
const onShutdown = (text: string, roomId: string) => { const onShutdown = (text: string) => {
if (!text.includes("nosave")) { if (!text.includes("nosave")) {
client.sendTextMessage(roomId, "Saving data...");
save(); save();
} }
const sendPromise = client.sendTextMessage(roomId, "Shutting down..."); process.exit(0);
sendPromise.finally(() => {
process.exit(0);
});
}; };
const onLoadData = (_text: string, roomId: string) => { const onLoadData = () => {
client.sendTextMessage(roomId, "Loading data...");
load(); load();
}; };
const onSaveData = (_text: string, roomId: string) => { const onSaveData = () => {
client.sendTextMessage(roomId, "Saving data...");
save(); save();
}; };

View file

@ -1,140 +0,0 @@
import { MatrixClient, MsgType } from "matrix-js-sdk";
import type { ICallbackStore } from "../types.js";
import { config } from "../../config.js";
import { getImageNanoBanana, getTextGemini } from "../../services/ai/ai.js";
import type { IAnimal } from "./types.js";
let client: MatrixClient;
const registerModuleAI = (
matrixClient: MatrixClient,
callbackStore: ICallbackStore,
) => {
client = matrixClient;
callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}ai `],
callbackFunc: onAI,
});
callbackStore.messageCallbacks.push({
startConditions: [
`satek when `,
`satek ked `,
`gabor when `,
`gabor ked `,
`martin when `,
`martin ked `,
`madys when `,
`madys ked `,
`mandak when `,
`mandak ked `,
`mando when `,
`mando ked `,
`mandik when `,
`mandik ked `,
`madik when `,
`madik ked `,
`janys when `,
`janys ked `,
`jano when `,
`jano ked `,
],
callbackFunc: onImageGen,
});
};
const getAnimal = (name: string): IAnimal | undefined => {
const animals: IAnimal[] = [
{
name: "satek",
animal: "black cat",
},
{
name: "gabor",
animal: "hedgehog",
},
{
name: "martin",
animal: "hedgehog",
},
{
name: "madys",
animal: "beaver",
},
{
name: "mandak",
animal: "beaver",
},
{
name: "mando",
animal: "beaver",
},
{
name: "mandik",
animal: "beaver",
},
{
name: "madik",
animal: "beaver",
},
{
name: "janys",
animal: "lion",
},
{
name: "jano",
animal: "lion",
},
];
const foundAnimals = animals
.map((animal) => {
if (name.includes(animal.name)) {
return animal;
}
})
.filter((animal) => animal);
return foundAnimals.at(0);
};
const onAI = async (text: string, roomId: string) => {
if (text.trim().length < 5) {
return;
}
const responseAI = await getTextGemini(text.replace("!ai ", ""));
client.sendTextMessage(roomId, responseAI);
};
const onImageGen = async (text: string, roomId: string) => {
const animal = getAnimal(text.trim().split(/\s+/)[0] ?? "");
if (!animal) {
return;
}
const textMod = text.replace(animal.name, animal.animal);
const buffer = await getImageNanoBanana(textMod.trim());
if (!buffer || buffer.length < 10) {
return;
}
const imageName = `photo-${animal.name}.png`;
const uploadResult = await client.uploadContent(buffer, {
type: "image/png",
name: imageName,
});
await client.sendMessage(roomId, {
msgtype: MsgType.Image,
body: imageName,
url: uploadResult.content_uri,
info: {
mimetype: "image/png",
size: buffer.length,
},
});
};
export { getAnimal, registerModuleAI, onImageGen };

View file

@ -1,2 +0,0 @@
export * from "./ai.js";
export * from "./types.js";

View file

@ -1,6 +0,0 @@
interface IAnimal {
name: string;
animal: string;
}
export { type IAnimal };

View file

@ -1,34 +1,25 @@
import { MatrixClient } from "matrix-js-sdk"; import { MatrixClient } from "matrix-js-sdk";
import type { ICallbackStore } from "../types.js"; import type { ICallbackStore } from "../types.js";
import { config, packageConfig } from "../../config.js"; import { config } from "../../config.js";
import { platform } from "os";
let client: MatrixClient; let client: MatrixClient;
const registerModuleBase = ( const registerModuleTest = (
matrixClient: MatrixClient, matrixClient: MatrixClient,
callbackStore: ICallbackStore, callbackStore: ICallbackStore,
) => { ) => {
client = matrixClient; client = matrixClient;
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}ping`], startCondition: `${config.app.triggerPrefix}ping`,
callbackFunc: onPing, callbackFunc: onPing,
}); });
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}info`], startCondition: `${config.app.triggerPrefix}say `,
callbackFunc: onInfo,
});
callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}say `],
callbackFunc: onSay, callbackFunc: onSay,
}); });
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}bowling `], startCondition: `${config.app.triggerPrefix}help`,
callbackFunc: onBowling,
});
callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}help`],
callbackFunc: onHelp, callbackFunc: onHelp,
}); });
}; };
@ -37,26 +28,12 @@ const onPing = (_text: string, roomId: string) => {
client.sendTextMessage(roomId, "Pong!"); client.sendTextMessage(roomId, "Pong!");
}; };
const onInfo = (_text: string, roomId: string) => {
client.sendHtmlMessage(
roomId,
"",
`<p>AsloBot version <b>${packageConfig.version}</b> running on <b>${platform()}</b></p>`,
);
};
const onSay = (text: string, roomId: string) => { const onSay = (text: string, roomId: string) => {
const trigger = `${config.app.triggerPrefix}say `; const trigger = `${config.app.triggerPrefix}say `;
client.sendTextMessage(roomId, text.replace(trigger, "")); client.sendTextMessage(roomId, text.replace(trigger, ""));
}; };
const onBowling = (text: string, _roomId: string) => {
const trigger = `${config.app.triggerPrefix}bowling `;
client.sendTextMessage(config.app.bowlingRoomId, text.replace(trigger, ""));
};
const onHelp = (_text: string, roomId: string) => { const onHelp = (_text: string, roomId: string) => {
client.sendHtmlMessage( client.sendHtmlMessage(
roomId, roomId,
@ -64,13 +41,10 @@ const onHelp = (_text: string, roomId: string) => {
`<h3>Role: User</h3> `<h3>Role: User</h3>
<ul> <ul>
<li><b>!ping</b> - Pong!</li> <li><b>!ping</b> - Pong!</li>
<li><b>!info</b> - Prints information about this bot</li>
<li><b>!say {text}</b> - Repeats your message</li> <li><b>!say {text}</b> - Repeats your message</li>
<li><b>!bowling {text}</b> - Repeats your message in bowling</li>
<li><b>!help</b> - Prints this help message</li> <li><b>!help</b> - Prints this help message</li>
<li><b>!level</b> - Prints your level and experience</li> <li><b>!rank</b> - Prints your rank and experience</li>
<li><b>!leaderboard</b> - Prints total user ranking</li> <li><b>!leaderboard</b> - Prints total user ranking</li>
<li><b>!ai {text}</b> - Say something to Gemini 3</li>
</ul> </ul>
<hr/> <hr/>
<h3>Role: Moderator</h3> <h3>Role: Moderator</h3>
@ -86,4 +60,4 @@ const onHelp = (_text: string, roomId: string) => {
); );
}; };
export { registerModuleBase }; export { registerModuleTest };

View file

@ -1,6 +1,6 @@
import type { MatrixClient } from "matrix-js-sdk"; import type { MatrixClient } from "matrix-js-sdk";
import type { TRole } from "../store/types.js"; import type { TRole } from "../store/types.js";
import { getLevel, getUserById } from "../helpers.js"; import { getRank, getUserById } from "../helpers.js";
import { config } from "../config.js"; import { config } from "../config.js";
import { state } from "../store/store.js"; import { state } from "../store/store.js";
@ -23,19 +23,19 @@ const onAnyMessage = (
return onAnyMessage(client, _text, roomId, sender); return onAnyMessage(client, _text, roomId, sender);
} }
const levelBefore = getLevel(user.experience); const rankBefore = getRank(user.experience);
if (date > user.lastMessageTimestamp + config.app.experience.timeout) { if (date > user.lastMessageTimestamp + config.app.experience.timeout) {
user.experience += config.app.experience.gain; user.experience += config.app.experience.gain;
} }
user.lastMessageTimestamp = date; user.lastMessageTimestamp = date;
const levelAfter = getLevel(user.experience); const rankAfter = getRank(user.experience);
if (levelAfter.level > levelBefore.level) { if (rankAfter.rank > rankBefore.rank) {
client.sendHtmlMessage( client.sendHtmlMessage(
roomId, roomId,
"", "",
`${sender} - You are now level <b>${levelAfter.level}</b>`, `${sender} - You are now rank <b>${rankAfter.rank}</b>`,
); );
} }
}; };

View file

@ -4,11 +4,10 @@ import {
RoomEvent, RoomEvent,
type IContent, type IContent,
} from "matrix-js-sdk"; } from "matrix-js-sdk";
import { registerModuleTest } from "./base/base.js";
import type { ICallback, ICallbackStore } from "./types.js"; import type { ICallback, ICallbackStore } from "./types.js";
import { registerModuleBase } from "./base/base.js";
import { registerModuleAdmin } from "./admin/admin.js"; import { registerModuleAdmin } from "./admin/admin.js";
import { registerModuleUser } from "./user/user.js"; import { registerModuleUser } from "./user/user.js";
import { registerModuleAI } from "./ai/ai.js";
import { checkRoles, getUserById } from "../helpers.js"; import { checkRoles, getUserById } from "../helpers.js";
import { onAnyMessage, onMissingRole } from "./global.js"; import { onAnyMessage, onMissingRole } from "./global.js";
import { config } from "../config.js"; import { config } from "../config.js";
@ -28,20 +27,13 @@ const checkMessageCallback = (
return false; return false;
} }
if ( if (callback.startCondition && !text.startsWith(callback.startCondition)) {
callback.startConditions &&
!callback.startConditions.some((condition) =>
text.startsWith(condition),
)
) {
return false; return false;
} }
if ( if (
callback.includesConditions && callback.includesCondition &&
!callback.includesConditions.some((condition) => !text.includes(callback.includesCondition)
text.includes(condition),
)
) { ) {
return false; return false;
} }
@ -102,10 +94,9 @@ const registerModules = (client: MatrixClient) => {
}); });
}); });
registerModuleBase(client, callbacks); registerModuleTest(client, callbacks);
registerModuleAdmin(client, callbacks); registerModuleAdmin(client, callbacks);
registerModuleUser(client, callbacks); registerModuleUser(client, callbacks);
registerModuleAI(client, callbacks);
}; };
export { registerModules }; export { registerModules };

View file

@ -5,8 +5,8 @@ interface ICallbackStore {
} }
interface ICallback { interface ICallback {
startConditions?: string[]; startCondition?: string;
includesConditions?: string[]; includesCondition?: string;
allowedRoles?: TRole[]; allowedRoles?: TRole[];
allowedRooms?: string; allowedRooms?: string;
callbackFunc: (text: string, roomId: string, sender: string) => void; callbackFunc: (text: string, roomId: string, sender: string) => void;

View file

@ -1,7 +1,7 @@
import { MatrixClient } from "matrix-js-sdk"; import { MatrixClient } from "matrix-js-sdk";
import type { ICallbackStore } from "../types.js"; import type { ICallbackStore } from "../types.js";
import { config } from "../../config.js"; import { config } from "../../config.js";
import { getLevel, getUserById, getUserName } from "../../helpers.js"; import { getRank, getUserById, getUserName } from "../../helpers.js";
import { state } from "../../store/store.js"; import { state } from "../../store/store.js";
import type { IUser } from "../../store/types.js"; import type { IUser } from "../../store/types.js";
let client: MatrixClient; let client: MatrixClient;
@ -13,35 +13,31 @@ const registerModuleUser = (
client = matrixClient; client = matrixClient;
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}level`], startCondition: `${config.app.triggerPrefix}rank`,
callbackFunc: onLevel, callbackFunc: onRank,
}); });
callbackStore.messageCallbacks.push({ callbackStore.messageCallbacks.push({
startConditions: [`${config.app.triggerPrefix}leaderboard`], startCondition: `${config.app.triggerPrefix}leaderboard`,
callbackFunc: onLeaderboard, callbackFunc: onLeaderboard,
}); });
}; };
const onLevel = (_text: string, roomId: string, sender: string) => { const onRank = (_text: string, roomId: string, sender: string) => {
const level = getLevel(getUserById(sender).experience); const rank = getRank(getUserById(sender).experience);
client.sendHtmlMessage( client.sendHtmlMessage(
roomId, roomId,
"", "",
`<h3>Your Level: ${level.level}</h3> `<h3>Your Rank: ${rank.rank}</h3>
</br> <i>Next rank progress: ${rank.experienceInRank}/${rank.expToNextRank}exp</i>`,
<i>Next level progress: ${level.experienceInLevel}/${level.expToNextLevel}xp</i>`,
); );
}; };
const onLeaderboard = (_text: string, roomId: string) => { const onLeaderboard = (_text: string, roomId: string) => {
const mapUsersToLeaderboard = (user: IUser): string => { const mapUsersToLeaderboard = (user: IUser): string => {
const level = getLevel(user.experience); const rank = getRank(user.experience);
const userName = getUserName(user);
const userNameMod =
userName.charAt(0).toUpperCase() + userName.slice(1);
return `<li>${userNameMod}: level <b>${level.level}</b> (${level.experienceInLevel}/${level.expToNextLevel}xp)</li>`; return `<li>${getUserName(user)}: rank ${rank.rank} (${rank.experienceInRank}/${rank.expToNextRank}exp)</li>`;
}; };
const users = state.users.sort( const users = state.users.sort(

View file

@ -1,44 +0,0 @@
import { GoogleGenAI } from "@google/genai";
import { config } from "../../config.js";
const googleAI = new GoogleGenAI({
apiKey: config.app.ai.api.key,
});
const getTextGemini = async (input: string): Promise<string> => {
const response = await googleAI.models.generateContent({
model: "gemini-3-flash-preview",
contents: input,
});
return response.text ?? "AI Error";
};
const getImageNanoBanana = async (
input: string,
): Promise<Buffer<ArrayBuffer> | undefined> => {
const response = await googleAI.models.generateContent({
model: "gemini-2.5-flash-image",
contents: input,
});
const firstCandidate = (response.candidates ?? [])[0];
const parts = firstCandidate?.content?.parts ?? [];
let buffer: Buffer<ArrayBuffer> | undefined = undefined;
parts.forEach((part) => {
if (part.inlineData) {
const imageData = part.inlineData.data;
if (!imageData) {
return;
}
buffer = Buffer.from(imageData, "base64");
}
});
return buffer;
};
export { getTextGemini, getImageNanoBanana };

View file

@ -1 +0,0 @@
export * from "./ai.js";

View file

@ -1,8 +1,8 @@
interface ILevel { interface IRank {
level: number; rank: number;
experience: number; experience: number;
experienceInLevel: number; experienceInRank: number;
expToNextLevel: number; expToNextRank: number;
} }
export { type ILevel }; export { type IRank };