调整 Docker 环境与依赖配置:

- 替换基础镜像为 `php:8.4.15-cli-alpine3.23`,重构依赖安装流程
- 切换包管理工具为 `apk`,添加必要系统库及扩展
- 更新 Composer 脚本及依赖映射
- 优化命令与环境变量配置,增强一致性与兼容性
This commit is contained in:
2025-12-17 17:13:37 +08:00
parent ced95c02cb
commit fa00da5966
6 changed files with 272 additions and 169 deletions

View File

@@ -1,9 +1,12 @@
{ {
"mcpServers": { "mcpServers": {
"laravel-boost": { "laravel-boost": {
"command": "docker compose run app", "command": "docker",
"args": [ "args": [
"vendor/bin/sail", "compose",
"exec",
"app",
"php",
"artisan", "artisan",
"boost:mcp" "boost:mcp"
] ]

411
CLAUDE.md
View File

@@ -1,228 +1,317 @@
<laravel-boost-guidelines> # CLAUDE.md
=== foundation rules ===
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
自然语言使用中文。
## 项目概述
这是一个基于 Laravel 12 + Octane + Docker 的 Agent Runtime Server (ARS),用于提供可部署的 Agent 运行时服务。核心特性包括:
- 兼容多种 Agent 模型
- Web 终端实时交互,支持断线重连
- 后台任务持续执行,重连后可续传会话
## 技术栈
- **PHP**: 8.2+
- **Laravel Framework**: 12.x
- **Laravel Octane**: 2.x (FrankenPHP)
- **Laravel Horizon**: 5.x (队列监控)
- **Laravel Telescope**: 5.x (调试工具)
- **数据库**: PostgreSQL 16
- **缓存/队列**: Redis 7
- **认证**: JWT (php-open-source-saver/jwt-auth)
- **容器化**: Docker Compose
## 核心架构
### 数据模型
#### ChatSession (会话)
- `session_id` (UUID, 主键): 会话唯一标识
- `session_name`: 会话名称
- `status`: 会话状态 (OPEN/LOCKED/CLOSED)
- `last_seq`: 最后消息序号
- `last_message_id`: 最后消息ID
#### Message (消息)
- `message_id` (UUID, 主键): 消息唯一标识
- `session_id`: 所属会话ID
- `role`: 消息角色 (USER/AGENT/TOOL/SYSTEM)
- `type`: 消息类型 (user.prompt/agent.message/run.status等)
- `content`: 消息内容 (text)
- `payload`: 附加数据 (jsonb)
- `seq`: 会话内序号 (单调递增)
- `reply_to`: 回复的消息ID
- `dedupe_key`: 幂等去重键
- **约束**: `unique(session_id, seq)``unique(session_id, dedupe_key)`
### 会话状态与门禁规则
- **OPEN**: 正常追加所有消息
- **LOCKED**: 拒绝 `role=USER && type=user.prompt`
- **CLOSED**: 拒绝追加,例外允许 `role=SYSTEM && type in [run.status, error]`
- **状态变更规则**: CLOSED 状态的会话不能重新打开
# Laravel Boost Guidelines ### Agent Run 执行流程
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications. 1. 用户发送 `user.prompt` 消息后自动触发,或通过 API 手动触发
2. `RunDispatcher` 检查幂等性(基于 `trigger_message_id`
3. 检查会话是否已有 RUNNING 状态的 run单会话单任务限制
4. 创建 `run.status=RUNNING` 消息并派发 `AgentRunJob`
5. `RunLoop` 执行 Agent 调用流程:
- `ContextBuilder` 构建上下文
- `AgentProviderInterface` 调用 Agent当前为 DummyAgentProvider
- `CancelChecker` 检查取消信号
- `OutputSink` 写入 agent.message
6. 完成后写入 `run.status=DONE/FAILED/CANCELED`
## Foundational Context ### 实时消息推送 (SSE)
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.3.28 - **端点**: `GET /api/sessions/{id}/sse?after_seq=123`
- laravel/framework (LARAVEL) - v12 - **机制**:
- laravel/horizon (HORIZON) - v5 1. 先从数据库补发历史消息seq > after_seq
- laravel/octane (OCTANE) - v2 2. 订阅 Redis 频道 `session:{id}:messages` 监听新消息
- laravel/prompts (PROMPTS) - v0 3. 支持 `Last-Event-ID` 自动续传
- laravel/telescope (TELESCOPE) - v5 - **事件格式**: SSE event id 为消息 seq
- laravel/mcp (MCP) - v0
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
- phpunit/phpunit (PHPUNIT) - v11
## Conventions ### 服务层架构
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, naming.
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
- Check for existing components to reuse before writing a new one.
## Verification Scripts - **ChatService**: 会话和消息的核心业务逻辑
- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. - 使用行锁 (`lockForUpdate`) + 事务保证消息 seq 单调递增
- 通过 `dedupe_key` 实现幂等性
- 消息追加后发布 Redis 事件用于 SSE 推送
## Application Structure & Architecture - **RunDispatcher**: Agent Run 调度器
- Stick to existing directory structure - don't create new base folders without approval. - 检查 trigger_message_id 幂等性
- Do not change the application's dependencies without approval. - 确保同会话只有一个 RUNNING 状态的 run
## Frontend Bundling - **RunLoop**: Agent 执行循环
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `vendor/bin/sail npm run build`, `vendor/bin/sail npm run dev`, or `vendor/bin/sail composer run dev`. Ask them. - 协调 ContextBuilder、AgentProvider、OutputSink、CancelChecker
## Replies - **OutputSink**: 统一的消息写入接口
- Be concise in your explanations - focus on what's important rather than explaining obvious details. - `appendAgentMessage()`: 写入 agent 回复
- `appendRunStatus()`: 写入 run 状态
- `appendError()`: 写入错误信息
## Documentation Files ## 常用开发命令
- You must only create documentation files if explicitly requested by the user.
### Docker 容器操作
=== boost rules === ```bash
# 构建并启动所有服务
docker compose build
docker compose up -d app horizon pgsql redis
## Laravel Boost # 停止服务
- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. docker compose stop
## Artisan # 查看日志
- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters. docker compose logs -f app
docker compose logs -f horizon
## URLs # 进入容器 shell
- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port. docker compose exec app bash
```
## Tinker / Debugging ### 数据库操作
- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
- Use the `database-query` tool when you only need to read from the database.
## Reading Browser Logs With the `browser-logs` Tool ```bash
- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost. # 运行迁移
- Only recent browser logs will be useful - ignore old logs. docker compose exec app php artisan migrate
## Searching Documentation (Critically Important) # 回滚迁移
- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. docker compose exec app php artisan migrate:rollback
- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc.
- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches.
- Search the documentation before making code changes to ensure we are taking the correct approach.
- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`.
- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`.
### Available Search Syntax # 刷新数据库(危险:删除所有表并重新迁移)
- You can and should pass multiple queries at once. The most relevant results will be returned first. docker compose exec app php artisan migrate:fresh
1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth' # 运行 seeder
2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit" docker compose exec app php artisan db:seed
3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order ```
4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit"
5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms
### 测试
=== php rules === ```bash
# 运行所有测试
docker compose exec app php artisan test
## PHP # 运行特定测试套件
docker compose exec app php artisan test --testsuite=Feature
docker compose exec app php artisan test --testsuite=Unit
- Always use curly braces for control structures, even if it has one line. # 运行特定测试文件
docker compose exec app php artisan test tests/Feature/ChatSessionTest.php
### Constructors # 运行特定测试方法(使用 filter
- Use PHP 8 constructor property promotion in `__construct()`. docker compose exec app php artisan test --filter=testCreateSession
- <code-snippet>public function __construct(public GitHub $github) { }</code-snippet> docker compose exec app php artisan test --filter=testAppendMessageWithDedupe
- Do not allow empty `__construct()` methods with zero parameters.
### Type Declarations # 显示测试覆盖率
- Always use explicit return type declarations for methods and functions. docker compose exec app php artisan test --coverage
- Use appropriate PHP type hints for method parameters. ```
<code-snippet name="Explicit Return Types and Method Params" lang="php"> ### 代码质量
protected function isAccessible(User $user, ?string $path = null): bool
{
...
}
</code-snippet>
## Comments ```bash
- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on. # 运行 Laravel Pint 格式化代码
docker compose exec app vendor/bin/pint
## PHPDoc Blocks # 只检查格式问题(不修改)
- Add useful array shape type definitions for arrays when appropriate. docker compose exec app vendor/bin/pint --test
## Enums # 格式化脏文件git 变更的文件)
- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. docker compose exec app vendor/bin/pint --dirty
```
### 队列与任务
=== sail rules === ```bash
# 查看 Horizon 仪表板
# 访问 http://localhost:8000/horizon
## Laravel Sail # 手动运行队列 worker开发调试用
docker compose exec app php artisan queue:work
- This project runs inside Laravel Sail's Docker containers. You MUST execute all commands through Sail. # 查看失败的任务
- Start services using `vendor/bin/sail up -d` and stop them with `vendor/bin/sail stop`. docker compose exec app php artisan queue:failed
- Open the application in the browser by running `vendor/bin/sail open`.
- Always prefix PHP, Artisan, Composer, and Node commands** with `vendor/bin/sail`. Examples:
- Run Artisan Commands: `vendor/bin/sail artisan migrate`
- Install Composer packages: `vendor/bin/sail composer install`
- Execute node commands: `vendor/bin/sail npm run dev`
- Execute PHP scripts: `vendor/bin/sail php [script]`
- View all available Sail commands by running `vendor/bin/sail` without arguments.
# 重试失败的任务
docker compose exec app php artisan queue:retry all
```
=== tests rules === ### 开发调试
## Test Enforcement ```bash
# 启动 Tinker REPL
docker compose exec app php artisan tinker
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass. # 查看路由列表
- Run the minimum number of tests needed to ensure code quality and speed. Use `vendor/bin/sail artisan test` with a specific filename or filter. docker compose exec app php artisan route:list
# 清除缓存
docker compose exec app php artisan cache:clear
docker compose exec app php artisan config:clear
docker compose exec app php artisan route:clear
=== laravel/core rules === # 查看实时日志(使用 Laravel Pail
docker compose exec app php artisan pail
```
## Do Things the Laravel Way ### Artisan 生成器
- Use `vendor/bin/sail artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. ```bash
- If you're creating a generic PHP class, use `vendor/bin/sail artisan make:class`. # 生成 Model推荐带选项一次性生成相关文件
- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior. docker compose exec app php artisan make:model ChatSession -mfs
# -m: migration, -f: factory, -s: seeder
### Database # 生成 Controller
- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. docker compose exec app php artisan make:controller ChatSessionController
- Use Eloquent models and relationships before suggesting raw database queries
- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them.
- Generate code that prevents N+1 query problems by using eager loading.
- Use Laravel's query builder for very complex database operations.
### Model Creation # 生成 Form Request用于验证
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `vendor/bin/sail artisan make:model`. docker compose exec app php artisan make:request AppendMessageRequest
### APIs & Eloquent Resources # 生成 ResourceAPI 响应格式化)
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention. docker compose exec app php artisan make:resource ChatSessionResource
### Controllers & Validation # 生成 Job
- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. docker compose exec app php artisan make:job AgentRunJob
- Check sibling Form Requests to see if the application uses array or string based validation rules.
### Queues # 生成 Service 类
- Use queued jobs for time-consuming operations with the `ShouldQueue` interface. docker compose exec app php artisan make:class Services/ChatService
### Authentication & Authorization # 生成测试
- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). docker compose exec app php artisan make:test ChatSessionTest --phpunit
docker compose exec app php artisan make:test ChatServiceTest --unit --phpunit
```
### URL Generation ## API 路由结构
- When generating links to other pages, prefer named routes and the `route()` function.
### Configuration 所有 API 路由均在 `/api/*` 下,除登录和健康检查外均需 JWT 认证:
- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`.
### Testing - `POST /api/login`: 用户登录
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model. - `GET /api/health`: 健康检查
- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`. - `GET /api/me`: 获取当前用户信息
- When creating tests, make use of `vendor/bin/sail artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
### Vite Error ### 用户管理
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `vendor/bin/sail npm run build` or ask the user to run `vendor/bin/sail npm run dev` or `vendor/bin/sail composer run dev`. - `GET /api/users`: 用户列表
- `POST /api/users`: 创建用户
- `PUT /api/users/{user}`: 更新用户
- `POST /api/users/{user}/deactivate`: 停用用户
- `POST /api/users/{user}/activate`: 激活用户
### 会话管理
- `POST /api/sessions`: 创建会话
- `GET /api/sessions`: 会话列表(支持分页、状态过滤、关键词搜索)
- `GET /api/sessions/{session_id}`: 获取会话详情
- `PATCH /api/sessions/{session_id}`: 更新会话(重命名、状态变更)
- `POST /api/sessions/{session_id}/archive`: 归档会话(幂等,设为 CLOSED
=== laravel/v12 rules === ### 消息管理
- `POST /api/sessions/{session_id}/messages`: 追加消息(支持幂等 dedupe_key
- `GET /api/sessions/{session_id}/messages`: 获取消息列表(支持 after_seq 增量拉取)
- `GET /api/sessions/{session_id}/messages/{message_id}`: 获取单条消息
## Laravel 12 ### 实时与 Agent Run
- `GET /api/sessions/{session_id}/sse`: SSE 实时消息流
- `POST /api/sessions/{session_id}/runs`: 手动触发 Agent Run
- Use the `search-docs` tool to get version specific documentation. ## 开发注意事项
- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.
### Laravel 12 Structure ### Laravel 12 新特性
- No middleware files in `app/Http/Middleware/`. - `app/Console/Kernel.php` `app/Http/Kernel.php`
- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. - 中间件、路由、异常处理在 `bootstrap/app.php` 配置
- `bootstrap/providers.php` contains application specific service providers. - 服务提供者在 `bootstrap/providers.php` 注册
- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration. - Commands 自动注册(无需手动注册)
- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual registration.
### Database ### 数据库操作规范
- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. - 消息追加必须使用 `ChatService::appendMessage()`,不要直接操作 Message 模型
- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. - 会话状态变更必须通过 `ChatService::updateSession()`
- 所有涉及 seq 递增的操作必须在事务 + 行锁中完成
### Models ### 测试规范
- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. - 所有测试使用 PHPUnit非 Pest
- Feature 测试必须测试完整的 HTTP 请求流程
- 测试中使用 Factory 创建模型数据
- 修改代码后必须运行相关测试确保通过
### 队列配置
- 开发环境可使用同步队列:`.env` 中设置 `QUEUE_CONNECTION=sync`
- 生产环境使用 Redis 队列 + Horizon 监控
- `AgentRunJob` 在队列中异步执行
=== pint/core rules === ### 幂等性设计
- 所有可能重复调用的操作都使用 `dedupe_key`
- `RunDispatcher` 通过 `trigger_message_id` 确保不会为同一 prompt 重复创建 run
- SSE 通过 `Last-Event-ID` / `after_seq` 支持断线续传
## Laravel Pint Code Formatter ## 环境变量关键配置
- You must run `vendor/bin/sail bin pint --dirty` before finalizing changes to ensure your code matches the project's expected style. ```bash
- Do not run `vendor/bin/sail bin pint --test`, simply run `vendor/bin/sail bin pint` to fix any formatting issues. # Octane 服务器
OCTANE_SERVER=frankenphp
# 数据库PostgreSQL
DB_CONNECTION=pgsql
DB_HOST=pgsql
DB_PORT=5432
DB_DATABASE=ars_backend
=== phpunit/core rules === # Redis
REDIS_HOST=redis
REDIS_PORT=6379
# 队列
QUEUE_CONNECTION=redis # 或 sync开发用
## PHPUnit Core # JWT 认证
JWT_SECRET=<生成的密钥>
AUTH_GUARD=api
- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use `vendor/bin/sail artisan make:test --phpunit {name}` to create a new test. # CORS
- If you see a test using "Pest", convert it to PHPUnit. CORS_ALLOWED_ORIGINS=http://localhost:5173
- Every time a test has been updated, run that singular test. ```
- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite to make sure everything is still passing.
- Tests should test all of the happy paths, failure paths, and weird paths. ## 相关文档
- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files, these are core to the application.
- API 详细文档:`docs/ChatSession/chat-session-api.md`
### Running Tests - OpenAPI 规范:`docs/ChatSession/chat-session-openapi.yaml`
- Run the minimal number of tests, using an appropriate filter, before finalizing. - 用户管理文档:`docs/User/user-api.md`
- To run all tests: `vendor/bin/sail artisan test`.
- To run all tests in a file: `vendor/bin/sail artisan test tests/Feature/ExampleTest.php`.
- To filter on a particular test name: `vendor/bin/sail artisan test --filter=testName` (recommended after making a change to a related file).
</laravel-boost-guidelines>

View File

@@ -1,23 +1,33 @@
FROM dunglas/frankenphp:1-php8.2 FROM php:8.4.15-cli-alpine3.23
WORKDIR /app WORKDIR /app
# System packages and PHP extensions required by Laravel/Octane # System packages and PHP extensions required by Laravel/Octane
RUN apt-get update \ RUN apk update \
&& apt-get install -y --no-install-recommends \ && apk add --no-cache \
git \ git \
unzip \ unzip \
libzip-dev \ libzip-dev \
libpq-dev \ postgresql-dev \
zlib1g-dev \ zlib-dev \
libpq \
icu-dev \
gcc \
g++ \
make \
autoconf \
libc-dev \
pkgconfig \
&& docker-php-ext-install \ && docker-php-ext-install \
pcntl \ pcntl \
zip \ zip \
pdo_mysql \ pdo_mysql \
pdo_pgsql \ pdo_pgsql \
intl \
&& pecl install redis \ && pecl install redis \
&& docker-php-ext-enable redis \ && docker-php-ext-enable redis \
&& rm -rf /var/lib/apt/lists/* pdo_pgsql \
&& rm -rf /var/cache/apk/*
# Composer for dependency management # Composer for dependency management
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer

View File

@@ -30,5 +30,6 @@
<env name="PULSE_ENABLED" value="false"/> <env name="PULSE_ENABLED" value="false"/>
<env name="TELESCOPE_ENABLED" value="false"/> <env name="TELESCOPE_ENABLED" value="false"/>
<env name="NIGHTWATCH_ENABLED" value="false"/> <env name="NIGHTWATCH_ENABLED" value="false"/>
<env name="JWT_SECRET" value="testing_jwt_secret_for_unit_tests_32_chars_min"/>
</php> </php>
</phpunit> </phpunit>