@hunyed15/codecgc 0.1.0 → 0.1.2

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/INSTALLATION.md CHANGED
@@ -34,16 +34,39 @@ npm --version # 应显示 9.x.x 或更高
34
34
 
35
35
  ## 安装 CodeCGC
36
36
 
37
- ### 方式 1:从源码全局安装(推荐)
37
+ ### 方式 1:从 npm 全局安装(推荐)
38
38
 
39
39
  ```bash
40
- # 1. 解压 release 包到本地目录
41
- cd /path/to/codecgc/release
40
+ # 使用 npm 官方源安装
41
+ npm install -g @hunyed15/codecgc --registry=https://registry.npmjs.org/
42
+ ```
43
+
44
+ 安装完成后,CodeCGC 会尝试自动执行一次用户级 Claude 集成,相当于:
45
+
46
+ ```bash
47
+ cgc-install --mode user
48
+ ```
49
+
50
+ 这会写入:
51
+
52
+ - `~/.claude/mcp.json`
53
+ - `~/.claude/hooks/route-edit.ps1`
54
+ - `~/.claude/commands/cgc.md`
55
+ - `~/.claude/commands/cgc-install.md`
56
+ - `~/.claude/commands/cgc-status.md`
57
+ - `~/.claude/commands/cgc-doctor.md`
42
58
 
43
- # 2. 全局安装
44
- npm install -g .
59
+ 写入完成后,可以在 Claude 中直接输入:
60
+
61
+ ```text
62
+ /cgc
63
+ /cgc-install
64
+ /cgc-status
65
+ /cgc-doctor
45
66
  ```
46
67
 
68
+ 如果安装阶段因为 Python 未就绪而跳过了这一步,可以在装好 Python 后手动补执行该命令。
69
+
47
70
  安装后,以下命令将全局可用:
48
71
  - `cgc`
49
72
  - `cgc-install`
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # CodeCGC Release v0.1.0
1
+ # CodeCGC Release v0.1.2
2
2
 
3
3
  ## 📦 发布内容
4
4
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 📋 版本信息
8
8
 
9
- - **版本号**: 0.1.0
9
+ - **版本号**: 0.1.2
10
10
  - **发布日期**: 2026-05-04
11
11
  - **Python 要求**: >= 3.10
12
12
  - **Node.js 要求**: >= 20.0.0
@@ -36,20 +36,31 @@
36
36
  ### 1. 安装
37
37
 
38
38
  ```bash
39
- # 进入 release 目录
40
- cd /path/to/codecgc/release
41
-
42
- # 安装 CodeCGC
43
- npm install -g .
39
+ # npm 安装 CodeCGC
40
+ npm install -g @hunyed15/codecgc --registry=https://registry.npmjs.org/
44
41
 
45
42
  # 安装 Python 依赖
46
43
  pip install pyyaml
47
44
 
48
- # 安装 MCP 服务器
49
- cd codexmcp && pip install -e . && cd ..
50
- cd geminimcp && pip install -e . && cd ..
45
+ # 如自动集成未生效,可手动补执行
46
+ cgc-install --mode user
51
47
  ```
52
48
 
49
+ 全局安装完成后,CodeCGC 会尝试自动写入 Claude 用户级集成到 `~/.claude`,包括:
50
+
51
+ - `~/.claude/mcp.json`
52
+ - `~/.claude/hooks/route-edit.ps1`
53
+ - `~/.claude/commands/cgc*.md` 自定义 slash commands
54
+
55
+ 安装完成后,可以在 Claude 中直接使用:
56
+
57
+ - `/cgc`
58
+ - `/cgc-install`
59
+ - `/cgc-status`
60
+ - `/cgc-doctor`
61
+
62
+ 如果安装时 Python 尚未就绪,自动集成会跳过,此时可在安装 Python 后手动执行 `cgc-install --mode user`。
63
+
53
64
  ### 2. 初始化项目
54
65
 
55
66
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunyed15/codecgc",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Claude-hosted multi-model workflow product shell for CodeCGC.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -23,6 +23,7 @@
23
23
  "cgc-route": "bin/cgc-route.js"
24
24
  },
