discord-ops 0.22.0 → 0.23.0
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/CHANGELOG.md +18 -0
- package/README.md +108 -29
- package/dist/cli/validate.d.ts.map +1 -1
- package/dist/cli/validate.js +48 -0
- package/dist/cli/validate.js.map +1 -1
- package/dist/config/index.d.ts +23 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +84 -4
- package/dist/config/index.js.map +1 -1
- package/dist/config/profiles.d.ts +7 -0
- package/dist/config/profiles.d.ts.map +1 -1
- package/dist/config/profiles.js +23 -1
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/schema.d.ts +166 -15
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +33 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +25 -6
- package/dist/config/validate.js.map +1 -1
- package/dist/profiles/index.d.ts.map +1 -1
- package/dist/profiles/index.js +2 -0
- package/dist/profiles/index.js.map +1 -1
- package/dist/routing/resolver.d.ts +5 -0
- package/dist/routing/resolver.d.ts.map +1 -1
- package/dist/routing/resolver.js +79 -16
- package/dist/routing/resolver.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +50 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/system/list-bots.d.ts +2 -0
- package/dist/tools/system/list-bots.d.ts.map +1 -0
- package/dist/tools/system/list-bots.js +49 -0
- package/dist/tools/system/list-bots.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# discord-ops
|
|
2
2
|
|
|
3
|
+
## 0.23.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bbc870b: Multi-bot architecture: bot personas, per-channel bot assignment, and per-project tool profile enforcement.
|
|
8
|
+
|
|
9
|
+
**Bot personas:** Named bots with identity metadata (`name`, `role`, `description`) configured in a top-level `bots` section. Each bot references a `token_env` and can have a `default_profile` restricting which tools it can use.
|
|
10
|
+
|
|
11
|
+
**Channel-level bot assignment:** Channels accept `{ "id": "...", "bot": "bot-name" }` to override which bot operates in that channel. Token resolution follows: channel bot → project bot → project `token_env` → default token.
|
|
12
|
+
|
|
13
|
+
**Per-project tool profile enforcement:** Runtime gate in the MCP server checks per-project `tool_profile` and per-bot `default_profile` on every tool call. Tools not in the effective profile return an error. Supports `profile_add`/`profile_remove` overrides.
|
|
14
|
+
|
|
15
|
+
**New tool:** `list_bots` — returns all configured bot personas with project assignments, channel overrides, and connection status. Does not expose token values.
|
|
16
|
+
|
|
17
|
+
**Validation:** `discord-ops validate` now checks bot references, profile names, and bot token availability.
|
|
18
|
+
|
|
19
|
+
Backwards compatible — existing configs without `bots` work unchanged. Channels accept both plain snowflake strings and `{ id, bot }` objects.
|
|
20
|
+
|
|
3
21
|
## 0.22.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -8,10 +8,11 @@ Agency-grade Discord MCP server with multi-guild project routing.
|
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- **
|
|
11
|
+
- **49 MCP tools** — messaging, channels, moderation, roles, webhooks, audit log, threads, guilds, invites, permissions, search, 23 templates, OG embed unfurling, project introspection
|
|
12
12
|
- **Multi-guild project routing** — `send_message({ project: "my-app", channel: "builds" })` instead of raw channel IDs
|
|
13
13
|
- **Notification routing** — map notification types (`ci_build`, `deploy`, `error`) to channels per project
|
|
14
14
|
- **Owner pings** — configure project owners so releases, errors, and alerts auto-mention the right people
|
|
15
|
+
- **Bot personas** — named bots with identity metadata, per-channel bot assignment, and per-bot tool profiles
|
|
15
16
|
- **Multi-bot support** — manage multiple Discord bots from a single MCP server with per-project tokens
|
|
16
17
|
- **Tool profiles** — load only the tools an agent needs; cut schema overhead by 85% with slim profiles
|
|
17
18
|
- **Smart channel resolution** — channel params accept channel name or snowflake ID, with 4-layer fuzzy fallback
|
|
@@ -183,6 +184,56 @@ Projects can specify their own bot token via `token_env`:
|
|
|
183
184
|
|
|
184
185
|
When all projects have `token_env`, the default `DISCORD_TOKEN` is optional. Each project connects with its own bot.
|
|
185
186
|
|
|
187
|
+
### Bot personas
|
|
188
|
+
|
|
189
|
+
Give bots names, roles, and per-channel assignment. This is ideal when your Discord server runs multiple bots with distinct personas (e.g., a community helper vs. a tech ops bot).
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"bots": {
|
|
194
|
+
"claire": {
|
|
195
|
+
"name": "Claire",
|
|
196
|
+
"role": "Community helper",
|
|
197
|
+
"description": "Handles support and community channels",
|
|
198
|
+
"token_env": "CLAIRE_TOKEN",
|
|
199
|
+
"default_profile": "messaging"
|
|
200
|
+
},
|
|
201
|
+
"courier": {
|
|
202
|
+
"name": "Clarity Courier",
|
|
203
|
+
"role": "Technical operations",
|
|
204
|
+
"token_env": "COURIER_TOKEN",
|
|
205
|
+
"default_profile": "full"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"projects": {
|
|
209
|
+
"clarity-house": {
|
|
210
|
+
"guild_id": "123456789012345678",
|
|
211
|
+
"bot": "courier",
|
|
212
|
+
"channels": {
|
|
213
|
+
"general": "111111111111111111",
|
|
214
|
+
"support": { "id": "222222222222222222", "bot": "claire" },
|
|
215
|
+
"dev-ops": "333333333333333333",
|
|
216
|
+
"ai-testing": { "id": "444444444444444444", "bot": "claire" }
|
|
217
|
+
},
|
|
218
|
+
"default_channel": "dev-ops",
|
|
219
|
+
"tool_profile": "full"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**How it works:**
|
|
226
|
+
|
|
227
|
+
- **`bots`** — named bot definitions with identity metadata and `token_env`
|
|
228
|
+
- **`project.bot`** — default bot for the project (all channels use this bot unless overridden)
|
|
229
|
+
- **Channel `bot` override** — individual channels can use a different bot: `{ "id": "...", "bot": "claire" }`
|
|
230
|
+
- **`default_profile`** — per-bot tool profile (restricts which tools a bot can use at runtime)
|
|
231
|
+
- **Token resolution** — channel bot → project bot → project `token_env` → default `DISCORD_TOKEN`
|
|
232
|
+
- **Bot persona in routing** — resolved targets include `bot: { name, role }` metadata for agent context
|
|
233
|
+
- **Backwards compatible** — `bots` is optional; channels accept both `"ID"` and `{ "id": "ID", "bot": "name" }` formats
|
|
234
|
+
|
|
235
|
+
Use `list_bots` to see all configured bots, their project assignments, channel overrides, and connection status.
|
|
236
|
+
|
|
186
237
|
### Owner pings
|
|
187
238
|
|
|
188
239
|
Configure project owners so that releases, errors, and alerts automatically prepend `@mentions`. This ensures the right people are always paged for critical events without hardcoding mentions in every message.
|
|
@@ -365,12 +416,13 @@ Useful for sharing GitHub PRs, npm releases, blog posts, or any URL with rich pr
|
|
|
365
416
|
| `list_threads` | List active threads |
|
|
366
417
|
| `archive_thread` | Archive (and optionally lock) a thread |
|
|
367
418
|
|
|
368
|
-
### System (
|
|
419
|
+
### System (3 tools)
|
|
369
420
|
|
|
370
|
-
| Tool | Description
|
|
371
|
-
| --------------- |
|
|
372
|
-
| `health_check` | Bot status, version, connected guilds, and permission audit
|
|
373
|
-
| `list_projects` | List all projects with guild mappings, token status, and validation
|
|
421
|
+
| Tool | Description |
|
|
422
|
+
| --------------- | -------------------------------------------------------------------- |
|
|
423
|
+
| `health_check` | Bot status, version, connected guilds, and permission audit |
|
|
424
|
+
| `list_projects` | List all projects with guild mappings, token status, and validation |
|
|
425
|
+
| `list_bots` | List all bot personas with project assignments and channel overrides |
|
|
374
426
|
|
|
375
427
|
## Tool Profiles
|
|
376
428
|
|
|
@@ -380,9 +432,9 @@ Load only the tools an agent needs. Reduces schema token overhead by up to 85% f
|
|
|
380
432
|
|
|
381
433
|
| Profile | Tools | Description |
|
|
382
434
|
| ------------ | ----- | ------------------------------------------------------------------------------------------------------ |
|
|
383
|
-
| `full` |
|
|
384
|
-
| `monitoring` |
|
|
385
|
-
| `readonly` |
|
|
435
|
+
| `full` | 49 | All tools (default) |
|
|
436
|
+
| `monitoring` | 7 | get_messages, send_message, add_reaction, create_thread, health_check, list_projects, list_bots |
|
|
437
|
+
| `readonly` | 7 | get_messages, list_channels, list_members, get_guild, health_check, list_projects, list_bots |
|
|
386
438
|
| `moderation` | 7 | get_messages, kick_member, ban_member, timeout_member, delete_message, purge_messages, query_audit_log |
|
|
387
439
|
| `messaging` | 5 | add_reaction, delete_message, edit_message, get_messages, send_message |
|
|
388
440
|
| `channels` | 7 | create_channel, delete_channel, edit_channel, get_channel, list_channels, purge_messages, set_slowmode |
|
|
@@ -484,10 +536,12 @@ Any tool name accepted by the MCP server works here — `send_message`, `send_te
|
|
|
484
536
|
|
|
485
537
|
### Token resolution
|
|
486
538
|
|
|
487
|
-
1.
|
|
488
|
-
2.
|
|
489
|
-
3.
|
|
490
|
-
4.
|
|
539
|
+
1. **Channel-level bot** — if the channel has a `bot` override, use that bot's `token_env`
|
|
540
|
+
2. **Project-level bot** — if the project has a `bot`, use that bot's `token_env`
|
|
541
|
+
3. **Project-level `token_env`** — project's own token env var
|
|
542
|
+
4. **Default token** — `DISCORD_TOKEN` (or custom via `DISCORD_OPS_TOKEN_ENV`)
|
|
543
|
+
|
|
544
|
+
If `DISCORD_OPS_TOKEN_ENV` is set, its value names the env var holding the default token (e.g., `DISCORD_OPS_TOKEN_ENV=MY_BOT_TOKEN` reads `MY_BOT_TOKEN`). If all projects have `token_env` or `bot` set, no default token is needed.
|
|
491
545
|
|
|
492
546
|
## CI/CD Integration
|
|
493
547
|
|
|
@@ -720,22 +774,33 @@ Full `~/.discord-ops.json` schema with all options:
|
|
|
720
774
|
|
|
721
775
|
```json
|
|
722
776
|
{
|
|
777
|
+
"bots": {
|
|
778
|
+
"my-bot": {
|
|
779
|
+
"name": "My Bot",
|
|
780
|
+
"role": "General purpose",
|
|
781
|
+
"description": "Handles all operations",
|
|
782
|
+
"token_env": "MY_BOT_TOKEN",
|
|
783
|
+
"default_profile": "full"
|
|
784
|
+
}
|
|
785
|
+
},
|
|
723
786
|
"projects": {
|
|
724
787
|
"my-app": {
|
|
725
788
|
"guild_id": "123456789012345678",
|
|
726
789
|
"token_env": "MY_APP_DISCORD_TOKEN",
|
|
790
|
+
"bot": "my-bot",
|
|
727
791
|
"channels": {
|
|
728
792
|
"dev": "CHANNEL_ID",
|
|
729
793
|
"builds": "CHANNEL_ID",
|
|
730
794
|
"releases": "CHANNEL_ID",
|
|
731
|
-
"alerts": "CHANNEL_ID"
|
|
795
|
+
"alerts": "CHANNEL_ID",
|
|
796
|
+
"support": { "id": "CHANNEL_ID", "bot": "my-bot" }
|
|
732
797
|
},
|
|
733
798
|
"default_channel": "dev",
|
|
734
799
|
"owners": ["USER_SNOWFLAKE_ID"],
|
|
735
800
|
"notify_owners_on": ["release", "error", "alert"],
|
|
736
801
|
"tool_profile": "full",
|
|
737
|
-
"
|
|
738
|
-
"
|
|
802
|
+
"profile_add": [],
|
|
803
|
+
"profile_remove": [],
|
|
739
804
|
"notification_routing": {
|
|
740
805
|
"ci_build": "builds",
|
|
741
806
|
"deploy": "builds",
|
|
@@ -755,20 +820,31 @@ Full `~/.discord-ops.json` schema with all options:
|
|
|
755
820
|
}
|
|
756
821
|
```
|
|
757
822
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
|
761
|
-
|
|
|
762
|
-
| `
|
|
763
|
-
| `
|
|
764
|
-
| `
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
|
769
|
-
|
|
|
823
|
+
**Global fields:**
|
|
824
|
+
|
|
825
|
+
| Field | Description |
|
|
826
|
+
| ---------------------- | ------------------------------------------------------------------------------------- |
|
|
827
|
+
| `bots` | Named bot personas with `name`, `role`, `description`, `token_env`, `default_profile` |
|
|
828
|
+
| `default_project` | Project used when no `project` param is provided |
|
|
829
|
+
| `notification_routing` | Global notification type → channel alias routing |
|
|
830
|
+
|
|
831
|
+
**Project fields:**
|
|
832
|
+
|
|
833
|
+
| Field | Description |
|
|
834
|
+
| ---------------------- | ------------------------------------------------------------------------------------- |
|
|
835
|
+
| `guild_id` | Discord server (guild) snowflake ID |
|
|
836
|
+
| `token_env` | Env var name for this project's bot token |
|
|
837
|
+
| `bot` | Default bot persona for this project (references a key in `bots`) |
|
|
838
|
+
| `channels` | Alias → channel ID or `{ id, bot }` map; `channel: "builds"` resolves here first |
|
|
839
|
+
| `default_channel` | Channel used when no `channel` param is provided |
|
|
840
|
+
| `owners` | User snowflake IDs to mention on matching notification types |
|
|
841
|
+
| `notify_owners_on` | Notification types that trigger owner pings (`"dev"` never pings) |
|
|
842
|
+
| `tool_profile` | Base tool profile for this project (`full`, `monitoring`, etc.) — enforced at runtime |
|
|
843
|
+
| `profile_add` | Additional tools to load on top of the base profile |
|
|
844
|
+
| `profile_remove` | Tools to exclude from the base profile |
|
|
845
|
+
| `notification_routing` | Per-project override of global notification → channel routing |
|
|
770
846
|
|
|
771
|
-
|
|
847
|
+
Per-project profiles are enforced at runtime — all tools stay registered on the MCP server, but tool calls are filtered when the resolved project or bot has a profile set. This means agents can discover all tools via MCP schema, but per-project restrictions are applied on each call.
|
|
772
848
|
|
|
773
849
|
## Multi-Organization Troubleshooting
|
|
774
850
|
|
|
@@ -777,6 +853,9 @@ Full `~/.discord-ops.json` schema with all options:
|
|
|
777
853
|
Run `discord-ops validate` to check your config without connecting to Discord. It detects:
|
|
778
854
|
|
|
779
855
|
- Missing `token_env` values (env var not set)
|
|
856
|
+
- Bot references (`project.bot`, channel `bot`) pointing to undefined bots
|
|
857
|
+
- Invalid `default_profile` or `tool_profile` values
|
|
858
|
+
- Missing bot `token_env` environment variables
|
|
780
859
|
- Duplicate guild IDs across projects with different tokens
|
|
781
860
|
- `default_channel` referencing a nonexistent alias
|
|
782
861
|
- `default_project` pointing to a nonexistent project
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyFjD"}
|
package/dist/cli/validate.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { loadConfig } from "../config/index.js";
|
|
2
|
+
import { isProfileName } from "../profiles/index.js";
|
|
2
3
|
/**
|
|
3
4
|
* Validates the discord-ops configuration files.
|
|
4
5
|
* Loads global and per-project configs and reports any issues.
|
|
@@ -7,8 +8,12 @@ export async function runValidate() {
|
|
|
7
8
|
try {
|
|
8
9
|
const config = loadConfig();
|
|
9
10
|
const projectCount = Object.keys(config.global.projects).length;
|
|
11
|
+
const botCount = Object.keys(config.global.bots ?? {}).length;
|
|
10
12
|
console.log("Configuration valid.");
|
|
11
13
|
console.log(` Projects: ${projectCount}`);
|
|
14
|
+
if (botCount > 0) {
|
|
15
|
+
console.log(` Bots: ${botCount}`);
|
|
16
|
+
}
|
|
12
17
|
if (config.global.default_project) {
|
|
13
18
|
console.log(` Default project: ${config.global.default_project}`);
|
|
14
19
|
}
|
|
@@ -21,6 +26,49 @@ export async function runValidate() {
|
|
|
21
26
|
else {
|
|
22
27
|
console.warn(" Warning: No default token configured (DISCORD_TOKEN not set)");
|
|
23
28
|
}
|
|
29
|
+
// Validate bot references and profiles
|
|
30
|
+
const warnings = [];
|
|
31
|
+
const errors = [];
|
|
32
|
+
const bots = config.global.bots ?? {};
|
|
33
|
+
// Validate bot personas
|
|
34
|
+
for (const [botKey, bot] of Object.entries(bots)) {
|
|
35
|
+
if (!process.env[bot.token_env]) {
|
|
36
|
+
warnings.push(`Bot "${botKey}": token_env "${bot.token_env}" is not set in environment`);
|
|
37
|
+
}
|
|
38
|
+
if (bot.default_profile && !isProfileName(bot.default_profile)) {
|
|
39
|
+
errors.push(`Bot "${botKey}": default_profile "${bot.default_profile}" is not a valid profile name`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Validate project-level bot and profile references
|
|
43
|
+
for (const [projectName, project] of Object.entries(config.global.projects)) {
|
|
44
|
+
// Check project.bot reference
|
|
45
|
+
if (project.bot && !bots[project.bot]) {
|
|
46
|
+
errors.push(`Project "${projectName}": bot "${project.bot}" is not defined in the bots section`);
|
|
47
|
+
}
|
|
48
|
+
// Check project tool_profile
|
|
49
|
+
if (project.tool_profile && !isProfileName(project.tool_profile)) {
|
|
50
|
+
errors.push(`Project "${projectName}": tool_profile "${project.tool_profile}" is not a valid profile name`);
|
|
51
|
+
}
|
|
52
|
+
// Check channel-level bot overrides
|
|
53
|
+
for (const [alias, channelConfig] of Object.entries(project.channels)) {
|
|
54
|
+
if (typeof channelConfig === "object" && channelConfig.bot) {
|
|
55
|
+
if (!bots[channelConfig.bot]) {
|
|
56
|
+
errors.push(`Project "${projectName}", channel "${alias}": bot "${channelConfig.bot}" is not defined in the bots section`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Report warnings
|
|
62
|
+
for (const warning of warnings) {
|
|
63
|
+
console.warn(` Warning: ${warning}`);
|
|
64
|
+
}
|
|
65
|
+
// Report errors
|
|
66
|
+
if (errors.length > 0) {
|
|
67
|
+
for (const error of errors) {
|
|
68
|
+
console.error(` Error: ${error}`);
|
|
69
|
+
}
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
24
72
|
}
|
|
25
73
|
catch (err) {
|
|
26
74
|
console.error("Configuration invalid:", err instanceof Error ? err.message : String(err));
|
package/dist/cli/validate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
|
-
import { type GlobalConfig, type PerProjectConfig } from "./schema.js";
|
|
1
|
+
import { type GlobalConfig, type PerProjectConfig, type BotPersona } from "./schema.js";
|
|
2
2
|
export interface LoadedConfig {
|
|
3
3
|
global: GlobalConfig;
|
|
4
4
|
perProject?: PerProjectConfig;
|
|
5
5
|
defaultToken?: string;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the token for a named bot from the bots config section.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getTokenForBot(botName: string, config: LoadedConfig): string;
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the token for a specific channel within a project.
|
|
13
|
+
* Checks channel-level bot override first, then falls back to project-level.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getTokenForChannel(projectName: string, channelAlias: string, config: LoadedConfig): string;
|
|
16
|
+
/**
|
|
17
|
+
* Returns bot persona metadata for agent context.
|
|
18
|
+
* Checks channel-level bot override first, then project-level bot.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getBotPersona(projectName: string, channelAlias?: string, config?: LoadedConfig): (BotPersona & {
|
|
21
|
+
key: string;
|
|
22
|
+
}) | undefined;
|
|
7
23
|
/**
|
|
8
24
|
* Resolves the token for a given project.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
25
|
+
*
|
|
26
|
+
* Token resolution priority:
|
|
27
|
+
* 1. Project-level bot (project.bot → bots[name].token_env)
|
|
28
|
+
* 2. Project-level token_env (existing behavior)
|
|
29
|
+
* 3. Default DISCORD_TOKEN (existing behavior)
|
|
11
30
|
*/
|
|
12
31
|
export declare function getTokenForProject(projectName: string, config: LoadedConfig): string;
|
|
13
32
|
/**
|
|
@@ -19,5 +38,5 @@ export declare function getTokenForProject(projectName: string, config: LoadedCo
|
|
|
19
38
|
* 3. Direct params always work regardless
|
|
20
39
|
*/
|
|
21
40
|
export declare function loadConfig(): LoadedConfig;
|
|
22
|
-
export { type GlobalConfig, type PerProjectConfig } from "./schema.js";
|
|
41
|
+
export { type GlobalConfig, type PerProjectConfig, type BotPersona } from "./schema.js";
|
|
23
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAU5E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,YAAY,GACnB,MAAM,CAcR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,YAAY,GACpB,CAAC,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAyB5C;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CA2BpF;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAgDzC;AA4DD,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/config/index.js
CHANGED
|
@@ -3,13 +3,85 @@ import { resolve, join } from "node:path";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { logger } from "../utils/logger.js";
|
|
5
5
|
import { GlobalConfigSchema, PerProjectConfigSchema, } from "./schema.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the token for a named bot from the bots config section.
|
|
8
|
+
*/
|
|
9
|
+
export function getTokenForBot(botName, config) {
|
|
10
|
+
const bot = config.global.bots?.[botName];
|
|
11
|
+
if (!bot) {
|
|
12
|
+
throw new Error(`Bot "${botName}" not found in bots config`);
|
|
13
|
+
}
|
|
14
|
+
const token = process.env[bot.token_env];
|
|
15
|
+
if (!token) {
|
|
16
|
+
throw new Error(`Bot "${botName}": token_env "${bot.token_env}" is not set in environment`);
|
|
17
|
+
}
|
|
18
|
+
return token;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolves the token for a specific channel within a project.
|
|
22
|
+
* Checks channel-level bot override first, then falls back to project-level.
|
|
23
|
+
*/
|
|
24
|
+
export function getTokenForChannel(projectName, channelAlias, config) {
|
|
25
|
+
const project = config.global.projects[projectName];
|
|
26
|
+
if (!project) {
|
|
27
|
+
throw new Error(`Project "${projectName}" not found in config`);
|
|
28
|
+
}
|
|
29
|
+
// Check channel-level bot override
|
|
30
|
+
const channelConfig = project.channels[channelAlias];
|
|
31
|
+
if (channelConfig && typeof channelConfig === "object" && channelConfig.bot) {
|
|
32
|
+
return getTokenForBot(channelConfig.bot, config);
|
|
33
|
+
}
|
|
34
|
+
// Fall back to project-level resolution
|
|
35
|
+
return getTokenForProject(projectName, config);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns bot persona metadata for agent context.
|
|
39
|
+
* Checks channel-level bot override first, then project-level bot.
|
|
40
|
+
*/
|
|
41
|
+
export function getBotPersona(projectName, channelAlias, config) {
|
|
42
|
+
if (!config)
|
|
43
|
+
return undefined;
|
|
44
|
+
const project = config.global.projects[projectName];
|
|
45
|
+
if (!project)
|
|
46
|
+
return undefined;
|
|
47
|
+
const bots = config.global.bots;
|
|
48
|
+
if (!bots)
|
|
49
|
+
return undefined;
|
|
50
|
+
// Check channel-level bot override
|
|
51
|
+
if (channelAlias) {
|
|
52
|
+
const channelConfig = project.channels[channelAlias];
|
|
53
|
+
if (channelConfig && typeof channelConfig === "object" && channelConfig.bot) {
|
|
54
|
+
const bot = bots[channelConfig.bot];
|
|
55
|
+
if (bot)
|
|
56
|
+
return { ...bot, key: channelConfig.bot };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check project-level bot
|
|
60
|
+
if (project.bot) {
|
|
61
|
+
const bot = bots[project.bot];
|
|
62
|
+
if (bot)
|
|
63
|
+
return { ...bot, key: project.bot };
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
6
67
|
/**
|
|
7
68
|
* Resolves the token for a given project.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
69
|
+
*
|
|
70
|
+
* Token resolution priority:
|
|
71
|
+
* 1. Project-level bot (project.bot → bots[name].token_env)
|
|
72
|
+
* 2. Project-level token_env (existing behavior)
|
|
73
|
+
* 3. Default DISCORD_TOKEN (existing behavior)
|
|
10
74
|
*/
|
|
11
75
|
export function getTokenForProject(projectName, config) {
|
|
12
76
|
const project = config.global.projects[projectName];
|
|
77
|
+
// Check project-level bot reference first
|
|
78
|
+
if (project?.bot && config.global.bots?.[project.bot]) {
|
|
79
|
+
const bot = config.global.bots[project.bot];
|
|
80
|
+
const token = process.env[bot.token_env];
|
|
81
|
+
if (token)
|
|
82
|
+
return token;
|
|
83
|
+
logger.warn(`Bot "${project.bot}" token_env "${bot.token_env}" for project "${projectName}" is not set, falling back`);
|
|
84
|
+
}
|
|
13
85
|
if (project?.token_env) {
|
|
14
86
|
const token = process.env[project.token_env];
|
|
15
87
|
if (token)
|
|
@@ -42,14 +114,22 @@ export function loadConfig() {
|
|
|
42
114
|
const defaultToken = process.env[tokenEnvName] || undefined;
|
|
43
115
|
const global = loadGlobalConfig();
|
|
44
116
|
const perProject = loadPerProjectConfig();
|
|
45
|
-
// Option B: if no default token, validate that all projects have their own token_env
|
|
117
|
+
// Option B: if no default token, validate that all projects have their own token_env or bot reference
|
|
46
118
|
if (!defaultToken) {
|
|
47
119
|
const projectEntries = Object.entries(global.projects);
|
|
48
120
|
if (projectEntries.length === 0) {
|
|
49
121
|
throw new Error(`${tokenEnvName} environment variable is required (no projects with token_env configured)`);
|
|
50
122
|
}
|
|
51
123
|
const missing = projectEntries
|
|
52
|
-
.filter(([, p]) =>
|
|
124
|
+
.filter(([, p]) => {
|
|
125
|
+
// Project has a bot reference — check if the bot's token_env is set
|
|
126
|
+
if (p.bot && global.bots?.[p.bot]) {
|
|
127
|
+
const bot = global.bots[p.bot];
|
|
128
|
+
return !process.env[bot.token_env];
|
|
129
|
+
}
|
|
130
|
+
// Fallback to direct token_env check
|
|
131
|
+
return !p.token_env || !process.env[p.token_env];
|
|
132
|
+
})
|
|
53
133
|
.map(([name]) => name);
|
|
54
134
|
if (missing.length > 0) {
|
|
55
135
|
throw new Error(`${tokenEnvName} is not set, and these projects lack a valid token_env: ${missing.join(", ")}`);
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,19 @@ export interface ResolvedProject {
|
|
|
3
3
|
name: string;
|
|
4
4
|
guildId: string;
|
|
5
5
|
channels: Record<string, string>;
|
|
6
|
+
channelBots: Record<string, string>;
|
|
6
7
|
defaultChannel?: string;
|
|
7
8
|
notificationRouting?: Record<string, string>;
|
|
9
|
+
bot?: string;
|
|
10
|
+
toolProfile?: string;
|
|
11
|
+
toolProfileAdd?: string[];
|
|
12
|
+
toolProfileRemove?: string[];
|
|
8
13
|
}
|
|
9
14
|
/**
|
|
10
15
|
* Resolves a project from global + per-project config.
|
|
11
16
|
* Per-project notification_routing overrides global.
|
|
17
|
+
* Normalizes ChannelConfigSchema union values — extracts plain IDs into `channels`
|
|
18
|
+
* and collects bot overrides into `channelBots`.
|
|
12
19
|
*/
|
|
13
20
|
export declare function resolveProject(projectName: string, globalConfig: GlobalConfig, perProjectConfig?: PerProjectConfig): ResolvedProject | undefined;
|
|
14
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AASD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,YAAY,EAC1B,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,eAAe,GAAG,SAAS,CAiC7B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,YAAY,EAC1B,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,MAAM,GAAG,SAAS,CAEpB"}
|
package/dist/config/profiles.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a channel config value (string or object) to a plain channel ID.
|
|
3
|
+
*/
|
|
4
|
+
function normalizeChannelId(value) {
|
|
5
|
+
return typeof value === "string" ? value : value.id;
|
|
6
|
+
}
|
|
1
7
|
/**
|
|
2
8
|
* Resolves a project from global + per-project config.
|
|
3
9
|
* Per-project notification_routing overrides global.
|
|
10
|
+
* Normalizes ChannelConfigSchema union values — extracts plain IDs into `channels`
|
|
11
|
+
* and collects bot overrides into `channelBots`.
|
|
4
12
|
*/
|
|
5
13
|
export function resolveProject(projectName, globalConfig, perProjectConfig) {
|
|
6
14
|
const project = globalConfig.projects[projectName];
|
|
@@ -11,12 +19,26 @@ export function resolveProject(projectName, globalConfig, perProjectConfig) {
|
|
|
11
19
|
...globalConfig.notification_routing,
|
|
12
20
|
...perProjectConfig?.notification_routing,
|
|
13
21
|
};
|
|
22
|
+
// Normalize channels: extract plain IDs and collect bot overrides
|
|
23
|
+
const channels = {};
|
|
24
|
+
const channelBots = {};
|
|
25
|
+
for (const [alias, value] of Object.entries(project.channels)) {
|
|
26
|
+
channels[alias] = normalizeChannelId(value);
|
|
27
|
+
if (typeof value === "object" && value.bot) {
|
|
28
|
+
channelBots[alias] = value.bot;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
14
31
|
return {
|
|
15
32
|
name: projectName,
|
|
16
33
|
guildId: project.guild_id,
|
|
17
|
-
channels
|
|
34
|
+
channels,
|
|
35
|
+
channelBots,
|
|
18
36
|
defaultChannel: project.default_channel,
|
|
19
37
|
notificationRouting,
|
|
38
|
+
bot: project.bot,
|
|
39
|
+
toolProfile: project.tool_profile,
|
|
40
|
+
toolProfileAdd: project.profile_add,
|
|
41
|
+
toolProfileRemove: project.profile_remove,
|
|
20
42
|
};
|
|
21
43
|
}
|
|
22
44
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,SAAS,kBAAkB,CAAC,KAA4C;IACtE,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,YAA0B,EAC1B,gBAAmC;IAEnC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/B,2DAA2D;IAC3D,MAAM,mBAAmB,GAAG;QAC1B,GAAG,YAAY,CAAC,oBAAoB;QACpC,GAAG,gBAAgB,EAAE,oBAAoB;KAC1C,CAAC;IAEF,kEAAkE;IAClE,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,WAAW,GAA2B,EAAE,CAAC;IAE/C,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,QAAQ,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC3C,WAAW,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO,CAAC,QAAQ;QACzB,QAAQ;QACR,WAAW;QACX,cAAc,EAAE,OAAO,CAAC,eAAe;QACvC,mBAAmB;QACnB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,WAAW,EAAE,OAAO,CAAC,YAAY;QACjC,cAAc,EAAE,OAAO,CAAC,WAAW;QACnC,iBAAiB,EAAE,OAAO,CAAC,cAAc;KAC1C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,YAA0B,EAC1B,gBAAmC;IAEnC,OAAO,gBAAgB,EAAE,OAAO,IAAI,YAAY,CAAC,eAAe,CAAC;AACnE,CAAC"}
|