# Linguise Script-PHP — AI Agent Guide

## Quick Overview

Script-PHP is the **PHP translation proxy script** for the Linguise translation system. It acts as the client-side interface between a website and two Linguise backend services:

- **API Server** (`api.linguise.com`) — domain configuration, subscription status, token validation
- **Core / Translation Server** (`translate.linguise.com`) — receives page HTML, returns translated HTML

**Important**: This is NOT the translation engine. Script-PHP manages the *proxy, caching, management UI, and configuration layer* that delivers translated pages to visitors.

**Important**: The `src/` classes are also vendored by the **WordPress and Joomla plugins**. `Processor`, `CurlRequest`, and `Translation` are shared public APIs — changes to their public method signatures require Plan Mode and plugin coordination.

## How It Works

### Request Pipeline

```
Browser → /?linguise_language=fr-fr
    │
    ▼
linguise.php  (public entry point)
    ├── Bootstrap: autoload, Configuration, CmsDetect, ui-config.php
    │
    ├─ [management: ?linguise_language=zz-zz]
    │       ├── OOBE not done → OobeManager::oobeRun()  (setup wizard)
    │       └── OOBE done     → OobeManager::run()      (admin panel)
    │
    └─ [translation: ?linguise_language=XX-XX]
            └── Processor::run()
                    ├── CurlRequest::makeRequest()    ← proxy to origin server
                    ├── Cache::serve()                ← short-circuit on cache hit
                    ├── Translation::translate()      ← POST to translate.linguise.com
                    ├── Defer → Cache::save()         ← write cache after response sent
                    └── Response::end()               ← flush headers + body to client
```

### WP / Joomla Plugin Entry Point

The WordPress and Joomla plugins bootstrap `Configuration` themselves and call `Processor::run()` directly, bypassing `linguise.php`.

### Key Features

| Feature | Entry Point |
|---------|-------------|
| Translation proxy | `Processor::run()` → `CurlRequest` → `Translation` |
| File-based cache | `Cache::serve()` / `Cache::save()` |
| Management dashboard | `OobeManager::run()` + `Management::*` |
| First-run OOBE wizard | `OobeManager::oobeRun()` |
| CMS auto-detection | `CmsDetect::detect()` |
| CMS platform adapters | `src/Platforms/PrestaShop`, `OpenCart`, `Zencart` |
| Self-update | `Updater::update()` |
| JSON AJAX translation | `JsonWalker` (PrestaShop only) |
| Debug logging | `Debug::log()` |

## Key Commands

### PHP / Composer

```bash
./vendor/bin/phpunit                          # Run all tests
./vendor/bin/phpunit --testsuite root         # Core tests only
./vendor/bin/phpunit --testsuite platforms    # Platform adapter tests only
./vendor/bin/phpunit tests/SomeTest.php       # Single test file
composer install                              # Install dependencies
```

### Node / Webpack (Admin UI)

```bash
npm install          # Install frontend dependencies
npm run build        # Build admin + login bundles (production)
npm run dev          # Build in watch mode (development)
```

## Plan Mode Files

**⚠️ CRITICAL**: Before modifying these files, you MUST enter Plan Mode — document the proposed change and get user approval.

For the full list with explanations, see [`memory-bank/planModeFiles.md`](memory-bank/planModeFiles.md).

### Quick Reference — Plan Mode Required

| Category | Files | Reason |
|----------|-------|--------|
| **Plugin API** | `src/Processor.php` | Entry point called directly by WP + Joomla plugins |
| **Plugin API** | `src/CurlRequest.php` | Core origin proxy; shared public contract |
| **Plugin API** | `src/Translation.php` | Sends HTML to translation server; shared public API |
| **Core Config** | `src/Configuration.php`, `Configuration.php` | All classes depend on these; user installations depend on root config |
| **Setup Flow** | `src/OobeManager.php` | Writes `ui-config.php`; errors break first-run setup |
| **Admin Security** | `src/Management.php` | CSRF logic + admin POST actions |
| **Data Layer** | `src/Database.php`, `src/Databases/*.php` | DDL embedded in code — no migration system |
| **Self-Update** | `src/Updater.php` | Replaces files on disk; supply-chain risk |
| **SSL** | `src/Certificates.php` | CA cert bundle for all HTTPS calls |
| **Generated** | `ui-config.php` | Never edit manually — regenerated by OobeManager |

### When to Use Plan Mode