25
25
  "scripts": {
26
+ "postinstall": "node scripts/postinstall_codecgc.js",
26
27
  "cgc:help": "node bin/cgc.js --help",
27
28
  "cgc:status": "node bin/cgc-status.js --format summary",
28
29
  "cgc:doctor": "node bin/cgc-doctor.js --format summary",
@@ -39,6 +40,7 @@
39
40
  "files": [
40
41
  "bin/",
41
42
  "scripts/*.py",
43
+ "scripts/postinstall_codecgc.js",
42
44
  "scripts/README-codecgc-cli.md",
43
45
  ".claude/hooks/route-edit.ps1",
44
46
  "codecgc/cgc/",
@@ -64,6 +64,7 @@ def get_user_claude_paths(override_root: str = "") -> dict[str, Path]:
64
64
  "mcp": root / "mcp.json",
65
65
  "hooks_dir": root / "hooks",
66
66
  "hook_script": root / "hooks" / "route-edit.ps1",
67
+ "commands_dir": root / "commands",
67
68
  }
68
69
 
69
70
 
@@ -78,6 +79,7 @@ def get_workspace_paths(override_workspace: str = "") -> dict[str, Path]:
78
79
  "settings": claude_dir / "settings.json",
79
80
  "mcp": root / ".mcp.json",
80
81
  "hook_script": hooks_dir / "route-edit.ps1",
82
+ "commands_dir": claude_dir / "commands",
81
83
  "routing_file": root / "model-routing.yaml",
82
84
  }
83
85
 
@@ -110,6 +112,79 @@ def build_hook_payload(command_text: str) -> dict[str, Any]:
110
112
  }
111
113
 
112
114
 
115
+ def _normalize_command_path_for_markdown(path: Path) -> str:
116
+ return str(path).replace("\\", "\\\\")
117
+
118
+
119
+ def build_custom_command_templates(bin_dir: Path) -> dict[str, str]:
120
+ cgc_js = _normalize_command_path_for_markdown(bin_dir / "cgc.js")
121
+ install_js = _normalize_command_path_for_markdown(bin_dir / "cgc-install.js")
122
+ status_js = _normalize_command_path_for_markdown(bin_dir / "cgc-status.js")
123
+ doctor_js = _normalize_command_path_for_markdown(bin_dir / "cgc-doctor.js")
124
+
125
+ return {
126
+ "cgc.md": f"""---
127
+ description: Run CodeCGC in the current project
128
+ argument-hint: "[request or flags]"
129
+ ---
130
+ Use the Bash tool to run CodeCGC in the current project directory.
131
+
132
+ - If the user supplied arguments, run:
133
+ `node "{cgc_js}" $ARGUMENTS`
134
+ - If the user did not supply arguments, run:
135
+ `node "{cgc_js}" --help`
136
+ - Show the command you ran and summarize the result briefly.
137
+ """,
138
+ "cgc-install.md": f"""---
139
+ description: Install or sync CodeCGC integration for the current project or user Claude profile
140
+ argument-hint: "[flags]"
141
+ ---
142
+ Use the Bash tool to run the CodeCGC install command.
143
+
144
+ - If the user supplied arguments, run:
145
+ `node "{install_js}" $ARGUMENTS`
146
+ - If the user did not supply arguments, run:
147
+ `node "{install_js}"`
148
+ - Show the command you ran and summarize the result briefly.
149
+ """,
150
+ "cgc-status.md": f"""---
151
+ description: Check CodeCGC integration status
152
+ argument-hint: "[flags]"
153
+ ---
154
+ Use the Bash tool to run the CodeCGC status command.
155
+
156
+ - If the user supplied arguments, run:
157
+ `node "{status_js}" $ARGUMENTS`
158
+ - If the user did not supply arguments, run:
159
+ `node "{status_js}"`
160
+ - Show the command you ran and summarize the result briefly.
161
+ """,
162
+ "cgc-doctor.md": f"""---
163
+ description: Run CodeCGC doctor checks
164
+ argument-hint: "[flags]"
165
+ ---
166
+ Use the Bash tool to run the CodeCGC doctor command.
167
+
168
+ - If the user supplied arguments, run:
169
+ `node "{doctor_js}" $ARGUMENTS`
170
+ - If the user did not supply arguments, run:
171
+ `node "{doctor_js}"`
172
+ - Show the command you ran and summarize the result briefly.
173
+ """,
174
+ }
175
+
176
+
177
+ def write_custom_command_files(target_dir: Path, bin_dir: Path) -> list[str]:
178
+ target_dir.mkdir(parents=True, exist_ok=True)
179
+ templates = build_custom_command_templates(bin_dir)
180
+ written: list[str] = []
181
+ for filename, content in templates.items():
182
+ path = target_dir / filename
183
+ path.write_text(content, encoding="utf-8")
184
+ written.append(str(path))
185
+ return written
186
+
187
+
113
188
  def merge_hook_settings(current: dict[str, Any], command_text: str) -> tuple[dict[str, Any], bool]:
