jvibe 1.1.5 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/JVIBE.md +1 -1
  3. package/README.md +143 -1
  4. package/lib/migrate.js +116 -24
  5. package/lib/migrations/index.js +55 -0
  6. package/lib/plugins/registry.json +54 -0
  7. package/package.json +2 -1
  8. package/scripts/init.js +2 -0
  9. package/scripts/setup.js +307 -18
  10. package/scripts/status.js +87 -0
  11. package/scripts/validate.js +125 -0
  12. package/template/.claude/agents/bugfix.md +178 -19
  13. package/template/.claude/agents/developer.md +139 -32
  14. package/template/.claude/agents/doc-sync.md +206 -72
  15. package/template/.claude/agents/planner.md +129 -28
  16. package/template/.claude/agents/reviewer.md +120 -66
  17. package/template/.claude/agents/tester.md +154 -27
  18. package/template/.claude/commands/JVibe:keepgo.md +68 -43
  19. package/template/.claude/error-handling.md +8 -2
  20. package/template/.claude/hooks/load-context.sh +3 -3
  21. package/template/.claude/hooks/load-jvibe-full-context.sh +285 -0
  22. package/template/.claude/hooks/sync-jvibe-context.sh +254 -0
  23. package/template/.claude/settings.json +21 -3
  24. package/template/.jvibe-doc-hash.json +9 -0
  25. package/template/.opencode/agent/bugfix.md +138 -19
  26. package/template/.opencode/agent/developer.md +125 -27
  27. package/template/.opencode/agent/doc-sync.md +169 -39
  28. package/template/.opencode/agent/planner.md +131 -30
  29. package/template/.opencode/agent/reviewer.md +100 -47
  30. package/template/.opencode/agent/tester.md +114 -28
  31. package/template/.opencode/command/jvibe-keepgo.md +68 -43
  32. package/template/.opencode/error-handling.md +8 -2
  33. package/template/docs/.jvibe/agent-contracts.yaml +188 -0
  34. package/template/docs/.jvibe/plugins.yaml +16 -0
  35. package/template/docs/core/Appendix.md +12 -1
  36. package/template/docs/core/Feature-List.md +9 -0
  37. package/template/docs/core/Project.md +19 -0
  38. package/template/docs/core/Standards.md +65 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,88 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.1.8] - 2026-01-19
