关于 workspace
workspace 是面向 Claude Code 的技能,用于分析单仓库、多仓库及混合工作区。它整理模块、依赖、API 合约和关键文件,帮助编码任务掌握跨项目背景。
主要功能
- 01识别单仓库与多仓库结构
- 02梳理模块依赖和 API 关系
- 03提取 API 与类型合约
- 04定位任务相关文件
- 05生成工作区分析文档
适用场景
- 01了解前后端仓库间的依赖
- 02修改前核对共享类型与 API 合约
- 03为模块任务查找相关文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ alinaqi/ maggy --skill workspace安装后在 Claude Code 中输入/workspace确认已加载。
详细介绍
工作区分析技能
为 Claude Code 提供动态的多仓库和 monorepo 感知能力。分析工作区拓扑,跟踪 API 契约,并维护跨仓库上下文。
问题
当你有独立的前端/后端仓库(或包含多个应用的 monorepo)时,Claude Code 会孤立运行。它不了解:
- 模块/仓库之间的 API 契约
- 共享类型和接口
- 完整的系统架构
- 跨仓库依赖
- 系统其他部分发生了哪些变化
这会导致:
- 重复定义类型
- API 契约不匹配
- 直到运行时才发现破坏性变更
- Claude 重新实现其他地方已有的功能
解决方案:动态工作区分析
与容易过时的静态清单不同,Claude 会动态分析工作区,并生成通过钩子保持最新的上下文文档。
┌─────────────────────────────────────────────────────────────────┐
│ WORKSPACE ANALYSIS SYSTEM │
├─────────────────────────────────────────────────────────────────┤
│ │
│ /analyze-workspace (Full Analysis - ~2 min) │
│ ├── Topology discovery (monorepo vs multi-repo) │
│ ├── Dependency graph (who calls whom) │
│ ├── Contract extraction (OpenAPI, GraphQL, types) │
│ └── Key file identification (what to load when) │
│ │
│ /sync-contracts (Incremental - ~15 sec) │
│ ├── Check contract source files for changes │
│ ├── Update CONTRACTS.md with diffs │
│ └── Validate consistency │
│ │
│ Hooks (Automatic) │
│ ├── Session start: Staleness advisory (~5 sec) │
│ ├── Post-commit: Auto-sync if contracts changed (~15 sec) │
│ └── Pre-push: Validation gate (~10 sec) │
│ │
└─────────────────────────────────────────────────────────────────┘
工作区分类
检测模式
| 类型 | 指示项 | 文件访问方式 |
|---|---|---|
| Monorepo | pnpm-workspace.yaml、nx.json、turbo.json、lerna.json | 直接(同一目录树) |
| Multi-repo | 使用独立 .git 的同级目录 | 通过符号链接或路径 |
| Hybrid | Monorepo + 外部仓库依赖 | 混合 |
| Single | 单个应用,没有工作区配置 | 不适用(使用 existing-repo) |
Monorepo 检测
# Check for monorepo indicators
ls package.json pnpm-workspace.yaml lerna.json nx.json turbo.json 2>/dev/null
ls apps/ packages/ services/ libs/ modules/ 2>/dev/null
多仓库检测
# Check sibling directories for related repos
ls -la ../*.git 2>/dev/null
cat ../*/.git/config 2>/dev/null | grep "url"
# Look for naming patterns
ls .. | grep -E "(frontend|backend|api|web|shared|common)"
多语言检测
# Find all package manifests
find . -maxdepth 4 -name "package.json" -o -name "pyproject.toml" \
-o -name "go.mod" -o -name "Cargo.toml" -o -name "pom.xml" \
-o -name "build.gradle" -o -name "Gemfile"
分析流程
阶段 1:拓扑发现(约 30 秒)
确定工作区结构:
## Discovery Checklist
1. [ ] Identify workspace root
2. [ ] Classify workspace type (monorepo/multi-repo/hybrid/single)
3. [ ] List all modules/apps/packages
4. [ ] Detect tech stack per module
5. [ ] Identify entry points per module
模块检测模式:
workspace-root/
├── apps/ → Application modules
│ ├── web/ → Frontend app
│ └── api/ → Backend app
├── packages/ → Shared packages
│ ├── ui/ → Component library
│ ├── types/ → Shared types
│ └── db/ → Database layer
├── services/ → Microservices
└── libs/ → Internal libraries
阶段 2:依赖图(约 60 秒)
为每个模块梳理:
1. 内部依赖
# TypeScript/JavaScript
grep -r "from ['\"]@" --include="*.ts" --include="*.tsx" | head -50
grep -r "workspace:" package.json
# Python
grep -r "from \." --include="*.py" | head -50
2. API 关系
# Find API calls
grep -rE "fetch|axios|httpx|requests\." --include="*.ts" --include="*.py" | \
grep -E "/api|localhost|127\.0\.0\.1" | head -30
3. 数据库连接
# Find DB access patterns
grep -rE "prisma|drizzle|sqlalchemy|sequelize|typeorm" --include="*.ts" --include="*.py"
阶段 3:契约提取(约 45 秒)
识别并解析 API 契约:
| 契约类型 | 检测方式 | 提取内容 |
|---|---|---|
| OpenAPI | openapi.json、swagger.yaml、/docs 端点 | 解析路径、架构 |
| GraphQL | schema.graphql、*.gql、/graphql 端点 | 解析类型、查询、变更 |
| tRPC | trpc 路由器文件、@trpc/* 导入 | 解析路由器定义 |
| Protobuf | *.proto 文件 | 解析服务、消息 |
| TypeScript | 共享的 .d.ts、导出的接口 | 解析导出的类型 |
| Pydantic | 含有 BaseModel 的 schemas/、models/ | 解析模型定义 |
| Zod | 含有 z.object 的 schemas/ | 解析架构定义 |
契约来源优先级:
- 生成的规范(openapi.json)——最准确
- 架构定义(Pydantic、Zod)——事实来源
- 类型导出(TypeScript .d.ts)——使用方契约
- 从代码推断——最后手段
阶段 4:关键文件识别(约 30 秒)
识别 Claude 在每种上下文中必须了解的文件:
| 类别 | 检测模式 | Token 优先级 |
|---|---|---|
| 路由定义 | **/routes/**、**/api/**、@app.get、@router | HIGH |
| 类型定义 | **/types/**、*.d.ts、schemas/、models/ | HIGH |
| 配置 | .env.example、config/、settings.py | MEDIUM |
| 入口点 | main.ts、index.ts、app.py、server.py | MEDIUM |
| API 客户端 | **/api/client*、**/lib/api* | HIGH |
| 数据库架构 | schema/、migrations/、prisma/schema.prisma | MEDIUM |
| 测试 | __tests__/、*_test.py、*.spec.ts | LOW(按需) |
生成的文档
所有文档都放在 _project_specs/workspace/ 中:
_project_specs/workspace/
├── TOPOLOGY.md # What modules exist, their roles
├── CONTRACTS.md # API specs, shared types (summarized)
├── DEPENDENCY_GRAPH.md # Who calls whom (visual + list)
├── KEY_FILES.md # What to load for each context
├── CROSS_REPO_INDEX.md # Capabilities across all modules
└── .contract-sources # Files to monitor for changes
TOPOLOGY.md 格式
# Workspace Topology
Generated: 2026-01-20T14:32:00Z
Analyzer: maggy/workspace-analysis
Workspace Type: Monorepo (Turborepo)
## Overview
┌─────────────────────────────────────────────────┐ │ apps/web (Next.js) ←→ apps/api (FastAPI) │ │ ↓ ↓ │ │ packages/shared-types ← packages/db │ └─────────────────────────────────────────────────┘
## Modules
### apps/web
- **Path**: /apps/web
- **Tech**: Next.js 14, TypeScript, TailwindCSS
- **Role**: Customer-facing dashboard
- **Consumes**: apps/api (REST), packages/shared-types
- **Entry**: src/app/layout.tsx
- **Key files**:
- `src/lib/api/client.ts` - API client (187 lines)
- `src/types/` - Frontend-specific types (12 files)
- **Token estimate**: ~15K (full), ~4K (summarized)
### apps/api
- **Path**: /apps/api
- **Tech**: FastAPI, Python 3.12, SQLAlchemy
- **Role**: REST API, business logic
- **Exposes**: OpenAPI at /docs (47 endpoints)
- **Consumes**: packages/db
- **Entry**: app/main.py
- **Key files**:
- `app/routes/` - All endpoints (8 routers)
- `app/schemas/` - Pydantic models (23 files)
- `openapi.json` - Generated spec
- **Token estimate**: ~22K (full), ~6K (summarized)
### packages/shared-types
- **Path**: /packages/shared-types
- **Tech**: TypeScript
- **Role**: Shared type definitions
- **Consumed by**: apps/web, apps/api (codegen)
- **Key files**:
- `src/index.ts` - All exports (340 lines)
- **Token estimate**: ~3K
### packages/db
- **Path**: /packages/db
- **Tech**: Drizzle ORM, TypeScript
- **Role**: Database schema, migrations
- **Consumed by**: apps/api
- **Key files**:
- `schema/` - Table definitions (8 files)
- `migrations/` - Migration history (23 files)
- **Token estimate**: ~8K (full), ~2K (schema only)
CONTRACTS.md 格式
# API Contracts
Generated: 2026-01-20T14:32:00Z
Last sync: 2026-01-20T16:45:00Z
Sources: 3 files monitored
## REST API: apps/api → apps/web
### Endpoints Summary (47 total)
| Domain | Count | Key Endpoints |
|--------|-------|---------------|
| /api/auth | 5 | POST /login, POST /register, POST /refresh |
| /api/users | 6 | GET /me, PATCH /me, GET /:id |
| /api/campaigns | 8 | CRUD + POST /bulk, GET /analytics |
| /api/analytics | 12 | GET /dashboard, GET /timeseries, GET /funnel |
| /api/settings | 4 | GET /, PATCH /, GET /integrations |
### Key Types
```typescript
// Campaign domain (from apps/api/app/schemas/campaign.py)
interface Campaign {
id: string;
name: string;
status: 'draft' | 'active' | 'paused' | 'completed';
budget: number;
target_audience: TargetAudience;
created_at: string;
updated_at: string;
}
interface CampaignCreate {
name: string;
budget: number;
target_audience?: TargetAudience;
}
// Auth domain (from apps/api/app/schemas/auth.py)
interface User {
id: string;
email: string;
name: string;
role: 'user' | 'admin';
}
interface TokenPair {
access_token: string;
refresh_token: string;
expires_in: number;
}
契约验证状态
| 检查项 | 状态 | 详情 |
|---|---|---|
| OpenAPI 与路由匹配 | ✅ | 已记录 47/47 个端点 |
| 类型与架构匹配 | ✅ | 已导出所有 Pydantic 模型 |
| 前端类型为最新 | ⚠️ | 需要重新生成 2 个类型 |
共享类型:packages/shared-types
导出的类型(共 34 个)
| 类别 | 类型 | 使用方 |
|---|---|---|
| 领域模型 | Campaign、User、Analytics | web、api |
| API 响应 | ApiResponse、PaginatedResponse | web |
| 工具类型 | DateRange、FilterParams | web、api |
数据库架构:packages/db
表(共 12 张)
| 表 | 关键列 | 关联 |
|---|---|---|
| users | id、email、name、role | campaigns、sessions |
| campaigns | id、user_id、name、status | analytics、targets |
| analytics | id、campaign_id、date、metrics | campaigns |
### DEPENDENCY_GRAPH.md Format
```markdown
# Dependency Graph
Generated: 2026-01-20T14:32:00Z
## Visual Overview
┌─────────────────┐
│ packages/db │
│ (Drizzle ORM) │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐ │ apps/web │◄──│ apps/api │ │ (Next.js) │ │ (FastAPI) │ └────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────────┐ │ packages/shared-types │ │ (TypeScript) │ └─────────────────────────────────────────┘
## Dependency Matrix
| Module | Depends On | Depended By |
|--------|------------|-------------|
| apps/web | shared-types, apps/api (runtime) | - |
| apps/api | shared-types (codegen), db | apps/web |
| packages/shared-types | - | apps/web, apps/api |
| packages/db | - | apps/api |
## Import Analysis
### apps/web imports:
@repo/shared-types:23 个文件 apps/api(通过 fetch):15 个文件
### apps/api imports:
packages/db:12 个文件 packages/shared-types(代码生成):8 个文件
## API Call Graph
apps/web apps/api ───────── ──────── src/lib/api/client.ts ──────────► app/routes/auth.py └── login() POST /api/auth/login └── register() POST /api/auth/register
src/app/campaigns/page.tsx ─────► app/routes/campaigns.py └── getCampaigns() GET /api/campaigns └── createCampaign() POST /api/campaigns
KEY_FILES.md 格式
# Key Files by Context
## Context: Frontend API Integration
**When**: Modifying API calls, response handling, or API types in frontend
Load these files (~8K tokens):
apps/web/src/lib/api/client.ts # API 客户端实现 apps/web/src/types/api.d.ts # 前端 API 类型 apps/api/openapi.json # 完整 API 规范(或摘要) packages/shared-types/src/index.ts # 共享类型定义
## Context: Backend Endpoint Development
**When**: Adding/modifying API endpoints
Load these files (~12K tokens):
apps/api/app/routes/ # 现有路由模式 apps/api/app/schemas/ # Pydantic 模型(相关领域) apps/api/app/dependencies/ # 身份验证、数据库依赖 packages/db/schema/ # 相关表定义
## Context: Database Changes
**When**: Schema modifications, migrations, queries
Load these files (~6K tokens):
packages/db/schema/ # 所有表定义 packages/db/migrations/ # 最近 5 次迁移 apps/api/app/models/ # ORM 模型用法
## Context: Shared Types
**When**: Modifying interfaces used across modules
Load these files (~4K tokens):
packages/shared-types/src/ # 类型源文件 apps/web/src/types/api.d.ts # 使用方(前端) apps/api/app/schemas/ # 源(后端)
## Context: Authentication
**When**: Auth flow, sessions, tokens
Load these files (~5K tokens):
apps/api/app/routes/auth.py # 身份验证端点 apps/api/app/dependencies/auth.py # 身份验证中间件 apps/web/src/lib/auth/ # 前端身份验证处理 packages/shared-types/src/auth.ts # 身份验证类型
## Load-on-Demand Triggers
| Claude detects... | Load additionally |
|-------------------|-------------------|
| "check the API contract" | Full OpenAPI spec |
| Import from another module | That module's exports |
| Database query pattern | Full schema definitions |
| Test failure in other module | That module's test files |
| "breaking change" | Both sides of the contract |
CROSS_REPO_INDEX.md 格式
# Cross-Repository Capability Index
Generated: 2026-01-20T14:32:00Z
## Capabilities by Domain
### Authentication
| Capability | Location | Module | Type |
|------------|----------|--------|------|
| Login user | POST /api/auth/login | apps/api | endpoint |
| Register user | POST /api/auth/register | apps/api | endpoint |
| Refresh token | POST /api/auth/refresh | apps/api | endpoint |
| Auth context | src/contexts/AuthContext.tsx | apps/web | component |
| Auth hook | src/hooks/useAuth.ts | apps/web | hook |
| User type | src/auth.ts | shared-types | type |
| Session type | src/auth.ts | shared-types | type |
### Campaigns
| Capability | Location | Module | Type |
|------------|----------|--------|------|
| List campaigns | GET /api/campaigns | apps/api | endpoint |
| Create campaign | POST /api/campaigns | apps/api | endpoint |
| Campaign CRUD | app/routes/campaigns.py | apps/api | router |
| Campaign form | src/components/CampaignForm.tsx | apps/web | component |
| Campaign type | src/campaign.ts | shared-types | type |
| campaigns table | schema/campaigns.ts | packages/db | table |
### Analytics
| Capability | Location | Module | Type |
|------------|----------|--------|------|
| Dashboard data | GET /api/analytics/dashboard | apps/api | endpoint |
| Timeseries | GET /api/analytics/timeseries | apps/api | endpoint |
| Analytics hook | src/hooks/useAnalytics.ts | apps/web | hook |
| Chart components | src/components/charts/ | apps/web | components |
## Search Index
Before implementing new functionality, search this index:
Q:“如何获取当前用户?” A:使用 apps/web/src/hooks/useAuth.ts 中的 useAuth() hook 或使用 apps/api 中的 GET /api/users/me 端点
Q:“在哪里定义 Campaign 类型?” A:事实来源:packages/shared-types/src/campaign.ts 后端架构:apps/api/app/schemas/campaign.py 前端类型:apps/web/src/types/api.d.ts(生成)
Q:“如何添加新的 API 端点?” A:参考 apps/api/app/routes/campaigns.py 中的模式 在 apps/api/app/routes/init.py 中注册 将类型添加到 packages/shared-types 重新生成前端类型
Token 预算管理
上下文限制
┌─────────────────────────────────────────────────────────────────┐
│ TOKEN BUDGET ALLOCATION │
├─────────────────────────────────────────────────────────────────┤
│ Total context: ~200K tokens │
│ Reserve for output: ~50K tokens │
│ Working budget: ~150K tokens │
├─────────────────────────────────────────────────────────────────┤
│ P0 (Must have): 50K │ Current module (full) │
│ P1 (Should have): 40K │ Directly related modules (summary) │
│ P2 (Nice to have): 30K │ Contracts + shared types │
│ P3 (If room): 20K │ Decisions, todos, history │
│ Buffer: 10K │ Dynamic loading during session │
└─────────────────────────────────────────────────────────────────┘
自动摘要
加载跨模块上下文时,请进行摘要:
| 内容类型 | 完整加载阈值 | 摘要策略 |
|---|---|---|
| OpenAPI 规范 | < 50 个端点 | 仅保留端点和关键类型 |
| 类型文件 | < 30 个类型 | 仅保留导出的类型 |
| 路由文件 | < 200 行 | 仅保留签名和文档字符串 |
| 配置文件 | < 50 行 | 仅保留键(不包含值或机密信息) |
| 测试文件 | 从不完整加载 | 仅在明确请求时加载 |
上下文加载策略
┌─────────────────────────────────────────────────────────────────┐
│ CONTEXT LOADING HIERARCHY │
├─────────────────────────────────────────────────────────────────┤
│ Level 1: Always loaded (~5K tokens) │
│ ├── TOPOLOGY.md (workspace structure) │
│ ├── CONTRACTS.md (API summary) │
│ └── CROSS_REPO_INDEX.md (capability search) │
│ │
│ Level 2: Loaded based on current file (~15K tokens) │
│ ├── KEY_FILES.md recommendations for current context │
│ ├── Related module summaries │
│ └── Relevant type definitions │
│ │
│ Level 3: On-demand expansion (variable) │
│ ├── Full OpenAPI spec (when "check API contract") │
│ ├── Full type files (when modifying interfaces) │
│ └── Other module's full files (when cross-repo change) │
└─────────────────────────────────────────────────────────────────┘
多仓库文件访问
对于多仓库工作区(各自拥有独立的 .git 目录):
选项 1:同级目录约定(推荐)
~/code/
├── myapp-frontend/ # git repo
├── myapp-backend/ # git repo
├── myapp-shared/ # git repo
└── .workspace/ # workspace config (optional)
└── myapp.yaml
Claude 通过相对路径访问:../myapp-backend/
选项 2:工作区符号链接
# In frontend repo
mkdir -p .workspace/repos
ln -s ../../myapp-backend .workspace/repos/backend
ln -s ../../myapp-shared .workspace/repos/shared
选项 3:Git 子模块
# Add related repos as submodules (read-only)
git submodule add --depth 1 ../myapp-shared .workspace/shared
文件访问规则
## Multi-Repo Access Protocol
WHEN accessing files from another repo:
1. Use relative paths from workspace root
2. Read-only access (never modify other repos)
3. Cache contract files locally in _project_specs/workspace/cache/
4. Log cross-repo reads in decisions.md
BEFORE making cross-repo changes:
1. Document the change in BOTH repos' decisions.md
2. Create linked todos in BOTH repos
3. Implement in dependency order (shared → backend → frontend)
跨仓库变更检测
当 Claude 检测到会影响其他模块的变更时:
┌─────────────────────────────────────────────────────────────────┐
│ ⚠️ CROSS-REPO CHANGE DETECTED │
├─────────────────────────────────────────────────────────────────┤
│ This change affects: apps/api │
│ Specifically: Endpoint POST /api/campaigns expects new field │
│ │
│ Impact Analysis: │
│ ├── apps/web/src/lib/api/client.ts - needs update │
│ ├── packages/shared-types/src/campaign.ts - needs new field │
│ └── apps/api/app/schemas/campaign.py - source of change │
│ │
│ Recommended Order: │
│ 1. Update packages/shared-types first (source of truth) │
│ 2. Update apps/api schema │
│ 3. Regenerate frontend types │
│ 4. Update apps/web API client │
│ 5. Run /sync-contracts │
│ │
│ [Proceed with guidance] [Load full context] [Cancel] │
└─────────────────────────────────────────────────────────────────┘
变更影响模式
| 变更类型 | 影响对象 | 操作 |
|---|---|---|
| 新增 API 端点 | 前端客户端、类型 | 在两处添加并同步契约 |
| 修改响应 | 前端类型、测试 | 重新生成类型并更新测试 |
| 新增必填字段 | 所有使用方 | 遵循破坏性变更流程 |
| 重命名字段 | 所有使用方 | 迁移并弃用旧字段 |
| 新增共享类型 | 下次使用时的使用方 | 从 shared-types 导出 |
| 架构迁移 | API 模型、查询 | 执行迁移并验证查询 |
契约新鲜度系统
陈旧检测
# .contract-sources file (auto-generated)
# Files that define contracts - monitored for changes
# OpenAPI specs
apps/api/openapi.json
apps/api/docs/openapi.yaml
# Type definitions
packages/shared-types/src/index.ts
packages/shared-types/src/api.ts
# Pydantic schemas
apps/api/app/schemas/*.py
# Database schema
packages/db/schema/*.ts
新鲜度等级
| 等级 | 触发条件 | 操作 | 耗时 | 阻塞 |
|---|---|---|---|---|
| 1 | 会话开始 | 陈旧检查 | ~5s | 否 |
| 2 | 提交后 | 若契约有变更则自动同步 | ~15s | 否 |
| 3 | 推送前 | 验证关卡 | ~10s | 是(可绕过) |
| 4 | PR 创建时 | CI 验证 | ~30s | 是 |
| 5 | 每周定时任务 | 完整重新分析 | ~2min | 否 |
新鲜度指示器
## Contract Status (shown in CONTRACTS.md header)
Last full analysis: 2026-01-18T10:00:00Z
Last sync: 2026-01-20T14:32:00Z
Staleness: 🟢 Fresh (synced 2 hours ago)
## Confidence Levels
🟢 Fresh - Synced within 24 hours, no source changes
🟡 Stale - Sources changed since last sync
🔴 Outdated - Over 7 days since last analysis
⚠️ Drift - Validation found inconsistencies
与现有技能集成
与 existing-repo.md 集成
workspace.md 会针对每个模块调用 existing-repo.md 进行分析:
## Module Analysis Delegation
For each module in workspace:
1. Run existing-repo analysis on that module
2. Extract: tech stack, conventions, guardrails status
3. Aggregate into TOPOLOGY.md
4. Don't duplicate - reference existing-repo output
与 session-management.md 集成
## Session State Integration
Workspace context files are part of session state:
- TOPOLOGY.md → structural context (rarely changes)
- CONTRACTS.md → API context (check freshness each session)
- KEY_FILES.md → loading guidance (static reference)
On session start:
1. Load _project_specs/workspace/*.md into context
2. Check contract freshness
3. Advise if sync needed
与 code-review.md 集成
## Cross-Repo Review Checks
When reviewing code that touches contracts:
1. Check if change affects other modules
2. Verify contract consistency
3. Flag if CONTRACTS.md needs update
4. Warn about breaking changes
Add to review output:
### 🔗 Cross-Repo Impact
- [ ] This change affects: apps/web (API client)
- [ ] Contract update needed: Yes
- [ ] Breaking change: No
命令
/analyze-workspace
完整工作区分析——首次设置或发生重大变更时运行。
完整规范请参见 commands/analyze-workspace.md。
/sync-contracts
轻量级增量契约更新——请经常运行。
完整规范请参见 commands/sync-contracts.md。
/workspace-status
快速状态检查:
📊 Workspace Status: myapp
Type: Monorepo (Turborepo)
Modules: 4 (2 apps, 2 packages)
Contracts: 🟢 Fresh (synced 2h ago)
Token estimate: 45K / 150K budget
Quick actions:
/sync-contracts - Update contracts
/analyze-workspace - Full refresh
CI/CD 集成
GitHub Actions:契约验证
# .github/workflows/contracts.yml
name: Contract Validation
on:
pull_request:
paths:
- 'apps/api/**'
- 'packages/shared-types/**'
- 'packages/db/schema/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check contract freshness
run: |
CHANGED=$(git diff --name-only origin/main HEAD | \
grep -E "openapi|schema|types" || true)
if [ -n "$CHANGED" ]; then
echo "Contract sources changed:"
echo "$CHANGED"
if ! git diff --name-only origin/main HEAD | grep -q "CONTRACTS.md"; then
echo "::error::Contract sources changed but CONTRACTS.md not updated"
echo "Run /sync-contracts before merging"
exit 1
fi
fi
- name: Validate consistency
run: |
if [ -f "apps/api/openapi.json" ]; then
ENDPOINTS=$(jq -r '.paths | keys | length' apps/api/openapi.json)
DOCUMENTED=$(grep -c "^| /" _project_specs/workspace/CONTRACTS.md || echo 0)
if [ "$ENDPOINTS" != "$DOCUMENTED" ]; then
echo "::warning::Endpoint count mismatch"
fi
fi
提交前钩子
#!/bin/bash
# hooks/pre-commit-contracts
WORKSPACE_DIR="_project_specs/workspace"
[ ! -f "$WORKSPACE_DIR/.contract-sources" ] && exit 0
# Check if staged files include contract sources
STAGED=$(git diff --cached --name-only)
CONTRACT_SOURCES=$(cat "$WORKSPACE_DIR/.contract-sources")
for source in $CONTRACT_SOURCES; do
if echo "$STAGED" | grep -q "$source"; then
echo "📝 Contract source staged: $source"
echo "Remember to run /sync-contracts before pushing"
fi
done
故障排除
“未检测到工作区”
# Check for workspace indicators
ls -la package.json pnpm-workspace.yaml turbo.json nx.json 2>/dev/null
# If multi-repo, check sibling directories
ls -la ../
# Manual classification
/analyze-workspace --type monorepo
/analyze-workspace --type multi-repo --repos "../backend,../shared"
“契约同步失败”
# Check contract sources exist
cat _project_specs/workspace/.contract-sources
# Verify file access
for f in $(cat .contract-sources); do
ls -la "$f" 2>/dev/null || echo "Missing: $f"
done
# Force full refresh
/analyze-workspace --force
“超出令牌预算”
# Check current estimates
/workspace-status
# Reduce context loading
# Edit KEY_FILES.md to prioritize
# Or work on one module at a time
“跨仓库访问被拒绝”
# Check paths are correct
ls ../backend/ # or wherever related repo is
# Set up symlinks if needed
mkdir -p .workspace/repos
ln -s ../../backend .workspace/repos/backend
# Or configure in workspace
/analyze-workspace --repo-path backend=../myapp-backend