diff --git a/cmd/cli_mode.go b/cmd/cli_mode.go index 901cc4974..c5ad0c4ff 100644 --- a/cmd/cli_mode.go +++ b/cmd/cli_mode.go @@ -55,6 +55,11 @@ var agentAllowed = map[string]bool{ "schedule.list": true, "schedule.get": true, "schedule.cancel": true, + "schedule.create": true, + "schedule.create-recurring": true, + "schedule.pause": true, + "schedule.resume": true, + "schedule.delete": true, "schedule.history": true, "shared-dir": true, "shared-dir.list": true, diff --git a/cmd/cli_mode_test.go b/cmd/cli_mode_test.go index 888a719ad..fe3234d17 100644 --- a/cmd/cli_mode_test.go +++ b/cmd/cli_mode_test.go @@ -283,7 +283,9 @@ func TestApplyModeRestrictions_Agent(t *testing.T) { "notifications.ack", "notifications.subscribe", "notifications.subscriptions", "notifications.unsubscribe", "notifications.update", "resume", - "schedule", "schedule.cancel", "schedule.get", "schedule.history", "schedule.list", + "schedule", "schedule.cancel", "schedule.create", "schedule.create-recurring", + "schedule.delete", "schedule.get", "schedule.history", "schedule.list", + "schedule.pause", "schedule.resume", "shared-dir", "shared-dir.info", "shared-dir.list", "start", "stop", "template", @@ -334,11 +336,11 @@ func TestApplyModeRestrictions_AgentScheduleSubcommands(t *testing.T) { assert.Contains(t, remaining, "schedule.cancel") assert.Contains(t, remaining, "schedule.history") - assert.NotContains(t, remaining, "schedule.create") - assert.NotContains(t, remaining, "schedule.create-recurring") - assert.NotContains(t, remaining, "schedule.pause") - assert.NotContains(t, remaining, "schedule.resume") - assert.NotContains(t, remaining, "schedule.delete") + assert.Contains(t, remaining, "schedule.create") + assert.Contains(t, remaining, "schedule.create-recurring") + assert.Contains(t, remaining, "schedule.pause") + assert.Contains(t, remaining, "schedule.resume") + assert.Contains(t, remaining, "schedule.delete") } func TestApplyModeRestrictions_HelpAlwaysKept(t *testing.T) { @@ -413,6 +415,7 @@ func TestAgentAllowedList(t *testing.T) { "resume", "version", "notifications", "schedule", "schedule.list", "schedule.get", "schedule.cancel", "schedule.history", + "schedule.create", "schedule.create-recurring", "schedule.pause", "schedule.resume", "schedule.delete", "shared-dir", "shared-dir.list", "shared-dir.info", "templates", "templates.list", "templates.show", "templates.create", "templates.clone", "templates.delete", "templates.update-default", @@ -436,8 +439,6 @@ func TestAgentAllowedList(t *testing.T) { "hub.auth", "hub.token", "hub.groves", "hub.brokers", "hub.env", "hub.secret", "hub.status", "hub.notifications", "messages.read", - "schedule.create", "schedule.create-recurring", "schedule.delete", - "schedule.pause", "schedule.resume", "shared-dir.create", "shared-dir.remove", } for _, path := range notAllowed { diff --git a/cmd/schedule.go b/cmd/schedule.go index 97783e7a2..1a0abca01 100644 --- a/cmd/schedule.go +++ b/cmd/schedule.go @@ -38,9 +38,6 @@ var ( scheduleName string scheduleCron string scheduleListType string // "events", "recurring", "all" - scheduleTemplate string - scheduleTask string - scheduleBranch string ) // scheduleCmd is the top-level command group for schedule management. @@ -77,8 +74,7 @@ var scheduleCancelCmd = &cobra.Command{ var scheduleCreateCmd = &cobra.Command{ Use: "create", Short: "Create a one-shot scheduled event", - Long: `Create a one-shot scheduled event. Requires --type, timing (--in or --at), -and type-specific flags (e.g. --agent and --message for message events).`, + Long: `Create a one-shot scheduled event. Requires timing (--in or --at), --agent, and --message.`, RunE: runScheduleCreate, } @@ -86,8 +82,7 @@ and type-specific flags (e.g. --agent and --message for message events).`, var scheduleCreateRecurringCmd = &cobra.Command{ Use: "create-recurring", Short: "Create a recurring schedule", - Long: `Create a recurring schedule with a cron expression. Requires --name, --cron, ---type, and type-specific flags (e.g. --agent and --message for message events).`, + Long: `Create a recurring schedule with a cron expression. Requires --name, --cron, --agent, and --message.`, RunE: runScheduleCreateRecurring, } @@ -408,9 +403,6 @@ func runScheduleCancel(cmd *cobra.Command, args []string) error { } func runScheduleCreate(cmd *cobra.Command, args []string) error { - if scheduleType == "" { - return fmt.Errorf("--type is required") - } if scheduleIn == "" && scheduleAt == "" { return fmt.Errorf("either --in or --at is required") } @@ -427,12 +419,8 @@ func runScheduleCreate(cmd *cobra.Command, args []string) error { if scheduleMessage == "" { return fmt.Errorf("--message is required for message events") } - case "dispatch_agent": - if scheduleAgent == "" { - return fmt.Errorf("--agent is required for dispatch_agent events (the name of the agent to create)") - } default: - return fmt.Errorf("unsupported event type: %q (supported: message, dispatch_agent)", scheduleType) + return fmt.Errorf("unsupported event type: %q (supported: message)", scheduleType) } hubCtx, err := CheckHubAvailabilityWithOptions(projectPath, true) @@ -457,9 +445,6 @@ func runScheduleCreate(cmd *cobra.Command, args []string) error { AgentName: scheduleAgent, Message: scheduleMessage, Interrupt: scheduleInterrupt, - Template: scheduleTemplate, - Task: scheduleTask, - Branch: scheduleBranch, } if scheduleIn != "" { @@ -494,10 +479,6 @@ func runScheduleCreateRecurring(cmd *cobra.Command, args []string) error { if scheduleCron == "" { return fmt.Errorf("--cron is required") } - if scheduleType == "" { - return fmt.Errorf("--type is required") - } - // Validate type-specific flags switch scheduleType { case "message": @@ -507,12 +488,8 @@ func runScheduleCreateRecurring(cmd *cobra.Command, args []string) error { if scheduleMessage == "" { return fmt.Errorf("--message is required for message schedules") } - case "dispatch_agent": - if scheduleAgent == "" { - return fmt.Errorf("--agent is required for dispatch_agent schedules (the name of the agent to create)") - } default: - return fmt.Errorf("unsupported event type: %q (supported: message, dispatch_agent)", scheduleType) + return fmt.Errorf("unsupported event type: %q (supported: message)", scheduleType) } hubCtx, err := CheckHubAvailabilityWithOptions(projectPath, true) @@ -539,9 +516,6 @@ func runScheduleCreateRecurring(cmd *cobra.Command, args []string) error { AgentName: scheduleAgent, Message: scheduleMessage, Interrupt: scheduleInterrupt, - Template: scheduleTemplate, - Task: scheduleTask, - Branch: scheduleBranch, } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) @@ -805,24 +779,18 @@ func init() { scheduleListCmd.Flags().StringVar(&scheduleListType, "show", "", "Filter by resource type: events, recurring, or all (default: all)") // Create one-shot flags - scheduleCreateCmd.Flags().StringVar(&scheduleType, "type", "", "Event type (required: message, dispatch_agent)") + scheduleCreateCmd.Flags().StringVar(&scheduleType, "type", "message", "Event type") scheduleCreateCmd.Flags().StringVar(&scheduleIn, "in", "", "Schedule after a duration (e.g. 30m, 1h)") scheduleCreateCmd.Flags().StringVar(&scheduleAt, "at", "", "Schedule at an absolute time (ISO 8601)") scheduleCreateCmd.Flags().StringVar(&scheduleAgent, "agent", "", "Target agent name") - scheduleCreateCmd.Flags().StringVar(&scheduleMessage, "message", "", "Message body (for message events)") - scheduleCreateCmd.Flags().BoolVar(&scheduleInterrupt, "interrupt", false, "Interrupt the agent (for message events)") - scheduleCreateCmd.Flags().StringVar(&scheduleTemplate, "template", "", "Agent template (for dispatch_agent events)") - scheduleCreateCmd.Flags().StringVar(&scheduleTask, "task", "", "Task/prompt for the agent (for dispatch_agent events)") - scheduleCreateCmd.Flags().StringVar(&scheduleBranch, "branch", "", "Git branch name (for dispatch_agent events)") + scheduleCreateCmd.Flags().StringVar(&scheduleMessage, "message", "", "Message body") + scheduleCreateCmd.Flags().BoolVar(&scheduleInterrupt, "interrupt", false, "Interrupt the agent") // Create recurring flags scheduleCreateRecurringCmd.Flags().StringVar(&scheduleName, "name", "", "Schedule name (required)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleCron, "cron", "", "Cron expression (required, 5-field: minute hour day month weekday)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleType, "type", "", "Event type (required: message, dispatch_agent)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleAgent, "agent", "", "Target agent name (for message: name or 'all'; for dispatch_agent: name to create)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleMessage, "message", "", "Message body (for message events)") - scheduleCreateRecurringCmd.Flags().BoolVar(&scheduleInterrupt, "interrupt", false, "Interrupt the agent (for message events)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleTemplate, "template", "", "Agent template (for dispatch_agent events)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleTask, "task", "", "Task/prompt for the agent (for dispatch_agent events)") - scheduleCreateRecurringCmd.Flags().StringVar(&scheduleBranch, "branch", "", "Git branch name (for dispatch_agent events)") + scheduleCreateRecurringCmd.Flags().StringVar(&scheduleCron, "cron", "", "Cron expression (required, 5-field: minute hour day month weekday, UTC)") + scheduleCreateRecurringCmd.Flags().StringVar(&scheduleType, "type", "message", "Event type") + scheduleCreateRecurringCmd.Flags().StringVar(&scheduleAgent, "agent", "", "Target agent name") + scheduleCreateRecurringCmd.Flags().StringVar(&scheduleMessage, "message", "", "Message body") + scheduleCreateRecurringCmd.Flags().BoolVar(&scheduleInterrupt, "interrupt", false, "Interrupt the agent") } diff --git a/cmd/schedule_test.go b/cmd/schedule_test.go index 573e346d2..5a3b247ca 100644 --- a/cmd/schedule_test.go +++ b/cmd/schedule_test.go @@ -81,12 +81,12 @@ func TestScheduleCreateValidation(t *testing.T) { scheduleMessage = origMessage }() - t.Run("missing type", func(t *testing.T) { + t.Run("empty type rejected", func(t *testing.T) { scheduleType = "" scheduleIn = "30m" err := runScheduleCreate(nil, nil) assert.Error(t, err) - assert.Contains(t, err.Error(), "--type is required") + assert.Contains(t, err.Error(), "unsupported event type") }) t.Run("missing timing", func(t *testing.T) {