Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bb83755
feat(messaging): add hook scaffold and channel manifests
sandl99 May 22, 2026
7f79ccf
fix(messaging): allow shared hook output values
sandl99 May 22, 2026
3a92503
feat(messaging): declare enrollment hooks
sandl99 May 22, 2026
b8aa2e6
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 22, 2026
ab94308
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 22, 2026
c044b80
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 23, 2026
ab564a0
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 23, 2026
1e64396
Merge remote-tracking branch 'origin/main' into HEAD
sandl99 May 25, 2026
b96f5af
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 25, 2026
51e9591
feat(messaging): add manifest compiler (#4069)
sandl99 May 25, 2026
d8947ec
fix(messaging): address review feedback
sandl99 May 25, 2026
b030f4a
fix(messaging): inline merge key guard
sandl99 May 25, 2026
710e793
fix(messaging): validate merge subtrees
sandl99 May 25, 2026
458b885
fix(messaging): implement channel hooks and split applier
sandl99 May 25, 2026
4e78355
refactor(messaging): move policy keys into manifests
sandl99 May 25, 2026
4b0b67f
fix(messaging): include policy keys in applier context
sandl99 May 25, 2026
34fcf23
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 25, 2026
e2e31dc
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 25, 2026
7e6464d
fix(messaging): harden channel enrollment and build paths
cv May 25, 2026
ba7c0d5
fix(messaging): complete channel manifest hardening
cv May 25, 2026
55c4b57
fix(messaging): validate agent config render targets
cv May 25, 2026
812defe
fix(messaging): keep wechat hook dependencies injected
cv May 25, 2026
b602fc7
fix(messaging): keep token paste dependencies injected
cv May 25, 2026
accf1e3
refactor(messaging): unify validation hook phase
sandl99 May 26, 2026
5953299
revert(messaging): restore separate validation phases
sandl99 May 26, 2026
352855b
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 26, 2026
bb1cb78
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 26, 2026
4ebd51b
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 26, 2026
c087d21
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 27, 2026
5daef1c
test(messaging): fix Hermes env helper calls
sandl99 May 27, 2026
31dc207
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 28, 2026
51fd119
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 28, 2026
9807d4b
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 29, 2026
498e9eb
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 May 29, 2026
47de166
refactor(messaging): simplify workflow planner
sandl99 May 29, 2026
7d05b57
refactor(messaging): simplify channel compiler context
sandl99 May 29, 2026
0f2d824
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
cv May 30, 2026
52ac6fb
Merge branch 'main' into u/sdang/messaging-hooks-channels-3993-3994
sandl99 Jun 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions src/lib/messaging/channels/discord/manifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import type { ChannelManifest } from "../../manifest";

export const discordManifest = {
schemaVersion: 1,
id: "discord",
displayName: "Discord",
description: "Discord bot messaging",
supportedAgents: ["openclaw", "hermes"],
auth: {
mode: "token-paste",
},
inputs: [
{
id: "botToken",
kind: "secret",
required: true,
envKey: "DISCORD_BOT_TOKEN",
prompt: {
label: "Discord Bot Token",
help: "Discord Developer Portal → Applications → Bot → Reset/Copy Token.",
},
},
{
id: "serverId",
kind: "config",
required: false,
envKey: "DISCORD_SERVER_ID",
statePath: "discordGuilds.serverId",
prompt: {
label: "Discord Server ID (for guild workspace access)",
help: "Enable Developer Mode in Discord, then right-click your server and copy the Server ID.",
},
},
{
id: "requireMention",
kind: "config",
required: false,
envKey: "DISCORD_REQUIRE_MENTION",
statePath: "discordGuilds.requireMention",
validValues: ["0", "1"],
prompt: {
label: "Discord mention mode",
help: "Choose whether the bot should reply only when @mentioned or to all messages in this server.",
},
},
{
id: "userId",
kind: "config",
required: false,
envKey: "DISCORD_USER_ID",
statePath: "discordGuilds.userIds",
prompt: {
label: "Discord User ID (optional guild allowlist)",
help: "Optional: enable Developer Mode in Discord, then right-click your user/avatar and copy the User ID. Leave blank to allow any member of the configured server to message the bot.",
},
},
],
credentials: [
{
id: "discordBotToken",
sourceInput: "botToken",
providerName: "{sandboxName}-discord-bridge",
providerEnvKey: "DISCORD_BOT_TOKEN",
placeholder: "openshell:resolve:env:DISCORD_BOT_TOKEN",
},
],
policyPresets: ["discord"],
render: [
{
id: "discord-openclaw-account",
kind: "json-fragment",
agent: "openclaw",
target: "openclaw.json",
fragment: {
path: "channels.discord.accounts.default",
value: {
token: "{{credential.discordBotToken.placeholder}}",
enabled: true,
healthMonitor: {
enabled: false,
},
proxy: "{{discordProxyUrl}}",
dmPolicy: "{{discord.allowedUsers.dmPolicy}}",
allowFrom: "{{discord.allowedUsers.values}}",
},
},
},
{
id: "discord-openclaw-guilds",
kind: "json-fragment",
agent: "openclaw",
target: "openclaw.json",
fragment: {
path: "channels.discord",
value: {
groupPolicy: "allowlist",
guilds: "{{discord.guilds}}",
},
},
},
{
id: "discord-hermes-env",
kind: "env-lines",
agent: "hermes",
target: "~/.hermes/.env",
lines: [
"DISCORD_BOT_TOKEN={{credential.discordBotToken.placeholder}}",
"NEMOCLAW_DISCORD_GUILD_IDS={{discord.guildIds.csv}}",
"DISCORD_ALLOWED_USERS={{discord.allowedUsers.csv}}",
"DISCORD_ALLOW_ALL_USERS={{discord.allowAllUsers}}",
],
},
{
id: "discord-hermes-config",
kind: "json-fragment",
agent: "hermes",
target: "~/.hermes/config.yaml",
fragment: {
path: "discord",
value: {
require_mention: "{{discord.requireMention}}",
free_response_channels: "",
allowed_channels: "",
auto_thread: true,
reactions: true,
channel_prompts: {},
},
},
},
],
state: {
persist: {
discordGuilds: ["serverId", "requireMention", "userId"],
},
rebuildHydration: [
{
statePath: "discordGuilds.serverId",
env: "DISCORD_SERVER_ID",
},
{
statePath: "discordGuilds.requireMention",
env: "DISCORD_REQUIRE_MENTION",
},
{
statePath: "discordGuilds.userIds",
env: "DISCORD_USER_ID",
},
],
},
hooks: [],
} as const satisfies ChannelManifest;
25 changes: 25 additions & 0 deletions src/lib/messaging/channels/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import type { ChannelManifestRegistry } from "../manifest";
import { createChannelManifestRegistry } from "../manifest";
import { discordManifest } from "./discord/manifest";
import { slackManifest } from "./slack/manifest";
import { telegramManifest } from "./telegram/manifest";
import { whatsappManifest } from "./whatsapp/manifest";

export { discordManifest } from "./discord/manifest";
export { slackManifest } from "./slack/manifest";
export { telegramManifest } from "./telegram/manifest";
export { whatsappManifest } from "./whatsapp/manifest";

export const BUILT_IN_CHANNEL_MANIFESTS = [
telegramManifest,
discordManifest,
slackManifest,
whatsappManifest,
] as const;

export function createBuiltInChannelManifestRegistry(): ChannelManifestRegistry {
return createChannelManifestRegistry(BUILT_IN_CHANNEL_MANIFESTS);
}
Loading
Loading