| name | surround-scm-extractor |
| description | Extracts files from Surround SCM 2015.1.0 using CLI automation. Discovers projects (mainline/branch) by keyword, searches files by pattern, retrieves by path/label/timestamp with modular extraction strategy. Use when user asks "extract from Surround", "get SCM files", "download from repository", "提取SCM文件", "从Surround下载", "get source code from SCM", or needs source code/configs/documents from Surround SCM repositories. |
Surround SCM Extractor
Intelligently extracts files from Surround SCM 2015.1.0 repositories through CLI automation.
Configure Credentials (One-time Setup)
Recommended: Configure persistent authentication via Surround SCM GUI to eliminate repetitive credential parameters.
🔴 CHECKPOINT · 首次凭证配置:若用户首次使用 sscm(无 -y/-z 也无 GUI 持久化凭证),必须暂停并引导用户完成 GUI 登录(勾选「Always log in」)。这是用户必须亲自操作的步骤,agent 无法代劳。配置完成前所有 sscm 命令都会失败。
Quick setup:
- Open Surround SCM Desktop Client (GUI)
- Connect to server with ✅ "Always log in with this username and password" checked
- Credentials persist in Windows Credential Manager (encrypted)
After setup:
# Commands work without -y and -z parameters
sscm lsmainline
sscm ls -b"Project" -p"Project"
Credential setup provides: 60% code reduction, no passwords in command history, Windows-encrypted storage.
Detailed setup guide: See credential_setup.md for complete instructions, troubleshooting, and security notes.
Quick Start
Critical: NO space between flag and value: -y"user:pass" NOT -y "user:pass"
Note: After configuring default credentials (see above), -y and -z can be omitted from all commands below.
1. Discover Project (Progressive)
Try mainline first (most projects are mainlines):
# With default credentials configured (recommended)
sscm lsmainline | Select-String "keyword"
# Or with explicit credentials
sscm lsmainline -y"user:pass" -z"server:port" | Select-String "keyword"
If not found, try branch search:
# 1. Find parent mainline
sscm lsmainline ... | Select-String "parent_keyword"
# 2. List branches under parent
sscm lsbranch -b"ParentMainline" -p"ParentMainline" ... | Select-String "keyword"
Note: Each project has unique name, not generic "Mainline".
Fallback if find_project.py unavailable (no Python / 0 hits): iterate lsbranch over common parents inline:
$parents = @("Preh_SSCM_TrainingProject","Preh_Root","DaimlerChrysler_Root","Preh_Development_Server","Preh_ProcessImprovement")
foreach ($p in $parents) {
$hits = sscm lsbranch -b"$p" -p"$p" 2>$null | Select-String "keyword"
if ($hits) { Write-Host "[$p]"; $hits }
}
# Still 0 → parent unknown: ask user for any project fragment, broaden keyword
🔴 CHECKPOINT · 项目确认:发现候选项目后、执行任何 sscm get 之前,必须向用户展示命中列表并等待确认。绝不在用户未确认项目名时直接开跑提取(项目名错误会拉错整个仓库)。
Complex scenarios: See branch_workflows.md
2. Verify Access (Lightweight)
Quick permission check before large operations:
# List top-level only (fast)
sscm ls -b"ProjectName" -p"ProjectName"
# Or with explicit credentials: ... -y"user:pass" -z"server:port"
Error handling: See troubleshooting.md
3. Extract Files
Check labels first (avoid no-label scenarios):
sscm lslabel -b"Branch" -p"Parent"
# If returns empty, branch has no labels - will extract current version
Basic extraction:
# Single file
sscm get "file.ext" -b"Project" -p"Project/Path" -d"output" -wreplace
# Small directory extraction
sscm get /SubDir -b"ProjectName" -p"ProjectName" -r -d"$PWD\output" -wreplace
# Specific version
sscm get ... -l"RELEASE_1.0" ... # By label
sscm get ... -s"2026020100:00:00" ... # By timestamp
Finding files when user is unsure of location:
# Output to file first (prevents truncation, enables re-search)
sscm ls -b"Project" -p"Project" -r > all_files.txt
Get-Content all_files.txt | Select-String "\.ldf" -CaseSensitive:$false # case-insensitive
Get-Content all_files.txt | Select-String "\.ldf" -Context 3,0 # with dir context
⚠️ Large directories & scattered files:
🔴 CHECKPOINT · 大目录策略:递归列出文件数 > 200 或目录层级 ≥ 3 时,必须切换到模块化分批提取(见下方 ✅ Step 2),禁止对整个 root 直接 sscm get -r(会静默跳过子目录)。
Recursive extraction (-r) of large directories may silently skip subdirectories. Extract by mid-level functional module instead:
# ✅ Step 1: Locate all target files
sscm ls -b"Project" -p"Project" -r > all_files.txt
Get-Content all_files.txt | Select-String "\.ldf" -Context 3,0
# ✅ Step 2: Extract by functional module (medium granularity)
# Granularity rule: split at depth-2 functional dirs (e.g. /03_Software/01_Doc, .../02_SW/01_Sources);
# each module should contain ~20-100 files. Too few = too many commands; too many = silent skip risk.
sscm get /03_Software/01_Doc -b"Project" -p"Project" -r -d"output"
sscm get /03_Software/02_SW/07_Workspaces/CANoe -b"Project" -p"Project" -r -d"output"
sscm get /03_Software/02_SW/01_Sources -b"Project" -p"Project" -r -d"output"
# ❌ Avoid: entire root (unreliable) or per-file (too many commands)
Verify extraction (MANDATORY after each operation):
🔴 CHECKPOINT · 提取验证:每次 sscm get 完成后必须立即用下方脚本/命令验证文件数与类型,发现缺口前不得进入下一步。验证未通过 → 触发 失败模式 F2 静默跳过修复流程。
# Quick inline verification
$files = Get-ChildItem -Path "output_dir" -Recurse -Filter "*.ldf" -File
Write-Host "✅ Extracted: $($files.Count) files" -ForegroundColor Green
# Or use verification script for detailed report (path relative to this skill's scripts/ dir)
python scripts/verify_extraction.py output_dir --expected-exts .c,.h
Failure Modes
主文 inline 三段式表 — 不必跳转 troubleshooting.md 即可处理 80% 常见失败。完整诊断见 troubleshooting.md。
| # | 触发条件 | 一线修复 | 仍失败兜底 |
|---|
| F1 | sscm lsmainline 返回空 / "Unable to find mainline" | 项目是 branch 不是 mainline → sscm lsbranch -b"Parent" -p"Parent" 在 common parents 下找 | 用 find_project.py "keyword" --test-access 模糊搜 mainline+branch |
| F2 | sscm get -r 提取数 < ls 显示数(静默跳过子目录) | 切模块化分批:sscm get /Module/Sub -r 按 mid-level 模块逐个提取 | 用 verify_extraction.py --compare all_files.txt 定位缺口 → 逐文件 sscm get "file" 补齐 |
| F3 | security access denied | 验证用户对该 project 有 read 权限 → 联系 SCM admin | 换已知可访问的项目测试,排除账号问题 |
| F4 | Incorrect input format / flag 报错 | 检查 flag 与值间无空格:-y"u:p" 而非 -y "u:p" | 查 cli_commands.md 核对精确语法 |
| F5 | lslabel 返回空(branch 无 label) | 该 branch 无版本标签 → 提取当前版本,或改用 timestamp -s"YYYYMMDDHH:MM:SS" | 问用户目标版本的近似日期,用 timestamp 兜底 |
| F6 | 提取产物含 .zip/.7z/.rar 但解压后内容缺失/损坏 | 重新解压:Expand-Archive(zip)/ 7z x(7z/rar),检查压缩包完整性 | 原始归档可能损坏 → 重新 sscm get 该归档文件 |
Anti-Patterns(不要做什么)
危险动作与反模式清单 — 出现以下行为时应立即停止并修正。
| # | ❌ 不要做 | 为什么 | ✅ 应该做 |
|---|
| AP1 | 在用户未确认项目名时直接 sscm get | 项目名错误会拉错整个仓库,浪费时间且污染 output 目录 | 🔴 先展示 find_project/lsmainline 命中列表,等用户确认 |
| AP2 | flag 与值之间加空格(-y "u:p") | sscm CLI 解析失败,报 Incorrect input format | 紧贴:-y"u:p"、-b"Proj"、-p"Path" |
| AP3 | get 完成后跳过验证直接进入下一步 | 静默跳过无法察觉,下游会基于不完整产物工作 | 🔴 每次 get 后立即 verify(count + 类型) |
| AP4 | 在命令行明文传递密码(-y"user:pass") | 密码进入 shell history、进程列表,有泄露风险 | 优先 GUI 持久化凭证;次选 sscm_config.json;明文仅用于一次性脚本 |
| AP5 | 递归列出全部文件(ls -r)当作默认动作 | 大仓库输出截断、context bloat | 仅当用户明确要求 "show all files" / "list structure" 时才 -r |
| AP6 | 假设 label 名存在而不先 lslabel 检查 | label 拼错或不存在会导致 get -l 失败或拉到错误版本 | 先 lslabel 确认,无 label 则走 timestamp 兜底 |
Deep-dive: See best_practices.md for search strategies, granularity guidelines, and real-world examples.
Archives: If extracted files contain .zip/.7z/.rar, decompress automatically:
Get-ChildItem -Path "output" -Recurse -Include *.zip,*.7z,*.rar | ForEach-Object {
$dest = Join-Path $_.DirectoryName $_.BaseName
if ($_.Extension -eq ".zip") { Expand-Archive $_.FullName -DestinationPath $dest -Force }
else { & "C:\Program Files\7-Zip\7z.exe" x $_.FullName -o"$dest" -y } # .7z/.rar needs 7-Zip
}
# After decompress: re-run verify_extraction.py to validate expanded contents
Nested/password-protected archives: see best_practices.md.
Default behavior: Do NOT recursively list all files unless user explicitly requests "show all files" or "list structure".
Reference Documentation
Scripts
All scripts support --help for full usage.
| Script | Purpose | Example |
|---|
find_project.py | Fuzzy project discovery (mainlines + common parent branches); ranks by relevance, suggests typo corrections | python scripts/find_project.py "Ctrl_AI" --test-access |
parse_sscm_output.py | Parses sscm ls -r output, reconstructs full paths, filters by ext/regex | python scripts/parse_sscm_output.py --input all_files.txt --filter-ext ".ldf" --context |
verify_extraction.py | Validates file counts/types, compares against search to catch silent failures | python scripts/verify_extraction.py output_dir --compare all_files.txt --expected-exts .ldf |
Troubleshooting
Common issues are covered inline by Failure Modes (F1-F6) above. For exhaustive diagnosis, connection issues, and edge cases, see troubleshooting.md. Quick connection test: sscm lsmainline (defaults) or sscm lsmainline -y"user:pass" -z"server:port" (explicit).
Best Practices
Core principles for reliable extraction (most already enforced by checkpoints/Failure Modes above):
- Output large
ls to file — prevents truncation, enables offline re-search
- Case-insensitive search — handles mixed extension cases (
.ldf/.LDF); use Select-String -CaseSensitive:$false
- Search with context (
Select-String -Context 3,0) — reveals parent directory structure
Principles #modular-extraction / #verify-after-each are already covered by 🔴 CHECKPOINT 大目录策略 + 🔴 CHECKPOINT 提取验证 above — do not duplicate.
Detailed strategies: See best_practices.md for comprehensive search patterns, extraction workflows, verification checklists, and complete real-world examples.
Progressive Disclosure
Three-level approach to minimize context bloat: (1) top-level listing only → (2) PowerShell pipeline filter → (3) recursive -r flag (only when explicitly requested). See "Default behavior" note above.
Key principle: Never recursively list files unless user asks for "detailed structure" or "show all files".