Compare commits
No commits in common. "6039e992bd7e19125741fc8f497cb40d7f236a18" and "86683297affb9446becf1dca8a85290abddd291a" have entirely different histories.
6039e992bd
...
86683297af
8 changed files with 27 additions and 327 deletions
243
package-lock.json
generated
243
package-lock.json
generated
|
|
@ -12,19 +12,16 @@
|
|||
"cross-spawn": "^7.0.6",
|
||||
"discord.js": "^14.16.0",
|
||||
"dotenv": "^16.4.0",
|
||||
"pino": "^10.3.1",
|
||||
"yaml": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.0",
|
||||
"@types/cross-spawn": "^6.0.6",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/pino": "^7.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"@vitest/coverage-v8": "^4.1.4",
|
||||
"eslint": "^8.57.0",
|
||||
"pino-pretty": "^13.1.3",
|
||||
"typescript": "^5.7.0",
|
||||
"vitest": "^4.1.4"
|
||||
},
|
||||
|
|
@ -916,12 +913,6 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@pinojs/redact": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
|
||||
"integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz",
|
||||
|
|
@ -1366,16 +1357,6 @@
|
|||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pino": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/pino/-/pino-7.0.4.tgz",
|
||||
"integrity": "sha512-yKw1UbZOTe7vP1xMQT+oz3FexwgIpBTrM+AC62vWgAkNRULgLTJWfYX+H5/sKPm8VXFbIcXkC3VZPyuaNioZFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pino": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.18.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
||||
|
|
@ -1862,15 +1843,6 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/atomic-sleep": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
|
||||
"integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-v8-to-istanbul": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz",
|
||||
|
|
@ -2044,13 +2016,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/colorette": {
|
||||
"version": "2.0.20",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
||||
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
|
@ -2079,16 +2044,6 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/dateformat": {
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
|
||||
"integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
|
|
@ -2500,13 +2455,6 @@
|
|||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-copy": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-4.0.2.tgz",
|
||||
"integrity": "sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
|
|
@ -2527,13 +2475,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-safe-stringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
|
||||
|
|
@ -2753,11 +2694,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/help-me": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
|
||||
"integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="
|
||||
},
|
||||
"node_modules/html-escaper": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||
|
|
@ -2885,13 +2821,6 @@
|
|||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/joycon": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
|
||||
"integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/istanbul-lib-coverage": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
|
||||
|
|
@ -3180,15 +3109,6 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/on-exit-leak-free": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
|
||||
"integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
|
|
@ -3317,81 +3237,6 @@
|
|||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pino": {
|
||||
"version": "10.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-10.3.1.tgz",
|
||||
"integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@pinojs/redact": "^0.4.0",
|
||||
"atomic-sleep": "^1.0.0",
|
||||
"on-exit-leak-free": "^2.1.0",
|
||||
"pino-abstract-transport": "^3.0.0",
|
||||
"pino-std-serializers": "^7.0.0",
|
||||
"process-warning": "^5.0.0",
|
||||
"quick-format-unescaped": "^4.0.3",
|
||||
"real-require": "^0.2.0",
|
||||
"safe-stable-stringify": "^2.3.1",
|
||||
"sonic-boom": "^4.0.1",
|
||||
"thread-stream": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"pino": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/pino-abstract-transport": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-3.0.0.tgz",
|
||||
"integrity": "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"split2": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pino-pretty": {
|
||||
"version": "13.1.3",
|
||||
"resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.3.tgz",
|
||||
"integrity": "sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"colorette": "^2.0.7",
|
||||
"dateformat": "^4.6.3",
|
||||
"fast-copy": "^4.0.0",
|
||||
"fast-safe-stringify": "^2.1.1",
|
||||
"help-me": "^5.0.0",
|
||||
"joycon": "^3.1.1",
|
||||
"minimist": "^1.2.6",
|
||||
"on-exit-leak-free": "^2.1.0",
|
||||
"pino-abstract-transport": "^3.0.0",
|
||||
"pump": "^3.0.0",
|
||||
"secure-json-parse": "^4.0.0",
|
||||
"sonic-boom": "^4.0.1",
|
||||
"strip-json-comments": "^5.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"pino-pretty": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/pino-pretty/node_modules/strip-json-comments": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz",
|
||||
"integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/pino-std-serializers": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz",
|
||||
"integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.9",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
|
||||
|
|
@ -3458,22 +3303,6 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/process-warning": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz",
|
||||
"integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
|
||||
|
|
@ -3515,12 +3344,6 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/quick-format-unescaped": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
||||
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
|
|
@ -3550,15 +3373,6 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/real-require": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
|
||||
"integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
|
|
@ -3686,32 +3500,6 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safe-stable-stringify": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
||||
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/secure-json-parse": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz",
|
||||
"integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
|
|
@ -3797,15 +3585,6 @@
|
|||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sonic-boom": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz",
|
||||
"integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"atomic-sleep": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
|
|
@ -3816,15 +3595,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/split2": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/stackback": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
|
||||
|
|
@ -3918,18 +3688,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/thread-stream": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.0.0.tgz",
|
||||
"integrity": "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"real-require": "^0.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/tinybench": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
||||
|
|
@ -4346,4 +4104,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,19 +23,16 @@
|
|||
"cross-spawn": "^7.0.6",
|
||||
"discord.js": "^14.16.0",
|
||||
"dotenv": "^16.4.0",
|
||||
"pino": "^10.3.1",
|
||||
"yaml": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.0",
|
||||
"@types/cross-spawn": "^6.0.6",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/pino": "^7.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"@vitest/coverage-v8": "^4.1.4",
|
||||
"eslint": "^8.57.0",
|
||||
"pino-pretty": "^13.1.3",
|
||||
"typescript": "^5.7.0",
|
||||
"vitest": "^4.1.4"
|
||||
},
|
||||
|
|
|
|||
19
src/bot.ts
19
src/bot.ts
|
|
@ -11,9 +11,6 @@ import { DisclawDatabase } from "./db/database";
|
|||
import { DisclawConfig, EnvConfig } from "./config/loader";
|
||||
import { newAgentCommand, handleNewAgent } from "./commands/new-agent";
|
||||
import { routeMessage } from "./router";
|
||||
import { childLogger } from "./runtime/logger";
|
||||
|
||||
const log = childLogger("bot");
|
||||
|
||||
export async function startBot(
|
||||
envConfig: EnvConfig,
|
||||
|
|
@ -34,18 +31,18 @@ export async function startBot(
|
|||
// --- Event: Ready ---
|
||||
client.once("ready", async () => {
|
||||
if (!client.user) return;
|
||||
log.info({ tag: client.user.tag }, "Bot online");
|
||||
console.log(`Bot online as ${client.user.tag}`);
|
||||
|
||||
const guild = envConfig.DISCORD_GUILD_ID
|
||||
? client.guilds.cache.get(envConfig.DISCORD_GUILD_ID)
|
||||
: client.guilds.cache.first();
|
||||
|
||||
if (!guild) {
|
||||
log.error("No guild found. Is the bot added to a server?");
|
||||
console.error("No guild found. Is the bot added to a server?");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
log.info({ guildName: guild.name, guildId: guild.id }, "Connected to guild");
|
||||
console.log(`Connected to guild: ${guild.name} (${guild.id})`);
|
||||
|
||||
// --- Ensure management channel exists ---
|
||||
const managementName = disclawConfig.management_channel;
|
||||
|
|
@ -58,7 +55,7 @@ export async function startBot(
|
|||
);
|
||||
if (existingChannel) {
|
||||
managementChannelId = existingWorkspace.channel_id;
|
||||
log.info({ channelName: managementName }, "Management channel found");
|
||||
console.log(`Management channel found: #${managementName}`);
|
||||
} else {
|
||||
// Channel was deleted from Discord, recreate it
|
||||
existingWorkspace = undefined;
|
||||
|
|
@ -83,7 +80,7 @@ export async function startBot(
|
|||
);
|
||||
managementChannelId = found.id;
|
||||
mgmtChannel = found;
|
||||
log.info({ channelName: managementName }, "Adopted existing channel");
|
||||
console.log(`Adopted existing channel #${managementName}`);
|
||||
} else {
|
||||
const newChannel = await guild.channels.create({
|
||||
name: managementName,
|
||||
|
|
@ -98,7 +95,7 @@ export async function startBot(
|
|||
);
|
||||
managementChannelId = newChannel.id;
|
||||
mgmtChannel = newChannel;
|
||||
log.info({ channelName: managementName }, "Created management channel");
|
||||
console.log(`Created management channel #${managementName}`);
|
||||
}
|
||||
|
||||
// Send welcome message using the direct channel reference
|
||||
|
|
@ -121,9 +118,9 @@ export async function startBot(
|
|||
body: [newAgentCommand.toJSON()],
|
||||
}
|
||||
);
|
||||
log.info("Slash commands registered.");
|
||||
console.log("Slash commands registered.");
|
||||
} catch (err) {
|
||||
log.error({ err }, "Failed to register slash commands");
|
||||
console.error("Failed to register slash commands:", err);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,6 @@ import * as os from "os";
|
|||
import * as path from "path";
|
||||
import * as dotenv from "dotenv";
|
||||
import * as YAML from "yaml";
|
||||
import { childLogger } from "../runtime/logger";
|
||||
|
||||
const log = childLogger("config");
|
||||
|
||||
export interface DisclawConfig {
|
||||
workspaces_root: string;
|
||||
|
|
@ -41,9 +38,10 @@ export function expandWorkspacesRoot(raw: string, repoRoot: string): string {
|
|||
const isInsideRepo = !rel.startsWith("..") && !path.isAbsolute(rel);
|
||||
|
||||
if (isInsideRepo) {
|
||||
log.warn(
|
||||
{ workspacesRoot: resolved },
|
||||
"workspaces_root lies inside the DisClaw repository. " +
|
||||
console.warn(
|
||||
"[DisClaw] WARNING: workspaces_root lies inside the DisClaw repository (" +
|
||||
resolved +
|
||||
"). " +
|
||||
"Claude Code walks parent directories and concatenates every CLAUDE.md it finds. " +
|
||||
"A workspace under the repo root will inherit the project CLAUDE.md, " +
|
||||
"leaking DisClaw system instructions into every agent context. " +
|
||||
|
|
|
|||
15
src/index.ts
15
src/index.ts
|
|
@ -3,20 +3,17 @@ import { loadEnv, loadDisclawConfig } from "./config/loader";
|
|||
import { DisclawDatabase } from "./db/database";
|
||||
import { startBot } from "./bot";
|
||||
import { acquireLock } from "./runtime/lockfile";
|
||||
import { childLogger } from "./runtime/logger";
|
||||
|
||||
const log = childLogger("main");
|
||||
const ROOT_DIR = path.resolve(__dirname, "..");
|
||||
|
||||
async function main(): Promise<void> {
|
||||
log.info("DisClaw starting...");
|
||||
console.log("DisClaw starting...");
|
||||
|
||||
// 1. Load configuration
|
||||
const envConfig = loadEnv(ROOT_DIR);
|
||||
const disclawConfig = loadDisclawConfig(ROOT_DIR);
|
||||
log.info(
|
||||
{ workspacesRoot: disclawConfig.workspaces_root },
|
||||
"Config loaded"
|
||||
console.log(
|
||||
`Config loaded. Workspaces root: ${disclawConfig.workspaces_root}`
|
||||
);
|
||||
|
||||
// 2. Acquire startup lock (before DB init)
|
||||
|
|
@ -27,14 +24,14 @@ async function main(): Promise<void> {
|
|||
// 3. Initialize database
|
||||
const dbPath = path.join(ROOT_DIR, "data", "disclaw.db");
|
||||
const db = new DisclawDatabase(dbPath);
|
||||
log.info({ dbPath }, "Database initialized");
|
||||
console.log(`Database initialized at ${dbPath}`);
|
||||
|
||||
// 4. Start Discord bot
|
||||
await startBot(envConfig, disclawConfig, db);
|
||||
|
||||
// Graceful shutdown
|
||||
const shutdown = (): void => {
|
||||
log.info("Shutting down...");
|
||||
console.log("\nShutting down...");
|
||||
db.close();
|
||||
lockRelease();
|
||||
process.exit(0);
|
||||
|
|
@ -45,6 +42,6 @@ async function main(): Promise<void> {
|
|||
}
|
||||
|
||||
main().catch((err) => {
|
||||
log.error({ err }, "Fatal error");
|
||||
console.error("Fatal error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
import pino from "pino";
|
||||
|
||||
export const rootLogger = pino({
|
||||
level: process.env.LOG_LEVEL ?? "info",
|
||||
transport:
|
||||
process.env.NODE_ENV !== "production"
|
||||
? { target: "pino-pretty" }
|
||||
: undefined,
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns a child logger that includes `component` in every log entry.
|
||||
*/
|
||||
export function childLogger(component: string): pino.Logger {
|
||||
return rootLogger.child({ component });
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import { describe, it, expect } from "vitest";
|
||||
import { childLogger, rootLogger } from "../../src/runtime/logger";
|
||||
import pino from "pino";
|
||||
|
||||
describe("childLogger", () => {
|
||||
it("returns a pino logger instance", () => {
|
||||
const logger = childLogger("runner");
|
||||
expect(logger).toBeDefined();
|
||||
expect(typeof logger.info).toBe("function");
|
||||
expect(typeof logger.error).toBe("function");
|
||||
});
|
||||
|
||||
it("sets component binding on child logger", () => {
|
||||
const logger = childLogger("runner");
|
||||
// pino child loggers expose their bindings via .bindings()
|
||||
const bindings = (logger as pino.Logger).bindings();
|
||||
expect(bindings.component).toBe("runner");
|
||||
});
|
||||
|
||||
it("rootLogger is a pino logger", () => {
|
||||
expect(typeof rootLogger.info).toBe("function");
|
||||
expect(typeof rootLogger.child).toBe("function");
|
||||
});
|
||||
|
||||
it("different component names produce distinct bindings", () => {
|
||||
const runnerLog = childLogger("runner");
|
||||
const botLog = childLogger("bot");
|
||||
expect(runnerLog.bindings().component).toBe("runner");
|
||||
expect(botLog.bindings().component).toBe("bot");
|
||||
});
|
||||
});
|
||||
|
|
@ -2,7 +2,6 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import { expandWorkspacesRoot } from "../../src/config/loader";
|
||||
import { rootLogger } from "../../src/runtime/logger";
|
||||
|
||||
const HOME = os.homedir();
|
||||
// Use an absolute path that is portable across Linux, macOS, and Windows.
|
||||
|
|
@ -11,7 +10,7 @@ const REPO_ROOT = path.join(os.tmpdir(), "fake-disclaw-repo");
|
|||
|
||||
describe("expandWorkspacesRoot", () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(rootLogger, "warn").mockImplementation(() => undefined);
|
||||
vi.spyOn(console, "warn").mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -41,22 +40,24 @@ describe("expandWorkspacesRoot", () => {
|
|||
expect(path.isAbsolute(result)).toBe(true);
|
||||
});
|
||||
|
||||
it("(d) triggers logger.warn when workspaces_root is inside the repo", () => {
|
||||
it("(d) triggers console.warn when workspaces_root is inside the repo", () => {
|
||||
expandWorkspacesRoot("workspaces", REPO_ROOT);
|
||||
expect(rootLogger.warn).toHaveBeenCalledOnce();
|
||||
expect(rootLogger.warn).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ workspacesRoot: expect.stringContaining(REPO_ROOT) }),
|
||||
expect(console.warn).toHaveBeenCalledOnce();
|
||||
expect(console.warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining("[DisClaw] WARNING")
|
||||
);
|
||||
expect(console.warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining("CLAUDE.md")
|
||||
);
|
||||
});
|
||||
|
||||
it("(d) does NOT warn when workspaces_root is outside the repo", () => {
|
||||
expandWorkspacesRoot("~/.disclaw/workspaces", REPO_ROOT);
|
||||
expect(rootLogger.warn).not.toHaveBeenCalled();
|
||||
expect(console.warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("(d) does NOT warn when an absolute path outside the repo is given", () => {
|
||||
expandWorkspacesRoot("/tmp/disclaw-workspaces", REPO_ROOT);
|
||||
expect(rootLogger.warn).not.toHaveBeenCalled();
|
||||
expect(console.warn).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue