Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name": "claudeclaw",
"source": "./",
"description": "Cron-like daemon that runs Claude prompts on a schedule",
"version": "1.0.44",
"version": "1.0.45",
"keywords": [
"cron",
"heartbeat",
Expand Down
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "claudeclaw",
"version": "1.0.44",
"version": "1.0.45",
"description": "Cron-like daemon that runs Claude prompts on a schedule"
}
16 changes: 14 additions & 2 deletions src/commands/discord.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ensureProjectClaudeMd, run, runUserMessage, compactCurrentSession, compactCurrentThreadSession, agentDirKey } from "../runner";
import { ensureProjectClaudeMd, run, runUserMessage, killActive, compactCurrentSession, compactCurrentThreadSession, agentDirKey } from "../runner";
import { wrapUntrusted } from "../prompt-safety";
import { isAllowed, isDiscordAuthorized } from "../allowlist";
import { extractErrorDetail } from "../messaging";
Expand Down Expand Up @@ -498,7 +498,7 @@ Rules:
const { execSync } = await import("node:child_process");
const input = `${systemPrompt}\n\n---\nUser message: ${text}`;
const result = execSync(
`claude --model claude-sonnet-4-20250514 --print --output-format text`,
`claude --model claude-sonnet-5 --print --output-format text`,
{
input,
encoding: "utf-8",
Expand Down Expand Up @@ -977,6 +977,18 @@ async function handleMessageCreate(token: string, message: DiscordMessage, skipC
// Skill routing: detect slash commands and resolve to SKILL.md prompts
const command = cleanContent.startsWith("/") ? cleanContent.trim().split(/\s+/, 1)[0].toLowerCase() : null;

if (command === "/kill" || command === "/stop") {
// killActive() is global: it kills every in-flight main run across all
// Discord channels/threads, not just the caller's. Combined with the
// channel-scoped allowlist (#248), a user authorized in one channel can
// kill runs in channels they aren't authorized for. Matches Telegram's
// existing /kill contract (not a regression); thread-scoped kill is
// tracked separately (see #237).
const killed = killActive();
await sendMessage(config.token, channelId, killed ? "Killed active agent." : "No active agent running.");
return;
}

let skillContext: string | null = null;
if (command) {
try {
Expand Down
Loading