Запуск ralphex в нескольких репозиториях workspace
Workspace DWE может содержать корневой Git-репозиторий и отдельные репозитории сервисов. Обычные Git-команды ralphex видят только корень: коммит сервиса может выглядеть как отсутствие изменений для цикла ревью, а корневой diff не показывает реализацию. Workspace-пак ralphex устанавливает Git-обёртку и блоки промптов, которые проверяют корень вместе с репозиториями, выбранными для конкретного плана. Остальные сервисы остаются вне этой области. Пустой коммит в корне после коммита сервиса не нужен.
Стартовый набор находится в examples/workspace-packs/ralphex/README.md. После копирования пак, команды и скрипты принадлежат вашему workspace. DWE предоставляет общий механизм рендеринга; он не встраивает промпты ralphex и не обновляет вашу копию стартового набора.
Установка стартового набора
Заголовок раздела «Установка стартового набора»Установите ralphex локально. Набор рассчитан на структуру defaults версии v1.7.0 и генерирует переопределения из установленной версии. Скриптам нужны POSIX sh, awk, diff, Git и sha256sum либо shasum.
Выполните dwe --version, затем скачайте тег DWE, соответствующий установленной
версии. Из корня workspace, подставив подходящий тег:
DWE_TAG='<matching-dwe-tag>'git clone --depth 1 --branch "$DWE_TAG" https://github.com/semsemyonoff/dwe.git /tmp/dwe-starterscp -R /tmp/dwe-starters/examples/workspace-packs/ralphex/workspace/. workspace/Окончание /. копирует содержимое каталога и в BSD, и в GNU cp. Объедините
workspace.yml.snippet из набора с корневым workspace.yml, сохранив остальные
элементы render.workspace. Фрагмент выбирает пак ralphex и при необходимости
задаёт ветку по умолчанию. Скопированный workspace/commands/ralphex.yml задаёт
группу команд; ссылки на все файлы набора есть в README.
Добавьте в корневой .gitignore:
/.ralphex/run/Удалите правило /.ralphex/ от старого scaffold, чтобы сгенерированные настройки
и промпты можно было закоммитить. Ralphex сам перезаписывает
.ralphex/.gitignore; правило для состояния запуска храните в корневом файле.
Сгенерируйте пак и промпты, затем закоммитьте:
dwe render workspacedwe cmd ralphex.promptsgit add workspace.yml workspace/ .gitignore .ralphex/git commit -m 'feat: configure workspace ralphex'Рендеринг записывает .ralphex/config, исполняемый .ralphex/scripts/ws-git и
четыре блока фаз. Генерация промптов вставляет эти блоки в десять переопределений:
пять промптов (task, review_first, review_second, codex, codex_review) и
пять агентов ревью. Она сохраняет defaults установленной версии, включая
завершающие правила сигналов, и никогда не копирует выгруженный config поверх
отрендеренного. Маркеры ralphex вроде {{PLAN_FILE}} остаются буквальным текстом
в файлах пака, которые копируются без шаблонизации.
Генерация отклоняет симлинки в выходных каталогах и принадлежащие ей пути,
которые не являются обычными файлами, до изменения переопределений и defaults stamp.
Область репозиториев для каждого плана
Заголовок раздела «Область репозиториев для каждого плана»Агент, который пишет план, готовит git и область одним шагом, а затем передаёт строку запуска человеку, который запускает ralphex в терминале.
-
Выберите базовый ref, рабочую ветку и репозитории в области (
repos— разделённый пробельными символами список путей относительно workspace; в именах путей не должно быть пробелов;repos=.означает план только в корне). Корень включён всегда. -
Напишите план и запустите scope с
prepare=trueи путём к плану:Окно терминала dwe cmd ralphex.scope --set repos='services/api/src services/web/src' --set base=plan-base --set branch=task/example --set prepare=true --set plan=docs/plans/example.md -
Передайте человеку последнюю строку вывода; её можно вставить в терминал как есть. Перед ней идут строки
ws-prepareиws-check:Launch ralphex with:ralphex --base-ref plan-base --branch task/example docs/plans/example.md
Значения при необходимости заключаются в кавычки по правилам POSIX. plan
необязателен: это относительный путь, не начинающийся с -, к существующему
обычному файлу. Если он не задан, в строке выводится буквальный placeholder
<plan>, который нужно заменить. Пути планов с пробельными символами
отклоняются: ralphex v1.7.0 при создании ветки в корне не распознаёт такой план
как единственный незакоммиченный файл и отказывается стартовать.
base не может ссылаться на HEAD или на рабочую ветку ни в каком написании
(task/example, heads/task/example, refs/heads/task/example, task/example~1):
такой base следовал бы за вершиной рабочей ветки и скрывал бы изменения задачи.
Написания сравниваются без учёта регистра, так как файловые системы macOS обычно
регистронезависимы.
base, который нужно создать как тег, не может быть назван как путь ref (refs/…,
heads/…, tags/…, remotes/…).
prepare=true запускает ws-git ws-prepare для корня и каждого выбранного
репозитория:
- Если base не разрешается, создаётся легковесный тег на текущем HEAD.
- В репозиториях, кроме корня, выполняется переключение на существующую рабочую ветку, которая должна содержать base, либо ветка создаётся от base (не от HEAD) без upstream.
- Корень обрабатывается иначе. Если он на
default_branchralphex (читается из.ralphex/config;mainилиmaster, если не задана), его ветка не трогается: ralphex сам создаёт или переключает--branchпри запуске и автоматически коммитит план. Иначе корень обрабатывается как остальные репозитории. Отрендеренная ветка по умолчанию —main, либо значениеvars.ralphex.default_branch, если оно задано. - Перед любыми изменениями всё проверяется во всех репозиториях, кроме ошибок,
которые может обнаружить только
git switch(конфликт с грязным деревом, ветка уже извлечена в другом worktree). - Созданные теги и ветки не откатываются при последующей ошибке. Prepare идемпотентен: устраните причину и запустите его снова.
- Грязные рабочие деревья заранее не проверяются; конфликт
git switchзавершается с сообщением git.
Ручной вариант: подготовьте теги и ветки сами в каждом выбранном репозитории и в
корне, затем запустите ту же команду с prepare=false (по умолчанию) и, при
желании, plan=…. Запускайте ralphex с теми же base и branch.
Команда записывает .ralphex/run/{repos,base-ref,task-branch,base-sha}, запускает
ws-check и восстанавливает предыдущее состояние, включая base-sha, при ошибке
проверки. Не коммитьте это состояние запуска. Репозитории должны быть обычными checkout с
каталогом .git; абсолютные пути, компоненты .. и симлинки отклоняются.
Существующие файлы настроек состояния должны быть обычными файлами; симлинки и
другие типы файлов отклоняются до изменения состояния.
Закреплённый base
Заголовок раздела «Закреплённый base»Scope закрепляет base для каждого репозитория, включая корень, на коммите, в который
он разрешается после prepare. В .ralphex/run/base-sha по одной строке
<repo> <sha> на репозиторий (корень записывается как .), а ws-check печатает
SHA как base_sha=. Preflight плана ссылается на этот вывод и не вычисляет base
сам и не сравнивает его с origin/*; отсутствующий или повреждённый файл
закрепления тоже блокирует запуск.
Любая команда ws-git, включая вызовы Git, которые ralphex направляет через
обёртку, завершается с <repo>: base <ref> moved since scope: <pinned> -> <now>,
если base теперь разрешается в другой коммит, например после fetch для
remote-tracking base или пересоздания тега. Отсутствующий файл закрепления или
запись для выбранного репозитория завершает команду сообщением повторить scope;
обёртка никогда не откатывается к разрешению base по имени. Сдвинувшийся base —
остановка с доказательствами: перезакрепление решает человек.
Повторный scope с тем же base (сравнение без учёта регистра) сохраняет закрепления.
Если base сдвинулся, scope отклоняется до того, как prepare что-либо создаст,
переключит или пометит тегом, а предыдущее состояние остаётся на месте; нечитаемый
прежний файл закрепления отклоняется так же. Принять новые коммиты явно можно через
--set repin=true. Другое имя base или репозиторий без прежнего закрепления получают
новое.
ws-check строг. Каждый репозиторий, кроме корня, должен быть на рабочей ветке, а
base должен быть её предком. Корень должен быть либо на рабочей ветке, либо на
default_branch, при этом base должен быть предком существующей рабочей ветки
(или HEAD, если ветки ещё нет). Ошибка блокирует запуск; её не нужно исправлять
созданием веток «на месте».
Проверить выбранные репозитории можно так:
.ralphex/scripts/ws-git ws-check.ralphex/scripts/ws-git ws-status.ralphex/scripts/ws-git ws-log.ralphex/scripts/ws-git ws-diff --stat.ralphex/scripts/ws-git ws-wipws-check проверяет описанный выше контракт. Во время запуска ws-log,
ws-diff и ws-wip требуют, чтобы каждый выбранный репозиторий, включая корень,
находился на рабочей ветке, а base был её предком (корень ralphex переключает при
запуске). Иначе они завершаются явной ошибкой. Блоки промптов направляют агентов
задач и ревью к этим командам и к коммитам в отдельных репозиториях с явно
выбранными путями задачи. Обёртка также объединяет HEAD и изменения рабочих
деревьев выбранных репозиториев для обнаружения изменений в ralphex. Пока
состояния запуска нет, перехваченные Git-проверки охватывают только корень, чтобы
работали bootstrap и генерация планов; для каждой команды ws-* и каждого запуска
задач или ревью сначала нужно задать область.
Правила workspace
Заголовок раздела «Правила workspace»Храните правила проекта в своей копии
workspace/templates/workspace/ralphex/policy/. Добавьте записи манифеста,
копирующие их в .ralphex/policy/. Фрагмент policy/<phase>.md применяется ко
всем файлам фазы, а policy/<file>.md — к одному промпту или агенту.
| Фаза | Файлы |
|---|---|
task | task |
review | review_first, review_second, codex |
codex_review | codex_review |
agent | documentation, implementation, quality, simplification, testing |
Например, поместите правила проверок и обработки ранее существовавших проблем в
policy/task.md и policy/review.md, а правило ревью AGENTS.md — в
policy/documentation.md. Порядок вставки: блок фазы, правила фазы, правила файла.
Если имена фазы и файла совпадают, фрагмент вставляется один раз.
Первая строка блока или фрагмента правил не должна начинаться с #; генерация
отклоняет её, потому что ralphex может удалить начальные Markdown-заголовки вместе
с заголовком-комментарием. Блоки и правила помещаются в начало тела после этого
заголовка; frontmatter агентов тоже сохраняется. После изменения блоков, правил
или манифеста пака:
dwe render workspacedwe cmd ralphex.promptsПроверьте и закоммитьте обновлённые исходники пака и файлы .ralphex/.
Проверка после обновления ralphex
Заголовок раздела «Проверка после обновления ralphex»dwe cmd ralphex.prompts --set check=trueРежим проверки генерирует файлы во временный каталог, сравнивает все десять
переопределений и сообщает об изменении версии или хеша defaults относительно
.ralphex/defaults.stamp. Он ничего не записывает в workspace и возвращает
ненулевой код при изменении переопределений или stamp. Так обнаруживаются
изменения defaults, блоков или правил, а также ручные правки промптов. Проверьте
различия, повторите генерацию через dwe cmd ralphex.prompts и закоммитьте.
Файлы в .ralphex/prompts/ и .ralphex/agents/, которыми генератор не управляет,
вызывают предупреждения и сохраняются. Удаляйте устаревшие переопределения явно:
старые custom_eval, custom_review или make_plan могут скрывать новые
defaults. Своим агентам может потребоваться отдельно добавить блок области
workspace. Рендеринг также сохраняет файлы, чьи записи удалены из манифеста;
удаляйте такие файлы самостоятельно.
Ограничения и будущее prepend-поддержки
Заголовок раздела «Ограничения и будущее prepend-поддержки»- Итоговая статистика diff охватывает только корневой репозиторий.
custom_reviewиcustom_evalне переопределены; приexternal_review_tool = customревью охватывает только корень.--worktreeне поддерживается. Набор задаётuse_worktree = false.- Finalize отключён через
finalize_enabled = false, потому что его rebase охватывает только корень.
Это первый этап интеграции: полные переопределения генерируются из установленных
defaults с добавлением блоков. Если upstream ralphex добавит prepend-поддержку
для промптов и агентов, пак второго этапа сможет копировать блоки и правила как
буквальные prepend-файлы; команду ralphex.prompts и stamp defaults тогда можно
будет удалить. Это будущая миграция, а не условие использования стартового набора.