discord-ops 0.16.0 → 0.18.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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # discord-ops
2
2
 
3
+ ## 0.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 637362e: feat: add move_channel and notify_owners tools
8
+ - `move_channel` — reposition a channel or category relative to another channel using `before_id`/`after_id` instead of fragile raw position integers. Resolves sibling positions automatically.
9
+ - `notify_owners` — standalone owner ping tool. Sends `<@mention>`s to a channel based on `notification_type` without a full message or embed. No-ops silently if the type isn't in the project's `notify_owners_on` list. Supports optional message text appended after mentions.
10
+
11
+ ## 0.17.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 350cb59: feat: add `run` CLI subcommand and inline JSON support for `DISCORD_OPS_CONFIG`
16
+ - `discord-ops run <tool> --args '<json>'` — execute any tool directly from shell, no AI/MCP required. Supports the full tool suite including `send_template`, `send_message`, `send_embed`, and all 46 tools.
17
+ - `DISCORD_OPS_CONFIG` now accepts an inline JSON string in addition to a file path — if the value starts with `{` it is parsed directly. Eliminates the need to write config files in CI environments.
18
+ - `release.yml` GitHub Actions workflow — automatically posts a rich Discord release notification to `#releases` after every successful npm publish via changesets.
19
+ - README — new CLI `run` docs with examples, CI/CD integration section with config shape, GitHub Actions example, and updated `DISCORD_OPS_CONFIG` env var description.
20
+
21
+ ### Patch Changes
22
+
23
+ - 350cb59: fix: add "alert" to NotificationType enum — global config with alert in notify_owners_on caused config parse failure and MCP startup crash
24
+ - 350cb59: fix: clean up changelog formatting in Discord release notifications — section headers now render as bold text, commit hashes stripped from bullet lines
25
+ - 350cb59: Fix stale npx cache — use `discord-ops@latest` in MCP config
26
+
27
+ Without `@latest`, npx may serve a cached older version indefinitely, causing MCP clients to run stale code even after new releases are published. All MCP config examples in the README updated to use `discord-ops@latest`.
28
+
29
+ - 350cb59: fix: release workflow — truncate highlights to Discord 1024-char field limit, auto-sync main back to staging after publish
30
+
3
31
  ## 0.16.0
4
32
 
5
33
  ### Minor Changes
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const moveChannel: ToolDefinition;
3
+ //# sourceMappingURL=move-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"move-channel.d.ts","sourceRoot":"","sources":["../../../src/tools/channels/move-channel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwBlD,eAAO,MAAM,WAAW,EAAE,cAyDzB,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { z } from "zod";
2
+ import { toolResultJson } from "../types.js";
3
+ import { snowflakeId } from "../schema.js";
4
+ import { getTokenForProject } from "../../config/index.js";
5
+ const inputSchema = z
6
+ .object({
7
+ channel_id: snowflakeId.describe("Channel or category to move"),
8
+ before_id: snowflakeId
9
+ .optional()
10
+ .describe("Place this channel directly before this channel ID"),
11
+ after_id: snowflakeId.optional().describe("Place this channel directly after this channel ID"),
12
+ project: z
13
+ .string()
14
+ .optional()
15
+ .describe("Project name (resolves bot token for multi-bot setups)"),
16
+ })
17
+ .refine((d) => d.before_id ?? d.after_id, {
18
+ message: "Provide either before_id or after_id",
19
+ })
20
+ .refine((d) => !(d.before_id && d.after_id), {
21
+ message: "Provide before_id or after_id, not both",
22
+ });
23
+ export const moveChannel = {
24
+ name: "move_channel",
25
+ description: "Move a channel or category to a position immediately before or after another channel. Uses before_id/after_id instead of raw position integers.",
26
+ category: "channels",
27
+ inputSchema,
28
+ permissions: ["ManageChannels"],
29
+ handle: async (input, ctx) => {
30
+ const token = input.project ? getTokenForProject(input.project, ctx.config) : undefined;
31
+ const channel = await ctx.discord.getAnyChannel(input.channel_id, token);
32
+ const guild = channel.guild;
33
+ const refId = (input.before_id ?? input.after_id);
34
+ // Fetch the reference channel to get its current position
35
+ const refChannel = (await guild.channels.fetch(refId));
36
+ if (!refChannel) {
37
+ return {
38
+ content: [{ type: "text", text: `Reference channel ${refId} not found` }],
39
+ isError: true,
40
+ };
41
+ }
42
+ // Collect siblings — channels in the same parent (or top-level if no parent)
43
+ const siblings = [...guild.channels.cache.values()]
44
+ .filter((c) => "position" in c && c.parentId === channel.parentId)
45
+ .sort((a, b) => a.position - b.position);
46
+ const refIndex = siblings.findIndex((c) => c.id === refId);
47
+ if (refIndex === -1) {
48
+ return {
49
+ content: [{ type: "text", text: `Reference channel ${refId} is not in the same category` }],
50
+ isError: true,
51
+ };
52
+ }
53
+ // before_id → insert at ref's position; after_id → insert at ref's position + 1
54
+ const targetPosition = input.before_id ? refChannel.position : refChannel.position + 1;
55
+ await guild.channels.setPositions([{ channel: input.channel_id, position: targetPosition }]);
56
+ // Re-fetch to confirm final position
57
+ const updated = (await guild.channels.fetch(input.channel_id));
58
+ return toolResultJson({
59
+ id: input.channel_id,
60
+ name: updated?.name,
61
+ position: updated?.position ?? null,
62
+ ...(input.before_id
63
+ ? { moved: "before", reference_id: input.before_id }
64
+ : { moved: "after", reference_id: input.after_id }),
65
+ });
66
+ },
67
+ };
68
+ //# sourceMappingURL=move-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"move-channel.js","sourceRoot":"","sources":["../../../src/tools/channels/move-channel.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAoEjD,eAAO,MAAM,QAAQ,EAAE,cAAc,EAkEpC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAsEjD,eAAO,MAAM,QAAQ,EAAE,cAAc,EAoEpC,CAAC"}
@@ -10,11 +10,13 @@ import { searchMessages } from "./messaging/search.js";
10
10
  import { sendTemplate } from "./messaging/send-template.js";
