diff --git a/CHANGELOG.md b/CHANGELOG.md index a97d81a..2c88bf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,47 @@ All notable changes to this project will be documented in this file. +## [6.7.0] - 2026-02-10 + +### 🚀 Features + +- feat(install): per-module agent merge/unmerge for ~/.codeagent/models.json +- feat(install): post-install verification (wrapper version, PATH, backend CLIs) +- feat(install): install CLAUDE.md by default +- feat(docs): document 9 skills, 11 commands, claudekit module, OpenCode backend + +### 🐛 Bug Fixes + +- fix(docs): correct 7-phase → 5-phase for do skill across all docs +- fix(install): best-effort default config install (never crashes main flow) +- fix(install): interactive quit no longer triggers post-install actions +- fix(install): empty parent directory cleanup on copy_file uninstall +- fix(install): agent restore on uninstall when shared by multiple modules +- fix(docs): remove non-existent on-stop hook references + +### 📚 Documentation + +- Updated USER_GUIDE.md with 13 CLI flags and OpenCode backend +- Updated README.md/README_CN.md with complete module and skill listings +- Added templates/models.json.example with all agent presets (do + omo) + +## [6.6.0] - 2026-02-10 + +### 🚀 Features + +- feat(skills): add per-task skill spec auto-detection and injection +- feat: add worktree support and refactor do skill to Python + +### 🐛 Bug Fixes + +- fix(test): set USERPROFILE on Windows for skills tests +- fix(do): reuse worktree across phases via DO_WORKTREE_DIR env var +- fix(release): auto-generate release notes from git history + +### 📚 Documentation + +- audit and fix documentation, installation scripts, and default configuration + ## [6.0.0] - 2026-01-26 ### 🚀 Features diff --git a/README.md b/README.md index db7596b..a600bed 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,30 @@ npx github:cexll/myclaude | Module | Description | Documentation | |--------|-------------|---------------| -| [do](skills/do/README.md) | **Recommended** - 7-phase feature development with codeagent orchestration | `/do` command | +| [do](skills/do/README.md) | **Recommended** - 5-phase feature development with codeagent orchestration | `/do` command | | [omo](skills/omo/README.md) | Multi-agent orchestration with intelligent routing | `/omo` command | | [bmad](agents/bmad/README.md) | BMAD agile workflow with 6 specialized agents | `/bmad-pilot` command | | [requirements](agents/requirements/README.md) | Lightweight requirements-to-code pipeline | `/requirements-pilot` command | -| [essentials](agents/development-essentials/README.md) | Core development commands and utilities | `/code`, `/debug`, etc. | +| [essentials](agents/development-essentials/README.md) | 11 core dev commands: ask, bugfix, code, debug, docs, enhance-prompt, optimize, refactor, review, test, think | `/code`, `/debug`, etc. | | [sparv](skills/sparv/README.md) | SPARV workflow (Specify→Plan→Act→Review→Vault) | `/sparv` command | | course | Course development (combines dev + product-requirements + test-cases) | Composite module | +| claudekit | ClaudeKit: do skill + global hooks (pre-bash, inject-spec, log-prompt) | Composite module | + +### Available Skills + +Individual skills can be installed separately via `npx github:cexll/myclaude --list` (skills bundled in modules like do, omo, sparv are listed above): + +| Skill | Description | +|-------|-------------| +| browser | Browser automation for web testing and data extraction | +| codeagent | codeagent-wrapper invocation for multi-backend AI code tasks | +| codex | Direct Codex backend execution | +| dev | Lightweight end-to-end development workflow | +| gemini | Direct Gemini backend execution | +| product-requirements | Interactive PRD generation with quality scoring | +| prototype-prompt-generator | Structured UI/UX prototype prompt generation | +| skill-install | Install skills from GitHub with security scanning | +| test-cases | Comprehensive test case generation from requirements | ## Installation @@ -87,17 +104,20 @@ Edit `config.json` to enable/disable modules: | Codex | `codex e`, `--json`, `-C`, `resume` | | Claude | `--output-format stream-json`, `-r` | | Gemini | `-o stream-json`, `-y`, `-r` | +| OpenCode | `opencode`, stdin mode | ## Directory Structure After Installation ``` ~/.claude/ ├── bin/codeagent-wrapper -├── CLAUDE.md -├── commands/ -├── agents/ -├── skills/ -└── config.json +├── CLAUDE.md (installed by default) +├── commands/ (from essentials module) +├── agents/ (from bmad/requirements modules) +├── skills/ (from do/omo/sparv/course modules) +├── hooks/ (from claudekit module) +├── settings.json (auto-generated, hooks config) +└── installed_modules.json (auto-generated, tracks modules) ``` ## Documentation diff --git a/README_CN.md b/README_CN.md index c92d498..f90fd3e 100644 --- a/README_CN.md +++ b/README_CN.md @@ -16,13 +16,30 @@ npx github:cexll/myclaude | 模块 | 描述 | 文档 | |------|------|------| -| [do](skills/do/README.md) | **推荐** - 7 阶段功能开发 + codeagent 编排 | `/do` 命令 | +| [do](skills/do/README.md) | **推荐** - 5 阶段功能开发 + codeagent 编排 | `/do` 命令 | | [omo](skills/omo/README.md) | 多智能体编排 + 智能路由 | `/omo` 命令 | | [bmad](agents/bmad/README.md) | BMAD 敏捷工作流 + 6 个专业智能体 | `/bmad-pilot` 命令 | | [requirements](agents/requirements/README.md) | 轻量级需求到代码流水线 | `/requirements-pilot` 命令 | -| [essentials](agents/development-essentials/README.md) | 核心开发命令和工具 | `/code`, `/debug` 等 | +| [essentials](agents/development-essentials/README.md) | 11 个核心开发命令:ask、bugfix、code、debug、docs、enhance-prompt、optimize、refactor、review、test、think | `/code`, `/debug` 等 | | [sparv](skills/sparv/README.md) | SPARV 工作流 (Specify→Plan→Act→Review→Vault) | `/sparv` 命令 | | course | 课程开发(组合 dev + product-requirements + test-cases) | 组合模块 | +| claudekit | ClaudeKit:do 技能 + 全局钩子(pre-bash、inject-spec、log-prompt)| 组合模块 | + +### 可用技能 + +可通过 `npx github:cexll/myclaude --list` 单独安装技能(模块内置技能如 do、omo、sparv 见上表): + +| 技能 | 描述 | +|------|------| +| browser | 浏览器自动化测试和数据提取 | +| codeagent | codeagent-wrapper 多后端 AI 代码任务调用 | +| codex | Codex 后端直接执行 | +| dev | 轻量级端到端开发工作流 | +| gemini | Gemini 后端直接执行 | +| product-requirements | 交互式 PRD 生成(含质量评分)| +| prototype-prompt-generator | 结构化 UI/UX 原型提示词生成 | +| skill-install | 从 GitHub 安装技能(含安全扫描)| +| test-cases | 从需求生成全面测试用例 | ## 核心架构 @@ -35,22 +52,20 @@ npx github:cexll/myclaude ### do 工作流(推荐) -7 阶段功能开发,通过 codeagent-wrapper 编排多个智能体。**大多数功能开发任务的首选工作流。** +5 阶段功能开发,通过 codeagent-wrapper 编排多个智能体。**大多数功能开发任务的首选工作流。** ```bash /do "添加用户登录功能" ``` -**7 阶段:** +**5 阶段:** | 阶段 | 名称 | 目标 | |------|------|------| -| 1 | Discovery | 理解需求 | -| 2 | Exploration | 映射代码库模式 | -| 3 | Clarification | 解决歧义(**强制**)| -| 4 | Architecture | 设计实现方案 | -| 5 | Implementation | 构建功能(**需审批**)| -| 6 | Review | 捕获缺陷 | -| 7 | Summary | 记录结果 | +| 1 | Understand | 并行探索理解需求和映射代码库 | +| 2 | Clarify | 解决阻塞性歧义(条件触发)| +| 3 | Design | 产出最小变更实现方案 | +| 4 | Implement + Review | 构建功能并审查 | +| 5 | Complete | 记录构建结果 | **智能体:** - `code-explorer` - 代码追踪、架构映射 @@ -162,6 +177,10 @@ npx github:cexll/myclaude | `/optimize` | 性能优化 | | `/refactor` | 代码重构 | | `/docs` | 编写文档 | +| `/ask` | 提问和咨询 | +| `/bugfix` | Bug 修复 | +| `/enhance-prompt` | 提示词优化 | +| `/think` | 深度思考分析 | --- @@ -218,6 +237,7 @@ npx github:cexll/myclaude --install-dir ~/.claude --force | Codex | `codex e`, `--json`, `-C`, `resume` | | Claude | `--output-format stream-json`, `-r` | | Gemini | `-o stream-json`, `-y`, `-r` | +| OpenCode | `opencode`, stdin 模式 | ## 故障排查 diff --git a/bin/cli.js b/bin/cli.js index a84a6af..11947bd 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -8,7 +8,7 @@ const os = require("os"); const path = require("path"); const readline = require("readline"); const zlib = require("zlib"); -const { spawn } = require("child_process"); +const { spawn, spawnSync } = require("child_process"); const REPO = { owner: "cexll", name: "myclaude" }; const API_HEADERS = { @@ -931,6 +931,63 @@ async function uninstallModule(moduleName, config, repoRoot, installDir, dryRun) deleteModuleStatus(installDir, moduleName); } +async function installDefaultConfigs(installDir, repoRoot) { + try { + const claudeMdTarget = path.join(installDir, "CLAUDE.md"); + const claudeMdSrc = path.join(repoRoot, "memorys", "CLAUDE.md"); + if (!fs.existsSync(claudeMdTarget) && fs.existsSync(claudeMdSrc)) { + await fs.promises.copyFile(claudeMdSrc, claudeMdTarget); + process.stdout.write(`Installed CLAUDE.md to ${claudeMdTarget}\n`); + } + } catch (err) { + process.stderr.write(`Warning: could not install default configs: ${err.message}\n`); + } +} + +function printPostInstallInfo(installDir) { + process.stdout.write("\n"); + + // Check codeagent-wrapper version + const wrapperBin = path.join(installDir, "bin", "codeagent-wrapper"); + let wrapperVersion = null; + try { + const r = spawnSync(wrapperBin, ["--version"], { timeout: 5000 }); + if (r.status === 0 && r.stdout) { + wrapperVersion = r.stdout.toString().trim(); + } + } catch {} + + // Check PATH + const binDir = path.join(installDir, "bin"); + const envPath = process.env.PATH || ""; + const pathOk = envPath.split(path.delimiter).some((p) => { + try { return fs.realpathSync(p) === fs.realpathSync(binDir); } catch { return p === binDir; } + }); + + // Check backend CLIs + const whichCmd = process.platform === "win32" ? "where" : "which"; + const backends = ["codex", "claude", "gemini", "opencode"]; + const detected = {}; + for (const name of backends) { + try { + const r = spawnSync(whichCmd, [name], { timeout: 3000 }); + detected[name] = r.status === 0; + } catch { + detected[name] = false; + } + } + + process.stdout.write("Setup Complete!\n"); + process.stdout.write(` codeagent-wrapper: ${wrapperVersion || "(not found)"} ${wrapperVersion ? "✓" : "✗"}\n`); + process.stdout.write(` PATH: ${binDir} ${pathOk ? "✓" : "✗ (not in PATH)"}\n`); + process.stdout.write("\nBackend CLIs detected:\n"); + process.stdout.write(" " + backends.map((b) => `${b} ${detected[b] ? "✓" : "✗"}`).join(" | ") + "\n"); + process.stdout.write("\nNext steps:\n"); + process.stdout.write(" 1. Configure API keys in ~/.codeagent/models.json\n"); + process.stdout.write(' 2. Try: /do "your first task"\n'); + process.stdout.write("\n"); +} + async function installSelected(picks, tag, config, installDir, force, dryRun) { const needRepo = picks.some((p) => p.kind !== "wrapper"); const needWrapper = picks.some((p) => p.kind === "wrapper"); @@ -985,6 +1042,9 @@ async function installSelected(picks, tag, config, installDir, force, dryRun) { ); } } + + await installDefaultConfigs(installDir, repoRoot); + printPostInstallInfo(installDir); } finally { await rmTree(tmp); } diff --git a/codeagent-wrapper/USER_GUIDE.md b/codeagent-wrapper/USER_GUIDE.md index 55d46f4..b31f596 100644 --- a/codeagent-wrapper/USER_GUIDE.md +++ b/codeagent-wrapper/USER_GUIDE.md @@ -1,11 +1,11 @@ # Codeagent-Wrapper User Guide -Multi-backend AI code execution wrapper supporting Codex, Claude, and Gemini. +Multi-backend AI code execution wrapper supporting Codex, Claude, Gemini, and OpenCode. ## Overview `codeagent-wrapper` is a Go-based CLI tool that provides a unified interface to multiple AI coding backends. It handles: -- Multi-backend execution (Codex, Claude, Gemini) +- Multi-backend execution (Codex, Claude, Gemini, OpenCode) - JSON stream parsing and output formatting - Session management and resumption - Parallel task execution with dependency resolution @@ -42,6 +42,24 @@ Implement user authentication: EOF ``` +### CLI Flags + +| Flag | Description | +|------|-------------| +| `--backend ` | Select backend (codex/claude/gemini/opencode) | +| `--model ` | Override model for this invocation | +| `--agent ` | Agent preset name (from ~/.codeagent/models.json) | +| `--config ` | Path to models.json config file | +| `--cleanup` | Clean up log files on startup | +| `--worktree` | Execute in a new git worktree (auto-generates task ID) | +| `--skills ` | Comma-separated skill names for spec injection | +| `--prompt-file ` | Read prompt from file | +| `--reasoning-effort ` | Set reasoning effort (low/medium/high) | +| `--skip-permissions` | Skip permission prompts | +| `--parallel` | Enable parallel task execution | +| `--full-output` | Show full output in parallel mode | +| `--version`, `-v` | Print version and exit | + ### Backend Selection | Backend | Command | Best For | @@ -49,6 +67,7 @@ EOF | **Codex** | `--backend codex` | General code tasks (default) | | **Claude** | `--backend claude` | Complex reasoning, architecture | | **Gemini** | `--backend gemini` | Fast iteration, prototyping | +| **OpenCode** | `--backend opencode` | Open-source alternative | ## Core Features diff --git a/config.json b/config.json index 18ae2d6..d8907aa 100644 --- a/config.json +++ b/config.json @@ -39,6 +39,36 @@ "omo": { "enabled": false, "description": "OmO multi-agent orchestration with Sisyphus coordinator", + "agents": { + "oracle": { + "backend": "claude", + "model": "claude-opus-4-5-20251101", + "yolo": true + }, + "librarian": { + "backend": "claude", + "model": "claude-sonnet-4-5-20250929", + "yolo": true + }, + "explore": { + "backend": "opencode", + "model": "opencode/grok-code" + }, + "develop": { + "backend": "codex", + "model": "gpt-5.2", + "reasoning": "xhigh", + "yolo": true + }, + "frontend-ui-ux-engineer": { + "backend": "gemini", + "model": "gemini-3-pro-preview" + }, + "document-writer": { + "backend": "gemini", + "model": "gemini-3-flash-preview" + } + }, "operations": [ { "type": "copy_file", @@ -98,7 +128,27 @@ }, "do": { "enabled": true, - "description": "7-phase feature development workflow with codeagent orchestration", + "description": "5-phase feature development workflow with codeagent orchestration", + "agents": { + "develop": { + "backend": "codex", + "model": "gpt-4.1", + "reasoning": "high", + "yolo": true + }, + "code-explorer": { + "backend": "opencode", + "model": "" + }, + "code-architect": { + "backend": "claude", + "model": "" + }, + "code-reviewer": { + "backend": "claude", + "model": "" + } + }, "operations": [ { "type": "copy_dir", @@ -148,7 +198,7 @@ }, "claudekit": { "enabled": false, - "description": "ClaudeKit workflow: skills/do + global hooks (pre-bash, inject-spec, log-prompt, on-stop)", + "description": "ClaudeKit workflow: skills/do + global hooks (pre-bash, inject-spec, log-prompt)", "operations": [ { "type": "copy_dir", @@ -160,7 +210,7 @@ "type": "copy_dir", "source": "hooks", "target": "hooks", - "description": "Install global hooks (pre-bash, inject-spec, log-prompt, on-stop)" + "description": "Install global hooks (pre-bash, inject-spec, log-prompt)" } ] } diff --git a/install.py b/install.py index 0528f73..05c55f7 100644 --- a/install.py +++ b/install.py @@ -244,6 +244,112 @@ def unmerge_hooks_from_settings(module_name: str, ctx: Dict[str, Any]) -> None: write_log({"level": "INFO", "message": f"Removed hooks for module: {module_name}"}, ctx) +def merge_agents_to_models(module_name: str, agents: Dict[str, Any], ctx: Dict[str, Any]) -> None: + """Merge module agent configs into ~/.codeagent/models.json.""" + models_path = Path.home() / ".codeagent" / "models.json" + models_path.parent.mkdir(parents=True, exist_ok=True) + + if models_path.exists(): + with models_path.open("r", encoding="utf-8") as fh: + models = json.load(fh) + else: + template = ctx["config_dir"] / "templates" / "models.json.example" + if template.exists(): + with template.open("r", encoding="utf-8") as fh: + models = json.load(fh) + # Clear template agents so modules populate with __module__ tags + models["agents"] = {} + else: + models = { + "default_backend": "codex", + "default_model": "gpt-4.1", + "backends": {}, + "agents": {}, + } + + models.setdefault("agents", {}) + for agent_name, agent_cfg in agents.items(): + entry = dict(agent_cfg) + entry["__module__"] = module_name + + existing = models["agents"].get(agent_name, {}) + if not existing or existing.get("__module__"): + models["agents"][agent_name] = entry + + with models_path.open("w", encoding="utf-8") as fh: + json.dump(models, fh, indent=2, ensure_ascii=False) + + write_log( + { + "level": "INFO", + "message": ( + f"Merged {len(agents)} agent(s) from {module_name} " + "into models.json" + ), + }, + ctx, + ) + + +def unmerge_agents_from_models(module_name: str, ctx: Dict[str, Any]) -> None: + """Remove module's agent configs from ~/.codeagent/models.json. + + If another installed module also declares a removed agent, restore that + module's version so shared agents (e.g. 'develop') are not lost. + """ + models_path = Path.home() / ".codeagent" / "models.json" + if not models_path.exists(): + return + + with models_path.open("r", encoding="utf-8") as fh: + models = json.load(fh) + + agents = models.get("agents", {}) + to_remove = [ + name + for name, cfg in agents.items() + if isinstance(cfg, dict) and cfg.get("__module__") == module_name + ] + + if not to_remove: + return + + # Load config to find other modules that declare the same agents + config_path = ctx["config_dir"] / "config.json" + config = _load_json(config_path) if config_path.exists() else {} + installed = load_installed_status(ctx).get("modules", {}) + + for name in to_remove: + del agents[name] + # Check if another installed module also declares this agent + for other_mod, other_status in installed.items(): + if other_mod == module_name: + continue + if other_status.get("status") != "success": + continue + other_cfg = config.get("modules", {}).get(other_mod, {}) + other_agents = other_cfg.get("agents", {}) + if name in other_agents: + restored = dict(other_agents[name]) + restored["__module__"] = other_mod + agents[name] = restored + break + + with models_path.open("w", encoding="utf-8") as fh: + json.dump(models, fh, indent=2, ensure_ascii=False) + + write_log( + { + "level": "INFO", + "message": ( + f"Removed {len(to_remove)} agent(s) from {module_name} " + "in models.json" + ), + }, + ctx, + ) + + def _hooks_equal(hook1: Dict[str, Any], hook2: Dict[str, Any]) -> bool: """Compare two hooks ignoring the __module__ marker.""" h1 = {k: v for k, v in hook1.items() if k != "__module__"} @@ -545,6 +651,14 @@ def uninstall_module(name: str, cfg: Dict[str, Any], ctx: Dict[str, Any]) -> Dic target.unlink() removed_paths.append(str(target)) write_log({"level": "INFO", "message": f"Removed: {target}"}, ctx) + # Clean up empty parent directories up to install_dir + parent = target.parent + while parent != install_dir and parent.exists(): + try: + parent.rmdir() + except OSError: + break + parent = parent.parent elif op_type == "merge_dir": if not merge_dir_files: write_log( @@ -604,6 +718,13 @@ def uninstall_module(name: str, cfg: Dict[str, Any], ctx: Dict[str, Any]) -> Dic except Exception as exc: write_log({"level": "WARNING", "message": f"Failed to remove hooks for {name}: {exc}"}, ctx) + # Remove module agents from ~/.codeagent/models.json + try: + unmerge_agents_from_models(name, ctx) + result["agents_removed"] = True + except Exception as exc: + write_log({"level": "WARNING", "message": f"Failed to remove agents for {name}: {exc}"}, ctx) + result["removed_paths"] = removed_paths return result @@ -626,7 +747,9 @@ def update_status_after_uninstall(uninstalled_modules: List[str], ctx: Dict[str, def interactive_manage(config: Dict[str, Any], ctx: Dict[str, Any]) -> int: - """Interactive module management menu.""" + """Interactive module management menu. Returns 0 on success, 1 on error. + Sets ctx['_did_install'] = True if any module was installed.""" + ctx.setdefault("_did_install", False) while True: installed_status = get_installed_modules(config, ctx) modules = config.get("modules", {}) @@ -695,6 +818,7 @@ def interactive_manage(config: Dict[str, Any], ctx: Dict[str, Any]) -> int: for r in results: if r.get("status") == "success": current_status.setdefault("modules", {})[r["module"]] = r + ctx["_did_install"] = True current_status["updated_at"] = datetime.now().isoformat() with Path(ctx["status_file"]).open("w", encoding="utf-8") as fh: json.dump(current_status, fh, indent=2, ensure_ascii=False) @@ -819,6 +943,17 @@ def execute_module(name: str, cfg: Dict[str, Any], ctx: Dict[str, Any]) -> Dict[ write_log({"level": "WARNING", "message": f"Failed to merge hooks for {name}: {exc}"}, ctx) result["operations"].append({"type": "merge_hooks", "status": "failed", "error": str(exc)}) + # Handle agents: merge module agent configs into ~/.codeagent/models.json + module_agents = cfg.get("agents", {}) + if module_agents: + try: + merge_agents_to_models(name, module_agents, ctx) + result["operations"].append({"type": "merge_agents", "status": "success"}) + result["has_agents"] = True + except Exception as exc: + write_log({"level": "WARNING", "message": f"Failed to merge agents for {name}: {exc}"}, ctx) + result["operations"].append({"type": "merge_agents", "status": "failed", "error": str(exc)}) + return result @@ -1060,6 +1195,67 @@ def write_status(results: List[Dict[str, Any]], ctx: Dict[str, Any]) -> None: json.dump(status, fh, indent=2, ensure_ascii=False) +def install_default_configs(ctx: Dict[str, Any]) -> None: + """Copy default config files if they don't already exist. Best-effort: never raises.""" + try: + install_dir = ctx["install_dir"] + config_dir = ctx["config_dir"] + + # Copy memorys/CLAUDE.md -> {install_dir}/CLAUDE.md + claude_md_src = config_dir / "memorys" / "CLAUDE.md" + claude_md_dst = install_dir / "CLAUDE.md" + if not claude_md_dst.exists() and claude_md_src.exists(): + shutil.copy2(claude_md_src, claude_md_dst) + print(f" Installed CLAUDE.md to {claude_md_dst}") + write_log({"level": "INFO", "message": f"Installed CLAUDE.md to {claude_md_dst}"}, ctx) + except Exception as exc: + print(f" Warning: could not install default configs: {exc}", file=sys.stderr) + + +def print_post_install_info(ctx: Dict[str, Any]) -> None: + """Print post-install verification and setup guidance.""" + install_dir = ctx["install_dir"] + + # Check codeagent-wrapper version + wrapper_bin = install_dir / "bin" / "codeagent-wrapper" + wrapper_version = None + try: + result = subprocess.run( + [str(wrapper_bin), "--version"], + capture_output=True, text=True, timeout=5, + ) + if result.returncode == 0: + wrapper_version = result.stdout.strip() + except Exception: + pass + + # Check PATH + bin_dir = str(install_dir / "bin") + env_path = os.environ.get("PATH", "") + path_ok = any( + os.path.realpath(p) == os.path.realpath(bin_dir) + if os.path.exists(p) else p == bin_dir + for p in env_path.split(os.pathsep) + ) + + # Check backend CLIs + backends = ["codex", "claude", "gemini", "opencode"] + detected = {name: shutil.which(name) is not None for name in backends} + + print("\nSetup Complete!") + v_mark = "✓" if wrapper_version else "✗" + print(f" codeagent-wrapper: {wrapper_version or '(not found)'} {v_mark}") + p_mark = "✓" if path_ok else "✗ (not in PATH)" + print(f" PATH: {bin_dir} {p_mark}") + print("\nBackend CLIs detected:") + cli_parts = [f"{b} {'✓' if detected[b] else '✗'}" for b in backends] + print(" " + " | ".join(cli_parts)) + print("\nNext steps:") + print(" 1. Configure API keys in ~/.codeagent/models.json") + print(' 2. Try: /do "your first task"') + print() + + def prepare_status_backup(ctx: Dict[str, Any]) -> None: status_path = Path(ctx["status_file"]) if status_path.exists(): @@ -1208,6 +1404,8 @@ def main(argv: Optional[Iterable[str]] = None) -> int: failed = len(results) - success if failed == 0: print(f"\n✓ Update complete: {success} module(s) updated") + install_default_configs(ctx) + print_post_install_info(ctx) else: print(f"\n⚠ Update finished with errors: {success} success, {failed} failed") if not args.force: @@ -1221,7 +1419,11 @@ def main(argv: Optional[Iterable[str]] = None) -> int: except Exception as exc: print(f"Failed to prepare install dir: {exc}", file=sys.stderr) return 1 - return interactive_manage(config, ctx) + result = interactive_manage(config, ctx) + if result == 0 and ctx.get("_did_install"): + install_default_configs(ctx) + print_post_install_info(ctx) + return result # Install specified modules modules = select_modules(config, args.module) @@ -1280,6 +1482,10 @@ def main(argv: Optional[Iterable[str]] = None) -> int: if not args.force: return 1 + if failed == 0: + install_default_configs(ctx) + print_post_install_info(ctx) + return 0 diff --git a/package.json b/package.json index 3de0388..4d516ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "myclaude", - "version": "0.0.0", + "version": "6.7.0", "private": true, "description": "Claude Code multi-agent workflows (npx installer)", "license": "AGPL-3.0", @@ -13,6 +13,7 @@ "agents/", "skills/", "memorys/", + "templates/", "codeagent-wrapper/", "config.json", "install.py", diff --git a/templates/models.json.example b/templates/models.json.example new file mode 100644 index 0000000..4106aa1 --- /dev/null +++ b/templates/models.json.example @@ -0,0 +1,52 @@ +{ + "default_backend": "codex", + "default_model": "gpt-5.2", + "backends": { + "codex": { "api_key": "" }, + "claude": { "api_key": "" }, + "gemini": { "api_key": "" }, + "opencode": { "api_key": "" } + }, + "agents": { + "develop": { + "backend": "codex", + "model": "gpt-5.2", + "reasoning": "xhigh", + "yolo": true + }, + "code-explorer": { + "backend": "opencode", + "model": "" + }, + "code-architect": { + "backend": "claude", + "model": "" + }, + "code-reviewer": { + "backend": "claude", + "model": "" + }, + "oracle": { + "backend": "claude", + "model": "claude-opus-4-5-20251101", + "yolo": true + }, + "librarian": { + "backend": "claude", + "model": "claude-sonnet-4-5-20250929", + "yolo": true + }, + "explore": { + "backend": "opencode", + "model": "opencode/grok-code" + }, + "frontend-ui-ux-engineer": { + "backend": "gemini", + "model": "gemini-3-pro-preview" + }, + "document-writer": { + "backend": "gemini", + "model": "gemini-3-flash-preview" + } + } +}