Skip to content

Commit c81c720

Browse files
committed
feat: add stopTask, Agent Teams env var, delegate mode, and help docs
1 parent 0340ee6 commit c81c720

File tree

6 files changed

+122
-2
lines changed

6 files changed

+122
-2
lines changed

claude/client.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ export interface ClaudeModelOptions {
113113
enableFileCheckpointing?: boolean;
114114
/** Sandbox settings for safer command execution */
115115
sandbox?: { enabled: boolean; autoAllowBashIfSandboxed?: boolean };
116+
/** Enable experimental Agent Teams (multi-agent collaboration) */
117+
enableAgentTeams?: boolean;
116118
/** Structured output format (JSON schema) */
117119
outputFormat?: { type: 'json_schema'; schema: Record<string, unknown> };
118120
/** Callback for AskUserQuestion tool — Claude asks the user mid-session.
@@ -170,6 +172,8 @@ export async function sendToClaudeCode(
170172
...Object.fromEntries(Object.entries(Deno.env.toObject())),
171173
// Enable the Tasks system for subagent background tasks (SDK v0.2.19+)
172174
CLAUDE_CODE_ENABLE_TASKS: '1',
175+
// Enable experimental Agent Teams if configured
176+
...(modelOptions?.enableAgentTeams && { CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: '1' }),
173177
};
174178

175179
// Apply extra env vars (proxy settings, etc.)

claude/info-commands.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
getAccountInfo,
2323
getSupportedModels,
2424
getMcpServerStatus,
25+
stopActiveTask,
2526
} from "./query-manager.ts";
2627

2728
// ================================
@@ -66,6 +67,7 @@ export const infoCommands = [
6667
{ name: 'Interrupt — Stop current processing', value: 'interrupt' },
6768
{ name: 'Change Model — Switch model mid-session', value: 'set-model' },
6869
{ name: 'Change Permissions — Switch permission mode', value: 'set-permissions' },
70+
{ name: 'Stop Task — Stop a running background task', value: 'stop-task' },
6971
{ name: 'Status — Show active session info', value: 'status' }
7072
))
7173
.addStringOption(option =>
@@ -428,9 +430,31 @@ export function createInfoCommandHandlers(deps: InfoCommandHandlerDeps) {
428430
break;
429431
}
430432

433+
case 'stop-task': {
434+
if (!value) {
435+
await ctx.editReply({
436+
content: 'Please provide a task ID. Example: `/claude-control action:stop-task value:<taskId>`\nTask IDs are shown in "Subagent Task Started" embeds.',
437+
ephemeral: true
438+
});
439+
return;
440+
}
441+
const success = await stopActiveTask(value);
442+
await ctx.editReply({
443+
embeds: [{
444+
color: success ? 0x00ff00 : 0xff0000,
445+
title: success ? '⏹️ Task Stop Requested' : '❌ Cannot Stop Task',
446+
description: success
447+
? `Stop signal sent for task \`${value}\`. A notification will appear when the task stops.`
448+
: 'No active query, or the task ID was not found.',
449+
timestamp: new Date().toISOString()
450+
}]
451+
});
452+
break;
453+
}
454+
431455
default:
432456
await ctx.editReply({
433-
content: `Unknown action: ${action}. Available: interrupt, set-model, set-permissions, status`,
457+
content: `Unknown action: ${action}. Available: interrupt, set-model, set-permissions, stop-task, status`,
434458
ephemeral: true
435459
});
436460
}

claude/query-manager.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,22 @@ export async function getMcpServerStatus(): Promise<McpServerStatus[] | null> {
203203
}
204204
}
205205

206+
/**
207+
* Stop a running background task (subagent).
208+
* A task_notification with status 'stopped' will be emitted.
209+
*
210+
* @param taskId - The task ID from task_notification/task_started events
211+
*/
212+
export async function stopActiveTask(taskId: string): Promise<boolean> {
213+
if (!activeQuery) return false;
214+
try {
215+
await activeQuery.stopTask(taskId);
216+
return true;
217+
} catch {
218+
return false;
219+
}
220+
}
221+
206222
// ================================
207223
// Ephemeral Info Query
208224
// ================================

core/handler-registry.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,9 @@ export function createAllHandlers(
436436
if (s.enableSandbox) {
437437
opts.sandbox = { enabled: true, autoAllowBashIfSandboxed: true };
438438
}
439+
if (s.enableAgentTeams) {
440+
opts.enableAgentTeams = true;
441+
}
439442
if (s.outputJsonSchema) {
440443
opts.outputFormat = { type: 'json_schema', schema: s.outputJsonSchema };
441444
}

help/commands.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,70 @@ export const COMMAND_HELP = {
799799
"Takes effect on the next query (persists across sessions)",
800800
"Use /fast again to toggle back to standard mode"
801801
]
802+
},
803+
"claude-info": {
804+
title: "ℹ️ Claude Info & Diagnostics",
805+
description: "Show Claude account info, available models, and MCP server status",
806+
usage: "/claude-info section: [account/models/mcp/all]",
807+
examples: [
808+
"/claude-info",
809+
"/claude-info section: account",
810+
"/claude-info section: models",
811+
"/claude-info section: mcp"
812+
],
813+
parameters: [
814+
{ name: "section", description: "Which info section to show (account, models, mcp, or all)", required: false }
815+
],
816+
notes: [
817+
"Requires an active Claude session to query",
818+
"Shows account tier, rate limits, and usage",
819+
"Lists all available models with capabilities",
820+
"Displays MCP server connection status"
821+
]
822+
},
823+
"rewind": {
824+
title: "⏪ Rewind File Changes",
825+
description: "Rewind file changes to a previous state (requires file checkpointing)",
826+
usage: "/rewind turn: [turn_number] dry_run: [true/false]",
827+
examples: [
828+
"/rewind",
829+
"/rewind turn: 5",
830+
"/rewind turn: 3 dry_run: true"
831+
],
832+
parameters: [
833+
{ name: "turn", description: "Turn number to rewind to (omit to see available turns)", required: false },
834+
{ name: "dry_run", description: "Preview changes without modifying files", required: false }
835+
],
836+
notes: [
837+
"Requires an active Claude session with file checkpointing enabled",
838+
"Use without arguments to list available checkpoint turns",
839+
"Use dry_run to preview which files would be affected",
840+
"Rewinding restores files to their state at the specified turn"
841+
]
842+
},
843+
"claude-control": {
844+
title: "🎛️ Mid-Session Controls",
845+
description: "Control an active Claude query — interrupt, switch models, change permissions, or stop tasks",
846+
usage: "/claude-control action: [interrupt/set-model/set-permissions/stop-task/status] value: [optional]",
847+
examples: [
848+
"/claude-control action: interrupt",
849+
"/claude-control action: set-model value: claude-sonnet-4",
850+
"/claude-control action: set-permissions value: plan",
851+
"/claude-control action: stop-task value: task_id_here",
852+
"/claude-control action: status"
853+
],
854+
parameters: [
855+
{ name: "action", description: "Control action to perform", required: true },
856+
{ name: "value", description: "Value for the action (model name, permission mode, or task ID)", required: false }
857+
],
858+
notes: [
859+
"Requires an active Claude session to control",
860+
"Interrupt stops the current processing immediately",
861+
"Set-model switches the model mid-conversation",
862+
"Set-permissions changes the permission mode (plan, autoEdit, fullAuto, delegate, bypassPermissions)",
863+
"Stop-task halts a running background task by its ID",
864+
"Status shows active session info"
865+
]
802866
}
803867
};
804868

