spiralcord-full 2.3.1 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/spiral.js +13 -13
- package/package.json +3 -3
- package/src/plugins/manager.js +1 -1
- package/src/runtime.js +60 -4
- package/src/types/index.d.ts +2 -0
package/bin/spiral.js
CHANGED
|
@@ -153,14 +153,23 @@ async function startBot(config) {
|
|
|
153
153
|
|
|
154
154
|
program
|
|
155
155
|
.command('run')
|
|
156
|
-
.description('Start the bot runtime')
|
|
157
|
-
.option('-
|
|
156
|
+
.description('Start the bot runtime (with REPL console by default)')
|
|
157
|
+
.option('-N, --normal', 'Start without auto-reload or REPL console')
|
|
158
158
|
.action(async (options) => {
|
|
159
159
|
try {
|
|
160
160
|
const config = await loadConfig();
|
|
161
161
|
if (!config) return;
|
|
162
162
|
|
|
163
|
-
if (options.
|
|
163
|
+
if (options.normal) {
|
|
164
|
+
const runtime = await startBot(config);
|
|
165
|
+
console.log('Bot is running! Press Ctrl+C to stop.');
|
|
166
|
+
|
|
167
|
+
process.on('SIGINT', async () => {
|
|
168
|
+
console.log('\nShutting down...');
|
|
169
|
+
await runtime.stop();
|
|
170
|
+
process.exit(0);
|
|
171
|
+
});
|
|
172
|
+
} else {
|
|
164
173
|
const chokidar = (() => {
|
|
165
174
|
try {
|
|
166
175
|
const resolved = require.resolve('chokidar', { paths: [process.cwd()] });
|
|
@@ -168,7 +177,7 @@ program
|
|
|
168
177
|
} catch { return null; }
|
|
169
178
|
})();
|
|
170
179
|
if (!chokidar) {
|
|
171
|
-
console.error('Error: "spiral run
|
|
180
|
+
console.error('Error: "spiral run" requires chokidar. Run: npm install chokidar');
|
|
172
181
|
process.exit(1);
|
|
173
182
|
}
|
|
174
183
|
|
|
@@ -502,15 +511,6 @@ program
|
|
|
502
511
|
if (runtime) await runtime.stop();
|
|
503
512
|
process.exit(0);
|
|
504
513
|
});
|
|
505
|
-
} else {
|
|
506
|
-
const runtime = await startBot(config);
|
|
507
|
-
console.log('Bot is running! Press Ctrl+C to stop.');
|
|
508
|
-
|
|
509
|
-
process.on('SIGINT', async () => {
|
|
510
|
-
console.log('\nShutting down...');
|
|
511
|
-
await runtime.stop();
|
|
512
|
-
process.exit(0);
|
|
513
|
-
});
|
|
514
514
|
}
|
|
515
515
|
} catch (error) {
|
|
516
516
|
console.error('Failed to start bot:', error.message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spiralcord-full",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "Spiralcord Full - Discord Bot Runtime with Voice, Music, AI, Database & Image Support",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/types/index.d.ts",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"database",
|
|
25
25
|
"canvas"
|
|
26
26
|
],
|
|
27
|
-
"author": "",
|
|
28
|
-
"license": "
|
|
27
|
+
"author": "Isam Ahmed",
|
|
28
|
+
"license": "custom",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"commander": "^12.1.0",
|
|
31
31
|
"discord.js": "^14.16.3",
|
package/src/plugins/manager.js
CHANGED
package/src/runtime.js
CHANGED
|
@@ -137,16 +137,30 @@ class SpiralRuntime {
|
|
|
137
137
|
const intents = this.config.intents || ['Guilds', 'GuildMessages', 'MessageContent'];
|
|
138
138
|
const map = {
|
|
139
139
|
'Guilds': GatewayIntentBits.Guilds,
|
|
140
|
-
'GuildMessages': GatewayIntentBits.GuildMessages,
|
|
141
|
-
'MessageContent': GatewayIntentBits.MessageContent,
|
|
142
140
|
'GuildMembers': GatewayIntentBits.GuildMembers,
|
|
141
|
+
'GuildModeration': GatewayIntentBits.GuildModeration,
|
|
142
|
+
'GuildEmojisAndStickers': GatewayIntentBits.GuildEmojisAndStickers,
|
|
143
|
+
'GuildIntegrations': GatewayIntentBits.GuildIntegrations,
|
|
144
|
+
'GuildWebhooks': GatewayIntentBits.GuildWebhooks,
|
|
145
|
+
'GuildInvites': GatewayIntentBits.GuildInvites,
|
|
143
146
|
'GuildVoiceStates': GatewayIntentBits.GuildVoiceStates,
|
|
147
|
+
'GuildPresences': GatewayIntentBits.GuildPresences,
|
|
148
|
+
'GuildMessages': GatewayIntentBits.GuildMessages,
|
|
149
|
+
'GuildMessageReactions': GatewayIntentBits.GuildMessageReactions,
|
|
150
|
+
'GuildMessageTyping': GatewayIntentBits.GuildMessageTyping,
|
|
144
151
|
'DirectMessages': GatewayIntentBits.DirectMessages,
|
|
145
|
-
'
|
|
152
|
+
'DirectMessageReactions': GatewayIntentBits.DirectMessageReactions,
|
|
153
|
+
'DirectMessageTyping': GatewayIntentBits.DirectMessageTyping,
|
|
154
|
+
'MessageContent': GatewayIntentBits.MessageContent,
|
|
155
|
+
'GuildScheduledEvents': GatewayIntentBits.GuildScheduledEvents,
|
|
156
|
+
'AutoModerationConfiguration': GatewayIntentBits.AutoModerationConfiguration,
|
|
157
|
+
'AutoModerationExecution': GatewayIntentBits.AutoModerationExecution,
|
|
158
|
+
'GuildMessagePolls': GatewayIntentBits.GuildMessagePolls,
|
|
159
|
+
'UserThreads': GatewayIntentBits.UserThreads
|
|
146
160
|
};
|
|
147
161
|
return intents.map(i => {
|
|
148
162
|
if (map[i] !== undefined) return map[i];
|
|
149
|
-
console.warn(`[runtime] Unknown intent "${i}",
|
|
163
|
+
console.warn(`[runtime] Unknown intent "${i}", skipping. Valid intents: ${Object.keys(map).join(', ')}`);
|
|
150
164
|
return GatewayIntentBits.Guilds;
|
|
151
165
|
});
|
|
152
166
|
}
|
|
@@ -310,6 +324,48 @@ class SpiralRuntime {
|
|
|
310
324
|
getPluginAPI(pluginName) {
|
|
311
325
|
return this.pluginManager.getPluginAPI(pluginName);
|
|
312
326
|
}
|
|
327
|
+
|
|
328
|
+
async registerSlashCommands(clientId, commands, options = {}) {
|
|
329
|
+
const { REST } = require('@discordjs/rest');
|
|
330
|
+
const { Routes } = require('discord-api-types/v10');
|
|
331
|
+
|
|
332
|
+
if (!clientId) throw new Error('[runtime] registerSlashCommands: clientId is required');
|
|
333
|
+
|
|
334
|
+
const token = this.config.token;
|
|
335
|
+
if (!token) throw new Error('[runtime] registerSlashCommands: no token in config');
|
|
336
|
+
|
|
337
|
+
const rest = new REST({ version: '10' }).setToken(token);
|
|
338
|
+
|
|
339
|
+
const body = commands.map(cmd => {
|
|
340
|
+
if (cmd.toJSON) return cmd.toJSON();
|
|
341
|
+
return cmd;
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
const BATCH_SIZE = 100;
|
|
345
|
+
|
|
346
|
+
if (this.config.perGuildSlash) {
|
|
347
|
+
const guilds = options.guilds || [...this.client.guilds.cache.values()];
|
|
348
|
+
console.log(`[runtime] Registering ${body.length} slash commands in ${guilds.length} guild(s)...`);
|
|
349
|
+
|
|
350
|
+
for (const guild of guilds) {
|
|
351
|
+
const guildId = guild.id || guild;
|
|
352
|
+
for (let i = 0; i < body.length; i += BATCH_SIZE) {
|
|
353
|
+
const batch = body.slice(i, i + BATCH_SIZE);
|
|
354
|
+
await rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: batch });
|
|
355
|
+
}
|
|
356
|
+
const name = guild.name || guildId;
|
|
357
|
+
console.log(`[runtime] Registered in ${name}`);
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
console.log(`[runtime] Registering ${body.length} slash commands globally...`);
|
|
361
|
+
for (let i = 0; i < body.length; i += BATCH_SIZE) {
|
|
362
|
+
const batch = body.slice(i, i + BATCH_SIZE);
|
|
363
|
+
await rest.put(Routes.applicationCommands(clientId), { body: batch });
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
console.log(`[runtime] Slash commands registered.`);
|
|
368
|
+
}
|
|
313
369
|
}
|
|
314
370
|
|
|
315
371
|
module.exports = SpiralRuntime;
|
package/src/types/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export interface SpiralConfig {
|
|
|
5
5
|
intents: string[];
|
|
6
6
|
clientId: string;
|
|
7
7
|
disabledCommands: string[];
|
|
8
|
+
perGuildSlash?: boolean;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export interface SpiralPluginManifest {
|
|
@@ -91,6 +92,7 @@ export interface SpiralRuntime {
|
|
|
91
92
|
getAllCommands(): Map<string, any>;
|
|
92
93
|
getPluginConfig(pluginName: string): SpiralPluginConfig;
|
|
93
94
|
getPluginAPI(pluginName: string): Record<string, (...args: any[]) => any> | null;
|
|
95
|
+
registerSlashCommands(clientId: string, commands: any[], options?: { guilds?: any[] }): Promise<void>;
|
|
94
96
|
emitHook(eventName: string, payload: any): Promise<void>;
|
|
95
97
|
emitHookSerial(eventName: string, payload: any): Promise<void>;
|
|
96
98
|
emitHookWithResult(eventName: string, payload: any): Promise<boolean>;
|