@hunyed15/codecgc 0.1.1 → 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
@@ -47,6 +47,24 @@ npm install -g @hunyed15/codecgc --registry=https://registry.npmjs.org/
47
47
  cgc-install --mode user
48
48
  ```
49
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`
58
+
59
+ 写入完成后,可以在 Claude 中直接输入:
60
+
61
+ ```text
62
+ /cgc
63
+ /cgc-install
64
+ /cgc-status
65
+ /cgc-doctor
66
+ ```
67
+
50
68
  如果安装阶段因为 Python 未就绪而跳过了这一步,可以在装好 Python 后手动补执行该命令。
51
69
 
52
70
  安装后,以下命令将全局可用:
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # CodeCGC Release v0.1.1
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.1
9
+ - **版本号**: 0.1.2
10
10
  - **发布日期**: 2026-05-04
11
11
  - **Python 要求**: >= 3.10
12
12
  - **Node.js 要求**: >= 20.0.0
@@ -46,7 +46,19 @@ pip install pyyaml
46
46
  cgc-install --mode user
47
47
  ```
48
48
 
49
- 全局安装完成后,CodeCGC 会尝试自动写入 Claude 用户级集成到 `~/.claude`。
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
+
50
62
  如果安装时 Python 尚未就绪,自动集成会跳过,此时可在安装 Python 后手动执行 `cgc-install --mode user`。
51
63
 
52
64
  ### 2. 初始化项目
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunyed15/codecgc",
3
- "version": "0.1.1",
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",
@@ -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 = [