mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-14 02:42:04 +08:00
feat: enhance MCP server management and system settings
- Added functionality to save MCP server configurations as templates in the MCP Manager. - Implemented new hooks for managing system settings including Chinese response, Windows platform, and Codex CLI enhancements. - Updated API calls to support fetching and toggling system settings. - Introduced UI components for displaying and managing response language settings and system status. - Enhanced error handling and notifications for server deletion and template saving actions. - Updated localization files for new settings and descriptions in English and Chinese.
This commit is contained in:
@@ -1,44 +1,40 @@
|
|||||||
---
|
---
|
||||||
name: workflow-lite-plan-execute
|
name: workflow-lite-plan-execute
|
||||||
description: Unified lightweight planning skill with mode selection (Lite Plan, Multi-CLI Plan, Lite Fix). Supports exploration, diagnosis, multi-CLI collaboration, and shared execution via lite-execute.
|
description: Lightweight planning and execution skill. Exploration → Clarification → Planning → Confirmation → Execution via lite-execute.
|
||||||
allowed-tools: spawn_agent, wait, send_input, close_agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep, mcp__ace-tool__search_context
|
allowed-tools: spawn_agent, wait, send_input, close_agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep, mcp__ace-tool__search_context
|
||||||
---
|
---
|
||||||
|
|
||||||
# Planning Workflow
|
# Planning Workflow
|
||||||
|
|
||||||
Unified lightweight planning skill that consolidates multiple planning approaches into a single entry point with mode selection. Default mode: **Lite Plan**. All planning modes share a common execution phase (lite-execute).
|
Lightweight planning skill: Lite Plan produces an implementation plan, then hands off to Lite Execute for task execution.
|
||||||
|
|
||||||
## Architecture Overview
|
## Architecture Overview
|
||||||
|
|
||||||
```
|
```
|
||||||
┌──────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────┐
|
||||||
│ Planning Workflow Orchestrator (SKILL.md) │
|
│ Planning Workflow Orchestrator (SKILL.md) │
|
||||||
│ → Parse args → Mode selection → Load phase → Execute │
|
│ → Parse args → Lite Plan → Lite Execute │
|
||||||
└────────────┬─────────────────────────────────────────────┘
|
└────────────┬─────────────────────────────────────┘
|
||||||
│ Mode Selection (default: Lite Plan)
|
│
|
||||||
┌────────┼────────┬──────────┐
|
┌────────┴────────┐
|
||||||
↓ ↓ ↓ ↓ (shared)
|
↓ ↓
|
||||||
┌────────┐ ┌────────┐ ┌────────┐ ┌────────────┐
|
┌────────┐ ┌────────────┐
|
||||||
│Phase 1 │ │Phase 2 │ │Phase 3 │ │ Phase 4 │
|
│Phase 1 │────→│ Phase 4 │
|
||||||
│ Lite │ │Multi- │ │ Lite │ │ Lite │
|
│ Lite │ │ Lite │
|
||||||
│ Plan │ │CLI Plan│ │ Fix │ │ Execute │
|
│ Plan │ │ Execute │
|
||||||
└────────┘ └────────┘ └────────┘ └────────────┘
|
└────────┘ └────────────┘
|
||||||
│ │ │ ↑
|
|
||||||
└──────────┴──────────┴───────────┘
|
|
||||||
(all hand off to Phase 4)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Design Principles
|
## Key Design Principles
|
||||||
|
|
||||||
1. **Mode Selection First**: User chooses planning approach before any work begins
|
1. **Shared Execution**: Lite Plan produces `executionContext` consumed by Phase 4 (lite-execute)
|
||||||
2. **Shared Execution**: All planning modes produce `executionContext` consumed by Phase 4 (lite-execute)
|
2. **Progressive Phase Loading**: Only load phase docs when about to execute
|
||||||
3. **Progressive Phase Loading**: Only load the selected planning phase + execution phase
|
3. **Auto-Continue**: Planning completes → automatically loads execution phase
|
||||||
4. **Auto-Continue**: Planning phase completes → automatically loads execution phase
|
4. **Default Auto Mode**: When `--yes`, skip confirmations and auto-approve plan
|
||||||
5. **Default Lite Plan**: When no mode specified, use Lite Plan (most common)
|
|
||||||
|
|
||||||
## Auto Mode
|
## Auto Mode
|
||||||
|
|
||||||
When `--yes` or `-y`: Skip mode selection (use default or flag-specified mode), auto-approve plan, skip clarifications.
|
When `--yes` or `-y`: Auto-approve plan, skip clarifications, use default execution settings.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -47,17 +43,13 @@ Skill(skill="workflow-lite-plan-execute", args="<task description>")
|
|||||||
Skill(skill="workflow-lite-plan-execute", args="[FLAGS] \"<task description>\"")
|
Skill(skill="workflow-lite-plan-execute", args="[FLAGS] \"<task description>\"")
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
--mode lite-plan|multi-cli|lite-fix Planning mode selection (default: lite-plan)
|
|
||||||
-y, --yes Skip all confirmations (auto mode)
|
-y, --yes Skip all confirmations (auto mode)
|
||||||
-e, --explore Force exploration (lite-plan only)
|
-e, --explore Force exploration phase
|
||||||
--hotfix Fast hotfix mode (lite-fix only)
|
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
Skill(skill="workflow-lite-plan-execute", args="\"Implement JWT authentication\"") # Default: lite-plan
|
Skill(skill="workflow-lite-plan-execute", args="\"Implement JWT authentication\"")
|
||||||
Skill(skill="workflow-lite-plan-execute", args="--mode multi-cli \"Refactor payment module\"") # Multi-CLI planning
|
Skill(skill="workflow-lite-plan-execute", args="-y \"Add user profile page\"")
|
||||||
Skill(skill="workflow-lite-plan-execute", args="--mode lite-fix \"Login fails with 500 error\"") # Bug fix mode
|
Skill(skill="workflow-lite-plan-execute", args="-e \"Refactor payment module\"")
|
||||||
Skill(skill="workflow-lite-plan-execute", args="-y \"Add user profile page\"") # Auto mode
|
|
||||||
Skill(skill="workflow-lite-plan-execute", args="--mode lite-fix --hotfix \"Production DB timeout\"") # Hotfix mode
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Subagent API Reference
|
## Subagent API Reference
|
||||||
@@ -129,30 +121,15 @@ close_agent({ id: agentId })
|
|||||||
|
|
||||||
```
|
```
|
||||||
Input Parsing:
|
Input Parsing:
|
||||||
├─ Extract flags: --mode, --yes, --explore, --hotfix
|
├─ Extract flags: --yes, --explore
|
||||||
└─ Extract task description (string or file path)
|
└─ Extract task description (string or file path)
|
||||||
|
|
||||||
Mode Selection:
|
Planning Phase:
|
||||||
└─ Decision:
|
└─ Phase 1: Lite Plan
|
||||||
├─ --mode lite-plan (or no --mode flag) → Read phases/01-lite-plan.md
|
└─ Ref: phases/01-lite-plan.md
|
||||||
├─ --mode multi-cli → Read phases/02-multi-cli-plan.md
|
└─ Output: executionContext (plan.json + explorations + selections)
|
||||||
├─ --mode lite-fix → Read phases/03-lite-fix.md
|
|
||||||
└─ No flag + not --yes → AskUserQuestion (default: Lite Plan)
|
|
||||||
|
|
||||||
Planning Phase (one of):
|
Execution Phase:
|
||||||
├─ Phase 1: Lite Plan
|
|
||||||
│ └─ Ref: phases/01-lite-plan.md
|
|
||||||
│ └─ Output: executionContext (plan.json + explorations + selections)
|
|
||||||
│
|
|
||||||
├─ Phase 2: Multi-CLI Plan
|
|
||||||
│ └─ Ref: phases/02-multi-cli-plan.md
|
|
||||||
│ └─ Output: executionContext (plan.json + synthesis rounds + selections)
|
|
||||||
│
|
|
||||||
└─ Phase 3: Lite Fix
|
|
||||||
└─ Ref: phases/03-lite-fix.md
|
|
||||||
└─ Output: executionContext (fix-plan.json + diagnoses + selections)
|
|
||||||
|
|
||||||
Execution Phase (always):
|
|
||||||
└─ Phase 4: Lite Execute
|
└─ Phase 4: Lite Execute
|
||||||
└─ Ref: phases/04-lite-execute.md
|
└─ Ref: phases/04-lite-execute.md
|
||||||
└─ Input: executionContext from planning phase
|
└─ Input: executionContext from planning phase
|
||||||
@@ -164,64 +141,33 @@ Execution Phase (always):
|
|||||||
| Phase | Document | Purpose |
|
| Phase | Document | Purpose |
|
||||||
|-------|----------|---------|
|
|-------|----------|---------|
|
||||||
| 1 | [phases/01-lite-plan.md](phases/01-lite-plan.md) | Lightweight planning with exploration, clarification, and plan generation |
|
| 1 | [phases/01-lite-plan.md](phases/01-lite-plan.md) | Lightweight planning with exploration, clarification, and plan generation |
|
||||||
| 2 | [phases/02-multi-cli-plan.md](phases/02-multi-cli-plan.md) | Multi-CLI collaborative planning with ACE context and cross-verification |
|
|
||||||
| 3 | [phases/03-lite-fix.md](phases/03-lite-fix.md) | Bug diagnosis and fix planning with severity-based workflow |
|
|
||||||
| 4 | [phases/04-lite-execute.md](phases/04-lite-execute.md) | Shared execution engine: task grouping, batch execution, code review |
|
| 4 | [phases/04-lite-execute.md](phases/04-lite-execute.md) | Shared execution engine: task grouping, batch execution, code review |
|
||||||
|
|
||||||
## Mode Selection Logic
|
## Orchestrator Logic
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Flag parsing
|
// Flag parsing
|
||||||
const autoYes = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
|
const autoYes = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
|
||||||
const modeFlag = extractFlag($ARGUMENTS, '--mode') // 'lite-plan' | 'multi-cli' | 'lite-fix' | null
|
const forceExplore = $ARGUMENTS.includes('--explore') || $ARGUMENTS.includes('-e')
|
||||||
|
const taskDescription = extractTaskDescription($ARGUMENTS)
|
||||||
|
|
||||||
// Mode determination
|
// Phase 1: Lite Plan
|
||||||
let selectedMode
|
Read('phases/01-lite-plan.md')
|
||||||
|
|
||||||
if (modeFlag) {
|
|
||||||
// Explicit mode flag
|
|
||||||
selectedMode = modeFlag
|
|
||||||
} else if (autoYes) {
|
|
||||||
// Auto mode: default to lite-plan
|
|
||||||
selectedMode = 'lite-plan'
|
|
||||||
} else {
|
|
||||||
// Interactive: ask user
|
|
||||||
const selection = AskUserQuestion({
|
|
||||||
questions: [{
|
|
||||||
question: "Select planning approach:",
|
|
||||||
header: "Mode",
|
|
||||||
multiSelect: false,
|
|
||||||
options: [
|
|
||||||
{ label: "Lite Plan (Recommended)", description: "Lightweight planning with exploration and clarification" },
|
|
||||||
{ label: "Multi-CLI Plan", description: "Multi-model collaborative planning (Gemini + Codex + Claude)" },
|
|
||||||
{ label: "Lite Fix", description: "Bug diagnosis and fix planning with severity assessment" }
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
selectedMode = parseSelection(selection) // Map to 'lite-plan' | 'multi-cli' | 'lite-fix'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load phase document
|
|
||||||
const phaseDoc = {
|
|
||||||
'lite-plan': 'phases/01-lite-plan.md',
|
|
||||||
'multi-cli': 'phases/02-multi-cli-plan.md',
|
|
||||||
'lite-fix': 'phases/03-lite-fix.md'
|
|
||||||
}[selectedMode]
|
|
||||||
|
|
||||||
Read(phaseDoc) // Load selected planning phase
|
|
||||||
// Execute planning phase...
|
// Execute planning phase...
|
||||||
|
|
||||||
// After planning completes:
|
// After planning completes:
|
||||||
Read('phases/04-lite-execute.md') // Load execution phase
|
Read('phases/04-lite-execute.md')
|
||||||
|
// Execute execution phase with executionContext from Phase 1
|
||||||
```
|
```
|
||||||
|
|
||||||
## Data Flow
|
## Data Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
Planning Phase (01/02/03)
|
Phase 1: Lite Plan
|
||||||
│
|
│
|
||||||
├─ Produces: executionContext = {
|
├─ Produces: executionContext = {
|
||||||
│ planObject: plan.json or fix-plan.json,
|
│ planObject: plan.json,
|
||||||
│ explorationsContext / diagnosisContext / synthesis rounds,
|
│ explorationsContext,
|
||||||
│ clarificationContext,
|
│ clarificationContext,
|
||||||
│ executionMethod: "Agent" | "Codex" | "Auto",
|
│ executionMethod: "Agent" | "Codex" | "Auto",
|
||||||
│ codeReviewTool: "Skip" | "Gemini Review" | ...,
|
│ codeReviewTool: "Skip" | "Gemini Review" | ...,
|
||||||
@@ -230,7 +176,7 @@ Planning Phase (01/02/03)
|
|||||||
│ }
|
│ }
|
||||||
│
|
│
|
||||||
↓
|
↓
|
||||||
Execution Phase (04)
|
Phase 4: Lite Execute
|
||||||
│
|
│
|
||||||
├─ Consumes: executionContext
|
├─ Consumes: executionContext
|
||||||
├─ Task grouping → Batch creation → Parallel/sequential execution
|
├─ Task grouping → Batch creation → Parallel/sequential execution
|
||||||
@@ -240,10 +186,10 @@ Execution Phase (04)
|
|||||||
|
|
||||||
## TodoWrite Pattern
|
## TodoWrite Pattern
|
||||||
|
|
||||||
**Initialization** (after mode selection):
|
**Initialization**:
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{"content": "Mode: {selectedMode} - Planning", "status": "in_progress", "activeForm": "Planning ({selectedMode})"},
|
{"content": "Lite Plan - Planning", "status": "in_progress", "activeForm": "Planning"},
|
||||||
{"content": "Execution (Phase 4)", "status": "pending", "activeForm": "Executing tasks"}
|
{"content": "Execution (Phase 4)", "status": "pending", "activeForm": "Executing tasks"}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
@@ -251,7 +197,7 @@ Execution Phase (04)
|
|||||||
**After planning completes**:
|
**After planning completes**:
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{"content": "Mode: {selectedMode} - Planning", "status": "completed", "activeForm": "Planning ({selectedMode})"},
|
{"content": "Lite Plan - Planning", "status": "completed", "activeForm": "Planning"},
|
||||||
{"content": "Execution (Phase 4)", "status": "in_progress", "activeForm": "Executing tasks"}
|
{"content": "Execution (Phase 4)", "status": "in_progress", "activeForm": "Executing tasks"}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
@@ -260,20 +206,17 @@ Phase-internal sub-tasks are managed by each phase document (attach/collapse pat
|
|||||||
|
|
||||||
## Core Rules
|
## Core Rules
|
||||||
|
|
||||||
1. **Planning phases NEVER execute code** - all execution delegated to Phase 4
|
1. **Planning phase NEVER executes code** - all execution delegated to Phase 4
|
||||||
2. **Only ONE planning phase runs** per invocation (Phase 1, 2, or 3)
|
2. **Phase 4 ALWAYS runs** after planning completes
|
||||||
3. **Phase 4 ALWAYS runs** after planning completes
|
3. **executionContext is the contract** between planning and execution phases
|
||||||
4. **executionContext is the contract** between planning and execution phases
|
4. **Progressive loading**: Read phase doc ONLY when about to execute
|
||||||
5. **Progressive loading**: Read phase doc ONLY when about to execute
|
5. **Explicit Lifecycle**: Always close_agent after wait completes to free resources
|
||||||
6. **No cross-phase loading**: Don't load Phase 2 if user selected Phase 1
|
|
||||||
7. **Explicit Lifecycle**: Always close_agent after wait completes to free resources
|
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
| Error | Resolution |
|
| Error | Resolution |
|
||||||
|-------|------------|
|
|-------|------------|
|
||||||
| Unknown --mode value | Default to lite-plan with warning |
|
| Planning phase failure | Display error, offer retry |
|
||||||
| Planning phase failure | Display error, offer retry or mode switch |
|
|
||||||
| executionContext missing | Error: planning phase did not produce context |
|
| executionContext missing | Error: planning phase did not produce context |
|
||||||
| Phase file not found | Error with file path for debugging |
|
| Phase file not found | Error with file path for debugging |
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: workflow-test-fix-cycle
|
name: workflow-test-fix-cycle
|
||||||
description: End-to-end test-fix workflow: generate test sessions with progressive layers (L0-L3), then execute iterative fix cycles until pass rate >= 95%. Combines test-fix-gen and test-cycle-execute into a unified pipeline. Triggers on "workflow:test-fix-cycle".
|
description: End-to-end test-fix workflow generate test sessions with progressive layers (L0-L3), then execute iterative fix cycles until pass rate >= 95%. Combines test-fix-gen and test-cycle-execute into a unified pipeline. Triggers on "workflow:test-fix-cycle".
|
||||||
allowed-tools: spawn_agent, wait, send_input, close_agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep
|
allowed-tools: spawn_agent, wait, send_input, close_agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,84 @@
|
|||||||
{}
|
{
|
||||||
|
"theme.AnnouncementBar.closeButtonAriaLabel": "关闭",
|
||||||
|
"theme.BackToTopButton.buttonAriaLabel": "回到顶部",
|
||||||
|
"theme.CodeBlock.copied": "复制成功",
|
||||||
|
"theme.CodeBlock.copy": "复制",
|
||||||
|
"theme.CodeBlock.copyButtonAriaLabel": "复制代码到剪贴板",
|
||||||
|
"theme.CodeBlock.wordWrapToggle": "切换自动换行",
|
||||||
|
"theme.DocSidebarItem.collapseCategoryAriaLabel": "折叠侧边栏分类 '{label}'",
|
||||||
|
"theme.DocSidebarItem.expandCategoryAriaLabel": "展开侧边栏分类 '{label}'",
|
||||||
|
"theme.ErrorPageContent.title": "页面已崩溃。",
|
||||||
|
"theme.ErrorPageContent.tryAgain": "重试",
|
||||||
|
"theme.IconExternalLink.ariaLabel": "(opens in new tab)",
|
||||||
|
"theme.NavBar.navAriaLabel": "主导航",
|
||||||
|
"theme.NotFound.p1": "我们找不到您要找的页面。",
|
||||||
|
"theme.NotFound.p2": "请联系原始链接来源网站的所有者,并告知他们链接已损坏。",
|
||||||
|
"theme.NotFound.title": "找不到页面",
|
||||||
|
"theme.TOCCollapsible.toggleButtonLabel": "本页总览",
|
||||||
|
"theme.admonition.caution": "警告",
|
||||||
|
"theme.admonition.danger": "危险",
|
||||||
|
"theme.admonition.info": "信息",
|
||||||
|
"theme.admonition.note": "备注",
|
||||||
|
"theme.admonition.tip": "提示",
|
||||||
|
"theme.admonition.warning": "注意",
|
||||||
|
"theme.blog.archive.description": "历史博文",
|
||||||
|
"theme.blog.archive.title": "历史博文",
|
||||||
|
"theme.blog.author.noPosts": "该作者尚未撰写任何文章。",
|
||||||
|
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
|
||||||
|
"theme.blog.authorsList.pageTitle": "作者",
|
||||||
|
"theme.blog.authorsList.viewAll": "查看所有作者",
|
||||||
|
"theme.blog.paginator.navAriaLabel": "博文列表分页导航",
|
||||||
|
"theme.blog.paginator.newerEntries": "较新的博文",
|
||||||
|
"theme.blog.paginator.olderEntries": "较旧的博文",
|
||||||
|
"theme.blog.post.paginator.navAriaLabel": "博文分页导航",
|
||||||
|
"theme.blog.post.paginator.newerPost": "较新一篇",
|
||||||
|
"theme.blog.post.paginator.olderPost": "较旧一篇",
|
||||||
|
"theme.blog.post.plurals": "{count} 篇博文",
|
||||||
|
"theme.blog.post.readMore": "阅读更多",
|
||||||
|
"theme.blog.post.readMoreLabel": "阅读 {title} 的全文",
|
||||||
|
"theme.blog.post.readingTime.plurals": "阅读需 {readingTime} 分钟",
|
||||||
|
"theme.blog.sidebar.navAriaLabel": "最近博文导航",
|
||||||
|
"theme.blog.tagTitle": "{nPosts} 含有标签「{tagName}」",
|
||||||
|
"theme.colorToggle.ariaLabel": "切换浅色/暗黑模式(当前为{mode})",
|
||||||
|
"theme.colorToggle.ariaLabel.mode.dark": "暗黑模式",
|
||||||
|
"theme.colorToggle.ariaLabel.mode.light": "浅色模式",
|
||||||
|
"theme.colorToggle.ariaLabel.mode.system": "system mode",
|
||||||
|
"theme.common.editThisPage": "编辑此页",
|
||||||
|
"theme.common.headingLinkTitle": "{heading}的直接链接",
|
||||||
|
"theme.common.skipToMainContent": "跳到主要内容",
|
||||||
|
"theme.contentVisibility.draftBanner.message": "此页面是草稿,仅在开发环境中可见,不会包含在正式版本中。",
|
||||||
|
"theme.contentVisibility.draftBanner.title": "草稿页",
|
||||||
|
"theme.contentVisibility.unlistedBanner.message": "此页面未列出。搜索引擎不会对其索引,只有拥有直接链接的用户才能访问。",
|
||||||
|
"theme.contentVisibility.unlistedBanner.title": "未列出页",
|
||||||
|
"theme.docs.DocCard.categoryDescription.plurals": "{count} 个项目",
|
||||||
|
"theme.docs.breadcrumbs.home": "主页面",
|
||||||
|
"theme.docs.breadcrumbs.navAriaLabel": "页面路径",
|
||||||
|
"theme.docs.paginator.navAriaLabel": "文件选项卡",
|
||||||
|
"theme.docs.paginator.next": "下一页",
|
||||||
|
"theme.docs.paginator.previous": "上一页",
|
||||||
|
"theme.docs.sidebar.closeSidebarButtonAriaLabel": "关闭导航栏",
|
||||||
|
"theme.docs.sidebar.collapseButtonAriaLabel": "收起侧边栏",
|
||||||
|
"theme.docs.sidebar.collapseButtonTitle": "收起侧边栏",
|
||||||
|
"theme.docs.sidebar.expandButtonAriaLabel": "展开侧边栏",
|
||||||
|
"theme.docs.sidebar.expandButtonTitle": "展开侧边栏",
|
||||||
|
"theme.docs.sidebar.navAriaLabel": "文档侧边栏",
|
||||||
|
"theme.docs.sidebar.toggleSidebarButtonAriaLabel": "切换导航栏",
|
||||||
|
"theme.docs.tagDocListPageTitle": "{nDocsTagged}「{tagName}」",
|
||||||
|
"theme.docs.tagDocListPageTitle.nDocsTagged": "{count} 篇文档带有标签",
|
||||||
|
"theme.docs.versionBadge.label": "版本:{versionLabel}",
|
||||||
|
"theme.docs.versions.latestVersionLinkLabel": "最新版本",
|
||||||
|
"theme.docs.versions.latestVersionSuggestionLabel": "最新的文档请参阅 {latestVersionLink} ({versionLabel})。",
|
||||||
|
"theme.docs.versions.unmaintainedVersionLabel": "此为 {siteTitle} {versionLabel} 版的文档,现已不再积极维护。",
|
||||||
|
"theme.docs.versions.unreleasedVersionLabel": "此为 {siteTitle} {versionLabel} 版尚未发行的文档。",
|
||||||
|
"theme.lastUpdated.atDate": "于 {date} ",
|
||||||
|
"theme.lastUpdated.byUser": "由 {user} ",
|
||||||
|
"theme.lastUpdated.lastUpdatedAtBy": "最后{byUser}{atDate}更新",
|
||||||
|
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": "Collapse the dropdown",
|
||||||
|
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": "Expand the dropdown",
|
||||||
|
"theme.navbar.mobileLanguageDropdown.label": "选择语言",
|
||||||
|
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← 回到主菜单",
|
||||||
|
"theme.navbar.mobileVersionsDropdown.label": "选择版本",
|
||||||
|
"theme.tags.tagsListLabel": "标签:",
|
||||||
|
"theme.tags.tagsPageLink": "查看所有标签",
|
||||||
|
"theme.tags.tagsPageTitle": "标签"
|
||||||
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
{"options":{"path":"docs","routeBasePath":"/","sidebarPath":"D:\\Claude_dms3\\ccw\\docs-site\\sidebars.ts","editUrl":"https://github.com/ccw/docs/tree/main/","editCurrentVersion":false,"editLocalizedFiles":false,"tagsBasePath":"tags","include":["**/*.{md,mdx}"],"exclude":["**/_*.{js,jsx,ts,tsx,md,mdx}","**/_*/**","**/*.test.{js,jsx,ts,tsx}","**/__tests__/**"],"sidebarCollapsible":true,"sidebarCollapsed":true,"docsRootComponent":"@theme/DocsRoot","docVersionRootComponent":"@theme/DocVersionRoot","docRootComponent":"@theme/DocRoot","docItemComponent":"@theme/DocItem","docTagsListComponent":"@theme/DocTagsListPage","docTagDocListComponent":"@theme/DocTagDocListPage","docCategoryGeneratedIndexComponent":"@theme/DocCategoryGeneratedIndexPage","remarkPlugins":[],"rehypePlugins":[],"recmaPlugins":[],"beforeDefaultRemarkPlugins":[],"beforeDefaultRehypePlugins":[],"admonitions":true,"showLastUpdateTime":false,"showLastUpdateAuthor":false,"includeCurrentVersion":true,"disableVersioning":false,"versions":{},"breadcrumbs":true,"onInlineTags":"warn","id":"default"},"versionsMetadata":[{"versionName":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","path":"/docs/","tagsPath":"/docs/tags","editUrl":"https://github.com/ccw/docs/tree/main/docs","isLast":true,"routePriority":-1,"sidebarFilePath":"D:\\Claude_dms3\\ccw\\docs-site\\sidebars.ts","contentPath":"D:\\Claude_dms3\\ccw\\docs-site\\docs"}]}
|
{"options":{"path":"docs","routeBasePath":"/","sidebarPath":"D:\\Claude_dms3\\ccw\\docs-site\\sidebars.ts","editUrl":"https://github.com/ccw/docs/tree/main/","editCurrentVersion":false,"editLocalizedFiles":false,"tagsBasePath":"tags","include":["**/*.{md,mdx}"],"exclude":["**/_*.{js,jsx,ts,tsx,md,mdx}","**/_*/**","**/*.test.{js,jsx,ts,tsx}","**/__tests__/**"],"sidebarCollapsible":true,"sidebarCollapsed":true,"docsRootComponent":"@theme/DocsRoot","docVersionRootComponent":"@theme/DocVersionRoot","docRootComponent":"@theme/DocRoot","docItemComponent":"@theme/DocItem","docTagsListComponent":"@theme/DocTagsListPage","docTagDocListComponent":"@theme/DocTagDocListPage","docCategoryGeneratedIndexComponent":"@theme/DocCategoryGeneratedIndexPage","remarkPlugins":[],"rehypePlugins":[],"recmaPlugins":[],"beforeDefaultRemarkPlugins":[],"beforeDefaultRehypePlugins":[],"admonitions":true,"showLastUpdateTime":false,"showLastUpdateAuthor":false,"includeCurrentVersion":true,"disableVersioning":false,"versions":{},"breadcrumbs":true,"onInlineTags":"warn","id":"default"},"versionsMetadata":[{"versionName":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","path":"/docs/zh/","tagsPath":"/docs/zh/tags","editUrl":"https://github.com/ccw/docs/tree/main/docs","editUrlLocalized":"https://github.com/ccw/docs/tree/main/i18n/zh/docusaurus-plugin-content-docs/current","isLast":true,"routePriority":-1,"sidebarFilePath":"D:\\Claude_dms3\\ccw\\docs-site\\sidebars.ts","contentPath":"D:\\Claude_dms3\\ccw\\docs-site\\docs","contentPathLocalized":"D:\\Claude_dms3\\ccw\\docs-site\\i18n\\zh\\docusaurus-plugin-content-docs\\current"}]}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/cli/cli-init.mdx",
|
"source": "@site/docs/commands/cli/cli-init.mdx",
|
||||||
"sourceDirName": "commands/cli",
|
"sourceDirName": "commands/cli",
|
||||||
"slug": "/commands/cli/cli-init",
|
"slug": "/commands/cli/cli-init",
|
||||||
"permalink": "/docs/commands/cli/cli-init",
|
"permalink": "/docs/zh/commands/cli/cli-init",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/cli/cli-init.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/cli/cli-init.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:convert-to-plan",
|
"title": "issue:convert-to-plan",
|
||||||
"permalink": "/docs/commands/issue/issue-convert-to-plan"
|
"permalink": "/docs/zh/commands/issue/issue-convert-to-plan"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/cli:codex-review",
|
"title": "/cli:codex-review",
|
||||||
"permalink": "/docs/commands/cli/codex-review"
|
"permalink": "/docs/zh/commands/cli/codex-review"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/cli/codex-review.mdx",
|
"source": "@site/docs/commands/cli/codex-review.mdx",
|
||||||
"sourceDirName": "commands/cli",
|
"sourceDirName": "commands/cli",
|
||||||
"slug": "/commands/cli/codex-review",
|
"slug": "/commands/cli/codex-review",
|
||||||
"permalink": "/docs/commands/cli/codex-review",
|
"permalink": "/docs/zh/commands/cli/codex-review",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/cli/codex-review.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/cli/codex-review.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/cli:cli-init",
|
"title": "/cli:cli-init",
|
||||||
"permalink": "/docs/commands/cli/cli-init"
|
"permalink": "/docs/zh/commands/cli/cli-init"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/memory:update-full",
|
"title": "/memory:update-full",
|
||||||
"permalink": "/docs/commands/memory/memory-update-full"
|
"permalink": "/docs/zh/commands/memory/memory-update-full"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/ccw-coordinator.mdx",
|
"source": "@site/docs/commands/general/ccw-coordinator.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/ccw-coordinator",
|
"slug": "/commands/general/ccw-coordinator",
|
||||||
"permalink": "/docs/commands/general/ccw-coordinator",
|
"permalink": "/docs/zh/commands/general/ccw-coordinator",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-coordinator.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-coordinator.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/ccw-test",
|
"title": "/ccw-test",
|
||||||
"permalink": "/docs/commands/general/ccw-test"
|
"permalink": "/docs/zh/commands/general/ccw-test"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/ccw-debug",
|
"title": "/ccw-debug",
|
||||||
"permalink": "/docs/commands/general/ccw-debug"
|
"permalink": "/docs/zh/commands/general/ccw-debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/ccw-debug.mdx",
|
"source": "@site/docs/commands/general/ccw-debug.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/ccw-debug",
|
"slug": "/commands/general/ccw-debug",
|
||||||
"permalink": "/docs/commands/general/ccw-debug",
|
"permalink": "/docs/zh/commands/general/ccw-debug",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-debug.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-debug.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/ccw-coordinator",
|
"title": "/ccw-coordinator",
|
||||||
"permalink": "/docs/commands/general/ccw-coordinator"
|
"permalink": "/docs/zh/commands/general/ccw-coordinator"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/flow-create",
|
"title": "/flow-create",
|
||||||
"permalink": "/docs/commands/general/flow-create"
|
"permalink": "/docs/zh/commands/general/flow-create"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/ccw.mdx",
|
"source": "@site/docs/commands/general/ccw.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/ccw",
|
"slug": "/commands/general/ccw",
|
||||||
"permalink": "/docs/commands/general/ccw",
|
"permalink": "/docs/zh/commands/general/ccw",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw.mdx",
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "Overview",
|
"title": "概览",
|
||||||
"permalink": "/docs/overview"
|
"permalink": "/docs/zh/overview"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/ccw-plan",
|
"title": "/ccw-plan",
|
||||||
"permalink": "/docs/commands/general/ccw-plan"
|
"permalink": "/docs/zh/commands/general/ccw-plan"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/ccw-plan.mdx",
|
"source": "@site/docs/commands/general/ccw-plan.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/ccw-plan",
|
"slug": "/commands/general/ccw-plan",
|
||||||
"permalink": "/docs/commands/general/ccw-plan",
|
"permalink": "/docs/zh/commands/general/ccw-plan",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-plan.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-plan.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/ccw",
|
"title": "/ccw",
|
||||||
"permalink": "/docs/commands/general/ccw"
|
"permalink": "/docs/zh/commands/general/ccw"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/ccw-test",
|
"title": "/ccw-test",
|
||||||
"permalink": "/docs/commands/general/ccw-test"
|
"permalink": "/docs/zh/commands/general/ccw-test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/ccw-test.mdx",
|
"source": "@site/docs/commands/general/ccw-test.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/ccw-test",
|
"slug": "/commands/general/ccw-test",
|
||||||
"permalink": "/docs/commands/general/ccw-test",
|
"permalink": "/docs/zh/commands/general/ccw-test",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-test.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/ccw-test.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/ccw-plan",
|
"title": "/ccw-plan",
|
||||||
"permalink": "/docs/commands/general/ccw-plan"
|
"permalink": "/docs/zh/commands/general/ccw-plan"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/ccw-coordinator",
|
"title": "/ccw-coordinator",
|
||||||
"permalink": "/docs/commands/general/ccw-coordinator"
|
"permalink": "/docs/zh/commands/general/ccw-coordinator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/codex-coordinator.mdx",
|
"source": "@site/docs/commands/general/codex-coordinator.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/codex-coordinator",
|
"slug": "/commands/general/codex-coordinator",
|
||||||
"permalink": "/docs/commands/general/codex-coordinator",
|
"permalink": "/docs/zh/commands/general/codex-coordinator",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/codex-coordinator.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/codex-coordinator.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/flow-create",
|
"title": "/flow-create",
|
||||||
"permalink": "/docs/commands/general/flow-create"
|
"permalink": "/docs/zh/commands/general/flow-create"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:new",
|
"title": "issue:new",
|
||||||
"permalink": "/docs/commands/issue/issue-new"
|
"permalink": "/docs/zh/commands/issue/issue-new"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/general/flow-create.mdx",
|
"source": "@site/docs/commands/general/flow-create.mdx",
|
||||||
"sourceDirName": "commands/general",
|
"sourceDirName": "commands/general",
|
||||||
"slug": "/commands/general/flow-create",
|
"slug": "/commands/general/flow-create",
|
||||||
"permalink": "/docs/commands/general/flow-create",
|
"permalink": "/docs/zh/commands/general/flow-create",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/flow-create.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/general/flow-create.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/ccw-debug",
|
"title": "/ccw-debug",
|
||||||
"permalink": "/docs/commands/general/ccw-debug"
|
"permalink": "/docs/zh/commands/general/ccw-debug"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/codex-coordinator",
|
"title": "/codex-coordinator",
|
||||||
"permalink": "/docs/commands/general/codex-coordinator"
|
"permalink": "/docs/zh/commands/general/codex-coordinator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-convert-to-plan.md",
|
"source": "@site/docs/commands/issue/issue-convert-to-plan.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-convert-to-plan",
|
"slug": "/commands/issue/issue-convert-to-plan",
|
||||||
"permalink": "/docs/commands/issue/issue-convert-to-plan",
|
"permalink": "/docs/zh/commands/issue/issue-convert-to-plan",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-convert-to-plan.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-convert-to-plan.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:from-brainstorm",
|
"title": "issue:from-brainstorm",
|
||||||
"permalink": "/docs/commands/issue/issue-from-brainstorm"
|
"permalink": "/docs/zh/commands/issue/issue-from-brainstorm"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/cli:cli-init",
|
"title": "/cli:cli-init",
|
||||||
"permalink": "/docs/commands/cli/cli-init"
|
"permalink": "/docs/zh/commands/cli/cli-init"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-discover.md",
|
"source": "@site/docs/commands/issue/issue-discover.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-discover",
|
"slug": "/commands/issue/issue-discover",
|
||||||
"permalink": "/docs/commands/issue/issue-discover",
|
"permalink": "/docs/zh/commands/issue/issue-discover",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-discover.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-discover.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:new",
|
"title": "issue:new",
|
||||||
"permalink": "/docs/commands/issue/issue-new"
|
"permalink": "/docs/zh/commands/issue/issue-new"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:plan",
|
"title": "issue:plan",
|
||||||
"permalink": "/docs/commands/issue/issue-plan"
|
"permalink": "/docs/zh/commands/issue/issue-plan"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-execute.md",
|
"source": "@site/docs/commands/issue/issue-execute.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-execute",
|
"slug": "/commands/issue/issue-execute",
|
||||||
"permalink": "/docs/commands/issue/issue-execute",
|
"permalink": "/docs/zh/commands/issue/issue-execute",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-execute.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-execute.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:queue",
|
"title": "issue:queue",
|
||||||
"permalink": "/docs/commands/issue/issue-queue"
|
"permalink": "/docs/zh/commands/issue/issue-queue"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:from-brainstorm",
|
"title": "issue:from-brainstorm",
|
||||||
"permalink": "/docs/commands/issue/issue-from-brainstorm"
|
"permalink": "/docs/zh/commands/issue/issue-from-brainstorm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-from-brainstorm.md",
|
"source": "@site/docs/commands/issue/issue-from-brainstorm.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-from-brainstorm",
|
"slug": "/commands/issue/issue-from-brainstorm",
|
||||||
"permalink": "/docs/commands/issue/issue-from-brainstorm",
|
"permalink": "/docs/zh/commands/issue/issue-from-brainstorm",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-from-brainstorm.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-from-brainstorm.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:execute",
|
"title": "issue:execute",
|
||||||
"permalink": "/docs/commands/issue/issue-execute"
|
"permalink": "/docs/zh/commands/issue/issue-execute"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:convert-to-plan",
|
"title": "issue:convert-to-plan",
|
||||||
"permalink": "/docs/commands/issue/issue-convert-to-plan"
|
"permalink": "/docs/zh/commands/issue/issue-convert-to-plan"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-new.md",
|
"source": "@site/docs/commands/issue/issue-new.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-new",
|
"slug": "/commands/issue/issue-new",
|
||||||
"permalink": "/docs/commands/issue/issue-new",
|
"permalink": "/docs/zh/commands/issue/issue-new",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-new.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-new.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/codex-coordinator",
|
"title": "/codex-coordinator",
|
||||||
"permalink": "/docs/commands/general/codex-coordinator"
|
"permalink": "/docs/zh/commands/general/codex-coordinator"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:discover",
|
"title": "issue:discover",
|
||||||
"permalink": "/docs/commands/issue/issue-discover"
|
"permalink": "/docs/zh/commands/issue/issue-discover"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-plan.md",
|
"source": "@site/docs/commands/issue/issue-plan.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-plan",
|
"slug": "/commands/issue/issue-plan",
|
||||||
"permalink": "/docs/commands/issue/issue-plan",
|
"permalink": "/docs/zh/commands/issue/issue-plan",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-plan.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-plan.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:discover",
|
"title": "issue:discover",
|
||||||
"permalink": "/docs/commands/issue/issue-discover"
|
"permalink": "/docs/zh/commands/issue/issue-discover"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:queue",
|
"title": "issue:queue",
|
||||||
"permalink": "/docs/commands/issue/issue-queue"
|
"permalink": "/docs/zh/commands/issue/issue-queue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/issue/issue-queue.md",
|
"source": "@site/docs/commands/issue/issue-queue.md",
|
||||||
"sourceDirName": "commands/issue",
|
"sourceDirName": "commands/issue",
|
||||||
"slug": "/commands/issue/issue-queue",
|
"slug": "/commands/issue/issue-queue",
|
||||||
"permalink": "/docs/commands/issue/issue-queue",
|
"permalink": "/docs/zh/commands/issue/issue-queue",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-queue.md",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/issue/issue-queue.md",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "issue:plan",
|
"title": "issue:plan",
|
||||||
"permalink": "/docs/commands/issue/issue-plan"
|
"permalink": "/docs/zh/commands/issue/issue-plan"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "issue:execute",
|
"title": "issue:execute",
|
||||||
"permalink": "/docs/commands/issue/issue-execute"
|
"permalink": "/docs/zh/commands/issue/issue-execute"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/memory/memory-compact.mdx",
|
"source": "@site/docs/commands/memory/memory-compact.mdx",
|
||||||
"sourceDirName": "commands/memory",
|
"sourceDirName": "commands/memory",
|
||||||
"slug": "/commands/memory/memory-compact",
|
"slug": "/commands/memory/memory-compact",
|
||||||
"permalink": "/docs/commands/memory/memory-compact",
|
"permalink": "/docs/zh/commands/memory/memory-compact",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-compact.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-compact.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/memory:docs-related-cli",
|
"title": "/memory:docs-related-cli",
|
||||||
"permalink": "/docs/commands/memory/memory-docs-related-cli"
|
"permalink": "/docs/zh/commands/memory/memory-docs-related-cli"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "Introduction",
|
"title": "Introduction",
|
||||||
"permalink": "/docs/workflows/introduction"
|
"permalink": "/docs/zh/workflows/introduction"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/memory/memory-docs-full-cli.mdx",
|
"source": "@site/docs/commands/memory/memory-docs-full-cli.mdx",
|
||||||
"sourceDirName": "commands/memory",
|
"sourceDirName": "commands/memory",
|
||||||
"slug": "/commands/memory/memory-docs-full-cli",
|
"slug": "/commands/memory/memory-docs-full-cli",
|
||||||
"permalink": "/docs/commands/memory/memory-docs-full-cli",
|
"permalink": "/docs/zh/commands/memory/memory-docs-full-cli",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-docs-full-cli.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-docs-full-cli.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/memory:load",
|
"title": "/memory:load",
|
||||||
"permalink": "/docs/commands/memory/memory-load"
|
"permalink": "/docs/zh/commands/memory/memory-load"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/memory:docs-related-cli",
|
"title": "/memory:docs-related-cli",
|
||||||
"permalink": "/docs/commands/memory/memory-docs-related-cli"
|
"permalink": "/docs/zh/commands/memory/memory-docs-related-cli"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/memory/memory-docs-related-cli.mdx",
|
"source": "@site/docs/commands/memory/memory-docs-related-cli.mdx",
|
||||||
"sourceDirName": "commands/memory",
|
"sourceDirName": "commands/memory",
|
||||||
"slug": "/commands/memory/memory-docs-related-cli",
|
"slug": "/commands/memory/memory-docs-related-cli",
|
||||||
"permalink": "/docs/commands/memory/memory-docs-related-cli",
|
"permalink": "/docs/zh/commands/memory/memory-docs-related-cli",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-docs-related-cli.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-docs-related-cli.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/memory:docs-full-cli",
|
"title": "/memory:docs-full-cli",
|
||||||
"permalink": "/docs/commands/memory/memory-docs-full-cli"
|
"permalink": "/docs/zh/commands/memory/memory-docs-full-cli"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/memory:compact",
|
"title": "/memory:compact",
|
||||||
"permalink": "/docs/commands/memory/memory-compact"
|
"permalink": "/docs/zh/commands/memory/memory-compact"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/memory/memory-load.mdx",
|
"source": "@site/docs/commands/memory/memory-load.mdx",
|
||||||
"sourceDirName": "commands/memory",
|
"sourceDirName": "commands/memory",
|
||||||
"slug": "/commands/memory/memory-load",
|
"slug": "/commands/memory/memory-load",
|
||||||
"permalink": "/docs/commands/memory/memory-load",
|
"permalink": "/docs/zh/commands/memory/memory-load",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-load.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-load.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/memory:update-related",
|
"title": "/memory:update-related",
|
||||||
"permalink": "/docs/commands/memory/memory-update-related"
|
"permalink": "/docs/zh/commands/memory/memory-update-related"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/memory:docs-full-cli",
|
"title": "/memory:docs-full-cli",
|
||||||
"permalink": "/docs/commands/memory/memory-docs-full-cli"
|
"permalink": "/docs/zh/commands/memory/memory-docs-full-cli"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/memory/memory-update-full.mdx",
|
"source": "@site/docs/commands/memory/memory-update-full.mdx",
|
||||||
"sourceDirName": "commands/memory",
|
"sourceDirName": "commands/memory",
|
||||||
"slug": "/commands/memory/memory-update-full",
|
"slug": "/commands/memory/memory-update-full",
|
||||||
"permalink": "/docs/commands/memory/memory-update-full",
|
"permalink": "/docs/zh/commands/memory/memory-update-full",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-update-full.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-update-full.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/cli:codex-review",
|
"title": "/cli:codex-review",
|
||||||
"permalink": "/docs/commands/cli/codex-review"
|
"permalink": "/docs/zh/commands/cli/codex-review"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/memory:update-related",
|
"title": "/memory:update-related",
|
||||||
"permalink": "/docs/commands/memory/memory-update-related"
|
"permalink": "/docs/zh/commands/memory/memory-update-related"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"source": "@site/docs/commands/memory/memory-update-related.mdx",
|
"source": "@site/docs/commands/memory/memory-update-related.mdx",
|
||||||
"sourceDirName": "commands/memory",
|
"sourceDirName": "commands/memory",
|
||||||
"slug": "/commands/memory/memory-update-related",
|
"slug": "/commands/memory/memory-update-related",
|
||||||
"permalink": "/docs/commands/memory/memory-update-related",
|
"permalink": "/docs/zh/commands/memory/memory-update-related",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"unlisted": false,
|
"unlisted": false,
|
||||||
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-update-related.mdx",
|
"editUrl": "https://github.com/ccw/docs/tree/main/docs/commands/memory/memory-update-related.mdx",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"sidebar": "docs",
|
"sidebar": "docs",
|
||||||
"previous": {
|
"previous": {
|
||||||
"title": "/memory:update-full",
|
"title": "/memory:update-full",
|
||||||
"permalink": "/docs/commands/memory/memory-update-full"
|
"permalink": "/docs/zh/commands/memory/memory-update-full"
|
||||||
},
|
},
|
||||||
"next": {
|
"next": {
|
||||||
"title": "/memory:load",
|
"title": "/memory:load",
|
||||||
"permalink": "/docs/commands/memory/memory-load"
|
"permalink": "/docs/zh/commands/memory/memory-load"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ export default {
|
|||||||
"tagline": "Professional Workflow Automation Platform",
|
"tagline": "Professional Workflow Automation Platform",
|
||||||
"favicon": "img/favicon.svg",
|
"favicon": "img/favicon.svg",
|
||||||
"url": "http://localhost:3001",
|
"url": "http://localhost:3001",
|
||||||
"baseUrl": "/docs/",
|
"baseUrl": "/docs/zh/",
|
||||||
"organizationName": "ccw",
|
"organizationName": "ccw",
|
||||||
"projectName": "docs",
|
"projectName": "docs",
|
||||||
"trailingSlash": false,
|
"trailingSlash": false,
|
||||||
@@ -48,9 +48,9 @@ export default {
|
|||||||
],
|
],
|
||||||
"themeConfig": {
|
"themeConfig": {
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"title": "CCW Help",
|
"title": "CCW 帮助",
|
||||||
"logo": {
|
"logo": {
|
||||||
"alt": "CCW Logo",
|
"alt": "CCW 标志",
|
||||||
"src": "img/logo.svg"
|
"src": "img/logo.svg"
|
||||||
},
|
},
|
||||||
"items": [
|
"items": [
|
||||||
@@ -65,7 +65,7 @@ export default {
|
|||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"style": "dark",
|
"style": "dark",
|
||||||
"copyright": "Copyright © 2026 CCW. Built with Docusaurus.",
|
"copyright": "版权 © 2026 CCW。使用 Docusaurus 构建。",
|
||||||
"links": []
|
"links": []
|
||||||
},
|
},
|
||||||
"prism": {
|
"prism": {
|
||||||
|
|||||||
@@ -1,172 +1,172 @@
|
|||||||
{
|
{
|
||||||
"docusaurus-plugin-content-docs": {
|
"docusaurus-plugin-content-docs": {
|
||||||
"default": {
|
"default": {
|
||||||
"path": "/docs/",
|
"path": "/docs/zh/",
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"name": "current",
|
"name": "current",
|
||||||
"label": "Next",
|
"label": "当前",
|
||||||
"isLast": true,
|
"isLast": true,
|
||||||
"path": "/docs/",
|
"path": "/docs/zh/",
|
||||||
"mainDocId": "index",
|
"mainDocId": "index",
|
||||||
"docs": [
|
"docs": [
|
||||||
{
|
{
|
||||||
"id": "commands/cli/cli-init",
|
"id": "commands/cli/cli-init",
|
||||||
"path": "/docs/commands/cli/cli-init",
|
"path": "/docs/zh/commands/cli/cli-init",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/cli/codex-review",
|
"id": "commands/cli/codex-review",
|
||||||
"path": "/docs/commands/cli/codex-review",
|
"path": "/docs/zh/commands/cli/codex-review",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/ccw",
|
"id": "commands/general/ccw",
|
||||||
"path": "/docs/commands/general/ccw",
|
"path": "/docs/zh/commands/general/ccw",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/ccw-coordinator",
|
"id": "commands/general/ccw-coordinator",
|
||||||
"path": "/docs/commands/general/ccw-coordinator",
|
"path": "/docs/zh/commands/general/ccw-coordinator",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/ccw-debug",
|
"id": "commands/general/ccw-debug",
|
||||||
"path": "/docs/commands/general/ccw-debug",
|
"path": "/docs/zh/commands/general/ccw-debug",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/ccw-plan",
|
"id": "commands/general/ccw-plan",
|
||||||
"path": "/docs/commands/general/ccw-plan",
|
"path": "/docs/zh/commands/general/ccw-plan",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/ccw-test",
|
"id": "commands/general/ccw-test",
|
||||||
"path": "/docs/commands/general/ccw-test",
|
"path": "/docs/zh/commands/general/ccw-test",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/codex-coordinator",
|
"id": "commands/general/codex-coordinator",
|
||||||
"path": "/docs/commands/general/codex-coordinator",
|
"path": "/docs/zh/commands/general/codex-coordinator",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/general/flow-create",
|
"id": "commands/general/flow-create",
|
||||||
"path": "/docs/commands/general/flow-create",
|
"path": "/docs/zh/commands/general/flow-create",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-convert-to-plan",
|
"id": "commands/issue/issue-convert-to-plan",
|
||||||
"path": "/docs/commands/issue/issue-convert-to-plan",
|
"path": "/docs/zh/commands/issue/issue-convert-to-plan",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-discover",
|
"id": "commands/issue/issue-discover",
|
||||||
"path": "/docs/commands/issue/issue-discover",
|
"path": "/docs/zh/commands/issue/issue-discover",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-execute",
|
"id": "commands/issue/issue-execute",
|
||||||
"path": "/docs/commands/issue/issue-execute",
|
"path": "/docs/zh/commands/issue/issue-execute",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-from-brainstorm",
|
"id": "commands/issue/issue-from-brainstorm",
|
||||||
"path": "/docs/commands/issue/issue-from-brainstorm",
|
"path": "/docs/zh/commands/issue/issue-from-brainstorm",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-new",
|
"id": "commands/issue/issue-new",
|
||||||
"path": "/docs/commands/issue/issue-new",
|
"path": "/docs/zh/commands/issue/issue-new",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-plan",
|
"id": "commands/issue/issue-plan",
|
||||||
"path": "/docs/commands/issue/issue-plan",
|
"path": "/docs/zh/commands/issue/issue-plan",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/issue/issue-queue",
|
"id": "commands/issue/issue-queue",
|
||||||
"path": "/docs/commands/issue/issue-queue",
|
"path": "/docs/zh/commands/issue/issue-queue",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/memory/memory-compact",
|
"id": "commands/memory/memory-compact",
|
||||||
"path": "/docs/commands/memory/memory-compact",
|
"path": "/docs/zh/commands/memory/memory-compact",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/memory/memory-docs-full-cli",
|
"id": "commands/memory/memory-docs-full-cli",
|
||||||
"path": "/docs/commands/memory/memory-docs-full-cli",
|
"path": "/docs/zh/commands/memory/memory-docs-full-cli",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/memory/memory-docs-related-cli",
|
"id": "commands/memory/memory-docs-related-cli",
|
||||||
"path": "/docs/commands/memory/memory-docs-related-cli",
|
"path": "/docs/zh/commands/memory/memory-docs-related-cli",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/memory/memory-load",
|
"id": "commands/memory/memory-load",
|
||||||
"path": "/docs/commands/memory/memory-load",
|
"path": "/docs/zh/commands/memory/memory-load",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/memory/memory-update-full",
|
"id": "commands/memory/memory-update-full",
|
||||||
"path": "/docs/commands/memory/memory-update-full",
|
"path": "/docs/zh/commands/memory/memory-update-full",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "commands/memory/memory-update-related",
|
"id": "commands/memory/memory-update-related",
|
||||||
"path": "/docs/commands/memory/memory-update-related",
|
"path": "/docs/zh/commands/memory/memory-update-related",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "faq",
|
"id": "faq",
|
||||||
"path": "/docs/faq",
|
"path": "/docs/zh/faq",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "index",
|
"id": "index",
|
||||||
"path": "/docs/",
|
"path": "/docs/zh/",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "overview",
|
"id": "overview",
|
||||||
"path": "/docs/overview",
|
"path": "/docs/zh/overview",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/faq",
|
"id": "workflows/faq",
|
||||||
"path": "/docs/workflows/faq"
|
"path": "/docs/zh/workflows/faq"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/introduction",
|
"id": "workflows/introduction",
|
||||||
"path": "/docs/workflows/introduction",
|
"path": "/docs/zh/workflows/introduction",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/level-1-ultra-lightweight",
|
"id": "workflows/level-1-ultra-lightweight",
|
||||||
"path": "/docs/workflows/level-1-ultra-lightweight",
|
"path": "/docs/zh/workflows/level-1-ultra-lightweight",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/level-2-rapid",
|
"id": "workflows/level-2-rapid",
|
||||||
"path": "/docs/workflows/level-2-rapid",
|
"path": "/docs/zh/workflows/level-2-rapid",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/level-3-standard",
|
"id": "workflows/level-3-standard",
|
||||||
"path": "/docs/workflows/level-3-standard",
|
"path": "/docs/zh/workflows/level-3-standard",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/level-4-brainstorm",
|
"id": "workflows/level-4-brainstorm",
|
||||||
"path": "/docs/workflows/level-4-brainstorm",
|
"path": "/docs/zh/workflows/level-4-brainstorm",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workflows/level-5-intelligent",
|
"id": "workflows/level-5-intelligent",
|
||||||
"path": "/docs/workflows/level-5-intelligent",
|
"path": "/docs/zh/workflows/level-5-intelligent",
|
||||||
"sidebar": "docs"
|
"sidebar": "docs"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
"sidebars": {
|
"sidebars": {
|
||||||
"docs": {
|
"docs": {
|
||||||
"link": {
|
"link": {
|
||||||
"path": "/docs/",
|
"path": "/docs/zh/",
|
||||||
"label": "Home"
|
"label": "Home"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"zh"
|
"zh"
|
||||||
],
|
],
|
||||||
"path": "i18n",
|
"path": "i18n",
|
||||||
"currentLocale": "en",
|
"currentLocale": "zh",
|
||||||
"localeConfigs": {
|
"localeConfigs": {
|
||||||
"en": {
|
"en": {
|
||||||
"label": "English",
|
"label": "English",
|
||||||
|
|||||||
@@ -1,47 +1,39 @@
|
|||||||
export default {
|
export default {
|
||||||
"__comp---theme-debug-config-23-a-2ff": [() => import(/* webpackChunkName: "__comp---theme-debug-config-23-a-2ff" */ "@theme/DebugConfig"), "@theme/DebugConfig", require.resolveWeak("@theme/DebugConfig")],
|
"04db0a2e": [() => import(/* webpackChunkName: "04db0a2e" */ "@site/docs/commands/general/ccw-plan.mdx"), "@site/docs/commands/general/ccw-plan.mdx", require.resolveWeak("@site/docs/commands/general/ccw-plan.mdx")],
|
||||||
"__comp---theme-debug-contentba-8-ce7": [() => import(/* webpackChunkName: "__comp---theme-debug-contentba-8-ce7" */ "@theme/DebugContent"), "@theme/DebugContent", require.resolveWeak("@theme/DebugContent")],
|
"05467734": [() => import(/* webpackChunkName: "05467734" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-2-rapid.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-2-rapid.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-2-rapid.mdx")],
|
||||||
"__comp---theme-debug-global-dataede-0fa": [() => import(/* webpackChunkName: "__comp---theme-debug-global-dataede-0fa" */ "@theme/DebugGlobalData"), "@theme/DebugGlobalData", require.resolveWeak("@theme/DebugGlobalData")],
|
"0566a0a8": [() => import(/* webpackChunkName: "0566a0a8" */ "@site/docs/commands/cli/cli-init.mdx"), "@site/docs/commands/cli/cli-init.mdx", require.resolveWeak("@site/docs/commands/cli/cli-init.mdx")],
|
||||||
"__comp---theme-debug-registry-679-501": [() => import(/* webpackChunkName: "__comp---theme-debug-registry-679-501" */ "@theme/DebugRegistry"), "@theme/DebugRegistry", require.resolveWeak("@theme/DebugRegistry")],
|
"157db180": [() => import(/* webpackChunkName: "157db180" */ "@site/docs/commands/memory/memory-load.mdx"), "@site/docs/commands/memory/memory-load.mdx", require.resolveWeak("@site/docs/commands/memory/memory-load.mdx")],
|
||||||
"__comp---theme-debug-routes-946-699": [() => import(/* webpackChunkName: "__comp---theme-debug-routes-946-699" */ "@theme/DebugRoutes"), "@theme/DebugRoutes", require.resolveWeak("@theme/DebugRoutes")],
|
"17896441": [() => import(/* webpackChunkName: "17896441" */ "@theme/DocItem"), "@theme/DocItem", require.resolveWeak("@theme/DocItem")],
|
||||||
"__comp---theme-debug-site-metadata-68-e-3d4": [() => import(/* webpackChunkName: "__comp---theme-debug-site-metadata-68-e-3d4" */ "@theme/DebugSiteMetadata"), "@theme/DebugSiteMetadata", require.resolveWeak("@theme/DebugSiteMetadata")],
|
"1bac9067": [() => import(/* webpackChunkName: "1bac9067" */ "@site/docs/commands/issue/issue-queue.md"), "@site/docs/commands/issue/issue-queue.md", require.resolveWeak("@site/docs/commands/issue/issue-queue.md")],
|
||||||
"__comp---theme-doc-item-178-a40": [() => import(/* webpackChunkName: "__comp---theme-doc-item-178-a40" */ "@theme/DocItem"), "@theme/DocItem", require.resolveWeak("@theme/DocItem")],
|
"1e3006f3": [() => import(/* webpackChunkName: "1e3006f3" */ "@site/docs/commands/issue/issue-discover.md"), "@site/docs/commands/issue/issue-discover.md", require.resolveWeak("@site/docs/commands/issue/issue-discover.md")],
|
||||||
"__comp---theme-doc-roota-94-67a": [() => import(/* webpackChunkName: "__comp---theme-doc-roota-94-67a" */ "@theme/DocRoot"), "@theme/DocRoot", require.resolveWeak("@theme/DocRoot")],
|
"2a5e3eff": [() => import(/* webpackChunkName: "2a5e3eff" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/faq.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/faq.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/faq.mdx")],
|
||||||
"__comp---theme-doc-version-roota-7-b-5de": [() => import(/* webpackChunkName: "__comp---theme-doc-version-roota-7-b-5de" */ "@theme/DocVersionRoot"), "@theme/DocVersionRoot", require.resolveWeak("@theme/DocVersionRoot")],
|
"2ecf8b4a": [() => import(/* webpackChunkName: "2ecf8b4a" */ "@site/docs/commands/issue/issue-from-brainstorm.md"), "@site/docs/commands/issue/issue-from-brainstorm.md", require.resolveWeak("@site/docs/commands/issue/issue-from-brainstorm.md")],
|
||||||
"__comp---theme-docs-root-5-e-9-0b6": [() => import(/* webpackChunkName: "__comp---theme-docs-root-5-e-9-0b6" */ "@theme/DocsRoot"), "@theme/DocsRoot", require.resolveWeak("@theme/DocsRoot")],
|
"3f1fe4a1": [() => import(/* webpackChunkName: "3f1fe4a1" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-3-standard.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-3-standard.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-3-standard.mdx")],
|
||||||
"__props---docs-11-b-f70": [() => import(/* webpackChunkName: "__props---docs-11-b-f70" */ "@generated/docusaurus-plugin-content-docs/default/p/docs-7fc.json"), "@generated/docusaurus-plugin-content-docs/default/p/docs-7fc.json", require.resolveWeak("@generated/docusaurus-plugin-content-docs/default/p/docs-7fc.json")],
|
"46f40178": [() => import(/* webpackChunkName: "46f40178" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/faq.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/faq.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/faq.mdx")],
|
||||||
"__props---docs-docusaurus-debug-content-344-8d5": [() => import(/* webpackChunkName: "__props---docs-docusaurus-debug-content-344-8d5" */ "@generated/docusaurus-plugin-debug/default/p/docs-docusaurus-debug-content-a52.json"), "@generated/docusaurus-plugin-debug/default/p/docs-docusaurus-debug-content-a52.json", require.resolveWeak("@generated/docusaurus-plugin-debug/default/p/docs-docusaurus-debug-content-a52.json")],
|
"4ad7db0f": [() => import(/* webpackChunkName: "4ad7db0f" */ "@site/docs/commands/issue/issue-new.md"), "@site/docs/commands/issue/issue-new.md", require.resolveWeak("@site/docs/commands/issue/issue-new.md")],
|
||||||
"content---docs-4-ed-831": [() => import(/* webpackChunkName: "content---docs-4-ed-831" */ "@site/docs/index.mdx"), "@site/docs/index.mdx", require.resolveWeak("@site/docs/index.mdx")],
|
"4cc74730": [() => import(/* webpackChunkName: "4cc74730" */ "@site/docs/commands/memory/memory-docs-full-cli.mdx"), "@site/docs/commands/memory/memory-docs-full-cli.mdx", require.resolveWeak("@site/docs/commands/memory/memory-docs-full-cli.mdx")],
|
||||||
"content---docs-commands-cli-cli-init-056-ce1": [() => import(/* webpackChunkName: "content---docs-commands-cli-cli-init-056-ce1" */ "@site/docs/commands/cli/cli-init.mdx"), "@site/docs/commands/cli/cli-init.mdx", require.resolveWeak("@site/docs/commands/cli/cli-init.mdx")],
|
"562bb8cb": [() => import(/* webpackChunkName: "562bb8cb" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-5-intelligent.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-5-intelligent.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-5-intelligent.mdx")],
|
||||||
"content---docs-commands-cli-codex-reviewf-1-b-55f": [() => import(/* webpackChunkName: "content---docs-commands-cli-codex-reviewf-1-b-55f" */ "@site/docs/commands/cli/codex-review.mdx"), "@site/docs/commands/cli/codex-review.mdx", require.resolveWeak("@site/docs/commands/cli/codex-review.mdx")],
|
"5c7b2278": [() => import(/* webpackChunkName: "5c7b2278" */ "@site/docs/commands/issue/issue-convert-to-plan.md"), "@site/docs/commands/issue/issue-convert-to-plan.md", require.resolveWeak("@site/docs/commands/issue/issue-convert-to-plan.md")],
|
||||||
"content---docs-commands-general-ccw-coordinatord-55-c6b": [() => import(/* webpackChunkName: "content---docs-commands-general-ccw-coordinatord-55-c6b" */ "@site/docs/commands/general/ccw-coordinator.mdx"), "@site/docs/commands/general/ccw-coordinator.mdx", require.resolveWeak("@site/docs/commands/general/ccw-coordinator.mdx")],
|
"5e95c892": [() => import(/* webpackChunkName: "5e95c892" */ "@theme/DocsRoot"), "@theme/DocsRoot", require.resolveWeak("@theme/DocsRoot")],
|
||||||
"content---docs-commands-general-ccw-debug-97-c-a72": [() => import(/* webpackChunkName: "content---docs-commands-general-ccw-debug-97-c-a72" */ "@site/docs/commands/general/ccw-debug.mdx"), "@site/docs/commands/general/ccw-debug.mdx", require.resolveWeak("@site/docs/commands/general/ccw-debug.mdx")],
|
"60eef997": [() => import(/* webpackChunkName: "60eef997" */ "@site/docs/commands/memory/memory-docs-related-cli.mdx"), "@site/docs/commands/memory/memory-docs-related-cli.mdx", require.resolveWeak("@site/docs/commands/memory/memory-docs-related-cli.mdx")],
|
||||||
"content---docs-commands-general-ccw-plan-04-d-fe0": [() => import(/* webpackChunkName: "content---docs-commands-general-ccw-plan-04-d-fe0" */ "@site/docs/commands/general/ccw-plan.mdx"), "@site/docs/commands/general/ccw-plan.mdx", require.resolveWeak("@site/docs/commands/general/ccw-plan.mdx")],
|
"611877e1": [() => import(/* webpackChunkName: "611877e1" */ "@site/docs/commands/memory/memory-update-related.mdx"), "@site/docs/commands/memory/memory-update-related.mdx", require.resolveWeak("@site/docs/commands/memory/memory-update-related.mdx")],
|
||||||
"content---docs-commands-general-ccw-testcce-912": [() => import(/* webpackChunkName: "content---docs-commands-general-ccw-testcce-912" */ "@site/docs/commands/general/ccw-test.mdx"), "@site/docs/commands/general/ccw-test.mdx", require.resolveWeak("@site/docs/commands/general/ccw-test.mdx")],
|
"666bb1bf": [() => import(/* webpackChunkName: "666bb1bf" */ "@site/docs/commands/memory/memory-update-full.mdx"), "@site/docs/commands/memory/memory-update-full.mdx", require.resolveWeak("@site/docs/commands/memory/memory-update-full.mdx")],
|
||||||
"content---docs-commands-general-ccwf-48-8c4": [() => import(/* webpackChunkName: "content---docs-commands-general-ccwf-48-8c4" */ "@site/docs/commands/general/ccw.mdx"), "@site/docs/commands/general/ccw.mdx", require.resolveWeak("@site/docs/commands/general/ccw.mdx")],
|
"6ab014e9": [() => import(/* webpackChunkName: "6ab014e9" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/index.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/index.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/index.mdx")],
|
||||||
"content---docs-commands-general-codex-coordinatorf-92-1dc": [() => import(/* webpackChunkName: "content---docs-commands-general-codex-coordinatorf-92-1dc" */ "@site/docs/commands/general/codex-coordinator.mdx"), "@site/docs/commands/general/codex-coordinator.mdx", require.resolveWeak("@site/docs/commands/general/codex-coordinator.mdx")],
|
"775938bf": [() => import(/* webpackChunkName: "775938bf" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-4-brainstorm.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-4-brainstorm.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-4-brainstorm.mdx")],
|
||||||
"content---docs-commands-general-flow-createfab-98a": [() => import(/* webpackChunkName: "content---docs-commands-general-flow-createfab-98a" */ "@site/docs/commands/general/flow-create.mdx"), "@site/docs/commands/general/flow-create.mdx", require.resolveWeak("@site/docs/commands/general/flow-create.mdx")],
|
"7a1ee27c": [() => import(/* webpackChunkName: "7a1ee27c" */ "@site/docs/commands/memory/memory-compact.mdx"), "@site/docs/commands/memory/memory-compact.mdx", require.resolveWeak("@site/docs/commands/memory/memory-compact.mdx")],
|
||||||
"content---docs-commands-issue-issue-convert-to-plan-5-c-7-184": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-convert-to-plan-5-c-7-184" */ "@site/docs/commands/issue/issue-convert-to-plan.md"), "@site/docs/commands/issue/issue-convert-to-plan.md", require.resolveWeak("@site/docs/commands/issue/issue-convert-to-plan.md")],
|
"8a7e39ed": [() => import(/* webpackChunkName: "8a7e39ed" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/overview.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/overview.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/overview.mdx")],
|
||||||
"content---docs-commands-issue-issue-discover-1-e-3-569": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-discover-1-e-3-569" */ "@site/docs/commands/issue/issue-discover.md"), "@site/docs/commands/issue/issue-discover.md", require.resolveWeak("@site/docs/commands/issue/issue-discover.md")],
|
"97c6e66a": [() => import(/* webpackChunkName: "97c6e66a" */ "@site/docs/commands/general/ccw-debug.mdx"), "@site/docs/commands/general/ccw-debug.mdx", require.resolveWeak("@site/docs/commands/general/ccw-debug.mdx")],
|
||||||
"content---docs-commands-issue-issue-executefe-8-c03": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-executefe-8-c03" */ "@site/docs/commands/issue/issue-execute.md"), "@site/docs/commands/issue/issue-execute.md", require.resolveWeak("@site/docs/commands/issue/issue-execute.md")],
|
"9cf7cb6b": [() => import(/* webpackChunkName: "9cf7cb6b" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-1-ultra-lightweight.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-1-ultra-lightweight.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/level-1-ultra-lightweight.mdx")],
|
||||||
"content---docs-commands-issue-issue-from-brainstorm-2-ec-eeb": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-from-brainstorm-2-ec-eeb" */ "@site/docs/commands/issue/issue-from-brainstorm.md"), "@site/docs/commands/issue/issue-from-brainstorm.md", require.resolveWeak("@site/docs/commands/issue/issue-from-brainstorm.md")],
|
"a6c3df16": [() => import(/* webpackChunkName: "a6c3df16" */ "@site/docs/commands/issue/issue-plan.md"), "@site/docs/commands/issue/issue-plan.md", require.resolveWeak("@site/docs/commands/issue/issue-plan.md")],
|
||||||
"content---docs-commands-issue-issue-new-4-ad-3f0": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-new-4-ad-3f0" */ "@site/docs/commands/issue/issue-new.md"), "@site/docs/commands/issue/issue-new.md", require.resolveWeak("@site/docs/commands/issue/issue-new.md")],
|
"a7bd4aaa": [() => import(/* webpackChunkName: "a7bd4aaa" */ "@theme/DocVersionRoot"), "@theme/DocVersionRoot", require.resolveWeak("@theme/DocVersionRoot")],
|
||||||
"content---docs-commands-issue-issue-plana-6-c-fbd": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-plana-6-c-fbd" */ "@site/docs/commands/issue/issue-plan.md"), "@site/docs/commands/issue/issue-plan.md", require.resolveWeak("@site/docs/commands/issue/issue-plan.md")],
|
"a94703ab": [() => import(/* webpackChunkName: "a94703ab" */ "@theme/DocRoot"), "@theme/DocRoot", require.resolveWeak("@theme/DocRoot")],
|
||||||
"content---docs-commands-issue-issue-queue-1-ba-55f": [() => import(/* webpackChunkName: "content---docs-commands-issue-issue-queue-1-ba-55f" */ "@site/docs/commands/issue/issue-queue.md"), "@site/docs/commands/issue/issue-queue.md", require.resolveWeak("@site/docs/commands/issue/issue-queue.md")],
|
"aba21aa0": [() => import(/* webpackChunkName: "aba21aa0" */ "@generated/docusaurus-plugin-content-docs/default/__plugin.json"), "@generated/docusaurus-plugin-content-docs/default/__plugin.json", require.resolveWeak("@generated/docusaurus-plugin-content-docs/default/__plugin.json")],
|
||||||
"content---docs-commands-memory-memory-compact-7-a-1-41c": [() => import(/* webpackChunkName: "content---docs-commands-memory-memory-compact-7-a-1-41c" */ "@site/docs/commands/memory/memory-compact.mdx"), "@site/docs/commands/memory/memory-compact.mdx", require.resolveWeak("@site/docs/commands/memory/memory-compact.mdx")],
|
"b17e4002": [() => import(/* webpackChunkName: "b17e4002" */ "@generated/docusaurus-plugin-content-docs/default/p/docs-zh-d2a.json"), "@generated/docusaurus-plugin-content-docs/default/p/docs-zh-d2a.json", require.resolveWeak("@generated/docusaurus-plugin-content-docs/default/p/docs-zh-d2a.json")],
|
||||||
"content---docs-commands-memory-memory-docs-full-cli-4-cc-96f": [() => import(/* webpackChunkName: "content---docs-commands-memory-memory-docs-full-cli-4-cc-96f" */ "@site/docs/commands/memory/memory-docs-full-cli.mdx"), "@site/docs/commands/memory/memory-docs-full-cli.mdx", require.resolveWeak("@site/docs/commands/memory/memory-docs-full-cli.mdx")],
|
"ccef5d0f": [() => import(/* webpackChunkName: "ccef5d0f" */ "@site/docs/commands/general/ccw-test.mdx"), "@site/docs/commands/general/ccw-test.mdx", require.resolveWeak("@site/docs/commands/general/ccw-test.mdx")],
|
||||||
"content---docs-commands-memory-memory-docs-related-cli-60-e-dd0": [() => import(/* webpackChunkName: "content---docs-commands-memory-memory-docs-related-cli-60-e-dd0" */ "@site/docs/commands/memory/memory-docs-related-cli.mdx"), "@site/docs/commands/memory/memory-docs-related-cli.mdx", require.resolveWeak("@site/docs/commands/memory/memory-docs-related-cli.mdx")],
|
"d550a629": [() => import(/* webpackChunkName: "d550a629" */ "@site/docs/commands/general/ccw-coordinator.mdx"), "@site/docs/commands/general/ccw-coordinator.mdx", require.resolveWeak("@site/docs/commands/general/ccw-coordinator.mdx")],
|
||||||
"content---docs-commands-memory-memory-load-157-952": [() => import(/* webpackChunkName: "content---docs-commands-memory-memory-load-157-952" */ "@site/docs/commands/memory/memory-load.mdx"), "@site/docs/commands/memory/memory-load.mdx", require.resolveWeak("@site/docs/commands/memory/memory-load.mdx")],
|
"e5f6eee3": [() => import(/* webpackChunkName: "e5f6eee3" */ "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/introduction.mdx"), "@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/introduction.mdx", require.resolveWeak("@site/i18n/zh/docusaurus-plugin-content-docs/current/workflows/introduction.mdx")],
|
||||||
"content---docs-commands-memory-memory-update-full-666-002": [() => import(/* webpackChunkName: "content---docs-commands-memory-memory-update-full-666-002" */ "@site/docs/commands/memory/memory-update-full.mdx"), "@site/docs/commands/memory/memory-update-full.mdx", require.resolveWeak("@site/docs/commands/memory/memory-update-full.mdx")],
|
"f1bf82ec": [() => import(/* webpackChunkName: "f1bf82ec" */ "@site/docs/commands/cli/codex-review.mdx"), "@site/docs/commands/cli/codex-review.mdx", require.resolveWeak("@site/docs/commands/cli/codex-review.mdx")],
|
||||||
"content---docs-commands-memory-memory-update-related-611-8d3": [() => import(/* webpackChunkName: "content---docs-commands-memory-memory-update-related-611-8d3" */ "@site/docs/commands/memory/memory-update-related.mdx"), "@site/docs/commands/memory/memory-update-related.mdx", require.resolveWeak("@site/docs/commands/memory/memory-update-related.mdx")],
|
"f4817052": [() => import(/* webpackChunkName: "f4817052" */ "@site/docs/commands/general/ccw.mdx"), "@site/docs/commands/general/ccw.mdx", require.resolveWeak("@site/docs/commands/general/ccw.mdx")],
|
||||||
"content---docs-faqea-3-888": [() => import(/* webpackChunkName: "content---docs-faqea-3-888" */ "@site/docs/faq.mdx"), "@site/docs/faq.mdx", require.resolveWeak("@site/docs/faq.mdx")],
|
"f9222419": [() => import(/* webpackChunkName: "f9222419" */ "@site/docs/commands/general/codex-coordinator.mdx"), "@site/docs/commands/general/codex-coordinator.mdx", require.resolveWeak("@site/docs/commands/general/codex-coordinator.mdx")],
|
||||||
"content---docs-overview-188-429": [() => import(/* webpackChunkName: "content---docs-overview-188-429" */ "@site/docs/overview.mdx"), "@site/docs/overview.mdx", require.resolveWeak("@site/docs/overview.mdx")],
|
"fabaf1c8": [() => import(/* webpackChunkName: "fabaf1c8" */ "@site/docs/commands/general/flow-create.mdx"), "@site/docs/commands/general/flow-create.mdx", require.resolveWeak("@site/docs/commands/general/flow-create.mdx")],
|
||||||
"content---docs-workflows-faqbcf-045": [() => import(/* webpackChunkName: "content---docs-workflows-faqbcf-045" */ "@site/docs/workflows/faq.mdx"), "@site/docs/workflows/faq.mdx", require.resolveWeak("@site/docs/workflows/faq.mdx")],
|
"fe8e3dcf": [() => import(/* webpackChunkName: "fe8e3dcf" */ "@site/docs/commands/issue/issue-execute.md"), "@site/docs/commands/issue/issue-execute.md", require.resolveWeak("@site/docs/commands/issue/issue-execute.md")],};
|
||||||
"content---docs-workflows-introduction-9-f-4-275": [() => import(/* webpackChunkName: "content---docs-workflows-introduction-9-f-4-275" */ "@site/docs/workflows/introduction.mdx"), "@site/docs/workflows/introduction.mdx", require.resolveWeak("@site/docs/workflows/introduction.mdx")],
|
|
||||||
"content---docs-workflows-level-1-ultra-lightweightc-5-a-5db": [() => import(/* webpackChunkName: "content---docs-workflows-level-1-ultra-lightweightc-5-a-5db" */ "@site/docs/workflows/level-1-ultra-lightweight.mdx"), "@site/docs/workflows/level-1-ultra-lightweight.mdx", require.resolveWeak("@site/docs/workflows/level-1-ultra-lightweight.mdx")],
|
|
||||||
"content---docs-workflows-level-2-rapid-19-b-095": [() => import(/* webpackChunkName: "content---docs-workflows-level-2-rapid-19-b-095" */ "@site/docs/workflows/level-2-rapid.mdx"), "@site/docs/workflows/level-2-rapid.mdx", require.resolveWeak("@site/docs/workflows/level-2-rapid.mdx")],
|
|
||||||
"content---docs-workflows-level-3-standardbdb-61a": [() => import(/* webpackChunkName: "content---docs-workflows-level-3-standardbdb-61a" */ "@site/docs/workflows/level-3-standard.mdx"), "@site/docs/workflows/level-3-standard.mdx", require.resolveWeak("@site/docs/workflows/level-3-standard.mdx")],
|
|
||||||
"content---docs-workflows-level-4-brainstormd-04-14f": [() => import(/* webpackChunkName: "content---docs-workflows-level-4-brainstormd-04-14f" */ "@site/docs/workflows/level-4-brainstorm.mdx"), "@site/docs/workflows/level-4-brainstorm.mdx", require.resolveWeak("@site/docs/workflows/level-4-brainstorm.mdx")],
|
|
||||||
"content---docs-workflows-level-5-intelligent-186-b05": [() => import(/* webpackChunkName: "content---docs-workflows-level-5-intelligent-186-b05" */ "@site/docs/workflows/level-5-intelligent.mdx"), "@site/docs/workflows/level-5-intelligent.mdx", require.resolveWeak("@site/docs/workflows/level-5-intelligent.mdx")],
|
|
||||||
"plugin---docs-aba-4f5": [() => import(/* webpackChunkName: "plugin---docs-aba-4f5" */ "@generated/docusaurus-plugin-content-docs/default/__plugin.json"), "@generated/docusaurus-plugin-content-docs/default/__plugin.json", require.resolveWeak("@generated/docusaurus-plugin-content-docs/default/__plugin.json")],
|
|
||||||
"plugin---docs-docusaurus-debugb-38-c84": [() => import(/* webpackChunkName: "plugin---docs-docusaurus-debugb-38-c84" */ "@generated/docusaurus-plugin-debug/default/__plugin.json"), "@generated/docusaurus-plugin-debug/default/__plugin.json", require.resolveWeak("@generated/docusaurus-plugin-debug/default/__plugin.json")],};
|
|
||||||
|
|||||||
@@ -3,240 +3,205 @@ import ComponentCreator from '@docusaurus/ComponentCreator';
|
|||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
path: '/docs/__docusaurus/debug',
|
path: '/docs/zh/',
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug', 'e58'),
|
component: ComponentCreator('/docs/zh/', 'b34'),
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/__docusaurus/debug/config',
|
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug/config', '2ce'),
|
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/__docusaurus/debug/content',
|
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug/content', '11b'),
|
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/__docusaurus/debug/globalData',
|
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug/globalData', 'f13'),
|
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/__docusaurus/debug/metadata',
|
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug/metadata', 'bff'),
|
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/__docusaurus/debug/registry',
|
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug/registry', '830'),
|
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/__docusaurus/debug/routes',
|
|
||||||
component: ComponentCreator('/docs/__docusaurus/debug/routes', '13e'),
|
|
||||||
exact: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/docs/',
|
|
||||||
component: ComponentCreator('/docs/', 'a3f'),
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/docs/',
|
path: '/docs/zh/',
|
||||||
component: ComponentCreator('/docs/', 'fa7'),
|
component: ComponentCreator('/docs/zh/', 'a8e'),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/docs/',
|
path: '/docs/zh/',
|
||||||
component: ComponentCreator('/docs/', '294'),
|
component: ComponentCreator('/docs/zh/', '632'),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/docs/commands/cli/cli-init',
|
path: '/docs/zh/commands/cli/cli-init',
|
||||||
component: ComponentCreator('/docs/commands/cli/cli-init', '159'),
|
component: ComponentCreator('/docs/zh/commands/cli/cli-init', 'fe3'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/cli/codex-review',
|
path: '/docs/zh/commands/cli/codex-review',
|
||||||
component: ComponentCreator('/docs/commands/cli/codex-review', 'c66'),
|
component: ComponentCreator('/docs/zh/commands/cli/codex-review', 'e65'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/ccw',
|
path: '/docs/zh/commands/general/ccw',
|
||||||
component: ComponentCreator('/docs/commands/general/ccw', '3c1'),
|
component: ComponentCreator('/docs/zh/commands/general/ccw', '83a'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/ccw-coordinator',
|
path: '/docs/zh/commands/general/ccw-coordinator',
|
||||||
component: ComponentCreator('/docs/commands/general/ccw-coordinator', '3b4'),
|
component: ComponentCreator('/docs/zh/commands/general/ccw-coordinator', 'f35'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/ccw-debug',
|
path: '/docs/zh/commands/general/ccw-debug',
|
||||||
component: ComponentCreator('/docs/commands/general/ccw-debug', 'e0c'),
|
component: ComponentCreator('/docs/zh/commands/general/ccw-debug', 'b0a'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/ccw-plan',
|
path: '/docs/zh/commands/general/ccw-plan',
|
||||||
component: ComponentCreator('/docs/commands/general/ccw-plan', '9ae'),
|
component: ComponentCreator('/docs/zh/commands/general/ccw-plan', '39d'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/ccw-test',
|
path: '/docs/zh/commands/general/ccw-test',
|
||||||
component: ComponentCreator('/docs/commands/general/ccw-test', 'e6f'),
|
component: ComponentCreator('/docs/zh/commands/general/ccw-test', '765'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/codex-coordinator',
|
path: '/docs/zh/commands/general/codex-coordinator',
|
||||||
component: ComponentCreator('/docs/commands/general/codex-coordinator', 'e7d'),
|
component: ComponentCreator('/docs/zh/commands/general/codex-coordinator', '486'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/general/flow-create',
|
path: '/docs/zh/commands/general/flow-create',
|
||||||
component: ComponentCreator('/docs/commands/general/flow-create', '507'),
|
component: ComponentCreator('/docs/zh/commands/general/flow-create', 'd53'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-convert-to-plan',
|
path: '/docs/zh/commands/issue/issue-convert-to-plan',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-convert-to-plan', 'a36'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-convert-to-plan', '0df'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-discover',
|
path: '/docs/zh/commands/issue/issue-discover',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-discover', '5ae'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-discover', '9b4'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-execute',
|
path: '/docs/zh/commands/issue/issue-execute',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-execute', '20b'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-execute', 'cfd'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-from-brainstorm',
|
path: '/docs/zh/commands/issue/issue-from-brainstorm',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-from-brainstorm', '10c'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-from-brainstorm', 'd2f'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-new',
|
path: '/docs/zh/commands/issue/issue-new',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-new', 'abb'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-new', '7f9'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-plan',
|
path: '/docs/zh/commands/issue/issue-plan',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-plan', '57f'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-plan', 'ed4'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/issue/issue-queue',
|
path: '/docs/zh/commands/issue/issue-queue',
|
||||||
component: ComponentCreator('/docs/commands/issue/issue-queue', '316'),
|
component: ComponentCreator('/docs/zh/commands/issue/issue-queue', 'a4b'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/memory/memory-compact',
|
path: '/docs/zh/commands/memory/memory-compact',
|
||||||
component: ComponentCreator('/docs/commands/memory/memory-compact', 'fbd'),
|
component: ComponentCreator('/docs/zh/commands/memory/memory-compact', '8dc'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/memory/memory-docs-full-cli',
|
path: '/docs/zh/commands/memory/memory-docs-full-cli',
|
||||||
component: ComponentCreator('/docs/commands/memory/memory-docs-full-cli', '8b8'),
|
component: ComponentCreator('/docs/zh/commands/memory/memory-docs-full-cli', '1a7'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/memory/memory-docs-related-cli',
|
path: '/docs/zh/commands/memory/memory-docs-related-cli',
|
||||||
component: ComponentCreator('/docs/commands/memory/memory-docs-related-cli', '707'),
|
component: ComponentCreator('/docs/zh/commands/memory/memory-docs-related-cli', 'f28'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/memory/memory-load',
|
path: '/docs/zh/commands/memory/memory-load',
|
||||||
component: ComponentCreator('/docs/commands/memory/memory-load', '1db'),
|
component: ComponentCreator('/docs/zh/commands/memory/memory-load', 'aee'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/memory/memory-update-full',
|
path: '/docs/zh/commands/memory/memory-update-full',
|
||||||
component: ComponentCreator('/docs/commands/memory/memory-update-full', '3fa'),
|
component: ComponentCreator('/docs/zh/commands/memory/memory-update-full', '2a1'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/commands/memory/memory-update-related',
|
path: '/docs/zh/commands/memory/memory-update-related',
|
||||||
component: ComponentCreator('/docs/commands/memory/memory-update-related', 'c50'),
|
component: ComponentCreator('/docs/zh/commands/memory/memory-update-related', '991'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/faq',
|
path: '/docs/zh/faq',
|
||||||
component: ComponentCreator('/docs/faq', '296'),
|
component: ComponentCreator('/docs/zh/faq', 'd6c'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/overview',
|
path: '/docs/zh/overview',
|
||||||
component: ComponentCreator('/docs/overview', 'f90'),
|
component: ComponentCreator('/docs/zh/overview', '2d1'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/faq',
|
path: '/docs/zh/workflows/faq',
|
||||||
component: ComponentCreator('/docs/workflows/faq', '58c'),
|
component: ComponentCreator('/docs/zh/workflows/faq', '319'),
|
||||||
exact: true
|
exact: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/introduction',
|
path: '/docs/zh/workflows/introduction',
|
||||||
component: ComponentCreator('/docs/workflows/introduction', '702'),
|
component: ComponentCreator('/docs/zh/workflows/introduction', 'dc8'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/level-1-ultra-lightweight',
|
path: '/docs/zh/workflows/level-1-ultra-lightweight',
|
||||||
component: ComponentCreator('/docs/workflows/level-1-ultra-lightweight', 'b4b'),
|
component: ComponentCreator('/docs/zh/workflows/level-1-ultra-lightweight', '4d3'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/level-2-rapid',
|
path: '/docs/zh/workflows/level-2-rapid',
|
||||||
component: ComponentCreator('/docs/workflows/level-2-rapid', 'fe1'),
|
component: ComponentCreator('/docs/zh/workflows/level-2-rapid', 'e2a'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/level-3-standard',
|
path: '/docs/zh/workflows/level-3-standard',
|
||||||
component: ComponentCreator('/docs/workflows/level-3-standard', '65f'),
|
component: ComponentCreator('/docs/zh/workflows/level-3-standard', '936'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/level-4-brainstorm',
|
path: '/docs/zh/workflows/level-4-brainstorm',
|
||||||
component: ComponentCreator('/docs/workflows/level-4-brainstorm', 'fae'),
|
component: ComponentCreator('/docs/zh/workflows/level-4-brainstorm', '87d'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/workflows/level-5-intelligent',
|
path: '/docs/zh/workflows/level-5-intelligent',
|
||||||
component: ComponentCreator('/docs/workflows/level-5-intelligent', 'fa9'),
|
component: ComponentCreator('/docs/zh/workflows/level-5-intelligent', 'b09'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/docs/',
|
path: '/docs/zh/',
|
||||||
component: ComponentCreator('/docs/', '6df'),
|
component: ComponentCreator('/docs/zh/', '0e3'),
|
||||||
exact: true,
|
exact: true,
|
||||||
sidebar: "docs"
|
sidebar: "docs"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,186 +1,143 @@
|
|||||||
{
|
{
|
||||||
"/docs/__docusaurus/debug-e58": {
|
"/docs/zh/-b34": {
|
||||||
"__comp": "__comp---theme-debug-config-23-a-2ff",
|
"__comp": "5e95c892",
|
||||||
"__context": {
|
"__context": {
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
"plugin": "aba21aa0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/docs/__docusaurus/debug/config-2ce": {
|
"/docs/zh/-a8e": {
|
||||||
"__comp": "__comp---theme-debug-config-23-a-2ff",
|
"__comp": "a7bd4aaa",
|
||||||
"__context": {
|
"__props": "b17e4002"
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"/docs/__docusaurus/debug/content-11b": {
|
"/docs/zh/-632": {
|
||||||
"__comp": "__comp---theme-debug-contentba-8-ce7",
|
"__comp": "a94703ab"
|
||||||
"__context": {
|
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
|
||||||
},
|
},
|
||||||
"__props": "__props---docs-docusaurus-debug-content-344-8d5"
|
"/docs/zh/commands/cli/cli-init-fe3": {
|
||||||
|
"__comp": "17896441",
|
||||||
|
"content": "0566a0a8"
|
||||||
},
|
},
|
||||||
"/docs/__docusaurus/debug/globalData-f13": {
|
"/docs/zh/commands/cli/codex-review-e65": {
|
||||||
"__comp": "__comp---theme-debug-global-dataede-0fa",
|
"__comp": "17896441",
|
||||||
"__context": {
|
"content": "f1bf82ec"
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"/docs/__docusaurus/debug/metadata-bff": {
|
"/docs/zh/commands/general/ccw-83a": {
|
||||||
"__comp": "__comp---theme-debug-site-metadata-68-e-3d4",
|
"__comp": "17896441",
|
||||||
"__context": {
|
"content": "f4817052"
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"/docs/__docusaurus/debug/registry-830": {
|
"/docs/zh/commands/general/ccw-coordinator-f35": {
|
||||||
"__comp": "__comp---theme-debug-registry-679-501",
|
"__comp": "17896441",
|
||||||
"__context": {
|
"content": "d550a629"
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"/docs/__docusaurus/debug/routes-13e": {
|
"/docs/zh/commands/general/ccw-debug-b0a": {
|
||||||
"__comp": "__comp---theme-debug-routes-946-699",
|
"__comp": "17896441",
|
||||||
"__context": {
|
"content": "97c6e66a"
|
||||||
"plugin": "plugin---docs-docusaurus-debugb-38-c84"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"/docs/-a3f": {
|
"/docs/zh/commands/general/ccw-plan-39d": {
|
||||||
"__comp": "__comp---theme-docs-root-5-e-9-0b6",
|
"__comp": "17896441",
|
||||||
"__context": {
|
"content": "04db0a2e"
|
||||||
"plugin": "plugin---docs-aba-4f5"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"/docs/-fa7": {
|
"/docs/zh/commands/general/ccw-test-765": {
|
||||||
"__comp": "__comp---theme-doc-version-roota-7-b-5de",
|
"__comp": "17896441",
|
||||||
"__props": "__props---docs-11-b-f70"
|
"content": "ccef5d0f"
|
||||||
},
|
},
|
||||||
"/docs/-294": {
|
"/docs/zh/commands/general/codex-coordinator-486": {
|
||||||
"__comp": "__comp---theme-doc-roota-94-67a"
|
"__comp": "17896441",
|
||||||
|
"content": "f9222419"
|
||||||
},
|
},
|
||||||
"/docs/commands/cli/cli-init-159": {
|
"/docs/zh/commands/general/flow-create-d53": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-cli-cli-init-056-ce1"
|
"content": "fabaf1c8"
|
||||||
},
|
},
|
||||||
"/docs/commands/cli/codex-review-c66": {
|
"/docs/zh/commands/issue/issue-convert-to-plan-0df": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-cli-codex-reviewf-1-b-55f"
|
"content": "5c7b2278"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/ccw-3c1": {
|
"/docs/zh/commands/issue/issue-discover-9b4": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-ccwf-48-8c4"
|
"content": "1e3006f3"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/ccw-coordinator-3b4": {
|
"/docs/zh/commands/issue/issue-execute-cfd": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-ccw-coordinatord-55-c6b"
|
"content": "fe8e3dcf"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/ccw-debug-e0c": {
|
"/docs/zh/commands/issue/issue-from-brainstorm-d2f": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-ccw-debug-97-c-a72"
|
"content": "2ecf8b4a"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/ccw-plan-9ae": {
|
"/docs/zh/commands/issue/issue-new-7f9": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-ccw-plan-04-d-fe0"
|
"content": "4ad7db0f"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/ccw-test-e6f": {
|
"/docs/zh/commands/issue/issue-plan-ed4": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-ccw-testcce-912"
|
"content": "a6c3df16"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/codex-coordinator-e7d": {
|
"/docs/zh/commands/issue/issue-queue-a4b": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-codex-coordinatorf-92-1dc"
|
"content": "1bac9067"
|
||||||
},
|
},
|
||||||
"/docs/commands/general/flow-create-507": {
|
"/docs/zh/commands/memory/memory-compact-8dc": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-general-flow-createfab-98a"
|
"content": "7a1ee27c"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-convert-to-plan-a36": {
|
"/docs/zh/commands/memory/memory-docs-full-cli-1a7": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-convert-to-plan-5-c-7-184"
|
"content": "4cc74730"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-discover-5ae": {
|
"/docs/zh/commands/memory/memory-docs-related-cli-f28": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-discover-1-e-3-569"
|
"content": "60eef997"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-execute-20b": {
|
"/docs/zh/commands/memory/memory-load-aee": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-executefe-8-c03"
|
"content": "157db180"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-from-brainstorm-10c": {
|
"/docs/zh/commands/memory/memory-update-full-2a1": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-from-brainstorm-2-ec-eeb"
|
"content": "666bb1bf"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-new-abb": {
|
"/docs/zh/commands/memory/memory-update-related-991": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-new-4-ad-3f0"
|
"content": "611877e1"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-plan-57f": {
|
"/docs/zh/faq-d6c": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-plana-6-c-fbd"
|
"content": "2a5e3eff"
|
||||||
},
|
},
|
||||||
"/docs/commands/issue/issue-queue-316": {
|
"/docs/zh/overview-2d1": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-issue-issue-queue-1-ba-55f"
|
"content": "8a7e39ed"
|
||||||
},
|
},
|
||||||
"/docs/commands/memory/memory-compact-fbd": {
|
"/docs/zh/workflows/faq-319": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-memory-memory-compact-7-a-1-41c"
|
"content": "46f40178"
|
||||||
},
|
},
|
||||||
"/docs/commands/memory/memory-docs-full-cli-8b8": {
|
"/docs/zh/workflows/introduction-dc8": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-memory-memory-docs-full-cli-4-cc-96f"
|
"content": "e5f6eee3"
|
||||||
},
|
},
|
||||||
"/docs/commands/memory/memory-docs-related-cli-707": {
|
"/docs/zh/workflows/level-1-ultra-lightweight-4d3": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-memory-memory-docs-related-cli-60-e-dd0"
|
"content": "9cf7cb6b"
|
||||||
},
|
},
|
||||||
"/docs/commands/memory/memory-load-1db": {
|
"/docs/zh/workflows/level-2-rapid-e2a": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-memory-memory-load-157-952"
|
"content": "05467734"
|
||||||
},
|
},
|
||||||
"/docs/commands/memory/memory-update-full-3fa": {
|
"/docs/zh/workflows/level-3-standard-936": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-memory-memory-update-full-666-002"
|
"content": "3f1fe4a1"
|
||||||
},
|
},
|
||||||
"/docs/commands/memory/memory-update-related-c50": {
|
"/docs/zh/workflows/level-4-brainstorm-87d": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-commands-memory-memory-update-related-611-8d3"
|
"content": "775938bf"
|
||||||
},
|
},
|
||||||
"/docs/faq-296": {
|
"/docs/zh/workflows/level-5-intelligent-b09": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-faqea-3-888"
|
"content": "562bb8cb"
|
||||||
},
|
},
|
||||||
"/docs/overview-f90": {
|
"/docs/zh/-0e3": {
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
"__comp": "17896441",
|
||||||
"content": "content---docs-overview-188-429"
|
"content": "6ab014e9"
|
||||||
},
|
|
||||||
"/docs/workflows/faq-58c": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-faqbcf-045"
|
|
||||||
},
|
|
||||||
"/docs/workflows/introduction-702": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-introduction-9-f-4-275"
|
|
||||||
},
|
|
||||||
"/docs/workflows/level-1-ultra-lightweight-b4b": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-level-1-ultra-lightweightc-5-a-5db"
|
|
||||||
},
|
|
||||||
"/docs/workflows/level-2-rapid-fe1": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-level-2-rapid-19-b-095"
|
|
||||||
},
|
|
||||||
"/docs/workflows/level-3-standard-65f": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-level-3-standardbdb-61a"
|
|
||||||
},
|
|
||||||
"/docs/workflows/level-4-brainstorm-fae": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-level-4-brainstormd-04-14f"
|
|
||||||
},
|
|
||||||
"/docs/workflows/level-5-intelligent-fa9": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-workflows-level-5-intelligent-186-b05"
|
|
||||||
},
|
|
||||||
"/docs/-6df": {
|
|
||||||
"__comp": "__comp---theme-doc-item-178-a40",
|
|
||||||
"content": "content---docs-4-ed-831"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
"name": "@docusaurus/plugin-content-pages",
|
"name": "@docusaurus/plugin-content-pages",
|
||||||
"version": "3.9.2"
|
"version": "3.9.2"
|
||||||
},
|
},
|
||||||
"docusaurus-plugin-debug": {
|
"docusaurus-plugin-sitemap": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"name": "@docusaurus/plugin-debug",
|
"name": "@docusaurus/plugin-sitemap",
|
||||||
"version": "3.9.2"
|
"version": "3.9.2"
|
||||||
},
|
},
|
||||||
"docusaurus-plugin-svgr": {
|
"docusaurus-plugin-svgr": {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ interface NavGroupDef {
|
|||||||
icon: React.ElementType;
|
icon: React.ElementType;
|
||||||
badge?: number | string;
|
badge?: number | string;
|
||||||
badgeVariant?: 'default' | 'success' | 'warning' | 'info';
|
badgeVariant?: 'default' | 'success' | 'warning' | 'info';
|
||||||
|
end?: boolean;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ const navGroupDefinitions: NavGroupDef[] = [
|
|||||||
items: [
|
items: [
|
||||||
{ path: '/settings/codexlens', labelKey: 'navigation.main.codexlens', icon: Sparkles },
|
{ path: '/settings/codexlens', labelKey: 'navigation.main.codexlens', icon: Sparkles },
|
||||||
{ path: '/api-settings', labelKey: 'navigation.main.apiSettings', icon: Server },
|
{ path: '/api-settings', labelKey: 'navigation.main.apiSettings', icon: Server },
|
||||||
{ path: '/settings', labelKey: 'navigation.main.settings', icon: Settings },
|
{ path: '/settings', labelKey: 'navigation.main.settings', icon: Settings, end: true },
|
||||||
{ path: '/help', labelKey: 'navigation.main.help', icon: HelpCircle },
|
{ path: '/help', labelKey: 'navigation.main.help', icon: HelpCircle },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ export function CcwToolsMcpCard({
|
|||||||
mutationFn: installCcwMcp,
|
mutationFn: installCcwMcp,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });
|
queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });
|
||||||
onInstall();
|
onInstall();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -123,8 +124,12 @@ export function CcwToolsMcpCard({
|
|||||||
mutationFn: uninstallCcwMcp,
|
mutationFn: uninstallCcwMcp,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });
|
queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });
|
||||||
onInstall();
|
onInstall();
|
||||||
},
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error('Failed to uninstall CCW MCP:', error);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateConfigMutation = useMutation({
|
const updateConfigMutation = useMutation({
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
createMcpServer,
|
createMcpServer,
|
||||||
updateMcpServer,
|
updateMcpServer,
|
||||||
fetchMcpServers,
|
fetchMcpServers,
|
||||||
|
saveMcpTemplate,
|
||||||
type McpServer,
|
type McpServer,
|
||||||
type McpProjectConfigType,
|
type McpProjectConfigType,
|
||||||
} from '@/lib/api';
|
} from '@/lib/api';
|
||||||
@@ -95,6 +96,7 @@ export function McpServerDialog({
|
|||||||
const [argsInput, setArgsInput] = useState('');
|
const [argsInput, setArgsInput] = useState('');
|
||||||
const [envInput, setEnvInput] = useState('');
|
const [envInput, setEnvInput] = useState('');
|
||||||
const [configType, setConfigType] = useState<McpConfigType>('mcp-json');
|
const [configType, setConfigType] = useState<McpConfigType>('mcp-json');
|
||||||
|
const [saveAsTemplate, setSaveAsTemplate] = useState(false);
|
||||||
const projectConfigType: McpProjectConfigType = configType === 'claude-json' ? 'claude' : 'mcp';
|
const projectConfigType: McpProjectConfigType = configType === 'claude-json' ? 'claude' : 'mcp';
|
||||||
|
|
||||||
// Initialize form from server prop (edit mode)
|
// Initialize form from server prop (edit mode)
|
||||||
@@ -128,6 +130,7 @@ export function McpServerDialog({
|
|||||||
setEnvInput('');
|
setEnvInput('');
|
||||||
}
|
}
|
||||||
setSelectedTemplate('');
|
setSelectedTemplate('');
|
||||||
|
setSaveAsTemplate(false);
|
||||||
setErrors({});
|
setErrors({});
|
||||||
}, [server, mode, open]);
|
}, [server, mode, open]);
|
||||||
|
|
||||||
@@ -261,6 +264,23 @@ export function McpServerDialog({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save as template if checked
|
||||||
|
if (saveAsTemplate) {
|
||||||
|
try {
|
||||||
|
await saveMcpTemplate({
|
||||||
|
name: formData.name,
|
||||||
|
category: 'custom',
|
||||||
|
serverConfig: {
|
||||||
|
command: formData.command,
|
||||||
|
args: formData.args.length > 0 ? formData.args : undefined,
|
||||||
|
env: Object.keys(formData.env).length > 0 ? formData.env : undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// Template save failure should not block server creation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mode === 'add') {
|
if (mode === 'add') {
|
||||||
createMutation.mutate({
|
createMutation.mutate({
|
||||||
server: {
|
server: {
|
||||||
@@ -501,6 +521,20 @@ export function McpServerDialog({
|
|||||||
{formatMessage({ id: 'mcp.dialog.form.enabled' })}
|
{formatMessage({ id: 'mcp.dialog.form.enabled' })}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Save as Template */}
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="save-as-template"
|
||||||
|
checked={saveAsTemplate}
|
||||||
|
onChange={(e) => setSaveAsTemplate(e.target.checked)}
|
||||||
|
className="w-4 h-4"
|
||||||
|
/>
|
||||||
|
<label htmlFor="save-as-template" className="text-sm font-medium text-foreground cursor-pointer">
|
||||||
|
{formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
|||||||
@@ -58,17 +58,18 @@ import type { McpTemplate } from '@/types/store';
|
|||||||
export interface McpTemplatesSectionProps {
|
export interface McpTemplatesSectionProps {
|
||||||
/** Callback when template is installed (opens McpServerDialog) */
|
/** Callback when template is installed (opens McpServerDialog) */
|
||||||
onInstallTemplate?: (template: McpTemplate) => void;
|
onInstallTemplate?: (template: McpTemplate) => void;
|
||||||
/** Callback when current server should be saved as template */
|
/** Callback when saving a new template */
|
||||||
onSaveAsTemplate?: (serverName: string, config: { command: string; args: string[]; env?: Record<string, string> }) => void;
|
onSaveAsTemplate?: (name: string, category: string, description: string, serverConfig: { command: string; args: string[]; env: Record<string, string> }) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TemplateSaveDialogProps {
|
interface TemplateSaveDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSave: (name: string, category: string, description: string) => void;
|
onSave: (name: string, category: string, description: string, serverConfig: { command: string; args: string[]; env: Record<string, string> }) => void;
|
||||||
defaultName?: string;
|
defaultName?: string;
|
||||||
defaultCommand?: string;
|
defaultCommand?: string;
|
||||||
defaultArgs?: string[];
|
defaultArgs?: string[];
|
||||||
|
defaultEnv?: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TemplateCardProps {
|
interface TemplateCardProps {
|
||||||
@@ -181,18 +182,26 @@ function TemplateCard({ template, onInstall, onDelete, isInstalling, isDeleting
|
|||||||
/**
|
/**
|
||||||
* Template Save Dialog - Save current server configuration as template
|
* Template Save Dialog - Save current server configuration as template
|
||||||
*/
|
*/
|
||||||
function TemplateSaveDialog({
|
export function TemplateSaveDialog({
|
||||||
open,
|
open,
|
||||||
onClose,
|
onClose,
|
||||||
onSave,
|
onSave,
|
||||||
defaultName = '',
|
defaultName = '',
|
||||||
|
defaultCommand = '',
|
||||||
|
defaultArgs = [],
|
||||||
|
defaultEnv = {},
|
||||||
}: TemplateSaveDialogProps) {
|
}: TemplateSaveDialogProps) {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
const [name, setName] = useState(defaultName);
|
const [name, setName] = useState(defaultName);
|
||||||
const [category, setCategory] = useState('');
|
const [category, setCategory] = useState('');
|
||||||
const [description, setDescription] = useState('');
|
const [description, setDescription] = useState('');
|
||||||
const [errors, setErrors] = useState<{ name?: string }>({});
|
const [command, setCommand] = useState(defaultCommand);
|
||||||
|
const [argsInput, setArgsInput] = useState(defaultArgs.join(', '));
|
||||||
|
const [envInput, setEnvInput] = useState(
|
||||||
|
Object.entries(defaultEnv).map(([k, v]) => `${k}=${v}`).join('\n')
|
||||||
|
);
|
||||||
|
const [errors, setErrors] = useState<{ name?: string; command?: string }>({});
|
||||||
|
|
||||||
// Reset form when dialog opens
|
// Reset form when dialog opens
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -200,25 +209,52 @@ function TemplateSaveDialog({
|
|||||||
setName(defaultName || '');
|
setName(defaultName || '');
|
||||||
setCategory('');
|
setCategory('');
|
||||||
setDescription('');
|
setDescription('');
|
||||||
|
setCommand(defaultCommand || '');
|
||||||
|
setArgsInput((defaultArgs || []).join(', '));
|
||||||
|
setEnvInput(
|
||||||
|
Object.entries(defaultEnv || {}).map(([k, v]) => `${k}=${v}`).join('\n')
|
||||||
|
);
|
||||||
setErrors({});
|
setErrors({});
|
||||||
}
|
}
|
||||||
}, [open, defaultName]);
|
}, [open, defaultName, defaultCommand, defaultArgs, defaultEnv]);
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
|
const newErrors: { name?: string; command?: string } = {};
|
||||||
if (!name.trim()) {
|
if (!name.trim()) {
|
||||||
setErrors({ name: formatMessage({ id: 'mcp.templates.saveDialog.validation.nameRequired' }) });
|
newErrors.name = formatMessage({ id: 'mcp.templates.saveDialog.validation.nameRequired' });
|
||||||
|
}
|
||||||
|
if (!command.trim()) {
|
||||||
|
newErrors.command = formatMessage({ id: 'mcp.dialog.validation.commandRequired' });
|
||||||
|
}
|
||||||
|
if (Object.keys(newErrors).length > 0) {
|
||||||
|
setErrors(newErrors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onSave(name.trim(), category.trim(), description.trim());
|
|
||||||
setName('');
|
const args = argsInput
|
||||||
setCategory('');
|
.split(',')
|
||||||
setDescription('');
|
.map((a) => a.trim())
|
||||||
setErrors({});
|
.filter((a) => a.length > 0);
|
||||||
|
|
||||||
|
const env: Record<string, string> = {};
|
||||||
|
for (const line of envInput.split('\n')) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (trimmed && trimmed.includes('=')) {
|
||||||
|
const [key, ...valParts] = trimmed.split('=');
|
||||||
|
if (key) env[key.trim()] = valParts.join('=').trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSave(name.trim(), category.trim(), description.trim(), {
|
||||||
|
command: command.trim(),
|
||||||
|
args,
|
||||||
|
env,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={onClose}>
|
<Dialog open={open} onOpenChange={onClose}>
|
||||||
<DialogContent className="max-w-md">
|
<DialogContent className="max-w-md max-h-[85vh] overflow-y-auto">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{formatMessage({ id: 'mcp.templates.saveDialog.title' })}
|
{formatMessage({ id: 'mcp.templates.saveDialog.title' })}
|
||||||
@@ -235,7 +271,7 @@ function TemplateSaveDialog({
|
|||||||
value={name}
|
value={name}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setName(e.target.value);
|
setName(e.target.value);
|
||||||
if (errors.name) setErrors({});
|
if (errors.name) setErrors((prev) => ({ ...prev, name: undefined }));
|
||||||
}}
|
}}
|
||||||
placeholder={formatMessage({ id: 'mcp.templates.saveDialog.namePlaceholder' })}
|
placeholder={formatMessage({ id: 'mcp.templates.saveDialog.namePlaceholder' })}
|
||||||
error={!!errors.name}
|
error={!!errors.name}
|
||||||
@@ -245,6 +281,54 @@ function TemplateSaveDialog({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Command */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium text-foreground">
|
||||||
|
{formatMessage({ id: 'mcp.dialog.form.command' })}
|
||||||
|
<span className="text-destructive ml-1">*</span>
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={command}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCommand(e.target.value);
|
||||||
|
if (errors.command) setErrors((prev) => ({ ...prev, command: undefined }));
|
||||||
|
}}
|
||||||
|
placeholder={formatMessage({ id: 'mcp.dialog.form.commandPlaceholder' })}
|
||||||
|
error={!!errors.command}
|
||||||
|
/>
|
||||||
|
{errors.command && (
|
||||||
|
<p className="text-sm text-destructive">{errors.command}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Args */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium text-foreground">
|
||||||
|
{formatMessage({ id: 'mcp.dialog.form.args' })}
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={argsInput}
|
||||||
|
onChange={(e) => setArgsInput(e.target.value)}
|
||||||
|
placeholder={formatMessage({ id: 'mcp.dialog.form.argsPlaceholder' })}
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{formatMessage({ id: 'mcp.dialog.form.argsHint' })}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Environment Variables */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium text-foreground">
|
||||||
|
{formatMessage({ id: 'mcp.dialog.form.env' })}
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
value={envInput}
|
||||||
|
onChange={(e) => setEnvInput(e.target.value)}
|
||||||
|
placeholder={formatMessage({ id: 'mcp.dialog.form.envPlaceholder' })}
|
||||||
|
className="flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Category */}
|
{/* Category */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label className="text-sm font-medium text-foreground">
|
<label className="text-sm font-medium text-foreground">
|
||||||
@@ -273,7 +357,7 @@ function TemplateSaveDialog({
|
|||||||
value={description}
|
value={description}
|
||||||
onChange={(e) => setDescription(e.target.value)}
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
placeholder={formatMessage({ id: 'mcp.templates.saveDialog.descriptionPlaceholder' })}
|
placeholder={formatMessage({ id: 'mcp.templates.saveDialog.descriptionPlaceholder' })}
|
||||||
className="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
className="flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -374,8 +458,8 @@ export function McpTemplatesSection({ onInstallTemplate, onSaveAsTemplate }: Mcp
|
|||||||
}
|
}
|
||||||
}, [templateToDelete, deleteMutation]);
|
}, [templateToDelete, deleteMutation]);
|
||||||
|
|
||||||
const handleSaveTemplate = useCallback((_name: string, _category: string, _description: string) => {
|
const handleSaveTemplate = useCallback((_name: string, _category: string, _description: string, _serverConfig: { command: string; args: string[]; env: Record<string, string> }) => {
|
||||||
onSaveAsTemplate?.(_name, { command: '', args: [] });
|
onSaveAsTemplate?.(_name, _category, _description, _serverConfig);
|
||||||
setSaveDialogOpen(false);
|
setSaveDialogOpen(false);
|
||||||
}, [onSaveAsTemplate]);
|
}, [onSaveAsTemplate]);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ export interface NavItem {
|
|||||||
icon: React.ElementType;
|
icon: React.ElementType;
|
||||||
badge?: number | string;
|
badge?: number | string;
|
||||||
badgeVariant?: 'default' | 'success' | 'warning' | 'info';
|
badgeVariant?: 'default' | 'success' | 'warning' | 'info';
|
||||||
|
/** When true, only exact path match activates this item (no prefix matching) */
|
||||||
|
end?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NavGroupProps {
|
export interface NavGroupProps {
|
||||||
@@ -54,9 +56,9 @@ export function NavGroup({
|
|||||||
{items.map((item) => {
|
{items.map((item) => {
|
||||||
const ItemIcon = item.icon;
|
const ItemIcon = item.icon;
|
||||||
const [basePath] = item.path.split('?');
|
const [basePath] = item.path.split('?');
|
||||||
// More precise matching: exact match or basePath followed by '/' to avoid parent/child conflicts
|
const isActive = item.end
|
||||||
const isActive =
|
? location.pathname === basePath
|
||||||
location.pathname === basePath ||
|
: location.pathname === basePath ||
|
||||||
(basePath !== '/' && location.pathname.startsWith(basePath + '/'));
|
(basePath !== '/' && location.pathname.startsWith(basePath + '/'));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -94,9 +96,9 @@ export function NavGroup({
|
|||||||
{items.map((item) => {
|
{items.map((item) => {
|
||||||
const ItemIcon = item.icon;
|
const ItemIcon = item.icon;
|
||||||
const [basePath, searchParams] = item.path.split('?');
|
const [basePath, searchParams] = item.path.split('?');
|
||||||
// More precise matching: exact match or basePath followed by '/' to avoid parent/child conflicts
|
const isActive = item.end
|
||||||
const isActive =
|
? location.pathname === basePath
|
||||||
location.pathname === basePath ||
|
: location.pathname === basePath ||
|
||||||
(basePath !== '/' && location.pathname.startsWith(basePath + '/'));
|
(basePath !== '/' && location.pathname.startsWith(basePath + '/'));
|
||||||
const isQueryParamActive =
|
const isQueryParamActive =
|
||||||
searchParams && location.search.includes(searchParams);
|
searchParams && location.search.includes(searchParams);
|
||||||
|
|||||||
406
ccw/frontend/src/components/shared/SkillCreateDialog.tsx
Normal file
406
ccw/frontend/src/components/shared/SkillCreateDialog.tsx
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
// ========================================
|
||||||
|
// Skill Create Dialog Component
|
||||||
|
// ========================================
|
||||||
|
// Modal dialog for creating/importing skills with two modes:
|
||||||
|
// - Import: import existing skill folder
|
||||||
|
// - CLI Generate: AI-generated skill from description
|
||||||
|
|
||||||
|
import { useState, useCallback } from 'react';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
import {
|
||||||
|
Folder,
|
||||||
|
User,
|
||||||
|
FolderInput,
|
||||||
|
Sparkles,
|
||||||
|
CheckCircle,
|
||||||
|
XCircle,
|
||||||
|
Loader2,
|
||||||
|
Info,
|
||||||
|
} from 'lucide-react';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogFooter,
|
||||||
|
DialogTitle,
|
||||||
|
DialogDescription,
|
||||||
|
} from '@/components/ui/Dialog';
|
||||||
|
import { Button } from '@/components/ui/Button';
|
||||||
|
import { Input } from '@/components/ui/Input';
|
||||||
|
import { Textarea } from '@/components/ui/Textarea';
|
||||||
|
import { Label } from '@/components/ui/Label';
|
||||||
|
import { validateSkillImport, createSkill } from '@/lib/api';
|
||||||
|
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
export interface SkillCreateDialogProps {
|
||||||
|
open: boolean;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
onCreated: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateMode = 'import' | 'cli-generate';
|
||||||
|
type SkillLocation = 'project' | 'user';
|
||||||
|
|
||||||
|
interface ValidationResult {
|
||||||
|
valid: boolean;
|
||||||
|
errors?: string[];
|
||||||
|
skillInfo?: { name: string; description: string; version?: string; supportingFiles?: string[] };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SkillCreateDialog({ open, onOpenChange, onCreated }: SkillCreateDialogProps) {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const projectPath = useWorkflowStore(selectProjectPath);
|
||||||
|
|
||||||
|
const [mode, setMode] = useState<CreateMode>('import');
|
||||||
|
const [location, setLocation] = useState<SkillLocation>('project');
|
||||||
|
|
||||||
|
// Import mode state
|
||||||
|
const [sourcePath, setSourcePath] = useState('');
|
||||||
|
const [customName, setCustomName] = useState('');
|
||||||
|
const [validationResult, setValidationResult] = useState<ValidationResult | null>(null);
|
||||||
|
const [isValidating, setIsValidating] = useState(false);
|
||||||
|
|
||||||
|
// CLI Generate mode state
|
||||||
|
const [skillName, setSkillName] = useState('');
|
||||||
|
const [description, setDescription] = useState('');
|
||||||
|
|
||||||
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
|
|
||||||
|
const resetState = useCallback(() => {
|
||||||
|
setMode('import');
|
||||||
|
setLocation('project');
|
||||||
|
setSourcePath('');
|
||||||
|
setCustomName('');
|
||||||
|
setValidationResult(null);
|
||||||
|
setIsValidating(false);
|
||||||
|
setSkillName('');
|
||||||
|
setDescription('');
|
||||||
|
setIsCreating(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleOpenChange = useCallback((open: boolean) => {
|
||||||
|
if (!open) {
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
onOpenChange(open);
|
||||||
|
}, [onOpenChange, resetState]);
|
||||||
|
|
||||||
|
const handleValidate = useCallback(async () => {
|
||||||
|
if (!sourcePath.trim()) return;
|
||||||
|
|
||||||
|
setIsValidating(true);
|
||||||
|
setValidationResult(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await validateSkillImport(sourcePath.trim());
|
||||||
|
setValidationResult(result);
|
||||||
|
} catch (err) {
|
||||||
|
setValidationResult({
|
||||||
|
valid: false,
|
||||||
|
errors: [err instanceof Error ? err.message : String(err)],
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setIsValidating(false);
|
||||||
|
}
|
||||||
|
}, [sourcePath]);
|
||||||
|
|
||||||
|
const handleCreate = useCallback(async () => {
|
||||||
|
if (mode === 'import') {
|
||||||
|
if (!sourcePath.trim()) return;
|
||||||
|
if (!validationResult?.valid) return;
|
||||||
|
} else {
|
||||||
|
if (!skillName.trim()) return;
|
||||||
|
if (!description.trim()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsCreating(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await createSkill({
|
||||||
|
mode,
|
||||||
|
location,
|
||||||
|
sourcePath: mode === 'import' ? sourcePath.trim() : undefined,
|
||||||
|
skillName: mode === 'import' ? (customName.trim() || undefined) : skillName.trim(),
|
||||||
|
description: mode === 'cli-generate' ? description.trim() : undefined,
|
||||||
|
generationType: mode === 'cli-generate' ? 'description' : undefined,
|
||||||
|
projectPath,
|
||||||
|
});
|
||||||
|
|
||||||
|
handleOpenChange(false);
|
||||||
|
onCreated();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to create skill:', err);
|
||||||
|
if (mode === 'import') {
|
||||||
|
setValidationResult({
|
||||||
|
valid: false,
|
||||||
|
errors: [err instanceof Error ? err.message : formatMessage({ id: 'skills.create.createError' })],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setIsCreating(false);
|
||||||
|
}
|
||||||
|
}, [mode, location, sourcePath, customName, skillName, description, validationResult, projectPath, handleOpenChange, onCreated, formatMessage]);
|
||||||
|
|
||||||
|
const canCreate = mode === 'import'
|
||||||
|
? sourcePath.trim() && validationResult?.valid && !isCreating
|
||||||
|
: skillName.trim() && description.trim() && !isCreating;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||||
|
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{formatMessage({ id: 'skills.create.title' })}</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
{formatMessage({ id: 'skills.description' })}
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div className="space-y-5 py-2">
|
||||||
|
{/* Location Selection */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>{formatMessage({ id: 'skills.create.location' })}</Label>
|
||||||
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={cn(
|
||||||
|
'px-4 py-3 text-left border-2 rounded-lg transition-all',
|
||||||
|
location === 'project'
|
||||||
|
? 'border-primary bg-primary/10'
|
||||||
|
: 'border-border hover:border-primary/50'
|
||||||
|
)}
|
||||||
|
onClick={() => setLocation('project')}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Folder className="w-5 h-5" />
|
||||||
|
<div>
|
||||||
|
<div className="font-medium text-sm">{formatMessage({ id: 'skills.create.locationProject' })}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.locationProjectHint' })}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={cn(
|
||||||
|
'px-4 py-3 text-left border-2 rounded-lg transition-all',
|
||||||
|
location === 'user'
|
||||||
|
? 'border-primary bg-primary/10'
|
||||||
|
: 'border-border hover:border-primary/50'
|
||||||
|
)}
|
||||||
|
onClick={() => setLocation('user')}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<User className="w-5 h-5" />
|
||||||
|
<div>
|
||||||
|
<div className="font-medium text-sm">{formatMessage({ id: 'skills.create.locationUser' })}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.locationUserHint' })}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mode Selection */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>{formatMessage({ id: 'skills.create.mode' })}</Label>
|
||||||
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={cn(
|
||||||
|
'px-4 py-3 text-left border-2 rounded-lg transition-all',
|
||||||
|
mode === 'import'
|
||||||
|
? 'border-primary bg-primary/10'
|
||||||
|
: 'border-border hover:border-primary/50'
|
||||||
|
)}
|
||||||
|
onClick={() => setMode('import')}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<FolderInput className="w-5 h-5" />
|
||||||
|
<div>
|
||||||
|
<div className="font-medium text-sm">{formatMessage({ id: 'skills.create.modeImport' })}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.modeImportHint' })}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={cn(
|
||||||
|
'px-4 py-3 text-left border-2 rounded-lg transition-all',
|
||||||
|
mode === 'cli-generate'
|
||||||
|
? 'border-primary bg-primary/10'
|
||||||
|
: 'border-border hover:border-primary/50'
|
||||||
|
)}
|
||||||
|
onClick={() => setMode('cli-generate')}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Sparkles className="w-5 h-5" />
|
||||||
|
<div>
|
||||||
|
<div className="font-medium text-sm">{formatMessage({ id: 'skills.create.modeGenerate' })}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.modeGenerateHint' })}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Import Mode Content */}
|
||||||
|
{mode === 'import' && (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="sourcePath">{formatMessage({ id: 'skills.create.sourcePath' })}</Label>
|
||||||
|
<Input
|
||||||
|
id="sourcePath"
|
||||||
|
value={sourcePath}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSourcePath(e.target.value);
|
||||||
|
setValidationResult(null);
|
||||||
|
}}
|
||||||
|
placeholder={formatMessage({ id: 'skills.create.sourcePathPlaceholder' })}
|
||||||
|
className="font-mono text-sm"
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.sourcePathHint' })}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="customName">
|
||||||
|
{formatMessage({ id: 'skills.create.customName' })}
|
||||||
|
<span className="text-muted-foreground ml-1">({formatMessage({ id: 'skills.create.customNameHint' })})</span>
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="customName"
|
||||||
|
value={customName}
|
||||||
|
onChange={(e) => setCustomName(e.target.value)}
|
||||||
|
placeholder={formatMessage({ id: 'skills.create.customNamePlaceholder' })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Validation Result */}
|
||||||
|
{isValidating && (
|
||||||
|
<div className="flex items-center gap-2 p-3 bg-muted/50 rounded-lg">
|
||||||
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
|
<span className="text-sm text-muted-foreground">{formatMessage({ id: 'skills.create.validating' })}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{validationResult && !isValidating && (
|
||||||
|
validationResult.valid ? (
|
||||||
|
<div className="p-4 bg-green-500/10 border border-green-500/20 rounded-lg">
|
||||||
|
<div className="flex items-center gap-2 text-green-600 mb-2">
|
||||||
|
<CheckCircle className="w-5 h-5" />
|
||||||
|
<span className="font-medium">{formatMessage({ id: 'skills.create.validSkill' })}</span>
|
||||||
|
</div>
|
||||||
|
{validationResult.skillInfo && (
|
||||||
|
<div className="space-y-1 text-sm">
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">{formatMessage({ id: 'skills.card.description' })}: </span>
|
||||||
|
<span>{validationResult.skillInfo.name}</span>
|
||||||
|
</div>
|
||||||
|
{validationResult.skillInfo.description && (
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">{formatMessage({ id: 'skills.card.description' })}: </span>
|
||||||
|
<span>{validationResult.skillInfo.description}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{validationResult.skillInfo.version && (
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">{formatMessage({ id: 'skills.card.version' })}: </span>
|
||||||
|
<span>{validationResult.skillInfo.version}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="p-4 bg-destructive/10 border border-destructive/20 rounded-lg">
|
||||||
|
<div className="flex items-center gap-2 text-destructive mb-2">
|
||||||
|
<XCircle className="w-5 h-5" />
|
||||||
|
<span className="font-medium">{formatMessage({ id: 'skills.create.invalidSkill' })}</span>
|
||||||
|
</div>
|
||||||
|
{validationResult.errors && (
|
||||||
|
<ul className="space-y-1 text-sm">
|
||||||
|
{validationResult.errors.map((error, i) => (
|
||||||
|
<li key={i} className="text-destructive">{error}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* CLI Generate Mode Content */}
|
||||||
|
{mode === 'cli-generate' && (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="skillName">
|
||||||
|
{formatMessage({ id: 'skills.create.skillName' })} <span className="text-destructive">*</span>
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="skillName"
|
||||||
|
value={skillName}
|
||||||
|
onChange={(e) => setSkillName(e.target.value)}
|
||||||
|
placeholder={formatMessage({ id: 'skills.create.skillNamePlaceholder' })}
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.skillNameHint' })}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="description">
|
||||||
|
{formatMessage({ id: 'skills.create.descriptionLabel' })} <span className="text-destructive">*</span>
|
||||||
|
</Label>
|
||||||
|
<Textarea
|
||||||
|
id="description"
|
||||||
|
value={description}
|
||||||
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
|
placeholder={formatMessage({ id: 'skills.create.descriptionPlaceholder' })}
|
||||||
|
rows={6}
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.descriptionHint' })}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg">
|
||||||
|
<div className="flex items-start gap-2">
|
||||||
|
<Info className="w-4 h-4 text-blue-600 mt-0.5" />
|
||||||
|
<div className="text-sm text-blue-600">
|
||||||
|
<p className="font-medium">{formatMessage({ id: 'skills.create.generateInfo' })}</p>
|
||||||
|
<p className="text-xs mt-1">{formatMessage({ id: 'skills.create.generateTimeHint' })}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DialogFooter className="gap-2">
|
||||||
|
<Button variant="outline" onClick={() => handleOpenChange(false)} disabled={isCreating}>
|
||||||
|
{formatMessage({ id: 'skills.actions.cancel' })}
|
||||||
|
</Button>
|
||||||
|
{mode === 'import' && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleValidate}
|
||||||
|
disabled={!sourcePath.trim() || isValidating || isCreating}
|
||||||
|
>
|
||||||
|
{isValidating && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
|
||||||
|
{formatMessage({ id: 'skills.create.validate' })}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
onClick={handleCreate}
|
||||||
|
disabled={!canCreate}
|
||||||
|
>
|
||||||
|
{isCreating && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
|
||||||
|
{isCreating
|
||||||
|
? formatMessage({ id: 'skills.create.creating' })
|
||||||
|
: mode === 'import'
|
||||||
|
? formatMessage({ id: 'skills.create.import' })
|
||||||
|
: formatMessage({ id: 'skills.create.generate' })
|
||||||
|
}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SkillCreateDialog;
|
||||||
@@ -19,6 +19,9 @@ export type { SkillCardProps } from './SkillCard';
|
|||||||
export { SkillDetailPanel } from './SkillDetailPanel';
|
export { SkillDetailPanel } from './SkillDetailPanel';
|
||||||
export type { SkillDetailPanelProps } from './SkillDetailPanel';
|
export type { SkillDetailPanelProps } from './SkillDetailPanel';
|
||||||
|
|
||||||
|
export { SkillCreateDialog } from './SkillCreateDialog';
|
||||||
|
export type { SkillCreateDialogProps } from './SkillCreateDialog';
|
||||||
|
|
||||||
export { StatCard, StatCardSkeleton } from './StatCard';
|
export { StatCard, StatCardSkeleton } from './StatCard';
|
||||||
export type { StatCardProps } from './StatCard';
|
export type { StatCardProps } from './StatCard';
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,27 @@ export type {
|
|||||||
UseRulesReturn,
|
UseRulesReturn,
|
||||||
} from './useCli';
|
} from './useCli';
|
||||||
|
|
||||||
|
// ========== System Settings ==========
|
||||||
|
export {
|
||||||
|
useChineseResponseStatus,
|
||||||
|
useToggleChineseResponse,
|
||||||
|
useWindowsPlatformStatus,
|
||||||
|
useToggleWindowsPlatform,
|
||||||
|
useCodexCliEnhancementStatus,
|
||||||
|
useToggleCodexCliEnhancement,
|
||||||
|
useRefreshCodexCliEnhancement,
|
||||||
|
useCcwInstallStatus,
|
||||||
|
useCliToolStatus,
|
||||||
|
systemSettingsKeys,
|
||||||
|
} from './useSystemSettings';
|
||||||
|
export type {
|
||||||
|
UseChineseResponseStatusReturn,
|
||||||
|
UseWindowsPlatformStatusReturn,
|
||||||
|
UseCodexCliEnhancementStatusReturn,
|
||||||
|
UseCcwInstallStatusReturn,
|
||||||
|
UseCliToolStatusReturn,
|
||||||
|
} from './useSystemSettings';
|
||||||
|
|
||||||
// ========== CLI Execution ==========
|
// ========== CLI Execution ==========
|
||||||
export {
|
export {
|
||||||
useCliExecutionDetail,
|
useCliExecutionDetail,
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ export function useDeleteMcpServer(): UseDeleteMcpServerReturn {
|
|||||||
deleteMcpServer(serverName, scope, { projectPath: projectPath ?? undefined }),
|
deleteMcpServer(serverName, scope, { projectPath: projectPath ?? undefined }),
|
||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });
|
queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
238
ccw/frontend/src/hooks/useSystemSettings.ts
Normal file
238
ccw/frontend/src/hooks/useSystemSettings.ts
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
// ========================================
|
||||||
|
// useSystemSettings Hook
|
||||||
|
// ========================================
|
||||||
|
// TanStack Query hooks for system settings (language, install status, tool status)
|
||||||
|
|
||||||
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import {
|
||||||
|
fetchChineseResponseStatus,
|
||||||
|
toggleChineseResponse,
|
||||||
|
fetchWindowsPlatformStatus,
|
||||||
|
toggleWindowsPlatform,
|
||||||
|
fetchCodexCliEnhancementStatus,
|
||||||
|
toggleCodexCliEnhancement,
|
||||||
|
refreshCodexCliEnhancement,
|
||||||
|
fetchAggregatedStatus,
|
||||||
|
fetchCliToolStatus,
|
||||||
|
type ChineseResponseStatus,
|
||||||
|
type WindowsPlatformStatus,
|
||||||
|
type CodexCliEnhancementStatus,
|
||||||
|
type CcwInstallStatus,
|
||||||
|
} from '../lib/api';
|
||||||
|
|
||||||
|
// Query key factory
|
||||||
|
export const systemSettingsKeys = {
|
||||||
|
all: ['systemSettings'] as const,
|
||||||
|
chineseResponse: () => [...systemSettingsKeys.all, 'chineseResponse'] as const,
|
||||||
|
windowsPlatform: () => [...systemSettingsKeys.all, 'windowsPlatform'] as const,
|
||||||
|
codexCliEnhancement: () => [...systemSettingsKeys.all, 'codexCliEnhancement'] as const,
|
||||||
|
aggregatedStatus: () => [...systemSettingsKeys.all, 'aggregatedStatus'] as const,
|
||||||
|
cliToolStatus: () => [...systemSettingsKeys.all, 'cliToolStatus'] as const,
|
||||||
|
};
|
||||||
|
|
||||||
|
const STALE_TIME = 60 * 1000; // 1 minute
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Chinese Response Hooks
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
export interface UseChineseResponseStatusReturn {
|
||||||
|
data: ChineseResponseStatus | undefined;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: Error | null;
|
||||||
|
refetch: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useChineseResponseStatus(): UseChineseResponseStatusReturn {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: systemSettingsKeys.chineseResponse(),
|
||||||
|
queryFn: fetchChineseResponseStatus,
|
||||||
|
staleTime: STALE_TIME,
|
||||||
|
retry: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: query.data,
|
||||||
|
isLoading: query.isLoading,
|
||||||
|
error: query.error,
|
||||||
|
refetch: () => { query.refetch(); },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useToggleChineseResponse() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: ({ enabled, target }: { enabled: boolean; target: 'claude' | 'codex' }) =>
|
||||||
|
toggleChineseResponse(enabled, target),
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: systemSettingsKeys.chineseResponse() });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
toggle: (enabled: boolean, target: 'claude' | 'codex') =>
|
||||||
|
mutation.mutateAsync({ enabled, target }),
|
||||||
|
isPending: mutation.isPending,
|
||||||
|
error: mutation.error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Windows Platform Hooks
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
export interface UseWindowsPlatformStatusReturn {
|
||||||
|
data: WindowsPlatformStatus | undefined;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: Error | null;
|
||||||
|
refetch: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useWindowsPlatformStatus(): UseWindowsPlatformStatusReturn {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: systemSettingsKeys.windowsPlatform(),
|
||||||
|
queryFn: fetchWindowsPlatformStatus,
|
||||||
|
staleTime: STALE_TIME,
|
||||||
|
retry: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: query.data,
|
||||||
|
isLoading: query.isLoading,
|
||||||
|
error: query.error,
|
||||||
|
refetch: () => { query.refetch(); },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useToggleWindowsPlatform() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: (enabled: boolean) => toggleWindowsPlatform(enabled),
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: systemSettingsKeys.windowsPlatform() });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
toggle: mutation.mutateAsync,
|
||||||
|
isPending: mutation.isPending,
|
||||||
|
error: mutation.error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Codex CLI Enhancement Hooks
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
export interface UseCodexCliEnhancementStatusReturn {
|
||||||
|
data: CodexCliEnhancementStatus | undefined;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: Error | null;
|
||||||
|
refetch: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCodexCliEnhancementStatus(): UseCodexCliEnhancementStatusReturn {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: systemSettingsKeys.codexCliEnhancement(),
|
||||||
|
queryFn: fetchCodexCliEnhancementStatus,
|
||||||
|
staleTime: STALE_TIME,
|
||||||
|
retry: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: query.data,
|
||||||
|
isLoading: query.isLoading,
|
||||||
|
error: query.error,
|
||||||
|
refetch: () => { query.refetch(); },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useToggleCodexCliEnhancement() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: (enabled: boolean) => toggleCodexCliEnhancement(enabled),
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: systemSettingsKeys.codexCliEnhancement() });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
toggle: mutation.mutateAsync,
|
||||||
|
isPending: mutation.isPending,
|
||||||
|
error: mutation.error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useRefreshCodexCliEnhancement() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const mutation = useMutation({
|
||||||
|
mutationFn: () => refreshCodexCliEnhancement(),
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: systemSettingsKeys.codexCliEnhancement() });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
refresh: mutation.mutateAsync,
|
||||||
|
isPending: mutation.isPending,
|
||||||
|
error: mutation.error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Aggregated Status / CCW Install Hooks
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
export interface UseCcwInstallStatusReturn {
|
||||||
|
data: CcwInstallStatus | undefined;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: Error | null;
|
||||||
|
refetch: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCcwInstallStatus(): UseCcwInstallStatusReturn {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: systemSettingsKeys.aggregatedStatus(),
|
||||||
|
queryFn: fetchAggregatedStatus,
|
||||||
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||||
|
retry: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: query.data?.ccwInstall,
|
||||||
|
isLoading: query.isLoading,
|
||||||
|
error: query.error,
|
||||||
|
refetch: () => { query.refetch(); },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// CLI Tool Status Hooks
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
export interface UseCliToolStatusReturn {
|
||||||
|
data: Record<string, { available: boolean; path?: string; version?: string }> | undefined;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: Error | null;
|
||||||
|
refetch: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useCliToolStatus(): UseCliToolStatusReturn {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: systemSettingsKeys.cliToolStatus(),
|
||||||
|
queryFn: fetchCliToolStatus,
|
||||||
|
staleTime: 2 * 60 * 1000, // 2 minutes
|
||||||
|
retry: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: query.data,
|
||||||
|
isLoading: query.isLoading,
|
||||||
|
error: query.error,
|
||||||
|
refetch: () => { query.refetch(); },
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -993,22 +993,36 @@ export interface SkillsResponse {
|
|||||||
* @param projectPath - Optional project path to filter data by workspace
|
* @param projectPath - Optional project path to filter data by workspace
|
||||||
*/
|
*/
|
||||||
export async function fetchSkills(projectPath?: string): Promise<SkillsResponse> {
|
export async function fetchSkills(projectPath?: string): Promise<SkillsResponse> {
|
||||||
|
// Response type from backend when includeDisabled=true
|
||||||
|
interface ExtendedSkillsResponse {
|
||||||
|
skills?: Skill[];
|
||||||
|
projectSkills?: Skill[];
|
||||||
|
userSkills?: Skill[];
|
||||||
|
disabledProjectSkills?: Skill[];
|
||||||
|
disabledUserSkills?: Skill[];
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to add location and enabled status to skills
|
// Helper to add location and enabled status to skills
|
||||||
// Backend only returns enabled skills (with SKILL.md), so we set enabled: true
|
const addEnabledMetadata = (skills: Skill[], location: 'project' | 'user'): Skill[] =>
|
||||||
const addMetadata = (skills: Skill[], location: 'project' | 'user'): Skill[] =>
|
|
||||||
skills.map(skill => ({ ...skill, location, enabled: true }));
|
skills.map(skill => ({ ...skill, location, enabled: true }));
|
||||||
|
|
||||||
|
const addDisabledMetadata = (skills: Skill[], location: 'project' | 'user'): Skill[] =>
|
||||||
|
skills.map(skill => ({ ...skill, location, enabled: false }));
|
||||||
|
|
||||||
|
const buildSkillsList = (data: ExtendedSkillsResponse): Skill[] => {
|
||||||
|
const projectSkillsEnabled = addEnabledMetadata(data.projectSkills ?? [], 'project');
|
||||||
|
const userSkillsEnabled = addEnabledMetadata(data.userSkills ?? [], 'user');
|
||||||
|
const projectSkillsDisabled = addDisabledMetadata(data.disabledProjectSkills ?? [], 'project');
|
||||||
|
const userSkillsDisabled = addDisabledMetadata(data.disabledUserSkills ?? [], 'user');
|
||||||
|
return [...projectSkillsEnabled, ...userSkillsEnabled, ...projectSkillsDisabled, ...userSkillsDisabled];
|
||||||
|
};
|
||||||
|
|
||||||
// Try with project path first, fall back to global on 403/404
|
// Try with project path first, fall back to global on 403/404
|
||||||
if (projectPath) {
|
if (projectPath) {
|
||||||
try {
|
try {
|
||||||
const url = `/api/skills?path=${encodeURIComponent(projectPath)}`;
|
const url = `/api/skills?path=${encodeURIComponent(projectPath)}&includeDisabled=true`;
|
||||||
const data = await fetchApi<{ skills?: Skill[]; projectSkills?: Skill[]; userSkills?: Skill[] }>(url);
|
const data = await fetchApi<ExtendedSkillsResponse>(url);
|
||||||
const projectSkillsWithMetadata = addMetadata(data.projectSkills ?? [], 'project');
|
return { skills: buildSkillsList(data) };
|
||||||
const userSkillsWithMetadata = addMetadata(data.userSkills ?? [], 'user');
|
|
||||||
const allSkills = [...projectSkillsWithMetadata, ...userSkillsWithMetadata];
|
|
||||||
return {
|
|
||||||
skills: data.skills ?? allSkills,
|
|
||||||
};
|
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const apiError = error as ApiError;
|
const apiError = error as ApiError;
|
||||||
if (apiError.status === 403 || apiError.status === 404) {
|
if (apiError.status === 403 || apiError.status === 404) {
|
||||||
@@ -1020,13 +1034,8 @@ export async function fetchSkills(projectPath?: string): Promise<SkillsResponse>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fallback: fetch global skills
|
// Fallback: fetch global skills
|
||||||
const data = await fetchApi<{ skills?: Skill[]; projectSkills?: Skill[]; userSkills?: Skill[] }>('/api/skills');
|
const data = await fetchApi<ExtendedSkillsResponse>('/api/skills?includeDisabled=true');
|
||||||
const projectSkillsWithMetadata = addMetadata(data.projectSkills ?? [], 'project');
|
return { skills: buildSkillsList(data) };
|
||||||
const userSkillsWithMetadata = addMetadata(data.userSkills ?? [], 'user');
|
|
||||||
const allSkills = [...projectSkillsWithMetadata, ...userSkillsWithMetadata];
|
|
||||||
return {
|
|
||||||
skills: data.skills ?? allSkills,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1074,6 +1083,38 @@ export async function fetchSkillDetail(
|
|||||||
return fetchApi<{ skill: Skill }>(url);
|
return fetchApi<{ skill: Skill }>(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a skill folder for import
|
||||||
|
*/
|
||||||
|
export async function validateSkillImport(sourcePath: string): Promise<{
|
||||||
|
valid: boolean;
|
||||||
|
errors?: string[];
|
||||||
|
skillInfo?: { name: string; description: string; version?: string; supportingFiles?: string[] };
|
||||||
|
}> {
|
||||||
|
return fetchApi('/api/skills/validate-import', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ sourcePath }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create/import a skill
|
||||||
|
*/
|
||||||
|
export async function createSkill(params: {
|
||||||
|
mode: 'import' | 'cli-generate';
|
||||||
|
location: 'project' | 'user';
|
||||||
|
sourcePath?: string;
|
||||||
|
skillName?: string;
|
||||||
|
description?: string;
|
||||||
|
generationType?: 'description' | 'template';
|
||||||
|
projectPath?: string;
|
||||||
|
}): Promise<{ skillName: string; path: string }> {
|
||||||
|
return fetchApi('/api/skills/create', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ========== Commands API ==========
|
// ========== Commands API ==========
|
||||||
|
|
||||||
export interface Command {
|
export interface Command {
|
||||||
@@ -5062,3 +5103,142 @@ export async function fetchExecutionLogs(
|
|||||||
const queryString = params.toString();
|
const queryString = params.toString();
|
||||||
return fetchApi(`/api/orchestrator/executions/${encodeURIComponent(execId)}/logs${queryString ? `?${queryString}` : ''}`);
|
return fetchApi(`/api/orchestrator/executions/${encodeURIComponent(execId)}/logs${queryString ? `?${queryString}` : ''}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== System Settings API ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chinese response setting status
|
||||||
|
*/
|
||||||
|
export interface ChineseResponseStatus {
|
||||||
|
enabled: boolean;
|
||||||
|
claudeEnabled: boolean;
|
||||||
|
codexEnabled: boolean;
|
||||||
|
codexNeedsMigration: boolean;
|
||||||
|
guidelinesPath: string;
|
||||||
|
guidelinesExists: boolean;
|
||||||
|
userClaudeMdExists: boolean;
|
||||||
|
userCodexAgentsExists: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Chinese response setting status
|
||||||
|
*/
|
||||||
|
export async function fetchChineseResponseStatus(): Promise<ChineseResponseStatus> {
|
||||||
|
return fetchApi('/api/language/chinese-response');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle Chinese response setting
|
||||||
|
*/
|
||||||
|
export async function toggleChineseResponse(
|
||||||
|
enabled: boolean,
|
||||||
|
target: 'claude' | 'codex' = 'claude'
|
||||||
|
): Promise<{ success: boolean; enabled: boolean; target: string }> {
|
||||||
|
return fetchApi('/api/language/chinese-response', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ enabled, target }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows platform setting status
|
||||||
|
*/
|
||||||
|
export interface WindowsPlatformStatus {
|
||||||
|
enabled: boolean;
|
||||||
|
guidelinesPath: string;
|
||||||
|
guidelinesExists: boolean;
|
||||||
|
userClaudeMdExists: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Windows platform setting status
|
||||||
|
*/
|
||||||
|
export async function fetchWindowsPlatformStatus(): Promise<WindowsPlatformStatus> {
|
||||||
|
return fetchApi('/api/language/windows-platform');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle Windows platform setting
|
||||||
|
*/
|
||||||
|
export async function toggleWindowsPlatform(
|
||||||
|
enabled: boolean
|
||||||
|
): Promise<{ success: boolean; enabled: boolean }> {
|
||||||
|
return fetchApi('/api/language/windows-platform', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ enabled }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Codex CLI Enhancement setting status
|
||||||
|
*/
|
||||||
|
export interface CodexCliEnhancementStatus {
|
||||||
|
enabled: boolean;
|
||||||
|
guidelinesPath: string;
|
||||||
|
guidelinesExists: boolean;
|
||||||
|
userCodexAgentsExists: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Codex CLI Enhancement setting status
|
||||||
|
*/
|
||||||
|
export async function fetchCodexCliEnhancementStatus(): Promise<CodexCliEnhancementStatus> {
|
||||||
|
return fetchApi('/api/language/codex-cli-enhancement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle Codex CLI Enhancement setting
|
||||||
|
*/
|
||||||
|
export async function toggleCodexCliEnhancement(
|
||||||
|
enabled: boolean
|
||||||
|
): Promise<{ success: boolean; enabled: boolean }> {
|
||||||
|
return fetchApi('/api/language/codex-cli-enhancement', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ enabled }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh Codex CLI Enhancement content
|
||||||
|
*/
|
||||||
|
export async function refreshCodexCliEnhancement(): Promise<{ success: boolean; refreshed: boolean }> {
|
||||||
|
return fetchApi('/api/language/codex-cli-enhancement', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ action: 'refresh' }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CCW Install status
|
||||||
|
*/
|
||||||
|
export interface CcwInstallStatus {
|
||||||
|
installed: boolean;
|
||||||
|
workflowsInstalled: boolean;
|
||||||
|
missingFiles: string[];
|
||||||
|
installPath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggregated status response
|
||||||
|
*/
|
||||||
|
export interface AggregatedStatus {
|
||||||
|
cli: Record<string, { available: boolean; path?: string; version?: string }>;
|
||||||
|
codexLens: { ready: boolean };
|
||||||
|
semantic: { available: boolean; backend: string | null };
|
||||||
|
ccwInstall: CcwInstallStatus;
|
||||||
|
timestamp: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch aggregated system status (includes CCW install status)
|
||||||
|
*/
|
||||||
|
export async function fetchAggregatedStatus(): Promise<AggregatedStatus> {
|
||||||
|
return fetchApi('/api/status/all');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch CLI tool availability status
|
||||||
|
*/
|
||||||
|
export async function fetchCliToolStatus(): Promise<Record<string, { available: boolean; path?: string; version?: string }>> {
|
||||||
|
return fetchApi('/api/cli/status');
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
"cliTools": "CLI Tools",
|
"cliTools": "CLI Tools",
|
||||||
"display": "Display Settings",
|
"display": "Display Settings",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
|
"responseLanguage": "Response Language",
|
||||||
|
"systemStatus": "System Status",
|
||||||
"hooks": "Git Hooks",
|
"hooks": "Git Hooks",
|
||||||
"rules": "Rules",
|
"rules": "Rules",
|
||||||
"about": "About"
|
"about": "About"
|
||||||
@@ -48,6 +50,35 @@
|
|||||||
"displayLanguage": "Display Language",
|
"displayLanguage": "Display Language",
|
||||||
"chooseLanguage": "Choose your preferred language for the interface"
|
"chooseLanguage": "Choose your preferred language for the interface"
|
||||||
},
|
},
|
||||||
|
"responseLanguage": {
|
||||||
|
"title": "Response Language Settings",
|
||||||
|
"chineseClaude": "Chinese Response",
|
||||||
|
"chineseClaudeDesc": "Enable Chinese response guidelines in ~/.claude/CLAUDE.md",
|
||||||
|
"chineseCodex": "Chinese Response",
|
||||||
|
"chineseCodexDesc": "Enable Chinese response guidelines in ~/.codex/AGENTS.md",
|
||||||
|
"windowsPlatform": "Windows Platform",
|
||||||
|
"windowsPlatformDesc": "Enable Windows path format conventions in global CLAUDE.md",
|
||||||
|
"cliEnhancement": "CLI Enhancement",
|
||||||
|
"cliEnhancementDesc": "Enable multi-CLI tool invocation for Codex",
|
||||||
|
"cliEnhancementHint": "After config changes, click refresh to update content",
|
||||||
|
"refreshConfig": "Refresh Config",
|
||||||
|
"migrationWarning": "Old format detected, please disable and re-enable to migrate",
|
||||||
|
"enabled": "Enabled",
|
||||||
|
"disabled": "Disabled"
|
||||||
|
},
|
||||||
|
"systemStatus": {
|
||||||
|
"title": "System Status",
|
||||||
|
"ccwInstall": "CCW Installation",
|
||||||
|
"installed": "Installed",
|
||||||
|
"incomplete": "Incomplete",
|
||||||
|
"notInstalled": "Not Installed",
|
||||||
|
"missingFiles": "Missing Files",
|
||||||
|
"runToFix": "Run to fix",
|
||||||
|
"toolStatus": "Tool Availability",
|
||||||
|
"available": "Available",
|
||||||
|
"unavailable": "Unavailable",
|
||||||
|
"checking": "Checking..."
|
||||||
|
},
|
||||||
"dataRefresh": {
|
"dataRefresh": {
|
||||||
"title": "Data Refresh",
|
"title": "Data Refresh",
|
||||||
"autoRefresh": "Auto Refresh",
|
"autoRefresh": "Auto Refresh",
|
||||||
|
|||||||
@@ -65,5 +65,45 @@
|
|||||||
"emptyState": {
|
"emptyState": {
|
||||||
"title": "No Skills Found",
|
"title": "No Skills Found",
|
||||||
"message": "No skills match your current filter."
|
"message": "No skills match your current filter."
|
||||||
|
},
|
||||||
|
"create": {
|
||||||
|
"title": "Create Skill",
|
||||||
|
"location": "Location",
|
||||||
|
"locationProject": "Project Skills",
|
||||||
|
"locationProjectHint": ".claude/skills/",
|
||||||
|
"locationUser": "Global Skills",
|
||||||
|
"locationUserHint": "~/.claude/skills/",
|
||||||
|
"mode": "Creation Mode",
|
||||||
|
"modeImport": "Import Folder",
|
||||||
|
"modeImportHint": "Import skill from existing folder",
|
||||||
|
"modeGenerate": "AI Generate",
|
||||||
|
"modeGenerateHint": "Generate skill using AI",
|
||||||
|
"sourcePath": "Source Folder Path",
|
||||||
|
"sourcePathPlaceholder": "Enter absolute path to skill folder",
|
||||||
|
"sourcePathHint": "Folder must contain a SKILL.md file",
|
||||||
|
"customName": "Custom Name",
|
||||||
|
"customNamePlaceholder": "Leave empty to use original name",
|
||||||
|
"customNameHint": "Optional, overrides default skill name",
|
||||||
|
"skillName": "Skill Name",
|
||||||
|
"skillNamePlaceholder": "Enter skill name",
|
||||||
|
"skillNameHint": "Used as the skill folder name",
|
||||||
|
"descriptionLabel": "Skill Description",
|
||||||
|
"descriptionPlaceholder": "Describe what this skill should do...",
|
||||||
|
"descriptionHint": "AI will generate skill content based on this description",
|
||||||
|
"generateInfo": "AI will use CLI tools to generate the skill",
|
||||||
|
"generateTimeHint": "Generation may take some time",
|
||||||
|
"validate": "Validate",
|
||||||
|
"import": "Import",
|
||||||
|
"generate": "Generate",
|
||||||
|
"validating": "Validating...",
|
||||||
|
"validSkill": "Validation passed",
|
||||||
|
"invalidSkill": "Validation failed",
|
||||||
|
"creating": "Creating...",
|
||||||
|
"created": "Skill \"{name}\" created successfully",
|
||||||
|
"createError": "Failed to create skill",
|
||||||
|
"sourcePathRequired": "Please enter source folder path",
|
||||||
|
"skillNameRequired": "Please enter skill name",
|
||||||
|
"descriptionRequired": "Please enter skill description",
|
||||||
|
"validateFirst": "Please validate the skill folder first"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
"cliTools": "CLI 工具",
|
"cliTools": "CLI 工具",
|
||||||
"display": "显示设置",
|
"display": "显示设置",
|
||||||
"language": "语言",
|
"language": "语言",
|
||||||
|
"responseLanguage": "回复语言设置",
|
||||||
|
"systemStatus": "系统状态",
|
||||||
"hooks": "Git 钩子",
|
"hooks": "Git 钩子",
|
||||||
"rules": "规则",
|
"rules": "规则",
|
||||||
"about": "关于"
|
"about": "关于"
|
||||||
@@ -48,6 +50,35 @@
|
|||||||
"displayLanguage": "显示语言",
|
"displayLanguage": "显示语言",
|
||||||
"chooseLanguage": "选择界面的首选语言"
|
"chooseLanguage": "选择界面的首选语言"
|
||||||
},
|
},
|
||||||
|
"responseLanguage": {
|
||||||
|
"title": "回复语言设置",
|
||||||
|
"chineseClaude": "中文回复",
|
||||||
|
"chineseClaudeDesc": "在 ~/.claude/CLAUDE.md 中启用中文回复准则",
|
||||||
|
"chineseCodex": "中文回复",
|
||||||
|
"chineseCodexDesc": "在 ~/.codex/AGENTS.md 中启用中文回复准则",
|
||||||
|
"windowsPlatform": "Windows 平台规范",
|
||||||
|
"windowsPlatformDesc": "在全局 CLAUDE.md 中启用 Windows 路径格式规范",
|
||||||
|
"cliEnhancement": "CLI 调用增强",
|
||||||
|
"cliEnhancementDesc": "为 Codex 启用多 CLI 工具调用功能",
|
||||||
|
"cliEnhancementHint": "配置文件变更后,点击刷新按钮更新内容",
|
||||||
|
"refreshConfig": "刷新配置",
|
||||||
|
"migrationWarning": "检测到旧格式,请关闭后重新启用以迁移",
|
||||||
|
"enabled": "已启用",
|
||||||
|
"disabled": "已禁用"
|
||||||
|
},
|
||||||
|
"systemStatus": {
|
||||||
|
"title": "系统状态",
|
||||||
|
"ccwInstall": "CCW 安装状态",
|
||||||
|
"installed": "已安装",
|
||||||
|
"incomplete": "不完整",
|
||||||
|
"notInstalled": "未安装",
|
||||||
|
"missingFiles": "缺失文件",
|
||||||
|
"runToFix": "运行以下命令修复",
|
||||||
|
"toolStatus": "工具可用性",
|
||||||
|
"available": "可用",
|
||||||
|
"unavailable": "不可用",
|
||||||
|
"checking": "检测中..."
|
||||||
|
},
|
||||||
"dataRefresh": {
|
"dataRefresh": {
|
||||||
"title": "数据刷新",
|
"title": "数据刷新",
|
||||||
"autoRefresh": "自动刷新",
|
"autoRefresh": "自动刷新",
|
||||||
|
|||||||
@@ -65,5 +65,45 @@
|
|||||||
"emptyState": {
|
"emptyState": {
|
||||||
"title": "未找到技能",
|
"title": "未找到技能",
|
||||||
"message": "没有符合当前筛选条件的技能。"
|
"message": "没有符合当前筛选条件的技能。"
|
||||||
|
},
|
||||||
|
"create": {
|
||||||
|
"title": "创建技能",
|
||||||
|
"location": "存储位置",
|
||||||
|
"locationProject": "项目技能",
|
||||||
|
"locationProjectHint": ".claude/skills/",
|
||||||
|
"locationUser": "全局技能",
|
||||||
|
"locationUserHint": "~/.claude/skills/",
|
||||||
|
"mode": "创建方式",
|
||||||
|
"modeImport": "导入文件夹",
|
||||||
|
"modeImportHint": "从现有文件夹导入技能",
|
||||||
|
"modeGenerate": "AI 生成",
|
||||||
|
"modeGenerateHint": "使用 AI 生成技能",
|
||||||
|
"sourcePath": "源文件夹路径",
|
||||||
|
"sourcePathPlaceholder": "输入技能文件夹的绝对路径",
|
||||||
|
"sourcePathHint": "文件夹中需要包含 SKILL.md 文件",
|
||||||
|
"customName": "自定义名称",
|
||||||
|
"customNamePlaceholder": "留空则使用原始名称",
|
||||||
|
"customNameHint": "可选,用于覆盖默认技能名称",
|
||||||
|
"skillName": "技能名称",
|
||||||
|
"skillNamePlaceholder": "输入技能名称",
|
||||||
|
"skillNameHint": "用作技能文件夹名称",
|
||||||
|
"descriptionLabel": "技能描述",
|
||||||
|
"descriptionPlaceholder": "描述这个技能应该做什么...",
|
||||||
|
"descriptionHint": "AI 将根据描述生成技能内容",
|
||||||
|
"generateInfo": "AI 将使用 CLI 工具生成技能",
|
||||||
|
"generateTimeHint": "生成过程可能需要一些时间",
|
||||||
|
"validate": "验证",
|
||||||
|
"import": "导入",
|
||||||
|
"generate": "生成",
|
||||||
|
"validating": "验证中...",
|
||||||
|
"validSkill": "验证通过",
|
||||||
|
"invalidSkill": "验证失败",
|
||||||
|
"creating": "创建中...",
|
||||||
|
"created": "技能 \"{name}\" 创建成功",
|
||||||
|
"createError": "创建技能失败",
|
||||||
|
"sourcePathRequired": "请输入源文件夹路径",
|
||||||
|
"skillNameRequired": "请输入技能名称",
|
||||||
|
"descriptionRequired": "请输入技能描述",
|
||||||
|
"validateFirst": "请先验证技能文件夹"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
Trash2,
|
Trash2,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronUp,
|
ChevronUp,
|
||||||
|
BookmarkPlus,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
@@ -29,20 +30,21 @@ import { McpServerDialog } from '@/components/mcp/McpServerDialog';
|
|||||||
import { CliModeToggle, type CliMode } from '@/components/mcp/CliModeToggle';
|
import { CliModeToggle, type CliMode } from '@/components/mcp/CliModeToggle';
|
||||||
import { CodexMcpEditableCard } from '@/components/mcp/CodexMcpEditableCard';
|
import { CodexMcpEditableCard } from '@/components/mcp/CodexMcpEditableCard';
|
||||||
import { CcwToolsMcpCard } from '@/components/mcp/CcwToolsMcpCard';
|
import { CcwToolsMcpCard } from '@/components/mcp/CcwToolsMcpCard';
|
||||||
import { McpTemplatesSection } from '@/components/mcp/McpTemplatesSection';
|
import { McpTemplatesSection, TemplateSaveDialog } from '@/components/mcp/McpTemplatesSection';
|
||||||
import { RecommendedMcpSection } from '@/components/mcp/RecommendedMcpSection';
|
import { RecommendedMcpSection } from '@/components/mcp/RecommendedMcpSection';
|
||||||
import { WindowsCompatibilityWarning } from '@/components/mcp/WindowsCompatibilityWarning';
|
import { WindowsCompatibilityWarning } from '@/components/mcp/WindowsCompatibilityWarning';
|
||||||
import { CrossCliCopyButton } from '@/components/mcp/CrossCliCopyButton';
|
import { CrossCliCopyButton } from '@/components/mcp/CrossCliCopyButton';
|
||||||
import { AllProjectsTable } from '@/components/mcp/AllProjectsTable';
|
import { AllProjectsTable } from '@/components/mcp/AllProjectsTable';
|
||||||
import { OtherProjectsSection } from '@/components/mcp/OtherProjectsSection';
|
import { OtherProjectsSection } from '@/components/mcp/OtherProjectsSection';
|
||||||
import { TabsNavigation } from '@/components/ui/TabsNavigation';
|
import { TabsNavigation } from '@/components/ui/TabsNavigation';
|
||||||
import { useMcpServers, useMcpServerMutations } from '@/hooks';
|
import { useMcpServers, useMcpServerMutations, useNotifications } from '@/hooks';
|
||||||
import {
|
import {
|
||||||
fetchCodexMcpServers,
|
fetchCodexMcpServers,
|
||||||
fetchCcwMcpConfig,
|
fetchCcwMcpConfig,
|
||||||
updateCcwConfig,
|
updateCcwConfig,
|
||||||
codexRemoveServer,
|
codexRemoveServer,
|
||||||
codexToggleServer,
|
codexToggleServer,
|
||||||
|
saveMcpTemplate,
|
||||||
type McpServer,
|
type McpServer,
|
||||||
type CcwMcpConfig,
|
type CcwMcpConfig,
|
||||||
} from '@/lib/api';
|
} from '@/lib/api';
|
||||||
@@ -57,9 +59,10 @@ interface McpServerCardProps {
|
|||||||
onToggle: (serverName: string, enabled: boolean) => void;
|
onToggle: (serverName: string, enabled: boolean) => void;
|
||||||
onEdit: (server: McpServer) => void;
|
onEdit: (server: McpServer) => void;
|
||||||
onDelete: (server: McpServer) => void;
|
onDelete: (server: McpServer) => void;
|
||||||
|
onSaveAsTemplate: (server: McpServer) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function McpServerCard({ server, isExpanded, onToggleExpand, onToggle, onEdit, onDelete }: McpServerCardProps) {
|
function McpServerCard({ server, isExpanded, onToggleExpand, onToggle, onEdit, onDelete, onSaveAsTemplate }: McpServerCardProps) {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -115,6 +118,18 @@ function McpServerCard({ server, isExpanded, onToggleExpand, onToggle, onEdit, o
|
|||||||
>
|
>
|
||||||
{server.enabled ? <Power className="w-4 h-4 text-green-600" /> : <PowerOff className="w-4 h-4" />}
|
{server.enabled ? <Power className="w-4 h-4 text-green-600" /> : <PowerOff className="w-4 h-4" />}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="h-8 w-8 p-0"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onSaveAsTemplate(server);
|
||||||
|
}}
|
||||||
|
title={formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}
|
||||||
|
>
|
||||||
|
<BookmarkPlus className="w-4 h-4 text-primary" />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -206,6 +221,10 @@ export function McpManagerPage() {
|
|||||||
const [editingServer, setEditingServer] = useState<McpServer | undefined>(undefined);
|
const [editingServer, setEditingServer] = useState<McpServer | undefined>(undefined);
|
||||||
const [cliMode, setCliMode] = useState<CliMode>('claude');
|
const [cliMode, setCliMode] = useState<CliMode>('claude');
|
||||||
const [codexExpandedServers, setCodexExpandedServers] = useState<Set<string>>(new Set());
|
const [codexExpandedServers, setCodexExpandedServers] = useState<Set<string>>(new Set());
|
||||||
|
const [saveTemplateDialogOpen, setSaveTemplateDialogOpen] = useState(false);
|
||||||
|
const [serverToSaveAsTemplate, setServerToSaveAsTemplate] = useState<McpServer | undefined>(undefined);
|
||||||
|
|
||||||
|
const notifications = useNotifications();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
servers,
|
servers,
|
||||||
@@ -269,9 +288,22 @@ export function McpManagerPage() {
|
|||||||
toggleServer(serverName, enabled);
|
toggleServer(serverName, enabled);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (server: McpServer) => {
|
const handleDelete = async (server: McpServer) => {
|
||||||
if (confirm(formatMessage({ id: 'mcp.deleteConfirm' }, { name: server.name }))) {
|
if (confirm(formatMessage({ id: 'mcp.deleteConfirm' }, { name: server.name }))) {
|
||||||
deleteServer(server.name, server.scope);
|
try {
|
||||||
|
await deleteServer(server.name, server.scope);
|
||||||
|
notifications.success(
|
||||||
|
formatMessage({ id: 'mcp.actions.delete' }),
|
||||||
|
server.name
|
||||||
|
);
|
||||||
|
refetch();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to delete MCP server:', error);
|
||||||
|
notifications.error(
|
||||||
|
formatMessage({ id: 'mcp.actions.delete' }),
|
||||||
|
error instanceof Error ? error.message : String(error)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -339,19 +371,64 @@ export function McpManagerPage() {
|
|||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveAsTemplate = (serverName: string, config: { command: string; args: string[] }) => {
|
const handleSaveServerAsTemplate = (server: McpServer) => {
|
||||||
// This would open a dialog to save current server as template
|
setServerToSaveAsTemplate(server);
|
||||||
// For now, just log it
|
setSaveTemplateDialogOpen(true);
|
||||||
console.log('Save as template:', serverName, config);
|
};
|
||||||
|
|
||||||
|
const handleSaveAsTemplate = async (
|
||||||
|
name: string,
|
||||||
|
category: string,
|
||||||
|
description: string,
|
||||||
|
serverConfig: { command: string; args: string[]; env: Record<string, string> },
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const result = await saveMcpTemplate({
|
||||||
|
name,
|
||||||
|
description: description || undefined,
|
||||||
|
category: category || 'custom',
|
||||||
|
serverConfig: {
|
||||||
|
command: serverConfig.command,
|
||||||
|
args: serverConfig.args.length > 0 ? serverConfig.args : undefined,
|
||||||
|
env: Object.keys(serverConfig.env).length > 0 ? serverConfig.env : undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.success) {
|
||||||
|
notifications.success(
|
||||||
|
formatMessage({ id: 'mcp.templates.feedback.saveSuccess' }),
|
||||||
|
name
|
||||||
|
);
|
||||||
|
setSaveTemplateDialogOpen(false);
|
||||||
|
setServerToSaveAsTemplate(undefined);
|
||||||
|
} else {
|
||||||
|
notifications.error(
|
||||||
|
formatMessage({ id: 'mcp.templates.feedback.saveError' }),
|
||||||
|
result.error || ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notifications.error(
|
||||||
|
formatMessage({ id: 'mcp.templates.feedback.saveError' }),
|
||||||
|
error instanceof Error ? error.message : String(error)
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Codex MCP handlers
|
// Codex MCP handlers
|
||||||
const handleCodexRemove = async (serverName: string) => {
|
const handleCodexRemove = async (serverName: string) => {
|
||||||
try {
|
try {
|
||||||
await codexRemoveServer(serverName);
|
await codexRemoveServer(serverName);
|
||||||
|
notifications.success(
|
||||||
|
formatMessage({ id: 'mcp.actions.delete' }),
|
||||||
|
serverName
|
||||||
|
);
|
||||||
codexQuery.refetch();
|
codexQuery.refetch();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to remove Codex MCP server:', error);
|
console.error('Failed to remove Codex MCP server:', error);
|
||||||
|
notifications.error(
|
||||||
|
formatMessage({ id: 'mcp.actions.delete' }),
|
||||||
|
error instanceof Error ? error.message : String(error)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -592,6 +669,7 @@ export function McpManagerPage() {
|
|||||||
onToggle={handleToggle}
|
onToggle={handleToggle}
|
||||||
onEdit={handleEdit}
|
onEdit={handleEdit}
|
||||||
onDelete={handleDelete}
|
onDelete={handleDelete}
|
||||||
|
onSaveAsTemplate={handleSaveServerAsTemplate}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
))}
|
))}
|
||||||
@@ -646,6 +724,20 @@ export function McpManagerPage() {
|
|||||||
onSave={handleDialogSave}
|
onSave={handleDialogSave}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Save as Template Dialog */}
|
||||||
|
<TemplateSaveDialog
|
||||||
|
open={saveTemplateDialogOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setSaveTemplateDialogOpen(false);
|
||||||
|
setServerToSaveAsTemplate(undefined);
|
||||||
|
}}
|
||||||
|
onSave={handleSaveAsTemplate}
|
||||||
|
defaultName={serverToSaveAsTemplate?.name}
|
||||||
|
defaultCommand={serverToSaveAsTemplate?.command}
|
||||||
|
defaultArgs={serverToSaveAsTemplate?.args}
|
||||||
|
defaultEnv={serverToSaveAsTemplate?.env as Record<string, string>}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ import {
|
|||||||
ChevronUp,
|
ChevronUp,
|
||||||
Languages,
|
Languages,
|
||||||
Plus,
|
Plus,
|
||||||
|
MessageSquareText,
|
||||||
|
Monitor,
|
||||||
|
Terminal,
|
||||||
|
AlertTriangle,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
@@ -29,6 +33,17 @@ import { useConfigStore, selectCliTools, selectDefaultCliTool, selectUserPrefere
|
|||||||
import type { CliToolConfig, UserPreferences } from '@/types/store';
|
import type { CliToolConfig, UserPreferences } from '@/types/store';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { LanguageSwitcher } from '@/components/layout/LanguageSwitcher';
|
import { LanguageSwitcher } from '@/components/layout/LanguageSwitcher';
|
||||||
|
import {
|
||||||
|
useChineseResponseStatus,
|
||||||
|
useToggleChineseResponse,
|
||||||
|
useWindowsPlatformStatus,
|
||||||
|
useToggleWindowsPlatform,
|
||||||
|
useCodexCliEnhancementStatus,
|
||||||
|
useToggleCodexCliEnhancement,
|
||||||
|
useRefreshCodexCliEnhancement,
|
||||||
|
useCcwInstallStatus,
|
||||||
|
useCliToolStatus,
|
||||||
|
} from '@/hooks/useSystemSettings';
|
||||||
|
|
||||||
// ========== CLI Tool Card Component ==========
|
// ========== CLI Tool Card Component ==========
|
||||||
|
|
||||||
@@ -37,6 +52,7 @@ interface CliToolCardProps {
|
|||||||
config: CliToolConfig;
|
config: CliToolConfig;
|
||||||
isDefault: boolean;
|
isDefault: boolean;
|
||||||
isExpanded: boolean;
|
isExpanded: boolean;
|
||||||
|
toolAvailable?: boolean;
|
||||||
onToggleExpand: () => void;
|
onToggleExpand: () => void;
|
||||||
onToggleEnabled: () => void;
|
onToggleEnabled: () => void;
|
||||||
onSetDefault: () => void;
|
onSetDefault: () => void;
|
||||||
@@ -51,6 +67,7 @@ function CliToolCard({
|
|||||||
config,
|
config,
|
||||||
isDefault,
|
isDefault,
|
||||||
isExpanded,
|
isExpanded,
|
||||||
|
toolAvailable,
|
||||||
onToggleExpand,
|
onToggleExpand,
|
||||||
onToggleEnabled,
|
onToggleEnabled,
|
||||||
onSetDefault,
|
onSetDefault,
|
||||||
@@ -125,6 +142,12 @@ function CliToolCard({
|
|||||||
<Badge variant="default" className="text-xs">{formatMessage({ id: 'settings.cliTools.default' })}</Badge>
|
<Badge variant="default" className="text-xs">{formatMessage({ id: 'settings.cliTools.default' })}</Badge>
|
||||||
)}
|
)}
|
||||||
<Badge variant="outline" className="text-xs">{config.type}</Badge>
|
<Badge variant="outline" className="text-xs">{config.type}</Badge>
|
||||||
|
{toolAvailable !== undefined && (
|
||||||
|
<span className={cn(
|
||||||
|
'inline-block w-2 h-2 rounded-full',
|
||||||
|
toolAvailable ? 'bg-green-500' : 'bg-red-400'
|
||||||
|
)} title={toolAvailable ? 'Available' : 'Unavailable'} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5">
|
<p className="text-xs text-muted-foreground mt-0.5">
|
||||||
{config.primaryModel}
|
{config.primaryModel}
|
||||||
@@ -345,6 +368,266 @@ function CliToolCard({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== Response Language Section ==========
|
||||||
|
|
||||||
|
function ResponseLanguageSection() {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const { data: chineseStatus, isLoading: chineseLoading } = useChineseResponseStatus();
|
||||||
|
const { toggle: toggleChinese, isPending: chineseToggling } = useToggleChineseResponse();
|
||||||
|
const { data: windowsStatus, isLoading: windowsLoading } = useWindowsPlatformStatus();
|
||||||
|
const { toggle: toggleWindows, isPending: windowsToggling } = useToggleWindowsPlatform();
|
||||||
|
const { data: cliEnhStatus, isLoading: cliEnhLoading } = useCodexCliEnhancementStatus();
|
||||||
|
const { toggle: toggleCliEnh, isPending: cliEnhToggling } = useToggleCodexCliEnhancement();
|
||||||
|
const { refresh: refreshCliEnh, isPending: refreshing } = useRefreshCodexCliEnhancement();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="p-6">
|
||||||
|
<h2 className="text-lg font-semibold text-foreground flex items-center gap-2 mb-4">
|
||||||
|
<MessageSquareText className="w-5 h-5" />
|
||||||
|
{formatMessage({ id: 'settings.sections.responseLanguage' })}
|
||||||
|
</h2>
|
||||||
|
<div className="grid gap-4 md:grid-cols-2">
|
||||||
|
{/* Chinese Response - Claude */}
|
||||||
|
<div className="rounded-lg border border-border p-4 space-y-2">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm font-medium">{formatMessage({ id: 'settings.responseLanguage.chineseClaude' })}</span>
|
||||||
|
<Badge variant="default" className="text-xs">Claude</Badge>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant={chineseStatus?.claudeEnabled ? 'default' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
className="h-7"
|
||||||
|
disabled={chineseLoading || chineseToggling}
|
||||||
|
onClick={() => toggleChinese(!chineseStatus?.claudeEnabled, 'claude')}
|
||||||
|
>
|
||||||
|
{chineseStatus?.claudeEnabled
|
||||||
|
? formatMessage({ id: 'settings.responseLanguage.enabled' })
|
||||||
|
: formatMessage({ id: 'settings.responseLanguage.disabled' })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{formatMessage({ id: 'settings.responseLanguage.chineseClaudeDesc' })}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Chinese Response - Codex */}
|
||||||
|
<div className="rounded-lg border border-border p-4 space-y-2">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm font-medium">{formatMessage({ id: 'settings.responseLanguage.chineseCodex' })}</span>
|
||||||
|
<Badge variant="secondary" className="text-xs">Codex</Badge>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant={chineseStatus?.codexEnabled ? 'default' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
className="h-7"
|
||||||
|
disabled={chineseLoading || chineseToggling}
|
||||||
|
onClick={() => toggleChinese(!chineseStatus?.codexEnabled, 'codex')}
|
||||||
|
>
|
||||||
|
{chineseStatus?.codexEnabled
|
||||||
|
? formatMessage({ id: 'settings.responseLanguage.enabled' })
|
||||||
|
: formatMessage({ id: 'settings.responseLanguage.disabled' })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{formatMessage({ id: 'settings.responseLanguage.chineseCodexDesc' })}
|
||||||
|
</p>
|
||||||
|
{chineseStatus?.codexNeedsMigration && (
|
||||||
|
<p className="text-xs text-yellow-500">
|
||||||
|
<AlertTriangle className="w-3 h-3 inline mr-1" />
|
||||||
|
{formatMessage({ id: 'settings.responseLanguage.migrationWarning' })}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Windows Platform */}
|
||||||
|
<div className="rounded-lg border border-border p-4 space-y-2">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Monitor className="w-4 h-4 text-muted-foreground" />
|
||||||
|
<span className="text-sm font-medium">{formatMessage({ id: 'settings.responseLanguage.windowsPlatform' })}</span>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant={windowsStatus?.enabled ? 'default' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
className="h-7"
|
||||||
|
disabled={windowsLoading || windowsToggling}
|
||||||
|
onClick={() => toggleWindows(!windowsStatus?.enabled)}
|
||||||
|
>
|
||||||
|
{windowsStatus?.enabled
|
||||||
|
? formatMessage({ id: 'settings.responseLanguage.enabled' })
|
||||||
|
: formatMessage({ id: 'settings.responseLanguage.disabled' })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{formatMessage({ id: 'settings.responseLanguage.windowsPlatformDesc' })}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* CLI Enhancement - Codex */}
|
||||||
|
<div className="rounded-lg border border-border p-4 space-y-2">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Terminal className="w-4 h-4 text-muted-foreground" />
|
||||||
|
<span className="text-sm font-medium">{formatMessage({ id: 'settings.responseLanguage.cliEnhancement' })}</span>
|
||||||
|
<Badge variant="secondary" className="text-xs">Codex</Badge>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
{cliEnhStatus?.enabled && (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="h-7 w-7 p-0"
|
||||||
|
disabled={cliEnhLoading || refreshing}
|
||||||
|
onClick={() => refreshCliEnh()}
|
||||||
|
title={formatMessage({ id: 'settings.responseLanguage.refreshConfig' })}
|
||||||
|
>
|
||||||
|
<RefreshCw className={cn('w-3.5 h-3.5', refreshing && 'animate-spin')} />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
variant={cliEnhStatus?.enabled ? 'default' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
className="h-7"
|
||||||
|
disabled={cliEnhLoading || cliEnhToggling}
|
||||||
|
onClick={() => toggleCliEnh(!cliEnhStatus?.enabled)}
|
||||||
|
>
|
||||||
|
{cliEnhStatus?.enabled
|
||||||
|
? formatMessage({ id: 'settings.responseLanguage.enabled' })
|
||||||
|
: formatMessage({ id: 'settings.responseLanguage.disabled' })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{formatMessage({ id: 'settings.responseLanguage.cliEnhancementDesc' })}
|
||||||
|
</p>
|
||||||
|
{cliEnhStatus?.enabled && (
|
||||||
|
<p className="text-xs text-muted-foreground/70">
|
||||||
|
{formatMessage({ id: 'settings.responseLanguage.cliEnhancementHint' })}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== System Status Section ==========
|
||||||
|
|
||||||
|
function SystemStatusSection() {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const { data: ccwInstall, isLoading: installLoading } = useCcwInstallStatus();
|
||||||
|
|
||||||
|
// Don't show if installed or still loading
|
||||||
|
if (installLoading || ccwInstall?.installed) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="p-6 border-yellow-500/50">
|
||||||
|
<h2 className="text-lg font-semibold text-foreground flex items-center gap-2 mb-4">
|
||||||
|
<AlertTriangle className="w-5 h-5 text-yellow-500" />
|
||||||
|
{formatMessage({ id: 'settings.systemStatus.title' })}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{/* CCW Install Status */}
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-sm font-medium">{formatMessage({ id: 'settings.systemStatus.ccwInstall' })}</span>
|
||||||
|
<Badge variant="outline" className="text-yellow-500 border-yellow-500/50">
|
||||||
|
{formatMessage({ id: 'settings.systemStatus.incomplete' })}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ccwInstall && ccwInstall.missingFiles.length > 0 && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{formatMessage({ id: 'settings.systemStatus.missingFiles' })}:
|
||||||
|
</p>
|
||||||
|
<ul className="text-xs text-muted-foreground/70 list-disc list-inside">
|
||||||
|
{ccwInstall.missingFiles.slice(0, 5).map((file) => (
|
||||||
|
<li key={file}>{file}</li>
|
||||||
|
))}
|
||||||
|
{ccwInstall.missingFiles.length > 5 && (
|
||||||
|
<li>+{ccwInstall.missingFiles.length - 5} more...</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
<div className="bg-muted/50 rounded-md p-3 mt-2">
|
||||||
|
<p className="text-xs font-medium mb-1">
|
||||||
|
{formatMessage({ id: 'settings.systemStatus.runToFix' })}:
|
||||||
|
</p>
|
||||||
|
<code className="text-xs bg-background px-2 py-1 rounded block font-mono">
|
||||||
|
ccw install
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== CLI Tools with Status Enhancement ==========
|
||||||
|
|
||||||
|
interface CliToolsWithStatusProps {
|
||||||
|
cliTools: Record<string, CliToolConfig>;
|
||||||
|
defaultCliTool: string;
|
||||||
|
expandedTools: Set<string>;
|
||||||
|
onToggleExpand: (toolId: string) => void;
|
||||||
|
onToggleEnabled: (toolId: string) => void;
|
||||||
|
onSetDefault: (toolId: string) => void;
|
||||||
|
onUpdateModel: (toolId: string, field: 'primaryModel' | 'secondaryModel', value: string) => void;
|
||||||
|
onUpdateTags: (toolId: string, tags: string[]) => void;
|
||||||
|
onUpdateAvailableModels: (toolId: string, models: string[]) => void;
|
||||||
|
onUpdateSettingsFile: (toolId: string, settingsFile: string | undefined) => void;
|
||||||
|
formatMessage: ReturnType<typeof useIntl>['formatMessage'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function CliToolsWithStatus({
|
||||||
|
cliTools,
|
||||||
|
defaultCliTool,
|
||||||
|
expandedTools,
|
||||||
|
onToggleExpand,
|
||||||
|
onToggleEnabled,
|
||||||
|
onSetDefault,
|
||||||
|
onUpdateModel,
|
||||||
|
onUpdateTags,
|
||||||
|
onUpdateAvailableModels,
|
||||||
|
onUpdateSettingsFile,
|
||||||
|
formatMessage,
|
||||||
|
}: CliToolsWithStatusProps) {
|
||||||
|
const { data: toolStatus } = useCliToolStatus();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className="text-sm text-muted-foreground mb-4">
|
||||||
|
{formatMessage({ id: 'settings.cliTools.description' })} <strong className="text-foreground">{defaultCliTool}</strong>
|
||||||
|
</p>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{Object.entries(cliTools).map(([toolId, config]) => {
|
||||||
|
const status = toolStatus?.[toolId];
|
||||||
|
return (
|
||||||
|
<CliToolCard
|
||||||
|
key={toolId}
|
||||||
|
toolId={toolId}
|
||||||
|
config={config}
|
||||||
|
isDefault={toolId === defaultCliTool}
|
||||||
|
isExpanded={expandedTools.has(toolId)}
|
||||||
|
toolAvailable={status?.available}
|
||||||
|
onToggleExpand={() => onToggleExpand(toolId)}
|
||||||
|
onToggleEnabled={() => onToggleEnabled(toolId)}
|
||||||
|
onSetDefault={() => onSetDefault(toolId)}
|
||||||
|
onUpdateModel={(field, value) => onUpdateModel(toolId, field, value)}
|
||||||
|
onUpdateTags={(tags) => onUpdateTags(toolId, tags)}
|
||||||
|
onUpdateAvailableModels={(models) => onUpdateAvailableModels(toolId, models)}
|
||||||
|
onUpdateSettingsFile={(settingsFile) => onUpdateSettingsFile(toolId, settingsFile)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ========== Main Page Component ==========
|
// ========== Main Page Component ==========
|
||||||
|
|
||||||
export function SettingsPage() {
|
export function SettingsPage() {
|
||||||
@@ -466,33 +749,31 @@ export function SettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
{/* Response Language Settings */}
|
||||||
|
<ResponseLanguageSection />
|
||||||
|
|
||||||
|
{/* System Status */}
|
||||||
|
<SystemStatusSection />
|
||||||
|
|
||||||
{/* CLI Tools Configuration */}
|
{/* CLI Tools Configuration */}
|
||||||
<Card className="p-6">
|
<Card className="p-6">
|
||||||
<h2 className="text-lg font-semibold text-foreground flex items-center gap-2 mb-4">
|
<h2 className="text-lg font-semibold text-foreground flex items-center gap-2 mb-4">
|
||||||
<Cpu className="w-5 h-5" />
|
<Cpu className="w-5 h-5" />
|
||||||
{formatMessage({ id: 'settings.sections.cliTools' })}
|
{formatMessage({ id: 'settings.sections.cliTools' })}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-sm text-muted-foreground mb-4">
|
<CliToolsWithStatus
|
||||||
{formatMessage({ id: 'settings.cliTools.description' })} <strong className="text-foreground">{defaultCliTool}</strong>
|
cliTools={cliTools}
|
||||||
</p>
|
defaultCliTool={defaultCliTool}
|
||||||
<div className="space-y-3">
|
expandedTools={expandedTools}
|
||||||
{Object.entries(cliTools).map(([toolId, config]) => (
|
onToggleExpand={toggleToolExpand}
|
||||||
<CliToolCard
|
onToggleEnabled={handleToggleToolEnabled}
|
||||||
key={toolId}
|
onSetDefault={handleSetDefaultTool}
|
||||||
toolId={toolId}
|
onUpdateModel={handleUpdateModel}
|
||||||
config={config}
|
onUpdateTags={handleUpdateTags}
|
||||||
isDefault={toolId === defaultCliTool}
|
onUpdateAvailableModels={handleUpdateAvailableModels}
|
||||||
isExpanded={expandedTools.has(toolId)}
|
onUpdateSettingsFile={handleUpdateSettingsFile}
|
||||||
onToggleExpand={() => toggleToolExpand(toolId)}
|
formatMessage={formatMessage}
|
||||||
onToggleEnabled={() => handleToggleToolEnabled(toolId)}
|
|
||||||
onSetDefault={() => handleSetDefaultTool(toolId)}
|
|
||||||
onUpdateModel={(field, value) => handleUpdateModel(toolId, field, value)}
|
|
||||||
onUpdateTags={(tags) => handleUpdateTags(toolId, tags)}
|
|
||||||
onUpdateAvailableModels={(models) => handleUpdateAvailableModels(toolId, models)}
|
|
||||||
onUpdateSettingsFile={(settingsFile) => handleUpdateSettingsFile(toolId, settingsFile)}
|
|
||||||
/>
|
/>
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Data Refresh Settings */}
|
{/* Data Refresh Settings */}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import {
|
|||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
AlertDialogCancel,
|
AlertDialogCancel,
|
||||||
} from '@/components/ui';
|
} from '@/components/ui';
|
||||||
import { SkillCard, SkillDetailPanel } from '@/components/shared';
|
import { SkillCard, SkillDetailPanel, SkillCreateDialog } from '@/components/shared';
|
||||||
import { useSkills, useSkillMutations } from '@/hooks';
|
import { useSkills, useSkillMutations } from '@/hooks';
|
||||||
import { fetchSkillDetail } from '@/lib/api';
|
import { fetchSkillDetail } from '@/lib/api';
|
||||||
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
|
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
|
||||||
@@ -118,6 +118,9 @@ export function SkillsManagerPage() {
|
|||||||
const [confirmDisable, setConfirmDisable] = useState<{ skill: Skill; enable: boolean } | null>(null);
|
const [confirmDisable, setConfirmDisable] = useState<{ skill: Skill; enable: boolean } | null>(null);
|
||||||
const [locationFilter, setLocationFilter] = useState<'project' | 'user'>('project');
|
const [locationFilter, setLocationFilter] = useState<'project' | 'user'>('project');
|
||||||
|
|
||||||
|
// Skill create dialog state
|
||||||
|
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
|
||||||
|
|
||||||
// Skill detail panel state
|
// Skill detail panel state
|
||||||
const [selectedSkill, setSelectedSkill] = useState<Skill | null>(null);
|
const [selectedSkill, setSelectedSkill] = useState<Skill | null>(null);
|
||||||
const [isDetailLoading, setIsDetailLoading] = useState(false);
|
const [isDetailLoading, setIsDetailLoading] = useState(false);
|
||||||
@@ -243,7 +246,7 @@ export function SkillsManagerPage() {
|
|||||||
<RefreshCw className={cn('w-4 h-4 mr-2', isFetching && 'animate-spin')} />
|
<RefreshCw className={cn('w-4 h-4 mr-2', isFetching && 'animate-spin')} />
|
||||||
{formatMessage({ id: 'common.actions.refresh' })}
|
{formatMessage({ id: 'common.actions.refresh' })}
|
||||||
</Button>
|
</Button>
|
||||||
<Button>
|
<Button onClick={() => setIsCreateDialogOpen(true)}>
|
||||||
<Plus className="w-4 h-4 mr-2" />
|
<Plus className="w-4 h-4 mr-2" />
|
||||||
{formatMessage({ id: 'skills.actions.install' })}
|
{formatMessage({ id: 'skills.actions.install' })}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -470,6 +473,13 @@ export function SkillsManagerPage() {
|
|||||||
onClose={handleCloseDetailPanel}
|
onClose={handleCloseDetailPanel}
|
||||||
isLoading={isDetailLoading}
|
isLoading={isDetailLoading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Skill Create Dialog */}
|
||||||
|
<SkillCreateDialog
|
||||||
|
open={isCreateDialogOpen}
|
||||||
|
onOpenChange={setIsCreateDialogOpen}
|
||||||
|
onCreated={() => refetch()}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -726,13 +726,23 @@ function toggleMcpServerEnabled(projectPath: string, serverName: string, enable:
|
|||||||
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
||||||
const config = JSON.parse(content);
|
const config = JSON.parse(content);
|
||||||
|
|
||||||
const normalizedPath = normalizeProjectPathForConfig(projectPath, config);
|
// Find matching project key by normalizing both input and config keys
|
||||||
|
const normalizedInput = normalizeProjectPathForConfig(projectPath, config);
|
||||||
if (!config.projects || !config.projects[normalizedPath]) {
|
let matchedKey: string | null = null;
|
||||||
return { error: `Project not found: ${normalizedPath}` };
|
if (config.projects) {
|
||||||
|
for (const key of Object.keys(config.projects)) {
|
||||||
|
if (normalizeProjectPathForConfig(key) === normalizedInput) {
|
||||||
|
matchedKey = key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectConfig = config.projects[normalizedPath];
|
if (!matchedKey || !config.projects[matchedKey]) {
|
||||||
|
return { error: `Project not found: ${normalizedInput}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
const projectConfig = config.projects[matchedKey];
|
||||||
|
|
||||||
// Ensure disabledMcpServers array exists
|
// Ensure disabledMcpServers array exists
|
||||||
if (!projectConfig.disabledMcpServers) {
|
if (!projectConfig.disabledMcpServers) {
|
||||||
@@ -865,11 +875,20 @@ function removeMcpServerFromProject(projectPath: string, serverName: string) {
|
|||||||
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
||||||
const config = JSON.parse(content);
|
const config = JSON.parse(content);
|
||||||
|
|
||||||
// Get normalized path that matches existing config format
|
// Find matching project key by normalizing both input path and config keys
|
||||||
const normalizedPath = normalizeProjectPathForConfig(projectPath, config);
|
const normalizedInput = normalizeProjectPathForConfig(projectPath, config);
|
||||||
|
let matchedKey: string | null = null;
|
||||||
|
if (config.projects) {
|
||||||
|
for (const key of Object.keys(config.projects)) {
|
||||||
|
if (normalizeProjectPathForConfig(key) === normalizedInput) {
|
||||||
|
matchedKey = key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config.projects && config.projects[normalizedPath]) {
|
if (matchedKey && config.projects[matchedKey]) {
|
||||||
const projectConfig = config.projects[normalizedPath];
|
const projectConfig = config.projects[matchedKey];
|
||||||
|
|
||||||
if (projectConfig.mcpServers && projectConfig.mcpServers[serverName]) {
|
if (projectConfig.mcpServers && projectConfig.mcpServers[serverName]) {
|
||||||
// Remove the server
|
// Remove the server
|
||||||
|
|||||||
Reference in New Issue
Block a user