diff --git a/.agents/code_quality.md b/.agents/code_quality.md index fed30c9..fc3b180 100644 --- a/.agents/code_quality.md +++ b/.agents/code_quality.md @@ -4,7 +4,7 @@ ## 1. 总体要求 -- 遵守 `docs/code_style.md` 与 `docs/naming.md`。 +- 遵守本标准快照中的 `docs/tsl/code_style.md` 与 `docs/tsl/naming.md`(通常位于目标项目的 `docs/standards/tsl/docs/tsl/`)。 - 改动聚焦目标;避免“顺手重构”。 - API 变更要显式说明影响与迁移方式。 diff --git a/.agents/index.md b/.agents/index.md index 1d6a0b3..ddeb09a 100644 --- a/.agents/index.md +++ b/.agents/index.md @@ -1,15 +1,21 @@ -# .agents 指南索引 +# TSL Playbook 代理规则集(.agents/tsl) + +本规则集用于存放 **AI/自动化代理在仓库内工作时必须遵守的规则**。 + +在多语言项目中,推荐将本规则集放在目标项目的 `.agents/tsl/` 下(由 `scripts/sync_standards.*` 同步),并与其他语言规则集并行: + +- `.agents/tsl/`:TSL 标准规则集(本仓库提供) +- `.agents/cpp/`、`.agents/python/` 等:其他语言规则集(按需新增) -本目录用于存放 **AI/自动化代理在本仓库内工作时必须遵守的规则**。 这些规则与 `docs/` 下的人类开发规范并行: - `docs/`:给人看的编码/命名/提交规范 - `.agents/`:给代理看的任务边界、质量与安全要求 -## 范围 +## 范围与优先级 -- 适用于本仓库所有目录与文件,除非子目录另有更具体的 `.agents/*.md` 覆盖说明。 -- 当 `.agents` 与 `docs` 发生冲突时: +- 作为仓库级基线规则集使用;更靠近代码目录的规则应更具体并可覆盖基线。 +- 当代理规则与 `docs` 发生冲突时: 1. 安全/合规优先 2. 其次保持仓库现有一致性 @@ -27,8 +33,19 @@ - 代码质量:`code_quality.md` - 测试:`testing.md` +## 分类(本仓库现状) + +当前本规则集下的文件全部为 **跨语言通用规则**(不绑定具体语言语法/工具链): + +- `auth.md`:敏感信息/鉴权边界 +- `code_quality.md`:质量底线与 review 清单 +- `performance.md`:性能原则与验证 +- `testing.md`:测试策略 + +若需要 TSL/C++ 等语言专属的代理要求,建议在目标项目新增对应目录(例如 `.agents/tsl/`、`.agents/cpp/`)或在源码子目录放置更具体的 `.agents` 覆盖规则。 + ## 与开发规范的关系 -- 代码风格:`docs/code_style.md` -- 命名规范:`docs/naming.md` -- 提交信息:`docs/commit_message.md` +- 代码风格:标准快照 `docs/tsl/code_style.md`(通常位于目标项目 `docs/standards/tsl/docs/tsl/code_style.md`) +- 命名规范:标准快照 `docs/tsl/naming.md`(通常位于目标项目 `docs/standards/tsl/docs/tsl/naming.md`) +- 提交信息:标准快照 `docs/common/commit_message.md`(通常位于目标项目 `docs/standards/tsl/docs/common/commit_message.md`) diff --git a/README.md b/README.md index d8b911a..7a2ead2 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,10 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则 `docs/` 目录是给开发者阅读的工程规范,约束代码写法、命名与提交信息。 -- `docs/code_style.md`:代码结构、格式、`begin/end` 代码块、注释与通用最佳实践。 -- `docs/naming.md`:TSL 命名规范(顶层声明、文件同名规则、变量/成员/property、常量、集合命名等)。 -- `docs/commit_message.md`:提交信息与版本号规范(type/scope/subject/body/footer、可选 Emoji 图例、SemVer)。 +- `docs/index.md`:文档导航(跨语言 common / TSL 专属)。 +- `docs/common/commit_message.md`:提交信息与版本号规范(type/scope/subject/body/footer、可选 Emoji 图例、SemVer)。 +- `docs/tsl/code_style.md`:TSL 代码结构、格式、`begin/end` 代码块、注释与通用最佳实践。 +- `docs/tsl/naming.md`:TSL 命名规范(顶层声明、文件同名规则、变量/成员/property、常量、集合命名等)。 ## .agents/(代理规则) @@ -47,7 +48,7 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则 ```bash git subtree add \ - --prefix docs/standards/tsl_playbook \ + --prefix docs/standards/tsl \ https://git.mytsl.cn/csh/tsl-playbook.git \ main --squash ``` @@ -56,7 +57,7 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则 ```bash git subtree pull \ - --prefix docs/standards/tsl_playbook \ + --prefix docs/standards/tsl \ https://git.mytsl.cn/csh/tsl-playbook.git \ main --squash ``` @@ -66,27 +67,33 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则 目标项目推荐采用以下结构(Playbook 快照与项目文档分离): ```txt - .agents/ # 从 Playbook 同步后可按项目微调 - .gitattributes # 从 Playbook 同步 - docs/ - standards/ - tsl_playbook/ # git subtree 快照(只读) - docs/ # code_style.md / naming.md / commit_message.md - .agents/ # 标准代理规则快照 - .gitattributes - SOURCE.md # 记录来源版本/commit(项目自行维护) - project/ # 目标项目自己的文档 - README.md # 说明遵循 standards + . + ├── .agents/ + │ ├── index.md # 多语言代理规则集索引(缺省时由脚本创建) + │ └── tsl/ # 从 Playbook 同步(仅覆盖该子目录) + ├── .gitattributes # 从 Playbook 同步 + ├── docs/ + │ ├── standards/ + │ │ └── tsl/ # git subtree 快照(只读) + │ │ ├── docs/ # common/ + tsl/ + │ │ ├── .agents/ # 标准代理规则快照 + │ │ ├── .gitattributes + │ │ └── SOURCE.md # 记录来源版本/commit(项目自行维护) + │ └── project/ # 目标项目自己的文档 + └── README.md # 说明遵循 standards ``` - 根目录的 `.agents/` 与 `.gitattributes` 通过同步脚本获得: + 根目录的 `.agents/tsl/` 与 `.gitattributes` 通过同步脚本获得: - 直接运行 Playbook 提供的脚本(子树快照里自带): - - `docs/standards/tsl_playbook/scripts/sync_playbook.sh` - - `docs/standards/tsl_playbook/scripts/sync_playbook.ps1` - - `docs/standards/tsl_playbook/scripts/sync_playbook.bat` + - `docs/standards/tsl/scripts/sync_standards.sh`(推荐) + - `docs/standards/tsl/scripts/sync_standards.ps1`(推荐) + - `docs/standards/tsl/scripts/sync_standards.bat`(推荐) - 脚本会从快照目录同步到项目根目录,并先备份旧文件(`.bak.*`)。 + 注:`docs/standards/tsl/` 只是推荐目录名;你可以用任意 `--prefix`(例如 `docs/standards/tsl_playbook/`)。同步脚本会从脚本自身路径推导快照根目录,不再依赖目录名。 + 注:默认同步到 `.agents/tsl/`;如需指定规则集名称,可通过环境变量 `AGENTS_NS`(例如 `AGENTS_NS=tsl`、`AGENTS_NS=common`)。 + 这样 clone 任意项目时都能直接读取规范文件,不依赖外部访问权限。 ### 方式二:手动复制快照 @@ -95,17 +102,86 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则 步骤: -1. 在目标项目创建目录:`docs/standards/tsl_playbook/`。 +1. 在目标项目创建目录:`docs/standards/tsl/`。 2. 从本仓库复制以下内容到目标项目: - - `docs/` → `docs/standards/tsl_playbook/docs/` - - `.agents/` → `docs/standards/tsl_playbook/.agents/` - - `.gitattributes` → `docs/standards/tsl_playbook/.gitattributes` - - `scripts/` → `docs/standards/tsl_playbook/scripts/` -3. 在目标项目根目录运行同步脚本,把 `.agents/` 与 `.gitattributes` 落到根目录(见上文脚本路径)。 -4. 在 `docs/standards/tsl_playbook/SOURCE.md` 记录本次复制的来源版本/日期(建议写 Playbook 的 commit hash)。 + - `docs/` → `docs/standards/tsl/docs/`(包含 `docs/common/` 与 `docs/tsl/`) + - `.agents/` → `docs/standards/tsl/.agents/` + - `.gitattributes` → `docs/standards/tsl/.gitattributes` + - `scripts/` → `docs/standards/tsl/scripts/` +3. 在目标项目根目录运行同步脚本,把 `.agents/tsl/` 与 `.gitattributes` 落到根目录(见上文脚本路径)。 +4. 在 `docs/standards/tsl/SOURCE.md` 记录本次复制的来源版本/日期(建议写 Playbook 的 commit hash)。 该方式没有自动同步能力,后续更新需重复上述复制流程。 +### 多语言项目落地(TSL + C++/其他语言) + +多语言项目建议把规范拆成两类: + +1. **仓库级(跨语言)共识**:对所有语言都成立的规则与流程。 + - 提交信息:`docs/common/commit_message.md` + - 行尾与文本规范:`.gitattributes` + - 代理最低要求:`.agents/*`(工作原则、质量底线、安全边界) +2. **语言级(Language-specific)规范**:只对某个语言成立的风格与工具。 + - 例如 TSL 的命名/文件顶层声明限制、C++ 的 `.clang-format/.clang-tidy`、Python 的 `ruff` 等。 + +建议:仓库级规则尽量少且稳定;语言级规则各自独立,避免互相“污染”。 + +本仓库提供的代理规则集(同步后位于目标项目的 `.agents/tsl/`)当前全部为**跨语言通用规则**: + +- `auth.md`:敏感信息/鉴权边界 +- `code_quality.md`:质量底线与 review 清单 +- `performance.md`:性能原则与验证 +- `testing.md`:测试策略 + +#### `.agents` 的覆盖/合并策略(可执行流程) + +同步脚本会同步到项目根目录的 `.agents/tsl/`(并不会覆盖 `.agents/` 下的其他语言目录)。若项目需要追加 C++ 等语言/模块专属规则,建议二选一: + +1. **推荐:子目录规则覆盖(无需改同步脚本)** + - 让本 Playbook 的规则集固定落在 `.agents/tsl/`,由同步脚本维护。 + - 在其他语言/模块目录下新增更具体规则,例如 `.agents/cpp/`、`cpp/.agents/`、`src/.agents/`。 +2. **Overlay 合并:项目维护叠加层并在同步后覆盖回去** + - 约定项目自定义规则放在 `docs/project/agents_overlay/`(不叫 `.agents`,避免被同步覆盖)。 + - 每次运行 `sync_standards.*` 后,再把 overlay 覆盖回 `.agents/tsl/`(建议封装成项目脚本)。 + +macOS/Linux 示例(目标项目的 `scripts/sync_standards.sh`): + +```sh +#!/usr/bin/env sh +set -eu + +sh docs/standards/tsl/scripts/sync_standards.sh + +OVERLAY="docs/project/agents_overlay" +if [ -d "$OVERLAY" ]; then + cp -R "$OVERLAY"/. ".agents/tsl/" + echo "Applied agents overlay." +fi +``` + +PowerShell 示例(目标项目的 `scripts/sync_standards.ps1`): + +```powershell +$ErrorActionPreference = "Stop" + +& "docs/standards/tsl/scripts/sync_standards.ps1" + +$overlay = "docs/project/agents_overlay" +if (Test-Path $overlay) { + Copy-Item "$overlay\\*" ".agents\\tsl" -Recurse -Force + Write-Host "Applied agents overlay." +} +``` + +#### 扩展新语言(模板) + +当目标项目需要新增一门语言(例如 C++),建议按以下模板扩展: + +- 文档:在目标项目增加 `docs/standards/cpp/docs/`(或另一个标准仓库 subtree),并在项目 `README.md`/`docs/index.md` 链接入口。 +- 代理规则:在目标项目增加 `.agents/cpp/`(与 `.agents/tsl/` 并行),只写 C++ 专属要求与工具链约束。 +- 同步策略:每个规则集只同步到对应子目录(例如 `.agents/cpp/`),避免覆盖整个 `.agents/`。 +- CI/工具:按文件类型分别执行格式化、lint、测试(不要让 TSL 规则去约束 C++ 代码,反之亦然)。 + ## 版本与贡献 - 本项目会持续迭代;变更以 PR 形式提交。 diff --git a/docs/commit_message.md b/docs/common/commit_message.md similarity index 100% rename from docs/commit_message.md rename to docs/common/commit_message.md diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..dccaf2c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,13 @@ +# 文档导航(Docs Index) + +本仓库文档按“跨语言共识 / 语言专属”分层组织,便于在多语言项目中扩展与复用。 + +## 跨语言(common) + +- 提交信息与版本号:`common/commit_message.md` + +## TSL(tsl) + +- 代码风格:`tsl/code_style.md` +- 命名规范:`tsl/naming.md` + diff --git a/docs/code_style.md b/docs/tsl/code_style.md similarity index 99% rename from docs/code_style.md rename to docs/tsl/code_style.md index f9d0836..674ad4e 100644 --- a/docs/code_style.md +++ b/docs/tsl/code_style.md @@ -1,4 +1,4 @@ -# 代码风格(Code Style) +# TSL 代码风格(Code Style) 本章节规定 TSL 代码的结构与格式约定。 diff --git a/docs/naming.md b/docs/tsl/naming.md similarity index 99% rename from docs/naming.md rename to docs/tsl/naming.md index bcb8b88..4a12df8 100644 --- a/docs/naming.md +++ b/docs/tsl/naming.md @@ -1,4 +1,4 @@ -# 命名规范(Naming) +# TSL 命名规范(Naming) 本仓库命名规则与 Google C++ Style Guide 对齐:通过名字的“形状”快速判断实体类型(类型/函数/变量/常量等),减少阅读成本。 diff --git a/scripts/sync_playbook.bat b/scripts/sync_playbook.bat deleted file mode 100644 index 5a0698b..0000000 --- a/scripts/sync_playbook.bat +++ /dev/null @@ -1,51 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -rem Sync TSL Playbook snapshot to project root. -rem - Copies docs\standards\tsl_playbook\.agents -> .agents -rem - Copies docs\standards\tsl_playbook\.gitattributes -> .gitattributes -rem Existing targets are backed up before overwrite. - -for /f "delims=" %%R in ('git rev-parse --show-toplevel 2^>nul') do set "ROOT=%%R" -if "%ROOT%"=="" set "ROOT=%cd%" - -set "SRC=%ROOT%\docs\standards\tsl_playbook" -set "AGENTS_SRC=%SRC%\.agents" -set "GITATTR_SRC=%SRC%\.gitattributes" -set "AGENTS_DST=%ROOT%\.agents" -set "GITATTR_DST=%ROOT%\.gitattributes" - -if not exist "%AGENTS_SRC%" ( - echo ERROR: Playbook snapshot not found at "%AGENTS_SRC%". - echo Run: git subtree add --prefix docs/standards/tsl_playbook ^ main --squash - exit /b 1 -) - -if exist "%AGENTS_DST%" ( - set "RAND=%RANDOM%" - set "BAK_NAME=.agents.bak.!RAND!" - ren "%AGENTS_DST%" "!BAK_NAME!" - echo Backed up existing .agents -> !BAK_NAME! -) - -xcopy "%AGENTS_SRC%" "%AGENTS_DST%\" /e /i /y >nul -if errorlevel 1 ( - echo ERROR: failed to copy .agents - exit /b 1 -) - -echo Synced .agents from Playbook. - -if exist "%GITATTR_SRC%" ( - if exist "%GITATTR_DST%" ( - set "RAND=%RANDOM%" - set "BAK_NAME=.gitattributes.bak.!RAND!" - ren "%GITATTR_DST%" "!BAK_NAME!" - echo Backed up existing .gitattributes -> !BAK_NAME! - ) - copy /y "%GITATTR_SRC%" "%GITATTR_DST%" >nul - echo Synced .gitattributes from Playbook. -) - -echo Done. -endlocal diff --git a/scripts/sync_playbook.ps1 b/scripts/sync_playbook.ps1 deleted file mode 100644 index 9073319..0000000 --- a/scripts/sync_playbook.ps1 +++ /dev/null @@ -1,41 +0,0 @@ -# Sync TSL Playbook snapshot to project root. -# - Copies docs/standards/tsl_playbook/.agents -> .agents -# - Copies docs/standards/tsl_playbook/.gitattributes -> .gitattributes -# Existing targets are backed up before overwrite. - -$ErrorActionPreference = "Stop" - -$Root = (git rev-parse --show-toplevel 2>$null) -if (-not $Root) { $Root = (Get-Location).Path } - -$Src = Join-Path $Root "docs/standards/tsl_playbook" -$AgentsSrc = Join-Path $Src ".agents" -$GitAttrSrc = Join-Path $Src ".gitattributes" - -if (-not (Test-Path $AgentsSrc)) { - throw "Playbook snapshot not found at $AgentsSrc. Run git subtree add first." -} - -$timestamp = Get-Date -Format "yyyyMMddHHmmss" - -$AgentsDst = Join-Path $Root ".agents" -if (Test-Path $AgentsDst) { - $bak = "$AgentsDst.bak.$timestamp" - Move-Item $AgentsDst $bak - Write-Host "Backed up existing .agents -> $bak" -} -Copy-Item $AgentsSrc $AgentsDst -Recurse -Force -Write-Host "Synced .agents from Playbook." - -$GitAttrDst = Join-Path $Root ".gitattributes" -if (Test-Path $GitAttrSrc) { - if (Test-Path $GitAttrDst) { - $bak = "$GitAttrDst.bak.$timestamp" - Move-Item $GitAttrDst $bak - Write-Host "Backed up existing .gitattributes -> $bak" - } - Copy-Item $GitAttrSrc $GitAttrDst -Force - Write-Host "Synced .gitattributes from Playbook." -} - -Write-Host "Done." diff --git a/scripts/sync_playbook.sh b/scripts/sync_playbook.sh deleted file mode 100644 index f356392..0000000 --- a/scripts/sync_playbook.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env sh -set -eu - -# Sync TSL Playbook snapshot to project root. -# - Copies docs/standards/tsl_playbook/.agents -> .agents -# - Copies docs/standards/tsl_playbook/.gitattributes -> .gitattributes -# Existing targets are backed up before overwrite. - -ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" -SRC="$ROOT/docs/standards/tsl_playbook" -AGENTS_SRC="$SRC/.agents" -GITATTR_SRC="$SRC/.gitattributes" - -if [ ! -d "$AGENTS_SRC" ]; then - echo "ERROR: Playbook snapshot not found at $AGENTS_SRC" >&2 - echo "Run: git subtree add --prefix docs/standards/tsl_playbook main --squash" >&2 - exit 1 -fi - -timestamp="$(date +%Y%m%d%H%M%S 2>/dev/null || echo bak)" - -AGENTS_DST="$ROOT/.agents" -if [ -e "$AGENTS_DST" ]; then - mv "$AGENTS_DST" "$ROOT/.agents.bak.$timestamp" - echo "Backed up existing .agents -> .agents.bak.$timestamp" -fi -cp -R "$AGENTS_SRC" "$AGENTS_DST" - -echo "Synced .agents from Playbook." - -if [ -f "$GITATTR_SRC" ]; then - GITATTR_DST="$ROOT/.gitattributes" - if [ -e "$GITATTR_DST" ]; then - mv "$GITATTR_DST" "$ROOT/.gitattributes.bak.$timestamp" - echo "Backed up existing .gitattributes -> .gitattributes.bak.$timestamp" - fi - cp "$GITATTR_SRC" "$GITATTR_DST" - echo "Synced .gitattributes from Playbook." -fi - -echo "Done." diff --git a/scripts/sync_standards.bat b/scripts/sync_standards.bat new file mode 100644 index 0000000..7eb4eae --- /dev/null +++ b/scripts/sync_standards.bat @@ -0,0 +1,87 @@ +@echo off +setlocal enabledelayedexpansion + +rem Sync standards snapshot to project root. +rem - Copies \.agents -> \.agents\tsl +rem - Copies \.gitattributes -> \.gitattributes +rem Existing targets are backed up before overwrite. + +set "SCRIPT_DIR=%~dp0" +for /f "delims=" %%R in ('git -C "%SCRIPT_DIR%" rev-parse --show-toplevel 2^>nul') do set "ROOT=%%R" +if "%ROOT%"=="" set "ROOT=%cd%" +for %%I in ("%ROOT%") do set "ROOT=%%~fI" + +for %%I in ("%SCRIPT_DIR%..") do set "SRC=%%~fI" +set "AGENTS_SRC=%SRC%\.agents" +set "GITATTR_SRC=%SRC%\.gitattributes" +set "AGENTS_NS=%AGENTS_NS%" +if "%AGENTS_NS%"=="" set "AGENTS_NS=tsl" +set "AGENTS_ROOT=%ROOT%\.agents" +set "AGENTS_DST=%AGENTS_ROOT%\%AGENTS_NS%" +set "GITATTR_DST=%ROOT%\.gitattributes" + +if not exist "%AGENTS_SRC%" ( + echo ERROR: Standards snapshot not found at "%AGENTS_SRC%". + echo Run: git subtree add --prefix ^ ^ ^ --squash + exit /b 1 +) + +if /I "%SRC%"=="%ROOT%" ( + echo Skip: snapshot root equals project root. + goto AfterGitAttr +) + +if not exist "%AGENTS_ROOT%" mkdir "%AGENTS_ROOT%" + +if exist "%AGENTS_DST%" ( + set "RAND=%RANDOM%" + pushd "%AGENTS_ROOT%" + ren "%AGENTS_NS%" "%AGENTS_NS%.bak.!RAND!" + popd + echo Backed up existing %AGENTS_NS% agents -> %AGENTS_NS%.bak.!RAND! +) + +xcopy "%AGENTS_SRC%\\*" "%AGENTS_DST%\\" /e /i /y >nul +if errorlevel 1 ( + echo ERROR: failed to copy .agents + exit /b 1 +) + +echo Synced .agents\%AGENTS_NS% from standards. + +if not exist "%AGENTS_ROOT%\index.md" ( + > "%AGENTS_ROOT%\index.md" echo # .agents(多语言) + >> "%AGENTS_ROOT%\index.md" echo. + >> "%AGENTS_ROOT%\index.md" echo 本目录用于存放仓库级/语言级的代理规则集。 + >> "%AGENTS_ROOT%\index.md" echo. + >> "%AGENTS_ROOT%\index.md" echo 建议约定: + >> "%AGENTS_ROOT%\index.md" echo. + >> "%AGENTS_ROOT%\index.md" echo - `.agents/tsl/`:TSL 相关标准(由 `sync_standards.*` 同步) + >> "%AGENTS_ROOT%\index.md" echo - `.agents/cpp/`、`.agents/python/` 等:其他语言的规则集(按需增加) + >> "%AGENTS_ROOT%\index.md" echo. + >> "%AGENTS_ROOT%\index.md" echo 规则发生冲突时,建议以“更靠近代码的目录规则更具体”为准。 + echo Created .agents\index.md +) + +:SyncGitAttr +if exist "%GITATTR_SRC%" ( + for %%I in ("%GITATTR_SRC%") do set "GITATTR_SRC_F=%%~fI" + for %%I in ("%GITATTR_DST%") do set "GITATTR_DST_F=%%~fI" + if /I "!GITATTR_SRC_F!"=="!GITATTR_DST_F!" ( + echo Skip: .gitattributes source equals destination. + goto AfterGitAttr + ) + + if exist "%GITATTR_DST%" ( + set "RAND=%RANDOM%" + set "BAK_NAME=.gitattributes.bak.!RAND!" + ren "%GITATTR_DST%" "!BAK_NAME!" + echo Backed up existing .gitattributes -> !BAK_NAME! + ) + copy /y "%GITATTR_SRC%" "%GITATTR_DST%" >nul + echo Synced .gitattributes from standards. +) + +:AfterGitAttr +echo Done. +endlocal diff --git a/scripts/sync_standards.ps1 b/scripts/sync_standards.ps1 new file mode 100644 index 0000000..2aecefc --- /dev/null +++ b/scripts/sync_standards.ps1 @@ -0,0 +1,82 @@ +# Sync standards snapshot to project root. +# - Copies /.agents -> /.agents/tsl +# - Copies /.gitattributes -> /.gitattributes +# Existing targets are backed up before overwrite. +$ErrorActionPreference = "Stop" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$Src = (Resolve-Path (Join-Path $ScriptDir "..")).Path + +$Root = (git -C $ScriptDir rev-parse --show-toplevel 2>$null) +if (-not $Root) { $Root = (Get-Location).Path } +$Root = (Resolve-Path $Root).Path + +$AgentsSrc = Join-Path $Src ".agents" +$GitAttrSrc = Join-Path $Src ".gitattributes" + +if (-not (Test-Path $AgentsSrc)) { + throw "Standards snapshot not found at $AgentsSrc. Run git subtree add first (choose any prefix)." +} + +$timestamp = Get-Date -Format "yyyyMMddHHmmss" + +$AgentsNs = $env:AGENTS_NS +if (-not $AgentsNs) { $AgentsNs = "tsl" } +if ($AgentsNs -match '[\\/]' -or $AgentsNs -match '\.\.') { + throw "Invalid AGENTS_NS=$AgentsNs" +} +$AgentsRoot = Join-Path $Root ".agents" +$AgentsDst = Join-Path $AgentsRoot $AgentsNs + +if ($Src -ieq $Root) { + Write-Host "Skip: snapshot root equals project root." + Write-Host "Done." + exit 0 +} + +New-Item -ItemType Directory -Path $AgentsRoot -Force | Out-Null + +if (Test-Path $AgentsDst) { + $bak = (Join-Path $AgentsRoot "$AgentsNs.bak.$timestamp") + Move-Item $AgentsDst $bak + Write-Host "Backed up existing $AgentsNs agents -> $(Split-Path -Leaf $bak)" +} + +New-Item -ItemType Directory -Path $AgentsDst -Force | Out-Null +Copy-Item (Join-Path $AgentsSrc "*") $AgentsDst -Recurse -Force +Write-Host "Synced .agents/$AgentsNs from standards." + +$AgentsIndex = Join-Path $AgentsRoot "index.md" +if (-not (Test-Path $AgentsIndex)) { +@" +# .agents(多语言) + +本目录用于存放仓库级/语言级的代理规则集。 + +建议约定: + +- `.agents/tsl/`:TSL 相关标准(由 `sync_standards.*` 同步) +- `.agents/cpp/`、`.agents/python/` 等:其他语言的规则集(按需增加) + +规则发生冲突时,建议以“更靠近代码的目录规则更具体”为准。 +"@ | Set-Content -Path $AgentsIndex -Encoding UTF8 + Write-Host "Created .agents/index.md" +} + +$GitAttrDst = Join-Path $Root ".gitattributes" +if (Test-Path $GitAttrSrc) { + if ($GitAttrSrc -ieq $GitAttrDst) { + Write-Host "Skip: .gitattributes source equals destination." + Write-Host "Done." + exit 0 + } + if (Test-Path $GitAttrDst) { + $bak = "$GitAttrDst.bak.$timestamp" + Move-Item $GitAttrDst $bak + Write-Host "Backed up existing .gitattributes -> $bak" + } + Copy-Item $GitAttrSrc $GitAttrDst -Force + Write-Host "Synced .gitattributes from standards." +} + +Write-Host "Done." diff --git a/scripts/sync_standards.sh b/scripts/sync_standards.sh new file mode 100644 index 0000000..95294f2 --- /dev/null +++ b/scripts/sync_standards.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env sh +set -eu + +# Sync standards snapshot to project root. +# - Copies /.agents -> /.agents/tsl +# - Copies /.gitattributes -> /.gitattributes +# Existing targets are backed up before overwrite. + +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)" +SRC="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd -P)" +ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || pwd)" +ROOT="$(CDPATH= cd -- "$ROOT" && pwd -P)" +AGENTS_SRC="$SRC/.agents" +GITATTR_SRC="$SRC/.gitattributes" + +if [ ! -d "$AGENTS_SRC" ]; then + echo "ERROR: Standards snapshot not found at $AGENTS_SRC" >&2 + echo "Run: git subtree add --prefix --squash" >&2 + exit 1 +fi + +timestamp="$(date +%Y%m%d%H%M%S 2>/dev/null || echo bak)" + +if [ "$SRC" = "$ROOT" ]; then + echo "Skip: snapshot root equals project root." + echo "Done." + exit 0 +fi + +: "${AGENTS_NS:=tsl}" +case "$AGENTS_NS" in + ""|*/*|*\\*|*..*) + echo "ERROR: invalid AGENTS_NS=$AGENTS_NS" >&2 + exit 1 + ;; +esac + +AGENTS_ROOT="$ROOT/.agents" +AGENTS_DST="$AGENTS_ROOT/$AGENTS_NS" +mkdir -p "$AGENTS_ROOT" + +if [ -e "$AGENTS_DST" ]; then + mv "$AGENTS_DST" "$AGENTS_ROOT/$AGENTS_NS.bak.$timestamp" + echo "Backed up existing $AGENTS_NS agents -> $AGENTS_NS.bak.$timestamp" +fi + +cp -R "$AGENTS_SRC" "$AGENTS_DST" +echo "Synced .agents/$AGENTS_NS from standards." + +AGENTS_INDEX="$AGENTS_ROOT/index.md" +if [ ! -f "$AGENTS_INDEX" ]; then + cat >"$AGENTS_INDEX" <<'EOF' +# .agents(多语言) + +本目录用于存放仓库级/语言级的代理规则集。 + +建议约定: + +- `.agents/tsl/`:TSL 相关标准(由 `sync_standards.*` 同步) +- `.agents/cpp/`、`.agents/python/` 等:其他语言的规则集(按需增加) + +规则发生冲突时,建议以“更靠近代码的目录规则更具体”为准。 +EOF + echo "Created .agents/index.md" +fi + +echo "Synced agents ruleset to $AGENTS_DST." + +GITATTR_DST="$ROOT/.gitattributes" +if [ -f "$GITATTR_SRC" ]; then + if [ "$(CDPATH= cd -- "$(dirname -- "$GITATTR_SRC")" && pwd -P)/$(basename -- "$GITATTR_SRC")" = "$GITATTR_DST" ]; then + echo "Skip: .gitattributes source equals destination." + else + if [ -e "$GITATTR_DST" ]; then + mv "$GITATTR_DST" "$ROOT/.gitattributes.bak.$timestamp" + echo "Backed up existing .gitattributes -> .gitattributes.bak.$timestamp" + fi + cp "$GITATTR_SRC" "$GITATTR_DST" + echo "Synced .gitattributes from standards." + fi +fi + +echo "Done."