关于 workspace
workspace 是用于围绕父级 Git 仓库中的共享团队上下文协调多仓库工作区的技能。它会发现直接子仓库,支持将其链接为子模块或加入忽略列表,并可在不使用注册表文件的情况下审计仓库状态。
主要功能
- 01初始化共享 .adlc/ 结构
- 02发现直接子仓库
- 03将仓库链接为 Git 子模块
- 04改为忽略子仓库
- 05审计分支和工作区状态
- 06通过 dry run 预览变更
适用场景
- 01为共享团队上下文设置父仓库
- 02将子仓库注册为子模块
- 03检查工作区改动和未推送提交
- 04验证子仓库能否查看共享上下文
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tikalk/ adlc-team-skills --skill workspace安装后在 Claude Code 中输入/workspace确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/bash/paths.shsetup-workspace.shworkspace.shscripts/powershell/paths.ps1setup-workspace.ps1workspace.ps1详细介绍
workspace
概述
用于共享团队上下文的多仓库工作区协调器。父仓库存放共享决策(PDR、ADR、CDR),位于 .adlc/ 下,由 product-specify、architect-specify 和 team-levelup 创建。系统会在深度为 1 的位置发现子实现仓库,并可选择将其链接为 Git 子模块,以便使用 git clone --recursive 克隆整个工作区。
不需要 workspace.yml,也不需要注册表文件。完全依靠约定:
- 父仓库 = 当前工作目录(必须是 Git 仓库)
- 子仓库 = 深度为 1 且包含
.git/的子目录 - 共享上下文 = 父仓库根目录中的
.adlc/
适用场景
- 首次设置(
--init):创建.adlc/目录结构、配置.gitignore约定,并可选择链接子仓库。 product-specify或architect-specify在父仓库中创建共享 PDR/ADR 后,且你有多个并列的实现仓库时。- 将新的子仓库克隆到工作区后,想将其注册为子模块(
--link)或忽略它们(--ignore-only)时。 - 审计工作区状态:检查工作树是否有未提交更改、提交是否尚未推送,以及父仓库子模块引用与子仓库 HEAD 之间的 SHA 是否偏移。
- 验证子仓库是否能访问父仓库中的
.adlc/共享上下文。
不适合使用 --init 的场景
- 工作区已初始化:改用
/workspace --status进行审计。 - 只审计子仓库状态:使用
/workspace(只读发现 + 状态)。 - 初始化后链接更多子仓库:直接使用
/workspace --link。
用户输入
$ARGUMENTS
命令
| 命令 | 用途 |
|---|---|
/workspace --init | 初始化:创建 .adlc/ 结构、配置 .gitignore、发现子仓库 |
/workspace | 发现子仓库并显示状态摘要(只读) |
/workspace --link | 将子仓库转换为 Git 子模块(要求父工作树干净) |
/workspace --status | 详细审计:分支、脏状态、未推送提交、SHA 偏移、.adlc 是否存在 |
/workspace --ignore-only | 将子仓库添加到 .gitignore,而不是创建子模块 |
/workspace --init --link | 一步完成初始化并链接子仓库 |
/workspace --init --ignore-only | 初始化并将子仓库添加到 .gitignore |
/workspace --dry-run | 预览变更但不执行(可与 --init、--link、--ignore-only 组合使用) |
/workspace --force | 转换已由父索引跟踪的仓库(要求工作树干净) |
执行
初始化模式(--init)
运行初始化设置脚本以创建 .adlc/ 结构、检查 .gitignore 约定并发现子仓库:
# Bash
scripts/bash/setup-workspace.sh --json
# PowerShell
scripts/powershell/setup-workspace.ps1
初始化设置输出(JSON):
{
"REPO_ROOT": "/path/to/parent",
"ADLC_DIR": "/path/to/parent/.adlc",
"ADLC_DIRS_CREATED": [".adlc/product", ".adlc/drafts", ".adlc/drafts/pdr"],
"GITIGNORE_EXISTS": true,
"GITIGNORE_RULES_MISSING": [".adlc/"],
"CHILD_REPOS": [
{"name": "backend-api", "path": "/path/to/parent/backend-api", "remote": "[email protected]:org/backend-api.git", "is_submodule": false, "is_tracked": false}
],
"CHILD_COUNT": 1,
"BRANCH": "main"
}
创建的目录:
.adlc/
├── product/ # PDRs (product-specify, product-init)
├── architecture/ # ADRs (architect-specify, architect-init)
├── context/ # CDRs (team-levelup, team-init)
├── skills/ # Team skills metadata
└── drafts/ # Draft artifacts before clarification
├── pdr/
├── adr/
├── cdr/
├── skills/
└── evals/
初始化设置完成后,如果还指定了 --link 或 --ignore-only,则继续执行下方对应的操作模式。
审计/链接模式(默认、--link、--status、--ignore-only)
运行工作区协调器脚本:
# Bash
"$(dirname "$0")/../scripts/bash/workspace.sh" --json [--link] [--status] [--dry-run] [--force] $ARGUMENTS
解析 JSON 输出并将其呈现给用户。
输出约定
初始化模式输出
由 setup-workspace.sh --json 发出(见上文)。
审计/链接模式输出
由 workspace.sh --json 发出:
{
"PARENT_REPO": "/abs/path/to/parent",
"PARENT_BRANCH": "main",
"PARENT_HAS_ADLC": true,
"MODE": "discover|link|status",
"DRY_RUN": false,
"DISCOVERED_COUNT": 3,
"REGISTERED_COUNT": 2,
"SKIPPED_COUNT": 1,
"ERROR_COUNT": 0,
"REPOS": [
{
"name": "backend-api",
"path": "/abs/path/to/parent/backend-api",
"remote": "[email protected]:org/backend-api.git",
"branch": "main",
"dirty": false,
"unpushed": 0,
"is_submodule": true,
"parent_sha": "abc1234",
"child_sha": "abc1234",
"sha_drift": false,
"has_adlc": false
}
],
"ERRORS": []
}
初始化阶段
阶段 1:创建 .adlc/ 结构
如果 .adlc/ 目录树不存在,设置脚本会创建该目录树(包括 product/、drafts/ 以及各系列对应的草稿子目录——共享布局将 .adlc/ 用于存放机器流水线状态)。这是共享上下文目录,其他技能会在其中写入草稿和流水线状态;已发布的决策记录和编译后的交付物则存放在 docs/adlc/ 下。
幂等:已存在的目录不会重复创建。
阶段 2:.gitignore 配置
设置脚本会检查 .gitignore 是否符合工作区规范,并报告缺失的规则。
允许列表模型 — 不再整体忽略 .adlc/。通过 .adlc/* 忽略机器流水线状态,并重新包含已跟踪的例外项;docs/adlc/ 下的已发布内容始终处于跟踪状态:
# agent-install surface (regenerated)
.agents/
.opencode/
.claude/
.cursor/
.codex/
.gemini/
.qwen/
.devin/
.tabnine/
skills-lock.json
.skills.json
.mcp.json
.events.json
.pytest_cache/
.ruff_cache/
# machine pipeline + runtime state (tracked exceptions follow)
.adlc/*
!.adlc/init-options.json
!.adlc/workspace.yml
!.adlc/drafts/
!.adlc/evals/
.adlc/evals/results/
!.adlc/memory/
.adlc/memory/*
!.adlc/memory/evals/
!.adlc/memory/evals/holdout.json
# generated reports (legacy name kept during transition)
.adlc/team-learn-report.md
.adlc/team-levelup-report.md
# knowledge graph (generated)
graphify-out/
允许列表仅在 scripts/bash/paths.sh 中定义一次(GITIGNORE_RULES_ALLOWLIST,并在 scripts/powershell/paths.ps1 中保持镜像);设置脚本会引入该定义,并报告任何缺失的规则。已跟踪的旧文件会继续正常工作——gitignore 只会限制未跟踪的文件。
操作:如果 GITIGNORE_RULES_MISSING 不为空,请将缺失的规则添加到 .gitignore。不要删除现有规则。如果进行了更改且未处于 --dry-run 模式,请使用提交消息 [workspace] Configure .gitignore for workspace conventions 提交。
阶段 3:子仓库发现
检查设置输出中发现的子仓库。
已发现的仓库:
## Discovered Child Repos
| # | Repo | Remote | Submodule? | Tracked? |
|---|------|--------|------------|----------|
| 1 | **backend-api** | [email protected]:org/backend-api.git | No | No |
| 2 | **frontend** | [email protected]:org/frontend.git | Yes | N/A |
Reply: Y to proceed with --link/--ignore-only, or adjust.
阶段 4:子仓库操作(可选)
如果将 --link 或 --ignore-only 与 --init 组合使用,请在初始化设置后执行相应操作。
--link(子模块注册)
委托给 workspace.sh --link。将执行以下安全检查:
- 父工作树必须干净(子仓库之外没有未提交的更改)
- 子仓库必须配置远程
originURL - 远程 URL 必须使用允许的方案(
https://、git@、ssh://)—— 其他方案(例如http://、file://)会报告为错误并跳过 - 跳过已注册的子模块(幂等)
- 父索引中已跟踪的仓库需要使用
--force - 先通过
--dry-run预览,并在链接前向用户确认
--ignore-only(忽略而非子模块)
将每个已发现的子仓库添加到 .gitignore,而不是创建子模块。
对于每个子仓库:
- 如果已在父索引中跟踪:
git rm --cached <name>(从索引中移除,但保留磁盘上的文件) - 如果
<name>/尚未存在于.gitignore中,则将其添加进去 - 跳过已在
.gitignore中的仓库(幂等)
如果进行了更改,请使用提交消息 [workspace] Add child repos to .gitignore 提交。
适用场景:子仓库确实是独立项目,团队成员会单独管理它们。
阶段 5:输出摘要
## Workspace Init Complete
### .adlc/ Structure
- Created: 7 directories under `.adlc/` (`product/`, `drafts/`, `drafts/{pdr,adr,cdr,skills,evals}/`)
### .gitignore
- Rules added: 5
- Rules verified: 12
### Child Repos
- Discovered: 3
- Registered as submodules: 2
- Ignored: 0
- Skipped (already submodules): 1
### Next Steps
1. Create product decisions: `/product-specify`
2. Create architecture decisions: `/architect-specify`
3. Audit workspace health: `/workspace --status`
发现规则
| 规则 | 行为 |
|---|---|
| 深度 | 仅 1 层(父目录根目录的直接子目录) |
| 检测 | 目录包含 .git/ 目录或 .git 文件 |
| 排除项 | node_modules、.venv、venv、dist、build、target、.idea、.vscode、.git、.cache、.specify |
| 无配置文件 | 没有 workspace.yml — 纯自动发现 |
共享团队上下文(.adlc/)
父仓库的 .adlc/ 目录是团队上下文的唯一事实来源。
该目录由 --init 创建,并由其他技能维护:
| 产物 | 路径 | 创建者 |
|---|---|---|
| PDR 草稿 | .adlc/drafts/pdr/(已接受 → docs/adlc/memory/pdr/) | product-specify、product-init |
| ADR 草稿 | .adlc/drafts/adr/(已接受 → docs/adlc/memory/adr/) | architect-specify、architect-init |
| CDR | team-ai-directives adlc 分支(本地草稿位于 .adlc/drafts/cdr/) | team-levelup、team-init |
| 技能 | Agent 技能目录(.agents/skills/ 镜像) | team-skills |
| 目录结构 | .adlc/ 树 | workspace --init(此技能) |
在审计模式(默认)下,此技能不会创建或修改 .adlc/ 内容。它只会:
- 验证父仓库是否有
.adlc/(若缺失则发出警告)。 - 检查每个子仓库是否有自己的
.adlc/(仅提供信息)。
安全性
--init是安全的:只创建目录并报告缺失的.gitignore规则;绝不覆盖现有内容。.gitignore的更改是增量式的:只添加缺失的规则;绝不移除现有规则。- 默认只读:
/workspace和/workspace --status不会进行任何更改。 --link要求父级工作树干净:子仓库以外的未提交更改会中止操作。--force会从父级 Git 索引中移除子目录(git rm --cached),然后将其重新添加为子模块。要求工作树干净。- 幂等:重新运行时会跳过已注册的子模块、已忽略的仓库和已创建的目录。
- 没有远程
origin的子仓库会被报告为错误,并在--link过程中跳过。 --dry-run会预览所有更改,但不执行。
常见的错误理由
| 错误理由 | 错误所在 | 应该这样做 |
|---|---|---|
“我会手动用 mkdir 创建 .adlc/” | 会遗漏完整的目录树和 .gitignore 约定 | 运行 --init 以完成初始化 |
“我会添加 workspace.yml 来显式列出仓库” | 增加配置开销;自动发现更简单,也足够满足需求 | 使用深度为 1 的发现;如有需要,通过 .gitignore 排除 |
“我会跳过 .gitignore 设置” | 可能会提交本地 Agent 状态(.agents/、.opencode/) | 让 --init 配置约定 |
“我也会在子仓库中创建 .adlc/” | 违背单一事实来源模型 | 只在父仓库中保留 .adlc/;子仓库引用父仓库 |
“我会跳过 --link 的工作树干净检查” | 可能会丢失父仓库中未提交的更改 | 要求工作树干净;告诉用户先提交或暂存 |
| “我会用工作树代替子模块” | 工作树用于隔离功能开发,而非多仓库协同 | 使用子模块来跟踪多仓库链接 |
“我会对所有内容使用 --ignore-only,而不是子模块” | 会失去工作区协同的优势 | 对受跟踪的仓库使用 --link;仅对独立项目使用 --ignore-only |
危险信号
- 未检查父级工作树是否干净就运行
--link。 - 父仓库在子仓库之外有未提交更改时运行
--force。 - 在子仓库中创建
.adlc/内容(父仓库是唯一的来源)。 - 添加
workspace.yml或注册表文件(仅使用约定,不需要配置)。 - 在发现过程中重新纳入
.specify——脚本会将其明确排除(参见 Discovery Rules),且此排除是有意为之。 - 在
--link过程中修改子仓库内容(只会更改父级索引)。 - 存在本地 Agent 目录时跳过
.gitignore设置。
验证
- 父仓库是 Git 仓库。
-
--init会创建.adlc/及其子目录(product/、drafts/、drafts/{pdr,adr,cdr,skills,evals}/)。 -
--init会报告缺失的.gitignore规则(只添加,不移除)。 -
--init具有幂等性(第二次运行会报告创建了 0 个目录)。 - 父级
.adlc/存在(审计模式下若缺失则发出警告)。 - 在深度为 1 的位置发现子仓库(排除
node_modules、.venv等)。 - 只有父级工作树干净时才运行
--link。 - 跳过已注册的子模块(幂等)。
- 将没有远程
origin的子仓库报告为错误。 -
--status会报告每个子仓库的分支、脏状态、未推送数量、SHA 偏差和.adlc是否存在。 -
--ignore-only会将仓库添加到.gitignore,并从父级索引中移除。 -
--dry-run不会产生文件更改。 - JSON 输出符合 init 和 audit 模式下的 Output Contract 架构。
与现有技能的集成
| 技能 | 关联方式 |
|---|---|
product-specify | 在运行 --init 后,在父级 .adlc/drafts/pdr/ 中创建 PDR 草案 |
architect-specify | 在运行 --init 后,在父级 .adlc/drafts/adr/ 中创建 ADR 草案 |
team-levelup | 在运行 --init 后创建 CDR 草案(发布到 team-ai-directives 的 adlc 分支) |
team-boot | 在会话开始时加载父级 .adlc 上下文 |
team-setup | 配置 Agent 目录(.agents/、.opencode/),与 --init 互为补充 |
与 12-Factor 的对齐
因子 XI(指令即代码)——建立一个受版本控制的多仓库工作区:共享决策存放在父级仓库中,实现仓库则通过子模块链接,或按惯例忽略。