114
189
  hooks = current.get("hooks")
115
190
  expected_hooks = build_hook_payload(command_text)
@@ -240,6 +315,7 @@ def install_local_runtime(override_workspace: str = "") -> dict[str, Any]:
240
315
 
241
316
  if PROJECT_HOOK_PATH.resolve() != workspace_paths["hook_script"].resolve():
242
317
  shutil.copyfile(PROJECT_HOOK_PATH, workspace_paths["hook_script"])
318
+ written_commands = write_custom_command_files(workspace_paths["commands_dir"], WORKSPACE / "bin")
243
319
 
244
320
  summary = build_mode_summary_payload(
245
321
  scope="项目级 Claude 与 MCP 集成面",
@@ -255,10 +331,13 @@ def install_local_runtime(override_workspace: str = "") -> dict[str, Any]:
255
331
  "routing_file": str(routing_path),
256
332
  "claude_settings": str(workspace_paths["settings"]),
257
333
  "hook_script": str(workspace_paths["hook_script"]),
334
+ "commands_dir": str(workspace_paths["commands_dir"]),
335
+ "command_files": written_commands,
258
336
  "notes": [
259
337
  "Repository-local MCP config was synced from the executor registry.",
260
338
  "Project-local model-routing.yaml was synchronized and preserves custom path blocks.",
261
339
  "Claude pre-edit guardrail hook was synchronized into the target workspace.",
340
+ "Project-local Claude slash commands were synchronized into .claude/commands.",
262
341
  "This mode prepares project-level integration surfaces for the selected workspace.",
263
342
  ],
264
343
  "summary": summary,
@@ -290,11 +369,13 @@ def preview_user_install(override_root: str = "") -> dict[str, Any]:
290
369
  "settings_json": str(user_paths["settings"]),
291
370
  "mcp_json": str(user_paths["mcp"]),
292
371
  "hook_script": str(user_paths["hook_script"]),
372
+ "commands_dir": str(user_paths["commands_dir"]),
293
373
  },
294
374
  "would_write": {
295
375
  "settings_changed": settings_changed or not user_paths["settings"].exists(),
296
376
  "mcp_changed": True,
297
377
  "hook_changed": True,
378
+ "commands_changed": True,
298
379
  },
299
380
  "preview": {
300
381
  "settings": sanitize_for_preview(merged_settings),
@@ -313,12 +394,14 @@ def install_user_runtime(override_root: str = "") -> dict[str, Any]:
313
394
  user_paths = get_user_claude_paths(override_root)
314
395
  user_paths["root"].mkdir(parents=True, exist_ok=True)
315
396
  user_paths["hooks_dir"].mkdir(parents=True, exist_ok=True)
397
+ user_paths["commands_dir"].mkdir(parents=True, exist_ok=True)
316
398
 
317
399
  settings = load_json_file(user_paths["settings"])
318
400
  merged_settings, settings_changed = merge_hook_settings(settings, build_user_hook_command(user_paths))
319
401
  write_json_file(user_paths["settings"], merged_settings)
320
402
  write_json_file(user_paths["mcp"], build_mcp_config())
321
403
  shutil.copyfile(PROJECT_HOOK_PATH, user_paths["hook_script"])
404
+ written_commands = write_custom_command_files(user_paths["commands_dir"], WORKSPACE / "bin")
322
405
  summary = build_mode_summary_payload(
323
406
  scope="用户级 Claude 集成面",
324
407
  human_summary="用户级 Claude 集成文件已写入。",
@@ -334,15 +417,19 @@ def install_user_runtime(override_root: str = "") -> dict[str, Any]:
334
417
  "settings_json": str(user_paths["settings"]),
335
418
  "mcp_json": str(user_paths["mcp"]),
336
419
  "hook_script": str(user_paths["hook_script"]),
420
+ "commands_dir": str(user_paths["commands_dir"]),
337
421
  },
338
422
  "changes": {
339
423
  "settings_changed": settings_changed or not user_paths["settings"].exists(),
340
424
  "mcp_changed": True,
341
425
  "hook_changed": True,
426
+ "commands_changed": True,
342
427
  },
428
+ "command_files": written_commands,
343
429
  "notes": [
344
430
  "User-level Claude integration files were written to the selected root.",
345
431
  "The user-level hook script was copied from the project hook source.",
432
+ "User-level Claude slash commands were written to ~/.claude/commands.",
346
433
  "This mode is explicit and should be used only when a broader Claude integration surface is intended.",
347
434
  ],
348
435
  "summary": summary,
@@ -373,6 +460,7 @@ def build_install_mode_summary(result: dict[str, Any]) -> str:
373
460
  f"- Routing 文件: {result.get('routing_file', '')}",
374
461
  f"- Claude 设置: {result.get('claude_settings', '')}",
375
462
  f"- Hook 脚本: {result.get('hook_script', '')}",
463
+ f"- Slash Commands: {result.get('commands_dir', '')}",
376
464
  "- 说明: 可选外部能力如 MemOS 不由 cgc-install 自动写入;如需启用,请在 Claude 中单独配置官方 MCP。",
377
465
  ]
