@tinyclaw/plugin-channel-discord 2.0.0-dev.7286c47 → 2.0.0-dev.7fde6f5

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/index.d.ts CHANGED
@@ -15,6 +15,13 @@
15
15
  * Prefixed to prevent collisions with web UI user IDs.
16
16
  */
17
17
  import type { ChannelPlugin } from '@tinyclaw/types';
18
+ export interface DiscordRuntimeStatus {
19
+ enabled: boolean;
20
+ state: 'idle' | 'disabled' | 'starting' | 'connected' | 'error' | 'stopped';
21
+ readyTag: string | null;
22
+ lastError: string | null;
23
+ }
24
+ export declare function getDiscordRuntimeStatus(): DiscordRuntimeStatus;
18
25
  declare const discordPlugin: ChannelPlugin;
19
26
  /** Split a string into chunks without cutting words at boundaries. */
20
27
  export declare function splitIntoChunks(text: string, maxLength: number): string[];
package/dist/index.js CHANGED
@@ -18,6 +18,15 @@ import { logger } from '@tinyclaw/logger';
18
18
  import { Client, Events, GatewayIntentBits, Partials, } from 'discord.js';
19
19
  import { createDiscordPairingTools, DISCORD_ENABLED_CONFIG_KEY, DISCORD_TOKEN_SECRET_KEY, } from './pairing.js';
20
20
  let client = null;
21
+ const runtimeStatus = {
22
+ enabled: false,
23
+ state: 'idle',
24
+ readyTag: null,
25
+ lastError: null,
26
+ };
27
+ export function getDiscordRuntimeStatus() {
28
+ return { ...runtimeStatus };
29
+ }
21
30
  const discordPlugin = {
22
31
  id: '@tinyclaw/plugin-channel-discord',
23
32
  name: 'Discord',
@@ -30,15 +39,25 @@ const discordPlugin = {
30
39
  },
31
40
  async start(context) {
32
41
  const isEnabled = context.configManager.get(DISCORD_ENABLED_CONFIG_KEY);
42
+ runtimeStatus.enabled = Boolean(isEnabled);
33
43
  if (!isEnabled) {
44
+ runtimeStatus.state = 'disabled';
45
+ runtimeStatus.readyTag = null;
46
+ runtimeStatus.lastError = null;
34
47
  logger.info('Discord plugin: not enabled — run pairing to enable');
35
48
  return;
36
49
  }
37
50
  const token = await context.secrets.retrieve(DISCORD_TOKEN_SECRET_KEY);
38
51
  if (!token) {
52
+ runtimeStatus.state = 'error';
53
+ runtimeStatus.readyTag = null;
54
+ runtimeStatus.lastError = 'Discord bot token not found in secrets';
39
55
  logger.warn('Discord plugin: enabled but no token found — re-pair to fix');
40
56
  return;
41
57
  }
58
+ runtimeStatus.state = 'starting';
59
+ runtimeStatus.readyTag = null;
60
+ runtimeStatus.lastError = null;
42
61
  client = new Client({
43
62
  intents: [
44
63
  GatewayIntentBits.Guilds,
@@ -49,8 +68,17 @@ const discordPlugin = {
49
68
  partials: [Partials.Channel],
50
69
  });
51
70
  client.once(Events.ClientReady, (readyClient) => {
71
+ runtimeStatus.state = 'connected';
72
+ runtimeStatus.readyTag = readyClient.user.tag;
73
+ runtimeStatus.lastError = null;
52
74
  logger.info(`Discord bot ready: ${readyClient.user.tag}`);
53
75
  });
76
+ client.on(Events.Error, (error) => {
77
+ runtimeStatus.state = 'error';
78
+ runtimeStatus.readyTag = null;
79
+ runtimeStatus.lastError = error.message;
80
+ logger.error('Discord plugin: client error', error);
81
+ });
54
82
  client.on(Events.MessageCreate, async (msg) => {
55
83
  // Ignore messages from bots (including self)
56
84
  if (msg.author.bot)
@@ -94,8 +122,20 @@ const discordPlugin = {
94
122
  }
95
123
  }
96
124
  });
97
- await client.login(token);
98
- logger.info('Discord bot connected');
125
+ try {
126
+ await client.login(token);
127
+ logger.info('Discord bot connected');
128
+ }
129
+ catch (error) {
130
+ runtimeStatus.state = 'error';
131
+ runtimeStatus.readyTag = null;
132
+ runtimeStatus.lastError = error instanceof Error ? error.message : String(error);
133
+ if (client) {
134
+ client.destroy();
135
+ client = null;
136
+ }
137
+ throw error;
138
+ }
99
139
  },
100
140
  async sendToUser(userId, message) {
101
141
  if (!client) {
@@ -131,6 +171,8 @@ const discordPlugin = {
131
171
  client = null;
132
172
  logger.info('Discord bot disconnected');
133
173
  }
174
+ runtimeStatus.state = runtimeStatus.enabled ? 'stopped' : 'disabled';
175
+ runtimeStatus.readyTag = null;
134
176
  },
135
177
  };
136
178
  /** Split a string into chunks without cutting words at boundaries. */
package/dist/pairing.js CHANGED
@@ -21,6 +21,7 @@ export function createDiscordPairingTools(secrets, configManager) {
21
21
  {
22
22
  name: 'discord_pair',
23
23
  description: 'Pair Tiny Claw with a Discord bot. ' +
24
+ 'If the user has not provided a bot token yet, first walk them through creating one in the Discord Developer Portal and ask them to paste it here. ' +
24
25
  'Stores the bot token securely and enables the Discord channel plugin. ' +
25
26
  'After pairing, call tinyclaw_restart to connect the bot. ' +
26
27
  'To get a token: go to https://discord.com/developers/applications, ' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinyclaw/plugin-channel-discord",
3
- "version": "2.0.0-dev.7286c47",
3
+ "version": "2.0.0-dev.7fde6f5",
4
4
  "description": "Discord channel plugin for Tiny Claw",
5
5
  "license": "GPL-3.0",
6
6
  "author": "Waren Gonzaga",
@@ -32,8 +32,8 @@
32
32
  "build": "tsc -p tsconfig.json"
33
33
  },
34
34
  "dependencies": {
35
- "@tinyclaw/logger": "workspace:*",
36
- "@tinyclaw/types": "workspace:*",
35
+ "@tinyclaw/logger": "2.0.0",
36
+ "@tinyclaw/types": "2.0.0",
37
37
  "discord.js": "^14.0.0"
38
38
  }
39
39
  }