mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-01-23 09:57:32 +00:00
Remove openspect files
This commit is contained in:
@@ -1,456 +0,0 @@
|
||||
# OpenSpec Instructions
|
||||
|
||||
Instructions for AI coding assistants using OpenSpec for spec-driven development.
|
||||
|
||||
## TL;DR Quick Checklist
|
||||
|
||||
- Search existing work: `openspec spec list --long`, `openspec list` (use `rg` only for full-text search)
|
||||
- Decide scope: new capability vs modify existing capability
|
||||
- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`)
|
||||
- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability
|
||||
- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement
|
||||
- Validate: `openspec validate [change-id] --strict --no-interactive` and fix issues
|
||||
- Request approval: Do not start implementation until proposal is approved
|
||||
|
||||
## Three-Stage Workflow
|
||||
|
||||
### Stage 1: Creating Changes
|
||||
Create proposal when you need to:
|
||||
- Add features or functionality
|
||||
- Make breaking changes (API, schema)
|
||||
- Change architecture or patterns
|
||||
- Optimize performance (changes behavior)
|
||||
- Update security patterns
|
||||
|
||||
Triggers (examples):
|
||||
- "Help me create a change proposal"
|
||||
- "Help me plan a change"
|
||||
- "Help me create a proposal"
|
||||
- "I want to create a spec proposal"
|
||||
- "I want to create a spec"
|
||||
|
||||
Loose matching guidance:
|
||||
- Contains one of: `proposal`, `change`, `spec`
|
||||
- With one of: `create`, `plan`, `make`, `start`, `help`
|
||||
|
||||
Skip proposal for:
|
||||
- Bug fixes (restore intended behavior)
|
||||
- Typos, formatting, comments
|
||||
- Dependency updates (non-breaking)
|
||||
- Configuration changes
|
||||
- Tests for existing behavior
|
||||
|
||||
**Workflow**
|
||||
1. Review `openspec/project.md`, `openspec list`, and `openspec list --specs` to understand current context.
|
||||
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `openspec/changes/<id>/`.
|
||||
3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement.
|
||||
4. Run `openspec validate <id> --strict --no-interactive` and resolve any issues before sharing the proposal.
|
||||
|
||||
### Stage 2: Implementing Changes
|
||||
Track these steps as TODOs and complete them one by one.
|
||||
1. **Read proposal.md** - Understand what's being built
|
||||
2. **Read design.md** (if exists) - Review technical decisions
|
||||
3. **Read tasks.md** - Get implementation checklist
|
||||
4. **Implement tasks sequentially** - Complete in order
|
||||
5. **Confirm completion** - Ensure every item in `tasks.md` is finished before updating statuses
|
||||
6. **Update checklist** - After all work is done, set every task to `- [x]` so the list reflects reality
|
||||
7. **Approval gate** - Do not start implementation until the proposal is reviewed and approved
|
||||
|
||||
### Stage 3: Archiving Changes
|
||||
After deployment, create separate PR to:
|
||||
- Move `changes/[name]/` → `changes/archive/YYYY-MM-DD-[name]/`
|
||||
- Update `specs/` if capabilities changed
|
||||
- Use `openspec archive <change-id> --skip-specs --yes` for tooling-only changes (always pass the change ID explicitly)
|
||||
- Run `openspec validate --strict --no-interactive` to confirm the archived change passes checks
|
||||
|
||||
## Before Any Task
|
||||
|
||||
**Context Checklist:**
|
||||
- [ ] Read relevant specs in `specs/[capability]/spec.md`
|
||||
- [ ] Check pending changes in `changes/` for conflicts
|
||||
- [ ] Read `openspec/project.md` for conventions
|
||||
- [ ] Run `openspec list` to see active changes
|
||||
- [ ] Run `openspec list --specs` to see existing capabilities
|
||||
|
||||
**Before Creating Specs:**
|
||||
- Always check if capability already exists
|
||||
- Prefer modifying existing specs over creating duplicates
|
||||
- Use `openspec show [spec]` to review current state
|
||||
- If request is ambiguous, ask 1–2 clarifying questions before scaffolding
|
||||
|
||||
### Search Guidance
|
||||
- Enumerate specs: `openspec spec list --long` (or `--json` for scripts)
|
||||
- Enumerate changes: `openspec list` (or `openspec change list --json` - deprecated but available)
|
||||
- Show details:
|
||||
- Spec: `openspec show <spec-id> --type spec` (use `--json` for filters)
|
||||
- Change: `openspec show <change-id> --json --deltas-only`
|
||||
- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" openspec/specs`
|
||||
|
||||
## Quick Start
|
||||
|
||||
### CLI Commands
|
||||
|
||||
```bash
|
||||
# Essential commands
|
||||
openspec list # List active changes
|
||||
openspec list --specs # List specifications
|
||||
openspec show [item] # Display change or spec
|
||||
openspec validate [item] # Validate changes or specs
|
||||
openspec archive <change-id> [--yes|-y] # Archive after deployment (add --yes for non-interactive runs)
|
||||
|
||||
# Project management
|
||||
openspec init [path] # Initialize OpenSpec
|
||||
openspec update [path] # Update instruction files
|
||||
|
||||
# Interactive mode
|
||||
openspec show # Prompts for selection
|
||||
openspec validate # Bulk validation mode
|
||||
|
||||
# Debugging
|
||||
openspec show [change] --json --deltas-only
|
||||
openspec validate [change] --strict --no-interactive
|
||||
```
|
||||
|
||||
### Command Flags
|
||||
|
||||
- `--json` - Machine-readable output
|
||||
- `--type change|spec` - Disambiguate items
|
||||
- `--strict` - Comprehensive validation
|
||||
- `--no-interactive` - Disable prompts
|
||||
- `--skip-specs` - Archive without spec updates
|
||||
- `--yes`/`-y` - Skip confirmation prompts (non-interactive archive)
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── project.md # Project conventions
|
||||
├── specs/ # Current truth - what IS built
|
||||
│ └── [capability]/ # Single focused capability
|
||||
│ ├── spec.md # Requirements and scenarios
|
||||
│ └── design.md # Technical patterns
|
||||
├── changes/ # Proposals - what SHOULD change
|
||||
│ ├── [change-name]/
|
||||
│ │ ├── proposal.md # Why, what, impact
|
||||
│ │ ├── tasks.md # Implementation checklist
|
||||
│ │ ├── design.md # Technical decisions (optional; see criteria)
|
||||
│ │ └── specs/ # Delta changes
|
||||
│ │ └── [capability]/
|
||||
│ │ └── spec.md # ADDED/MODIFIED/REMOVED
|
||||
│ └── archive/ # Completed changes
|
||||
```
|
||||
|
||||
## Creating Change Proposals
|
||||
|
||||
### Decision Tree
|
||||
|
||||
```
|
||||
New request?
|
||||
├─ Bug fix restoring spec behavior? → Fix directly
|
||||
├─ Typo/format/comment? → Fix directly
|
||||
├─ New feature/capability? → Create proposal
|
||||
├─ Breaking change? → Create proposal
|
||||
├─ Architecture change? → Create proposal
|
||||
└─ Unclear? → Create proposal (safer)
|
||||
```
|
||||
|
||||
### Proposal Structure
|
||||
|
||||
1. **Create directory:** `changes/[change-id]/` (kebab-case, verb-led, unique)
|
||||
|
||||
2. **Write proposal.md:**
|
||||
```markdown
|
||||
# Change: [Brief description of change]
|
||||
|
||||
## Why
|
||||
[1-2 sentences on problem/opportunity]
|
||||
|
||||
## What Changes
|
||||
- [Bullet list of changes]
|
||||
- [Mark breaking changes with **BREAKING**]
|
||||
|
||||
## Impact
|
||||
- Affected specs: [list capabilities]
|
||||
- Affected code: [key files/systems]
|
||||
```
|
||||
|
||||
3. **Create spec deltas:** `specs/[capability]/spec.md`
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: New Feature
|
||||
The system SHALL provide...
|
||||
|
||||
#### Scenario: Success case
|
||||
- **WHEN** user performs action
|
||||
- **THEN** expected result
|
||||
|
||||
## MODIFIED Requirements
|
||||
### Requirement: Existing Feature
|
||||
[Complete modified requirement]
|
||||
|
||||
## REMOVED Requirements
|
||||
### Requirement: Old Feature
|
||||
**Reason**: [Why removing]
|
||||
**Migration**: [How to handle]
|
||||
```
|
||||
If multiple capabilities are affected, create multiple delta files under `changes/[change-id]/specs/<capability>/spec.md`—one per capability.
|
||||
|
||||
4. **Create tasks.md:**
|
||||
```markdown
|
||||
## 1. Implementation
|
||||
- [ ] 1.1 Create database schema
|
||||
- [ ] 1.2 Implement API endpoint
|
||||
- [ ] 1.3 Add frontend component
|
||||
- [ ] 1.4 Write tests
|
||||
```
|
||||
|
||||
5. **Create design.md when needed:**
|
||||
Create `design.md` if any of the following apply; otherwise omit it:
|
||||
- Cross-cutting change (multiple services/modules) or a new architectural pattern
|
||||
- New external dependency or significant data model changes
|
||||
- Security, performance, or migration complexity
|
||||
- Ambiguity that benefits from technical decisions before coding
|
||||
|
||||
Minimal `design.md` skeleton:
|
||||
```markdown
|
||||
## Context
|
||||
[Background, constraints, stakeholders]
|
||||
|
||||
## Goals / Non-Goals
|
||||
- Goals: [...]
|
||||
- Non-Goals: [...]
|
||||
|
||||
## Decisions
|
||||
- Decision: [What and why]
|
||||
- Alternatives considered: [Options + rationale]
|
||||
|
||||
## Risks / Trade-offs
|
||||
- [Risk] → Mitigation
|
||||
|
||||
## Migration Plan
|
||||
[Steps, rollback]
|
||||
|
||||
## Open Questions
|
||||
- [...]
|
||||
```
|
||||
|
||||
## Spec File Format
|
||||
|
||||
### Critical: Scenario Formatting
|
||||
|
||||
**CORRECT** (use #### headers):
|
||||
```markdown
|
||||
#### Scenario: User login success
|
||||
- **WHEN** valid credentials provided
|
||||
- **THEN** return JWT token
|
||||
```
|
||||
|
||||
**WRONG** (don't use bullets or bold):
|
||||
```markdown
|
||||
- **Scenario: User login** ❌
|
||||
**Scenario**: User login ❌
|
||||
### Scenario: User login ❌
|
||||
```
|
||||
|
||||
Every requirement MUST have at least one scenario.
|
||||
|
||||
### Requirement Wording
|
||||
- Use SHALL/MUST for normative requirements (avoid should/may unless intentionally non-normative)
|
||||
|
||||
### Delta Operations
|
||||
|
||||
- `## ADDED Requirements` - New capabilities
|
||||
- `## MODIFIED Requirements` - Changed behavior
|
||||
- `## REMOVED Requirements` - Deprecated features
|
||||
- `## RENAMED Requirements` - Name changes
|
||||
|
||||
Headers matched with `trim(header)` - whitespace ignored.
|
||||
|
||||
#### When to use ADDED vs MODIFIED
|
||||
- ADDED: Introduces a new capability or sub-capability that can stand alone as a requirement. Prefer ADDED when the change is orthogonal (e.g., adding "Slash Command Configuration") rather than altering the semantics of an existing requirement.
|
||||
- MODIFIED: Changes the behavior, scope, or acceptance criteria of an existing requirement. Always paste the full, updated requirement content (header + all scenarios). The archiver will replace the entire requirement with what you provide here; partial deltas will drop previous details.
|
||||
- RENAMED: Use when only the name changes. If you also change behavior, use RENAMED (name) plus MODIFIED (content) referencing the new name.
|
||||
|
||||
Common pitfall: Using MODIFIED to add a new concern without including the previous text. This causes loss of detail at archive time. If you aren’t explicitly changing the existing requirement, add a new requirement under ADDED instead.
|
||||
|
||||
Authoring a MODIFIED requirement correctly:
|
||||
1) Locate the existing requirement in `openspec/specs/<capability>/spec.md`.
|
||||
2) Copy the entire requirement block (from `### Requirement: ...` through its scenarios).
|
||||
3) Paste it under `## MODIFIED Requirements` and edit to reflect the new behavior.
|
||||
4) Ensure the header text matches exactly (whitespace-insensitive) and keep at least one `#### Scenario:`.
|
||||
|
||||
Example for RENAMED:
|
||||
```markdown
|
||||
## RENAMED Requirements
|
||||
- FROM: `### Requirement: Login`
|
||||
- TO: `### Requirement: User Authentication`
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Errors
|
||||
|
||||
**"Change must have at least one delta"**
|
||||
- Check `changes/[name]/specs/` exists with .md files
|
||||
- Verify files have operation prefixes (## ADDED Requirements)
|
||||
|
||||
**"Requirement must have at least one scenario"**
|
||||
- Check scenarios use `#### Scenario:` format (4 hashtags)
|
||||
- Don't use bullet points or bold for scenario headers
|
||||
|
||||
**Silent scenario parsing failures**
|
||||
- Exact format required: `#### Scenario: Name`
|
||||
- Debug with: `openspec show [change] --json --deltas-only`
|
||||
|
||||
### Validation Tips
|
||||
|
||||
```bash
|
||||
# Always use strict mode for comprehensive checks
|
||||
openspec validate [change] --strict --no-interactive
|
||||
|
||||
# Debug delta parsing
|
||||
openspec show [change] --json | jq '.deltas'
|
||||
|
||||
# Check specific requirement
|
||||
openspec show [spec] --json -r 1
|
||||
```
|
||||
|
||||
## Happy Path Script
|
||||
|
||||
```bash
|
||||
# 1) Explore current state
|
||||
openspec spec list --long
|
||||
openspec list
|
||||
# Optional full-text search:
|
||||
# rg -n "Requirement:|Scenario:" openspec/specs
|
||||
# rg -n "^#|Requirement:" openspec/changes
|
||||
|
||||
# 2) Choose change id and scaffold
|
||||
CHANGE=add-two-factor-auth
|
||||
mkdir -p openspec/changes/$CHANGE/{specs/auth}
|
||||
printf "## Why\n...\n\n## What Changes\n- ...\n\n## Impact\n- ...\n" > openspec/changes/$CHANGE/proposal.md
|
||||
printf "## 1. Implementation\n- [ ] 1.1 ...\n" > openspec/changes/$CHANGE/tasks.md
|
||||
|
||||
# 3) Add deltas (example)
|
||||
cat > openspec/changes/$CHANGE/specs/auth/spec.md << 'EOF'
|
||||
## ADDED Requirements
|
||||
### Requirement: Two-Factor Authentication
|
||||
Users MUST provide a second factor during login.
|
||||
|
||||
#### Scenario: OTP required
|
||||
- **WHEN** valid credentials are provided
|
||||
- **THEN** an OTP challenge is required
|
||||
EOF
|
||||
|
||||
# 4) Validate
|
||||
openspec validate $CHANGE --strict --no-interactive
|
||||
```
|
||||
|
||||
## Multi-Capability Example
|
||||
|
||||
```
|
||||
openspec/changes/add-2fa-notify/
|
||||
├── proposal.md
|
||||
├── tasks.md
|
||||
└── specs/
|
||||
├── auth/
|
||||
│ └── spec.md # ADDED: Two-Factor Authentication
|
||||
└── notifications/
|
||||
└── spec.md # ADDED: OTP email notification
|
||||
```
|
||||
|
||||
auth/spec.md
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: Two-Factor Authentication
|
||||
...
|
||||
```
|
||||
|
||||
notifications/spec.md
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: OTP Email Notification
|
||||
...
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Simplicity First
|
||||
- Default to <100 lines of new code
|
||||
- Single-file implementations until proven insufficient
|
||||
- Avoid frameworks without clear justification
|
||||
- Choose boring, proven patterns
|
||||
|
||||
### Complexity Triggers
|
||||
Only add complexity with:
|
||||
- Performance data showing current solution too slow
|
||||
- Concrete scale requirements (>1000 users, >100MB data)
|
||||
- Multiple proven use cases requiring abstraction
|
||||
|
||||
### Clear References
|
||||
- Use `file.ts:42` format for code locations
|
||||
- Reference specs as `specs/auth/spec.md`
|
||||
- Link related changes and PRs
|
||||
|
||||
### Capability Naming
|
||||
- Use verb-noun: `user-auth`, `payment-capture`
|
||||
- Single purpose per capability
|
||||
- 10-minute understandability rule
|
||||
- Split if description needs "AND"
|
||||
|
||||
### Change ID Naming
|
||||
- Use kebab-case, short and descriptive: `add-two-factor-auth`
|
||||
- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-`
|
||||
- Ensure uniqueness; if taken, append `-2`, `-3`, etc.
|
||||
|
||||
## Tool Selection Guide
|
||||
|
||||
| Task | Tool | Why |
|
||||
|------|------|-----|
|
||||
| Find files by pattern | Glob | Fast pattern matching |
|
||||
| Search code content | Grep | Optimized regex search |
|
||||
| Read specific files | Read | Direct file access |
|
||||
| Explore unknown scope | Task | Multi-step investigation |
|
||||
|
||||
## Error Recovery
|
||||
|
||||
### Change Conflicts
|
||||
1. Run `openspec list` to see active changes
|
||||
2. Check for overlapping specs
|
||||
3. Coordinate with change owners
|
||||
4. Consider combining proposals
|
||||
|
||||
### Validation Failures
|
||||
1. Run with `--strict` flag
|
||||
2. Check JSON output for details
|
||||
3. Verify spec file format
|
||||
4. Ensure scenarios properly formatted
|
||||
|
||||
### Missing Context
|
||||
1. Read project.md first
|
||||
2. Check related specs
|
||||
3. Review recent archives
|
||||
4. Ask for clarification
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Stage Indicators
|
||||
- `changes/` - Proposed, not yet built
|
||||
- `specs/` - Built and deployed
|
||||
- `archive/` - Completed changes
|
||||
|
||||
### File Purposes
|
||||
- `proposal.md` - Why and what
|
||||
- `tasks.md` - Implementation steps
|
||||
- `design.md` - Technical decisions
|
||||
- `spec.md` - Requirements and behavior
|
||||
|
||||
### CLI Essentials
|
||||
```bash
|
||||
openspec list # What's in progress?
|
||||
openspec show [item] # View details
|
||||
openspec validate --strict --no-interactive # Is it correct?
|
||||
openspec archive <change-id> [--yes|-y] # Mark complete (add --yes for automation)
|
||||
```
|
||||
|
||||
Remember: Specs are truth. Changes are proposals. Keep them in sync.
|
||||
@@ -1,456 +0,0 @@
|
||||
# OpenSpec 指令
|
||||
|
||||
使用 OpenSpec 进行规范驱动开发的 AI 编程助手指南。
|
||||
|
||||
## 快速检查清单
|
||||
|
||||
- 搜索现有工作:`openspec spec list --long`、`openspec list`(仅在全文搜索时使用 `rg`)
|
||||
- 决定范围:新功能 vs 修改现有功能
|
||||
- 选择唯一的 `change-id`:kebab-case,动词开头(`add-`、`update-`、`remove-`、`refactor-`)
|
||||
- 创建骨架:`proposal.md`、`tasks.md`、`design.md`(仅在需要时)以及每个受影响功能的增量规范
|
||||
- 编写增量:使用 `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`;每个需求至少包含一个 `#### Scenario:`
|
||||
- 验证:`openspec validate [change-id] --strict --no-interactive` 并修复问题
|
||||
- 请求批准:在提案获批前不要开始实施
|
||||
|
||||
## 三阶段工作流
|
||||
|
||||
### 阶段 1:创建变更
|
||||
在以下情况下创建提案:
|
||||
- 添加功能或特性
|
||||
- 进行破坏性更改(API、架构)
|
||||
- 更改架构或模式
|
||||
- 优化性能(改变行为)
|
||||
- 更新安全模式
|
||||
|
||||
触发器(示例):
|
||||
- "帮我创建变更提案"
|
||||
- "帮我规划变更"
|
||||
- "帮我创建提案"
|
||||
- "我想创建规范提案"
|
||||
- "我想创建规范"
|
||||
|
||||
模糊匹配指南:
|
||||
- 包含以下之一:`proposal`、`change`、`spec`
|
||||
- 加上以下之一:`create`、`plan`、`make`、`start`、`help`
|
||||
|
||||
跳过提案的情况:
|
||||
- 错误修复(恢复预期行为)
|
||||
- 拼写错误、格式、注释
|
||||
- 依赖项更新(非破坏性)
|
||||
- 配置更改
|
||||
- 为现有行为添加测试
|
||||
|
||||
**工作流**
|
||||
1. 查看 `openspec/project.md`、`openspec list` 和 `openspec list --specs` 以了解当前上下文。
|
||||
2. 选择唯一的动词开头的 `change-id`,并在 `openspec/changes/<id>/` 下创建 `proposal.md`、`tasks.md`、可选的 `design.md` 和规范增量骨架。
|
||||
3. 使用 `## ADDED|MODIFIED|REMOVED Requirements` 起草规范增量,每个需求至少包含一个 `#### Scenario:`。
|
||||
4. 运行 `openspec validate <id> --strict --no-interactive` 并在共享提案之前解决所有问题。
|
||||
|
||||
### 阶段 2:实施变更
|
||||
将这些步骤跟踪为 TODO 并逐一完成。
|
||||
1. **阅读 proposal.md** - 了解要构建的内容
|
||||
2. **阅读 design.md**(如果存在)- 查看技术决策
|
||||
3. **阅读 tasks.md** - 获取实施清单
|
||||
4. **按顺序实施任务** - 按顺序完成
|
||||
5. **确认完成** - 确保在更新状态之前完成 `tasks.md` 中的每一项
|
||||
6. **更新清单** - 所有工作完成后,将每个任务设置为 `- [x]`,使列表反映实际情况
|
||||
7. **批准门槛** - 在提案被审查和批准之前不要开始实施
|
||||
|
||||
### 阶段 3:归档变更
|
||||
部署后,创建单独的 PR 以:
|
||||
- 将 `changes/[name]/` 移至 `changes/archive/YYYY-MM-DD-[name]/`
|
||||
- 如果功能发生变化,则更新 `specs/`
|
||||
- 对于仅工具的更改,使用 `openspec archive <change-id> --skip-specs --yes`(始终明确传递变更 ID)
|
||||
- 运行 `openspec validate --strict --no-interactive` 以确认归档的更改通过检查
|
||||
|
||||
## 在任何任务之前
|
||||
|
||||
**上下文清单:**
|
||||
- [ ] 阅读 `specs/[capability]/spec.md` 中的相关规范
|
||||
- [ ] 检查 `changes/` 中的待处理变更是否有冲突
|
||||
- [ ] 阅读 `openspec/project.md` 了解约定
|
||||
- [ ] 运行 `openspec list` 查看活动变更
|
||||
- [ ] 运行 `openspec list --specs` 查看现有功能
|
||||
|
||||
**创建规范之前:**
|
||||
- 始终检查功能是否已存在
|
||||
- 优先修改现有规范而不是创建重复项
|
||||
- 使用 `openspec show [spec]` 查看当前状态
|
||||
- 如果请求模棱两可,请在创建骨架之前询问 1-2 个澄清问题
|
||||
|
||||
### 搜索指南
|
||||
- 枚举规范:`openspec spec list --long`(或使用 `--json` 用于脚本)
|
||||
- 枚举变更:`openspec list`(或 `openspec change list --json` - 已弃用但可用)
|
||||
- 显示详细信息:
|
||||
- 规范:`openspec show <spec-id> --type spec`(使用 `--json` 进行过滤)
|
||||
- 变更:`openspec show <change-id> --json --deltas-only`
|
||||
- 全文搜索(使用 ripgrep):`rg -n "Requirement:|Scenario:" openspec/specs`
|
||||
|
||||
## 快速开始
|
||||
|
||||
### CLI 命令
|
||||
|
||||
```bash
|
||||
# 基本命令
|
||||
openspec list # 列出活动变更
|
||||
openspec list --specs # 列出规范
|
||||
openspec show [item] # 显示变更或规范
|
||||
openspec validate [item] # 验证变更或规范
|
||||
openspec archive <change-id> [--yes|-y] # 部署后归档(添加 --yes 以非交互运行)
|
||||
|
||||
# 项目管理
|
||||
openspec init [path] # 初始化 OpenSpec
|
||||
openspec update [path] # 更新指令文件
|
||||
|
||||
# 交互模式
|
||||
openspec show # 提示进行选择
|
||||
openspec validate # 批量验证模式
|
||||
|
||||
# 调试
|
||||
openspec show [change] --json --deltas-only
|
||||
openspec validate [change] --strict --no-interactive
|
||||
```
|
||||
|
||||
### 命令标志
|
||||
|
||||
- `--json` - 机器可读输出
|
||||
- `--type change|spec` - 消除项目歧义
|
||||
- `--strict` - 全面验证
|
||||
- `--no-interactive` - 禁用提示
|
||||
- `--skip-specs` - 归档而不更新规范
|
||||
- `--yes`/`-y` - 跳过确认提示(非交互式归档)
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
openspec/
|
||||
├── project.md # 项目约定
|
||||
├── specs/ # 当前事实 - 已构建的内容
|
||||
│ └── [capability]/ # 单一专注功能
|
||||
│ ├── spec.md # 需求和场景
|
||||
│ └── design.md # 技术模式
|
||||
├── changes/ # 提案 - 应该更改的内容
|
||||
│ ├── [change-name]/
|
||||
│ │ ├── proposal.md # 原因、内容、影响
|
||||
│ │ ├── tasks.md # 实施清单
|
||||
│ │ ├── design.md # 技术决策(可选;参见标准)
|
||||
│ │ └── specs/ # 增量更改
|
||||
│ │ └── [capability]/
|
||||
│ │ └── spec.md # ADDED/MODIFIED/REMOVED
|
||||
│ └── archive/ # 已完成的变更
|
||||
```
|
||||
|
||||
## 创建变更提案
|
||||
|
||||
### 决策树
|
||||
|
||||
```
|
||||
新请求?
|
||||
├─ 恢复规范行为的错误修复? → 直接修复
|
||||
├─ 拼写错误/格式/注释? → 直接修复
|
||||
├─ 新功能/能力? → 创建提案
|
||||
├─ 破坏性更改? → 创建提案
|
||||
├─ 架构更改? → 创建提案
|
||||
└─ 不清楚? → 创建提案(更安全)
|
||||
```
|
||||
|
||||
### 提案结构
|
||||
|
||||
1. **创建目录:** `changes/[change-id]/`(kebab-case,动词开头,唯一)
|
||||
|
||||
2. **编写 proposal.md:**
|
||||
```markdown
|
||||
# 变更:[变更简要描述]
|
||||
|
||||
## 原因
|
||||
[1-2 句话说明问题/机会]
|
||||
|
||||
## 变更内容
|
||||
- [变更要点列表]
|
||||
- [使用 **BREAKING** 标记破坏性更改]
|
||||
|
||||
## 影响
|
||||
- 受影响的规范:[列出功能]
|
||||
- 受影响的代码:[关键文件/系统]
|
||||
```
|
||||
|
||||
3. **创建规范增量:** `specs/[capability]/spec.md`
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: 新功能
|
||||
系统应提供...
|
||||
|
||||
#### Scenario: 成功案例
|
||||
- **WHEN** 用户执行操作
|
||||
- **THEN** 预期结果
|
||||
|
||||
## MODIFIED Requirements
|
||||
### Requirement: 现有功能
|
||||
[完整的修改后需求]
|
||||
|
||||
## REMOVED Requirements
|
||||
### Requirement: 旧功能
|
||||
**原因**:[为什么删除]
|
||||
**迁移**:[如何处理]
|
||||
```
|
||||
如果影响多个功能,请在 `changes/[change-id]/specs/<capability>/spec.md` 下创建多个增量文件——每个功能一个。
|
||||
|
||||
4. **创建 tasks.md:**
|
||||
```markdown
|
||||
## 1. 实施
|
||||
- [ ] 1.1 创建数据库架构
|
||||
- [ ] 1.2 实施 API 端点
|
||||
- [ ] 1.3 添加前端组件
|
||||
- [ ] 1.4 编写测试
|
||||
```
|
||||
|
||||
5. **在需要时创建 design.md:**
|
||||
如果符合以下任一情况,请创建 `design.md`;否则省略:
|
||||
- 跨领域更改(多个服务/模块)或新的架构模式
|
||||
- 新的外部依赖或重要的数据模型更改
|
||||
- 安全性、性能或迁移复杂性
|
||||
- 在编码之前受益于技术决策的歧义
|
||||
|
||||
最小 `design.md` 骨架:
|
||||
```markdown
|
||||
## 上下文
|
||||
[背景、约束、利益相关者]
|
||||
|
||||
## 目标 / 非目标
|
||||
- 目标:[...]
|
||||
- 非目标:[...]
|
||||
|
||||
## 决策
|
||||
- 决策:[内容和原因]
|
||||
- 考虑的替代方案:[选项 + 理由]
|
||||
|
||||
## 风险 / 权衡
|
||||
- [风险] → 缓解措施
|
||||
|
||||
## 迁移计划
|
||||
[步骤、回滚]
|
||||
|
||||
## 未解决的问题
|
||||
- [...]
|
||||
```
|
||||
|
||||
## 规范文件格式
|
||||
|
||||
### 关键:场景格式
|
||||
|
||||
**正确**(使用 #### 标题):
|
||||
```markdown
|
||||
#### Scenario: 用户登录成功
|
||||
- **WHEN** 提供有效凭据
|
||||
- **THEN** 返回 JWT 令牌
|
||||
```
|
||||
|
||||
**错误**(不要使用项目符号或粗体):
|
||||
```markdown
|
||||
- **Scenario: 用户登录** ❌
|
||||
**Scenario**: 用户登录 ❌
|
||||
### Scenario: 用户登录 ❌
|
||||
```
|
||||
|
||||
每个需求必须至少有一个场景。
|
||||
|
||||
### 需求措辞
|
||||
- 对规范性要求使用 SHALL/MUST(除非有意非规范性,否则避免 should/may)
|
||||
|
||||
### 增量操作
|
||||
|
||||
- `## ADDED Requirements` - 新功能
|
||||
- `## MODIFIED Requirements` - 更改的行为
|
||||
- `## REMOVED Requirements` - 已弃用功能
|
||||
- `## RENAMED Requirements` - 名称更改
|
||||
|
||||
使用 `trim(header)` 匹配标题 - 忽略空格。
|
||||
|
||||
#### 何时使用 ADDED vs MODIFIED
|
||||
- ADDED:引入可以独立作为需求的新功能或子功能。当更改是正交的(例如,添加"斜杠命令配置")而不是更改现有需求的语义时,优先使用 ADDED。
|
||||
- MODIFIED:更改现有需求的行为、范围或验收标准。始终粘贴完整、更新的需求内容(标题 + 所有场景)。归档器将用您在此处提供的内容替换整个需求;部分增量将丢失先前的详细信息。
|
||||
- RENAMED:仅在名称更改时使用。如果您还更改行为,请使用 RENAMED(名称)加上 MODIFIED(内容)引用新名称。
|
||||
|
||||
常见错误:使用 MODIFIED 添加新关注点而不包含先前的文本。这会导致归档时丢失详细信息。如果您没有明确更改现有需求,请改为在 ADDED 下添加新需求。
|
||||
|
||||
正确编写 MODIFIED 需求:
|
||||
1) 在 `openspec/specs/<capability>/spec.md` 中找到现有需求。
|
||||
2) 复制整个需求块(从 `### Requirement: ...` 到其场景)。
|
||||
3) 将其粘贴到 `## MODIFIED Requirements` 下并编辑以反映新行为。
|
||||
4) 确保标题文本完全匹配(不区分空格)并保留至少一个 `#### Scenario:`。
|
||||
|
||||
RENAMED 示例:
|
||||
```markdown
|
||||
## RENAMED Requirements
|
||||
- FROM: `### Requirement: Login`
|
||||
- TO: `### Requirement: User Authentication`
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见错误
|
||||
|
||||
**"Change must have at least one delta"**
|
||||
- 检查 `changes/[name]/specs/` 是否存在 .md 文件
|
||||
- 验证文件是否具有操作前缀(## ADDED Requirements)
|
||||
|
||||
**"Requirement must have at least one scenario"**
|
||||
- 检查场景是否使用 `#### Scenario:` 格式(4 个井号)
|
||||
- 不要对场景标题使用项目符号或粗体
|
||||
|
||||
**静默场景解析失败**
|
||||
- 需要精确格式:`#### Scenario: 名称`
|
||||
- 使用以下命令调试:`openspec show [change] --json --deltas-only`
|
||||
|
||||
### 验证技巧
|
||||
|
||||
```bash
|
||||
# 始终使用严格模式进行全面检查
|
||||
openspec validate [change] --strict --no-interactive
|
||||
|
||||
# 调试增量解析
|
||||
openspec show [change] --json | jq '.deltas'
|
||||
|
||||
# 检查特定需求
|
||||
openspec show [spec] --json -r 1
|
||||
```
|
||||
|
||||
## 理想路径脚本
|
||||
|
||||
```bash
|
||||
# 1) 探索当前状态
|
||||
openspec spec list --long
|
||||
openspec list
|
||||
# 可选全文搜索:
|
||||
# rg -n "Requirement:|Scenario:" openspec/specs
|
||||
# rg -n "^#|Requirement:" openspec/changes
|
||||
|
||||
# 2) 选择变更 ID 并创建骨架
|
||||
CHANGE=add-two-factor-auth
|
||||
mkdir -p openspec/changes/$CHANGE/{specs/auth}
|
||||
printf "## Why\n...\n\n## What Changes\n- ...\n\n## Impact\n- ...\n" > openspec/changes/$CHANGE/proposal.md
|
||||
printf "## 1. Implementation\n- [ ] 1.1 ...\n" > openspec/changes/$CHANGE/tasks.md
|
||||
|
||||
# 3) 添加增量(示例)
|
||||
cat > openspec/changes/$CHANGE/specs/auth/spec.md << 'EOF'
|
||||
## ADDED Requirements
|
||||
### Requirement: 双因素认证
|
||||
用户在登录期间必须提供第二个因素。
|
||||
|
||||
#### Scenario: 需要 OTP
|
||||
- **WHEN** 提供有效凭据
|
||||
- **THEN** 需要OTP 挑战
|
||||
EOF
|
||||
|
||||
# 4) 验证
|
||||
openspec validate $CHANGE --strict --no-interactive
|
||||
```
|
||||
|
||||
## 多功能示例
|
||||
|
||||
```
|
||||
openspec/changes/add-2fa-notify/
|
||||
├── proposal.md
|
||||
├── tasks.md
|
||||
└── specs/
|
||||
├── auth/
|
||||
│ └── spec.md # ADDED: 双因素认证
|
||||
└── notifications/
|
||||
└── spec.md # ADDED: OTP 电子邮件通知
|
||||
```
|
||||
|
||||
auth/spec.md
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: 双因素认证
|
||||
...
|
||||
```
|
||||
|
||||
notifications/spec.md
|
||||
```markdown
|
||||
## ADDED Requirements
|
||||
### Requirement: OTP 电子邮件通知
|
||||
...
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 简单优先
|
||||
- 默认小于 100 行新代码
|
||||
- 单文件实施,直到被证明不足
|
||||
- 避免没有明确理由的框架
|
||||
- 选择无聊、经过验证的模式
|
||||
|
||||
### 复杂性触发器
|
||||
仅在以下情况下添加复杂性:
|
||||
- 显示当前解决方案太慢的性能数据
|
||||
- 具体的规模要求(>1000 用户,>100MB 数据)
|
||||
- 多个经过验证的用例需要抽象
|
||||
|
||||
### 清晰参考
|
||||
- 使用 `file.ts:42` 格式表示代码位置
|
||||
- 将规范引用为 `specs/auth/spec.md`
|
||||
- 链接相关变更和 PR
|
||||
|
||||
### 功能命名
|
||||
- 使用动词-名词:`user-auth`、`payment-capture`
|
||||
- 每个功能单一目的
|
||||
- 10 分钟可理解规则
|
||||
- 如果描述需要"AND"则拆分
|
||||
|
||||
### 变更 ID 命名
|
||||
- 使用 kebab-case,简短且描述性:`add-two-factor-auth`
|
||||
- 优先使用动词开头的前缀:`add-`、`update-`、`remove-`、`refactor-`
|
||||
- 确保唯一性;如果已占用,请附加 `-2`、`-3` 等
|
||||
|
||||
## 工具选择指南
|
||||
|
||||
| 任务 | 工具 | 原因 |
|
||||
|------|------|-----|
|
||||
| 按模式查找文件 | Glob | 快速模式匹配 |
|
||||
| 搜索代码内容 | Grep | 优化的正则表达式搜索 |
|
||||
| 读取特定文件 | Read | 直接文件访问 |
|
||||
| 探索未知范围 | Task | 多步骤调查 |
|
||||
|
||||
## 错误恢复
|
||||
|
||||
### 变更冲突
|
||||
1. 运行 `openspec list` 查看活动变更
|
||||
2. 检查重叠的规范
|
||||
3. 与变更所有者协调
|
||||
4. 考虑合并提案
|
||||
|
||||
### 验证失败
|
||||
1. 使用 `--strict` 标志运行
|
||||
2. 检查 JSON 输出以了解详细信息
|
||||
3. 验证规范文件格式
|
||||
4. 确保场景格式正确
|
||||
|
||||
### 缺少上下文
|
||||
1. 首先阅读 project.md
|
||||
2. 检查相关规范
|
||||
3. 查看最近的归档
|
||||
4. 请求澄清
|
||||
|
||||
## 快速参考
|
||||
|
||||
### 阶段指示器
|
||||
- `changes/` - 已提议,尚未构建
|
||||
- `specs/` - 已构建和部署
|
||||
- `archive/` - 已完成的变更
|
||||
|
||||
### 文件用途
|
||||
- `proposal.md` - 原因和内容
|
||||
- `tasks.md` - 实施步骤
|
||||
- `design.md` - 技术决策
|
||||
- `spec.md` - 需求和行为
|
||||
|
||||
### CLI 要点
|
||||
```bash
|
||||
openspec list # 正在进行什么?
|
||||
openspec show [item] # 查看详细信息
|
||||
openspec validate --strict --no-interactive # 正确吗?
|
||||
openspec archive <change-id> [--yes|-y] # 标记完成(添加 --yes 以实现自动化)
|
||||
```
|
||||
|
||||
记住:规范是事实。变更是提案。保持它们同步。
|
||||
@@ -1,246 +0,0 @@
|
||||
# Design: i18n Implementation Architecture
|
||||
|
||||
## Context
|
||||
|
||||
Claude Code UI is a React-based web application with ~50 components, currently serving English-speaking users only. The application uses:
|
||||
- React 18 with functional components and hooks
|
||||
- Context-based state management (AuthContext, ThemeContext, etc.)
|
||||
- localStorage for user preferences
|
||||
- Vite for bundling
|
||||
|
||||
**Constraints:**
|
||||
- Must not impact performance (bundle size, runtime overhead)
|
||||
- Must support hot-reload during development
|
||||
- Must allow switching language without page reload
|
||||
- Must be extensible for additional languages in the future
|
||||
|
||||
**Stakeholders:**
|
||||
- End users: Need intuitive language switching
|
||||
- Developers: Need easy translation management workflow
|
||||
- Maintainers: Need to keep translations synchronized
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
1. Implement production-ready i18n using `react-i18next`
|
||||
2. Support English (en) and Simplified Chinese (zh-CN) in Phase 1
|
||||
3. Provide language selector in Settings > Account
|
||||
4. Store user language preference in localStorage
|
||||
5. Extract and translate top 100 most common UI strings in Phase 1
|
||||
6. Create reusable translation namespace structure
|
||||
|
||||
**Non-Goals:**
|
||||
1. Translate AI-generated content (chat messages, code responses)
|
||||
2. Translate backend error logs or terminal output
|
||||
3. Implement server-side translation
|
||||
4. Create translation management web UI
|
||||
5. Add RTL (Right-to-Left) language support
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Use react-i18next Library
|
||||
|
||||
**Rationale:**
|
||||
- Industry-standard for React internationalization (2.5M weekly downloads)
|
||||
- Built-in hooks (`useTranslation`) compatible with React 18
|
||||
- Supports interpolation, plurals, date/number formatting
|
||||
- Excellent TypeScript support (even though we use JS)
|
||||
- Lazy-loading and code-splitting for translations
|
||||
- Active community and long-term viability
|
||||
|
||||
**Alternatives Considered:**
|
||||
- **Format.js (React Intl)**: More complex setup, larger bundle size
|
||||
- **Lingui**: Compile-time approach, requires Babel plugin, over-engineering for our needs
|
||||
- **Custom solution**: Would require building interpolation, plurals, date formatting from scratch
|
||||
|
||||
### Decision 2: Namespace-Based Translation Structure
|
||||
|
||||
**Structure:**
|
||||
```
|
||||
src/i18n/
|
||||
├── locales/
|
||||
│ ├── en/
|
||||
│ │ ├── common.json # Shared UI strings
|
||||
│ │ ├── settings.json # Settings page
|
||||
│ │ ├── auth.json # Login/Auth
|
||||
│ │ └── sidebar.json # Navigation/Sidebar
|
||||
│ └── zh-CN/
|
||||
│ ├── common.json
|
||||
│ ├── settings.json
|
||||
│ ├── auth.json
|
||||
│ └── sidebar.json
|
||||
├── config.js # i18next configuration
|
||||
└── ReactSuspense.js # Lazy-loading wrapper
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- Namespace-based approach aligns with feature boundaries
|
||||
- Smaller files = easier to manage translations
|
||||
- Supports code-splitting (load only needed namespaces)
|
||||
- Scalable for future languages
|
||||
|
||||
### Decision 3: Language Preference Storage in localStorage
|
||||
|
||||
**Rationale:**
|
||||
- Consistent with existing preferences (theme, code editor settings)
|
||||
- No backend changes required
|
||||
- Instant sync across tabs
|
||||
- Works in offline mode
|
||||
|
||||
**Storage Key:** `userLanguage`
|
||||
**Default Value:** `'en'` (English)
|
||||
**Valid Values:** `'en'`, `'zh-CN'`
|
||||
|
||||
### Decision 4: Translation Key Naming Convention
|
||||
|
||||
**Pattern:** `{namespace}.{component}.{element}.{state}`
|
||||
|
||||
**Examples:**
|
||||
- `common.buttons.save` → "Save"
|
||||
- `common.buttons.cancel` → "Cancel"
|
||||
- `settings.account.language.label` → "Language"
|
||||
- `auth.login.title` → "Sign In"
|
||||
- `sidebar.projects.new` → "New Project"
|
||||
|
||||
**Rationale:**
|
||||
- Hierarchical structure mirrors component tree
|
||||
- Easy to locate translation key in code
|
||||
- Prevents naming collisions across namespaces
|
||||
- Self-documenting
|
||||
|
||||
### Decision 5: Fallback Strategy
|
||||
|
||||
**Fallback Chain:**
|
||||
1. User's selected language (e.g., `zh-CN`)
|
||||
2. English (`en`) as default fallback
|
||||
3. Return translation key if not found in any language
|
||||
|
||||
**Configuration:**
|
||||
```javascript
|
||||
fallbackLng: 'en',
|
||||
debug: false, // Set true in development to log missing keys
|
||||
saveMissing: false, // Don't auto-create missing keys (manual review required)
|
||||
```
|
||||
|
||||
**Rationale:**
|
||||
- English is source language, guaranteed to have all keys
|
||||
- Showing translation key in production is better than blank text
|
||||
- Manual review prevents typo propagation
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
### Risk 1: Bundle Size Increase
|
||||
|
||||
**Impact:** Initial bundle may increase by ~30KB (gzip) for react-i18next + translations
|
||||
|
||||
**Mitigation:**
|
||||
- Use code-splitting to load translations per namespace
|
||||
- Enable tree-shaking for unused languages
|
||||
- Target Phase 1: Top 100 strings only
|
||||
|
||||
**Monitoring:**
|
||||
```bash
|
||||
npm run build
|
||||
# Check dist/ size before/after
|
||||
```
|
||||
|
||||
### Risk 2: Missing Translations at Runtime
|
||||
|
||||
**Impact:** Users may see English text mixed with Chinese
|
||||
|
||||
**Mitigation:**
|
||||
- Use `useTranslation` with `{ fallbackLng: 'en' }`
|
||||
- Implement `missingKeyHandler` to log missing keys in development
|
||||
- Create translation coverage report in CI
|
||||
|
||||
### Risk 3: Translation Synchronization Debt
|
||||
|
||||
**Impact:** New features may forget to add translations
|
||||
|
||||
**Mitigation:**
|
||||
- Add ESLint rule to detect hardcoded strings in JSX
|
||||
- Include i18n checklist in PR template
|
||||
- Document translation workflow in CLAUDE.md
|
||||
|
||||
### Risk 4: Context-Aware Translations
|
||||
|
||||
**Example:** "Save" could mean:
|
||||
- Save file (保存文件)
|
||||
- Save money (节省)
|
||||
- Rescue (救援)
|
||||
|
||||
**Mitigation:**
|
||||
- Use descriptive keys: `common.buttons.saveFile` vs `common.buttons.saveMoney`
|
||||
- Add context comments for translators: `{{context}} "Save file to disk"`
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### Phase 1: Infrastructure Setup (Day 1)
|
||||
|
||||
1. Install `react-i18next` and `i18next`
|
||||
2. Create `src/i18n/` directory structure
|
||||
3. Configure i18next with lazy-loading
|
||||
4. Add I18nextProvider to App.jsx
|
||||
5. Create translation resource files (en, zh-CN)
|
||||
|
||||
### Phase 2: Core UI Translation (Day 2-3)
|
||||
|
||||
**Priority Order:**
|
||||
1. Common buttons and labels (Save, Cancel, Delete, Create)
|
||||
2. Navigation elements (Settings, menus)
|
||||
3. Settings page
|
||||
4. Auth/Login pages
|
||||
5. Sidebar labels
|
||||
|
||||
**Process per component:**
|
||||
1. Replace hardcoded strings with `useTranslation()` hook
|
||||
2. Add translation key to JSON files
|
||||
3. Verify English still works
|
||||
4. Add Chinese translation
|
||||
5. Test language switching
|
||||
|
||||
### Phase 3: Language Selector (Day 3)
|
||||
|
||||
1. Add language dropdown to `AccountContent.jsx`
|
||||
2. Implement `changeLanguage()` handler
|
||||
3. Save preference to localStorage
|
||||
4. Test reload persistence
|
||||
|
||||
### Phase 4: Validation (Day 4)
|
||||
|
||||
1. Manual testing of all translated components
|
||||
2. Check for missing keys (console warnings)
|
||||
3. Test language switching in both directions
|
||||
4. Verify localStorage persistence
|
||||
5. Test mobile responsive layout with longer Chinese text
|
||||
|
||||
### Rollback Plan
|
||||
|
||||
If critical issues arise:
|
||||
1. Revert to commit before i18n changes
|
||||
2. Keep translation files for future retry
|
||||
3. Document blockers for next attempt
|
||||
|
||||
**Rollback Command:**
|
||||
```bash
|
||||
git revert <i18n-commit-hash>
|
||||
npm install
|
||||
```
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Should we add TypeScript support for translations?**
|
||||
- Current: No, project uses JavaScript
|
||||
- Future consideration: Migrate to TypeScript for better type safety
|
||||
|
||||
2. **Should we integrate with translation management platform (e.g., Crowdin, Lokalise)?**
|
||||
- Current decision: No, manual JSON editing is sufficient for 2 languages
|
||||
- Future: Consider when adding 3+ languages or external translators
|
||||
|
||||
3. **Should we format dates and numbers according to locale?**
|
||||
- Current decision: No, keep ISO format for simplicity
|
||||
- Future: Use `i18next-intlplural` if users request localized dates
|
||||
|
||||
4. **How to handle pluralization in Chinese (which doesn't have plurals)?**
|
||||
- Solution: Use same translation for singular/plural forms
|
||||
- Example: `"1 file"` → `"1 个文件"`, `"2 files"` → `"2 个文件"`
|
||||
@@ -1,51 +0,0 @@
|
||||
# Change: Add i18n Internationalization Support
|
||||
|
||||
## Why
|
||||
|
||||
The application currently has all UI text hardcoded in English, which limits accessibility for non-English speaking users. Adding internationalization (i18n) support will enable the application to serve a broader user base, particularly Chinese-speaking users who form a significant portion of the AI development community. This will improve user experience and adoption by allowing users to interact with the application in their preferred language.
|
||||
|
||||
## What Changes
|
||||
|
||||
- **BREAKING**: Add `react-i18next` dependency and configure i18n infrastructure
|
||||
- Add `I18nextProvider` wrapper in App.jsx
|
||||
- Create translation resource files for English (en) and Simplified Chinese (zh-CN)
|
||||
- Extract and translate core UI text (menus, buttons, labels, error messages)
|
||||
- Add language selector in Settings > Account section
|
||||
- Store user language preference in localStorage
|
||||
- Implement language switching without page reload
|
||||
- Create translation namespace structure for scalable management
|
||||
|
||||
**Scope - Phase 1 (Progressive Translation):**
|
||||
- Navigation elements (Settings, menus, buttons)
|
||||
- Common UI labels (Save, Cancel, Delete, Create, Loading, Error messages)
|
||||
- Settings page labels and descriptions
|
||||
- Login/Auth related text
|
||||
- Sidebar labels (Projects, Sessions, Files)
|
||||
|
||||
**Out of Scope - Phase 1:**
|
||||
- AI-generated content (chat messages, responses)
|
||||
- Developer-facing error logs
|
||||
- Documentation and help text
|
||||
- Terminal/shell output
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs:**
|
||||
- `i18n` (NEW capability) - Internationalization system
|
||||
- `user-interface` (NEW capability) - Language-aware UI components
|
||||
|
||||
- **Affected code:**
|
||||
- `src/main.jsx` - Add i18n initialization
|
||||
- `src/App.jsx` - Wrap with I18nextProvider
|
||||
- `src/components/Settings.jsx` - Add language selector
|
||||
- `src/components/settings/AccountContent.jsx` - Language preference UI
|
||||
- All UI components - Replace hardcoded text with translation keys
|
||||
- `src/i18n/` (NEW) - Translation resources and configuration
|
||||
- `package.json` - Add react-i18next dependency
|
||||
|
||||
- **Affected database:** None (language preference stored in localStorage)
|
||||
|
||||
- **Migration:**
|
||||
- No data migration required
|
||||
- Default language: English (fallback for missing translations)
|
||||
- User preference stored in `localStorage.getItem('userLanguage')`
|
||||
@@ -1,202 +0,0 @@
|
||||
# i18n Capability Specification (Delta)
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Translation Infrastructure
|
||||
|
||||
The system SHALL provide internationalization (i18n) infrastructure using react-i18next library to support multiple languages for user-facing text.
|
||||
|
||||
#### Scenario: Initialize i18n on application startup
|
||||
- **WHEN** the application starts
|
||||
- **THEN** the system SHALL initialize i18next with configuration
|
||||
- **AND** load translation resources for English (en) and Chinese (zh-CN)
|
||||
- **AND** set default language to English
|
||||
- **AND** detect saved language preference from localStorage
|
||||
|
||||
#### Scenario: Load translation namespaces lazily
|
||||
- **WHEN** a component requires translations
|
||||
- **THEN** the system SHALL load only the required namespace (e.g., 'common', 'settings')
|
||||
- **AND** cache loaded namespaces for subsequent access
|
||||
- **AND** show loading state only during initial load
|
||||
|
||||
### Requirement: Language Selection and Persistence
|
||||
|
||||
The system SHALL allow users to select their preferred language and persist this preference across sessions.
|
||||
|
||||
#### Scenario: User selects language in Settings
|
||||
- **WHEN** user navigates to Settings > Account > Language selector
|
||||
- **THEN** the system SHALL display available languages: English and 简体中文
|
||||
- **AND** show currently selected language as default
|
||||
- **AND** allow user to change selection
|
||||
|
||||
#### Scenario: System saves language preference
|
||||
- **WHEN** user selects a new language from dropdown
|
||||
- **THEN** the system SHALL immediately change application language
|
||||
- **AND** save selection to `localStorage.setItem('userLanguage', '<language>')`
|
||||
- **AND** refresh all translated components without page reload
|
||||
|
||||
#### Scenario: System restores language preference on startup
|
||||
- **WHEN** user returns to application after closing
|
||||
- **THEN** the system SHALL read `localStorage.getItem('userLanguage')`
|
||||
- **AND** initialize i18n with saved language
|
||||
- **AND** default to English if no preference is saved
|
||||
|
||||
### Requirement: Translation Resource Structure
|
||||
|
||||
The system SHALL organize translation resources in namespace-based JSON files under `src/i18n/locales/{language}/`.
|
||||
|
||||
#### Scenario: Translation file organization
|
||||
- **WHEN** developers add new translations
|
||||
- **THEN** translations SHALL be organized by namespace: `common.json`, `settings.json`, `auth.json`, `sidebar.json`
|
||||
- **AND** each namespace SHALL contain hierarchical keys with dot notation
|
||||
- **AND** each key SHALL have corresponding translations in all supported languages
|
||||
|
||||
**Example structure:**
|
||||
```json
|
||||
{
|
||||
"buttons": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"status": {
|
||||
"loading": "Loading...",
|
||||
"success": "Success",
|
||||
"error": "Error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Scenario: Translation key naming convention
|
||||
- **WHEN** developers create new translation keys
|
||||
- **THEN** keys SHALL follow pattern: `{namespace}.{component}.{element}.{state}`
|
||||
- **AND** use descriptive names to avoid ambiguity
|
||||
- **AND** avoid abbreviations except for common UI terms (btn, lbl, msg)
|
||||
|
||||
**Examples:**
|
||||
- `common.buttons.save` ✓
|
||||
- `settings.account.language.label` ✓
|
||||
- `auth.login.title` ✓
|
||||
- `btn.save` ✗ (too generic)
|
||||
- `msg` ✗ (too vague)
|
||||
|
||||
### Requirement: Fallback Translation Strategy
|
||||
|
||||
The system SHALL provide fallback translations when a translation key is missing in the user's preferred language.
|
||||
|
||||
#### Scenario: Missing translation in selected language
|
||||
- **WHEN** a translation key does not exist in Chinese (zh-CN)
|
||||
- **THEN** the system SHALL fall back to English (en) translation
|
||||
- **AND** log warning in development console
|
||||
- **AND** display English text to user
|
||||
|
||||
#### Scenario: Missing translation in all languages
|
||||
- **WHEN** a translation key does not exist in any language
|
||||
- **THEN** the system SHALL display the translation key itself (e.g., `common.buttons.save`)
|
||||
- **AND** log error in development console
|
||||
- **AND** NOT break the application or crash
|
||||
|
||||
### Requirement: Component Translation Integration
|
||||
|
||||
The system SHALL provide React components and hooks for translating UI text.
|
||||
|
||||
#### Scenario: Functional component uses useTranslation hook
|
||||
- **WHEN** a functional component needs translations
|
||||
- **THEN** the component SHALL use `useTranslation()` hook from react-i18next
|
||||
- **AND** specify namespace: `useTranslation('common')`
|
||||
- **AND** call `t()` function with translation key
|
||||
- **AND** automatically re-render when language changes
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function SaveButton() {
|
||||
const { t } = useTranslation('common');
|
||||
return <button>{t('buttons.save')}</button>;
|
||||
}
|
||||
```
|
||||
|
||||
#### Scenario: Component with interpolation
|
||||
- **WHEN** a translation contains dynamic values (e.g., username, file count)
|
||||
- **THEN** the translation SHALL use interpolation syntax: `{{variableName}}`
|
||||
- **AND** the component SHALL pass variables to `t()` function
|
||||
- **AND** the system SHALL insert values into translated string
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"welcome": "Welcome, {{username}}!",
|
||||
"fileCount": "You have {{count}} files"
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
const { t } = useTranslation('common');
|
||||
t('welcome', { username: 'Alice' }); // "Welcome, Alice!"
|
||||
t('fileCount', { count: 5 }); // "You have 5 files"
|
||||
```
|
||||
|
||||
### Requirement: Excluded Content from Translation
|
||||
|
||||
The system SHALL NOT translate certain types of content to preserve accuracy and developer experience.
|
||||
|
||||
#### Scenario: AI-generated content remains untranslated
|
||||
- **WHEN** AI assistant generates chat messages, code, or responses
|
||||
- **THEN** the content SHALL remain in original language (usually English)
|
||||
- **AND** NOT be processed by translation system
|
||||
|
||||
#### Scenario: Developer-facing logs remain in English
|
||||
- **WHEN** the application logs errors, warnings, or debug information
|
||||
- **THEN** log messages SHALL remain in English
|
||||
- **AND** NOT be translated to maintain debugging consistency
|
||||
|
||||
#### Scenario: Terminal/shell output remains as-is
|
||||
- **WHEN** the application displays terminal or shell output
|
||||
- **THEN** the output SHALL remain in original language
|
||||
- **AND** NOT be modified by translation system
|
||||
|
||||
### Requirement: Performance and Bundle Size
|
||||
|
||||
The system SHALL minimize the impact of i18n on application bundle size and runtime performance.
|
||||
|
||||
#### Scenario: Code-splitting for translation files
|
||||
- **WHEN** the application is built for production
|
||||
- **THEN** translation files SHALL be split by language and namespace
|
||||
- **AND** loaded only when needed (lazy-loading)
|
||||
- **AND** increase bundle size by less than 50KB (gzip)
|
||||
|
||||
#### Scenario: No performance regression on language switch
|
||||
- **WHEN** user changes language preference
|
||||
- **THEN** the system SHALL update UI within 100ms
|
||||
- **AND** NOT require full page reload
|
||||
- **AND** maintain smooth user experience
|
||||
|
||||
### Requirement: Developer Experience
|
||||
|
||||
The system SHALL provide tools and guidelines for contributors to add and maintain translations.
|
||||
|
||||
#### Scenario: Detecting missing translations in development
|
||||
- **WHEN** a developer references a non-existent translation key
|
||||
- **THEN** the system SHALL log warning in browser console
|
||||
- **AND** display translation key in UI with warning styling
|
||||
- **AND** NOT break the build process
|
||||
|
||||
#### Scenario: Documentation for contributors
|
||||
- **WHEN** a contributor needs to add new translations
|
||||
- **THEN** CLAUDE.md SHALL document i18n workflow
|
||||
- **AND** provide examples of correct translation key usage
|
||||
- **AND** list translation naming conventions
|
||||
- **AND** explain how to add new languages
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
*N/A - This is a new capability, no existing requirements are modified.*
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
*N/A - This is a new capability, no existing requirements are removed.*
|
||||
|
||||
## RENAMED Requirements
|
||||
|
||||
*N/A - This is a new capability, no existing requirements are renamed.*
|
||||
@@ -1,176 +0,0 @@
|
||||
# User Interface Capability Specification (Delta)
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Language-Aware UI Components
|
||||
|
||||
All user-facing UI components SHALL support internationalization and display translated text based on user's language preference.
|
||||
|
||||
#### Scenario: Settings page displays translated labels
|
||||
- **WHEN** user opens Settings page
|
||||
- **THEN** all section labels (Account, Permissions, MCP Servers, Appearance) SHALL be translated
|
||||
- **AND** button labels (Save, Cancel, Delete) SHALL be translated
|
||||
- **AND** description text SHALL be translated
|
||||
- **AND** technical terms (e.g., JWT, API, SSH) may remain in English if no common translation exists
|
||||
|
||||
#### Scenario: Sidebar displays translated navigation
|
||||
- **WHEN** user views sidebar navigation
|
||||
- **THEN** section headers (Projects, Sessions) SHALL be translated
|
||||
- **AND** action buttons (New Project, Refresh, Settings) SHALL be translated
|
||||
- **AND** status messages (Loading, Error) SHALL be translated
|
||||
|
||||
#### Scenario: Login form displays translated text
|
||||
- **WHEN** user views login form
|
||||
- **THEN** form labels (Username, Password) SHALL be translated
|
||||
- **AND** button text (Sign In, Create Account) SHALL be translated
|
||||
- **AND** validation messages (Invalid credentials, Required field) SHALL be translated
|
||||
- **AND** error messages SHALL be translated
|
||||
|
||||
#### Scenario: File operations show translated prompts
|
||||
- **WHEN** user performs file operations (Save, Delete, Rename)
|
||||
- **THEN** confirmation dialogs SHALL be translated
|
||||
- **AND** success messages SHALL be translated
|
||||
- **AND** error messages SHALL be translated
|
||||
|
||||
### Requirement: Language Selector in Settings
|
||||
|
||||
The Settings > Account section SHALL provide a language selector dropdown allowing users to choose their preferred language.
|
||||
|
||||
#### Scenario: Language selector displays current language
|
||||
- **WHEN** user navigates to Settings > Account
|
||||
- **THEN** a language selector dropdown SHALL be visible
|
||||
- **AND** display label: "Language" (or translated equivalent)
|
||||
- **AND** show currently selected language as default value
|
||||
- **AND** list available options: English, 简体中文
|
||||
|
||||
#### Scenario: Language selector updates preference
|
||||
- **WHEN** user selects a different language from dropdown
|
||||
- **THEN** the system SHALL immediately change application language
|
||||
- **AND** show loading indicator if translations are being loaded
|
||||
- **AND** refresh all UI components with new language
|
||||
- **AND** save preference to localStorage
|
||||
- **AND** display success message: "Language changed successfully"
|
||||
|
||||
#### Scenario: Language selector persists across sessions
|
||||
- **WHEN** user returns to application after closing
|
||||
- **THEN** the language selector SHALL display the previously selected language
|
||||
- **AND** the application UI SHALL be in the selected language
|
||||
- **AND** the selector SHALL not show "Language" as default if user previously chose Chinese
|
||||
|
||||
### Requirement: Responsive Layout for Translated Text
|
||||
|
||||
UI components SHALL accommodate varying text lengths across languages without breaking layout or readability.
|
||||
|
||||
#### Scenario: Chinese text fits in buttons
|
||||
- **WHEN** UI is displayed in Chinese (which often has longer text than English)
|
||||
- **THEN** buttons SHALL expand to fit translated text
|
||||
- **AND** text SHALL NOT overflow or wrap awkwardly
|
||||
- **AND** button heights SHALL remain consistent
|
||||
|
||||
#### Scenario: Mobile layout handles longer translations
|
||||
- **WHEN** application is viewed on mobile device with Chinese language
|
||||
- **THEN** navigation menus SHALL accommodate longer text labels
|
||||
- **AND** sidebar items SHALL not truncate important text
|
||||
- **AND** layout SHALL remain responsive and touch-friendly
|
||||
|
||||
#### Scenario: Tables and lists maintain alignment
|
||||
- **WHEN** table headers or list items are translated
|
||||
- **THEN** column widths SHALL adjust to fit translated content
|
||||
- **AND** text alignment SHALL remain appropriate (left-to-right for both languages)
|
||||
- **AND** content SHALL remain readable without horizontal scrolling
|
||||
|
||||
### Requirement: Error and Status Messages
|
||||
|
||||
All error messages, success notifications, and status indicators SHALL be translated to provide clear feedback in user's preferred language.
|
||||
|
||||
#### Scenario: Error messages are translated
|
||||
- **WHEN** an error occurs (e.g., network failure, validation error)
|
||||
- **THEN** error message SHALL be displayed in user's selected language
|
||||
- **AND** technical error codes MAY remain in English
|
||||
- **AND** suggestions for resolution SHALL be translated
|
||||
|
||||
#### Scenario: Success notifications are translated
|
||||
- **WHEN** an operation completes successfully (e.g., file saved, settings updated)
|
||||
- **THEN** success message SHALL be displayed in user's selected language
|
||||
- **AND** action buttons in notification (e.g., "Dismiss") SHALL be translated
|
||||
|
||||
#### Scenario: Loading states are translated
|
||||
- **WHEN** application shows loading indicator
|
||||
- **THEN** loading text SHALL be in user's selected language (e.g., "Loading..." vs "加载中...")
|
||||
- **AND** progress messages SHALL be translated
|
||||
|
||||
#### Scenario: Validation messages are translated
|
||||
- **WHEN** user submits form with invalid data
|
||||
- **THEN** validation error SHALL be in user's selected language
|
||||
- **AND** field-specific hints SHALL be translated
|
||||
- **AND** placeholder text SHALL be translated
|
||||
|
||||
### Requirement: Accessibility with Translations
|
||||
|
||||
Translated UI SHALL maintain accessibility standards including screen reader compatibility and keyboard navigation.
|
||||
|
||||
#### Scenario: Screen readers announce translated text
|
||||
- **WHEN** screen reader user navigates UI
|
||||
- **THEN** screen reader SHALL announce translated text correctly
|
||||
- **AND** language attribute SHALL be set on HTML element: `<html lang="zh-CN">`
|
||||
- **AND** dynamic language changes SHALL update lang attribute
|
||||
|
||||
#### Scenario: Keyboard navigation works with translated labels
|
||||
- **WHEN** user navigates with keyboard
|
||||
- **THEN** all interactive elements SHALL be accessible via Tab key
|
||||
- **AND** focus indicators SHALL be visible regardless of text length
|
||||
- **AND** keyboard shortcuts SHALL work consistently across languages
|
||||
|
||||
### Requirement: Date and Number Formatting
|
||||
|
||||
The system SHALL format dates, numbers, and other locale-specific data according to user's language preference.
|
||||
|
||||
#### Scenario: Dates are formatted for locale
|
||||
- **WHEN** application displays dates (e.g., file modification time, session creation time)
|
||||
- **THEN** dates SHALL be formatted according to locale conventions
|
||||
- **AND** Chinese users see: 2025年1月16日
|
||||
- **AND** English users see: January 16, 2025
|
||||
|
||||
#### Scenario: Numbers are formatted for locale
|
||||
- **WHEN** application displays numbers (e.g., token usage, file sizes)
|
||||
- **THEN** numbers SHALL use appropriate digit grouping symbols
|
||||
- **AND** Chinese users see: 1,234 (comma separator)
|
||||
- **AND** decimal separators match locale preference
|
||||
|
||||
#### Scenario: File sizes are human-readable
|
||||
- **WHEN** application displays file sizes
|
||||
- **THEN** sizes SHALL be formatted with appropriate units (KB, MB, GB)
|
||||
- **AND** unit labels SHALL be translated (e.g., "KB" vs "千字节")
|
||||
- **AND** formatting shall be consistent across languages
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Settings Page Navigation
|
||||
|
||||
The Settings page SHALL provide tabs for Account, Permissions, MCP Servers, and Appearance settings. All tab labels, section headers, and descriptions SHALL be translated based on user's language preference. The Account tab SHALL include a language selector dropdown that allows users to choose between English and Simplified Chinese.
|
||||
|
||||
#### Scenario: Navigate Settings with translated labels
|
||||
- **WHEN** user opens Settings page
|
||||
- **THEN** all navigation elements SHALL be in user's selected language
|
||||
- **AND** tab labels SHALL be translated (Account → 账户, Permissions → 权限)
|
||||
- **AND** active tab SHALL be visually indicated
|
||||
- **AND** language selector SHALL be visible in Account tab
|
||||
|
||||
### Requirement: Onboarding Flow
|
||||
|
||||
New users SHALL see onboarding wizard explaining application features. All onboarding text, instructions, and button labels SHALL be translated based on user's language preference. The wizard SHALL automatically detect user's system language when possible.
|
||||
|
||||
#### Scenario: Onboarding in selected language
|
||||
- **WHEN** new user first launches application
|
||||
- **THEN** onboarding wizard SHALL detect system language or default to English
|
||||
- **AND** all wizard text SHALL be translated
|
||||
- **AND** user may change language during onboarding via language selector
|
||||
- **AND** language preference SHALL persist after onboarding completes
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
*N/A - No requirements are removed, only enhanced with i18n support.*
|
||||
|
||||
## RENAMED Requirements
|
||||
|
||||
*N/A - No requirements are renamed.*
|
||||
@@ -1,285 +0,0 @@
|
||||
# Project Context
|
||||
|
||||
## Purpose
|
||||
|
||||
Claude Code UI (aka Cloud CLI) is a full-stack web application that provides a responsive desktop and mobile interface for [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code), [Cursor CLI](https://docs.cursor.com/en/cli/overview), and [OpenAI Codex](https://developers.openai.com/codex). It enables users to interact with their AI programming assistants from any device through a browser, providing a seamless cross-device experience for AI-powered development workflows.
|
||||
|
||||
**Key Goals:**
|
||||
- Provide universal access to AI CLI tools from any device (desktop, tablet, mobile)
|
||||
- Enable real-time chat and terminal interactions with AI assistants
|
||||
- Offer integrated file browsing, code editing, and Git operations
|
||||
- Support session management and conversation resumption
|
||||
- Maintain security through authentication and tool permission systems
|
||||
|
||||
## Tech Stack
|
||||
|
||||
### Frontend
|
||||
- **React 18** - Functional components with hooks
|
||||
- **Vite 7** - Fast build tool with hot module replacement
|
||||
- **React Router v6** - Client-side routing
|
||||
- **Tailwind CSS 3** - Utility-first styling with custom components
|
||||
- **CodeMirror 6** - Code editing with syntax highlighting (JavaScript, Python, JSON, Markdown, CSS, HTML)
|
||||
- **Xterm.js 5** - Terminal emulation with WebGL rendering
|
||||
- **React Markdown** - Markdown rendering with KaTeX math support
|
||||
- **Lucide React** - Icon library
|
||||
|
||||
### Backend
|
||||
- **Node.js** (v20+) - ES modules (type: "module")
|
||||
- **Express.js 4** - REST API server
|
||||
- **WebSocket (ws 8)** - Real-time bidirectional communication
|
||||
- **SQLite (better-sqlite3 12)** - Embedded database for users, sessions, settings
|
||||
- **JWT (jsonwebtoken 9)** - Authentication tokens
|
||||
- **bcrypt 6** - Password hashing
|
||||
- **node-pty 1** - Pseudo-terminal for shell sessions
|
||||
|
||||
### AI SDKs
|
||||
- **@anthropic-ai/claude-agent-sdk 0.1.x** - Direct Claude integration
|
||||
- **@openai/codex-sdk 0.75.x** - OpenAI Codex integration
|
||||
- **child process spawning** - Cursor CLI integration
|
||||
|
||||
### DevOps
|
||||
- **concurrently** - Run frontend and backend in parallel
|
||||
- **Vite** - Build system with manual chunk splitting
|
||||
- **auto-changelog** - Automated CHANGELOG generation
|
||||
- **release-it** - Release automation
|
||||
|
||||
### Database
|
||||
- **SQLite** with three main tables:
|
||||
- `users` - Authentication and user settings
|
||||
- `api_keys` - External API key management
|
||||
- `user_credentials` - Stored service credentials (GitHub, GitLab, etc.)
|
||||
|
||||
## Project Conventions
|
||||
|
||||
### Code Style
|
||||
|
||||
#### JavaScript/React (Frontend)
|
||||
- **ES Modules** - All imports use `.js` or `.jsx` extensions explicitly
|
||||
- **Functional Components** - React components are functional with hooks (no class components)
|
||||
- **File Naming**:
|
||||
- Components: PascalCase (e.g., `ChatInterface.jsx`, `Settings.jsx`)
|
||||
- Utilities: camelCase (e.g., `api.js`, `websocket.js`)
|
||||
- Hooks: camelCase with `use` prefix (e.g., `useAudioRecorder.js`, `useLocalStorage.jsx`)
|
||||
- **Imports**: Organized in groups (React, third-party, relative imports)
|
||||
- **JSX**: Single quotes for attributes, double quotes for strings
|
||||
- **Component Organization**:
|
||||
- Hooks at top level
|
||||
- Event handlers after hooks
|
||||
- Render helpers at bottom
|
||||
- Main render return at end
|
||||
|
||||
#### JavaScript (Backend)
|
||||
- **ES Modules** - All files use `.js` extension with import/export
|
||||
- **Async/Await** - Preferred over callbacks for async operations
|
||||
- **Error Handling** - Try-catch blocks for file I/O, process spawning, database operations
|
||||
- **Comments**: JSDoc-style for modules and key functions
|
||||
- **Constants**: UPPER_SNAKE_CASE (e.g., `TOOL_APPROVAL_TIMEOUT_MS`, `CONTEXT_WINDOW`)
|
||||
|
||||
#### Code Comments
|
||||
- **Block comments** (`/* */`) for file headers and complex logic explanations
|
||||
- **Line comments** (`//`) for inline explanations
|
||||
- **TODO/FIXME** markers for pending work
|
||||
- **Session Protection comments** use multi-line header format for critical integration points
|
||||
|
||||
### Architecture Patterns
|
||||
|
||||
#### Frontend Architecture
|
||||
- **Component Hierarchy**: `App.jsx` → Context Providers → Page Components → UI Components
|
||||
- **Context-based State Management**:
|
||||
- `AuthContext` - User authentication state
|
||||
- `WebSocketContext` - WebSocket connection management
|
||||
- `ThemeContext` - Dark/light mode
|
||||
- `TaskMasterContext` - Task management state
|
||||
- `TasksSettingsContext` - Task settings persistence
|
||||
- **Custom Hooks** for reusable logic (e.g., `useAudioRecorder`, `useLocalStorage`)
|
||||
- **Protected Routes** - `ProtectedRoute` component wraps authenticated pages
|
||||
- **Error Boundaries** - `ErrorBoundary` wraps main app for graceful failure
|
||||
|
||||
#### Backend Architecture
|
||||
- **Express Middleware Chain**:
|
||||
1. CORS (cross-origin requests)
|
||||
2. JSON body parser
|
||||
3. JWT authentication (`middleware/auth.js`)
|
||||
4. Route handlers
|
||||
- **Modular Routes** - Each feature has its own router in `routes/` directory
|
||||
- **Session Management**:
|
||||
- In-memory `activeSessions` Maps per provider (Claude, Cursor, Codex)
|
||||
- PTY sessions cached in `ptySessionsMap` with 30-minute timeout
|
||||
- Session resumption via `sessionId` parameter
|
||||
- **WebSocket Handlers**:
|
||||
- `/ws` - Chat and AI assistant communication
|
||||
- `/shell` - Terminal/shell access with PTY spawning
|
||||
- **Error Handling**:
|
||||
- Path validation prevents directory traversal
|
||||
- Try-catch wrapping for process spawning
|
||||
- WebSocket errors logged but don't crash server
|
||||
|
||||
#### Communication Patterns
|
||||
- **REST API** - Standard HTTP methods for CRUD operations
|
||||
- **WebSocket Message Flow**:
|
||||
1. Client sends command with options (projectPath, sessionId, etc.)
|
||||
2. Server invokes SDK/CLI integration
|
||||
3. Responses streamed via `writer.send()` with message type markers
|
||||
4. UI renders based on message type (content, tool_use, error, etc.)
|
||||
- **Message Types**: `claude-command`, `cursor-command`, `codex-command`, `abort-session`, `claude-permission-response`
|
||||
|
||||
### Testing Strategy
|
||||
|
||||
**Current Status**: No formal test suite exists. Manual testing focuses on:
|
||||
- Multi-provider session management (Claude, Cursor, Codex)
|
||||
- WebSocket connection reliability
|
||||
- File operations security
|
||||
- Terminal session persistence
|
||||
- Cross-device responsiveness
|
||||
|
||||
**Testing Guidelines** (for future tests):
|
||||
- Test WebSocket reconnection scenarios
|
||||
- Verify file system path validation (directory traversal prevention)
|
||||
- Test tool permission approval flows
|
||||
- Validate session resumption across providers
|
||||
- Test concurrent sessions and PTY cleanup
|
||||
- Verify database migrations and schema changes
|
||||
|
||||
### Git Workflow
|
||||
|
||||
#### Branching Strategy
|
||||
- **main** - Production-ready code, always deployable
|
||||
- **feature/*** - New features (e.g., `feat/show-grant-permission-button`)
|
||||
- **fix/*** - Bug fixes (e.g., `fix/server-crash-when-opening-settings`)
|
||||
- **Merge commits** - Pull requests merged with merge commits (not rebase)
|
||||
|
||||
#### Commit Message Conventions
|
||||
Based on recent commit history:
|
||||
- **feat:** - New features (e.g., "feat: add Bash command approval handling")
|
||||
- **fix:** - Bug fixes (e.g., "fix: normalize file path handling")
|
||||
- **Merge pull request #XXX** - PR merges (automated)
|
||||
- **Merge branch** - Branch merges (automated)
|
||||
|
||||
**Commit Message Format**:
|
||||
```
|
||||
type: brief description
|
||||
|
||||
Optional detailed explanation with multiple lines.
|
||||
|
||||
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
||||
```
|
||||
|
||||
#### Release Process
|
||||
1. Update version in `package.json`
|
||||
2. Run `npm run release` (triggers `release-it`)
|
||||
3. Auto-generated CHANGELOG via `auto-changelog`
|
||||
4. Tag and push to GitHub repository
|
||||
|
||||
## Domain Context
|
||||
|
||||
### AI CLI Tools Integration
|
||||
|
||||
#### Claude Code
|
||||
- **Session Location**: `~/.claude/projects/[encoded-path]/`
|
||||
- **Models**: Claude Sonnet 4.5, Opus 4.5 (see `shared/modelConstants.js`)
|
||||
- **Tool Permissions**: All tools **disabled by default** for security
|
||||
- **Approval Timeout**: 55 seconds (configurable via `CLAUDE_TOOL_APPROVAL_TIMEOUT_MS`)
|
||||
- **SDK Integration**: Direct SDK usage (no child processes) for better performance
|
||||
|
||||
#### Cursor CLI
|
||||
- **Session Location**: `~/.cursor/projects/`
|
||||
- **Integration**: Child process spawning (`cursor-agent` command)
|
||||
- **Resume Support**: `--resume` parameter for session continuation
|
||||
|
||||
#### OpenAI Codex
|
||||
- **Session Location**: `~/.codex/sessions/` (JSONL format)
|
||||
- **Token Usage**: Tracked and displayed in UI
|
||||
- **Integration**: `@openai/codex-sdk` with session file parsing
|
||||
|
||||
### Project Discovery
|
||||
Projects auto-discovered from provider-specific directories using:
|
||||
- `extractProjectDirectory()` - Resolves encoded project paths
|
||||
- `getFileTree()` - Generates file tree structure for browsing
|
||||
- `chokidar` - File watcher for live updates
|
||||
|
||||
### File System Security
|
||||
All file operations validate paths are within project root:
|
||||
```javascript
|
||||
const normalizedRoot = path.resolve(projectRoot) + path.sep;
|
||||
if (!resolved.startsWith(normalizedRoot)) {
|
||||
return res.status(403).json({ error: 'Path must be under project root' });
|
||||
}
|
||||
```
|
||||
|
||||
### Session Protection System
|
||||
Prevents sidebar project updates from interrupting active chat sessions:
|
||||
- User sends message → Session marked as **active**
|
||||
- Claude completes → Session marked as **inactive**
|
||||
- Session aborted → Session marked as **inactive**
|
||||
- App.jsx pauses sidebar updates when session is **active**
|
||||
|
||||
## Important Constraints
|
||||
|
||||
### Technical Constraints
|
||||
- **Node.js Version**: Minimum v20 required (ES modules, crypto.randomUUID())
|
||||
- **Single User System**: Database designed for single-user instance (not multi-tenant)
|
||||
- **In-Memory State**: Active sessions and tool approvals don't persist across restarts
|
||||
- **No Native Notifications**: Uses in-app UI for all alerts
|
||||
- **Tool Approval Timeout**: Must be < 60s (SDK control timeout limit)
|
||||
|
||||
### Security Constraints
|
||||
- **Path Traversal Protection**: All file paths validated against project root
|
||||
- **Tool Permissions**: Opt-in model (all tools disabled by default)
|
||||
- **Authentication**: JWT-based with bcrypt password hashing
|
||||
- **API Key Management**: Stored in database with user association
|
||||
- **WebSocket Security**: Same-origin policy, no CORS on WebSocket routes
|
||||
|
||||
### Performance Constraints
|
||||
- **Context Window**: Default 160,000 tokens (configurable via `CONTEXT_WINDOW`)
|
||||
- **Chunk Size**: Vite build warns at 1000KB chunks
|
||||
- **PTY Session Cache**: 30-minute timeout to prevent memory leaks
|
||||
- **Database**: SQLite (not suitable for high-concurrency multi-user scenarios)
|
||||
|
||||
### Business Constraints
|
||||
- **Provider Dependency**: Requires external CLI tools to be installed separately
|
||||
- **Single Instance Design**: Not designed for hosted multi-tenant deployments
|
||||
- **No Native Mobile Apps**: Web-only (can be wrapped in PWA, but not native)
|
||||
- **Open Source MIT License**: Free to use, modify, and distribute
|
||||
|
||||
## External Dependencies
|
||||
|
||||
### Required CLI Tools (User-Installed)
|
||||
- **Claude Code CLI** - `npm install -g @anthropic-ai/claude-code`
|
||||
- **Cursor CLI** - Installed via Cursor IDE
|
||||
- **OpenAI Codex CLI** - `npm install -g @openai/codex`
|
||||
|
||||
### NPM Dependencies
|
||||
**Runtime** (production):
|
||||
- Web framework: `express`, `react`, `react-dom`, `react-router-dom`
|
||||
- Real-time: `ws`, `@xterm/xterm`, `node-pty`
|
||||
- Database: `better-sqlite3`, `sqlite3`
|
||||
- Auth: `jsonwebtoken`, `bcrypt`
|
||||
- AI SDKs: `@anthropic-ai/claude-agent-sdk`, `@openai/codex-sdk`
|
||||
- UI: `@uiw/react-codemirror`, `lucide-react`, `tailwindcss`
|
||||
- Utilities: `chokidar`, `fuse.js`, `gray-matter`, `katex`
|
||||
|
||||
**Development**:
|
||||
- Build: `vite`, `@vitejs/plugin-react`, `concurrently`
|
||||
- Release: `release-it`, `auto-changelog`
|
||||
- Image processing: `sharp`
|
||||
|
||||
### External Services
|
||||
- **GitHub API** - Via `@octokit/rest` for Git operations
|
||||
- **OpenAI API** - Optional Whisper transcription (requires `OPENAI_API_KEY`)
|
||||
- **MCP Servers** - User-configurable Model Context Protocol servers
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
PORT=3001 # Backend server port
|
||||
VITE_PORT=5173 # Frontend dev server port
|
||||
CONTEXT_WINDOW=160000 # Claude context size
|
||||
CLAUDE_TOOL_APPROVAL_TIMEOUT_MS=55000 # Tool approval timeout
|
||||
OPENAI_API_KEY= # Whisper transcription key
|
||||
VITE_IS_PLATFORM=false # Platform mode flag
|
||||
```
|
||||
|
||||
### Repository Information
|
||||
- **Homepage**: https://claudecodeui.siteboon.ai
|
||||
- **Repository**: https://github.com/siteboon/claudecodeui
|
||||
- **Issues**: https://github.com/siteboon/claudecodeui/issues
|
||||
- **Package**: `@siteboon/claude-code-ui` on npm
|
||||
@@ -1,285 +0,0 @@
|
||||
# 项目上下文
|
||||
|
||||
## 目的
|
||||
|
||||
Claude Code UI(又名 Cloud CLI)是一个全栈 Web 应用程序,为 [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)、[Cursor CLI](https://docs.cursor.com/en/cli/overview) 和 [OpenAI Codex](https://developers.openai.com/codex) 提供响应式桌面和移动界面。它使用户能够通过浏览器从任何设备与 AI 编程助手交互,为 AI 驱动的开发工作流程提供无缝的跨设备体验。
|
||||
|
||||
**主要目标:**
|
||||
- 提供从任何设备(桌面、平板、移动)对 AI CLI 工具的通用访问
|
||||
- 启用与 AI 助手的实时聊天和终端交互
|
||||
- 提供集成的文件浏览、代码编辑和 Git 操作
|
||||
- 支持会话管理和对话恢复
|
||||
- 通过身份验证和工具权限系统维护安全性
|
||||
|
||||
## 技术栈
|
||||
|
||||
### 前端
|
||||
- **React 18** - 使用 hooks 的函数式组件
|
||||
- **Vite 7** - 快速构建工具,支持热模块替换
|
||||
- **React Router v6** - 客户端路由
|
||||
- **Tailwind CSS 3** - 实用工具优先的样式,带有自定义组件
|
||||
- **CodeMirror 6** - 代码编辑,支持语法高亮(JavaScript、Python、JSON、Markdown、CSS、HTML)
|
||||
- **Xterm.js 5** - 终端模拟,使用 WebGL 渲染
|
||||
- **React Markdown** - Markdown 渲染,支持 KaTeX 数学
|
||||
- **Lucide React** - 图标库
|
||||
|
||||
### 后端
|
||||
- **Node.js**(v20+)- ES 模块(type: "module")
|
||||
- **Express.js 4** - REST API 服务器
|
||||
- **WebSocket (ws 8)** - 实时双向通信
|
||||
- **SQLite (better-sqlite3 12)** - 嵌入式数据库,用于用户、会话、设置
|
||||
- **JWT (jsonwebtoken 9)** - 身份验证令牌
|
||||
- **bcrypt 6** - 密码哈希
|
||||
- **node-pty 1** - 用于 shell 会话的伪终端
|
||||
|
||||
### AI SDK
|
||||
- **@anthropic-ai/claude-agent-sdk 0.1.x** - 直接 Claude 集成
|
||||
- **@openai/codex-sdk 0.75.x** - OpenAI Codex 集成
|
||||
- **子进程生成** - Cursor CLI 集成
|
||||
|
||||
### DevOps
|
||||
- **concurrently** - 并行运行前端和后端
|
||||
- **Vite** - 构建系统,手动代码分割
|
||||
- **auto-changelog** - 自动生成 CHANGELOG
|
||||
- **release-it** - 发布自动化
|
||||
|
||||
### 数据库
|
||||
- **SQLite** 三个主要表:
|
||||
- `users` - 身份验证和用户设置
|
||||
- `api_keys` - 外部 API 密钥管理
|
||||
- `user_credentials` - 存储的服务凭据(GitHub、GitLab 等)
|
||||
|
||||
## 项目约定
|
||||
|
||||
### 代码风格
|
||||
|
||||
#### JavaScript/React(前端)
|
||||
- **ES 模块** - 所有导入都显式使用 `.js` 或 `.jsx` 扩展名
|
||||
- **函数式组件** - React 组件是使用 hooks 的函数(无类组件)
|
||||
- **文件命名**:
|
||||
- 组件:PascalCase(例如 `ChatInterface.jsx`、`Settings.jsx`)
|
||||
- 工具:camelCase(例如 `api.js`、`websocket.js`)
|
||||
- Hooks:带 `use` 前缀的 camelCase(例如 `useAudioRecorder.js`、`useLocalStorage.jsx`)
|
||||
- **导入**:按组组织(React、第三方、相对导入)
|
||||
- **JSX**:属性使用单引号,字符串使用双引号
|
||||
- **组件组织**:
|
||||
- Hooks 在顶层
|
||||
- 事件处理程序在 hooks 之后
|
||||
- 渲染助手在底部
|
||||
- 主渲染返回在最后
|
||||
|
||||
#### JavaScript(后端)
|
||||
- **ES 模块** - 所有文件都使用 `.js` 扩展名和 import/export
|
||||
- **Async/Await** - 异步操作优于回调
|
||||
- **错误处理** - 文件 I/O、进程生成、数据库操作的 try-catch 块
|
||||
- **注释**:模块和关键函数使用 JSDoc 风格
|
||||
- **常量**:UPPER_SNAKE_CASE(例如 `TOOL_APPROVAL_TIMEOUT_MS`、`CONTEXT_WINDOW`)
|
||||
|
||||
#### 代码注释
|
||||
- **块注释**(`/* */`)用于文件头和复杂逻辑说明
|
||||
- **行注释**(`//`)用于内联说明
|
||||
- **TODO/FIXME** 标记用于待处理工作
|
||||
- **会话保护注释**在关键集成点使用多行标题格式
|
||||
|
||||
### 架构模式
|
||||
|
||||
#### 前端架构
|
||||
- **组件层次结构**:`App.jsx` → 上下文提供者 → 页面组件 → UI 组件
|
||||
- **基于上下文的状态管理**:
|
||||
- `AuthContext` - 用户身份验证状态
|
||||
- `WebSocketContext` - WebSocket 连接管理
|
||||
- `ThemeContext` - 深色/浅色模式
|
||||
- `TaskMasterContext` - 任务管理状态
|
||||
- `TasksSettingsContext` - 任务设置持久化
|
||||
- **自定义 Hooks** 用于可重用逻辑(例如 `useAudioRecorder`、`useLocalStorage`)
|
||||
- **受保护路由** - `ProtectedRoute` 组件包装已验证的页面
|
||||
- **错误边界** - `ErrorBoundary` 包装主应用程序以实现优雅故障
|
||||
|
||||
#### 后端架构
|
||||
- **Express 中间件链**:
|
||||
1. CORS(跨域请求)
|
||||
2. JSON 正文解析器
|
||||
3. JWT 身份验证(`middleware/auth.js`)
|
||||
4. 路由处理程序
|
||||
- **模块化路由** - 每个功能在 `routes/` 目录中都有自己的路由器
|
||||
- **会话管理**:
|
||||
- 每个提供者的内存 `activeSessions` 映射(Claude、Cursor、Codex)
|
||||
- PTY 会话缓存在 `ptySessionsMap` 中,具有 30 分钟超时
|
||||
- 通过 `sessionId` 参数恢复会话
|
||||
- **WebSocket 处理程序**:
|
||||
- `/ws` - 聊天和 AI 助手通信
|
||||
- `/shell` - 终端/shell 访问,带有 PTY 生成
|
||||
- **错误处理**:
|
||||
- 路径验证防止目录遍历
|
||||
- 进程生成的 try-catch 包装
|
||||
- WebSocket 错误被记录但不会导致服务器崩溃
|
||||
|
||||
#### 通信模式
|
||||
- **REST API** - 用于 CRUD 操作的标准 HTTP 方法
|
||||
- **WebSocket 消息流**:
|
||||
1. 客户端发送带有选项(projectPath、sessionId 等)的命令
|
||||
2. 服务器调用 SDK/CLI 集成
|
||||
3. 通过 `writer.send()` 流式传输响应,带有消息类型标记
|
||||
4. UI 根据消息类型(content、tool_use、error 等)进行渲染
|
||||
- **消息类型**:`claude-command`、`cursor-command`、`codex-command`、`abort-session`、`claude-permission-response`
|
||||
|
||||
### 测试策略
|
||||
|
||||
**当前状态**:不存在正式测试套件。手动测试侧重于:
|
||||
- 多提供商会话管理(Claude、Cursor、Codex)
|
||||
- WebSocket 连接可靠性
|
||||
- 文件操作安全性
|
||||
- 终端会话持久性
|
||||
- 跨设备响应能力
|
||||
|
||||
**测试指南**(用于未来测试):
|
||||
- 测试 WebSocket 重新连接场景
|
||||
- 验证文件系统路径验证(目录遍历预防)
|
||||
- 测试工具权限批准流程
|
||||
- 验证跨提供商的会话恢复
|
||||
- 测试并发会话和 PTY 清理
|
||||
- 验证数据库迁移和架构更改
|
||||
|
||||
### Git 工作流
|
||||
|
||||
#### 分支策略
|
||||
- **main** - 生产就绪代码,始终可部署
|
||||
- **feature/*** - 新功能(例如 `feat/show-grant-permission-button`)
|
||||
- **fix/*** - 错误修复(例如 `fix/server-crash-when-opening-settings`)
|
||||
- **合并提交** - 使用合并提交合并的拉取请求(不是 rebase)
|
||||
|
||||
#### 提交消息约定
|
||||
基于最近的提交历史:
|
||||
- **feat:** - 新功能(例如 "feat: add Bash command approval handling")
|
||||
- **fix:** - 错误修复(例如 "fix: normalize file path handling")
|
||||
- **Merge pull request #XXX** - PR 合并(自动)
|
||||
- **Merge branch** - 分支合并(自动)
|
||||
|
||||
**提交消息格式**:
|
||||
```
|
||||
type: 简要描述
|
||||
|
||||
可选的详细说明,多行。
|
||||
|
||||
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
||||
```
|
||||
|
||||
#### 发布流程
|
||||
1. 更新 `package.json` 中的版本
|
||||
2. 运行 `npm run release`(触发 `release-it`)
|
||||
3. 通过 `auto-changelog` 自动生成 CHANGELOG
|
||||
4. 标记并推送到 GitHub 存储库
|
||||
|
||||
## 领域上下文
|
||||
|
||||
### AI CLI 工具集成
|
||||
|
||||
#### Claude Code
|
||||
- **会话位置**:`~/.claude/projects/[encoded-path]/`
|
||||
- **模型**:Claude Sonnet 4.5、Opus 4.5(参见 `shared/modelConstants.js`)
|
||||
- **工具权限**:出于安全考虑,所有工具**默认禁用**
|
||||
- **批准超时**:55 秒(可通过 `CLAUDE_TOOL_APPROVAL_TIMEOUT_MS` 配置)
|
||||
- **SDK 集成**:直接 SDK 使用(无子进程)以获得更好的性能
|
||||
|
||||
#### Cursor CLI
|
||||
- **会话位置**:`~/.cursor/projects/`
|
||||
- **集成**:子进程生成(`cursor-agent` 命令)
|
||||
- **恢复支持**:`--resume` 参数用于会话继续
|
||||
|
||||
#### OpenAI Codex
|
||||
- **会话位置**:`~/.codex/sessions/`(JSONL 格式)
|
||||
- **令牌使用**:在 UI 中跟踪和显示
|
||||
- **集成**:`@openai/codex-sdk` 与会话文件解析
|
||||
|
||||
### 项目发现
|
||||
从特定于提供程序的目录自动发现项目,使用:
|
||||
- `extractProjectDirectory()` - 解析编码的项目路径
|
||||
- `getFileTree()` - 生成文件树结构以供浏览
|
||||
- `chokidar` - 用于实时更新的文件监视程序
|
||||
|
||||
### 文件系统安全性
|
||||
所有文件操作验证路径都在项目根目录内:
|
||||
```javascript
|
||||
const normalizedRoot = path.resolve(projectRoot) + path.sep;
|
||||
if (!resolved.startsWith(normalizedRoot)) {
|
||||
return res.status(403).json({ error: 'Path must be under project root' });
|
||||
}
|
||||
```
|
||||
|
||||
### 会话保护系统
|
||||
防止侧边栏项目更新中断活动聊天会话:
|
||||
- 用户发送消息 → 会话标记为**活动**
|
||||
- Claude 完成 → 会话标记为**非活动**
|
||||
- 会话中止 → 会话标记为**非活动**
|
||||
- App.jsx 在会话**活动**时暂停侧边栏更新
|
||||
|
||||
## 重要约束
|
||||
|
||||
### 技术约束
|
||||
- **Node.js 版本**:最低 v20(ES 模块、crypto.randomUUID())
|
||||
- **单用户系统**:数据库设计用于单用户实例(非多租户)
|
||||
- **内存状态**:活动会话和工具批准不会在重启后持久化
|
||||
- **无原生通知**:使用应用内 UI 进行所有警报
|
||||
- **工具批准超时**:必须 < 60s(SDK 控制超时限制)
|
||||
|
||||
### 安全约束
|
||||
- **路径遍历保护**:所有文件路径都根据项目根目录进行验证
|
||||
- **工具权限**:选择加入模式(所有工具默认禁用)
|
||||
- **身份验证**:基于 JWT,使用 bcrypt 密码哈希
|
||||
- **API 密钥管理**:存储在数据库中,与用户关联
|
||||
- **WebSocket 安全性**:同源策略,WebSocket 路由上无 CORS
|
||||
|
||||
### 性能约束
|
||||
- **上下文窗口**:默认 160,000 个令牌(可通过 `CONTEXT_WINDOW` 配置)
|
||||
- **块大小**:Vite 构建在 1000KB 块时警告
|
||||
- **PTY 会话缓存**:30 分钟超时以防止内存泄漏
|
||||
- **数据库**:SQLite(不适合高并发多用户场景)
|
||||
|
||||
### 业务约束
|
||||
- **提供程序依赖**:需要单独安装外部 CLI 工具
|
||||
- **单实例设计**:不适用于托管多租户部署
|
||||
- **无原生移动应用**:仅 Web(可以包装在 PWA 中,但不是原生)
|
||||
- **开源 MIT 许可证**:可免费使用、修改和分发
|
||||
|
||||
## 外部依赖
|
||||
|
||||
### 必需的 CLI 工具(用户安装)
|
||||
- **Claude Code CLI** - `npm install -g @anthropic-ai/claude-code`
|
||||
- **Cursor CLI** - 通过 Cursor IDE 安装
|
||||
- **OpenAI Codex CLI** - `npm install -g @openai/codex`
|
||||
|
||||
### NPM 依赖
|
||||
**运行时**(生产):
|
||||
- Web 框架:`express`、`react`、`react-dom`、`react-router-dom`
|
||||
- 实时:`ws`、`@xterm/xterm`、`node-pty`
|
||||
- 数据库:`better-sqlite3`、`sqlite3`
|
||||
- 身份验证:`jsonwebtoken`、`bcrypt`
|
||||
- AI SDK:`@anthropic-ai/claude-agent-sdk`、`@openai/codex-sdk`
|
||||
- UI:`@uiw/react-codemirror`、`lucide-react`、`tailwindcss`
|
||||
- 工具:`chokidar`、`fuse.js`、`gray-matter`、`katex`
|
||||
|
||||
**开发**:
|
||||
- 构建:`vite`、`@vitejs/plugin-react`、`concurrently`
|
||||
- 发布:`release-it`、`auto-changelog`
|
||||
- 图像处理:`sharp`
|
||||
|
||||
### 外部服务
|
||||
- **GitHub API** - 通过 `@octokit/rest` 进行 Git 操作
|
||||
- **OpenAI API** - 可选的 Whisper 转录(需要 `OPENAI_API_KEY`)
|
||||
- **MCP 服务器** - 用户可配置的模型上下文协议服务器
|
||||
|
||||
### 环境变量
|
||||
```bash
|
||||
PORT=3001 # 后端服务器端口
|
||||
VITE_PORT=5173 # 前端开发服务器端口
|
||||
CONTEXT_WINDOW=160000 # Claude 上下文大小
|
||||
CLAUDE_TOOL_APPROVAL_TIMEOUT_MS=55000 # 工具批准超时
|
||||
OPENAI_API_KEY= # Whisper 转录密钥
|
||||
VITE_IS_PLATFORM=false # 平台模式标志
|
||||
```
|
||||
|
||||
### 存储库信息
|
||||
- **主页**:https://claudecodeui.siteboon.ai
|
||||
- **存储库**:https://github.com/siteboon/claudecodeui
|
||||
- **问题**:https://github.com/siteboon/claudecodeui/issues
|
||||
- **包**:npm 上的 `@siteboon/claude-code-ui`
|
||||
Reference in New Issue
Block a user