feat: add China Telecom R&D project template

This commit is contained in:
v6ole
2026-07-28 22:30:20 +08:00
commit b6a1fd85d8
51 changed files with 11196 additions and 0 deletions
@@ -0,0 +1,143 @@
[CmdletBinding()]
param(
[string]$SourceDirectory = (Join-Path $PSScriptRoot '..\skills\telecom-rd-standards\references\source-documents'),
[switch]$Replace
)
$ErrorActionPreference = 'Stop'
$sourceDirectory = (Resolve-Path $SourceDirectory).Path
$titles = @{
'00-issue-notice' = '关于印发中国电信软件研发规范(修订版)的通知'
'01-capability-classification' = '中国电信软件研发规范分级分类实施指导意见(修订版)'
'02-rd-standards-revision-overview' = '软件研发系列规范修订介绍'
'03-overall-rd-standard' = '中国电信软件研发规范总体规范(修订版)'
'04-requirements-management' = '中国电信软件研发规范需求管理分册(修订版)'
'05-database-design' = '中国电信软件研发规范数据库设计分册(修订版)'
'06-python-coding' = '中国电信软件研发规范编码规范(Python 分册)'
'07-frontend-coding' = '中国电信软件研发规范编码规范(前端分册)'
'08-code-management' = '中国电信软件研发规范代码管理分册(修订版)'
'09-artifact-management' = '中国电信软件研发规范制品管理分册(修订版)'
'10-pipeline-management' = '中国电信软件研发规范流水线管理分册(修订版)'
'11-test-management' = '中国电信软件研发规范测试管理分册(修订版)'
'12-security' = '中国电信软件研发规范安全分册(修订版)'
'13-deployment' = '中国电信软件研发规范部署管理分册'
'20-rd-cloud-overview' = '研发云平台互联互通规范总册(试行稿)'
'21-rd-cloud-system-access-auth' = '研发云互联互通规范系统接入技术规范(用户认证和资产授权)(试行稿)'
'22-rd-cloud-data-open-access' = '研发云互联互通规范数据开放和接入技术规范(试行稿)'
'23-rd-cloud-openapi' = '研发云互联互通规范能力开放技术规范(OpenAPI 接口)(试行稿)'
'24-rd-cloud-scaffold-service' = '研发云互联互通规范服务接入技术规范(脚手架服务)(试行稿)'
}
function Test-StructuralLine([string]$Line) {
return $Line -match '^(\d+(\.\d+){0,4}\s+\S+|第[一二三四五六七八九十]+[章节]|[一二三四五六七八九十]+、|\d+[)]|[-*•]\s+|[A-Za-z][)]\s+|[{}\[\]`]|"|//)'
}
function Join-Paragraph([string]$Left, [string]$Right) {
if ([string]::IsNullOrEmpty($Left)) { return $Right }
if ($Left -match '[A-Za-z0-9]$' -and $Right -match '^[A-Za-z0-9]') { return "$Left $Right" }
return "$Left$Right"
}
function Write-Buffer([System.Collections.Generic.List[string]]$Output, [string]$Buffer) {
if (-not [string]::IsNullOrWhiteSpace($Buffer)) {
$Output.Add($Buffer)
$Output.Add('')
}
}
$txtFiles = Get-ChildItem -LiteralPath $sourceDirectory -File -Filter '*.txt'
if ($txtFiles.Count -eq 0) {
throw "No TXT documents found in $sourceDirectory."
}
foreach ($txtFile in $txtFiles) {
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($txtFile.Name)
$title = $titles[$baseName]
if (-not $title) { $title = $baseName }
$output = [System.Collections.Generic.List[string]]::new()
$output.Add("# $title")
$output.Add('')
$output.Add('> 脱敏整理版:已移除编制人员、联系人和联系方式,并合并无意义硬换行。技术条款、章节和示例以原始 DOCX 为争议核验依据。')
$output.Add('')
$buffer = ''
$skipAuthorMetadata = $false
$skipContactLines = 0
foreach ($rawLine in Get-Content -LiteralPath $txtFile.FullName) {
$line = ($rawLine -replace '[\u00A0\t]+', ' ' -replace '\s{2,}', ' ').Trim()
if ($skipContactLines -gt 0) {
$skipContactLines--
continue
}
if ($line -match '^(规范编制人员|编制人员)(|:)?') {
Write-Buffer $output $buffer
$buffer = ''
$output.Add('> 编制人员信息已移除。')
$output.Add('')
$skipAuthorMetadata = $true
continue
}
if ($skipAuthorMetadata) {
if ($line -match '^(版本变更历史|目录|\d+(\.\d+){0,4}\s+\S+)') {
$skipAuthorMetadata = $false
} elseif ([string]::IsNullOrWhiteSpace($line)) {
continue
} else {
continue
}
}
if ($line -match '^(评审人员|传阅人员|审阅人员|审核人员)[::]') {
Write-Buffer $output $buffer
$buffer = ''
$output.Add('> 评审与传阅人员信息已移除。')
$output.Add('')
continue
}
if ($line -match '联系人[:]?$' -or $line -match '^如有问题.*联系人') {
Write-Buffer $output $buffer
$buffer = ''
$output.Add('> 联系方式已移除。')
$output.Add('')
$skipContactLines = 2
continue
}
$line = $line -replace '(?<!\d)1[3-9]\d{9}(?!\d)', '[手机号已脱敏]'
$line = $line -replace '(?i)[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}', '[邮箱已脱敏]'
$line = $line -replace '张三', '示例创建人'
if ([string]::IsNullOrWhiteSpace($line)) {
Write-Buffer $output $buffer
$buffer = ''
continue
}
if (Test-StructuralLine $line) {
Write-Buffer $output $buffer
$buffer = ''
if ($line -match '^(\d+(\.\d+)*)\s+(.+)$' -and $line -notmatch '【强制】') {
$depth = ([regex]::Matches($Matches[1], '\.').Count + 2)
$depth = [Math]::Min($depth, 6)
$output.Add(('#' * $depth) + ' ' + $line)
} elseif ($line -match '^(第[一二三四五六七八九十]+[章节]|[一二三四五六七八九十]+、)') {
$output.Add('## ' + $line)
} else {
$output.Add($line)
}
$output.Add('')
continue
}
$buffer = Join-Paragraph $buffer $line
}
Write-Buffer $output $buffer
$markdownPath = Join-Path $sourceDirectory "$baseName.md"
[System.IO.File]::WriteAllText($markdownPath, (($output -join [Environment]::NewLine).TrimEnd() + [Environment]::NewLine), [System.Text.UTF8Encoding]::new($false))
if ($Replace) {
Remove-Item -LiteralPath $txtFile.FullName
}
}
Write-Output "Converted $($txtFiles.Count) TXT documents to Markdown. Replace=$Replace"
@@ -0,0 +1,84 @@
[CmdletBinding()]
param(
[string]$ProjectRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
)
$ErrorActionPreference = 'Stop'
$agentsDir = Join-Path $ProjectRoot '.agents'
$skillDir = Join-Path $agentsDir 'skills\telecom-rd-standards'
$sourceDir = Join-Path $skillDir 'references\source-documents'
$mapPath = Join-Path $skillDir 'references\standards-map.md'
$guideDir = Join-Path $agentsDir 'references\quick-guides'
$functionalReferenceNames = @(
'01-project-init-and-architecture.md',
'02-requirements-and-traceability.md',
'03-code-standards.md',
'04-database-and-data-model.md',
'05-api-and-rd-cloud-integration.md',
'06-security-and-secrets.md',
'07-repository-and-change-management.md',
'08-ci-artifacts-and-release.md',
'09-testing-and-deployment.md'
)
$requiredPaths = @(
(Join-Path $ProjectRoot 'AGENTS.md'),
(Join-Path $agentsDir 'INDEX.md'),
(Join-Path $skillDir 'SKILL.md'),
$mapPath,
$sourceDir,
$guideDir
)
$missing = $requiredPaths | Where-Object { -not (Test-Path -LiteralPath $_) }
if ($missing) {
throw "Missing required paths: $($missing -join '; ')"
}
$sourceFiles = Get-ChildItem -LiteralPath $sourceDir -File -Filter '*.md'
if ($sourceFiles.Count -ne 19) {
throw "Expected 19 source documents; found $($sourceFiles.Count)."
}
$invalidSourceNames = $sourceFiles | Where-Object { $_.Name -notmatch '^[0-9]{2}-[a-z0-9-]+\.md$' }
if ($invalidSourceNames) {
throw "Non-standard source filenames: $($invalidSourceNames.Name -join ', ')"
}
$legacyTextFiles = Get-ChildItem -LiteralPath $sourceDir -File -Filter '*.txt'
if ($legacyTextFiles) {
throw "Legacy TXT source documents remain: $($legacyTextFiles.Name -join ', ')"
}
$standardsMap = Get-Content -LiteralPath $mapPath -Raw
$unindexedSources = $sourceFiles | Where-Object { $standardsMap -notmatch [regex]::Escape($_.Name) }
if ($unindexedSources) {
throw "Source documents missing from standards map: $($unindexedSources.Name -join ', ')"
}
$guideFiles = Get-ChildItem -LiteralPath $guideDir -File -Filter '*.md'
if ($guideFiles.Count -ne 13) {
throw "Expected 13 quick guides; found $($guideFiles.Count)."
}
$index = Get-Content -LiteralPath (Join-Path $agentsDir 'INDEX.md') -Raw
$unindexedGuides = $guideFiles | Where-Object { $index -notmatch [regex]::Escape($_.Name) }
if ($unindexedGuides) {
throw "Quick guides missing from index: $($unindexedGuides.Name -join ', ')"
}
$missingFunctionalReferences = $functionalReferenceNames | Where-Object {
-not (Test-Path -LiteralPath (Join-Path $skillDir "references\$_"))
}
if ($missingFunctionalReferences) {
throw "Missing functional references: $($missingFunctionalReferences -join ', ')"
}
$skill = Get-Content -LiteralPath (Join-Path $skillDir 'SKILL.md') -Raw
$unlinkedFunctionalReferences = $functionalReferenceNames | Where-Object {
$skill -notmatch [regex]::Escape($_) -or $index -notmatch [regex]::Escape($_)
}
if ($unlinkedFunctionalReferences) {
throw "Functional references missing from SKILL.md or INDEX.md: $($unlinkedFunctionalReferences -join ', ')"
}
Write-Output "Agent starter is valid: 19 source documents, 13 quick guides, and 9 functional references are indexed."