9
+
10
+ ### Added
11
+
12
+ - **Agent I/O 协议统一** (`agent-contracts.yaml`)
13
+ - 新增 `docs/.jvibe/agent-contracts.yaml` 作为 subagent 输入输出的单一事实来源
14
+ - 定义了 `planner`、`developer`、`tester`、`bugfix`、`doc-sync` 的 `task_input` 与输出结构
15
+ - 包含硬规则 (HR-001 ~ HR-003) 约束 subagent 行为
16
+
17
+ - **插件管理配置** (`plugins.yaml`)
18
+ - 新增 `docs/.jvibe/plugins.yaml` 管理工具与插件启用状态
19
+ - 区分 `core_plugins`(核心工具)与 `project_plugins`(项目按需)
20
+
21
+ - **上下文最小化原则**
22
+ - 所有 Agent 新增"硬规则"章节,禁止全仓库扫描
23
+ - `developer`: 只在 `code_roots`/`test_roots` 范围内读取与修改
24
+ - `tester`: 新增 `mode: targeted | discover` 双模式
25
+ - `bugfix`: 优先使用 tester 报告的 `failures`/`modules_hit`/`files`
26
+
27
+ - **Tester 双模式支持**
28
+ - `targeted`: 给定 `files`,精确限制测试范围
29
+ - `discover`: 允许从测试输出反推落点文件,解决"用户报错但不知道 F-XXX"场景
30
+ - 新增 `issue` 字段用于 discover 模式的问题描述
31
+
32
+ - **Keepgo 用户报错判定**
33
+ - 新增关键词匹配(报错/失败/异常/bug/error 等)自动识别用户报告的问题
34
+ - 支持 `feature_id=null` 时进入 discover 测试流程
35
+ - 新增 `user_reported_issue`、`user_reported_feature_id`、`user_issue` 状态字段
36
+
37
+ ### Changed
38
+
39
+ - **测试失败分流策略**
40
+ - 从简单的 `return_to_developer` 改为 `triage_then_fix` 策略
41
+ - 多模块/核心模块/用户强制 → 调用 `bugfix`
42
+ - 单模块/简单问题 → 回退到 `developer`
43
+
44
+ - **Handoff Payload 结构**
45
+ - 新增 `mode` 字段(`targeted`/`discover`)
46
+ - `files` 字段在 targeted 模式下必填且非空
47
+ - `feature_id` 允许为 `null`
48
+
49
+ - **文档更新条件**
50
+ - `doc_updates` 仅在 `pass` 且 `feature_id` 非空时执行
51
+ - 避免无法关联功能编号时错误更新状态
52
+
53
+ - **Standards.md**
54
+ - 新增 §2.6 Tools & Plugins 章节说明工具与插件概念
55
+
56
+ ### Fixed
57
+
58
+ - **Hook 脚本 grep 错误处理**
59
+ - 修复 `grep -c ... || true` 导致空字符串的问题
60
+ - 改为 `|| echo 0` 确保输出为数字,避免后续算术运算错误
61
+ - 影响文件:`load-context.sh`、`load-jvibe-full-context.sh`、`sync-jvibe-context.sh`
62
+
63
+ ## [1.1.7] - 2026-01-18
64
+
65
+ ### Added
66
+
67
+ - Hooks 自动加载和同步 JVibe 上下文
68
+
69
+ ### Fixed
70
+
71
+ - Hooks 脚本 jq-free 重写,fail-open 模式
72
+
73
+ ## [1.1.6] - 2026-01-17
74
+
75
+ ### Added
76
+
77
+ - Context hooks 自动加载功能
78
+
79
+ ---
80
+
81
+ ## Summary of v1.1.8
82
+
83
+ This release introduces a major architectural improvement focused on **context minimization** and **unified I/O contracts** for subagents:
84
+
85
+ 1. **Single Source of Truth**: `agent-contracts.yaml` defines all subagent input/output schemas
86
+ 2. **Dual-mode Testing**: `targeted` (precise) vs `discover` (user-reported issues without F-XXX)
87
+ 3. **Smarter Dispatch**: Main agent no longer directly fixes code; uses `bugfix` for complex issues
88
+ 4. **Robust Hooks**: Fixed shell script arithmetic errors with proper fallback values
package/JVIBE.md CHANGED
@@ -75,7 +75,7 @@ TODO 完成情况 → 功能状态
75
75
  5. **测试自动派发**:TODO 包含“测试/test”时,进入测试阶段必须自动调用 tester,无需用户手动指定
76
76
  6. **已有项目初始化**:若项目已有代码/文档,/JVibe:init 应先扫描现有项目并用扫描结果填充 Project 与 Feature-List
77
77
  7. **Bugfix 调用**:tester 报告失败且问题涉及**多模块**或**核心模块**时才调用 bugfix;否则回退给 developer。用户明确要求时可直接调用
78
- 8. **MCP 权限**:主 Agent 与所有 Sub-Agents 允许直接调用 MCP 工具进行查询/集成操作
78
+ 8. **Tools/Plugins 权限**:主 Agent 与所有 Sub-Agents 允许直接调用 Tools/Plugins 进行查询/集成操作(包括 MCP Server、Skills、Daemon 等)
79
79
 
80
80
  保持此管理块,以便 `jvibe upgrade` 更新指令。
81
81
  <!-- JVIBE:END -->
package/README.md CHANGED
@@ -1,9 +1,39 @@
1
+ <div align="center">
2
+
1
3
  # JVibe
2
4
 
