feat(workspace): add PHP CODEX.md template + language-aware prep
Workspace prep now detects repo language and copies the right CODEX.md: - Go repos get CODEX.md.tmpl (existing — Core primitives, banned imports) - PHP repos get CODEX-PHP.md.tmpl (CorePHP patterns, lifecycle events, Actions, BelongsToWorkspace, Flux Pro, FA Pro, UK English) Added lib.WorkspaceFile() helper for reading individual template files. Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
f7397324b1
commit
95c104f7b3
3 changed files with 183 additions and 0 deletions
|
|
@ -466,6 +466,16 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques
|
|||
out.Branch = s.gitOutput(ctx, repoDir, "rev-parse", "--abbrev-ref", "HEAD")
|
||||
}
|
||||
|
||||
// Overwrite CODEX.md with language-specific version if needed.
|
||||
// The default template is Go-focused. PHP repos get CODEX-PHP.md instead.
|
||||
lang := detectLanguage(repoPath)
|
||||
if lang == "php" {
|
||||
if r := lib.WorkspaceFile("default", "CODEX-PHP.md.tmpl"); r.OK {
|
||||
codexPath := core.JoinPath(wsDir, "CODEX.md")
|
||||
fs.Write(codexPath, r.Value.(string))
|
||||
}
|
||||
}
|
||||
|
||||
// Clone workspace dependencies — Core modules needed to build the repo.
|
||||
// Reads go.mod, finds dappco.re/go/core/* imports, clones from Forge,
|
||||
// and updates go.work so the agent can build inside the workspace.
|
||||
|
|
|
|||
|
|
@ -238,6 +238,20 @@ func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// WorkspaceFile reads a single file from a workspace template.
|
||||
// Returns the file content as a string.
|
||||
//
|
||||
// r := lib.WorkspaceFile("default", "CODEX-PHP.md.tmpl")
|
||||
// if r.OK { content := r.Value.(string) }
|
||||
func WorkspaceFile(tmplName, filename string) core.Result {
|
||||
r := workspaceFS.Sub(tmplName)
|
||||
if !r.OK {
|
||||
return r
|
||||
}
|
||||
embed := r.Value.(*core.Embed)
|
||||
return embed.ReadString(filename)
|
||||
}
|
||||
|
||||
// --- List Functions ---
|
||||
|
||||
// ListPrompts returns available system prompt slugs.
|
||||
|
|
|
|||
159
pkg/lib/workspace/default/CODEX-PHP.md.tmpl
Normal file
159
pkg/lib/workspace/default/CODEX-PHP.md.tmpl
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
# CODEX.md — PHP / CorePHP
|
||||
|
||||
Instructions for Codex when working with PHP code in this workspace.
|
||||
|
||||
## CorePHP Framework
|
||||
|
||||
This project uses CorePHP (`core/php`) as its foundation. CorePHP is a Laravel package that provides:
|
||||
- Event-driven module loading (modules only load when their events fire)
|
||||
- Multi-tenant isolation via `BelongsToWorkspace` trait
|
||||
- Actions pattern for single-purpose business logic
|
||||
- Lifecycle events for route/panel/command registration
|
||||
|
||||
## Architecture
|
||||
|
||||
### Module Pattern
|
||||
|
||||
```php
|
||||
// app/Mod/{Name}/Boot.php
|
||||
class Boot extends ServiceProvider
|
||||
{
|
||||
public static array $listens = [
|
||||
WebRoutesRegistering::class => 'onWebRoutes',
|
||||
AdminPanelBooting::class => 'onAdmin',
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Website Pattern
|
||||
|
||||
```php
|
||||
// app/Website/{Name}/Boot.php
|
||||
class Boot extends ServiceProvider
|
||||
{
|
||||
public static array $domains = [
|
||||
'/^api\.lthn\.(ai|test|sh)$/',
|
||||
];
|
||||
|
||||
public static array $listens = [
|
||||
DomainResolving::class => 'onDomain',
|
||||
WebRoutesRegistering::class => 'onWebRoutes',
|
||||
ApiRoutesRegistering::class => 'onApiRoutes',
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Lifecycle Events
|
||||
|
||||
| Event | Purpose |
|
||||
|-------|---------|
|
||||
| `DomainResolving` | Match domain → register website module |
|
||||
| `WebRoutesRegistering` | Public web routes (sessions, CSRF, Vite) |
|
||||
| `ApiRoutesRegistering` | Stateless API routes |
|
||||
| `AdminPanelBooting` | Admin panel resources |
|
||||
| `ClientRoutesRegistering` | Authenticated SaaS client routes |
|
||||
| `ConsoleBooting` | Artisan commands |
|
||||
| `McpToolsRegistering` | MCP tool handlers |
|
||||
|
||||
### Actions Pattern
|
||||
|
||||
```php
|
||||
use Core\Actions\Action;
|
||||
|
||||
class CreateOrder
|
||||
{
|
||||
use Action;
|
||||
|
||||
public function handle(User $user, array $data): Order
|
||||
{
|
||||
return Order::create($data);
|
||||
}
|
||||
}
|
||||
// Usage: CreateOrder::run($user, $validated);
|
||||
```
|
||||
|
||||
### Multi-Tenant Isolation
|
||||
|
||||
```php
|
||||
use Core\Mod\Tenant\Concerns\BelongsToWorkspace;
|
||||
|
||||
class Memory extends Model
|
||||
{
|
||||
use BelongsToWorkspace;
|
||||
// Auto-scopes queries to current workspace
|
||||
// Auto-assigns workspace_id on create
|
||||
}
|
||||
```
|
||||
|
||||
## Mandatory Patterns
|
||||
|
||||
### Strict Types — every PHP file
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
```
|
||||
|
||||
### Type Hints — all parameters and return types
|
||||
|
||||
```php
|
||||
// WRONG
|
||||
function process($data) { }
|
||||
|
||||
// CORRECT
|
||||
function process(array $data): JsonResponse { }
|
||||
```
|
||||
|
||||
### UK English in all comments and strings
|
||||
|
||||
```
|
||||
colour not color
|
||||
organisation not organization
|
||||
initialise not initialize
|
||||
serialise not serialize
|
||||
centre not center
|
||||
```
|
||||
|
||||
### Testing — PHPUnit with Orchestra Testbench
|
||||
|
||||
```php
|
||||
class BrainServiceTest extends TestCase
|
||||
{
|
||||
public function test_remember_stores_memory(): void { }
|
||||
public function test_remember_validates_input(): void { }
|
||||
public function test_recall_returns_ranked_results(): void { }
|
||||
public function test_recall_filters_by_org(): void { }
|
||||
}
|
||||
```
|
||||
|
||||
### Formatting — Laravel Pint (PSR-12)
|
||||
|
||||
```bash
|
||||
./vendor/bin/pint --dirty # Format changed files only
|
||||
```
|
||||
|
||||
## UI
|
||||
|
||||
- **Flux Pro** — component library (NOT vanilla Livewire/Alpine)
|
||||
- **Font Awesome Pro** — icons (NOT Heroicons)
|
||||
- **Livewire 3** — server-driven components
|
||||
- **Alpine.js** — client-side interactivity
|
||||
|
||||
## What NOT to do
|
||||
|
||||
- Don't use American English spellings
|
||||
- Don't use Heroicons (use Font Awesome Pro)
|
||||
- Don't use vanilla Blade components where Flux Pro has an equivalent
|
||||
- Don't create loose route files — routes belong in Boot.php via lifecycle events
|
||||
- Don't bypass BelongsToWorkspace — all tenant data must be scoped
|
||||
- Don't use raw DB queries where Eloquent works
|
||||
|
||||
## Build & Test
|
||||
|
||||
```bash
|
||||
composer install
|
||||
composer test
|
||||
./vendor/bin/pint --dirty
|
||||
php artisan test --filter=SpecificTest
|
||||
```
|
||||
Loading…
Add table
Reference in a new issue