playbook/scripts/sync_templates.bat

234 lines
7.8 KiB
Batchfile

@echo off
setlocal enabledelayedexpansion
rem Sync project templates to target project.
rem - Copies templates/memory-bank/ -> <project-root>/memory-bank/
rem - Copies templates/prompts/ -> <project-root>/docs/prompts/
rem - Copies templates/AGENTS.template.md -> <project-root>/AGENTS.md
rem - Copies templates/AGENT_RULES.template.md -> <project-root>/AGENT_RULES.md
rem Existing targets are NOT overwritten (skip if exists).
rem
rem Usage:
rem sync_templates.bat # sync to current git root
rem sync_templates.bat -project-root <path> # sync to specified project
rem sync_templates.bat -force # overwrite existing files
rem sync_templates.bat -full # append full framework to existing AGENTS.md
set "SCRIPT_DIR=%~dp0"
for %%I in ("%SCRIPT_DIR%..") do set "SRC=%%~fI"
set "FORCE=0"
set "FULL=0"
set "PROJECT_ROOT="
:parse_args
if "%~1"=="" goto args_done
if /I "%~1"=="-force" (
set "FORCE=1"
shift
goto parse_args
)
if /I "%~1"=="-full" (
set "FULL=1"
shift
goto parse_args
)
if /I "%~1"=="-project-root" (
if "%~2"=="" (
echo ERROR: -project-root requires a path.
exit /b 1
)
set "PROJECT_ROOT=%~2"
shift
shift
goto parse_args
)
if /I "%~1"=="-h" goto show_help
if /I "%~1"=="-help" goto show_help
echo ERROR: positional args are not supported. Use -project-root.
exit /b 1
:show_help
echo Usage:
echo sync_templates.bat [options]
echo sync_templates.bat -project-root ^<path^>
echo.
echo Options:
echo -project-root PATH Target project root ^(default: git root^)
echo -force Overwrite existing files
echo -full Append full framework (规则优先级 + 新会话开始时) to existing AGENTS.md
echo -h, -help Show this help
exit /b 0
:args_done
rem Determine project root
if "%PROJECT_ROOT%"=="" (
for /f "delims=" %%R in ('git -C "%SCRIPT_DIR%" rev-parse --show-toplevel 2^>nul') do set "PROJECT_ROOT=%%R"
)
if "%PROJECT_ROOT%"=="" set "PROJECT_ROOT=%cd%"
for %%I in ("%PROJECT_ROOT%") do set "PROJECT_ROOT=%%~fI"
rem Source directories
set "TEMPLATES_DIR=%SRC%\templates"
set "MEMORY_BANK_SRC=%TEMPLATES_DIR%\memory-bank"
set "PROMPTS_SRC=%TEMPLATES_DIR%\prompts"
set "AGENTS_SRC=%TEMPLATES_DIR%\AGENTS.template.md"
set "AGENT_RULES_SRC=%TEMPLATES_DIR%\AGENT_RULES.template.md"
rem Check source exists
if not exist "%TEMPLATES_DIR%" (
echo ERROR: Templates directory not found: %TEMPLATES_DIR%
exit /b 1
)
rem Skip if source equals destination
if /I "%SRC%"=="%PROJECT_ROOT%" (
echo Skip: playbook root equals project root.
echo Done.
exit /b 0
)
for /f "usebackq delims=" %%D in (`powershell -NoProfile -Command "Get-Date -Format 'yyyy-MM-dd'"`) do set "SYNC_DATE=%%D"
if "%SYNC_DATE%"=="" set "SYNC_DATE=%date%"
echo Syncing templates to: %PROJECT_ROOT%
echo.
rem 1. Sync memory-bank/
set "MEMORY_BANK_DST=%PROJECT_ROOT%\memory-bank"
if exist "%MEMORY_BANK_SRC%" (
if exist "%MEMORY_BANK_DST%" (
if "%FORCE%"=="0" (
echo memory-bank/ already exists. Skip. Use -force to overwrite.
goto sync_prompts
)
)
if not exist "%MEMORY_BANK_DST%" mkdir "%MEMORY_BANK_DST%"
xcopy "%MEMORY_BANK_SRC%\*" "%MEMORY_BANK_DST%\" /e /i /y >nul 2>nul
rem Rename .template.md to .md
for %%F in ("%MEMORY_BANK_DST%\*.template.md") do (
set "OLDNAME=%%~nxF"
set "NEWNAME=!OLDNAME:.template.md=.md!"
ren "%%F" "!NEWNAME!"
)
rem Replace {{DATE}} placeholder
for %%F in ("%MEMORY_BANK_DST%\*.md") do (
powershell -NoProfile -Command "$f='%%~fF'; $c=Get-Content -Raw $f; $c=$c.Replace('{{DATE}}','%SYNC_DATE%'); Set-Content -Path $f -Value $c -Encoding UTF8 -NoNewline"
)
echo Synced: memory-bank/
) else (
echo Skip: memory-bank/ templates not found
)
:sync_prompts
rem 2. Sync docs/prompts/
set "PROMPTS_DST=%PROJECT_ROOT%\docs\prompts"
if exist "%PROMPTS_SRC%" (
if exist "%PROMPTS_DST%" (
if "%FORCE%"=="0" (
echo docs/prompts/ already exists. Skip. Use -force to overwrite.
goto sync_agents
)
)
if not exist "%PROJECT_ROOT%\docs" mkdir "%PROJECT_ROOT%\docs"
if not exist "%PROMPTS_DST%" mkdir "%PROMPTS_DST%"
xcopy "%PROMPTS_SRC%\*" "%PROMPTS_DST%\" /e /i /y >nul 2>nul
rem Rename .template.md to .md recursively
for /r "%PROMPTS_DST%" %%F in (*.template.md) do (
set "OLDNAME=%%~nxF"
set "NEWNAME=!OLDNAME:.template.md=.md!"
ren "%%F" "!NEWNAME!"
)
rem Replace {{DATE}} placeholder
for /r "%PROMPTS_DST%" %%F in (*.md) do (
powershell -NoProfile -Command "$f='%%~fF'; $c=Get-Content -Raw $f; $c=$c.Replace('{{DATE}}','%SYNC_DATE%'); Set-Content -Path $f -Value $c -Encoding UTF8 -NoNewline"
)
echo Synced: docs/prompts/
) else (
echo Skip: prompts/ templates not found
)
:sync_agents
rem 3. Sync AGENTS.md
set "AGENTS_DST=%PROJECT_ROOT%\AGENTS.md"
rem Choose markers based on -full flag
if "%FULL%"=="1" (
set "MARKER_START=<!-- playbook:framework:start -->"
set "MARKER_END=<!-- playbook:framework:end -->"
set "SECTION_NAME=framework"
) else (
set "MARKER_START=<!-- playbook:templates:start -->"
set "MARKER_END=<!-- playbook:templates:end -->"
set "SECTION_NAME=templates"
)
if exist "%AGENTS_SRC%" (
if not exist "%AGENTS_DST%" (
rem AGENTS.md doesn't exist: create from full template
copy /y "%AGENTS_SRC%" "%AGENTS_DST%" >nul
powershell -NoProfile -Command "$f='%AGENTS_DST%'; $c=Get-Content -Raw $f; $c=$c.Replace('{{DATE}}','%SYNC_DATE%'); Set-Content -Path $f -Value $c -Encoding UTF8 -NoNewline"
echo Created: AGENTS.md
) else (
rem AGENTS.md exists: update or append section (extract from template)
powershell -NoProfile -Command ^
"$src='%AGENTS_SRC%'; $dst='%AGENTS_DST%'; $date='%SYNC_DATE%'; " ^
"$markerStart='!MARKER_START!'; $markerEnd='!MARKER_END!'; $sectionName='!SECTION_NAME!'; " ^
"$templateContent = Get-Content -Raw $src; " ^
"$extractPattern = '(?s)(' + [regex]::Escape($markerStart) + '.*?' + [regex]::Escape($markerEnd) + ')'; " ^
"if ($templateContent -match $extractPattern) { " ^
" $snippetContent = $Matches[1]; " ^
" $content = Get-Content -Raw $dst; " ^
" if ($content -match [regex]::Escape($markerStart)) { " ^
" $replacePattern = '(?s)' + [regex]::Escape($markerStart) + '.*?' + [regex]::Escape($markerEnd); " ^
" $newContent = $content -replace $replacePattern, $snippetContent; " ^
" $newContent = $newContent.Replace('{{DATE}}', $date); " ^
" Set-Content -Path $dst -Value $newContent -Encoding UTF8 -NoNewline; " ^
" Write-Host \"Updated: AGENTS.md ($sectionName section)\"; " ^
" } else { " ^
" $newContent = $content.TrimEnd() + \"`n`n\" + $snippetContent; " ^
" $newContent = $newContent.Replace('{{DATE}}', $date); " ^
" Set-Content -Path $dst -Value $newContent -Encoding UTF8 -NoNewline; " ^
" Write-Host \"Appended: AGENTS.md ($sectionName section)\"; " ^
" } " ^
"} else { " ^
" Write-Host 'Skip: markers not found in template'; " ^
"}"
)
) else (
echo Skip: AGENTS.template.md not found
)
:sync_agent_rules
rem 4. Sync AGENT_RULES.md
set "AGENT_RULES_DST=%PROJECT_ROOT%\AGENT_RULES.md"
if exist "%AGENT_RULES_SRC%" (
if exist "%AGENT_RULES_DST%" (
if "%FORCE%"=="0" (
echo AGENT_RULES.md already exists. Skip. Use -force to overwrite.
goto sync_done
)
)
copy /y "%AGENT_RULES_SRC%" "%AGENT_RULES_DST%" >nul
powershell -NoProfile -Command "$f='%AGENT_RULES_DST%'; $c=Get-Content -Raw $f; $c=$c.Replace('{{DATE}}','%SYNC_DATE%'); Set-Content -Path $f -Value $c -Encoding UTF8 -NoNewline"
echo Synced: AGENT_RULES.md
) else (
echo Skip: AGENT_RULES.template.md not found
)
:sync_done
echo.
echo Done.
echo.
echo Next steps:
echo 1. Edit memory-bank\*.md to fill in project-specific content
echo 2. Replace remaining {{PLACEHOLDER}} values
echo 3. Run sync_standards.bat to sync .agents\ rules
endlocal