378
466
  next_actions = [
@@ -391,6 +479,7 @@ def build_install_mode_summary(result: dict[str, Any]) -> str:
391
479
  f"- 预演 Settings: {planned.get('settings_json', '')}",
392
480
  f"- 预演 MCP: {planned.get('mcp_json', '')}",
393
481
  f"- 预演 Hook: {planned.get('hook_script', '')}",
482
+ f"- 预演 Slash Commands: {planned.get('commands_dir', '')}",
394
483
  "- 说明: 该预演只覆盖 CodeCGC 必需执行器;MemOS 等可选外部能力仍建议在 Claude 中独立配置。",
395
484
  ]
396
485
  next_actions = []
@@ -410,6 +499,7 @@ def build_install_mode_summary(result: dict[str, Any]) -> str:
410
499
  f"- Settings: {written.get('settings_json', '')}",
411
500
  f"- MCP: {written.get('mcp_json', '')}",
412
501
  f"- Hook 脚本: {written.get('hook_script', '')}",
502
+ f"- Slash Commands: {written.get('commands_dir', '')}",
413
503
  "- 说明: 该安装只写入 CodeCGC 必需执行器;MemOS 等可选外部能力仍需在 Claude 中单独配置。",
414
504
  ]
415
505
  next_actions = [
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawnSync } = require("node:child_process");
4
+ const path = require("node:path");
5
+
6
+ function shouldRunUserInstall() {
7
+ const globalFlag = String(process.env.npm_config_global || "").toLowerCase();
8
+ const localPrefix = String(process.env.npm_config_local_prefix || "");
9
+ const prefix = String(process.env.npm_config_prefix || "");
10
+
11
+ if (globalFlag === "true") {
12
+ return true;
13
+ }
14
+ if (prefix && localPrefix && prefix !== localPrefix) {
15
+ return true;
16
+ }
17
+ return false;
18
+ }
19
+
20
+ function findPython() {
21
+ const override = String(process.env.CODECGC_PYTHON_COMMAND || "").trim();
22
+ const candidates = override
23
+ ? [override]
24
+ : (process.platform === "win32" ? ["python", "py"] : ["python3", "python"]);
25
+
26
+ for (const command of candidates) {
27
+ const probe = spawnSync(command, ["--version"], {
28
+ encoding: "utf8",
29
+ shell: false,
30
+ });
31
+ if (probe.status === 0) {
32
+ return command;
33
+ }
34
+ }
35
+ return "";
36
+ }
37
+
38
+ function main() {
39
+ if (!shouldRunUserInstall()) {
40
+ return 0;
41
+ }
42
+
43
+ const python = findPython();
44
+ if (!python) {
45
+ console.warn("[codecgc] Skipped automatic Claude integration: Python was not found.");
46
+ console.warn("[codecgc] Run `cgc-install --mode user` after installing Python.");
47
+ return 0;
48
+ }
49
+
50
+ const repoRoot = path.resolve(__dirname, "..");
51
+ const installScript = path.join(repoRoot, "scripts", "install_codecgc.py");
52
+ const result = spawnSync(
53
+ python,
54
+ [installScript, "--mode", "user", "--format", "summary"],
55
+ {
56
+ cwd: repoRoot,
57
+ stdio: "inherit",
58
+ shell: false,
59
+ env: {
60
+ ...process.env,
61
+ PYTHONIOENCODING: process.env.PYTHONIOENCODING || "utf-8",
62
+ PYTHONUTF8: process.env.PYTHONUTF8 || "1",
63
+ },
64
+ },
65
+ );
66
+
67
+ if (result.status !== 0) {
68
+ console.warn("[codecgc] Automatic Claude integration did not complete during npm install.");
69
+ console.warn("[codecgc] You can retry manually with `cgc-install --mode user`.");
70
+ }
71
+
72
+ return 0;
73
+ }
74
+
75
+ process.exit(main());