kimaki 0.4.1 → 0.4.4
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/dist/cli.js +20 -37
- package/dist/discordBot.js +312 -147
- package/dist/escape-backticks.test.js +125 -0
- package/package.json +11 -13
- package/src/cli.ts +22 -49
- package/src/discordBot.ts +411 -145
- package/src/escape-backticks.test.ts +146 -0
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cac } from 'cac';
|
|
3
3
|
import { intro, outro, text, password, note, cancel, isCancel, confirm, log, multiselect, spinner, } from '@clack/prompts';
|
|
4
4
|
import { deduplicateByKey, generateBotInstallUrl } from './utils.js';
|
|
5
|
-
import { getChannelsWithDescriptions, createDiscordClient, getDatabase, startDiscordBot, initializeOpencodeForDirectory, } from './discordBot.js';
|
|
5
|
+
import { getChannelsWithDescriptions, createDiscordClient, getDatabase, startDiscordBot, initializeOpencodeForDirectory, ensureKimakiCategory, createProjectChannels, } from './discordBot.js';
|
|
6
6
|
import { Events, ChannelType, REST, Routes, SlashCommandBuilder, } from 'discord.js';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import fs from 'node:fs';
|
|
@@ -45,6 +45,18 @@ async function registerCommands(token, appId) {
|
|
|
45
45
|
return option;
|
|
46
46
|
})
|
|
47
47
|
.toJSON(),
|
|
48
|
+
new SlashCommandBuilder()
|
|
49
|
+
.setName('add-project')
|
|
50
|
+
.setDescription('Create Discord channels for a new OpenCode project')
|
|
51
|
+
.addStringOption((option) => {
|
|
52
|
+
option
|
|
53
|
+
.setName('project')
|
|
54
|
+
.setDescription('Select an OpenCode project')
|
|
55
|
+
.setRequired(true)
|
|
56
|
+
.setAutocomplete(true);
|
|
57
|
+
return option;
|
|
58
|
+
})
|
|
59
|
+
.toJSON(),
|
|
48
60
|
];
|
|
49
61
|
const rest = new REST().setToken(token);
|
|
50
62
|
try {
|
|
@@ -58,21 +70,6 @@ async function registerCommands(token, appId) {
|
|
|
58
70
|
throw error;
|
|
59
71
|
}
|
|
60
72
|
}
|
|
61
|
-
async function ensureKimakiCategory(guild) {
|
|
62
|
-
const existingCategory = guild.channels.cache.find((channel) => {
|
|
63
|
-
if (channel.type !== ChannelType.GuildCategory) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
return channel.name.toLowerCase() === 'kimaki';
|
|
67
|
-
});
|
|
68
|
-
if (existingCategory) {
|
|
69
|
-
return existingCategory;
|
|
70
|
-
}
|
|
71
|
-
return guild.channels.create({
|
|
72
|
-
name: 'Kimaki',
|
|
73
|
-
type: ChannelType.GuildCategory,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
73
|
async function run({ restart, addChannels }) {
|
|
77
74
|
const forceSetup = Boolean(restart);
|
|
78
75
|
intro('🤖 Discord Bot Setup');
|
|
@@ -344,34 +341,20 @@ async function run({ restart, addChannels }) {
|
|
|
344
341
|
const project = projects.find((p) => p.id === projectId);
|
|
345
342
|
if (!project)
|
|
346
343
|
continue;
|
|
347
|
-
const baseName = path.basename(project.worktree);
|
|
348
|
-
const channelName = `${baseName}`
|
|
349
|
-
.toLowerCase()
|
|
350
|
-
.replace(/[^a-z0-9-]/g, '-')
|
|
351
|
-
.slice(0, 100);
|
|
352
344
|
try {
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
parent: kimakiCategory,
|
|
358
|
-
topic: `<kimaki><directory>${project.worktree}</directory><app>${appId}</app></kimaki>`,
|
|
359
|
-
});
|
|
360
|
-
const voiceChannel = await targetGuild.channels.create({
|
|
361
|
-
name: channelName,
|
|
362
|
-
type: ChannelType.GuildVoice,
|
|
363
|
-
parent: kimakiCategory,
|
|
345
|
+
const { textChannelId, channelName } = await createProjectChannels({
|
|
346
|
+
guild: targetGuild,
|
|
347
|
+
projectDirectory: project.worktree,
|
|
348
|
+
appId,
|
|
364
349
|
});
|
|
365
|
-
db.prepare('INSERT OR REPLACE INTO channel_directories (channel_id, directory, channel_type) VALUES (?, ?, ?)').run(textChannel.id, project.worktree, 'text');
|
|
366
|
-
db.prepare('INSERT OR REPLACE INTO channel_directories (channel_id, directory, channel_type) VALUES (?, ?, ?)').run(voiceChannel.id, project.worktree, 'voice');
|
|
367
350
|
createdChannels.push({
|
|
368
|
-
name:
|
|
369
|
-
id:
|
|
351
|
+
name: channelName,
|
|
352
|
+
id: textChannelId,
|
|
370
353
|
guildId: targetGuild.id,
|
|
371
354
|
});
|
|
372
355
|
}
|
|
373
356
|
catch (error) {
|
|
374
|
-
cliLogger.error(`Failed to create channels for ${
|
|
357
|
+
cliLogger.error(`Failed to create channels for ${path.basename(project.worktree)}:`, error);
|
|
375
358
|
}
|
|
376
359
|
}
|
|
377
360
|
s.stop(`Created ${createdChannels.length} channel(s)`);
|