1. Modifying any file above
2. Changing any **public method signature** in `Processor`, `CurlRequest`, or `Translation`
3. Adding or removing database columns (requires coordinated manual DDL, no migration system)
4. Adding a new `on*` hook to `Configuration.php`

## Architecture

For a detailed breakdown, see [`memory-bank/architecture.md`](memory-bank/architecture.md).

### Component Overview

```
linguise.php           # Public entry point; bootstraps + dispatches
src/
├── Processor.php      # Translation orchestrator (WP/Joomla plugin entry point) ⚠
├── CurlRequest.php    # Proxy curl to origin server ⚠
├── Translation.php    # Sends HTML to translation server ⚠
├── Configuration.php  # Internal runtime config singleton ⚠
├── Request.php        # Inbound URL + language parser
├── Response.php       # Response accumulator + emitter
├── Cache.php          # File-based translation cache
├── Database.php       # DB facade (Mysql or Sqlite) ⚠
├── OobeManager.php    # First-run wizard + admin panel controller ⚠
├── Management.php     # Admin POST action handlers ⚠
├── Updater.php        # Self-update logic ⚠
├── Hook.php           # Lightweight event system
├── Helper.php         # Static utilities
├── Debug.php          # Conditional file logger
├── Defer.php          # Post-response deferred execution
├── JsonWalker.php     # JSON AJAX translation (PrestaShop)
├── Certificates.php   # CA cert bundle management ⚠
├── CmsDetect.php      # Filesystem-based CMS detection
├── Databases/         # Mysql.php, Sqlite.php ⚠
├── Platforms/         # PrestaShop.php, OpenCart.php, Zencart.php
└── templates/         # Admin UI templates (management, OOBE, login, editor)
```

## Memory Bank

The `memory-bank/` folder contains detailed documentation:

