Log a warning for each AI provider registered without an API key so
that misconfiguration is surfaced at boot time (not silently on the
first API call). Each message names the environment variable to set:
ANTHROPIC_API_KEY – Claude
GOOGLE_AI_API_KEY – Gemini
OPENAI_API_KEY – OpenAI
Providers without a key remain registered but are marked unavailable
via isAvailable(), preserving backward compatibility.
- Add Log::warning() calls in registerProviders() for empty keys
- Extend AgenticManagerTest with a dedicated 'API key validation
warnings' describe block (7 new test cases)
- Update DX-002 in TODO.md as resolved
Closes#29
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace individual __get expectations with a single closure that handles
all property access. Fixes ErrorException on undefined property access
with Mockery mocks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded cache key in ForAgentsController with a config-based
key (`mcp.cache.for_agents_key`) and configurable TTL
(`mcp.cache.for_agents_ttl`). This prevents collisions with other modules
or packages that might use the same flat cache key.
- Add `cacheKey()` method on ForAgentsController, reads from config
- Add `cache` section to config.php with default key and TTL
- Dynamic Cache-Control max-age now follows the configured TTL
- Add ForAgentsControllerTest covering key customisation,
cache storage, invalidation, TTL, and response structure
Refs: TODO.md CQ-003
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch View/Modal/Admin/ApiKeyManager.php from Core\Api\Models\ApiKey
to Core\Mod\Agentic\Models\AgentApiKey and AgentApiKeyService, bringing
the workspace-owner admin UI into consistency with all other services.
Changes:
- Replace Core\Api\Models\ApiKey import with AgentApiKey + AgentApiKeyService
- Use AgentApiKeyService::create() for key generation
- Use AgentApiKey::forWorkspace() scoping in revokeKey() and render()
- Rename newKeyScopes → newKeyPermissions, toggleScope → togglePermission
- Expose availablePermissions() from AgentApiKey for the create form
- Update blade template: permissions field, getMaskedKey(), togglePermission,
dynamic permission checkboxes from AgentApiKey::availablePermissions()
- Add tests/Feature/ApiKeyManagerTest.php with integration coverage
- Mark CQ-002 resolved in TODO.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The processOutput() method was a stub with no implementation. The
ContentProcessingService dependency it accepted is from the external
host-uk/core package and its API is not available here. Content
is already persisted via markCompleted() so no output processing
was ever performed.
Removes:
- processOutput() stub method
- ContentProcessingService import and handle() parameter
- target_type/target_id guard block that called the stub
Adds unit tests covering: prompt validation, entitlement checks,
provider availability, task completion metadata, usage recording,
and template variable interpolation.
Closes#17
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Feature test covering PromptVersion creation, relationships (prompt,
creator), restore() rollback method, and version history tracking. Also
add idempotent migration for prompts and prompt_versions tables required
by the test suite.
Closes#15
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>
Convert PHPUnit class-based tests to Pest functional syntax with:
- 47 test cases organised into 9 describe blocks
- Proper beforeEach/afterEach hooks for test setup/teardown
- Covers: template listing, retrieval, preview, variable substitution,
plan creation, validation, categories, context generation, edge cases
- Uses expect() assertions and method chaining for clarity
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rewrote all test methods to use Pest's test() function with expect()
assertions instead of PHPUnit class-based syntax:
- IP validation tests (IPv4 and IPv6)
- CIDR range matching for all prefix lengths (/0 to /32 for IPv4, /0 to /128 for IPv6)
- Whitelist management tests (parsing, formatting, comments)
- Entry validation and error handling
- Edge cases (loopback, private ranges, link-local, mixed protocols)
Test count increased from 60+ to 78 with additional edge case coverage.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Convert AgentApiKeyTest from PHPUnit class-based syntax to Pest functional syntax
- Add tests/Pest.php configuration with helper functions (createWorkspace, createApiKey)
- Organise tests using describe() blocks for better structure
- Add additional test coverage for key rotation and security edge cases
- Update TODO.md to reflect Pest syntax usage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
P2 Items Completed (P2-062 to P2-068):
- Switch AgentApiKey from SHA-256 to Argon2id hashing
- Add 200+ tests for models, services, and AI providers
- Create agent_plans migration with phases and workspace states
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Core\Mod\Tenant -> Core\Tenant
- Core\Service\Agentic -> Core\Mod\Agentic\Service
Part of namespace restructure to align with L1/L2 module conventions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates all classes to use the new modular namespace convention.
Adds Service/ layer with Core\Service\Agentic for service definition.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>