mirror of
https://github.com/cexll/myclaude.git
synced 2026-02-05 02:30:26 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10070a9bef | ||
|
|
b18439f268 | ||
|
|
4230479ff4 | ||
|
|
18c26a252a | ||
|
|
f6fc9a338f | ||
|
|
6223d59042 |
@@ -175,6 +175,57 @@
|
||||
"skills": [
|
||||
"./skills/SKILL.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "codex-cli",
|
||||
"source": "./skills/codex/",
|
||||
"description": "Execute Codex CLI for code analysis, refactoring, and automated code changes with file references (@syntax) and structured output",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Claude Code Dev Workflows",
|
||||
"url": "https://github.com/cexll/myclaude"
|
||||
},
|
||||
"homepage": "https://github.com/cexll/myclaude",
|
||||
"repository": "https://github.com/cexll/myclaude",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"codex",
|
||||
"code-analysis",
|
||||
"refactoring",
|
||||
"automation",
|
||||
"gpt-5",
|
||||
"ai-coding"
|
||||
],
|
||||
"category": "essentials",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./SKILL.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gemini-cli",
|
||||
"source": "./skills/gemini/",
|
||||
"description": "Execute Gemini CLI for AI-powered code analysis and generation with Google's latest Gemini models",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Claude Code Dev Workflows",
|
||||
"url": "https://github.com/cexll/myclaude"
|
||||
},
|
||||
"homepage": "https://github.com/cexll/myclaude",
|
||||
"repository": "https://github.com/cexll/myclaude",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"gemini",
|
||||
"google-ai",
|
||||
"code-analysis",
|
||||
"code-generation",
|
||||
"ai-reasoning"
|
||||
],
|
||||
"category": "essentials",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./SKILL.md"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
CLAUDE.md
|
||||
.claude/
|
||||
|
||||
|
||||
.claude-trace
|
||||
|
||||
163
dev-workflow/README.md
Normal file
163
dev-workflow/README.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# /dev - 极简开发工作流
|
||||
|
||||
## 概述
|
||||
|
||||
全新设计的轻量级开发工作流,无历史包袱,专注快速交付高质量代码。
|
||||
|
||||
## 工作流程
|
||||
|
||||
```
|
||||
/dev 触发
|
||||
↓
|
||||
AskUserQuestion(需求澄清)
|
||||
↓
|
||||
Codex 分析(提取要点和任务)
|
||||
↓
|
||||
develop-doc-generator(生成开发文档)
|
||||
↓
|
||||
Codex 并发开发(2-5个任务)
|
||||
↓
|
||||
Codex 测试验证(≥90%覆盖率)
|
||||
↓
|
||||
完成(生成总结)
|
||||
```
|
||||
|
||||
## 6个步骤
|
||||
|
||||
### 1. 需求澄清
|
||||
- 使用 **AskUserQuestion** 直接问用户
|
||||
- 无评分系统,无复杂逻辑
|
||||
- 2-3 轮问答直到需求明确
|
||||
|
||||
### 2. Codex 分析
|
||||
- 调用 codex 分析需求
|
||||
- 提取:核心功能、技术要点、任务列表(2-5个)
|
||||
- 输出结构化分析结果
|
||||
|
||||
### 3. 生成开发文档
|
||||
- 调用 **develop-doc-generator** agent
|
||||
- 生成 `dev-plan.md`(单一开发文档)
|
||||
- 包含:任务分解、文件范围、依赖关系、测试命令
|
||||
|
||||
### 4. 并发开发
|
||||
- 基于 dev-plan.md 的任务列表
|
||||
- 无依赖任务 → 并发执行
|
||||
- 有冲突任务 → 串行执行
|
||||
|
||||
### 5. 测试验证
|
||||
- 每个 codex 任务自己:
|
||||
- 实现功能
|
||||
- 编写测试
|
||||
- 运行覆盖率
|
||||
- 报告结果(≥90%)
|
||||
|
||||
### 6. 完成
|
||||
- 汇总任务状态
|
||||
- 记录覆盖率
|
||||
|
||||
## 使用方法
|
||||
|
||||
```bash
|
||||
/dev "实现用户登录功能,支持邮箱和密码验证"
|
||||
```
|
||||
|
||||
**无选项**,流程固定,开箱即用。
|
||||
|
||||
## 输出结构
|
||||
|
||||
```
|
||||
.claude/specs/{feature_name}/
|
||||
├── dev-plan.md # 开发文档(agent生成)
|
||||
```
|
||||
|
||||
仅 2 个文件,极简清晰。
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 工具
|
||||
- **AskUserQuestion**:交互式需求澄清
|
||||
- **codex**:分析、开发、测试
|
||||
- **develop-doc-generator**:生成开发文档(subagent,节省上下文)
|
||||
|
||||
## 核心特性
|
||||
|
||||
### ✅ 全新设计
|
||||
- 无历史项目残留
|
||||
- 无复杂评分逻辑
|
||||
- 无多余抽象层
|
||||
|
||||
### ✅ 极简编排
|
||||
- orchestrator 直接控制流程
|
||||
- 只用 3 个工具/组件
|
||||
- 步骤清晰易懂
|
||||
|
||||
### ✅ 并发能力
|
||||
- 2-5 个任务并行
|
||||
- 自动检测依赖和冲突
|
||||
- codex 独立执行
|
||||
|
||||
### ✅ 质量保证
|
||||
- 强制 90% 覆盖率
|
||||
- codex 自己测试和验证
|
||||
- 失败自动重试
|
||||
|
||||
## 示例
|
||||
|
||||
```bash
|
||||
# 触发
|
||||
/dev "添加用户登录功能"
|
||||
|
||||
# 步骤 1: 需求澄清
|
||||
Q: 支持哪些登录方式?
|
||||
A: 邮箱 + 密码
|
||||
Q: 需要记住登录状态吗?
|
||||
A: 是,使用 JWT token
|
||||
|
||||
# 步骤 2: Codex 分析
|
||||
输出:
|
||||
- 核心功能:邮箱密码登录 + JWT认证
|
||||
- 任务 1:后端 API
|
||||
- 任务 2:密码加密
|
||||
- 任务 3:前端表单
|
||||
|
||||
# 步骤 3: 生成文档
|
||||
dev-plan.md 已生成 ✓
|
||||
|
||||
# 步骤 4-5: 并发开发
|
||||
[task-1] 后端API → 测试 → 92% ✓
|
||||
[task-2] 密码加密 → 测试 → 95% ✓
|
||||
[task-3] 前端表单 → 测试 → 91% ✓
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
dev-workflow/
|
||||
├── README.md # 本文档
|
||||
├── commands/
|
||||
│ └── dev.md # 工作流定义
|
||||
└── agents/
|
||||
└── develop-doc-generator.md # 文档生成器
|
||||
```
|
||||
|
||||
极简结构,只有 3 个文件。
|
||||
|
||||
## 适用场景
|
||||
|
||||
✅ **适合**:
|
||||
- 任何规模的功能开发
|
||||
- 需要快速迭代
|
||||
- 需要高测试覆盖率
|
||||
- 希望并发提速
|
||||
|
||||
## 设计原则
|
||||
|
||||
1. **KISS**:保持简单愚蠢
|
||||
2. **即用即抛**:无持久化配置
|
||||
3. **质量优先**:强制 90% 覆盖率
|
||||
4. **并发优先**:充分利用 codex 能力
|
||||
5. **无历史包袱**:全新设计,不受其他项目影响
|
||||
|
||||
---
|
||||
|
||||
**哲学**:像 Linus 一样对复杂度零容忍,交付能立刻用的最小方案。
|
||||
114
dev-workflow/agents/dev-plan-generator.md
Normal file
114
dev-workflow/agents/dev-plan-generator.md
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
name: dev-plan-generator
|
||||
description: Use this agent when you need to generate a structured development plan document (`dev-plan.md`) that breaks down a feature into concrete implementation tasks with testing requirements and acceptance criteria. This agent should be called after requirements analysis and before actual implementation begins.\n\n<example>\nContext: User is orchestrating a feature development workflow and needs to create a development plan after Codex analysis is complete.\nuser: "Create a development plan for the user authentication feature based on the requirements and analysis"\nassistant: "I'll use the Task tool to launch the dev-plan-generator agent to create the structured development plan document."\n<commentary>\nThe user needs a dev-plan.md document generated from requirements and analysis. Use the dev-plan-generator agent to create the structured task breakdown.\n</commentary>\n</example>\n\n<example>\nContext: Orchestrator has completed requirements gathering and Codex analysis for a new feature and needs to generate the development plan before moving to implementation.\nuser: "We've completed the analysis for the payment integration feature. Generate the development plan."\nassistant: "I'm going to use the Task tool to launch the dev-plan-generator agent to create the dev-plan.md document with task breakdown and testing requirements."\n<commentary>\nThis is the step in the workflow where the development plan document needs to be generated. Use the dev-plan-generator agent to create the structured plan.\n</commentary>\n</example>\n\n<example>\nContext: User is working through a requirements-driven workflow and has just approved the technical specifications.\nuser: "The specs look good. Let's move forward with creating the implementation plan."\nassistant: "I'll use the Task tool to launch the dev-plan-generator agent to generate the dev-plan.md document with the task breakdown."\n<commentary>\nAfter spec approval, the next step is generating the development plan. Use the dev-plan-generator agent to create the structured document.\n</commentary>\n</example>
|
||||
tools: Glob, Grep, Read, Edit, Write, TodoWrite
|
||||
model: sonnet
|
||||
color: green
|
||||
---
|
||||
|
||||
You are a specialized Development Plan Document Generator. Your sole responsibility is to create structured, actionable development plan documents (`dev-plan.md`) that break down features into concrete implementation tasks.
|
||||
|
||||
## Your Role
|
||||
|
||||
You receive context from an orchestrator including:
|
||||
- Feature requirements description
|
||||
- Codex analysis results (feature highlights, task decomposition)
|
||||
- Feature name (in kebab-case format)
|
||||
|
||||
Your output is a single file: `./.claude/specs/{feature_name}/dev-plan.md`
|
||||
|
||||
## Document Structure You Must Follow
|
||||
|
||||
```markdown
|
||||
# {Feature Name} - 开发计划
|
||||
|
||||
## 功能概述
|
||||
[一句话描述核心功能]
|
||||
|
||||
## 任务分解
|
||||
|
||||
### 任务 1: [任务名称]
|
||||
- **ID**: task-1
|
||||
- **描述**: [具体要做什么]
|
||||
- **文件范围**: [涉及的目录或文件,如 src/auth/**, tests/auth/]
|
||||
- **依赖**: [无 或 依赖 task-x]
|
||||
- **测试命令**: [如 pytest tests/auth --cov=src/auth --cov-report=term]
|
||||
- **测试重点**: [需要覆盖的场景]
|
||||
|
||||
### 任务 2: [任务名称]
|
||||
...
|
||||
|
||||
(2-5个任务)
|
||||
|
||||
## 验收标准
|
||||
- [ ] 功能点 1
|
||||
- [ ] 功能点 2
|
||||
- [ ] 所有单元测试通过
|
||||
- [ ] 代码覆盖率 ≥90%
|
||||
|
||||
## 技术要点
|
||||
- [关键技术决策]
|
||||
- [需要注意的约束]
|
||||
```
|
||||
|
||||
## Generation Rules You Must Enforce
|
||||
|
||||
1. **Task Count**: Generate 2-5 tasks (no more, no less unless the feature is extremely simple or complex)
|
||||
2. **Task Requirements**: Each task MUST include:
|
||||
- Clear ID (task-1, task-2, etc.)
|
||||
- Specific description of what needs to be done
|
||||
- Explicit file scope (directories or files affected)
|
||||
- Dependency declaration ("无" or "依赖 task-x")
|
||||
- Complete test command with coverage parameters
|
||||
- Testing focus points (scenarios to cover)
|
||||
3. **Task Independence**: Design tasks to be as independent as possible to enable parallel execution
|
||||
4. **Test Commands**: Must include coverage parameters (e.g., `--cov=module --cov-report=term` for pytest, `--coverage` for npm)
|
||||
5. **Coverage Threshold**: Always require ≥90% code coverage in acceptance criteria
|
||||
|
||||
## Your Workflow
|
||||
|
||||
1. **Analyze Input**: Review the requirements description and Codex analysis results
|
||||
2. **Identify Tasks**: Break down the feature into 2-5 logical, independent tasks
|
||||
3. **Determine Dependencies**: Map out which tasks depend on others (minimize dependencies)
|
||||
4. **Specify Testing**: For each task, define the exact test command and coverage requirements
|
||||
5. **Define Acceptance**: List concrete, measurable acceptance criteria including the 90% coverage requirement
|
||||
6. **Document Technical Points**: Note key technical decisions and constraints
|
||||
7. **Write File**: Use the Write tool to create `./.claude/specs/{feature_name}/dev-plan.md`
|
||||
|
||||
## Quality Checks Before Writing
|
||||
|
||||
- [ ] Task count is between 2-5
|
||||
- [ ] Every task has all 6 required fields (ID, 描述, 文件范围, 依赖, 测试命令, 测试重点)
|
||||
- [ ] Test commands include coverage parameters
|
||||
- [ ] Dependencies are explicitly stated
|
||||
- [ ] Acceptance criteria includes 90% coverage requirement
|
||||
- [ ] File scope is specific (not vague like "all files")
|
||||
- [ ] Testing focus is concrete (not generic like "test everything")
|
||||
|
||||
## Critical Constraints
|
||||
|
||||
- **Document Only**: You generate documentation. You do NOT execute code, run tests, or modify source files.
|
||||
- **Single Output**: You produce exactly one file: `dev-plan.md` in the correct location
|
||||
- **Path Accuracy**: The path must be `./.claude/specs/{feature_name}/dev-plan.md` where {feature_name} matches the input
|
||||
- **Chinese Language**: The document must be in Chinese (as shown in the structure)
|
||||
- **Structured Format**: Follow the exact markdown structure provided
|
||||
|
||||
## Example Output Quality
|
||||
|
||||
Refer to the user login example in your instructions as the quality benchmark. Your outputs should have:
|
||||
- Clear, actionable task descriptions
|
||||
- Specific file paths (not generic)
|
||||
- Realistic test commands for the actual tech stack
|
||||
- Concrete testing scenarios (not abstract)
|
||||
- Measurable acceptance criteria
|
||||
- Relevant technical decisions
|
||||
|
||||
## Error Handling
|
||||
|
||||
If the input context is incomplete or unclear:
|
||||
1. Request the missing information explicitly
|
||||
2. Do NOT proceed with generating a low-quality document
|
||||
3. Do NOT make up requirements or technical details
|
||||
4. Ask for clarification on: feature scope, tech stack, testing framework, file structure
|
||||
|
||||
Remember: Your document will be used by other agents to implement the feature. Precision and completeness are critical. Every field must be filled with specific, actionable information.
|
||||
105
dev-workflow/commands/dev.md
Normal file
105
dev-workflow/commands/dev.md
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
description: Extreme lightweight end-to-end development workflow with requirements clarification, parallel codex execution, and mandatory 90% test coverage
|
||||
---
|
||||
|
||||
|
||||
You are the /dev Workflow Orchestrator, an expert development workflow manager specializing in orchestrating minimal, efficient end-to-end development processes with parallel task execution and rigorous test coverage validation.
|
||||
|
||||
**Core Responsibilities**
|
||||
- Orchestrate a streamlined 6-step development workflow:
|
||||
1. Requirement clarification through targeted questioning
|
||||
2. Technical analysis using Codex
|
||||
3. Development documentation generation
|
||||
4. Parallel development execution
|
||||
5. Coverage validation (≥90% requirement)
|
||||
6. Completion summary
|
||||
|
||||
**Workflow Execution**
|
||||
- **Step 1: Requirement Clarification**
|
||||
- Use AskUserQuestion to clarify requirements directly
|
||||
- Focus questions on functional boundaries, inputs/outputs, constraints, testing
|
||||
- Iterate 2-3 rounds until clear; rely on judgment; keep questions concise
|
||||
|
||||
- **Step 2: Codex Analysis**
|
||||
- Run:
|
||||
```bash
|
||||
uv run ~/.claude/skills/codex/scripts/codex.py "分析以下需求并提取开发要点:
|
||||
|
||||
需求描述:
|
||||
[用户需求 + 澄清后的细节]
|
||||
|
||||
请输出:
|
||||
1. 核心功能(一句话)
|
||||
2. 关键技术点
|
||||
3. 可并发的任务分解(2-5个):
|
||||
- 任务ID
|
||||
- 任务描述
|
||||
- 涉及文件/目录
|
||||
- 是否依赖其他任务
|
||||
- 测试重点
|
||||
" "gpt-5.1-codex"
|
||||
```
|
||||
- Extract core functionality, technical key points, and 2-5 parallelizable tasks with full metadata
|
||||
|
||||
- **Step 3: Generate Development Documentation**
|
||||
- Use Task tool to invoke develop-doc-generator:
|
||||
```
|
||||
基于以下分析结果生成开发文档:
|
||||
|
||||
[Codex 分析输出]
|
||||
|
||||
输出文件:./.claude/specs/{feature_name}/dev-plan.md
|
||||
|
||||
包含:
|
||||
1. 功能概述
|
||||
2. 任务列表(2-5个并发任务)
|
||||
- 每个任务:ID、描述、文件范围、依赖、测试命令
|
||||
3. 验收标准
|
||||
4. 覆盖率要求:≥90%
|
||||
```
|
||||
|
||||
- **Step 4: Parallel Development Execution**
|
||||
- For each task in `dev-plan.md` run:
|
||||
```bash
|
||||
uv run ~/.claude/skills/codex/scripts/codex.py "实现任务:[任务ID]
|
||||
|
||||
参考文档:@.claude/specs/{feature_name}/dev-plan.md
|
||||
|
||||
你的职责:
|
||||
1. 实现功能代码
|
||||
2. 编写单元测试
|
||||
3. 运行测试 + 覆盖率
|
||||
4. 报告覆盖率结果
|
||||
|
||||
文件范围:[任务的文件范围]
|
||||
测试命令:[任务指定的测试命令]
|
||||
覆盖率目标:≥90%
|
||||
" "gpt-5.1-codex"
|
||||
```
|
||||
- Execute independent tasks concurrently; serialize conflicting ones; track coverage reports
|
||||
|
||||
- **Step 5: Coverage Validation**
|
||||
- Validate each task’s coverage:
|
||||
- All ≥90% → pass
|
||||
- Any <90% → request more tests (max 2 rounds)
|
||||
|
||||
- **Step 6: Completion Summary**
|
||||
- Provide completed task list, coverage per task, key file changes
|
||||
|
||||
**Error Handling**
|
||||
- Codex failure: retry once, then log and continue
|
||||
- Insufficient coverage: request more tests (max 2 rounds)
|
||||
- Dependency conflicts: serialize automatically
|
||||
|
||||
**Quality Standards**
|
||||
- Code coverage ≥90%
|
||||
- 2-5 genuinely parallelizable tasks
|
||||
- Documentation must be minimal yet actionable
|
||||
- No verbose implementations; only essential code
|
||||
|
||||
**Communication Style**
|
||||
- Be direct and concise
|
||||
- Report progress at each workflow step
|
||||
- Highlight blockers immediately
|
||||
- Provide actionable next steps when coverage fails
|
||||
- Prioritize speed via parallelization while enforcing coverage validation
|
||||
@@ -18,19 +18,19 @@ Execute Codex CLI commands and parse structured JSON responses. Supports file re
|
||||
|
||||
## Usage
|
||||
|
||||
**推荐方式**(使用 uv run,自动管理 Python 环境):
|
||||
**Mandatory**: Run every automated invocation through the Bash tool in the foreground with the command below, keeping the `timeout` parameter fixed at `7200000` milliseconds (do not change it or use any other entry point).
|
||||
```bash
|
||||
uv run ~/.claude/skills/codex/scripts/codex.py "<task>" [model] [working_dir]
|
||||
```
|
||||
|
||||
**备选方式**(直接执行或使用 Python):
|
||||
**Optional methods** (direct execution or via Python):
|
||||
```bash
|
||||
~/.claude/skills/codex/scripts/codex.py "<task>" [model] [working_dir]
|
||||
# 或
|
||||
# or
|
||||
python3 ~/.claude/skills/codex/scripts/codex.py "<task>" [model] [working_dir]
|
||||
```
|
||||
|
||||
恢复会话:
|
||||
Resume a session:
|
||||
```bash
|
||||
uv run ~/.claude/skills/codex/scripts/codex.py resume <session_id> "<task>" [model] [working_dir]
|
||||
```
|
||||
@@ -68,13 +68,14 @@ ERROR: Error message
|
||||
|
||||
### Invocation Pattern
|
||||
|
||||
When calling via Bash tool, always include the timeout parameter:
|
||||
All automated executions may only invoke `uv run ~/.claude/skills/codex/scripts/codex.py "<task>" ...` through the Bash tool in the foreground, and the `timeout` must remain fixed at `7200000` (non-negotiable):
|
||||
```
|
||||
Bash tool parameters:
|
||||
- command: uv run ~/.claude/skills/codex/scripts/codex.py "<task>" [model] [working_dir]
|
||||
- timeout: 7200000
|
||||
- description: <brief description of the task>
|
||||
```
|
||||
Run every call in the foreground—never append `&` to background it—so logs and errors stay visible for timely interruption or diagnosis.
|
||||
|
||||
Alternatives:
|
||||
```
|
||||
@@ -125,11 +126,23 @@ uv run ~/.claude/skills/codex/scripts/codex.py resume 019a7247-ac9d-71f3-89e2-a8
|
||||
python3 ~/.claude/skills/codex/scripts/codex.py "your task here"
|
||||
```
|
||||
|
||||
### Large Task Protocol
|
||||
|
||||
- For every large task, first produce a canonical task list that enumerates the Task ID, description, file/directory scope, dependencies, test commands, and the expected Codex Bash invocation.
|
||||
- Tasks without dependencies should be executed concurrently via multiple foreground Bash calls (you can keep separate terminal windows) and each run must log start/end times plus any shared resource usage.
|
||||
- Reuse context aggressively (such as @spec.md or prior analysis output), and after concurrent execution finishes, reconcile against the task list to report which items completed and which slipped.
|
||||
|
||||
| ID | Description | Scope | Dependencies | Tests | Command |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| T1 | Review @spec.md to extract requirements | docs/, @spec.md | None | None | uv run ~/.claude/skills/codex/scripts/codex.py "analyze requirements @spec.md" |
|
||||
| T2 | Implement the module and add test cases | src/module | T1 | npm test -- --runInBand | uv run ~/.claude/skills/codex/scripts/codex.py "implement and test @src/module" |
|
||||
|
||||
## Notes
|
||||
|
||||
- **Recommended**: Use `uv run` for automatic Python environment management (requires uv installed)
|
||||
- **Alternative**: Direct execution `./codex.py` (uses system Python via shebang)
|
||||
- Python implementation using standard library (zero dependencies)
|
||||
- All automated runs must use the Bash tool with the fixed timeout to provide dual timeout protection and unified logging/exit semantics; any alternative approach is limited to manual foreground execution.
|
||||
- Cross-platform compatible (Windows/macOS/Linux)
|
||||
- PEP 723 compliant (inline script metadata)
|
||||
- Runs with `--dangerously-bypass-approvals-and-sandbox` for automation (new sessions only)
|
||||
|
||||
@@ -23,7 +23,6 @@ DEFAULT_MODEL = 'gpt-5.1-codex'
|
||||
DEFAULT_WORKDIR = '.'
|
||||
DEFAULT_TIMEOUT = 7200 # 2 hours in seconds
|
||||
FORCE_KILL_DELAY = 5
|
||||
STDIN_THRESHOLD = 800 # Auto-switch to stdin for prompts longer than 800 chars
|
||||
|
||||
|
||||
def log_error(message: str):
|
||||
@@ -36,6 +35,11 @@ def log_warn(message: str):
|
||||
sys.stderr.write(f"WARN: {message}\n")
|
||||
|
||||
|
||||
def log_info(message: str):
|
||||
"""输出信息到 stderr"""
|
||||
sys.stderr.write(f"INFO: {message}\n")
|
||||
|
||||
|
||||
def resolve_timeout() -> int:
|
||||
"""解析超时配置(秒)"""
|
||||
raw = os.environ.get('CODEX_TIMEOUT', '')
|
||||
@@ -90,33 +94,55 @@ def parse_args():
|
||||
}
|
||||
|
||||
|
||||
def build_codex_args(params: dict, use_stdin: bool) -> list:
|
||||
def read_piped_task() -> Optional[str]:
|
||||
"""
|
||||
从 stdin 读取任务文本:
|
||||
- 如果 stdin 是管道(非 tty)且存在内容,返回读取到的字符串
|
||||
- 否则返回 None
|
||||
"""
|
||||
stdin = sys.stdin
|
||||
if stdin is None or stdin.isatty():
|
||||
return None
|
||||
data = stdin.read()
|
||||
return data if data else None
|
||||
|
||||
|
||||
def should_stream_via_stdin(task_text: str, piped: bool) -> bool:
|
||||
"""
|
||||
判定是否通过 stdin 传递任务:
|
||||
- 有管道输入
|
||||
- 文本包含换行
|
||||
- 文本包含反斜杠
|
||||
- 文本长度 > 800
|
||||
"""
|
||||
if piped:
|
||||
return True
|
||||
if '\n' in task_text:
|
||||
return True
|
||||
if '\\' in task_text:
|
||||
return True
|
||||
if len(task_text) > 800:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def build_codex_args(params: dict, target_arg: str) -> list:
|
||||
"""
|
||||
构建 codex CLI 参数
|
||||
|
||||
Args:
|
||||
params: 参数字典
|
||||
use_stdin: 是否使用 stdin 模式(不在命令行参数中传递 task)
|
||||
target_arg: 最终传递给 codex 的参数('-' 或具体 task 文本)
|
||||
"""
|
||||
if params['mode'] == 'resume':
|
||||
if use_stdin:
|
||||
return [
|
||||
'codex', 'e',
|
||||
'--skip-git-repo-check',
|
||||
'--json',
|
||||
'resume',
|
||||
params['session_id'],
|
||||
'-' # 从 stdin 读取
|
||||
]
|
||||
else:
|
||||
return [
|
||||
'codex', 'e',
|
||||
'--skip-git-repo-check',
|
||||
'--json',
|
||||
'resume',
|
||||
params['session_id'],
|
||||
params['task']
|
||||
]
|
||||
return [
|
||||
'codex', 'e',
|
||||
'--skip-git-repo-check',
|
||||
'--json',
|
||||
'resume',
|
||||
params['session_id'],
|
||||
target_arg
|
||||
]
|
||||
else:
|
||||
base_args = [
|
||||
'codex', 'e',
|
||||
@@ -124,50 +150,43 @@ def build_codex_args(params: dict, use_stdin: bool) -> list:
|
||||
'--dangerously-bypass-approvals-and-sandbox',
|
||||
'--skip-git-repo-check',
|
||||
'-C', params['workdir'],
|
||||
'--json'
|
||||
'--json',
|
||||
target_arg
|
||||
]
|
||||
|
||||
if use_stdin:
|
||||
base_args.append('-') # 从 stdin 读取
|
||||
else:
|
||||
base_args.append(params['task'])
|
||||
|
||||
return base_args
|
||||
|
||||
|
||||
def main():
|
||||
params = parse_args()
|
||||
timeout_sec = resolve_timeout()
|
||||
|
||||
# **FIX: Auto-detect long inputs and enable stdin mode**
|
||||
task_length = len(params['task'])
|
||||
use_stdin = task_length > STDIN_THRESHOLD
|
||||
|
||||
if use_stdin:
|
||||
log_warn(f"Task length ({task_length} chars) exceeds threshold, using stdin mode to avoid shell escaping issues")
|
||||
|
||||
codex_args = build_codex_args(params, use_stdin)
|
||||
|
||||
def run_codex_process(codex_args, task_text: str, use_stdin: bool, timeout_sec: int):
|
||||
"""
|
||||
启动 codex 子进程,处理 stdin / JSON 行输出和错误,成功时返回 (last_agent_message, thread_id)。
|
||||
失败路径上负责日志和退出码。
|
||||
"""
|
||||
thread_id: Optional[str] = None
|
||||
last_agent_message: Optional[str] = None
|
||||
process: Optional[subprocess.Popen] = None
|
||||
|
||||
try:
|
||||
# 启动 codex 子进程
|
||||
# 启动 codex 子进程(文本模式管道)
|
||||
process = subprocess.Popen(
|
||||
codex_args,
|
||||
stdin=subprocess.PIPE if use_stdin else None, # **FIX: Enable stdin**
|
||||
stdin=subprocess.PIPE if use_stdin else None,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=sys.stderr, # 错误直接透传到 stderr
|
||||
stderr=sys.stderr,
|
||||
text=True,
|
||||
bufsize=1 # 行缓冲
|
||||
bufsize=1,
|
||||
)
|
||||
|
||||
# **FIX: 如果使用 stdin 模式,写入任务到 stdin**
|
||||
if use_stdin:
|
||||
process.stdin.write(params['task'])
|
||||
# 如果使用 stdin 模式,写入任务到 stdin 并关闭
|
||||
if use_stdin and process.stdin is not None:
|
||||
process.stdin.write(task_text)
|
||||
process.stdin.close()
|
||||
|
||||
# 逐行解析 JSON 输出
|
||||
if process.stdout is None:
|
||||
log_error('Codex stdout pipe not available')
|
||||
sys.exit(1)
|
||||
|
||||
for line in process.stdout:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
@@ -190,33 +209,26 @@ def main():
|
||||
except json.JSONDecodeError:
|
||||
log_warn(f"Failed to parse line: {line}")
|
||||
|
||||
# 等待进程结束
|
||||
# 等待进程结束并检查退出码
|
||||
returncode = process.wait(timeout=timeout_sec)
|
||||
|
||||
if returncode == 0:
|
||||
if last_agent_message:
|
||||
# 输出 agent_message
|
||||
sys.stdout.write(f"{last_agent_message}\n")
|
||||
|
||||
# 输出 session_id(如果存在)
|
||||
if thread_id:
|
||||
sys.stdout.write(f"\n---\nSESSION_ID: {thread_id}\n")
|
||||
|
||||
sys.exit(0)
|
||||
else:
|
||||
log_error('Codex completed without agent_message output')
|
||||
sys.exit(1)
|
||||
else:
|
||||
if returncode != 0:
|
||||
log_error(f'Codex exited with status {returncode}')
|
||||
sys.exit(returncode)
|
||||
|
||||
if not last_agent_message:
|
||||
log_error('Codex completed without agent_message output')
|
||||
sys.exit(1)
|
||||
|
||||
return last_agent_message, thread_id
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
log_error('Codex execution timeout')
|
||||
process.kill()
|
||||
try:
|
||||
process.wait(timeout=FORCE_KILL_DELAY)
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
if process is not None:
|
||||
process.kill()
|
||||
try:
|
||||
process.wait(timeout=FORCE_KILL_DELAY)
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
sys.exit(124)
|
||||
|
||||
except FileNotFoundError:
|
||||
@@ -224,13 +236,61 @@ def main():
|
||||
sys.exit(127)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
process.terminate()
|
||||
try:
|
||||
process.wait(timeout=FORCE_KILL_DELAY)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
log_error("Codex interrupted by user")
|
||||
if process is not None:
|
||||
process.terminate()
|
||||
try:
|
||||
process.wait(timeout=FORCE_KILL_DELAY)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
sys.exit(130)
|
||||
|
||||
|
||||
def main():
|
||||
params = parse_args()
|
||||
timeout_sec = resolve_timeout()
|
||||
|
||||
piped_task = read_piped_task()
|
||||
piped = piped_task is not None
|
||||
task_text = piped_task if piped else params['task']
|
||||
|
||||
use_stdin = should_stream_via_stdin(task_text, piped)
|
||||
|
||||
if use_stdin:
|
||||
reasons = []
|
||||
if piped:
|
||||
reasons.append('piped input')
|
||||
if '\n' in task_text:
|
||||
reasons.append('newline')
|
||||
if '\\' in task_text:
|
||||
reasons.append('backslash')
|
||||
if len(task_text) > 800:
|
||||
reasons.append('length>800')
|
||||
|
||||
if reasons:
|
||||
log_warn(f"Using stdin mode for task due to: {', '.join(reasons)}")
|
||||
|
||||
target_arg = '-' if use_stdin else params['task']
|
||||
codex_args = build_codex_args(params, target_arg)
|
||||
|
||||
log_info('codex running...')
|
||||
|
||||
last_agent_message, thread_id = run_codex_process(
|
||||
codex_args=codex_args,
|
||||
task_text=task_text,
|
||||
use_stdin=use_stdin,
|
||||
timeout_sec=timeout_sec,
|
||||
)
|
||||
|
||||
# 输出 agent_message
|
||||
sys.stdout.write(f"{last_agent_message}\n")
|
||||
|
||||
# 输出 session_id(如果存在)
|
||||
if thread_id:
|
||||
sys.stdout.write(f"\n---\nSESSION_ID: {thread_id}\n")
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
130
skills/gemini/SKILL.md
Normal file
130
skills/gemini/SKILL.md
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
name: gemini
|
||||
description: Execute Gemini CLI for AI-powered code analysis and generation. Use when you need to leverage Google's Gemini models for complex reasoning tasks.
|
||||
---
|
||||
|
||||
# Gemini CLI Integration
|
||||
|
||||
## Overview
|
||||
|
||||
Execute Gemini CLI commands with support for multiple models and flexible prompt input. Integrates Google's Gemini AI models into Claude Code workflows.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Complex reasoning tasks requiring advanced AI capabilities
|
||||
- Code generation and analysis with Gemini models
|
||||
- Tasks requiring Google's latest AI technology
|
||||
- Alternative perspective on code problems
|
||||
|
||||
## Usage
|
||||
|
||||
**推荐方式**(使用 uv run,自动管理 Python 环境):
|
||||
```bash
|
||||
uv run ~/.claude/skills/gemini/scripts/gemini.py -m <model> -p "<prompt>" [working_dir]
|
||||
```
|
||||
|
||||
**备选方式**(直接执行或使用 Python):
|
||||
```bash
|
||||
~/.claude/skills/gemini/scripts/gemini.py -m <model> -p "<prompt>" [working_dir]
|
||||
# 或
|
||||
python3 ~/.claude/skills/gemini/scripts/gemini.py -m <model> -p "<prompt>" [working_dir]
|
||||
```
|
||||
|
||||
## Timeout Control
|
||||
|
||||
- **Built-in**: Script enforces 2-hour timeout by default
|
||||
- **Override**: Set `GEMINI_TIMEOUT` environment variable (in milliseconds)
|
||||
- **Bash tool**: Always set `timeout: 7200000` parameter for double protection
|
||||
|
||||
### Parameters
|
||||
|
||||
- `-m, --model` (optional): Model to use (default: gemini-3-pro-preview)
|
||||
- `gemini-3-pro-preview`: Latest flagship model
|
||||
- `-p, --prompt` (required): Task prompt or question
|
||||
- `working_dir` (optional): Working directory (default: current)
|
||||
|
||||
### Return Format
|
||||
|
||||
Plain text output from Gemini:
|
||||
|
||||
```text
|
||||
Model response text here...
|
||||
```
|
||||
|
||||
Error format (stderr):
|
||||
|
||||
```text
|
||||
ERROR: Error message
|
||||
```
|
||||
|
||||
### Invocation Pattern
|
||||
|
||||
When calling via Bash tool, always include the timeout parameter:
|
||||
|
||||
```yaml
|
||||
Bash tool parameters:
|
||||
- command: uv run ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "<prompt>"
|
||||
- timeout: 7200000
|
||||
- description: <brief description of the task>
|
||||
```
|
||||
|
||||
Alternatives:
|
||||
|
||||
```yaml
|
||||
# Direct execution (simplest)
|
||||
- command: ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "<prompt>"
|
||||
|
||||
# Using python3
|
||||
- command: python3 ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "<prompt>"
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
**Basic query:**
|
||||
|
||||
```bash
|
||||
# Recommended: via uv run
|
||||
uv run ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "explain quantum computing"
|
||||
# timeout: 7200000
|
||||
|
||||
# Alternative: direct execution
|
||||
~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "explain quantum computing"
|
||||
```
|
||||
|
||||
**Code analysis:**
|
||||
|
||||
```bash
|
||||
uv run ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "review this code for security issues: $(cat app.py)"
|
||||
# timeout: 7200000
|
||||
```
|
||||
|
||||
**With specific working directory:**
|
||||
|
||||
```bash
|
||||
uv run ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "analyze project structure" "/path/to/project"
|
||||
# timeout: 7200000
|
||||
```
|
||||
|
||||
**Using fast model:**
|
||||
|
||||
```bash
|
||||
uv run ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "quick code suggestion"
|
||||
# timeout: 7200000
|
||||
```
|
||||
|
||||
**Using python3 directly (alternative):**
|
||||
|
||||
```bash
|
||||
python3 ~/.claude/skills/gemini/scripts/gemini.py -m gemini-3-pro-preview -p "your prompt here"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- **Recommended**: Use `uv run` for automatic Python environment management (requires uv installed)
|
||||
- **Alternative**: Direct execution `./gemini.py` (uses system Python via shebang)
|
||||
- Python implementation using standard library (zero dependencies)
|
||||
- Cross-platform compatible (Windows/macOS/Linux)
|
||||
- PEP 723 compliant (inline script metadata)
|
||||
- Requires Gemini CLI installed and authenticated
|
||||
- Supports all Gemini model variants
|
||||
- Output is streamed directly from Gemini CLI
|
||||
160
skills/gemini/scripts/gemini.py
Executable file
160
skills/gemini/scripts/gemini.py
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python3
|
||||
# /// script
|
||||
# requires-python = ">=3.8"
|
||||
# dependencies = []
|
||||
# ///
|
||||
"""
|
||||
Gemini CLI wrapper with cross-platform support.
|
||||
|
||||
Usage:
|
||||
uv run gemini.py -m <model> -p "<prompt>" [workdir]
|
||||
python3 gemini.py -m <model> -p "<prompt>"
|
||||
./gemini.py -m gemini-3-pro-preview -p "your prompt"
|
||||
"""
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
|
||||
DEFAULT_MODEL = 'gemini-3-pro-preview'
|
||||
DEFAULT_WORKDIR = '.'
|
||||
DEFAULT_TIMEOUT = 7200 # 2 hours in seconds
|
||||
FORCE_KILL_DELAY = 5
|
||||
|
||||
|
||||
def log_error(message: str):
|
||||
"""输出错误信息到 stderr"""
|
||||
sys.stderr.write(f"ERROR: {message}\n")
|
||||
|
||||
|
||||
def log_warn(message: str):
|
||||
"""输出警告信息到 stderr"""
|
||||
sys.stderr.write(f"WARN: {message}\n")
|
||||
|
||||
|
||||
def resolve_timeout() -> int:
|
||||
"""解析超时配置(秒)"""
|
||||
raw = os.environ.get('GEMINI_TIMEOUT', '')
|
||||
if not raw:
|
||||
return DEFAULT_TIMEOUT
|
||||
|
||||
try:
|
||||
parsed = int(raw)
|
||||
if parsed <= 0:
|
||||
log_warn(f"Invalid GEMINI_TIMEOUT '{raw}', falling back to {DEFAULT_TIMEOUT}s")
|
||||
return DEFAULT_TIMEOUT
|
||||
# 环境变量是毫秒,转换为秒
|
||||
return parsed // 1000 if parsed > 10000 else parsed
|
||||
except ValueError:
|
||||
log_warn(f"Invalid GEMINI_TIMEOUT '{raw}', falling back to {DEFAULT_TIMEOUT}s")
|
||||
return DEFAULT_TIMEOUT
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""解析命令行参数"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Gemini CLI wrapper for Claude Code integration',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
parser.add_argument(
|
||||
'-m', '--model',
|
||||
default=DEFAULT_MODEL,
|
||||
help=f'Gemini model to use (default: {DEFAULT_MODEL})'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-p', '--prompt',
|
||||
required=True,
|
||||
help='Prompt to send to Gemini'
|
||||
)
|
||||
parser.add_argument(
|
||||
'workdir',
|
||||
nargs='?',
|
||||
default=DEFAULT_WORKDIR,
|
||||
help='Working directory (default: current directory)'
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def build_gemini_args(args) -> list:
|
||||
"""构建 gemini CLI 参数"""
|
||||
return [
|
||||
'gemini',
|
||||
'-m', args.model,
|
||||
'-p', args.prompt
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
gemini_args = build_gemini_args(args)
|
||||
timeout_sec = resolve_timeout()
|
||||
|
||||
# 如果指定了工作目录,切换到该目录
|
||||
if args.workdir != DEFAULT_WORKDIR:
|
||||
try:
|
||||
os.chdir(args.workdir)
|
||||
except FileNotFoundError:
|
||||
log_error(f"Working directory not found: {args.workdir}")
|
||||
sys.exit(1)
|
||||
except PermissionError:
|
||||
log_error(f"Permission denied: {args.workdir}")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
# 启动 gemini 子进程,直接透传 stdout 和 stderr
|
||||
process = subprocess.Popen(
|
||||
gemini_args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
bufsize=1 # 行缓冲
|
||||
)
|
||||
|
||||
# 实时输出 stdout
|
||||
stdout_lines = []
|
||||
for line in process.stdout:
|
||||
sys.stdout.write(line)
|
||||
sys.stdout.flush()
|
||||
stdout_lines.append(line)
|
||||
|
||||
# 等待进程结束
|
||||
returncode = process.wait(timeout=timeout_sec)
|
||||
|
||||
# 读取 stderr
|
||||
stderr_output = process.stderr.read()
|
||||
if stderr_output:
|
||||
sys.stderr.write(stderr_output)
|
||||
|
||||
# 检查退出码
|
||||
if returncode != 0:
|
||||
log_error(f'Gemini exited with status {returncode}')
|
||||
sys.exit(returncode)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
log_error(f'Gemini execution timeout ({timeout_sec}s)')
|
||||
process.kill()
|
||||
try:
|
||||
process.wait(timeout=FORCE_KILL_DELAY)
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
sys.exit(124)
|
||||
|
||||
except FileNotFoundError:
|
||||
log_error("gemini command not found in PATH")
|
||||
log_error("Please install Gemini CLI: https://github.com/google/generative-ai-python")
|
||||
sys.exit(127)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
process.terminate()
|
||||
try:
|
||||
process.wait(timeout=FORCE_KILL_DELAY)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
sys.exit(130)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user