mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-03-21 11:53:08 +00:00
Merge remote-tracking branch 'origin/kenneth/discord-resilience' into kenneth/channels-rollup
This commit is contained in:
@@ -58,6 +58,15 @@ if (!TOKEN) {
|
|||||||
}
|
}
|
||||||
const INBOX_DIR = join(STATE_DIR, 'inbox')
|
const INBOX_DIR = join(STATE_DIR, 'inbox')
|
||||||
|
|
||||||
|
// Last-resort safety net — without these the process dies silently on any
|
||||||
|
// unhandled promise rejection. With them it logs and keeps serving tools.
|
||||||
|
process.on('unhandledRejection', err => {
|
||||||
|
process.stderr.write(`discord channel: unhandled rejection: ${err}\n`)
|
||||||
|
})
|
||||||
|
process.on('uncaughtException', err => {
|
||||||
|
process.stderr.write(`discord channel: uncaught exception: ${err}\n`)
|
||||||
|
})
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.DirectMessages,
|
GatewayIntentBits.DirectMessages,
|
||||||
@@ -342,7 +351,7 @@ function checkApprovals(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!STATIC) setInterval(checkApprovals, 5000)
|
if (!STATIC) setInterval(checkApprovals, 5000).unref()
|
||||||
|
|
||||||
// Discord caps messages at 2000 chars (hard limit — larger sends reject).
|
// Discord caps messages at 2000 chars (hard limit — larger sends reject).
|
||||||
// Split long replies, preferring paragraph boundaries when chunkMode is
|
// Split long replies, preferring paragraph boundaries when chunkMode is
|
||||||
@@ -637,6 +646,25 @@ mcp.setRequestHandler(CallToolRequestSchema, async req => {
|
|||||||
|
|
||||||
await mcp.connect(new StdioServerTransport())
|
await mcp.connect(new StdioServerTransport())
|
||||||
|
|
||||||
|
// When Claude Code closes the MCP connection, stdin gets EOF. Without this
|
||||||
|
// the gateway stays connected as a zombie holding resources.
|
||||||
|
let shuttingDown = false
|
||||||
|
function shutdown(): void {
|
||||||
|
if (shuttingDown) return
|
||||||
|
shuttingDown = true
|
||||||
|
process.stderr.write('discord channel: shutting down\n')
|
||||||
|
setTimeout(() => process.exit(0), 2000)
|
||||||
|
void Promise.resolve(client.destroy()).finally(() => process.exit(0))
|
||||||
|
}
|
||||||
|
process.stdin.on('end', shutdown)
|
||||||
|
process.stdin.on('close', shutdown)
|
||||||
|
process.on('SIGTERM', shutdown)
|
||||||
|
process.on('SIGINT', shutdown)
|
||||||
|
|
||||||
|
client.on('error', err => {
|
||||||
|
process.stderr.write(`discord channel: client error: ${err}\n`)
|
||||||
|
})
|
||||||
|
|
||||||
client.on('messageCreate', msg => {
|
client.on('messageCreate', msg => {
|
||||||
if (msg.author.bot) return
|
if (msg.author.bot) return
|
||||||
handleInbound(msg).catch(e => process.stderr.write(`discord: handleInbound failed: ${e}\n`))
|
handleInbound(msg).catch(e => process.stderr.write(`discord: handleInbound failed: ${e}\n`))
|
||||||
@@ -685,7 +713,7 @@ async function handleInbound(msg: Message): Promise<void> {
|
|||||||
// forgeable by any allowlisted sender typing that string.
|
// forgeable by any allowlisted sender typing that string.
|
||||||
const content = msg.content || (atts.length > 0 ? '(attachment)' : '')
|
const content = msg.content || (atts.length > 0 ? '(attachment)' : '')
|
||||||
|
|
||||||
void mcp.notification({
|
mcp.notification({
|
||||||
method: 'notifications/claude/channel',
|
method: 'notifications/claude/channel',
|
||||||
params: {
|
params: {
|
||||||
content,
|
content,
|
||||||
@@ -698,6 +726,8 @@ async function handleInbound(msg: Message): Promise<void> {
|
|||||||
...(atts.length > 0 ? { attachment_count: String(atts.length), attachments: atts.join('; ') } : {}),
|
...(atts.length > 0 ? { attachment_count: String(atts.length), attachments: atts.join('; ') } : {}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
}).catch(err => {
|
||||||
|
process.stderr.write(`discord channel: failed to deliver inbound to Claude: ${err}\n`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,4 +735,7 @@ client.once('ready', c => {
|
|||||||
process.stderr.write(`discord channel: gateway connected as ${c.user.tag}\n`)
|
process.stderr.write(`discord channel: gateway connected as ${c.user.tag}\n`)
|
||||||
})
|
})
|
||||||
|
|
||||||
await client.login(TOKEN)
|
client.login(TOKEN).catch(err => {
|
||||||
|
process.stderr.write(`discord channel: login failed: ${err}\n`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user