11
11
  import { sendEmbed } from "./messaging/send-embed.js";
12
12
  import { listTemplatesCmd } from "./messaging/list-templates.js";
13
+ import { notifyOwners } from "./messaging/notify-owners.js";
13
14
  // Channels
14
15
  import { listChannels } from "./channels/list-channels.js";
15
16
  import { getChannel } from "./channels/get-channel.js";
16
17
  import { createChannel } from "./channels/create-channel.js";
17
18
  import { editChannel } from "./channels/edit-channel.js";
19
+ import { moveChannel } from "./channels/move-channel.js";
18
20
  import { deleteChannel } from "./channels/delete-channel.js";
19
21
  import { purgeMessages } from "./channels/purge-messages.js";
20
22
  import { setSlowmode } from "./channels/set-slowmode.js";
@@ -67,11 +69,13 @@ export const allTools = [
67
69
  sendTemplate,
68
70
  sendEmbed,
69
71
  listTemplatesCmd,
72
+ notifyOwners,
70
73
  // Channels
71
74
  listChannels,
72
75
  getChannel,
73
76
  createChannel,
74
77
  editChannel,
78
+ moveChannel,
75
79
  deleteChannel,
76
80
  purgeMessages,
77
81
  setSlowmode,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const notifyOwners: ToolDefinition;
3
+ //# sourceMappingURL=notify-owners.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notify-owners.d.ts","sourceRoot":"","sources":["../../../src/tools/messaging/notify-owners.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAuBlD,eAAO,MAAM,YAAY,EAAE,cAiC1B,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { toolResultJson, toolResult } from "../types.js";
3
+ import { snowflakeId } from "../schema.js";
4
+ import { resolveTarget } from "../../routing/resolver.js";
5
+ import { buildOwnerMentions } from "../../config/owners.js";
6
+ import { NotificationType } from "../../config/schema.js";
7
+ const inputSchema = z.object({
8
+ project: z
9
+ .string()
10
+ .describe("Project name — owners and notify_owners_on are read from this project's config"),
11
+ notification_type: NotificationType.describe("Notification type — must be in the project's notify_owners_on list or no ping is sent"),
12
+ channel_id: snowflakeId.optional().describe("Direct channel ID (overrides project default)"),
13
+ channel: z.string().optional().describe("Channel alias within the project"),
14
+ message: z
15
+ .string()
16
+ .max(1800)
17
+ .optional()
18
+ .describe("Optional message text to append after the mentions"),
19
+ });
20
+ export const notifyOwners = {
21
+ name: "notify_owners",
22
+ description: "Ping project owners in a channel based on notification_type. Sends owner <@mention>s only — no embed, no template. Use when you need a raw ping without a full message. No-ops silently if notification_type is not in the project's notify_owners_on list.",
23
+ category: "messaging",
24
+ inputSchema,
25
+ handle: async (input, ctx) => {
26
+ const mentions = buildOwnerMentions(input.project, input.notification_type, ctx.config);
27
+ if (!mentions) {
28
+ return toolResult(`No ping sent — "${input.notification_type}" is not in notify_owners_on for project "${input.project}", or no owners configured.`);
29
+ }
30
+ const target = await resolveTarget(input, ctx.config, ctx.discord);
31
+ if ("error" in target) {
32
+ return { content: [{ type: "text", text: target.error }], isError: true };
33
+ }
34
+ const channel = await ctx.discord.getChannel(target.channelId, target.token);
35
+ const content = input.message ? `${mentions}\n${input.message}` : mentions;
36
+ const message = await channel.send({ content });
37
+ return toolResultJson({
38
+ id: message.id,
39
+ channel_id: message.channelId,
40
+ mentions,
41
+ notification_type: input.notification_type,
42
+ project: input.project,
43
+ timestamp: message.createdAt.toISOString(),
44
+ });
45
+ },
46
+ };
47
+ //# sourceMappingURL=notify-owners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notify-owners.js","sourceRoot":"","sources":["../../../src/tools/messaging/notify-owners.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,CAAC,gFAAgF,CAAC;IAC7F,iBAAiB,EAAE,gBAAgB,CAAC,QAAQ,CAC1C,uFAAuF,CACxF;IACD,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC5F,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC3E,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,CAAC,IAAI,CAAC;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,oDAAoD,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,6PAA6P;IAC/P,QAAQ,EAAE,WAAW;IACrB,WAAW;IACX,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAExF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,UAAU,CACf,mBAAmB,KAAK,CAAC,iBAAiB,6CAA6C,KAAK,CAAC,OAAO,6BAA6B,CAClI,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACnE,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC5E,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAEhD,OAAO,cAAc,CAAC;YACpB,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,QAAQ;YACR,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-ops",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "Agency-grade Discord MCP server with multi-guild project routing",
5
5
  "type": "module",
6
6
  "license": "MIT",