chore: fix pint code style and add test config
Some checks failed
CI / tests (push) Failing after 1m9s

Add phpunit.xml for standalone test execution.
Apply Laravel Pint formatting fixes across all source files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude 2026-02-23 03:50:09 +00:00
parent 1226ec0db0
commit 3f905583a8
No known key found for this signature in database
GPG key ID: AF404715446AEB41
62 changed files with 277 additions and 244 deletions

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Console\Commands;
use Illuminate\Console\Command;
use Core\Mod\Agentic\Models\AgentPlan;
use Illuminate\Console\Command;
use Mod\Content\Jobs\GenerateContentJob;
use Mod\Content\Models\ContentBrief;
use Mod\Content\Services\AIGatewayService;

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Console\Commands;
use Illuminate\Console\Command;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Services\PlanTemplateService;
use Illuminate\Console\Command;
class PlanCommand extends Command
{

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Console\Commands;
use Illuminate\Console\Command;
use Core\Mod\Agentic\Models\Task;
use Illuminate\Console\Command;
class TaskCommand extends Command
{

View file

@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Jobs;
use Mod\Content\Models\ContentTask;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Mod\Content\Models\ContentTask;
class BatchContentGeneration implements ShouldQueue
{

View file

@ -5,14 +5,14 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Jobs;
use Core\Mod\Agentic\Services\AgenticManager;
use Mod\Content\Models\ContentTask;
use Mod\Content\Services\ContentProcessingService;
use Core\Tenant\Services\EntitlementService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mod\Content\Models\ContentTask;
use Mod\Content\Services\ContentProcessingService;
use Throwable;
class ProcessContentTask implements ShouldQueue

View file

@ -15,12 +15,12 @@ use Core\Mcp\Tools\ListRoutes;
use Core\Mcp\Tools\ListSites;
use Core\Mcp\Tools\ListTables;
use Core\Mcp\Tools\QueryDatabase;
use Mod\Bio\Mcp\BioResource;
use Laravel\Mcp\Server;
use Core\Mod\Agentic\Mcp\Prompts\AnalysePerformancePrompt;
use Core\Mod\Agentic\Mcp\Prompts\ConfigureNotificationsPrompt;
use Core\Mod\Agentic\Mcp\Prompts\CreateBioPagePrompt;
use Core\Mod\Agentic\Mcp\Prompts\SetupQrCampaignPrompt;
use Laravel\Mcp\Server;
use Mod\Bio\Mcp\BioResource;
class HostHub extends Server
{

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Mod\Content\Jobs\GenerateContentJob;
use Mod\Content\Models\ContentBrief;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Queue multiple briefs for batch content generation.

View file

@ -4,11 +4,11 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Illuminate\Support\Str;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
use Illuminate\Support\Str;
use Mod\Content\Enums\BriefContentType;
use Mod\Content\Models\ContentBrief;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Create a content brief for AI generation.

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Mod\Content\Enums\BriefContentType;
use Mod\Content\Models\ContentBrief;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Get details of a specific content brief including generated content.

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Mod\Content\Enums\BriefContentType;
use Mod\Content\Models\ContentBrief;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* List content briefs with optional status filter.

View file

@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Illuminate\Support\Str;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
use Illuminate\Support\Str;
use Mod\Content\Enums\BriefContentType;
use Mod\Content\Jobs\GenerateContentJob;
use Mod\Content\Models\ContentBrief;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Create content briefs from plan tasks and queue for generation.

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Mod\Content\Jobs\GenerateContentJob;
use Mod\Content\Models\ContentBrief;
use Mod\Content\Services\AIGatewayService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Generate content for a brief using AI pipeline.

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Mod\Content\Models\ContentBrief;
use Mod\Content\Services\AIGatewayService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Get content generation pipeline status.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Content;
use Mod\Content\Models\AIUsage;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Mod\Content\Models\AIUsage;
/**
* Get AI usage statistics for content generation.

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Phase;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPhase;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Add a checkpoint note to a phase.

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Phase;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPhase;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Get details of a specific phase within a plan.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Plan;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
/**
* Archive a completed or abandoned plan.

View file

@ -5,10 +5,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Plan;
use Core\Mcp\Dependencies\ToolDependency;
use Illuminate\Support\Str;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPhase;
use Core\Mod\Agentic\Models\AgentPlan;
use Illuminate\Support\Str;
/**
* Create a new work plan with phases and tasks.

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Plan;
use Core\Mcp\Dependencies\ToolDependency;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
/**
* Get detailed information about a specific plan.

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Plan;
use Core\Mcp\Dependencies\ToolDependency;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
/**
* List all work plans with their current status and progress.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Plan;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
/**
* Update the status of a plan.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mod\Agentic\Models\AgentSession;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentSession;
/**
* Record an artifact created/modified during the session.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mod\Agentic\Services\AgentSessionService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Services\AgentSessionService;
/**
* Continue from a previous session (multi-agent handoff).

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mod\Agentic\Models\AgentSession;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentSession;
/**
* End the current session.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mod\Agentic\Models\AgentSession;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentSession;
/**
* Prepare session for handoff to another agent.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mod\Agentic\Services\AgentSessionService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Services\AgentSessionService;
/**
* List sessions, optionally filtered by status.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mod\Agentic\Services\AgentSessionService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Services\AgentSessionService;
/**
* Resume a paused or handed-off session.

View file

@ -5,10 +5,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session;
use Core\Mcp\Dependencies\ToolDependency;
use Illuminate\Support\Str;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentSession;
use Illuminate\Support\Str;
/**
* Start a new agent session for a plan.

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\State;
use Core\Mcp\Dependencies\ToolDependency;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
/**
* Get a workspace state value.

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\State;
use Core\Mcp\Dependencies\ToolDependency;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
/**
* List all state values for a plan.

View file

@ -5,9 +5,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\State;
use Core\Mcp\Dependencies\ToolDependency;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentWorkspaceState;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
/**
* Set a workspace state value.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Template;
use Core\Mod\Agentic\Services\PlanTemplateService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Services\PlanTemplateService;
/**
* Create a new plan from a template.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Template;
use Core\Mod\Agentic\Services\PlanTemplateService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Services\PlanTemplateService;
/**
* List available plan templates.

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Template;
use Core\Mod\Agentic\Services\PlanTemplateService;
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool;
use Core\Mod\Agentic\Services\PlanTemplateService;
/**
* Preview a template with variables.

View file

@ -5,9 +5,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Middleware;
use Closure;
use Illuminate\Http\Request;
use Core\Mod\Agentic\Models\AgentApiKey;
use Core\Mod\Agentic\Services\AgentApiKeyService;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**

View file

@ -4,11 +4,11 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Models;
use Core\Mod\Agentic\Database\Factories\AgentPhaseFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;
use Core\Mod\Agentic\Database\Factories\AgentPhaseFactory;
/**
* Agent Phase - individual phase within a plan.

View file

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Models;
use Core\Mod\Agentic\Database\Factories\AgentPlanFactory;
use Core\Tenant\Concerns\BelongsToWorkspace;
use Core\Tenant\Models\Workspace;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;
use Core\Mod\Agentic\Database\Factories\AgentPlanFactory;
use Core\Tenant\Concerns\BelongsToWorkspace;
use Core\Tenant\Models\Workspace;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
@ -128,7 +128,7 @@ class AgentPlan extends Model
WHEN ? THEN 3
WHEN ? THEN 4
ELSE 5
END ' . ($direction === 'desc' ? 'DESC' : 'ASC'), [self::STATUS_ACTIVE, self::STATUS_DRAFT, self::STATUS_COMPLETED, self::STATUS_ARCHIVED]);
END '.($direction === 'desc' ? 'DESC' : 'ASC'), [self::STATUS_ACTIVE, self::STATUS_DRAFT, self::STATUS_COMPLETED, self::STATUS_ARCHIVED]);
}
// Helpers

View file

@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Models;
use Core\Mod\Agentic\Database\Factories\AgentSessionFactory;
use Core\Tenant\Concerns\BelongsToWorkspace;
use Core\Tenant\Models\Workspace;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Core\Mod\Agentic\Database\Factories\AgentSessionFactory;
use Ramsey\Uuid\Uuid;
/**

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Models;
use Mod\Content\Models\ContentTask;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Mod\Content\Models\ContentTask;
class Prompt extends Model
{

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Models;
use Illuminate\Database\Eloquent\Model;
use Core\Tenant\Concerns\BelongsToWorkspace;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
@ -60,7 +60,7 @@ class Task extends Model
WHEN ? THEN 3
WHEN ? THEN 4
ELSE 5
END ' . ($direction === 'desc' ? 'DESC' : 'ASC'), ['urgent', 'high', 'normal', 'low']);
END '.($direction === 'desc' ? 'DESC' : 'ASC'), ['urgent', 'high', 'normal', 'low']);
}
/**
@ -76,7 +76,7 @@ class Task extends Model
WHEN ? THEN 2
WHEN ? THEN 3
ELSE 4
END ' . ($direction === 'desc' ? 'DESC' : 'ASC'), ['in_progress', 'pending', 'done']);
END '.($direction === 'desc' ? 'DESC' : 'ASC'), ['in_progress', 'pending', 'done']);
}
public function getStatusBadgeAttribute(): string

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Services;
use Core\Mod\Agentic\Models\AgentApiKey;
use Core\Tenant\Models\Workspace;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Core\Mod\Agentic\Models\AgentApiKey;
/**
* Agent API Key Service.

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Services;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentSession;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
/**
* Agent Session Service - manages session persistence for agent continuity.

View file

@ -7,8 +7,8 @@ namespace Core\Mod\Agentic\Services;
use Core\Api\Models\ApiKey;
use Core\Mcp\Dependencies\HasDependencies;
use Core\Mcp\Services\ToolDependencyService;
use Illuminate\Support\Collection;
use Core\Mod\Agentic\Mcp\Tools\Agent\Contracts\AgentToolInterface;
use Illuminate\Support\Collection;
/**
* Registry for MCP Agent Server tools.

View file

@ -4,12 +4,11 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Services;
use Core\Mod\Agentic\Services\Concerns\HasRetry;
use Core\Mod\Agentic\Services\Concerns\HasStreamParsing;
use Generator;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Core\Mod\Agentic\Services\Concerns\HasRetry;
use Core\Mod\Agentic\Services\Concerns\HasStreamParsing;
use RuntimeException;
class ClaudeService implements AgenticProviderInterface
{

View file

@ -25,7 +25,6 @@ trait HasRetry
*
* @param callable $callback Function that returns Response
* @param string $provider Provider name for error messages
* @return Response
*
* @throws RuntimeException
*/

View file

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Services;
use Mod\Content\Models\ContentItem;
use Illuminate\Support\Facades\File;
use Mod\Content\Models\ContentItem;
use Symfony\Component\Yaml\Yaml;
class ContentService

View file

@ -4,12 +4,11 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Services;
use Core\Mod\Agentic\Services\Concerns\HasRetry;
use Core\Mod\Agentic\Services\Concerns\HasStreamParsing;
use Generator;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Core\Mod\Agentic\Services\Concerns\HasRetry;
use Core\Mod\Agentic\Services\Concerns\HasStreamParsing;
use RuntimeException;
class GeminiService implements AgenticProviderInterface
{

View file

@ -4,12 +4,11 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Services;
use Core\Mod\Agentic\Services\Concerns\HasRetry;
use Core\Mod\Agentic\Services\Concerns\HasStreamParsing;
use Generator;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Core\Mod\Agentic\Services\Concerns\HasRetry;
use Core\Mod\Agentic\Services\Concerns\HasStreamParsing;
use RuntimeException;
class OpenAIService implements AgenticProviderInterface
{

View file

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\View\Modal\Admin;
use Core\Mod\Agentic\Models\AgentApiKey;
use Core\Mod\Agentic\Services\AgentApiKeyService;
use Core\Tenant\Models\Workspace;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
@ -13,8 +15,6 @@ use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;
use Core\Mod\Agentic\Models\AgentApiKey;
use Core\Mod\Agentic\Services\AgentApiKeyService;
use Symfony\Component\HttpFoundation\StreamedResponse;
#[Title('API Keys')]

View file

@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\View\Modal\Admin;
use Core\Mcp\Models\McpToolCallStat;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentSession;
use Core\Mcp\Models\McpToolCallStat;
use Illuminate\Cache\Lock;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Cache;
use Illuminate\Cache\Lock;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;

View file

@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\View\Modal\Admin;
use Core\Mod\Agentic\Models\AgentSession;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Core\Mod\Agentic\Models\AgentSession;
#[Title('Session Detail')]
#[Layout('hub::admin.layouts.app')]

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\View\Modal\Admin;
use Core\Tenant\Models\Workspace;
use Core\Mcp\Models\McpToolCall;
use Core\Mcp\Models\McpToolCallStat;
use Core\Tenant\Models\Workspace;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Livewire\Attributes\Computed;

View file

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\View\Modal\Admin;
use Core\Tenant\Models\Workspace;
use Core\Mcp\Models\McpToolCall;
use Core\Mcp\Models\McpToolCallStat;
use Core\Tenant\Models\Workspace;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;

39
phpunit.xml Normal file
View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
cacheDirectory=".phpunit.cache"
executionOrder="random"
requireCoverageMetadata="false"
beStrictAboutCoverageMetadata="false"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_DEBUG" value="true"/>
<env name="APP_KEY" value="base64:Kx0qLJZJAQcDSFE2gMpuOlwrJcC6kXHM0j0KJdMGqzQ="/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_STORE" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>

View file

@ -1,5 +1,3 @@
<?php
use Illuminate\Support\Facades\Route;
// API routes are registered via Core modules

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Core\Mod\Agentic\Models\AgentPhase;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Tenant\Models\Workspace;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AgentPhaseTest extends TestCase

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Core\Mod\Agentic\Models\AgentPhase;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Tenant\Models\Workspace;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AgentPlanTest extends TestCase

View file

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentSession;
use Core\Tenant\Models\Workspace;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AgentSessionTest extends TestCase

View file

@ -794,7 +794,7 @@ describe('edge cases', function () {
});
it('handles malformed YAML gracefully', function () {
File::put($this->testTemplatesPath.'/malformed.yaml', "invalid: yaml: content: [");
File::put($this->testTemplatesPath.'/malformed.yaml', 'invalid: yaml: content: [');
// Should not throw when listing
$result = $this->service->list();

View file

@ -4,16 +4,16 @@ declare(strict_types=1);
namespace Core\Mod\Agentic\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentWorkspaceState;
use Core\Mod\Agentic\Models\Task;
use Core\Mod\Agentic\Mcp\Tools\Agent\Plan\PlanGet;
use Core\Mod\Agentic\Mcp\Tools\Agent\Plan\PlanList;
use Core\Mod\Agentic\Mcp\Tools\Agent\State\StateGet;
use Core\Mod\Agentic\Mcp\Tools\Agent\State\StateList;
use Core\Mod\Agentic\Mcp\Tools\Agent\State\StateSet;
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentWorkspaceState;
use Core\Mod\Agentic\Models\Task;
use Core\Tenant\Models\Workspace;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
@ -24,6 +24,7 @@ class SecurityTest extends TestCase
use RefreshDatabase;
private Workspace $workspace;
private Workspace $otherWorkspace;
protected function setUp(): void
@ -43,7 +44,7 @@ class SecurityTest extends TestCase
'workspace_id' => $this->workspace->id,
]);
$tool = new StateSet();
$tool = new StateSet;
$result = $tool->handle([
'plan_slug' => $plan->slug,
'key' => 'test_key',
@ -60,7 +61,7 @@ class SecurityTest extends TestCase
'workspace_id' => $this->otherWorkspace->id,
]);
$tool = new StateSet();
$tool = new StateSet;
$result = $tool->handle([
'plan_slug' => $otherPlan->slug,
'key' => 'test_key',
@ -77,7 +78,7 @@ class SecurityTest extends TestCase
'workspace_id' => $this->workspace->id,
]);
$tool = new StateSet();
$tool = new StateSet;
$result = $tool->handle([
'plan_slug' => $plan->slug,
'key' => 'test_key',
@ -105,7 +106,7 @@ class SecurityTest extends TestCase
'value' => ['data' => 'secret'],
]);
$tool = new StateGet();
$tool = new StateGet;
$result = $tool->handle([
'plan_slug' => $plan->slug,
'key' => 'test_key',
@ -127,7 +128,7 @@ class SecurityTest extends TestCase
'value' => ['data' => 'sensitive'],
]);
$tool = new StateGet();
$tool = new StateGet;
$result = $tool->handle([
'plan_slug' => $otherPlan->slug,
'key' => 'secret_key',
@ -149,7 +150,7 @@ class SecurityTest extends TestCase
'value' => ['data' => 'allowed'],
]);
$tool = new StateGet();
$tool = new StateGet;
$result = $tool->handle([
'plan_slug' => $plan->slug,
'key' => 'test_key',
@ -170,7 +171,7 @@ class SecurityTest extends TestCase
'workspace_id' => $this->workspace->id,
]);
$tool = new StateList();
$tool = new StateList;
$result = $tool->handle([
'plan_slug' => $plan->slug,
], []); // No workspace_id in context
@ -191,7 +192,7 @@ class SecurityTest extends TestCase
'value' => ['data' => 'sensitive'],
]);
$tool = new StateList();
$tool = new StateList;
$result = $tool->handle([
'plan_slug' => $otherPlan->slug,
], ['workspace_id' => $this->workspace->id]); // Different workspace
@ -210,7 +211,7 @@ class SecurityTest extends TestCase
'workspace_id' => $this->workspace->id,
]);
$tool = new PlanGet();
$tool = new PlanGet;
$result = $tool->handle([
'slug' => $plan->slug,
], []); // No workspace_id in context
@ -226,7 +227,7 @@ class SecurityTest extends TestCase
'title' => 'Secret Plan',
]);
$tool = new PlanGet();
$tool = new PlanGet;
$result = $tool->handle([
'slug' => $otherPlan->slug,
], ['workspace_id' => $this->workspace->id]); // Different workspace
@ -242,7 +243,7 @@ class SecurityTest extends TestCase
'title' => 'My Plan',
]);
$tool = new PlanGet();
$tool = new PlanGet;
$result = $tool->handle([
'slug' => $plan->slug,
], ['workspace_id' => $this->workspace->id]);
@ -258,7 +259,7 @@ class SecurityTest extends TestCase
public function test_plan_list_requires_workspace_context(): void
{
$tool = new PlanList();
$tool = new PlanList;
$result = $tool->handle([], []); // No workspace_id in context
$this->assertArrayHasKey('error', $result);
@ -277,7 +278,7 @@ class SecurityTest extends TestCase
'title' => 'Other Plan',
]);
$tool = new PlanList();
$tool = new PlanList;
$result = $tool->handle([], ['workspace_id' => $this->workspace->id]);
$this->assertArrayHasKey('success', $result);
@ -387,7 +388,7 @@ class SecurityTest extends TestCase
public function test_state_set_has_workspace_dependency(): void
{
$tool = new StateSet();
$tool = new StateSet;
$dependencies = $tool->dependencies();
$this->assertNotEmpty($dependencies);
@ -396,7 +397,7 @@ class SecurityTest extends TestCase
public function test_state_get_has_workspace_dependency(): void
{
$tool = new StateGet();
$tool = new StateGet;
$dependencies = $tool->dependencies();
$this->assertNotEmpty($dependencies);
@ -405,7 +406,7 @@ class SecurityTest extends TestCase
public function test_state_list_has_workspace_dependency(): void
{
$tool = new StateList();
$tool = new StateList;
$dependencies = $tool->dependencies();
$this->assertNotEmpty($dependencies);
@ -414,7 +415,7 @@ class SecurityTest extends TestCase
public function test_plan_get_has_workspace_dependency(): void
{
$tool = new PlanGet();
$tool = new PlanGet;
$dependencies = $tool->dependencies();
$this->assertNotEmpty($dependencies);
@ -423,7 +424,7 @@ class SecurityTest extends TestCase
public function test_plan_list_has_workspace_dependency(): void
{
$tool = new PlanList();
$tool = new PlanList;
$dependencies = $tool->dependencies();
$this->assertNotEmpty($dependencies);

View file

@ -27,7 +27,7 @@ describe('provider registration', function () {
Config::set('services.google.ai_api_key', 'test-gemini-key');
Config::set('services.openai.api_key', 'test-openai-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->claude())->toBeInstanceOf(ClaudeService::class)
->and($manager->gemini())->toBeInstanceOf(GeminiService::class)
@ -38,7 +38,7 @@ describe('provider registration', function () {
Config::set('services.anthropic.api_key', 'test-key');
Config::set('services.anthropic.model', 'claude-opus-4-20250514');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->claude()->defaultModel())->toBe('claude-opus-4-20250514');
});
@ -47,7 +47,7 @@ describe('provider registration', function () {
Config::set('services.google.ai_api_key', 'test-key');
Config::set('services.google.ai_model', 'gemini-1.5-pro');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->gemini()->defaultModel())->toBe('gemini-1.5-pro');
});
@ -56,7 +56,7 @@ describe('provider registration', function () {
Config::set('services.openai.api_key', 'test-key');
Config::set('services.openai.model', 'gpt-4o');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->openai()->defaultModel())->toBe('gpt-4o');
});
@ -65,7 +65,7 @@ describe('provider registration', function () {
Config::set('services.anthropic.api_key', 'test-key');
Config::set('services.anthropic.model', null);
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->claude()->defaultModel())->toBe('claude-sonnet-4-20250514');
});
@ -74,7 +74,7 @@ describe('provider registration', function () {
Config::set('services.google.ai_api_key', 'test-key');
Config::set('services.google.ai_model', null);
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->gemini()->defaultModel())->toBe('gemini-2.0-flash');
});
@ -83,7 +83,7 @@ describe('provider registration', function () {
Config::set('services.openai.api_key', 'test-key');
Config::set('services.openai.model', null);
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->openai()->defaultModel())->toBe('gpt-4o-mini');
});
@ -101,7 +101,7 @@ describe('provider retrieval', function () {
});
it('retrieves provider by name using provider() method', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->provider('claude'))->toBeInstanceOf(ClaudeService::class)
->and($manager->provider('gemini'))->toBeInstanceOf(GeminiService::class)
@ -109,27 +109,27 @@ describe('provider retrieval', function () {
});
it('returns default provider when null passed to provider()', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
// Default is 'claude'
expect($manager->provider(null))->toBeInstanceOf(ClaudeService::class);
});
it('returns default provider when no argument passed to provider()', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->provider())->toBeInstanceOf(ClaudeService::class);
});
it('throws exception for unknown provider name', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect(fn () => $manager->provider('unknown'))
->toThrow(InvalidArgumentException::class, 'Unknown AI provider: unknown');
});
it('returns provider implementing AgenticProviderInterface', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->provider('claude'))->toBeInstanceOf(AgenticProviderInterface::class);
});
@ -147,13 +147,13 @@ describe('default provider', function () {
});
it('uses claude as default provider initially', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->provider()->name())->toBe('claude');
});
it('allows changing default provider to gemini', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
$manager->setDefault('gemini');
@ -161,7 +161,7 @@ describe('default provider', function () {
});
it('allows changing default provider to openai', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
$manager->setDefault('openai');
@ -169,14 +169,14 @@ describe('default provider', function () {
});
it('throws exception when setting unknown default provider', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect(fn () => $manager->setDefault('unknown'))
->toThrow(InvalidArgumentException::class, 'Unknown AI provider: unknown');
});
it('allows switching default provider multiple times', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
$manager->setDefault('gemini');
expect($manager->provider()->name())->toBe('gemini');
@ -197,7 +197,7 @@ describe('provider availability', function () {
it('reports provider as available when API key is set', function () {
Config::set('services.anthropic.api_key', 'test-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->isAvailable('claude'))->toBeTrue();
});
@ -207,7 +207,7 @@ describe('provider availability', function () {
Config::set('services.google.ai_api_key', '');
Config::set('services.openai.api_key', '');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->isAvailable('claude'))->toBeFalse()
->and($manager->isAvailable('gemini'))->toBeFalse()
@ -217,13 +217,13 @@ describe('provider availability', function () {
it('reports provider as unavailable when API key is null', function () {
Config::set('services.anthropic.api_key', null);
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->isAvailable('claude'))->toBeFalse();
});
it('returns false for unknown provider name', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->isAvailable('unknown'))->toBeFalse();
});
@ -233,7 +233,7 @@ describe('provider availability', function () {
Config::set('services.google.ai_api_key', '');
Config::set('services.openai.api_key', 'test-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->isAvailable('claude'))->toBeTrue()
->and($manager->isAvailable('gemini'))->toBeFalse()
@ -251,7 +251,7 @@ describe('available providers list', function () {
Config::set('services.google.ai_api_key', 'test-gemini-key');
Config::set('services.openai.api_key', 'test-openai-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
$available = $manager->availableProviders();
expect($available)->toHaveCount(3)
@ -263,7 +263,7 @@ describe('available providers list', function () {
Config::set('services.google.ai_api_key', '');
Config::set('services.openai.api_key', '');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->availableProviders())->toBeEmpty();
});
@ -273,7 +273,7 @@ describe('available providers list', function () {
Config::set('services.google.ai_api_key', '');
Config::set('services.openai.api_key', 'test-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
$available = $manager->availableProviders();
expect($available)->toHaveCount(2)
@ -283,7 +283,7 @@ describe('available providers list', function () {
it('returns providers implementing AgenticProviderInterface', function () {
Config::set('services.anthropic.api_key', 'test-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
$available = $manager->availableProviders();
foreach ($available as $provider) {
@ -304,7 +304,7 @@ describe('direct provider access methods', function () {
});
it('returns ClaudeService from claude() method', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->claude())
->toBeInstanceOf(ClaudeService::class)
@ -312,7 +312,7 @@ describe('direct provider access methods', function () {
});
it('returns GeminiService from gemini() method', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->gemini())
->toBeInstanceOf(GeminiService::class)
@ -320,7 +320,7 @@ describe('direct provider access methods', function () {
});
it('returns OpenAIService from openai() method', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->openai())
->toBeInstanceOf(OpenAIService::class)
@ -328,7 +328,7 @@ describe('direct provider access methods', function () {
});
it('returns same instance on repeated calls', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
$claude1 = $manager->claude();
$claude2 = $manager->claude();
@ -350,7 +350,7 @@ describe('edge cases', function () {
Config::set('services.openai.api_key', null);
Config::set('services.openai.model', null);
$manager = new AgenticManager();
$manager = new AgenticManager;
// Should still construct without throwing
expect($manager->claude())->toBeInstanceOf(ClaudeService::class)
@ -364,7 +364,7 @@ describe('edge cases', function () {
it('provider retrieval is case-sensitive', function () {
Config::set('services.anthropic.api_key', 'test-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect(fn () => $manager->provider('Claude'))
->toThrow(InvalidArgumentException::class);
@ -373,7 +373,7 @@ describe('edge cases', function () {
it('isAvailable handles case sensitivity', function () {
Config::set('services.anthropic.api_key', 'test-key');
$manager = new AgenticManager();
$manager = new AgenticManager;
expect($manager->isAvailable('claude'))->toBeTrue()
->and($manager->isAvailable('Claude'))->toBeFalse()
@ -381,7 +381,7 @@ describe('edge cases', function () {
});
it('setDefault handles case sensitivity', function () {
$manager = new AgenticManager();
$manager = new AgenticManager;
expect(fn () => $manager->setDefault('Gemini'))
->toThrow(InvalidArgumentException::class);

View file

@ -10,7 +10,6 @@
*/
use Core\Mod\Agentic\Models\AgentPlan;
use Core\Mod\Agentic\Models\AgentSession;
use Core\Tenant\Models\User;
use Core\Tenant\Models\Workspace;
@ -34,17 +33,17 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to Agentic dashboard
$page->navigate('/hub/agents')
->assertSee(__('agentic::agentic.dashboard.title'))
->assertSee(__('agentic::agentic.dashboard.subtitle'))
->assertSee(__('agentic::agentic.actions.refresh'))
->assertSee(__('agentic::agentic.dashboard.recent_activity'))
->assertSee(__('agentic::agentic.dashboard.top_tools'));
->assertSee(__('agentic::agentic.dashboard.title'))
->assertSee(__('agentic::agentic.dashboard.subtitle'))
->assertSee(__('agentic::agentic.actions.refresh'))
->assertSee(__('agentic::agentic.dashboard.recent_activity'))
->assertSee(__('agentic::agentic.dashboard.top_tools'));
});
it('can view plans list with filters', function () {
@ -59,24 +58,24 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to plans
$page->navigate('/hub/agents/plans')
->assertSee(__('agentic::agentic.plans.title'))
->assertSee(__('agentic::agentic.plans.subtitle'))
->assertSee(__('agentic::agentic.plans.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_statuses'))
->assertSee(__('agentic::agentic.filters.all_workspaces'))
->assertSee(__('agentic::agentic.table.plan'))
->assertSee(__('agentic::agentic.table.workspace'))
->assertSee(__('agentic::agentic.table.status'))
->assertSee(__('agentic::agentic.table.progress'))
->assertSee(__('agentic::agentic.table.sessions'))
->assertSee(__('agentic::agentic.table.last_activity'))
->assertSee(__('agentic::agentic.table.actions'));
->assertSee(__('agentic::agentic.plans.title'))
->assertSee(__('agentic::agentic.plans.subtitle'))
->assertSee(__('agentic::agentic.plans.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_statuses'))
->assertSee(__('agentic::agentic.filters.all_workspaces'))
->assertSee(__('agentic::agentic.table.plan'))
->assertSee(__('agentic::agentic.table.workspace'))
->assertSee(__('agentic::agentic.table.status'))
->assertSee(__('agentic::agentic.table.progress'))
->assertSee(__('agentic::agentic.table.sessions'))
->assertSee(__('agentic::agentic.table.last_activity'))
->assertSee(__('agentic::agentic.table.actions'));
});
it('can view sessions list with filters', function () {
@ -84,23 +83,23 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to sessions
$page->navigate('/hub/agents/sessions')
->assertSee(__('agentic::agentic.sessions.title'))
->assertSee(__('agentic::agentic.sessions.subtitle'))
->assertSee(__('agentic::agentic.sessions.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_statuses'))
->assertSee(__('agentic::agentic.filters.all_agents'))
->assertSee(__('agentic::agentic.filters.all_workspaces'))
->assertSee(__('agentic::agentic.filters.all_plans'))
->assertSee(__('agentic::agentic.table.session'))
->assertSee(__('agentic::agentic.table.agent'))
->assertSee(__('agentic::agentic.table.duration'))
->assertSee(__('agentic::agentic.table.activity'));
->assertSee(__('agentic::agentic.sessions.title'))
->assertSee(__('agentic::agentic.sessions.subtitle'))
->assertSee(__('agentic::agentic.sessions.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_statuses'))
->assertSee(__('agentic::agentic.filters.all_agents'))
->assertSee(__('agentic::agentic.filters.all_workspaces'))
->assertSee(__('agentic::agentic.filters.all_plans'))
->assertSee(__('agentic::agentic.table.session'))
->assertSee(__('agentic::agentic.table.agent'))
->assertSee(__('agentic::agentic.table.duration'))
->assertSee(__('agentic::agentic.table.activity'));
});
it('can view templates page', function () {
@ -108,22 +107,22 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to templates
$page->navigate('/hub/agents/templates')
->assertSee(__('agentic::agentic.templates.title'))
->assertSee(__('agentic::agentic.templates.subtitle'))
->assertSee(__('agentic::agentic.actions.import'))
->assertSee(__('agentic::agentic.actions.back_to_plans'))
->assertSee(__('agentic::agentic.templates.stats.templates'))
->assertSee(__('agentic::agentic.templates.stats.categories'))
->assertSee(__('agentic::agentic.templates.stats.total_phases'))
->assertSee(__('agentic::agentic.templates.stats.with_variables'))
->assertSee(__('agentic::agentic.templates.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_categories'));
->assertSee(__('agentic::agentic.templates.title'))
->assertSee(__('agentic::agentic.templates.subtitle'))
->assertSee(__('agentic::agentic.actions.import'))
->assertSee(__('agentic::agentic.actions.back_to_plans'))
->assertSee(__('agentic::agentic.templates.stats.templates'))
->assertSee(__('agentic::agentic.templates.stats.categories'))
->assertSee(__('agentic::agentic.templates.stats.total_phases'))
->assertSee(__('agentic::agentic.templates.stats.with_variables'))
->assertSee(__('agentic::agentic.templates.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_categories'));
});
it('can view API keys page', function () {
@ -131,25 +130,25 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to API keys
$page->navigate('/hub/agents/api-keys')
->assertSee(__('agentic::agentic.api_keys.title'))
->assertSee(__('agentic::agentic.api_keys.subtitle'))
->assertSee(__('agentic::agentic.actions.create_key'))
->assertSee(__('agentic::agentic.api_keys.stats.total_keys'))
->assertSee(__('agentic::agentic.api_keys.stats.active'))
->assertSee(__('agentic::agentic.api_keys.stats.revoked'))
->assertSee(__('agentic::agentic.api_keys.stats.total_calls'))
->assertSee(__('agentic::agentic.table.name'))
->assertSee(__('agentic::agentic.table.permissions'))
->assertSee(__('agentic::agentic.table.rate_limit'))
->assertSee(__('agentic::agentic.table.usage'))
->assertSee(__('agentic::agentic.table.last_used'))
->assertSee(__('agentic::agentic.table.created'));
->assertSee(__('agentic::agentic.api_keys.title'))
->assertSee(__('agentic::agentic.api_keys.subtitle'))
->assertSee(__('agentic::agentic.actions.create_key'))
->assertSee(__('agentic::agentic.api_keys.stats.total_keys'))
->assertSee(__('agentic::agentic.api_keys.stats.active'))
->assertSee(__('agentic::agentic.api_keys.stats.revoked'))
->assertSee(__('agentic::agentic.api_keys.stats.total_calls'))
->assertSee(__('agentic::agentic.table.name'))
->assertSee(__('agentic::agentic.table.permissions'))
->assertSee(__('agentic::agentic.table.rate_limit'))
->assertSee(__('agentic::agentic.table.usage'))
->assertSee(__('agentic::agentic.table.last_used'))
->assertSee(__('agentic::agentic.table.created'));
});
it('can view tool analytics page', function () {
@ -157,23 +156,23 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to tool analytics
$page->navigate('/hub/agents/tools')
->assertSee(__('agentic::agentic.tools.title'))
->assertSee(__('agentic::agentic.tools.subtitle'))
->assertSee(__('agentic::agentic.actions.view_all_calls'))
->assertSee(__('agentic::agentic.tools.stats.total_calls'))
->assertSee(__('agentic::agentic.tools.stats.successful'))
->assertSee(__('agentic::agentic.tools.stats.errors'))
->assertSee(__('agentic::agentic.tools.stats.success_rate'))
->assertSee(__('agentic::agentic.tools.stats.unique_tools'))
->assertSee(__('agentic::agentic.tools.daily_trend'))
->assertSee(__('agentic::agentic.tools.server_breakdown'))
->assertSee(__('agentic::agentic.tools.top_tools'));
->assertSee(__('agentic::agentic.tools.title'))
->assertSee(__('agentic::agentic.tools.subtitle'))
->assertSee(__('agentic::agentic.actions.view_all_calls'))
->assertSee(__('agentic::agentic.tools.stats.total_calls'))
->assertSee(__('agentic::agentic.tools.stats.successful'))
->assertSee(__('agentic::agentic.tools.stats.errors'))
->assertSee(__('agentic::agentic.tools.stats.success_rate'))
->assertSee(__('agentic::agentic.tools.stats.unique_tools'))
->assertSee(__('agentic::agentic.tools.daily_trend'))
->assertSee(__('agentic::agentic.tools.server_breakdown'))
->assertSee(__('agentic::agentic.tools.top_tools'));
});
it('can view tool calls page', function () {
@ -181,21 +180,21 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to tool calls
$page->navigate('/hub/agents/tools/calls')
->assertSee(__('agentic::agentic.tool_calls.title'))
->assertSee(__('agentic::agentic.tool_calls.subtitle'))
->assertSee(__('agentic::agentic.tool_calls.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_servers'))
->assertSee(__('agentic::agentic.filters.all_tools'))
->assertSee(__('agentic::agentic.filters.all_status'))
->assertSee(__('agentic::agentic.table.tool'))
->assertSee(__('agentic::agentic.table.server'))
->assertSee(__('agentic::agentic.table.time'));
->assertSee(__('agentic::agentic.tool_calls.title'))
->assertSee(__('agentic::agentic.tool_calls.subtitle'))
->assertSee(__('agentic::agentic.tool_calls.search_placeholder'))
->assertSee(__('agentic::agentic.filters.all_servers'))
->assertSee(__('agentic::agentic.filters.all_tools'))
->assertSee(__('agentic::agentic.filters.all_status'))
->assertSee(__('agentic::agentic.table.tool'))
->assertSee(__('agentic::agentic.table.server'))
->assertSee(__('agentic::agentic.table.time'));
});
it('shows empty state when no plans exist', function () {
@ -203,14 +202,14 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to plans (should be empty)
$page->navigate('/hub/agents/plans')
->assertSee(__('agentic::agentic.empty.no_plans'))
->assertSee(__('agentic::agentic.empty.plans_appear'));
->assertSee(__('agentic::agentic.empty.no_plans'))
->assertSee(__('agentic::agentic.empty.plans_appear'));
});
it('shows empty state when no sessions exist', function () {
@ -218,14 +217,14 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to sessions (should be empty)
$page->navigate('/hub/agents/sessions')
->assertSee(__('agentic::agentic.empty.no_sessions'))
->assertSee(__('agentic::agentic.empty.sessions_appear'));
->assertSee(__('agentic::agentic.empty.no_sessions'))
->assertSee(__('agentic::agentic.empty.sessions_appear'));
});
it('can clear filters', function () {
@ -233,20 +232,20 @@ describe('Agentic Admin Panel', function () {
$page = visit('/login');
$page->fill('email', 'test@example.com')
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
->fill('password', 'password')
->click(__('pages::pages.login.submit'))
->assertPathContains('/hub');
// Navigate to plans and use filter
$page->navigate('/hub/agents/plans')
->assertSee(__('agentic::agentic.plans.title'));
->assertSee(__('agentic::agentic.plans.title'));
// Type in search to trigger filter
$page->type('input[placeholder="' . __('agentic::agentic.plans.search_placeholder') . '"]', 'test')
->wait(1)
->assertSee(__('agentic::agentic.actions.clear'));
$page->type('input[placeholder="'.__('agentic::agentic.plans.search_placeholder').'"]', 'test')
->wait(1)
->assertSee(__('agentic::agentic.actions.clear'));
$page->click(__('agentic::agentic.actions.clear'))
->wait(1);
->wait(1);
});
});