@echo off setlocal enabledelayedexpansion rem Vendor a trimmed Playbook snapshot into a target project (offline copy), rem then run sync_standards to materialize .agents\\ and .gitattributes in rem the target project root. rem rem Usage: rem scripts\vendor_playbook.bat (default: tsl) rem scripts\vendor_playbook.bat tsl cpp rem scripts\vendor_playbook.bat --langs tsl,cpp rem scripts\vendor_playbook.bat tsl cpp --apply-templates rem rem Options: rem --apply-templates Apply CI/lang templates to project root (skip if exists) rem rem Notes: rem - Snapshot is written to: \docs\standards\playbook\ rem - Existing snapshot is backed up before overwrite. rem - With --apply-templates, CI and lang templates are copied to project root. set "SCRIPT_DIR=%~dp0" for %%I in ("%SCRIPT_DIR%..") do set "SRC=%%~fI" if "%~1"=="" goto Usage if "%~1"=="-h" goto Usage if "%~1"=="--help" goto Usage set "DEST_ROOT=%~1" shift /1 set "LANGS=" set "APPLY_TEMPLATES=0" rem Parse arguments :parse_args if "%~1"=="" goto args_done if "%~1"=="--langs" ( set "LANGS=%~2" shift /1 shift /1 goto parse_args ) if "%~1"=="--apply-templates" ( set "APPLY_TEMPLATES=1" shift /1 goto parse_args ) if "%LANGS%"=="" ( set "LANGS=%~1" ) else ( set "LANGS=%LANGS% %~1" ) shift /1 goto parse_args :args_done if "%LANGS%"=="" set "LANGS=tsl" set "LANGS=%LANGS:,= %" if not exist "%DEST_ROOT%" mkdir "%DEST_ROOT%" for %%I in ("%DEST_ROOT%") do set "DEST_ROOT_ABS=%%~fI" set "STANDARDS_DIR=%DEST_ROOT_ABS%\\docs\\standards" set "DEST_PREFIX=%STANDARDS_DIR%\\playbook" if not exist "%STANDARDS_DIR%" mkdir "%STANDARDS_DIR%" if exist "%DEST_PREFIX%" ( set "RAND=%RANDOM%" pushd "%STANDARDS_DIR%" ren "playbook" "playbook.bak.!RAND!" popd echo Backed up existing snapshot -^> docs\\standards\\playbook.bak.!RAND! ) if not exist "%DEST_PREFIX%" mkdir "%DEST_PREFIX%" copy /y "%SRC%\\.gitattributes" "%DEST_PREFIX%\\.gitattributes" >nul copy /y "%SRC%\\SKILLS.md" "%DEST_PREFIX%\\SKILLS.md" >nul xcopy "%SRC%\\scripts\\*" "%DEST_PREFIX%\\scripts\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy scripts exit /b 1 ) xcopy "%SRC%\\codex\\*" "%DEST_PREFIX%\\codex\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy codex exit /b 1 ) xcopy "%SRC%\\docs\\common\\*" "%DEST_PREFIX%\\docs\\common\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy docs\\common exit /b 1 ) if not exist "%DEST_PREFIX%\\rulesets" mkdir "%DEST_PREFIX%\\rulesets" copy /y "%SRC%\\rulesets\\index.md" "%DEST_PREFIX%\\rulesets\\index.md" >nul if not exist "%DEST_PREFIX%\\templates" mkdir "%DEST_PREFIX%\\templates" if exist "%SRC%\\templates\\ci" ( xcopy "%SRC%\\templates\\ci\\*" "%DEST_PREFIX%\\templates\\ci\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy templates\\ci exit /b 1 ) ) set "LANGS_CSV=" for %%L in (%LANGS%) do ( echo %%~L| findstr /r "[\\/]" >nul && ( echo ERROR: invalid lang=%%~L exit /b 1 ) echo %%~L| findstr /c:".." >nul && ( echo ERROR: invalid lang=%%~L exit /b 1 ) if not exist "%SRC%\\docs\\%%~L" ( echo ERROR: docs not found for lang=%%~L "%SRC%\\docs\\%%~L" exit /b 1 ) if not exist "%SRC%\\rulesets\\%%~L" ( echo ERROR: agents ruleset not found for lang=%%~L "%SRC%\\rulesets\\%%~L" exit /b 1 ) xcopy "%SRC%\\docs\\%%~L\\*" "%DEST_PREFIX%\\docs\\%%~L\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy docs for lang=%%~L exit /b 1 ) xcopy "%SRC%\\rulesets\\%%~L\\*" "%DEST_PREFIX%\\rulesets\\%%~L\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy agents for lang=%%~L exit /b 1 ) if exist "%SRC%\\templates\\%%~L" ( xcopy "%SRC%\\templates\\%%~L\\*" "%DEST_PREFIX%\\templates\\%%~L\\" /e /i /y >nul if errorlevel 1 ( echo ERROR: failed to copy templates for lang=%%~L exit /b 1 ) ) if "!LANGS_CSV!"=="" ( set "LANGS_CSV=%%~L" ) else ( set "LANGS_CSV=!LANGS_CSV!,%%~L" ) ) set "DOC_INDEX=%DEST_PREFIX%\\docs\\index.md" > "%DOC_INDEX%" echo # 文档导航(Docs Index) >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo 本快照为裁剪版 Playbook(langs: %LANGS_CSV%)。 >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo ## 跨语言(common) >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo - 提交信息与版本号:`common/commit_message.md` for %%L in (%LANGS%) do call :AppendDocsSection "%%~L" set "COMMIT=" for /f "delims=" %%H in ('git -C "%SRC%" rev-parse HEAD 2^>nul') do set "COMMIT=%%H" if "%COMMIT%"=="" set "COMMIT=N/A" set "README=%DEST_PREFIX%\\README.md" > "%README%" echo # Playbook(裁剪快照) >> "%README%" echo. >> "%README%" echo 本目录为从 Playbook vendoring 的裁剪快照(langs: %LANGS_CSV%)。 >> "%README%" echo. >> "%README%" echo ## 使用 >> "%README%" echo. >> "%README%" echo 在目标项目根目录执行(多语言一次同步): >> "%README%" echo. >> "%README%" echo ```sh >> "%README%" echo sh docs/standards/playbook/scripts/sync_standards.sh %LANGS_CSV% >> "%README%" echo ``` >> "%README%" echo. >> "%README%" echo 查看规范入口: >> "%README%" echo. >> "%README%" echo - `docs/standards/playbook/docs/index.md` >> "%README%" echo - `.agents/index.md` >> "%README%" echo. >> "%README%" echo ## Codex skills(可选) >> "%README%" echo. >> "%README%" echo 安装到本机(需要先在 `~/.codex/config.toml` 启用 skills;见 `docs/standards/playbook/SKILLS.md`): >> "%README%" echo. >> "%README%" echo ```sh >> "%README%" echo sh docs/standards/playbook/scripts/install_codex_skills.sh >> "%README%" echo ``` >> "%README%" echo. >> "%README%" echo ## CI templates(可选) >> "%README%" echo. >> "%README%" echo 目标项目可复制启用的 CI 示例模板(如 Gitea Actions):`templates/ci/`。 set "SOURCE=%DEST_PREFIX%\\SOURCE.md" > "%SOURCE%" echo # SOURCE >> "%SOURCE%" echo. >> "%SOURCE%" echo - Source: %SRC% >> "%SOURCE%" echo - Commit: %COMMIT% >> "%SOURCE%" echo - Date: %DATE% %TIME% >> "%SOURCE%" echo - Langs: %LANGS_CSV% >> "%SOURCE%" echo - Generated-by: scripts/vendor_playbook.bat echo Vendored snapshot -^> %DEST_PREFIX% set "PROJECT_AGENTS_ROOT=%DEST_ROOT_ABS%\\.agents" set "PROJECT_AGENTS_INDEX=%PROJECT_AGENTS_ROOT%\\index.md" if not exist "%PROJECT_AGENTS_ROOT%" mkdir "%PROJECT_AGENTS_ROOT%" if not exist "%PROJECT_AGENTS_INDEX%" ( > "%PROJECT_AGENTS_INDEX%" echo # .agents(多语言) >> "%PROJECT_AGENTS_INDEX%" echo. >> "%PROJECT_AGENTS_INDEX%" echo 本目录用于存放仓库级/语言级的代理规则集。 >> "%PROJECT_AGENTS_INDEX%" echo. >> "%PROJECT_AGENTS_INDEX%" echo 本项目已启用的规则集: for %%L in (%LANGS%) do ( if /I "%%~L"=="tsl" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/tsl/:TSL 相关规则集(适用于 .tsl/.tsf) if /I "%%~L"=="cpp" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/cpp/:C++ 相关规则集(C++23,含 Modules) if /I "%%~L"=="python" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/python/:Python 相关规则集 if /I "%%~L"=="markdown" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/markdown/:Markdown 相关规则集(仅代码格式化) ) >> "%PROJECT_AGENTS_INDEX%" echo. >> "%PROJECT_AGENTS_INDEX%" echo 入口建议从: for %%L in (%LANGS%) do >> "%PROJECT_AGENTS_INDEX%" echo - .agents/%%~L/index.md >> "%PROJECT_AGENTS_INDEX%" echo. >> "%PROJECT_AGENTS_INDEX%" echo 标准快照文档入口: >> "%PROJECT_AGENTS_INDEX%" echo. >> "%PROJECT_AGENTS_INDEX%" echo - docs/standards/playbook/docs/index.md ) set "OLD_SYNC_ROOT=%SYNC_ROOT%" set "SYNC_ROOT=%DEST_ROOT_ABS%" pushd "%DEST_ROOT_ABS%" call "%DEST_PREFIX%\\scripts\\sync_standards.bat" %LANGS% popd set "SYNC_ROOT=%OLD_SYNC_ROOT%" rem Apply templates to project root if requested if "%APPLY_TEMPLATES%"=="1" ( echo. echo Applying templates to project root... rem Apply CI templates ^(Gitea workflows^) set "CI_SRC=%DEST_PREFIX%\templates\ci\gitea\.gitea" if exist "!CI_SRC!" ( if exist "%DEST_ROOT_ABS%\.gitea" ( echo Skip ^(exists^): .gitea\ ) else ( xcopy "!CI_SRC!\*" "%DEST_ROOT_ABS%\.gitea\" /e /i /y >nul 2>nul echo Applied: .gitea\ ) ) rem Apply lang-specific templates for %%L in (%LANGS%) do ( set "LANG_SRC=%DEST_PREFIX%\templates\%%~L" if exist "!LANG_SRC!" ( if /I "%%~L"=="cpp" ( call :CopyIfNotExists "!LANG_SRC!\.clang-format" "%DEST_ROOT_ABS%\.clang-format" call :CopyIfNotExists "!LANG_SRC!\.clangd" "%DEST_ROOT_ABS%\.clangd" call :CopyIfNotExists "!LANG_SRC!\CMakeLists.txt" "%DEST_ROOT_ABS%\CMakeLists.txt" call :CopyIfNotExists "!LANG_SRC!\CMakeUserPresets.json" "%DEST_ROOT_ABS%\CMakeUserPresets.json" call :CopyIfNotExists "!LANG_SRC!\conanfile.txt" "%DEST_ROOT_ABS%\conanfile.txt" if exist "!LANG_SRC!\conan" ( if exist "%DEST_ROOT_ABS%\conan" ( echo Skip ^(exists^): conan\ ) else ( xcopy "!LANG_SRC!\conan\*" "%DEST_ROOT_ABS%\conan\" /e /i /y >nul 2>nul echo Applied: conan\ ) ) ) if /I "%%~L"=="python" ( call :CopyIfNotExists "!LANG_SRC!\.editorconfig" "%DEST_ROOT_ABS%\.editorconfig" call :CopyIfNotExists "!LANG_SRC!\.flake8" "%DEST_ROOT_ABS%\.flake8" call :CopyIfNotExists "!LANG_SRC!\.pre-commit-config.yaml" "%DEST_ROOT_ABS%\.pre-commit-config.yaml" call :CopyIfNotExists "!LANG_SRC!\.pylintrc" "%DEST_ROOT_ABS%\.pylintrc" call :CopyIfNotExists "!LANG_SRC!\pyproject.toml" "%DEST_ROOT_ABS%\pyproject.toml" if exist "!LANG_SRC!\.vscode" ( if exist "%DEST_ROOT_ABS%\.vscode" ( echo Skip ^(exists^): .vscode\ ) else ( xcopy "!LANG_SRC!\.vscode\*" "%DEST_ROOT_ABS%\.vscode\" /e /i /y >nul 2>nul echo Applied: .vscode\ ) ) ) ) ) echo Templates applied. ) echo Done. endlocal exit /b 0 :AppendDocsSection set "LANG=%~1" if /I "%LANG%"=="tsl" ( >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo ## TSL(tsl) >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo - 代码风格:`tsl/code_style.md` >> "%DOC_INDEX%" echo - 命名规范:`tsl/naming.md` >> "%DOC_INDEX%" echo - 语法手册:`tsl/syntax_book/index.md` >> "%DOC_INDEX%" echo - 工具链与验证命令(模板):`tsl/toolchain.md` ) if /I "%LANG%"=="cpp" ( >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo ## C++(cpp) >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo - 代码风格:`cpp/code_style.md` >> "%DOC_INDEX%" echo - 命名规范:`cpp/naming.md` >> "%DOC_INDEX%" echo - 工具链与验证命令(模板):`cpp/toolchain.md` >> "%DOC_INDEX%" echo - 第三方依赖(Conan):`cpp/dependencies_conan.md` >> "%DOC_INDEX%" echo - clangd 配置:`cpp/clangd.md` ) if /I "%LANG%"=="python" ( >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo ## Python(python) >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo - 代码风格:`python/style_guide.md` >> "%DOC_INDEX%" echo - 工具链:`python/tooling.md` >> "%DOC_INDEX%" echo - 配置清单:`python/configuration.md` ) if /I "%LANG%"=="markdown" ( >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo ## Markdown(markdown) >> "%DOC_INDEX%" echo. >> "%DOC_INDEX%" echo - 代码块与行内代码格式:`markdown/index.md` ) exit /b 0 :CopyIfNotExists set "SRC_FILE=%~1" set "DST_FILE=%~2" if exist "%SRC_FILE%" ( if exist "%DST_FILE%" ( for %%F in ("%DST_FILE%") do echo Skip ^(exists^): %%~nxF ) else ( copy /y "%SRC_FILE%" "%DST_FILE%" >nul for %%F in ("%DST_FILE%") do echo Applied: %%~nxF ) ) exit /b 0 :Usage echo Usage: echo scripts\vendor_playbook.bat ^ ^(default: tsl^) echo scripts\vendor_playbook.bat ^ tsl cpp echo scripts\vendor_playbook.bat ^ --langs tsl,cpp echo scripts\vendor_playbook.bat ^ tsl cpp --apply-templates echo. echo Options: echo --apply-templates Apply CI/lang templates to project root ^(skip if exists^) exit /b 1