- **`projectBrief.md`** — Project overview, purpose, key responsibilities, commands
- **`architecture.md`** — Full pipeline breakdown, component descriptions, WP/Joomla plugin integration
- **`structure.md`** — Annotated file tree for all directories
- **`techStack.md`** — PHP version, Composer deps, Node/Webpack pipeline, external services
- **`environment.md`** — All `LINGUISE_*` constants, three-layer configuration system, `ui-config.php`
- **`testing.md`** — PHPUnit config, test structure, `CurlStub`/`NamespaceStub` patterns, best practices
- **`planModeFiles.md`** — Complete list of files requiring Plan Mode before modification
- **`cmsSupport.md`** — CMS detection, platform adapters (PrestaShop, OpenCart, Zencart), `JsonWalker`
- **`managementFlow.md`** — Management dashboard, OOBE wizard (with-token vs. without-token), CSRF
- **`progress.md`** — Task progress tracking (update when working on tasks)
- **`activeContext.md`** — Current working context (read before starting work)`

**Important for Agents**:
1. Always read `memory-bank/activeContext.md` and `memory-bank/progress.md` before starting work + any other relevant memory bank files
2. Always check `memory-bank/planModeFiles.md` before modifying any core file

## Common Tasks

### Adding a new API endpoint / admin action
1. Add the action to the `switch` block in `linguise.php`
2. Implement the handler in `Management.php` (requires Plan Mode)
3. Add CSRF verification (`Session::verifyCsrfToken()`)
4. Add/update a template partial in `src/templates/tpl/`
5. Write tests in `tests/ManagementTest.php`

### Adding a new CMS platform adapter
1. Create `src/Platforms/MyCms.php` in namespace `Linguise\Script\Core\Platforms`
2. Register hooks (`onBeforeTranslationRequest`, etc.) using `Hook::add()`
3. Load the adapter in `Processor::run()` when `Configuration::get('cms') === 'mycms'`
4. Add CMS detection logic to `CmsDetect.php` if needed
5. Create `tests/Platforms/MyCmsTest.php`
6. Update `memory-bank/cmsSupport.md`

### Debugging a translation failure
1. Enable debug logging: set `$debug = 5` in `Configuration.php`
2. Check `{data_dir}/debug.php` for log output
3. Verify the token in `Configuration.php` matches the domain in the Linguise dashboard
4. Check `CurlRequest` response: is the origin page being fetched correctly?
5. Check `Translation::translate()`: is the translation server reachable at `translate.linguise.com`?
6. Check `Certificates.php`: is `cacert.pem` present and up to date?

### Debugging the management interface
1. If the page shows nothing: check `ui-config.php` exists and `LINGUISE_OOBE_DONE = true`
2. If login fails: verify `LINGUISE_LOGIN_SECRET` in `ui-config.php` matches the session
3. If 403 on POST: CSRF token mismatch — clear browser cookies and reload
4. If OOBE is stuck: delete `ui-config.php` to restart the wizard (⚠ loses DB config)

### Running tests
```bash
./vendor/bin/phpunit                    # All tests
./vendor/bin/phpunit tests/SomeTest.php # Single file
```

### Rebuilding the admin UI
```bash
npm run build    # Production build
npm run dev      # Watch mode for development
```
## Agent Skills

The `.agents/skills/` directory contains reusable skill definitions that AI agents can invoke for scaffolding, documentation synchronization, and safety checks. Each skill is a standalone `SKILL.md` file following the [agentskills.io](https://agentskills.io) format.

### Available Skills

| Skill | Input | What it creates |
|-------|-------|-----------------|
| **`scaffold-test`** | Target `src/` class name | Generates `tests/<ClassName>Test.php` with PHPUnit 9 structure, singleton resets, CurlStub/NamespaceStub imports auto-detected from the target class's dependencies |
| **`scaffold-platform`** | CMS platform name | Generates `src/Platforms/<Name>.php` with Hook callback stubs + `tests/Platforms/<Name>Test.php` + placeholder section in `memory-bank/cmsSupport.md` + manual checklist (with ⚠ Plan Mode warning for `Processor.php`) |
| **`scaffold-admin-action`** | Action name + description | Generates template partial, adds handler stub to `Management.php` (⚠ Plan Mode), adds switch case in `linguise.php`, writes test stub in `tests/ManagementTest.php`, and updates `memory-bank/managementFlow.md` |
| **`update-memory-bank`** | Change type + description of work done | Reads all 11 memory-bank files, identifies which are stale based on change type, updates `activeContext.md` and `progress.md` for every invocation, applies targeted edits to other relevant files (architecture, CMS support, management flow, etc.), and reports which files need manual review. ⚠ Never auto-modifies `planModeFiles.md` |
| **`plan-mode-preflight`** | One or more file paths to check | Reads the Plan Mode file list from `memory-bank/planModeFiles.md`, checks each input file against the list, outputs `BLOCKED` status with category + reason + Plan Mode workflow reference if a match is found (and halts), or `CLEAR` status with all checked files if none match. Read-only — never modifies any file |
| **`debug-translation`** | (none — run directly) | Diagnoses translation failures by reading `Configuration.php` for token and debug state, checking `certificates/cacert.pem`, reading debug log entries, and cross-referencing findings against the pipeline in `memory-bank/architecture.md` to identify the most likely failure stage (CurlRequest, Cache, or Translation). Read-only — never modifies any file |
| **`debug-management-ui`** | (none — run directly) | Diagnoses management interface failures by reading `ui-config.php` to inspect `LINGUISE_OOBE_DONE`, `LINGUISE_LOGIN_SECRET`, and DB constants, then mapping the constant state to the four silent failure modes from AGENTS.md (blank page, login failure, 403 on POST, stuck OOBE). Read-only — never modifies any file |

### When to Use a Skill

Invoke a skill when the user asks to:
- **"Add a test for class X"** → use `scaffold-test`
- **"Add support for CMS Y"** → use `scaffold-platform`
- **"Add an admin action for Z"** → use `scaffold-admin-action`
- **"Update the memory bank after..."** or **"Sync the memory bank"** → use `update-memory-bank`
- **"Check if these files need Plan Mode"** or **"Run Plan Mode preflight"** → use `plan-mode-preflight`
- **"Debug a translation failure"** or **"Why is translation not working?"** → use `debug-translation`
- **"Debug the management interface"** or **"Why is the admin panel broken?"** → use `debug-management-ui`

Scaffolding skills produce a complete scaffold; the developer then fills in the TODO stubs with actual business logic. `update-memory-bank` and `plan-mode-preflight` are read/write and read-only utility skills for documentation and safety workflows. `debug-translation` and `debug-management-ui` are read-only diagnostic skills.

### Skill Locations

```
.agents/skills/
├── debug-management-ui/
│   └── SKILL.md
├── debug-translation/
│   └── SKILL.md
├── plan-mode-preflight/
│   └── SKILL.md
├── scaffold-admin-action/
│   └── SKILL.md
├── scaffold-platform/
│   └── SKILL.md
├── scaffold-test/
│   └── SKILL.md
└── update-memory-bank/
    └── SKILL.md
```