3
- > 文档驱动的 AI 辅助开发系统
5
+ **文档驱动的 AI 辅助开发系统**
6
+
7
+ *Doc-driven AI-assisted Development System for Claude Code & OpenCode*
4
8
 
5
9
  [![npm version](https://badge.fury.io/js/jvibe.svg)](https://badge.fury.io/js/jvibe)
10
+ [![npm downloads](https://img.shields.io/npm/dm/jvibe.svg)](https://www.npmjs.com/package/jvibe)
6
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D16.0.0-brightgreen)](https://nodejs.org/)
13
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/9963KK/VibeCoding-Tech/pulls)
14
+
15
+ [快速开始](#-快速开始) · [使用方法](#-使用方法一览) · [文档](#-文档) · [贡献](#-贡献)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## 目录
22
+
23
+ - [什么是 JVibe?](#-什么是-jvibe)
24
+ - [为什么选择 JVibe?](#-为什么选择-jvibe)
25
+ - [快速开始](#-快速开始)
26
+ - [使用方法一览](#-使用方法一览)
27
+ - [典型使用场景](#-典型使用场景)
28
+ - [项目结构](#-项目结构)
29
+ - [文档体系](#-文档体系)
30
+ - [Agent 架构](#-agent-架构)
31
+ - [CLI 命令](#-cli-命令)
32
+ - [核心原则](#-核心原则)
33
+ - [���见问题](#-常见问题)
34
+ - [文档](#-文档)
35
+ - [贡献](#-贡献)
36
+ - [许可证](#-许可证)
7
37
 
8
38
  ---
9
39
 
@@ -18,6 +48,35 @@ JVibe 是一个**文档驱动的 AI 辅助开发系统**,面向 Claude Code
18
48
 
19
49
  ---
20
50
 
51
+ ## 💡 为什么选择 JVibe?
52
+
53
+ | 痛点 | JVibe 解决方案 |
54
+ |------|---------------|
55
+ | AI 缺乏项目上下文,每次都要重复解释 | 自动加载项目文档,AI 开箱即知项目全貌 |
56
+ | 功能状态散落各处,难以追踪 | 单一事实来源(SoT),状态只在一处维护 |
57
+ | AI 生成代码质量参差不齐 | 多 Agent 分工协作,专业的事交给专业的 Agent |
58
+ | 文档与代码脱节,维护困难 | 文档驱动开发,代码变更自动触发文档同步 |
59
+ | 团队协作时上下文丢失 | 结构化任务交接文件,无缝衔接工作进度 |
60
+
61
+ **核心优势**:
62
+
63
+ ```
64
+ ┌─────────────────────────────────────────────────────────────┐
65
+ │ JVibe 工作流 │
66
+ ├─────────────────────────────────────────────────────────────┤
67
+ │ │
68
+ │ 需求 ──→ planner ──→ developer ──→ tester ──→ reviewer │
69
+ │ │ │ │ │ │
70
+ │ └──────────────────────┴────────────┴───────────┘ │
71
+ │ ↓ │
72
+ │ doc-sync │
73
+ │ (自动同步状态) │
74
+ │ │
75
+ └─────────────────────────────────────────────────────────────┘
76
+ ```
77
+
78
+ ---
79
+
21
80
  ## 🚀 快速开始
22
81
 
23
82
  ### 初始化方式(选一种)
@@ -281,12 +340,83 @@ JVibe 基于以下原则设计:
281
340
 
282
341
  ---
283
342
 
343
+ ## ❓ 常见问题
344
+
345
+ <details>
346
+ <summary><b>JVibe 支持哪些 AI 编码工具?</b></summary>
347
+
348
+ 目前支持:
349
+ - **Claude Code** - Anthropic 官方 CLI 工具
350
+ - **OpenCode** - 开源 AI 编码助手
351
+
352
+ 通过 `--adapter` 参数选择适配器,或使用 `--adapter=both` 同时支持两者。
353
+ </details>
354
+
355
+ <details>
356
+ <summary><b>已有项目如何接入 JVibe?</b></summary>
357
+
358
+ 推荐使用 `/JVibe:init` 命令(在 Claude Code 中)或 `/jvibe-init`(在 OpenCode 中)。AI 会自动扫描现有代码和文档,生成符合项目现状的 Feature-List 和 Project 文档。
359
+ </details>
360
+
361
+ <details>
362
+ <summary><b>CORE-DOCS 和 PROJECT-DOCS 有什么区别?</b></summary>
363
+
364
+ - **CORE-DOCS**:固定 4 个核心文档,所有项目结构相同,自动存在
365
+ - **PROJECT-DOCS**:按需创建的扩展文档(如 API 文档、数据库文档),必须在规范文档中注册
366
+
367
+ 详见 [CORE vs PROJECT 文档](docs/CORE_VS_PROJECT_DOCS.md)。
368
+ </details>
369
+
370
+ <details>
371
+ <summary><b>如何升级到新版本?</b></summary>
372
+
373
+ ```bash
374
+ # 检查是否有新版本
375
+ jvibe upgrade --check
376
+
377
+ # 执行升级(会提示确认)
378
+ jvibe upgrade
379
+
380
+ # 强制升级(跳过确认)
381
+ jvibe upgrade --force
382
+ ```
383
+ </details>
384
+
385
+ <details>
386
+ <summary><b>Agent 之间如何协作?</b></summary>
387
+
388
+ JVibe 采用流水线式协作:
389
+ 1. `planner` 分析需求,拆解为 TODO 列表
390
+ 2. `developer` 逐项完成 TODO,编写代码
391
+ 3. `tester` 执行测试,验证功能
392
+ 4. `bugfix` 处理复杂 bug(多模块/核心模块问题)
393
+ 5. `reviewer` 代码审查,确保质量
394
+ 6. `doc-sync` 自动同步文档状态
395
+
396
+ 使用 `/JVibe:keepgo` 可自动推进到下一阶段。
397
+ </details>
398
+
399
+ <details>
400
+ <summary><b>如何卸载 JVibe?</b></summary>
401
+
402
+ ```bash
403
+ # 卸载项目内的 JVibe 配置
404
+ jvibe uninstall
405
+
406
+ # 全局卸载
407
+ npm uninstall -g jvibe
408
+ ```
409
+ </details>
410
+
411
+ ---
412
+
284
413
  ## 📖 文档
285
414
 
286
415
  - [快速开始指南](docs/GETTING_STARTED.md)
287
416
  - [CLI 命令参考](docs/CLI_COMMANDS.md)
288
417
  - [架构说明](docs/ARCHITECTURE.md)
289
418
  - [CORE vs PROJECT 文档](docs/CORE_VS_PROJECT_DOCS.md)
419
+ - [Tools & Plugins(工具与插件)](docs/TOOLS_AND_PLUGINS.md)
290
420
  - [贡献指南](docs/CONTRIBUTING.md)
291
421
 
292
422
  ---
@@ -314,3 +444,15 @@ JVibe 基于以下原则设计:
314
444
  - [Claude Code 官方文档](https://docs.anthropic.com/claude-code)
315
445
  - [OpenCode 官方文档](https://opencode.ai/docs)
316
446
  - [OpenSpec](https://github.com/openspec/openspec) - 灵感来源
447
+ - [GitHub Issues](https://github.com/9963KK/VibeCoding-Tech/issues) - 问题反馈
448
+ - [NPM Package](https://www.npmjs.com/package/jvibe) - NPM 主页
449
+
450
+ ---
451
+
452
+ <div align="center">
453
+
454
+ **如果 JVibe 对你有帮助,请给个 ⭐ Star 支持一下!**
455
+
456
+ Made with ❤️ by [9963KK](https://github.com/9963KK)
457
+
458
+ </div>
package/lib/migrate.js CHANGED
@@ -471,6 +471,7 @@ async function inferOpencodeVersionFromStructure(opencodeDir) {
471
471
  path.join('agent', 'planner.md'),
472
472
  path.join('agent', 'developer.md'),
473
473
  path.join('agent', 'tester.md'),
474
+ path.join('agent', 'bugfix.md'),
474
475
  path.join('agent', 'reviewer.md'),
475
476
  path.join('agent', 'doc-sync.md')
476
477
  ];
@@ -584,16 +585,25 @@ async function checkContentMigration(projectDir, currentVersion) {
584
585
  * @returns {Promise<MigrationPlan>}
585
586
  */
586
587
  async function getMigrationPlan(projectDir, versionInfo) {
588
+ const latestVersion = pkg.version || null;
589
+ const currentVersion = versionInfo.version || null;
590
+ const versionMismatch = Boolean(latestVersion && currentVersion && currentVersion !== latestVersion);
591
+
587
592
  const plan = {
588
- needsMigration: versionInfo.isLegacy,
593
+ // needsMigration 表示“是否需要执行自动迁移动作”,不等同于 isLegacy
594
+ needsMigration: false,
589
595
  needsAIMigration: versionInfo.contentMigration.required,
590
596
  tasks: [],
591
597
  aiTasks: [],
592
598
  details: {
593
599
  docsToMove: [],
600
+ hooksNeedUpdate: false,
594
601
  hooksToUpdate: [],
602
+ commandsNeedUpdate: false,
595
603
  commandsToRename: [],
604
+ agentsNeedUpdate: false,
596
605
  agentsToUpdate: [],
606
+ opencodeNeedUpdate: false,
597
607
  configToUpdate: false,
598
608
  contentChanges: versionInfo.contentMigration.changes || []
599
609
  }
@@ -606,7 +616,7 @@ async function getMigrationPlan(projectDir, versionInfo) {
606
616
  }
607
617
  }
608
618
 
609
- if (!versionInfo.isLegacy && !versionInfo.contentMigration.required) {
619
+ if (!versionInfo.isLegacy && !versionInfo.contentMigration.required && !versionMismatch) {
610
620
  return plan;
611
621
  }
612
622
 
@@ -642,7 +652,8 @@ async function getMigrationPlan(projectDir, versionInfo) {
642
652
  if (await fs.pathExists(hooksDir)) {
643
653
  const hookFiles = await fs.readdir(hooksDir);
644
654
  const legacyHookIssues = await checkLegacyHooks(hooksDir);
645
- if (legacyHookIssues.length > 0) {
655
+ if (legacyHookIssues.length > 0 || versionMismatch) {
656
+ plan.details.hooksNeedUpdate = true;
646
657
  plan.details.hooksToUpdate = hookFiles.filter(f => f.endsWith('.sh'));
647
658
  plan.tasks.push('更新 hooks 脚本到最新版本');
648
659
  }
@@ -660,21 +671,49 @@ async function getMigrationPlan(projectDir, versionInfo) {
660
671
  plan.details.commandsToRename.push({ from: cmd, to: newName });
661
672
  plan.tasks.push(`重命名 command: ${cmd} → ${newName}`);
662
673
  }
674
+
675
+ if (legacyCommands.length > 0 || versionMismatch) {
676
+ plan.details.commandsNeedUpdate = true;
677
+ if (legacyCommands.length === 0) {
678
+ plan.tasks.push('更新 commands 到最新版本');
679
+ }
680
+ }
663
681
  }
664
682
 
665
683
  // 4. 检查 agents 更新需求
666
684
  const agentsDir = path.join(projectDir, '.claude/agents');
667
685
  if (await fs.pathExists(agentsDir)) {
668
- plan.details.agentsToUpdate = ['planner.md', 'developer.md', 'reviewer.md', 'doc-sync.md'];
686
+ plan.details.agentsNeedUpdate = true;
687
+ plan.details.agentsToUpdate = ['planner.md', 'developer.md', 'tester.md', 'reviewer.md', 'doc-sync.md', 'bugfix.md'];
669
688
  plan.tasks.push('更新所有 agents 到最新版本');
670
689
  }
671
690
 
672
- // 5. 配置更新
673
- if (!versionInfo.version) {
691
+ // 5. OpenCode 配置更新
692
+ const opencodeDir = path.join(projectDir, '.opencode');
693
+ if (await fs.pathExists(opencodeDir)) {
694
+ if (versionInfo.isLegacy || versionMismatch) {
695
+ plan.details.opencodeNeedUpdate = true;
696
+ plan.tasks.push('更新 OpenCode 配置到最新版本');
697
+ }
698
+ }
699
+
700
+ // 6. 配置更新
701
+ if (!versionInfo.version || versionMismatch) {
674
702
  plan.details.configToUpdate = true;
675
- plan.tasks.push('更新 settings.json 添加版本信息');
703
+ plan.tasks.push('更新版本信息(settings.json / jvibe.json)');
676
704
  }
677
705
 
706
+ // 最终 needsMigration:只要存在任一自动迁移动作即可
707
+ plan.needsMigration = Boolean(
708
+ plan.details.docsToMove.length > 0 ||
709
+ plan.details.hooksNeedUpdate ||
710
+ plan.details.commandsNeedUpdate ||
711
+ plan.details.commandsToRename.length > 0 ||
712
+ plan.details.agentsNeedUpdate ||
713
+ plan.details.opencodeNeedUpdate ||
714
+ plan.details.configToUpdate
715
+ );
716
+
678
717
  return plan;
679
718
  }
680
719
 
@@ -760,30 +799,76 @@ async function migrateAgents(projectDir, templateDir) {
760
799
  console.log(chalk.gray(' 已更新 agents'));
761
800
  }
762
801
 
802
+ /**
803
+ * 执行 OpenCode 配置迁移(覆盖同步)
804
+ * @param {string} projectDir - 项目目录
805
+ * @param {string} templateDir - 模板目录
806
+ */
807
+ async function migrateOpencode(projectDir, templateDir) {
808
+ const projectOpencodeDir = path.join(projectDir, '.opencode');
809
+ const templateOpencodeDir = path.join(templateDir, '.opencode');
810
+
811
+ if (!await fs.pathExists(projectOpencodeDir)) {
812
+ return;
813
+ }
814
+ if (!await fs.pathExists(templateOpencodeDir)) {
815
+ return;
816
+ }
817
+
818
+ await fs.copy(templateOpencodeDir, projectOpencodeDir, { overwrite: true });
819
+ console.log(chalk.gray(' 已更新 OpenCode 配置'));
820
+ }
821
+
763
822
  /**
764
823
  * 更新配置文件
765
824
  * @param {string} projectDir - 项目目录
766
825
  * @param {string} newVersion - 新版本号
767
826
  */
768
827
  async function updateConfig(projectDir, newVersion) {
769
- const settingsPath = path.join(projectDir, '.claude/settings.json');
828
+ const migratedAt = new Date().toISOString();
770
829
 
771
- let settings = {};
772
- if (await fs.pathExists(settingsPath)) {
773
- try {
774
- settings = await fs.readJson(settingsPath);
775
- } catch (e) {
776
- // 如果读取失败,创建新的配置
830
+ // Claude Code settings
831
+ const claudeDir = path.join(projectDir, '.claude');
832
+ if (await fs.pathExists(claudeDir)) {
833
+ const settingsPath = path.join(claudeDir, 'settings.json');
834
+ let settings = {};
835
+ if (await fs.pathExists(settingsPath)) {
836
+ try {
837
+ settings = await fs.readJson(settingsPath);
838
+ } catch (e) {
839
+ // 如果读取失败,创建新的配置
840
+ }
777
841
  }
842
+
843
+ settings.jvibe = {
844
+ ...settings.jvibe,
845
+ version: newVersion,
846
+ migratedAt
847
+ };
848
+
849
+ await fs.writeJson(settingsPath, settings, { spaces: 2 });
778
850
  }
779
851
 
780
- settings.jvibe = {
781
- ...settings.jvibe,
782
- version: newVersion,
783
- migratedAt: new Date().toISOString()
784
- };
852
+ // OpenCode meta
853
+ const opencodeDir = path.join(projectDir, '.opencode');
854
+ if (await fs.pathExists(opencodeDir)) {
855
+ const opencodeMetaPath = path.join(opencodeDir, 'jvibe.json');
856
+ let meta = {};
857
+ if (await fs.pathExists(opencodeMetaPath)) {
858
+ try {
859
+ meta = await fs.readJson(opencodeMetaPath);
860
+ } catch (e) {
861
+ // ignore
862
+ }
863
+ }
864
+ meta = {
865
+ ...meta,
866
+ version: newVersion,
867
+ migratedAt
868
+ };
869
+ await fs.writeJson(opencodeMetaPath, meta, { spaces: 2 });
870
+ }
785
871
 
786
- await fs.writeJson(settingsPath, settings, { spaces: 2 });
787
872
  console.log(chalk.gray(' 已更新版本信息'));
788
873
  }
789
874
 
@@ -857,24 +942,30 @@ async function executeMigration(projectDir, templateDir, plan, newVersion) {
857
942
  await migrateFeatureList(projectDir);
858
943
 
859
944
  // 3. 迁移 hooks
860
- if (plan.details.hooksToUpdate.length > 0) {
945
+ if (plan.details.hooksNeedUpdate) {
861
946
  console.log(chalk.gray(' 更新 hooks...'));
862
947
  await migrateHooks(projectDir, templateDir);
863
948
  }
864
949
 
865
950
  // 4. 迁移 commands
866
- if (plan.details.commandsToRename.length > 0) {
951
+ if (plan.details.commandsNeedUpdate || plan.details.commandsToRename.length > 0) {
867
952
  console.log(chalk.gray(' 更新 commands...'));
868
953
  await migrateCommands(projectDir, templateDir, plan);
869
954
  }
870
955
 
871
956
  // 5. 迁移 agents
872
- if (plan.details.agentsToUpdate.length > 0) {
957
+ if (plan.details.agentsNeedUpdate) {
873
958
  console.log(chalk.gray(' 更新 agents...'));
874
959
  await migrateAgents(projectDir, templateDir);
875
960
  }
876
961
 
877
- // 6. 更新配置
962
+ // 6. 迁移 OpenCode
963
+ if (plan.details.opencodeNeedUpdate) {
964
+ console.log(chalk.gray(' 更新 OpenCode 配置...'));
965
+ await migrateOpencode(projectDir, templateDir);
966
+ }
967
+
968
+ // 7. 更新配置
878
969
  if (plan.details.configToUpdate) {
879
970
  console.log(chalk.gray(' 更新配置...'));
880
971
  await updateConfig(projectDir, newVersion);
@@ -925,6 +1016,7 @@ module.exports = {
925
1016
  migrateHooks,
926
1017
  migrateCommands,
927
1018
  migrateAgents,
1019
+ migrateOpencode,
928
1020
  migrateFeatureList,
929
1021
  updateConfig
930
1022
  };
@@ -140,6 +140,61 @@ const MIGRATIONS = [
140
140
  renamed: []
141
141
  },
142
142
  aiMigrationRequired: []
143
+ },
144
+ {
145
+ version: '1.1.3',
146
+ description: '补丁版本(无文档结构变更)',
147
+ changes: {
148
+ added: [],
149
+ modified: [],
150
+ removed: [],
151
+ renamed: []
152
+ },
153
+ aiMigrationRequired: []
154
+ },
155
+ {
156
+ version: '1.1.4',
157
+ description: '补丁版本(无文档结构变更)',
158
+ changes: {
159
+ added: [],
160
+ modified: [],
161
+ removed: [],
162
+ renamed: []
163
+ },
164
+ aiMigrationRequired: []
165
+ },
166
+ {
167
+ version: '1.1.5',
168
+ description: '补丁版本(无文档结构变更)',
169
+ changes: {
170
+ added: [],
171
+ modified: [],
172
+ removed: [],
173
+ renamed: []
174
+ },
175
+ aiMigrationRequired: []
176
+ },
177
+ {
178
+ version: '1.1.6',
179
+ description: '补丁版本(无文档结构变更)',
180
+ changes: {
181
+ added: [],
182
+ modified: [],
183
+ removed: [],
184
+ renamed: []
185
+ },
186
+ aiMigrationRequired: []
187
+ },
188
+ {
189
+ version: '1.1.7',
190
+ description: '补丁版本(无文档结构变更)',
191
+ changes: {
192
+ added: [],
193
+ modified: [],
194
+ removed: [],
195
+ renamed: []
196
+ },
197
+ aiMigrationRequired: []
143
198
  }
144
199
  ];
145
200
 
@@ -0,0 +1,54 @@
1
+ {
2
+ "version": 1,
3
+ "plugins": [
4
+ {
5
+ "id": "serena",
6
+ "name": "Serena",
7
+ "category": "memory",
8
+ "integration": { "type": "mcp" },
9
+ "default_tier": "core"
10
+ },
11
+ {
12
+ "id": "brave-search",
13
+ "name": "Brave Search",
14
+ "category": "search",
15
+ "integration": { "type": "mcp" },
16
+ "default_tier": "core"
17
+ },
18
+ {
19
+ "id": "filesystem-mcp",
20
+ "name": "Filesystem MCP",
21
+ "category": "filesystem",
22
+ "integration": { "type": "mcp" },
23
+ "default_tier": "core"
24
+ },
25
+ {
26
+ "id": "github-mcp",
27
+ "name": "GitHub MCP",
28
+ "category": "git",
29
+ "integration": { "type": "mcp" },
30
+ "default_tier": "core"
31
+ },
32
+ {
33
+ "id": "context7",
34
+ "name": "Context7",
35
+ "category": "docs",
36
+ "integration": { "type": "mcp" },
37
+ "default_tier": "core"
38
+ },
39
+ {
40
+ "id": "agent-browser",
41
+ "name": "Agent Browser",
42
+ "category": "browser",
43
+ "integration": { "type": "daemon+skill" },
44
+ "default_tier": "core"
45
+ },
46
+ {
47
+ "id": "playwright-mcp",
48
+ "name": "Playwright MCP",
49
+ "category": "browser",
50
+ "integration": { "type": "mcp" },
51
+ "default_tier": "project"
52
+ }
53
+ ]
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jvibe",
3
- "version": "1.1.5",
3
+ "version": "1.1.8",
4
4
  "description": "\u6587\u6863\u9a71\u52a8\u7684 AI \u8f85\u52a9\u5f00\u53d1\u7cfb\u7edf - Doc-driven AI-assisted development system for Claude Code and OpenCode",
5
5
  "main": "bin/jvibe.js",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "template/",
17
17
  "JVIBE.md",
18
18
  "README.md",
19
+ "CHANGELOG.md",
19
20
  "LICENSE"
20
21
  ],
21
22
  "keywords": [
package/scripts/init.js CHANGED
@@ -165,8 +165,10 @@ async function init(options = {}) {
165
165
  if (mode === 'full') {
166
166
  console.log(chalk.gray(' - docs/core/ (4 个核心文档)'));
167
167
  console.log(chalk.gray(' - docs/project/ (项目文档目录)'));
168
+ console.log(chalk.gray(' - docs/.jvibe/ (tasks.yaml + agent-contracts.yaml + plugins.yaml)'));
168
169
  } else {
169
170
  console.log(chalk.gray(' - docs/core/ (4 个核心文档)'));
171
+ console.log(chalk.gray(' - docs/.jvibe/ (tasks.yaml + agent-contracts.yaml + plugins.yaml)'));
170
172
  }
171
173
 
172
174
  const nextSteps = [];