✨ feat(typescript): add standards docs and sync rewrite coverage
This commit is contained in:
parent
872c1afc24
commit
1f46203299
20
README.md
20
README.md
|
|
@ -1,6 +1,6 @@
|
|||
# playbook
|
||||
|
||||
Playbook:TSL(`.tsl`/`.tsf`)+ C++ + Python + Markdown(代码格式化)工程规范与代理规则合集。
|
||||
Playbook:TSL(`.tsl`/`.tsf`)+ C++ + Python + TypeScript/JavaScript + Markdown(代码格式化)工程规范与代理规则合集。
|
||||
|
||||
## 原则
|
||||
|
||||
|
|
@ -10,14 +10,14 @@ Playbook:TSL(`.tsl`/`.tsf`)+ C++ + Python + Markdown(代码格式化)
|
|||
|
||||
## 适用范围
|
||||
|
||||
- 本指南适用于所有 TSL/C++/Python/Markdown 相关仓库与脚本
|
||||
- 本指南适用于所有 TSL/C++/Python/TypeScript/JavaScript/Markdown 相关仓库与脚本
|
||||
- 当现有代码与本指南冲突时,**以保持局部一致性为优先**,逐步迁移
|
||||
|
||||
## docs/(开发规范)
|
||||
|
||||
`docs/` 目录是给开发者阅读的工程规范,约束代码写法、命名与提交信息。
|
||||
|
||||
- `docs/index.md`:文档导航(跨语言 common / TSL / C++ / Python / Markdown)。
|
||||
- `docs/index.md`:文档导航(跨语言 common / TSL / C++ / Python / TypeScript / Markdown)。
|
||||
- `docs/common/commit_message.md`:提交信息与版本号规范(type/scope/subject/body/footer、可选 Emoji 图例、SemVer)。
|
||||
- `docs/tsl/code_style.md`:TSL 代码结构、格式、`begin/end`
|
||||
代码块、注释与通用最佳实践。
|
||||
|
|
@ -35,6 +35,10 @@ Playbook:TSL(`.tsl`/`.tsf`)+ C++ + Python + Markdown(代码格式化)
|
|||
- `docs/python/configuration.md`:Python 配置清单(落地时从 `templates/python/`
|
||||
复制到项目根目录)。
|
||||
- `docs/markdown/index.md`:Markdown 代码块与行内代码格式(仅代码格式化)。
|
||||
- `docs/typescript/code_style.md`:TypeScript 代码风格(Google 基线)。
|
||||
- `docs/typescript/naming.md`:TypeScript 命名规范。
|
||||
- `docs/typescript/toolchain.md`:TypeScript 工具链(typescript/prettier/eslint/vitest)。
|
||||
- `docs/typescript/configuration.md`:TypeScript 配置清单(tsconfig/eslint/prettier)。
|
||||
- `templates/cpp/`:C++ 落地模板(`.clang-format`、`conanfile.txt`、`CMakeUserPresets.json`、`CMakeLists.txt`)。
|
||||
- `templates/python/`:Python 落地模板(`pyproject.toml`
|
||||
工具配置、`.flake8`、`.pylintrc`、`.pre-commit-config.yaml`、`.editorconfig`、`.vscode/settings.json`)。
|
||||
|
|
@ -124,6 +128,7 @@ Layer 3: docs/ (权威静态文档)
|
|||
- `rulesets/tsl/index.md`:TSL 核心约定(44 行)
|
||||
- `rulesets/cpp/index.md`:C++ 核心约定(47 行)
|
||||
- `rulesets/python/index.md`:Python 核心约定(45 行)
|
||||
- `rulesets/typescript/index.md`:TypeScript 核心约定(47 行)
|
||||
- `rulesets/markdown/index.md`:Markdown 核心约定(31 行,仅代码格式化)
|
||||
|
||||
更多说明:`rulesets/index.md`
|
||||
|
|
@ -287,16 +292,16 @@ python scripts/playbook.py -config playbook.toml
|
|||
- 行尾与文本规范:`.gitattributes`
|
||||
- 代理最低要求:`.agents/*`(工作原则、质量底线、安全边界)
|
||||
2. **语言级(Language-specific)规范**:只对某个语言成立的风格与工具。
|
||||
- 例如 TSL 的命名/文件顶层声明限制、C++ 的 `.clang-format/.clang-tidy`、Python 的 `ruff` 等。
|
||||
- 例如 TSL 的命名/文件顶层声明限制、C++ 的 `.clang-format/.clang-tidy`、Python 的 `ruff`、TypeScript 的 ESLint/类型约束等。
|
||||
|
||||
**建议**:仓库级规则尽量少且稳定;语言级规则各自独立,避免互相"污染"。
|
||||
|
||||
本仓库提供多套代理规则集(同步后位于目标项目的 `.agents/tsl/` / `.agents/cpp/` / `.agents/python/` / `.agents/markdown/`):
|
||||
本仓库提供多套代理规则集(同步后位于目标项目的 `.agents/tsl/` / `.agents/cpp/` / `.agents/python/` / `.agents/typescript/` / `.agents/markdown/`):
|
||||
|
||||
- 三者都包含核心约定与安全红线
|
||||
- 并在 `index.md` 中叠加语言级"硬约束"(TSL/TSF 语法限制、C++23/Modules、Python 风格、Markdown 代码格式化等)
|
||||
- 并在 `index.md` 中叠加语言级"硬约束"(TSL/TSF 语法限制、C++23/Modules、Python 风格、TypeScript 类型约束、Markdown 代码格式化等)
|
||||
|
||||
**多语言项目推荐结构**(示例:TSL + C++ + Python + Markdown):
|
||||
**多语言项目推荐结构**(示例:TSL + C++ + Python + TypeScript + Markdown):
|
||||
|
||||
```txt
|
||||
.
|
||||
|
|
@ -305,6 +310,7 @@ python scripts/playbook.py -config playbook.toml
|
|||
│ ├── tsl/ # 由本 Playbook 同步(适用于 .tsl/.tsf)
|
||||
│ ├── cpp/ # 由本 Playbook 同步(适用于 C++23/Modules)
|
||||
│ ├── python/ # Python 规则集(同上)
|
||||
│ ├── typescript/ # TypeScript/JavaScript 规则集(同上)
|
||||
│ └── markdown/ # Markdown 规则集(仅代码格式化)
|
||||
├── .gitattributes # 行尾/文本规范
|
||||
├── docs/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@
|
|||
- 工具链:`python/tooling.md`
|
||||
- 配置清单:`python/configuration.md`
|
||||
|
||||
## TypeScript(typescript)
|
||||
|
||||
- 代码风格:`typescript/code_style.md`
|
||||
- 命名规范:`typescript/naming.md`
|
||||
- 工具链:`typescript/toolchain.md`
|
||||
- 配置清单:`typescript/configuration.md`
|
||||
|
||||
## Markdown(markdown)
|
||||
|
||||
- 代码块与行内代码格式:`markdown/index.md`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
# TypeScript 代码风格
|
||||
|
||||
本 Playbook 的 TypeScript 代码风格以 Google TypeScript Style Guide 为基线:
|
||||
|
||||
- Google TypeScript Style Guide: https://google.github.io/styleguide/tsguide.html
|
||||
- TypeScript 官方手册: https://www.typescriptlang.org/docs/handbook/
|
||||
|
||||
## 项目约定
|
||||
|
||||
- 行宽:100(与 Prettier 配置保持一致)
|
||||
- 缩进:2 空格
|
||||
- 引号:单引号(Prettier `singleQuote: true`)
|
||||
- 分号:不加(Prettier `semi: false`);如仓库已有配置则以仓库为准
|
||||
- 尾随逗号:`all`(ES5+)
|
||||
|
||||
## 类型约定
|
||||
|
||||
- 禁止 `any`;需要宽泛类型时用 `unknown` 并做类型收窄
|
||||
- 优先使用 `interface` 描述对象结构;`type` 用于联合/交叉/工具类型
|
||||
- 函数返回类型:公共 API 必须显式标注;内部实现可依赖推断
|
||||
- 泛型参数名:单字母(`T`、`K`、`V`)或描述性名称(`TItem`)
|
||||
|
||||
## 模块约定
|
||||
|
||||
- 使用 ES Module(`import`/`export`);禁止 `require()`(除 `.cjs` 文件)
|
||||
- 每文件一个主要导出;避免桶文件(`index.ts` re-export 过多)
|
||||
- 路径别名:以 `tsconfig.json` 的 `paths` 为准
|
||||
|
||||
## 异步约定
|
||||
|
||||
- 优先 `async/await`;避免裸 `.then()/.catch()` 链
|
||||
- `async` 函数必须处理错误(`try/catch` 或调用方捕获)
|
||||
- 不得忽略 Promise(使用 `void` 操作符显式标记有意忽略)
|
||||
|
||||
当既有代码与本约定冲突时,优先保持局部一致性,逐步迁移。
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
# TypeScript 配置清单
|
||||
|
||||
本文件汇总 TypeScript 项目常用配置文件说明。
|
||||
|
||||
## 1) `tsconfig.json`
|
||||
|
||||
关键编译选项:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
```
|
||||
|
||||
- `strict: true`:启用全部严格检查(必须)
|
||||
- `noUncheckedIndexedAccess`:数组/对象索引访问返回 `T | undefined`(推荐)
|
||||
- `skipLibCheck`:跳过 `.d.ts` 检查,加快编译
|
||||
|
||||
## 2) `.prettierrc`
|
||||
|
||||
```json
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2
|
||||
}
|
||||
```
|
||||
|
||||
## 3) `eslint.config.js`(Flat Config)
|
||||
|
||||
```js
|
||||
import tseslint from 'typescript-eslint'
|
||||
|
||||
export default tseslint.config(
|
||||
...tseslint.configs.recommendedTypeChecked,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: { projectService: true },
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
},
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
## 4) `.editorconfig`
|
||||
|
||||
```ini
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{ts,tsx,js,jsx,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
max_line_length = 100
|
||||
```
|
||||
|
||||
## 5) `.vscode/settings.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.rulers": [100],
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# TypeScript 命名规范
|
||||
|
||||
## 文件与目录
|
||||
|
||||
- 文件名:`kebab-case.ts` / `kebab-case.tsx`
|
||||
- 测试文件:`kebab-case.test.ts` / `kebab-case.spec.ts`
|
||||
- 类型声明文件:`kebab-case.d.ts`
|
||||
- 目录名:`kebab-case/`
|
||||
|
||||
## 标识符
|
||||
|
||||
| 类别 | 风格 | 示例 |
|
||||
| ----------------- | -------------------------- | ------------------------------ |
|
||||
| 类(Class) | `PascalCase` | `UserService` |
|
||||
| 接口(Interface) | `PascalCase` | `UserProfile`(不加 `I` 前缀) |
|
||||
| 类型别名(Type) | `PascalCase` | `ApiResponse<T>` |
|
||||
| 枚举(Enum) | `PascalCase` | `HttpStatus` |
|
||||
| 枚举成员 | `UPPER_WITH_UNDER` | `NOT_FOUND` |
|
||||
| 函数/方法 | `camelCase` | `getUserById` |
|
||||
| 变量/参数 | `camelCase` | `userId` |
|
||||
| 常量(模块级) | `UPPER_WITH_UNDER` | `MAX_RETRY_COUNT` |
|
||||
| 私有成员 | `_camelCase` | `_cache` |
|
||||
| 泛型参数 | 单字母或 `T` 前缀 | `T`、`TItem`、`K`、`V` |
|
||||
| React 组件 | `PascalCase` | `UserCard` |
|
||||
| React Hook | `camelCase`,以 `use` 开头 | `useUserData` |
|
||||
|
||||
## 布尔值命名
|
||||
|
||||
布尔变量/属性以 `is`、`has`、`can`、`should` 开头:
|
||||
|
||||
```ts
|
||||
const isLoading = true
|
||||
const hasPermission = false
|
||||
```
|
||||
|
||||
## 避免
|
||||
|
||||
- 单字母变量(循环索引 `i`/`j` 除外)
|
||||
- 缩写(`usr`、`btn`);优先完整单词
|
||||
- 匈牙利命名法(`strName`、`nCount`)
|
||||
- 接口名加 `I` 前缀(`IUserService`)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# TypeScript 工具链
|
||||
|
||||
本 Playbook 推荐以下工具保证代码一致性与质量:
|
||||
|
||||
- `typescript`:编译器(`tsc`)
|
||||
- `prettier`:格式化
|
||||
- `eslint`:风格检查与静态分析(配合 `@typescript-eslint`)
|
||||
- `vitest` / `jest`:测试(按项目选择)
|
||||
- `tsx` / `ts-node`:直接运行 `.ts` 文件(开发/脚本场景)
|
||||
|
||||
## 常用命令(示例)
|
||||
|
||||
安装工具(按项目实际包管理器调整):
|
||||
|
||||
```bash
|
||||
pnpm add -D typescript prettier eslint typescript-eslint
|
||||
```
|
||||
|
||||
类型检查:
|
||||
|
||||
```bash
|
||||
tsc --noEmit
|
||||
```
|
||||
|
||||
格式化:
|
||||
|
||||
```bash
|
||||
prettier --write .
|
||||
```
|
||||
|
||||
Lint 检查:
|
||||
|
||||
```bash
|
||||
eslint .
|
||||
```
|
||||
|
||||
运行测试:
|
||||
|
||||
```bash
|
||||
vitest run
|
||||
# 或
|
||||
jest --ci
|
||||
```
|
||||
|
||||
## 包管理器
|
||||
|
||||
优先使用仓库已有的包管理器(`pnpm` / `npm` / `yarn`);未经沟通不切换。
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
- `rulesets/tsl/`:TSL 相关规则集(适用于 `.tsl`/`.tsf`)
|
||||
- `rulesets/cpp/`:C++ 相关规则集(C++23,含 Modules)
|
||||
- `rulesets/python/`:Python 相关规则集
|
||||
- `rulesets/typescript/`:TypeScript/JavaScript 相关规则集
|
||||
- `rulesets/markdown/`:Markdown 相关规则集(仅代码格式化)
|
||||
|
||||
目标项目落地时,通过 `scripts/playbook.py` 的 `[sync_standards]`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# TypeScript 代理规则集
|
||||
|
||||
本规则集定义 AI/自动化代理在处理 TypeScript/JavaScript 代码时必须遵守的核心约束。
|
||||
|
||||
## 范围与优先级
|
||||
|
||||
- 作为仓库级基线规则集使用;更靠近代码目录的规则更具体并可覆盖基线。
|
||||
- 当代理规则与 docs 冲突:安全/合规优先,其次保持仓库一致性。
|
||||
|
||||
## 代理工作原则(铁律)
|
||||
|
||||
1. 先理解目标与上下文,再动手改代码
|
||||
2. 修改要小而清晰;避免无关重构
|
||||
3. 发现安全问题(明文密钥/鉴权漏洞)立即标注或修复
|
||||
4. 不引入新依赖或工具,除非明确要求
|
||||
|
||||
## TypeScript 核心约定(不可违反)
|
||||
|
||||
- 语言标准:优先 TypeScript;仅在纯脚本/配置场景使用 JavaScript
|
||||
- 类型:禁止使用 `any`;优先 `unknown`;所有公共 API 必须有明确类型注解
|
||||
- 代码风格:以仓库既有 ESLint/Prettier 配置为准;未经沟通不切换 formatter/linter
|
||||
- Import:使用 ES Module(`import`/`export`);避免 `require()`;按 外部 → 内部 → 相对路径 分组
|
||||
- 命名:文件 `kebab-case.ts`;类/接口/类型 `PascalCase`;函数/变量 `camelCase`;常量 `UPPER_WITH_UNDER`;私有成员 `_camelCase`
|
||||
- 异步:优先 `async/await`;避免裸 `.then()` 链;错误必须处理
|
||||
|
||||
## 安全红线(不可触碰)
|
||||
|
||||
- 不得在代码/日志/注释中写入明文密钥、密码、Token、API Key
|
||||
- 不得使用 `eval()` / `new Function()` 处理不可信输入
|
||||
- 不得直接拼接用户输入到 SQL/命令/HTML(防注入/XSS)
|
||||
- 修改鉴权/权限逻辑必须说明动机与风险
|
||||
|
||||
## 权威来源
|
||||
|
||||
- 代码风格:`docs/typescript/code_style.md`
|
||||
- 命名规范:`docs/typescript/naming.md`
|
||||
- 工具链:`docs/typescript/toolchain.md`
|
||||
- 配置清单:`docs/typescript/configuration.md`
|
||||
|
||||
## Skills(按需加载)
|
||||
|
||||
- `$commit-message`
|
||||
|
||||
## 与开发规范的关系
|
||||
|
||||
- 本仓库内:`docs/typescript/` 与 `docs/common/`
|
||||
- 目标项目 subtree:`docs/standards/playbook/docs/typescript/` 与 `docs/standards/playbook/docs/common/`
|
||||
|
|
@ -269,6 +269,16 @@ def write_docs_index(dest_prefix: Path, langs: list[str]) -> None:
|
|||
"- 工具链:`python/tooling.md`",
|
||||
"- 配置清单:`python/configuration.md`",
|
||||
]
|
||||
elif lang == "typescript":
|
||||
lines += [
|
||||
"",
|
||||
"## TypeScript(typescript)",
|
||||
"",
|
||||
"- 代码风格:`typescript/code_style.md`",
|
||||
"- 命名规范:`typescript/naming.md`",
|
||||
"- 工具链:`typescript/toolchain.md`",
|
||||
"- 配置清单:`typescript/configuration.md`",
|
||||
]
|
||||
elif lang == "markdown":
|
||||
lines += [
|
||||
"",
|
||||
|
|
@ -832,6 +842,7 @@ def create_agents_index(agents_root: Path, langs: list[str], docs_prefix: str |
|
|||
"- `.agents/tsl/`:TSL 相关规则集(由 playbook 同步;适用于 `.tsl`/`.tsf`)",
|
||||
"- `.agents/cpp/`:C++ 相关规则集(由 playbook 同步;适用于 C++23/Modules)",
|
||||
"- `.agents/python/`:Python 相关规则集(由 playbook 同步)",
|
||||
"- `.agents/typescript/`:TypeScript/JavaScript 相关规则集(由 playbook 同步)",
|
||||
"- `.agents/markdown/`:Markdown 相关规则集(仅代码格式化)",
|
||||
"",
|
||||
"规则发生冲突时,建议以“更靠近代码的目录规则更具体”为准。",
|
||||
|
|
@ -856,6 +867,7 @@ def rewrite_agents_docs_links(agents_dir: Path, docs_prefix: str) -> None:
|
|||
"`docs/tsl/": f"`{docs_prefix}/tsl/",
|
||||
"`docs/cpp/": f"`{docs_prefix}/cpp/",
|
||||
"`docs/python/": f"`{docs_prefix}/python/",
|
||||
"`docs/typescript/": f"`{docs_prefix}/typescript/",
|
||||
"`docs/markdown/": f"`{docs_prefix}/markdown/",
|
||||
"`docs/common/": f"`{docs_prefix}/common/",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@ VALID_LINKS=0
|
|||
BROKEN_LINKS=0
|
||||
SKIPPED_LINKS=0
|
||||
|
||||
BROKEN_LINKS_FILE="/tmp/broken_links.txt"
|
||||
REPORT_FILE="/tmp/doc_links_report.txt"
|
||||
|
||||
> "$BROKEN_LINKS_FILE"
|
||||
> "$REPORT_FILE"
|
||||
BROKEN_LINKS_FILE="$(mktemp "${TMPDIR:-/tmp}/broken_links.XXXXXX")"
|
||||
REPORT_FILE="$(mktemp "${TMPDIR:-/tmp}/doc_links_report.XXXXXX")"
|
||||
|
||||
echo "📁 Playbook 根目录: $PLAYBOOK_ROOT"
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
README = ROOT / "README.md"
|
||||
|
||||
|
||||
class ReadmeLanguageListsTests(unittest.TestCase):
|
||||
def test_rulesets_list_includes_typescript(self):
|
||||
text = README.read_text(encoding="utf-8")
|
||||
self.assertIn("- `rulesets/typescript/index.md`:TypeScript 核心约定", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
@ -16,6 +16,15 @@ def run_cli(*args):
|
|||
)
|
||||
|
||||
|
||||
def run_script(script_path: Path, *args, cwd: Path | None = None):
|
||||
return subprocess.run(
|
||||
[sys.executable, str(script_path), *args],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=str(cwd) if cwd else None,
|
||||
)
|
||||
|
||||
|
||||
class SyncTemplatesPlaceholdersTests(unittest.TestCase):
|
||||
def test_main_language_placeholder_replaced(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
|
|
@ -44,6 +53,49 @@ langs = [\"cpp\", \"tsl\"]
|
|||
self.assertIn("docs/standards/playbook/scripts/plan_progress.py", rules_text)
|
||||
self.assertNotIn("{{PLAYBOOK_SCRIPTS}}", rules_text)
|
||||
|
||||
def test_sync_standards_rewrites_typescript_docs_prefix_for_vendored_playbook(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
root = Path(tmp_dir)
|
||||
vendor_config = root / "vendor.toml"
|
||||
vendor_config.write_text(
|
||||
f"""
|
||||
[playbook]
|
||||
project_root = "{tmp_dir}"
|
||||
|
||||
[vendor]
|
||||
langs = ["typescript"]
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
vendor_result = run_cli("-config", str(vendor_config))
|
||||
self.assertEqual(vendor_result.returncode, 0, msg=vendor_result.stderr)
|
||||
|
||||
sync_config = root / "sync.toml"
|
||||
sync_config.write_text(
|
||||
f"""
|
||||
[playbook]
|
||||
project_root = "{tmp_dir}"
|
||||
|
||||
[sync_standards]
|
||||
langs = ["typescript"]
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
vendored_script = (
|
||||
root / "docs" / "standards" / "playbook" / "scripts" / "playbook.py"
|
||||
)
|
||||
sync_result = run_script(
|
||||
vendored_script, "-config", str(sync_config), cwd=root
|
||||
)
|
||||
self.assertEqual(sync_result.returncode, 0, msg=sync_result.stderr)
|
||||
|
||||
agents_index = root / ".agents" / "typescript" / "index.md"
|
||||
text = agents_index.read_text(encoding="utf-8")
|
||||
self.assertIn("`docs/standards/playbook/docs/typescript/", text)
|
||||
self.assertNotIn("`docs/typescript/", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Reference in New Issue