✨ feat(playbook): support multi-language standards layout
This commit is contained in:
parent
5311f33802
commit
88f0842134
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
## 1. 总体要求
|
## 1. 总体要求
|
||||||
|
|
||||||
- 遵守 `docs/code_style.md` 与 `docs/naming.md`。
|
- 遵守本标准快照中的 `docs/tsl/code_style.md` 与 `docs/tsl/naming.md`(通常位于目标项目的 `docs/standards/tsl/docs/tsl/`)。
|
||||||
- 改动聚焦目标;避免“顺手重构”。
|
- 改动聚焦目标;避免“顺手重构”。
|
||||||
- API 变更要显式说明影响与迁移方式。
|
- API 变更要显式说明影响与迁移方式。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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/` 下的人类开发规范并行:
|
||||||
|
|
||||||
- `docs/`:给人看的编码/命名/提交规范
|
- `docs/`:给人看的编码/命名/提交规范
|
||||||
- `.agents/`:给代理看的任务边界、质量与安全要求
|
- `.agents/`:给代理看的任务边界、质量与安全要求
|
||||||
|
|
||||||
## 范围
|
## 范围与优先级
|
||||||
|
|
||||||
- 适用于本仓库所有目录与文件,除非子目录另有更具体的 `.agents/*.md` 覆盖说明。
|
- 作为仓库级基线规则集使用;更靠近代码目录的规则应更具体并可覆盖基线。
|
||||||
- 当 `.agents` 与 `docs` 发生冲突时:
|
- 当代理规则与 `docs` 发生冲突时:
|
||||||
1. 安全/合规优先
|
1. 安全/合规优先
|
||||||
2. 其次保持仓库现有一致性
|
2. 其次保持仓库现有一致性
|
||||||
|
|
||||||
|
|
@ -27,8 +33,19 @@
|
||||||
- 代码质量:`code_quality.md`
|
- 代码质量:`code_quality.md`
|
||||||
- 测试:`testing.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/tsl/code_style.md`(通常位于目标项目 `docs/standards/tsl/docs/tsl/code_style.md`)
|
||||||
- 命名规范:`docs/naming.md`
|
- 命名规范:标准快照 `docs/tsl/naming.md`(通常位于目标项目 `docs/standards/tsl/docs/tsl/naming.md`)
|
||||||
- 提交信息:`docs/commit_message.md`
|
- 提交信息:标准快照 `docs/common/commit_message.md`(通常位于目标项目 `docs/standards/tsl/docs/common/commit_message.md`)
|
||||||
|
|
|
||||||
130
README.md
130
README.md
|
|
@ -23,9 +23,10 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则
|
||||||
|
|
||||||
`docs/` 目录是给开发者阅读的工程规范,约束代码写法、命名与提交信息。
|
`docs/` 目录是给开发者阅读的工程规范,约束代码写法、命名与提交信息。
|
||||||
|
|
||||||
- `docs/code_style.md`:代码结构、格式、`begin/end` 代码块、注释与通用最佳实践。
|
- `docs/index.md`:文档导航(跨语言 common / TSL 专属)。
|
||||||
- `docs/naming.md`:TSL 命名规范(顶层声明、文件同名规则、变量/成员/property、常量、集合命名等)。
|
- `docs/common/commit_message.md`:提交信息与版本号规范(type/scope/subject/body/footer、可选 Emoji 图例、SemVer)。
|
||||||
- `docs/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/(代理规则)
|
## .agents/(代理规则)
|
||||||
|
|
||||||
|
|
@ -47,7 +48,7 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git subtree add \
|
git subtree add \
|
||||||
--prefix docs/standards/tsl_playbook \
|
--prefix docs/standards/tsl \
|
||||||
https://git.mytsl.cn/csh/tsl-playbook.git \
|
https://git.mytsl.cn/csh/tsl-playbook.git \
|
||||||
main --squash
|
main --squash
|
||||||
```
|
```
|
||||||
|
|
@ -56,7 +57,7 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git subtree pull \
|
git subtree pull \
|
||||||
--prefix docs/standards/tsl_playbook \
|
--prefix docs/standards/tsl \
|
||||||
https://git.mytsl.cn/csh/tsl-playbook.git \
|
https://git.mytsl.cn/csh/tsl-playbook.git \
|
||||||
main --squash
|
main --squash
|
||||||
```
|
```
|
||||||
|
|
@ -66,27 +67,33 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则
|
||||||
目标项目推荐采用以下结构(Playbook 快照与项目文档分离):
|
目标项目推荐采用以下结构(Playbook 快照与项目文档分离):
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
.agents/ # 从 Playbook 同步后可按项目微调
|
.
|
||||||
.gitattributes # 从 Playbook 同步
|
├── .agents/
|
||||||
docs/
|
│ ├── index.md # 多语言代理规则集索引(缺省时由脚本创建)
|
||||||
standards/
|
│ └── tsl/ # 从 Playbook 同步(仅覆盖该子目录)
|
||||||
tsl_playbook/ # git subtree 快照(只读)
|
├── .gitattributes # 从 Playbook 同步
|
||||||
docs/ # code_style.md / naming.md / commit_message.md
|
├── docs/
|
||||||
.agents/ # 标准代理规则快照
|
│ ├── standards/
|
||||||
.gitattributes
|
│ │ └── tsl/ # git subtree 快照(只读)
|
||||||
SOURCE.md # 记录来源版本/commit(项目自行维护)
|
│ │ ├── docs/ # common/ + tsl/
|
||||||
project/ # 目标项目自己的文档
|
│ │ ├── .agents/ # 标准代理规则快照
|
||||||
README.md # 说明遵循 standards
|
│ │ ├── .gitattributes
|
||||||
|
│ │ └── SOURCE.md # 记录来源版本/commit(项目自行维护)
|
||||||
|
│ └── project/ # 目标项目自己的文档
|
||||||
|
└── README.md # 说明遵循 standards
|
||||||
```
|
```
|
||||||
|
|
||||||
根目录的 `.agents/` 与 `.gitattributes` 通过同步脚本获得:
|
根目录的 `.agents/tsl/` 与 `.gitattributes` 通过同步脚本获得:
|
||||||
|
|
||||||
- 直接运行 Playbook 提供的脚本(子树快照里自带):
|
- 直接运行 Playbook 提供的脚本(子树快照里自带):
|
||||||
- `docs/standards/tsl_playbook/scripts/sync_playbook.sh`
|
- `docs/standards/tsl/scripts/sync_standards.sh`(推荐)
|
||||||
- `docs/standards/tsl_playbook/scripts/sync_playbook.ps1`
|
- `docs/standards/tsl/scripts/sync_standards.ps1`(推荐)
|
||||||
- `docs/standards/tsl_playbook/scripts/sync_playbook.bat`
|
- `docs/standards/tsl/scripts/sync_standards.bat`(推荐)
|
||||||
- 脚本会从快照目录同步到项目根目录,并先备份旧文件(`.bak.*`)。
|
- 脚本会从快照目录同步到项目根目录,并先备份旧文件(`.bak.*`)。
|
||||||
|
|
||||||
|
注:`docs/standards/tsl/` 只是推荐目录名;你可以用任意 `--prefix`(例如 `docs/standards/tsl_playbook/`)。同步脚本会从脚本自身路径推导快照根目录,不再依赖目录名。
|
||||||
|
注:默认同步到 `.agents/tsl/`;如需指定规则集名称,可通过环境变量 `AGENTS_NS`(例如 `AGENTS_NS=tsl`、`AGENTS_NS=common`)。
|
||||||
|
|
||||||
这样 clone 任意项目时都能直接读取规范文件,不依赖外部访问权限。
|
这样 clone 任意项目时都能直接读取规范文件,不依赖外部访问权限。
|
||||||
|
|
||||||
### 方式二:手动复制快照
|
### 方式二:手动复制快照
|
||||||
|
|
@ -95,17 +102,86 @@ TSL Playbook:Tinysoft Language(`.tsl` / `.tsf`)工程规范与代理规则
|
||||||
|
|
||||||
步骤:
|
步骤:
|
||||||
|
|
||||||
1. 在目标项目创建目录:`docs/standards/tsl_playbook/`。
|
1. 在目标项目创建目录:`docs/standards/tsl/`。
|
||||||
2. 从本仓库复制以下内容到目标项目:
|
2. 从本仓库复制以下内容到目标项目:
|
||||||
- `docs/` → `docs/standards/tsl_playbook/docs/`
|
- `docs/` → `docs/standards/tsl/docs/`(包含 `docs/common/` 与 `docs/tsl/`)
|
||||||
- `.agents/` → `docs/standards/tsl_playbook/.agents/`
|
- `.agents/` → `docs/standards/tsl/.agents/`
|
||||||
- `.gitattributes` → `docs/standards/tsl_playbook/.gitattributes`
|
- `.gitattributes` → `docs/standards/tsl/.gitattributes`
|
||||||
- `scripts/` → `docs/standards/tsl_playbook/scripts/`
|
- `scripts/` → `docs/standards/tsl/scripts/`
|
||||||
3. 在目标项目根目录运行同步脚本,把 `.agents/` 与 `.gitattributes` 落到根目录(见上文脚本路径)。
|
3. 在目标项目根目录运行同步脚本,把 `.agents/tsl/` 与 `.gitattributes` 落到根目录(见上文脚本路径)。
|
||||||
4. 在 `docs/standards/tsl_playbook/SOURCE.md` 记录本次复制的来源版本/日期(建议写 Playbook 的 commit hash)。
|
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 形式提交。
|
- 本项目会持续迭代;变更以 PR 形式提交。
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# 文档导航(Docs Index)
|
||||||
|
|
||||||
|
本仓库文档按“跨语言共识 / 语言专属”分层组织,便于在多语言项目中扩展与复用。
|
||||||
|
|
||||||
|
## 跨语言(common)
|
||||||
|
|
||||||
|
- 提交信息与版本号:`common/commit_message.md`
|
||||||
|
|
||||||
|
## TSL(tsl)
|
||||||
|
|
||||||
|
- 代码风格:`tsl/code_style.md`
|
||||||
|
- 命名规范:`tsl/naming.md`
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# 代码风格(Code Style)
|
# TSL 代码风格(Code Style)
|
||||||
|
|
||||||
本章节规定 TSL 代码的结构与格式约定。
|
本章节规定 TSL 代码的结构与格式约定。
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# 命名规范(Naming)
|
# TSL 命名规范(Naming)
|
||||||
|
|
||||||
本仓库命名规则与 Google C++ Style Guide 对齐:通过名字的“形状”快速判断实体类型(类型/函数/变量/常量等),减少阅读成本。
|
本仓库命名规则与 Google C++ Style Guide 对齐:通过名字的“形状”快速判断实体类型(类型/函数/变量/常量等),减少阅读成本。
|
||||||
|
|
||||||
|
|
@ -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 ^<playbook-url^> 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
|
|
||||||
|
|
@ -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."
|
|
||||||
|
|
@ -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 <playbook-url> 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."
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
rem Sync standards snapshot to project root.
|
||||||
|
rem - Copies <snapshot>\.agents -> <project-root>\.agents\tsl
|
||||||
|
rem - Copies <snapshot>\.gitattributes -> <project-root>\.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 ^<your-prefix^> ^<standards-url^> ^<branch^> --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
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Sync standards snapshot to project root.
|
||||||
|
# - Copies <snapshot>/.agents -> <project-root>/.agents/tsl
|
||||||
|
# - Copies <snapshot>/.gitattributes -> <project-root>/.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."
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Sync standards snapshot to project root.
|
||||||
|
# - Copies <snapshot>/.agents -> <project-root>/.agents/tsl
|
||||||
|
# - Copies <snapshot>/.gitattributes -> <project-root>/.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 <your-prefix> <standards-url> <branch> --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."
|
||||||
Loading…
Reference in New Issue