@cregis-dev/cckit 0.6.5 → 0.6.6

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.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 cregis-dev
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 cregis-dev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,221 +1,221 @@
1
- # @cregis-dev/cckit
2
-
3
- [![npm version](https://img.shields.io/npm/v/@cregis-dev/cckit.svg)](https://www.npmjs.com/package/@cregis-dev/cckit)
4
- [![license](https://img.shields.io/npm/l/@cregis-dev/cckit.svg)](LICENSE)
5
-
6
- Claude Code 企业级配置工具 — 编排外部工具,一条命令为团队统一 Rules、Skills、MCP、API 网关和 AI 开发方法论。
7
-
8
- ## 它解决什么问题
9
-
10
- 企业采用 Claude Code 时面临的核心痛点:
11
-
12
- - **配置碎片化** — 每个项目、每个开发者各自为政,编码规范、安全策略、工具链配置不一致
13
- - **最佳实践缺失** — AI 辅助开发需要精心设计的 Rules、Skills、Agents 才能发挥最大效能
14
- - **重复劳动** — 新项目需要从零配置 MCP、方法论框架、编码规范
15
- - **API 管理分散** — 每个开发者自行配置 API 网关和模型,无法统一管控
16
-
17
- cckit 将业界验证的 AI 开发最佳实践打包到一个 CLI 中:
18
-
19
- | 能力 | 说明 |
20
- |------|------|
21
- | **API 网关** | 统一配置企业 API 网关 URL、密钥和大模型(MiniMax、Kimi、Gemini、GPT) |
22
- | **Rules** | 来自 [ECC](https://github.com/affaan-m/everything-claude-code) 的企业级编码规范 — 覆盖 TypeScript、Python、Go,含安全、测试、性能、Git 工作流 |
23
- | **Skills** | 44+ 内置技能 + 第三方技能 — TDD、安全审计、前后端模式、数据库优化、API 设计、持续学习等 |
24
- | **Methodology** | 来自 [BMAD](https://www.npmjs.com/package/bmad-method) 的 AI 驱动敏捷方法论 — 核心 Agent、测试架构、需求管理 |
25
- | **MCP** | 预配置的 Model Context Protocol 服务器 — 文档查询、浏览器自动化、Cloudflare 集成 |
26
- | **Plugins** | 7 个默认插件 — ECC、Superpowers、代码简化、提交工作流、CLAUDE.md 管理等 |
27
-
28
- cckit 是**编排工具**,不是模板打包器。运行时调用外部工具(npx、git clone),不预置模板文件。
29
-
30
- ## 快速开始
31
-
32
- ```bash
33
- # 直接使用(推荐)
34
- npx @cregis-dev/cckit install
35
-
36
- # 或全局安装
37
- npm install -g @cregis-dev/cckit
38
- cckit install
39
- ```
40
-
41
- 交互式引导会依次:
42
-
43
- 1. 配置 API 网关(默认 `gateway.cregis.ai`)和 API Key
44
- 2. 选择大模型(MiniMax / Kimi / Gemini / GPT)
45
- 3. 安装 Plugins、Rules、Skills、BMAD、MCP
46
-
47
- ### 本地测试
48
-
49
- ```bash
50
- node bin/cckit.js install
51
- ```
52
-
53
- ### 企业统一部署
54
-
55
- ```bash
56
- # 全默认模式 — 适合 CI/CD 或批量初始化
57
- npx @cregis-dev/cckit install --yes --api-key sk-your-key
58
-
59
- # 企业标准化参数
60
- cckit install \
61
- --user-name "TeamMember" \
62
- --lang ts,py \
63
- --model kimi \
64
- --api-key sk-your-key \
65
- --communication-language English \
66
- --doc-language English \
67
- --yes
68
- ```
69
-
70
- ## 命令
71
-
72
- ### `cckit install`
73
-
74
- 初始化项目,编排安装所有组件。
75
-
76
- | 参数 | 简写 | 默认值 | 说明 |
77
- |------|------|--------|------|
78
- | `--yes` | `-y` | `false` | 接受所有默认值 |
79
- | `--dir <path>` | `-d` | 当前目录 | 目标项目目录 |
80
- | `--user-name <name>` | — | `"User"` | 你的名字 |
81
- | `--lang <codes>` | `-l` | `ts,py,go` | 编程语言(逗号分隔) |
82
- | `--communication-language` | — | `"Chinese"` | Agent 沟通语言 |
83
- | `--doc-language` | — | `"Chinese"` | 文档输出语言 |
84
- | `--api-url <url>` | — | `gateway.cregis.ai` | API 网关地址 |
85
- | `--api-key <key>` | — | — | API 密钥(未提供则交互式输入) |
86
- | `--force-api-key` | — | `false` | 强制覆盖已有 API Key |
87
- | `--model <name>` | — | `minimax` | 大模型:minimax / kimi / gemini / gpt |
88
- | `--plugins <ids>` | — | `"default"` | 插件 ID、`"default"` 或 `"none"` |
89
- | `--no-bmad` | — | — | 跳过 BMAD 安装 |
90
- | `--no-ecc` | — | — | 跳过 ECC Rules |
91
- | `--no-mcp` | — | — | 跳过 MCP 配置 |
92
- | `--no-skills` | — | — | 跳过 Skills 安装 |
93
- | `--no-plugins` | — | — | 跳过插件启用 |
94
- | `--debug` | — | `false` | 调试输出 |
95
-
96
- ### `cckit status`
97
-
98
- 查看当前安装状态和各步骤执行结果。
99
-
100
- ```bash
101
- cckit status
102
- cckit status -d /path/to/project
103
- ```
104
-
105
- ### `cckit update`
106
-
107
- 重新执行所有安装步骤,更新组件到最新版。
108
-
109
- ```bash
110
- cckit update # 重新执行所有步骤
111
- cckit update --dry-run # 仅预览,不修改
112
- cckit update --no-apply # 仅检查,更新时间戳
113
- cckit update --force # 强制覆盖已修改的文件
114
- cckit update --model gpt --api-key sk-new # 更新模型和密钥
115
- ```
116
-
117
- ## 安装内容
118
-
119
- ### 编排步骤
120
-
121
- | 步骤 | 工具 | 目标 |
122
- |------|------|------|
123
- | **Configure User** | 写入 `~/.claude/settings.json` | API URL + API Key + 模型环境变量(用户级) |
124
- | **Enable Plugins** | 写入 `.claude/settings.json` | 插件 + 市场源 + 环境变量默认值(项目级) |
125
- | **Install BMAD** | `npx bmad-method install` | `_bmad/core`、`_bmad/bmm`、`_bmad/tea`、`.claude/commands/` |
126
- | **Install Rules** | `git clone` + copy | `.claude/rules/`(ECC 编码规范) |
127
- | **Install Skills** | `npx skills add` | 从注册的技能仓库安装 |
128
- | **Install MCP** | 文件复制 | `.mcp.json`(MCP 服务器配置) |
129
-
130
- ### 用户级设置(`~/.claude/settings.json`)
131
-
132
- | 环境变量 | 说明 |
133
- |----------|------|
134
- | `ANTHROPIC_BASE_URL` | API 网关地址(默认 `https://gateway.cregis.ai`) |
135
- | `ANTHROPIC_AUTH_TOKEN` | API 密钥 |
136
- | `ANTHROPIC_MODEL` | 默认模型 |
137
- | `ANTHROPIC_SMALL_FAST_MODEL` | 快速模型 |
138
- | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Sonnet 映射 |
139
- | `ANTHROPIC_DEFAULT_OPUS_MODEL` | Opus 映射 |
140
- | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Haiku 映射 |
141
-
142
- 支持的模型:
143
-
144
- | 别名 | 模型 ID |
145
- |------|---------|
146
- | `minimax`(默认) | `MiniMax-M2.5` |
147
- | `kimi` | `Kimi-K2.5` |
148
- | `gemini` | `gemini-3.1-pro-preview` |
149
- | `gpt` | `gpt-5.3-codex` |
150
-
151
- ### 项目级设置(`.claude/settings.json`)
152
-
153
- 默认写入的环境变量:
154
-
155
- | 变量 | 值 | 说明 |
156
- |------|-----|------|
157
- | `DISABLE_BUG_COMMAND` | `1` | 禁用 /bug 命令 |
158
- | `DISABLE_ERROR_REPORTING` | `1` | 禁用 Sentry 错误报告 |
159
- | `DISABLE_TELEMETRY` | `1` | 禁用 Statsig 遥测 |
160
- | `MCP_TIMEOUT` | `60000` | MCP 工具超时(毫秒) |
161
- | `MAX_THINKING_TOKENS` | `31999` | 扩展思考最大 token 数 |
162
- | `CLAUDE_CODE_MAX_OUTPUT_TOKENS` | `64000` | 输出最大 token 数 |
163
-
164
- ### 插件体系
165
-
166
- cckit 默认启用 7 个 Claude Code marketplace 插件,写入 `.claude/settings.json` 的 `enabledPlugins`:
167
-
168
- - **everything-claude-code** — 全套 ECC Skills/Agents/Commands
169
- - **superpowers** — 结构化开发工作流
170
- - **claude-code-setup** — 自动化分析与 CLAUDE.md 审计
171
- - **claude-md-management** — CLAUDE.md 改进工具
172
- - **code-simplifier** — 代码简化 Agent
173
- - **commit-commands** — Git 提交工作流
174
- - **firecrawl** — 网页爬取与搜索
175
-
176
- ## 生成的目录结构
177
-
178
- ```
179
- your-project/
180
- ├── _bmad/ # BMAD 方法论框架
181
- │ ├── core/ # 核心 Agent 与 Task 定义
182
- │ ├── bmm/ # 敏捷方法工作流
183
- │ ├── tea/ # 测试架构企业版
184
- │ └── _config/ # 配置 + manifest.yaml
185
- ├── _bmad-output/ # BMAD 产出物(自动创建)
186
- │ ├── planning-artifacts/
187
- │ ├── implementation-artifacts/
188
- │ └── test-artifacts/
189
- ├── .claude/ # Claude Code 配置
190
- │ ├── rules/ # ECC 编码规范(按语言分目录)
191
- │ ├── commands/ # BMAD 命令
192
- │ └── settings.json # 插件 + 市场源 + 环境变量
193
- ├── .mcp.json # Claude Code MCP 配置
194
- └── docs/ # 项目文档目录
195
- ```
196
-
197
- ## 上游来源
198
-
199
- | 来源 | 类型 | 项目 |
200
- |------|------|------|
201
- | BMAD | npm (运行时) | [bmad-method](https://www.npmjs.com/package/bmad-method) |
202
- | ECC | Git clone (运行时) | [everything-claude-code](https://github.com/affaan-m/everything-claude-code) |
203
- | Skills | npm (运行时) | 按 `registry.json` 中配置的仓库 |
204
-
205
- ## 系统要求
206
-
207
- - Node.js >= 18.0.0
208
- - git(ECC Rules 克隆需要)
209
-
210
- ## 开发
211
-
212
- 详见 [CONTRIBUTING.md](CONTRIBUTING.md)。
213
-
214
- ```bash
215
- npm install
216
- npm test
217
- ```
218
-
219
- ## 许可证
220
-
221
- [MIT](LICENSE)
1
+ # @cregis-dev/cckit
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@cregis-dev/cckit.svg)](https://www.npmjs.com/package/@cregis-dev/cckit)
4
+ [![license](https://img.shields.io/npm/l/@cregis-dev/cckit.svg)](LICENSE)
5
+
6
+ Claude Code 企业级配置工具 — 编排外部工具,一条命令为团队统一 Rules、Skills、MCP、API 网关和 AI 开发方法论。
7
+
8
+ ## 它解决什么问题
9
+
10
+ 企业采用 Claude Code 时面临的核心痛点:
11
+
12
+ - **配置碎片化** — 每个项目、每个开发者各自为政,编码规范、安全策略、工具链配置不一致
13
+ - **最佳实践缺失** — AI 辅助开发需要精心设计的 Rules、Skills、Agents 才能发挥最大效能
14
+ - **重复劳动** — 新项目需要从零配置 MCP、方法论框架、编码规范
15
+ - **API 管理分散** — 每个开发者自行配置 API 网关和模型,无法统一管控
16
+
17
+ cckit 将业界验证的 AI 开发最佳实践打包到一个 CLI 中:
18
+
19
+ | 能力 | 说明 |
20
+ |------|------|
21
+ | **API 网关** | 统一配置企业 API 网关 URL、密钥和大模型(MiniMax、Kimi、Gemini、GPT) |
22
+ | **Rules** | 来自 [ECC](https://github.com/affaan-m/everything-claude-code) 的企业级编码规范 — 覆盖 TypeScript、Python、Go,含安全、测试、性能、Git 工作流 |
23
+ | **Skills** | 44+ 内置技能 + 第三方技能 — TDD、安全审计、前后端模式、数据库优化、API 设计、持续学习等 |
24
+ | **Methodology** | 来自 [BMAD](https://www.npmjs.com/package/bmad-method) 的 AI 驱动敏捷方法论 — 核心 Agent、测试架构、需求管理 |
25
+ | **MCP** | 预配置的 Model Context Protocol 服务器 — 文档查询、浏览器自动化、Cloudflare 集成 |
26
+ | **Plugins** | 7 个默认插件 — ECC、Superpowers、代码简化、提交工作流、CLAUDE.md 管理等 |
27
+
28
+ cckit 是**编排工具**,不是模板打包器。运行时调用外部工具(npx、git clone),不预置模板文件。
29
+
30
+ ## 快速开始
31
+
32
+ ```bash
33
+ # 直接使用(推荐)
34
+ npx @cregis-dev/cckit install
35
+
36
+ # 或全局安装
37
+ npm install -g @cregis-dev/cckit
38
+ cckit install
39
+ ```
40
+
41
+ 交互式引导会依次:
42
+
43
+ 1. 配置 API 网关(默认 `gateway.cregis.ai`)和 API Key
44
+ 2. 选择大模型(MiniMax / Kimi / Gemini / GPT)
45
+ 3. 安装 Plugins、Rules、Skills、BMAD、MCP
46
+
47
+ ### 本地测试
48
+
49
+ ```bash
50
+ node bin/cckit.js install
51
+ ```
52
+
53
+ ### 企业统一部署
54
+
55
+ ```bash
56
+ # 全默认模式 — 适合 CI/CD 或批量初始化
57
+ npx @cregis-dev/cckit install --yes --api-key sk-your-key
58
+
59
+ # 企业标准化参数
60
+ cckit install \
61
+ --user-name "TeamMember" \
62
+ --lang ts,py \
63
+ --model kimi \
64
+ --api-key sk-your-key \
65
+ --communication-language English \
66
+ --doc-language English \
67
+ --yes
68
+ ```
69
+
70
+ ## 命令
71
+
72
+ ### `cckit install`
73
+
74
+ 初始化项目,编排安装所有组件。
75
+
76
+ | 参数 | 简写 | 默认值 | 说明 |
77
+ |------|------|--------|------|
78
+ | `--yes` | `-y` | `false` | 接受所有默认值 |
79
+ | `--dir <path>` | `-d` | 当前目录 | 目标项目目录 |
80
+ | `--user-name <name>` | — | `"User"` | 你的名字 |
81
+ | `--lang <codes>` | `-l` | `ts,py,go` | 编程语言(逗号分隔) |
82
+ | `--communication-language` | — | `"Chinese"` | Agent 沟通语言 |
83
+ | `--doc-language` | — | `"Chinese"` | 文档输出语言 |
84
+ | `--api-url <url>` | — | `gateway.cregis.ai` | API 网关地址 |
85
+ | `--api-key <key>` | — | — | API 密钥(未提供则交互式输入) |
86
+ | `--force-api-key` | — | `false` | 强制覆盖已有 API Key |
87
+ | `--model <name>` | — | `minimax` | 大模型:minimax / kimi / gemini / gpt |
88
+ | `--plugins <ids>` | — | `"default"` | 插件 ID、`"default"` 或 `"none"` |
89
+ | `--no-bmad` | — | — | 跳过 BMAD 安装 |
90
+ | `--no-ecc` | — | — | 跳过 ECC Rules |
91
+ | `--no-mcp` | — | — | 跳过 MCP 配置 |
92
+ | `--no-skills` | — | — | 跳过 Skills 安装 |
93
+ | `--no-plugins` | — | — | 跳过插件启用 |
94
+ | `--debug` | — | `false` | 调试输出 |
95
+
96
+ ### `cckit status`
97
+
98
+ 查看当前安装状态和各步骤执行结果。
99
+
100
+ ```bash
101
+ cckit status
102
+ cckit status -d /path/to/project
103
+ ```
104
+
105
+ ### `cckit update`
106
+
107
+ 重新执行所有安装步骤,更新组件到最新版。
108
+
109
+ ```bash
110
+ cckit update # 重新执行所有步骤
111
+ cckit update --dry-run # 仅预览,不修改
112
+ cckit update --no-apply # 仅检查,更新时间戳
113
+ cckit update --force # 强制覆盖已修改的文件
114
+ cckit update --model gpt --api-key sk-new # 更新模型和密钥
115
+ ```
116
+
117
+ ## 安装内容
118
+
119
+ ### 编排步骤
120
+
121
+ | 步骤 | 工具 | 目标 |
122
+ |------|------|------|
123
+ | **Configure User** | 写入 `~/.claude/settings.json` | API URL + API Key + 模型环境变量(用户级) |
124
+ | **Enable Plugins** | 写入 `.claude/settings.json` | 插件 + 市场源 + 环境变量默认值(项目级) |
125
+ | **Install BMAD** | `npx bmad-method install` | `_bmad/core`、`_bmad/bmm`、`_bmad/tea`、`.claude/commands/` |
126
+ | **Install Rules** | `git clone` + copy | `.claude/rules/`(ECC 编码规范) |
127
+ | **Install Skills** | `npx skills add` | 从注册的技能仓库安装 |
128
+ | **Install MCP** | 文件复制 | `.mcp.json`(MCP 服务器配置) |
129
+
130
+ ### 用户级设置(`~/.claude/settings.json`)
131
+
132
+ | 环境变量 | 说明 |
133
+ |----------|------|
134
+ | `ANTHROPIC_BASE_URL` | API 网关地址(默认 `https://gateway.cregis.ai`) |
135
+ | `ANTHROPIC_AUTH_TOKEN` | API 密钥 |
136
+ | `ANTHROPIC_MODEL` | 默认模型 |
137
+ | `ANTHROPIC_SMALL_FAST_MODEL` | 快速模型 |
138
+ | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Sonnet 映射 |
139
+ | `ANTHROPIC_DEFAULT_OPUS_MODEL` | Opus 映射 |
140
+ | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Haiku 映射 |
141
+
142
+ 支持的模型:
143
+
144
+ | 别名 | 模型 ID |
145
+ |------|---------|
146
+ | `minimax`(默认) | `MiniMax-M2.5` |
147
+ | `kimi` | `Kimi-K2.5` |
148
+ | `gemini` | `gemini-3.1-pro-preview` |
149
+ | `gpt` | `gpt-5.3-codex` |
150
+
151
+ ### 项目级设置(`.claude/settings.json`)
152
+
153
+ 默认写入的环境变量:
154
+
155
+ | 变量 | 值 | 说明 |
156
+ |------|-----|------|
157
+ | `DISABLE_BUG_COMMAND` | `1` | 禁用 /bug 命令 |
158
+ | `DISABLE_ERROR_REPORTING` | `1` | 禁用 Sentry 错误报告 |
159
+ | `DISABLE_TELEMETRY` | `1` | 禁用 Statsig 遥测 |
160
+ | `MCP_TIMEOUT` | `60000` | MCP 工具超时(毫秒) |
161
+ | `MAX_THINKING_TOKENS` | `31999` | 扩展思考最大 token 数 |
162
+ | `CLAUDE_CODE_MAX_OUTPUT_TOKENS` | `64000` | 输出最大 token 数 |
163
+
164
+ ### 插件体系
165
+
166
+ cckit 默认启用 7 个 Claude Code marketplace 插件,写入 `.claude/settings.json` 的 `enabledPlugins`:
167
+
168
+ - **everything-claude-code** — 全套 ECC Skills/Agents/Commands
169
+ - **superpowers** — 结构化开发工作流
170
+ - **claude-code-setup** — 自动化分析与 CLAUDE.md 审计
171
+ - **claude-md-management** — CLAUDE.md 改进工具
172
+ - **code-simplifier** — 代码简化 Agent
173
+ - **commit-commands** — Git 提交工作流
174
+ - **firecrawl** — 网页爬取与搜索
175
+
176
+ ## 生成的目录结构
177
+
178
+ ```
179
+ your-project/
180
+ ├── _bmad/ # BMAD 方法论框架
181
+ │ ├── core/ # 核心 Agent 与 Task 定义
182
+ │ ├── bmm/ # 敏捷方法工作流
183
+ │ ├── tea/ # 测试架构企业版
184
+ │ └── _config/ # 配置 + manifest.yaml
185
+ ├── _bmad-output/ # BMAD 产出物(自动创建)
186
+ │ ├── planning-artifacts/
187
+ │ ├── implementation-artifacts/
188
+ │ └── test-artifacts/
189
+ ├── .claude/ # Claude Code 配置
190
+ │ ├── rules/ # ECC 编码规范(按语言分目录)
191
+ │ ├── commands/ # BMAD 命令
192
+ │ └── settings.json # 插件 + 市场源 + 环境变量
193
+ ├── .mcp.json # Claude Code MCP 配置
194
+ └── docs/ # 项目文档目录
195
+ ```
196
+
197
+ ## 上游来源
198
+
199
+ | 来源 | 类型 | 项目 |
200
+ |------|------|------|
201
+ | BMAD | npm (运行时) | [bmad-method](https://www.npmjs.com/package/bmad-method) |
202
+ | ECC | Git clone (运行时) | [everything-claude-code](https://github.com/affaan-m/everything-claude-code) |
203
+ | Skills | npm (运行时) | 按 `registry.json` 中配置的仓库 |
204
+
205
+ ## 系统要求
206
+
207
+ - Node.js >= 18.0.0
208
+ - git(ECC Rules 克隆需要)
209
+
210
+ ## 开发
211
+
212
+ 详见 [CONTRIBUTING.md](CONTRIBUTING.md)。
213
+
214
+ ```bash
215
+ npm install
216
+ npm test
217
+ ```
218
+
219
+ ## 许可证
220
+
221
+ [MIT](LICENSE)
package/bin/cckit.js CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env node
2
- import { run } from '../src/cli.js'
3
- run(process.argv)
1
+ #!/usr/bin/env node
2
+ import { run } from '../src/cli.js'
3
+ run(process.argv)
package/package.json CHANGED
@@ -1,53 +1,53 @@
1
- {
2
- "name": "@cregis-dev/cckit",
3
- "version": "0.6.5",
4
- "description": "Enterprise-grade Claude Code configuration toolkit — orchestrates external tools to set up unified rules, skills, MCP and methodology for teams",
5
- "type": "module",
6
- "bin": {
7
- "cckit": "./bin/cckit.js"
8
- },
9
- "publishConfig": {
10
- "access": "public"
11
- },
12
- "files": [
13
- "bin/",
14
- "src/",
15
- "templates/mcp/",
16
- "registry.json",
17
- "templates/rules/"
18
- ],
19
- "engines": {
20
- "node": ">=18.0.0"
21
- },
22
- "scripts": {
23
- "test": "vitest run",
24
- "test:watch": "vitest",
25
- "test:coverage": "vitest run --coverage",
26
- "release": "node scripts/release.js",
27
- "release:dry": "node scripts/release.js --dry-run"
28
- },
29
- "keywords": [
30
- "claude-code",
31
- "enterprise",
32
- "configuration",
33
- "bmad",
34
- "ecc",
35
- "mcp",
36
- "cli",
37
- "rules",
38
- "ai-coding",
39
- "developer-tools",
40
- "team"
41
- ],
42
- "license": "MIT",
43
- "dependencies": {
44
- "chalk": "^5.6.2",
45
- "commander": "^14.0.3",
46
- "fs-extra": "^11.3.3",
47
- "glob": "^13.0.3",
48
- "yaml": "^2.8.2"
49
- },
50
- "devDependencies": {
51
- "vitest": "^4.0.18"
52
- }
53
- }
1
+ {
2
+ "name": "@cregis-dev/cckit",
3
+ "version": "0.6.6",
4
+ "description": "Enterprise-grade Claude Code configuration toolkit — orchestrates external tools to set up unified rules, skills, MCP and methodology for teams",
5
+ "type": "module",
6
+ "bin": {
7
+ "cckit": "./bin/cckit.js"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "files": [
13
+ "bin/",
14
+ "src/",
15
+ "templates/mcp/",
16
+ "registry.json",
17
+ "templates/rules/"
18
+ ],
19
+ "engines": {
20
+ "node": ">=18.0.0"
21
+ },
22
+ "scripts": {
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "test:coverage": "vitest run --coverage",
26
+ "release": "node scripts/release.js",
27
+ "release:dry": "node scripts/release.js --dry-run"
28
+ },
29
+ "keywords": [
30
+ "claude-code",
31
+ "enterprise",
32
+ "configuration",
33
+ "bmad",
34
+ "ecc",
35
+ "mcp",
36
+ "cli",
37
+ "rules",
38
+ "ai-coding",
39
+ "developer-tools",
40
+ "team"
41
+ ],
42
+ "license": "MIT",
43
+ "dependencies": {
44
+ "chalk": "^5.6.2",
45
+ "commander": "^14.0.3",
46
+ "fs-extra": "^11.3.3",
47
+ "glob": "^13.0.3",
48
+ "yaml": "^2.8.2"
49
+ },
50
+ "devDependencies": {
51
+ "vitest": "^4.0.18"
52
+ }
53
+ }
package/registry.json CHANGED
@@ -1,5 +1,13 @@
1
1
  {
2
2
  "version": "2.0.0",
3
+ "versions": {
4
+ "plugins": "1.0.0",
5
+ "rules": "1.0.0",
6
+ "skills": "1.0.0",
7
+ "bmad": "1.0.0",
8
+ "mcp": "1.0.0",
9
+ "userSettings": "1.0.0"
10
+ },
3
11
  "plugins": {
4
12
  "everything-claude-code": {
5
13
  "name": "Everything Claude Code",
@@ -8,54 +16,63 @@
8
16
  "source": "github",
9
17
  "repo": "affaan-m/everything-claude-code"
10
18
  },
19
+ "scope": "project",
11
20
  "default": true,
12
21
  "description": "Rules, agents, commands, skills, and hooks for Claude Code"
13
22
  },
14
23
  "superpowers": {
15
24
  "name": "Superpowers",
16
25
  "marketplace": "claude-plugins-official",
26
+ "scope": "project",
17
27
  "default": true,
18
28
  "description": "Structured workflows with brainstorming, debugging, TDD, and code review skills"
19
29
  },
20
30
  "claude-code-setup": {
21
31
  "name": "Claude Code Setup",
22
32
  "marketplace": "claude-plugins-official",
33
+ "scope": "project",
23
34
  "default": true,
24
35
  "description": "Analyze codebases and recommend Claude Code automations, audit and improve CLAUDE.md files"
25
36
  },
26
37
  "claude-md-management": {
27
38
  "name": "Claude MD Management",
28
39
  "marketplace": "claude-plugins-official",
40
+ "scope": "project",
29
41
  "default": true,
30
42
  "description": "Audit, improve, and update CLAUDE.md documentation files"
31
43
  },
32
44
  "code-simplifier": {
33
45
  "name": "Code Simplifier",
34
46
  "marketplace": "claude-plugins-official",
47
+ "scope": "project",
35
48
  "default": true,
36
49
  "description": "Simplify and refine code for clarity, consistency, and maintainability"
37
50
  },
38
51
  "commit-commands": {
39
52
  "name": "Commit Commands",
40
53
  "marketplace": "claude-plugins-official",
54
+ "scope": "project",
41
55
  "default": true,
42
56
  "description": "Git commit workflows: commit, push, PR creation, and branch cleanup"
43
57
  },
44
58
  "firecrawl": {
45
59
  "name": "Firecrawl",
46
60
  "marketplace": "claude-plugins-official",
61
+ "scope": "project",
47
62
  "default": true,
48
63
  "description": "Web scraping, search, and skill generation using Firecrawl"
49
64
  },
50
65
  "typescript-lsp": {
51
66
  "name": "TypeScript LSP",
52
67
  "marketplace": "claude-plugins-official",
68
+ "scope": "project",
53
69
  "default": true,
54
70
  "description": "TypeScript language server protocol integration for enhanced TypeScript development"
55
71
  },
56
72
  "pr-review-toolkit": {
57
73
  "name": "PR Review Toolkit",
58
74
  "marketplace": "claude-plugins-official",
75
+ "scope": "project",
59
76
  "default": true,
60
77
  "description": "Comprehensive PR review using specialized agents"
61
78
  }
@@ -12,6 +12,7 @@ import { orchestrate } from '../core/orchestrator.js'
12
12
  import { MANIFEST_REL, buildManifest, writeManifest } from '../utils/manifest.js'
13
13
  import { createLogger } from '../utils/logger.js'
14
14
  import { enablePlugins } from '../steps/enable-plugins.js'
15
+ import { addPlugin } from '../steps/add-plugin.js'
15
16
  import { installBmad } from '../steps/install-bmad.js'
16
17
  import { installRules } from '../steps/install-rules.js'
17
18
  import { installSkills } from '../steps/install-skills.js'
@@ -53,7 +54,9 @@ export async function runInit(opts = {}, _deps = {}) {
53
54
  // Load registry and merge config
54
55
  const registry = _deps.registry || await loadRegistry()
55
56
  const config = mergeConfig(opts)
57
+ const versions = registry.versions || {}
56
58
  logger.debug(`Config: ${JSON.stringify(config, null, 2)}`)
59
+ logger.debug(`Versions: ${JSON.stringify(versions, null, 2)}`)
57
60
 
58
61
  // Resolve plugins
59
62
  const plugins = resolvePlugins(registry, config)
@@ -87,6 +90,16 @@ export async function runInit(opts = {}, _deps = {}) {
87
90
  skip: config.plugins === 'none',
88
91
  },
89
92
  },
93
+ // Test: CLI-based plugin installation for project-scoped plugins
94
+ {
95
+ id: 'add-plugin',
96
+ fn: _deps.addPlugin || addPlugin,
97
+ opts: {
98
+ targetDir,
99
+ plugins,
100
+ skip: config.plugins === 'none' || !config.cliPlugins,
101
+ },
102
+ },
90
103
  {
91
104
  id: 'install-bmad',
92
105
  fn: _deps.installBmad || installBmad,
@@ -140,7 +153,7 @@ export async function runInit(opts = {}, _deps = {}) {
140
153
  }))
141
154
 
142
155
  // Write manifest
143
- const manifest = buildManifest({ config, report, version: VERSION })
156
+ const manifest = buildManifest({ config, report, version: VERSION, versions })
144
157
  await writeManifest(targetDir, manifest)
145
158
  logger.success(`Manifest written to ${MANIFEST_REL}`)
146
159
 
@@ -5,6 +5,8 @@
5
5
  import path from 'node:path'
6
6
  import chalk from 'chalk'
7
7
  import { readManifest, isLegacyManifest } from '../utils/manifest.js'
8
+ import { compareVersions } from '../utils/compare-versions.js'
9
+ import { loadRegistry } from '../core/registry.js'
8
10
 
9
11
  /**
10
12
  * @param {object} opts
@@ -30,17 +32,55 @@ export async function runStatus(opts = {}) {
30
32
  return { installed: true, legacy: true, output: msg }
31
33
  }
32
34
 
35
+ // Load registry and compare versions
36
+ let registry
37
+ let needsUpdate = false
38
+ let components = {}
39
+ try {
40
+ registry = await loadRegistry()
41
+ const result = compareVersions(manifest, registry)
42
+ needsUpdate = result.needsUpdate
43
+ components = result.components
44
+ } catch {
45
+ // Registry load failed - skip version check
46
+ }
47
+
33
48
  const lines = []
34
49
  lines.push('')
35
50
  lines.push(chalk.bold('cckit installation status'))
36
51
  lines.push('')
37
52
 
38
- // Step results
39
- const steps = manifest.cckit?.steps || []
53
+ // Component versions
54
+ const installedVersions = manifest.cckit?.config?.versions || {}
55
+ const versionHeader = `${'Component'.padEnd(22)} ${'Installed'.padEnd(12)} ${'Latest'.padEnd(12)} ${'Status'.padEnd(24)}`
56
+ lines.push(chalk.bold(versionHeader))
57
+ lines.push('-'.repeat(70))
58
+
59
+ for (const [stepId, info] of Object.entries(components)) {
60
+ const current = installedVersions[info.versionKey] || 'none'
61
+ const latest = info.latest
62
+ const hasUpdate = current !== latest
63
+
64
+ const versionStatus = hasUpdate
65
+ ? chalk.yellow(`update (${current} -> ${latest})`)
66
+ : chalk.green('up to date')
67
+
68
+ lines.push(`${stepId.padEnd(22)} ${current.padEnd(12)} ${latest.padEnd(12)} ${versionStatus}`)
69
+ }
70
+
71
+ if (needsUpdate) {
72
+ lines.push('')
73
+ lines.push(chalk.yellow(' Updates available. Run "cckit update" to update.'))
74
+ }
75
+
76
+ lines.push('')
77
+ lines.push(chalk.bold('Step Results:'))
40
78
  const header = `${'Step'.padEnd(20)} ${'Status'.padEnd(12)} ${'Details'.padEnd(40)}`
41
79
  lines.push(header)
42
80
  lines.push('-'.repeat(72))
43
81
 
82
+ // Step results
83
+ const steps = manifest.cckit?.steps || []
44
84
  for (const step of steps) {
45
85
  const status = step.skipped
46
86
  ? chalk.gray('skipped')
@@ -81,5 +121,5 @@ export async function runStatus(opts = {}) {
81
121
  const output = lines.join('\n')
82
122
  console.log(output)
83
123
 
84
- return { installed: true, cckit: manifest.cckit, output }
124
+ return { installed: true, cckit: manifest.cckit, output, needsUpdate, components }
85
125
  }
@@ -7,11 +7,12 @@
7
7
  */
8
8
 
9
9
  import path from 'node:path'
10
- import fse from 'fs-extra'
10
+ import chalk from 'chalk'
11
11
  import { loadRegistry, resolvePlugins, resolveModelId } from '../core/registry.js'
12
12
  import { DEFAULT_API_URL } from '../core/config.js'
13
13
  import { orchestrate } from '../core/orchestrator.js'
14
14
  import { readManifest, writeManifest, isLegacyManifest, serializeSteps } from '../utils/manifest.js'
15
+ import { compareVersions } from '../utils/compare-versions.js'
15
16
  import { createLogger } from '../utils/logger.js'
16
17
  import { enablePlugins } from '../steps/enable-plugins.js'
17
18
  import { installBmad } from '../steps/install-bmad.js'
@@ -33,6 +34,7 @@ import { configureUser } from '../steps/configure-user.js'
33
34
  export async function runUpdate(opts = {}, _deps = {}) {
34
35
  const logger = _deps.logger || createLogger({ debug: opts.debug })
35
36
  const targetDir = path.resolve(opts.dir || process.cwd())
37
+ const registry = _deps.registry || await loadRegistry()
36
38
 
37
39
  const manifest = await readManifest(targetDir)
38
40
 
@@ -45,16 +47,38 @@ export async function runUpdate(opts = {}, _deps = {}) {
45
47
 
46
48
  logger.banner('cckit update')
47
49
 
48
- // Show current step status
50
+ // Compare versions
51
+ const { needsUpdate, components } = compareVersions(manifest, registry)
52
+
53
+ // Show current step status with version info
49
54
  const steps = manifest.cckit?.steps || []
50
- for (const step of steps) {
51
- const status = step.skipped ? 'skipped' : step.success ? 'ok' : 'FAILED'
52
- logger.info(` ${step.stepId}: ${status}`)
55
+ const installedVersions = manifest.cckit?.config?.versions || {}
56
+
57
+ logger.info('')
58
+ logger.info(chalk.bold('Component Versions:'))
59
+ logger.info('')
60
+
61
+ for (const [stepId, info] of Object.entries(components)) {
62
+ const current = installedVersions[info.versionKey] || 'none'
63
+ const latest = info.latest
64
+ const needsUpdate = current !== latest
65
+
66
+ const status = needsUpdate
67
+ ? chalk.yellow(`update available (${current} -> ${latest})`)
68
+ : chalk.green('up to date')
69
+
70
+ logger.info(` ${stepId}: ${status}`)
71
+ }
72
+
73
+ if (needsUpdate) {
74
+ logger.info('')
75
+ logger.info(chalk.yellow(' Some components have updates available.'))
76
+ logger.info(chalk.gray(' Run "cckit update" to apply updates.'))
53
77
  }
54
78
 
55
79
  if (opts.dryRun) {
56
80
  logger.info('\n (dry run - no changes made)')
57
- return { dryRun: true, steps }
81
+ return { dryRun: true, steps, needsUpdate, components }
58
82
  }
59
83
 
60
84
  if (opts.apply === false) {
@@ -62,11 +86,24 @@ export async function runUpdate(opts = {}, _deps = {}) {
62
86
  manifest.cckit.lastUpdated = new Date().toISOString()
63
87
  await writeManifest(targetDir, manifest)
64
88
  logger.success('Check complete.')
65
- return { checked: true, steps }
89
+ return { checked: true, steps, needsUpdate, components }
90
+ }
91
+
92
+ // Show step status
93
+ logger.info('')
94
+ logger.info(chalk.bold('Step Status:'))
95
+ for (const step of steps) {
96
+ const status = step.skipped ? 'skipped' : step.success ? 'ok' : 'FAILED'
97
+ logger.info(` ${step.stepId}: ${status}`)
98
+ }
99
+
100
+ if (!needsUpdate) {
101
+ logger.info('')
102
+ logger.success('All components are up to date. No update needed.')
103
+ return { applied: false, reason: 'already_up_to_date', needsUpdate: false }
66
104
  }
67
105
 
68
106
  // Apply mode: re-run orchestrator
69
- const registry = _deps.registry || await loadRegistry()
70
107
  const config = manifest.cckit?.config || {}
71
108
  const plugins = resolvePlugins(registry, { plugins: config.plugins || 'default' })
72
109
 
@@ -136,7 +173,11 @@ export async function runUpdate(opts = {}, _deps = {}) {
136
173
 
137
174
  const report = await orchestrate(stepSpecs, logger)
138
175
 
139
- // Update manifest
176
+ // Update manifest with new versions
177
+ manifest.cckit.config.versions = {
178
+ ...(manifest.cckit.config.versions || {}),
179
+ ...registry.versions,
180
+ }
140
181
  manifest.cckit.steps = serializeSteps(report.steps)
141
182
  manifest.cckit.fileRegistry = {
142
183
  ...(manifest.cckit.fileRegistry || {}),
@@ -14,6 +14,7 @@ export const DEFAULT_CONFIG = {
14
14
  document_output_language: 'Chinese',
15
15
  languages: ['typescript', 'python', 'golang'],
16
16
  plugins: 'default',
17
+ cliPlugins: true, // Use Claude CLI for project-scoped plugins
17
18
  excludeGroups: []
18
19
  }
19
20
 
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Step: Install plugins using Claude Code CLI.
3
+ *
4
+ * Uses `claude plugin install <plugin>@<marketplace> --scope <scope>` commands
5
+ * to install plugins at project scope.
6
+ */
7
+
8
+ import { spawn } from 'node:child_process'
9
+ import path from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
11
+
12
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
13
+
14
+ /**
15
+ * @param {object} opts
16
+ * @param {string} opts.targetDir - Project root
17
+ * @param {Array<{id: string, def: object}>} opts.plugins - Resolved plugins with scope
18
+ * @param {boolean} opts.skip - Skip this step
19
+ * @param {object} logger
20
+ * @returns {Promise<import('../core/orchestrator.js').StepResult>}
21
+ */
22
+ export async function addPlugin(opts, logger) {
23
+ if (opts.skip) {
24
+ return { stepId: 'add-plugin', name: 'Add Plugin (CLI)', success: true, skipped: true, details: {} }
25
+ }
26
+
27
+ const projectPlugins = opts.plugins.filter(p => p.def.scope === 'project' || !p.def.scope)
28
+
29
+ if (projectPlugins.length === 0) {
30
+ logger.debug('No project-scoped plugins to install via CLI')
31
+ return {
32
+ stepId: 'add-plugin',
33
+ name: 'Add Plugin (CLI)',
34
+ success: true,
35
+ skipped: false,
36
+ details: { installed: [], errors: [] },
37
+ }
38
+ }
39
+
40
+ const installed = []
41
+ const errors = []
42
+
43
+ for (const { id, def } of projectPlugins) {
44
+ const pluginKey = `${id}@${def.marketplace}`
45
+ const scope = def.scope || 'project'
46
+
47
+ try {
48
+ logger.info(` Installing ${pluginKey} (scope: ${scope})...`)
49
+
50
+ await execCommand('claude', [
51
+ 'plugin',
52
+ 'install',
53
+ pluginKey,
54
+ '--scope',
55
+ scope,
56
+ ], logger)
57
+
58
+ installed.push({ id: pluginKey, scope })
59
+ logger.success(` ✓ ${pluginKey} installed`)
60
+ } catch (err) {
61
+ errors.push({ id: pluginKey, error: err.message })
62
+ logger.warn(` ✗ Failed to install ${pluginKey}: ${err.message}`)
63
+ }
64
+ }
65
+
66
+ return {
67
+ stepId: 'add-plugin',
68
+ name: 'Add Plugin (CLI)',
69
+ success: errors.length === 0,
70
+ skipped: false,
71
+ details: {
72
+ installed,
73
+ errors,
74
+ },
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Execute a command and return a promise.
80
+ *
81
+ * @param {string} command - Command to run
82
+ * @param {string[]} args - Command arguments
83
+ * @param {object} logger - Logger instance
84
+ * @returns {Promise<void>}
85
+ */
86
+ function execCommand(command, args, logger) {
87
+ return new Promise((resolve, reject) => {
88
+ const proc = spawn(command, args, {
89
+ shell: true,
90
+ stdio: 'pipe',
91
+ })
92
+
93
+ let stdout = ''
94
+ let stderr = ''
95
+
96
+ proc.stdout.on('data', (data) => {
97
+ stdout += data.toString()
98
+ })
99
+
100
+ proc.stderr.on('data', (data) => {
101
+ stderr += data.toString()
102
+ })
103
+
104
+ proc.on('close', (code) => {
105
+ if (code === 0) {
106
+ resolve()
107
+ } else {
108
+ reject(new Error(stderr || stdout || `Exit code: ${code}`))
109
+ }
110
+ })
111
+
112
+ proc.on('error', (err) => {
113
+ reject(err)
114
+ })
115
+ })
116
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Version comparison utilities for detecting configuration changes.
3
+ *
4
+ * Compares installed versions (from manifest) with registry versions
5
+ * to determine which components need updating.
6
+ */
7
+
8
+ import { loadRegistry } from '../core/registry.js'
9
+
10
+ /**
11
+ * Component map: stepId -> version key in registry.versions
12
+ */
13
+ const COMPONENT_MAP = {
14
+ 'configure-user': 'userSettings',
15
+ 'enable-plugins': 'plugins',
16
+ 'install-rules': 'rules',
17
+ 'install-skills': 'skills',
18
+ 'install-bmad': 'bmad',
19
+ 'install-mcp': 'mcp',
20
+ }
21
+
22
+ /**
23
+ * Compare installed versions against registry versions.
24
+ *
25
+ * @param {object} manifest - Installed manifest with config.versions
26
+ * @param {object} registry - Current registry with versions
27
+ * @returns {object} - { needsUpdate: boolean, components: { [stepId]: { current, latest, needsUpdate } } }
28
+ */
29
+ export function compareVersions(manifest, registry) {
30
+ const installedVersions = manifest.cckit?.config?.versions || {}
31
+ const latestVersions = registry.versions || {}
32
+
33
+ const components = {}
34
+ let needsUpdate = false
35
+
36
+ // Compare each component
37
+ for (const [stepId, versionKey] of Object.entries(COMPONENT_MAP)) {
38
+ const current = installedVersions[versionKey]
39
+ const latest = latestVersions[versionKey]
40
+
41
+ // If either version is missing, consider it needs update
42
+ const componentNeedsUpdate = !current || !latest || current !== latest
43
+
44
+ components[stepId] = {
45
+ versionKey,
46
+ current: current || 'none',
47
+ latest: latest || 'none',
48
+ needsUpdate: componentNeedsUpdate,
49
+ }
50
+
51
+ if (componentNeedsUpdate) {
52
+ needsUpdate = true
53
+ }
54
+ }
55
+
56
+ return { needsUpdate, components }
57
+ }
58
+
59
+ /**
60
+ * Check if specific component needs update.
61
+ *
62
+ * @param {object} manifest - Installed manifest
63
+ * @param {object} registry - Current registry
64
+ * @param {string} stepId - Step ID to check
65
+ * @returns {boolean}
66
+ */
67
+ export function needsComponentUpdate(manifest, registry, stepId) {
68
+ const versionKey = COMPONENT_MAP[stepId]
69
+ if (!versionKey) return false
70
+
71
+ const current = manifest.cckit?.config?.versions?.[versionKey]
72
+ const latest = registry.versions?.[versionKey]
73
+
74
+ return !current || !latest || current !== latest
75
+ }
76
+
77
+ /**
78
+ * Get version info for a specific component.
79
+ *
80
+ * @param {object} registry - Current registry
81
+ * @returns {object} - { plugins, rules, skills, bmad, mcp, userSettings }
82
+ */
83
+ export function getRegistryVersions(registry) {
84
+ return registry.versions || {}
85
+ }
86
+
87
+ /**
88
+ * Load registry and compare versions (async).
89
+ *
90
+ * @param {string} targetDir - Project directory
91
+ * @returns {Promise<{ needsUpdate: boolean, components: object }>}
92
+ */
93
+ export async function checkForUpdates(targetDir) {
94
+ const { readManifest } = await import('../utils/manifest.js')
95
+ const registry = await loadRegistry()
96
+
97
+ let manifest
98
+ try {
99
+ manifest = await readManifest(targetDir)
100
+ } catch {
101
+ // Not installed yet
102
+ return { needsUpdate: true, components: {}, notInstalled: true }
103
+ }
104
+
105
+ return compareVersions(manifest, registry)
106
+ }
@@ -1,16 +1,16 @@
1
- import chalk from 'chalk'
2
-
3
- export function createLogger(options = {}) {
4
- const { write = (msg) => console.log(msg), debug: debugEnabled = false } = options
5
-
6
- return {
7
- info: (msg) => write(msg),
8
- success: (msg) => write(chalk.green(` \u2713 ${msg}`)),
9
- error: (msg) => write(chalk.red(` \u2717 ${msg}`)),
10
- warn: (msg) => write(chalk.yellow(` \u26A0 ${msg}`)),
11
- debug: (msg) => { if (debugEnabled) write(chalk.gray(` [debug] ${msg}`)) },
12
- step: (current, total, msg) => write(chalk.blue(` [${current}/${total}] ${msg}`)),
13
- banner: (msg) => write(chalk.bold.green(`\n${msg}\n`)),
14
- newline: () => write('')
15
- }
16
- }
1
+ import chalk from 'chalk'
2
+
3
+ export function createLogger(options = {}) {
4
+ const { write = (msg) => console.log(msg), debug: debugEnabled = false } = options
5
+
6
+ return {
7
+ info: (msg) => write(msg),
8
+ success: (msg) => write(chalk.green(` \u2713 ${msg}`)),
9
+ error: (msg) => write(chalk.red(` \u2717 ${msg}`)),
10
+ warn: (msg) => write(chalk.yellow(` \u26A0 ${msg}`)),
11
+ debug: (msg) => { if (debugEnabled) write(chalk.gray(` [debug] ${msg}`)) },
12
+ step: (current, total, msg) => write(chalk.blue(` [${current}/${total}] ${msg}`)),
13
+ banner: (msg) => write(chalk.bold.green(`\n${msg}\n`)),
14
+ newline: () => write('')
15
+ }
16
+ }
@@ -69,9 +69,10 @@ export function serializeSteps(steps) {
69
69
  * @param {object} params.config - Merged config
70
70
  * @param {import('../core/orchestrator.js').RunReport} params.report - Orchestration report
71
71
  * @param {string} params.version - cckit version
72
+ * @param {object} [params.versions] - Component versions from registry
72
73
  * @returns {object} Manifest object
73
74
  */
74
- export function buildManifest({ config, report, version }) {
75
+ export function buildManifest({ config, report, version, versions = {} }) {
75
76
  return {
76
77
  cckit: {
77
78
  version,
@@ -81,6 +82,7 @@ export function buildManifest({ config, report, version }) {
81
82
  communication_language: config.communication_language,
82
83
  document_output_language: config.document_output_language,
83
84
  languages: config.languages,
85
+ versions,
84
86
  },
85
87
  steps: serializeSteps(report.steps),
86
88
  fileRegistry: report.fileRegistry,