Appearance
<div style="display: none;" hidden="true" aria-hidden="true">Are you an LLM? You can read better optimized documentation at /guides/claude/repo-flexibility.md for this page in Markdown format</div>
Main vs Client Repo Flexibility
See also: System Overview | Agent Catalog | Usage Guide | Developer Overrides
TL;DR
All agents work in both repo types. The SessionStart hook auto-detects which repo you're in and sets context flags (REPO_TYPE, CUSTOM_DIR, CUSTOM_PSR4). Agents read these flags and adjust file paths, namespaces, and bootstrap behavior automatically. Client repos use application/ for legacy code and custom/ (PSR-4 Custom\ namespace) for modern code. Fresh client forks without custom/ are handled gracefully — agents scaffold it only when actually needed.
Detection Mechanism
The .claude/hooks/detect-repo.sh script runs at session start and outputs context flags:
| Flag | Values | Meaning |
|---|---|---|
REPO_TYPE | main or client | Detected from git remote URL (checks for devteamadvisable/adveshop4) |
CUSTOM_DIR | exists or missing | Whether custom/ directory exists (client repos only) |
CUSTOM_PSR4 | configured or missing | Whether "Custom\\" PSR-4 mapping exists in composer.json (client repos only) |
File Placement Summary
Where code goes in each repo type
| Code type | Main repo | Client repo |
|---|---|---|
| Domain entities/repos/services | src/Domains/ (Advisable\) | custom/Domains/ (Custom\) |
| REST controllers/resources | src/Rest/ (Advisable\) | custom/Rest/ (Custom\) |
| DI container configs | Per-module container.php in src/ | Shared container.php in custom/Domains/ and custom/Rest/ |
| Legacy controllers | — | application/controllers/ |
| Legacy models | ecommercen/{module}/models/ | application/models/ |
| Legacy libraries | ecommercen/{module}/libraries/ | application/libraries/ |
| HMVC modules | ecommercen/{module}/ | application/modules/{module}/ |
| Jobs | ecommercen/job/libraries/ | application/libraries/ or custom/{Module}/Jobs/ |
| Feeds | src/Feeds/Output/ | application/libraries/feeds/ or custom/Feeds/Output/ |
| Migrations | database/migrations/ | database/migrations/ (same) |
| Patchers | patches/ | patches/ (same) |
| Tests | tests/Unit/ | tests/Unit/ (same) |
What's off-limits in client repos
These directories are upstream and must never be modified in a client repo:
ecommercen/— core HMVC modules (updated via upstream merges)src/— modern domain/REST layer (updated via upstream merges)
The custom/ Layer
Client repos extend the platform via a custom/ directory with PSR-4 autoloading:
composer.json: "Custom\\": "custom/"Structure
custom/
├── Domains/ ← Mirrors src/Domains/ structure
│ ├── {Context}/{Entity}/ ← Custom entities, repos, services
│ │ ├── Repository/
│ │ │ ├── Entity.php
│ │ │ ├── Repository.php
│ │ │ └── RepositoryConfigurator.php
│ │ ├── Service.php
│ │ └── ListRequest.php
│ └── container.php ← Shared DI config for ALL custom domains
├── Rest/ ← Mirrors src/Rest/ structure
│ ├── {Context}/
│ │ ├── Controllers/
│ │ └── Resources/
│ └── container.php ← Shared DI config for ALL custom REST
├── {StandaloneModule}/ ← Client-specific integrations (e.g., Certus, Wallbid)
│ ├── Jobs/ ← Module-specific jobs
│ ├── Controllers/
│ └── container.php ← Module's own DI config
└── Feeds/
└── Output/ ← Custom feed outputsTwo use cases for custom/
New entities — Entirely new domain objects that don't exist upstream. Use
Custom\namespace throughout.Override upstream — Replace or extend an upstream
Advisable\service. Create theCustom\class and register a DI alias:php$services->set(\Custom\Domains\Map\Location\Repository\RepositoryConfigurator::class); $services->alias( \Advisable\Domains\Map\Location\Repository\RepositoryConfigurator::class, \Custom\Domains\Map\Location\Repository\RepositoryConfigurator::class );
Container registration
All custom modules are registered in application/config/container/modules.php:
php
new ContainerModule('app', APPPATH . '../custom/Domains', 'container.php'),
new ContainerModule('app', APPPATH . '../custom/Rest', 'container.php'),
new ContainerModule('app', APPPATH . '../custom/Certus', 'container.php'),Fresh Client Forks (No custom/ Layer)
A fresh fork of the main repo will NOT have:
- A
custom/directory - A
Custom\PSR-4 mapping incomposer.json
How agents handle this
The system does NOT eagerly scaffold custom/. Instead, each agent has its own decision logic:
| Situation | Agent behavior |
|---|---|
| Developer asks for a simple job | Creates in application/libraries/ — no custom/ needed |
| Developer asks for a new feed | Creates in application/libraries/feeds/ — no custom/ needed |
| Developer asks for legacy controller work | Works in application/ — no custom/ needed |
| Developer asks to generate a new domain entity | domain-generator detects missing custom layer, scaffolds it (creates dirs, PSR-4 mapping, composer dump-autoload, container files, module registration), then generates |
| Developer asks for a job tied to a custom domain that doesn't exist | job-writer stops and reports back that the domain needs to be created first |
| Developer asks to override an upstream feed | feed-writer scaffolds custom/ only then, creates feed there |
The principle: custom/ is created on demand, not preemptively. Legacy application/ paths are always available and preferred for simple tasks.
Agent Availability Matrix
| Agent | Main | Client | Notes |
|---|---|---|---|
domain-generator | Yes | Yes | Client uses custom/, bootstraps if needed |
rest-crud-writer | Yes | Yes | Client uses custom/, references domain-generator bootstrap |
code-reviewer | Yes | Yes | Read-only, no file placement differences |
migration-writer | Yes | Yes | Same path in both (database/migrations/) |
test-writer | Yes | Yes | Same path in both (tests/Unit/) |
container-writer | Yes | Yes | Main: per-module, Client: shared in custom/ |
job-writer | Yes | Yes | Client: application/ default, custom/ only when needed |
patcher-writer | Yes | Yes | Same paths in both |
feed-writer | Yes | Yes | Client: application/ default, custom/ only when needed |
schema-analyzer | Yes | Yes | Read-only, no differences |
legacy-developer | Yes | Yes | Main: ecommercen/, Client: application/ |
docs-updater | Yes | Yes | Main: docs/, Client: docs/client/ |
Client Repo Override Support
Clients can customize the agent system itself:
- Override an agent — Create
.claude/agents/{name}.mdin the client repo. The client's version takes precedence over inherited agents. - Add client-specific agents — Create new
.claude/agents/*.mdfiles for client-only workflows. - Disable agents — Add to
.claude/settings.local.json:json{ "permissions": { "deny": ["Agent(domain-generator)"] } } - Add personal rules — Create
~/.claude/rules/*.mdfor per-developer conventions. - Personal CLAUDE.md — Create
~/.claude/CLAUDE.mdfor user-level instructions (loaded alongside the project CLAUDE.md). - Personal MCP servers — Add per-project servers in
~/.claude.json.
For the full override hierarchy and recipes, see Developer Overrides.