From 95c104f7b3d9f94a05dc8166fb32fe75c0111d85 Mon Sep 17 00:00:00 2001 From: Snider Date: Fri, 27 Mar 2026 06:50:54 +0000 Subject: [PATCH] feat(workspace): add PHP CODEX.md template + language-aware prep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- pkg/agentic/prep.go | 10 ++ pkg/lib/lib.go | 14 ++ pkg/lib/workspace/default/CODEX-PHP.md.tmpl | 159 ++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 pkg/lib/workspace/default/CODEX-PHP.md.tmpl diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index 5accce9..db91f5a 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -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. diff --git a/pkg/lib/lib.go b/pkg/lib/lib.go index 7d2aa73..382493b 100644 --- a/pkg/lib/lib.go +++ b/pkg/lib/lib.go @@ -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. diff --git a/pkg/lib/workspace/default/CODEX-PHP.md.tmpl b/pkg/lib/workspace/default/CODEX-PHP.md.tmpl new file mode 100644 index 0000000..a06b8e0 --- /dev/null +++ b/pkg/lib/workspace/default/CODEX-PHP.md.tmpl @@ -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 +