settings/unified-settings.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface UnifiedBotSettings {
2121
effortLevel: 'low' | 'medium' | 'high' | 'max';
2222

2323
// Mode settings
24-
operationMode: 'normal' | 'plan' | 'auto-accept' | 'danger' | 'dont-ask';
24+
operationMode: 'normal' | 'plan' | 'auto-accept' | 'danger' | 'dont-ask' | 'delegate';
2525

2626
// Fast mode — Opus 4.6 speed-optimized API config (2.5x faster, higher cost, same quality)
2727
fastMode: boolean;
@@ -36,6 +36,8 @@ export interface UnifiedBotSettings {
3636
enableFileCheckpointing: boolean;
3737
/** Enable sandbox mode for safer command execution */
3838
enableSandbox: boolean;
39+
/** Enable experimental Agent Teams (multi-agent collaboration) */
40+
enableAgentTeams: boolean;
3941
/** JSON schema for structured output (null = unstructured text) */
4042
outputJsonSchema: Record<string, unknown> | null;
4143

@@ -96,6 +98,7 @@ export const UNIFIED_DEFAULT_SETTINGS: UnifiedBotSettings = {
9698
enable1MContext: false,
9799
enableFileCheckpointing: false,
98100
enableSandbox: false,
101+
enableAgentTeams: false,
99102
outputJsonSchema: null,
100103

101104
// Output
@@ -213,6 +216,12 @@ export const OPERATION_MODES = {
213216
description: 'Bypasses all permission checks — use with extreme caution',
214217
permissionMode: 'bypassPermissions' as const,
215218
riskLevel: 'high'
219+
},
220+
'delegate': {
221+
name: 'Delegate Mode',
222+
description: 'Restricts to Teammate + Task tools only — for agent team leaders',
223+
permissionMode: 'delegate' as const,
224+
riskLevel: 'low'
216225
}
217226
} as const;
218227

0 commit comments

Comments
 (0)