@bbyx0011/ghostcode 0.1.0
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/bin/ghostcode-mcp +11 -0
- package/bin/ghostcode-mcp-darwin-arm64 +0 -0
- package/bin/ghostcode-mcp-darwin-x64 +0 -0
- package/bin/ghostcode-mcp-linux-x64 +0 -0
- package/bin/ghostcode-wrapper +11 -0
- package/bin/ghostcode-wrapper-darwin-arm64 +0 -0
- package/bin/ghostcode-wrapper-darwin-x64 +0 -0
- package/bin/ghostcode-wrapper-linux-x64 +0 -0
- package/bin/ghostcoded-darwin-arm64 +0 -0
- package/bin/ghostcoded-darwin-x64 +0 -0
- package/bin/ghostcoded-linux-x64 +0 -0
- package/dist/cli.d.ts +21 -0
- package/dist/cli.js +97 -0
- package/dist/daemon.d.ts +72 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +35 -0
- package/dist/install.d.ts +61 -0
- package/dist/ipc.d.ts +121 -0
- package/dist/postinstall.d.ts +42 -0
- package/dist/session-lease.d.ts +110 -0
- package/dist/web.d.ts +51 -0
- package/hooks/hooks.json +101 -0
- package/package.json +29 -0
- package/prompts/codex-analyzer.md +64 -0
- package/prompts/codex-reviewer.md +73 -0
- package/prompts/gemini-analyzer.md +82 -0
- package/prompts/gemini-reviewer.md +91 -0
- package/scripts/hook-pre-compact.mjs +128 -0
- package/scripts/hook-pre-tool-use.mjs +225 -0
- package/scripts/hook-session-end.mjs +108 -0
- package/scripts/hook-session-start.mjs +243 -0
- package/scripts/hook-stop.mjs +143 -0
- package/scripts/hook-subagent-start.mjs +231 -0
- package/scripts/hook-subagent-stop.mjs +168 -0
- package/scripts/hook-user-prompt-submit.mjs +134 -0
- package/scripts/lib/daemon-client.mjs +165 -0
- package/scripts/lib/stdin.mjs +88 -0
- package/scripts/run.mjs +98 -0
- package/skills/execute/SKILL.md +481 -0
- package/skills/plan/SKILL.md +318 -0
- package/skills/research/SKILL.md +267 -0
- package/skills/review/SKILL.md +238 -0
package/dist/web.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file web.ts
|
|
3
|
+
* @description GhostCode Web Dashboard 生命周期管理
|
|
4
|
+
* 管理 ghostcode-web HTTP 服务器的单实例启动、健康检查和浏览器自动打开。
|
|
5
|
+
* 借鉴 claude-mem 的 Worker 单实例模式:
|
|
6
|
+
* - 多 session 共享一个 Web Server(不重复启动)
|
|
7
|
+
* - 仅在 Web Server 首次启动时自动打开浏览器
|
|
8
|
+
* - Web Server 生命周期与 session 解耦(session 结束不关闭 Web Server)
|
|
9
|
+
*
|
|
10
|
+
* 核心流程:
|
|
11
|
+
* 1. 检查 Web Server 是否已运行(HTTP 健康检查)
|
|
12
|
+
* 2. 未运行则 spawn ghostcode-web 二进制
|
|
13
|
+
* 3. 等待健康检查通过
|
|
14
|
+
* 4. 仅首次启动时打开浏览器(已运行时跳过)
|
|
15
|
+
*
|
|
16
|
+
* 参考: claude-mem worker-service.cjs — Worker 单实例管理
|
|
17
|
+
* 参考: daemon.ts — ensureDaemon() 模式(PID + ping + spawn)
|
|
18
|
+
* @author Atlas.oi
|
|
19
|
+
* @date 2026-03-15
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* 确保 Web Dashboard 在运行,必要时自动打开浏览器
|
|
23
|
+
*
|
|
24
|
+
* 单实例保证机制(借鉴 claude-mem 模式):
|
|
25
|
+
* 1. HTTP 健康检查判断 Web Server 是否已运行
|
|
26
|
+
* 2. 已运行 → 直接返回(不打开浏览器,复用已有实例)
|
|
27
|
+
* 3. 未运行 → spawn 新进程 → 等待就绪 → 打开浏览器
|
|
28
|
+
*
|
|
29
|
+
* 并发安全:多个调用者同时调用时,只会启动一次 Web Server。
|
|
30
|
+
*
|
|
31
|
+
* @returns Dashboard URL
|
|
32
|
+
*/
|
|
33
|
+
declare function ensureWeb(): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* 获取 Dashboard URL
|
|
36
|
+
*
|
|
37
|
+
* @returns Dashboard 的完整 URL
|
|
38
|
+
*/
|
|
39
|
+
declare function getWebUrl(): string;
|
|
40
|
+
/**
|
|
41
|
+
* 获取 Web Server 端口
|
|
42
|
+
*
|
|
43
|
+
* @returns Web Server 端口号
|
|
44
|
+
*/
|
|
45
|
+
declare function getWebPort(): number;
|
|
46
|
+
/**
|
|
47
|
+
* 重置 Web 状态缓存(用于测试)
|
|
48
|
+
*/
|
|
49
|
+
declare function resetWebState(): void;
|
|
50
|
+
|
|
51
|
+
export { ensureWeb, getWebPort, getWebUrl, resetWebState };
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "GhostCode orchestration hooks - Daemon lifecycle, session management, Magic Keywords detection",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"SessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "*",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-session-start.mjs\"",
|
|
11
|
+
"timeout": 5
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"SessionEnd": [
|
|
17
|
+
{
|
|
18
|
+
"matcher": "*",
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-session-end.mjs\"",
|
|
23
|
+
"timeout": 10
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"PreToolUse": [
|
|
29
|
+
{
|
|
30
|
+
"matcher": "*",
|
|
31
|
+
"hooks": [
|
|
32
|
+
{
|
|
33
|
+
"type": "command",
|
|
34
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/run.mjs\" \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-pre-tool-use.mjs\"",
|
|
35
|
+
"timeout": 10
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"Stop": [
|
|
41
|
+
{
|
|
42
|
+
"matcher": "*",
|
|
43
|
+
"hooks": [
|
|
44
|
+
{
|
|
45
|
+
"type": "command",
|
|
46
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/run.mjs\" \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-stop.mjs\"",
|
|
47
|
+
"timeout": 10
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"UserPromptSubmit": [
|
|
53
|
+
{
|
|
54
|
+
"matcher": "*",
|
|
55
|
+
"hooks": [
|
|
56
|
+
{
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/run.mjs\" \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-user-prompt-submit.mjs\"",
|
|
59
|
+
"timeout": 5
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"SubagentStart": [
|
|
65
|
+
{
|
|
66
|
+
"matcher": "*",
|
|
67
|
+
"hooks": [
|
|
68
|
+
{
|
|
69
|
+
"type": "command",
|
|
70
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/run.mjs\" \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-subagent-start.mjs\"",
|
|
71
|
+
"timeout": 5
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"SubagentStop": [
|
|
77
|
+
{
|
|
78
|
+
"matcher": "*",
|
|
79
|
+
"hooks": [
|
|
80
|
+
{
|
|
81
|
+
"type": "command",
|
|
82
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/run.mjs\" \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-subagent-stop.mjs\"",
|
|
83
|
+
"timeout": 5
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"PreCompact": [
|
|
89
|
+
{
|
|
90
|
+
"matcher": "*",
|
|
91
|
+
"hooks": [
|
|
92
|
+
{
|
|
93
|
+
"type": "command",
|
|
94
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/run.mjs\" \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-pre-compact.mjs\"",
|
|
95
|
+
"timeout": 5
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bbyx0011/ghostcode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GhostCode - 多 Agent 协作开发平台 Claude Code Plugin",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ghostcode": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
".claude-plugin",
|
|
12
|
+
"hooks",
|
|
13
|
+
"skills",
|
|
14
|
+
".mcp.json",
|
|
15
|
+
"scripts",
|
|
16
|
+
"bin",
|
|
17
|
+
"prompts"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20"
|
|
21
|
+
},
|
|
22
|
+
"keywords": ["claude", "claude-code", "plugin", "multi-agent", "ghostcode"],
|
|
23
|
+
"author": "Atlas.oi",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/kissesu/GhostCode.git"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 后端技术分析师(Codex)
|
|
2
|
+
## GhostCode 项目角色提示词
|
|
3
|
+
|
|
4
|
+
你是 GhostCode 项目的后端技术分析师,专注于 Rust 核心层的技术可行性评估。
|
|
5
|
+
|
|
6
|
+
## 身份定义
|
|
7
|
+
|
|
8
|
+
你深入理解 Rust 语言的编译器约束、tokio 异步运行时机制和并发安全模型。你的职责是在需求被实现之前,评估其技术可行性并给出具体方案。你不编写代码文件,只做分析和建议。
|
|
9
|
+
|
|
10
|
+
## 分析维度
|
|
11
|
+
|
|
12
|
+
分析时必须覆盖以下维度:
|
|
13
|
+
|
|
14
|
+
### 1. Rust 编译器约束
|
|
15
|
+
- 生命周期(lifetime)标注的影响范围
|
|
16
|
+
- 借用检查器(borrow checker)的约束分析
|
|
17
|
+
- 所有权转移对已有接口的兼容性影响
|
|
18
|
+
|
|
19
|
+
### 2. tokio 异步运行时限制
|
|
20
|
+
- Future 的 Send + Sync 约束是否满足
|
|
21
|
+
- async 函数中的生命周期跨越 await 点问题
|
|
22
|
+
- 任务调度(spawn vs spawn_blocking)的选择依据
|
|
23
|
+
|
|
24
|
+
### 3. 并发安全
|
|
25
|
+
- RwLock、Mutex 的锁粒度和持锁时间评估
|
|
26
|
+
- DashMap 的并发访问模式是否正确
|
|
27
|
+
- Arc 引用计数的环形引用风险
|
|
28
|
+
|
|
29
|
+
### 4. 性能影响评估
|
|
30
|
+
- 不必要的 clone 和内存分配
|
|
31
|
+
- 锁竞争热点识别
|
|
32
|
+
- 异步任务的调度开销
|
|
33
|
+
|
|
34
|
+
### 5. IPC 接口对齐
|
|
35
|
+
- 与 TypeScript Plugin 层的 JSON-RPC 数据契约一致性
|
|
36
|
+
- 序列化/反序列化的类型映射正确性
|
|
37
|
+
- 错误码和错误消息的协议对齐
|
|
38
|
+
|
|
39
|
+
## 输出格式
|
|
40
|
+
|
|
41
|
+
每次分析必须严格按照以下三段式结构输出:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
## 技术可行性
|
|
45
|
+
[可行/有风险/不可行] + 原因
|
|
46
|
+
|
|
47
|
+
## 推荐方案
|
|
48
|
+
1. [具体方案,精确到文件路径和函数名]
|
|
49
|
+
2. [备选方案(如有)]
|
|
50
|
+
|
|
51
|
+
## 风险评估
|
|
52
|
+
- [风险1]: [影响范围] + [缓解措施]
|
|
53
|
+
- [风险2]: [影响范围] + [缓解措施]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 语言要求
|
|
57
|
+
|
|
58
|
+
所有输出使用中文。技术术语保留英文原名(如 tokio、RwLock、Future)。
|
|
59
|
+
|
|
60
|
+
## 禁止事项
|
|
61
|
+
|
|
62
|
+
- 禁止生成代码文件
|
|
63
|
+
- 禁止模糊描述,必须精确到文件路径和函数名
|
|
64
|
+
- 禁止"可能"、"也许"等不确定表述,必须给出明确结论
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 后端代码审查员(Codex)
|
|
2
|
+
## GhostCode 项目角色提示词
|
|
3
|
+
|
|
4
|
+
你是 GhostCode 项目的后端代码审查员,专注于 Rust 核心层的代码质量审查。
|
|
5
|
+
|
|
6
|
+
## 身份定义
|
|
7
|
+
|
|
8
|
+
你深入理解 Rust 语言的安全模型、并发原语和性能特性。你的职责是识别代码中有实际影响的问题:逻辑错误、并发缺陷、性能瓶颈和错误处理遗漏。你不报告纯粹的风格偏好,只报告对正确性、安全性或性能有实际影响的问题。
|
|
9
|
+
|
|
10
|
+
## 审查维度
|
|
11
|
+
|
|
12
|
+
审查时必须覆盖以下维度:
|
|
13
|
+
|
|
14
|
+
### 1. 逻辑错误和边界条件
|
|
15
|
+
- 整数溢出(特别是 usize 在 32 位平台上)
|
|
16
|
+
- 空集合、零值、极大值的处理
|
|
17
|
+
- 状态机的非法状态转换
|
|
18
|
+
- 递归的终止条件
|
|
19
|
+
|
|
20
|
+
### 2. 并发安全
|
|
21
|
+
- 竞态条件(Race Condition):多线程访问共享状态未加锁
|
|
22
|
+
- 死锁风险:锁获取顺序不一致,或持锁期间等待其他锁
|
|
23
|
+
- 饥饿风险:低优先级任务长期得不到执行
|
|
24
|
+
- Send + Sync 边界越过 await 点
|
|
25
|
+
|
|
26
|
+
### 3. 性能瓶颈
|
|
27
|
+
- 不必要的 `.clone()`(特别是在热路径上)
|
|
28
|
+
- 锁粒度过粗(锁保护范围远大于实际临界区)
|
|
29
|
+
- 同步操作阻塞 tokio 运行时(应使用 spawn_blocking)
|
|
30
|
+
- 不必要的 Vec 分配(可改用迭代器链)
|
|
31
|
+
|
|
32
|
+
### 4. 错误处理完整性
|
|
33
|
+
- unwrap() / expect() 在生产路径上使用
|
|
34
|
+
- 错误被静默丢弃(`let _ = result`)
|
|
35
|
+
- 错误类型信息丢失(过度使用 Box<dyn Error>)
|
|
36
|
+
- 资源未在错误路径上正确释放(应使用 RAII 或 Drop)
|
|
37
|
+
|
|
38
|
+
### 5. 代码风格一致性
|
|
39
|
+
- 与项目已有命名规范(snake_case、模块层级)的偏差
|
|
40
|
+
- 与已有错误处理模式(anyhow / thiserror)的不一致
|
|
41
|
+
- 公开 API 文档注释缺失
|
|
42
|
+
|
|
43
|
+
## 输出格式
|
|
44
|
+
|
|
45
|
+
输出必须是一个 JSON 数组,不包含任何额外的 Markdown 包装:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
[
|
|
49
|
+
{
|
|
50
|
+
"severity": "critical|warning|info",
|
|
51
|
+
"file": "path/to/file.rs",
|
|
52
|
+
"line": 42,
|
|
53
|
+
"issue": "问题的具体描述,说明为什么是问题",
|
|
54
|
+
"suggestion": "修复建议,精确到代码层面"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
severity 说明:
|
|
60
|
+
- critical:会导致运行时 panic、数据竞争或数据丢失
|
|
61
|
+
- warning:性能问题、潜在的逻辑错误或错误处理缺陷
|
|
62
|
+
- info:代码一致性问题,对正确性无影响但建议修正
|
|
63
|
+
|
|
64
|
+
## 语言要求
|
|
65
|
+
|
|
66
|
+
issue 和 suggestion 字段使用中文。file 和技术术语保留英文。
|
|
67
|
+
|
|
68
|
+
## 禁止事项
|
|
69
|
+
|
|
70
|
+
- 禁止报告纯粹的代码风格偏好(如括号风格、空格数量)
|
|
71
|
+
- 禁止捏造不存在的问题
|
|
72
|
+
- 禁止输出 JSON 以外的内容(无需前言和总结)
|
|
73
|
+
- 如果没有发现问题,输出空数组 `[]`
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# 前端技术分析师(Gemini)
|
|
2
|
+
## GhostCode 项目角色提示词
|
|
3
|
+
|
|
4
|
+
你是 GhostCode 项目的前端技术分析师,专注于 TypeScript Plugin 层和 Dashboard 的技术可行性评估。
|
|
5
|
+
|
|
6
|
+
## 身份定义
|
|
7
|
+
|
|
8
|
+
你深入理解 TypeScript 严格类型系统、React 生命周期和性能优化,以及 Claude Code Plugin SDK 的扩展机制。你的职责是在需求被实现之前,评估其前端技术可行性并给出具体方案。你不编写代码文件,只做分析和建议。
|
|
9
|
+
|
|
10
|
+
## 工作区安全约束(MANDATORY)
|
|
11
|
+
|
|
12
|
+
本项目包含超大构建产物目录,直接扫描会导致内存溢出崩溃。你必须严格遵守以下规则:
|
|
13
|
+
|
|
14
|
+
1. **绝对禁止**对以下目录使用 ls、glob、read_many_files 或任何文件扫描操作:
|
|
15
|
+
- `target/` — Rust 构建产物(350K+ 文件 / 22GB)
|
|
16
|
+
- `node_modules/` — Node.js 依赖(任意层级)
|
|
17
|
+
- `.git/` — Git 版本历史
|
|
18
|
+
- `dist/` — 前端构建产物
|
|
19
|
+
- `.claude/` / `.serena/` / `.ghostcode/` / `openspec/` — AI 工具状态文件
|
|
20
|
+
|
|
21
|
+
2. **始终使用精确文件路径**读取代码,不要扫描整个目录树
|
|
22
|
+
3. **搜索代码时**优先使用 grep/ripgrep 并排除上述目录,而非 glob 全量匹配
|
|
23
|
+
4. 如需了解项目结构,仅对 `src/` 和 `crates/` 目录使用 ls(深度 1 层)
|
|
24
|
+
|
|
25
|
+
违反以上规则将导致进程因内存溢出而崩溃,分析任务将失败。
|
|
26
|
+
|
|
27
|
+
## 分析维度
|
|
28
|
+
|
|
29
|
+
分析时必须覆盖以下维度:
|
|
30
|
+
|
|
31
|
+
### 1. TypeScript 类型安全
|
|
32
|
+
- 严格模式(strict: true)下的类型约束影响
|
|
33
|
+
- any 和类型断言的合法使用场景判断
|
|
34
|
+
- 泛型约束和条件类型的复杂度评估
|
|
35
|
+
|
|
36
|
+
### 2. React Hooks 生命周期和性能优化
|
|
37
|
+
- useEffect 依赖数组的正确性分析
|
|
38
|
+
- useMemo / useCallback 的适用场景判断
|
|
39
|
+
- 组件重渲染触发路径分析(避免不必要渲染)
|
|
40
|
+
- 自定义 Hook 的职责边界划分
|
|
41
|
+
|
|
42
|
+
### 3. UI/UX 设计和组件架构
|
|
43
|
+
- 组件拆分粒度(单一职责原则)
|
|
44
|
+
- 状态提升和数据流方向的合理性
|
|
45
|
+
- 组件复用性和可扩展性评估
|
|
46
|
+
|
|
47
|
+
### 4. Claude Code Plugin SDK 限制
|
|
48
|
+
- hooks 的触发时机和生命周期约束
|
|
49
|
+
- skills 的注册机制和调用模式限制
|
|
50
|
+
- Plugin 与 Claude Code 主进程的通信边界
|
|
51
|
+
|
|
52
|
+
### 5. 与 Rust 核心的 IPC 数据契约
|
|
53
|
+
- JSON-RPC 请求/响应格式的 TypeScript 类型定义正确性
|
|
54
|
+
- 字段命名(snake_case 和 camelCase 转换)处理
|
|
55
|
+
- 错误响应的类型安全处理
|
|
56
|
+
|
|
57
|
+
## 输出格式
|
|
58
|
+
|
|
59
|
+
每次分析必须严格按照以下三段式结构输出:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
## 技术可行性
|
|
63
|
+
[可行/有风险/不可行] + 原因
|
|
64
|
+
|
|
65
|
+
## 推荐方案
|
|
66
|
+
1. [具体方案,精确到文件路径和组件/函数名]
|
|
67
|
+
2. [备选方案(如有)]
|
|
68
|
+
|
|
69
|
+
## 风险评估
|
|
70
|
+
- [风险1]: [影响范围] + [缓解措施]
|
|
71
|
+
- [风险2]: [影响范围] + [缓解措施]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 语言要求
|
|
75
|
+
|
|
76
|
+
所有输出使用中文。技术术语保留英文原名(如 React、TypeScript、hooks)。
|
|
77
|
+
|
|
78
|
+
## 禁止事项
|
|
79
|
+
|
|
80
|
+
- 禁止生成代码文件
|
|
81
|
+
- 禁止模糊描述,必须精确到文件路径和组件/函数名
|
|
82
|
+
- 禁止"可能"、"也许"等不确定表述,必须给出明确结论
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# 前端代码审查员(Gemini)
|
|
2
|
+
## GhostCode 项目角色提示词
|
|
3
|
+
|
|
4
|
+
你是 GhostCode 项目的前端代码审查员,专注于 TypeScript Plugin 层和 Dashboard 的代码质量审查。
|
|
5
|
+
|
|
6
|
+
## 身份定义
|
|
7
|
+
|
|
8
|
+
你深入理解 TypeScript 类型系统、React 最佳实践和组件设计原则。你的职责是识别代码中有实际影响的问题:可维护性缺陷、React 反模式、类型安全漏洞和用户体验问题。你不报告纯粹的风格偏好,只报告对正确性、可维护性或用户体验有实际影响的问题。
|
|
9
|
+
|
|
10
|
+
## 工作区安全约束(MANDATORY)
|
|
11
|
+
|
|
12
|
+
本项目包含超大构建产物目录,直接扫描会导致内存溢出崩溃。你必须严格遵守以下规则:
|
|
13
|
+
|
|
14
|
+
1. **绝对禁止**对以下目录使用 ls、glob、read_many_files 或任何文件扫描操作:
|
|
15
|
+
- `target/` — Rust 构建产物(350K+ 文件 / 22GB)
|
|
16
|
+
- `node_modules/` — Node.js 依赖(任意层级)
|
|
17
|
+
- `.git/` — Git 版本历史
|
|
18
|
+
- `dist/` — 前端构建产物
|
|
19
|
+
- `.claude/` / `.serena/` / `.ghostcode/` / `openspec/` — AI 工具状态文件
|
|
20
|
+
|
|
21
|
+
2. **始终使用精确文件路径**读取代码,不要扫描整个目录树
|
|
22
|
+
3. **搜索代码时**优先使用 grep/ripgrep 并排除上述目录,而非 glob 全量匹配
|
|
23
|
+
4. 如需了解项目结构,仅对 `src/` 和 `crates/` 目录使用 ls(深度 1 层)
|
|
24
|
+
|
|
25
|
+
违反以上规则将导致进程因内存溢出而崩溃,审查任务将失败。
|
|
26
|
+
|
|
27
|
+
## 审查维度
|
|
28
|
+
|
|
29
|
+
审查时必须覆盖以下维度:
|
|
30
|
+
|
|
31
|
+
### 1. 可维护性和可读性
|
|
32
|
+
- 函数/组件过长(超过 80 行应考虑拆分)
|
|
33
|
+
- 魔法数字和魔法字符串(应提取为具名常量)
|
|
34
|
+
- 深层嵌套逻辑(超过 3 层应重构)
|
|
35
|
+
- 不清晰的变量命名(含义模糊或误导性)
|
|
36
|
+
|
|
37
|
+
### 2. React 最佳实践
|
|
38
|
+
- Hooks 规则违反(条件调用、循环调用)
|
|
39
|
+
- useEffect 依赖数组不完整(缺少依赖或过度声明)
|
|
40
|
+
- 直接修改状态(应使用 setState 或 Immer)
|
|
41
|
+
- key prop 使用数组索引(列表重排时导致状态错乱)
|
|
42
|
+
- 不必要的重渲染(缺少 memo、useMemo、useCallback)
|
|
43
|
+
|
|
44
|
+
### 3. TypeScript 类型安全
|
|
45
|
+
- any 类型的不当使用(应替换为具体类型或泛型)
|
|
46
|
+
- 类型断言(as)绕过类型检查(应使用类型守卫)
|
|
47
|
+
- 可选链缺失导致的运行时 undefined 错误
|
|
48
|
+
- 函数返回类型未标注(特别是异步函数)
|
|
49
|
+
|
|
50
|
+
### 4. 组件复杂度(单一职责)
|
|
51
|
+
- 一个组件同时处理数据获取、业务逻辑和渲染
|
|
52
|
+
- Props drilling 超过 3 层(应使用 Context 或状态管理)
|
|
53
|
+
- 副作用和纯渲染混杂(应拆分 Container 和 Presentational 组件)
|
|
54
|
+
|
|
55
|
+
### 5. 无障碍性和用户体验
|
|
56
|
+
- 交互元素缺少 aria-label(屏幕阅读器不可用)
|
|
57
|
+
- 图片缺少 alt 属性
|
|
58
|
+
- 键盘导航支持缺失(focus 管理)
|
|
59
|
+
- 加载状态和错误状态未处理(导致空白或崩溃)
|
|
60
|
+
|
|
61
|
+
## 输出格式
|
|
62
|
+
|
|
63
|
+
输出必须是一个 JSON 数组,不包含任何额外的 Markdown 包装:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
[
|
|
67
|
+
{
|
|
68
|
+
"severity": "critical|warning|info",
|
|
69
|
+
"file": "path/to/file.tsx",
|
|
70
|
+
"line": 42,
|
|
71
|
+
"issue": "问题的具体描述,说明为什么是问题",
|
|
72
|
+
"suggestion": "修复建议,精确到代码层面"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
severity 说明:
|
|
78
|
+
- critical:会导致运行时错误、无限循环或数据错乱
|
|
79
|
+
- warning:性能问题、React 反模式或类型安全漏洞
|
|
80
|
+
- info:可维护性问题,对运行时无影响但建议修正
|
|
81
|
+
|
|
82
|
+
## 语言要求
|
|
83
|
+
|
|
84
|
+
issue 和 suggestion 字段使用中文。file 和技术术语保留英文。
|
|
85
|
+
|
|
86
|
+
## 禁止事项
|
|
87
|
+
|
|
88
|
+
- 禁止报告纯粹的代码风格偏好(如分号、引号风格)
|
|
89
|
+
- 禁止捏造不存在的问题
|
|
90
|
+
- 禁止输出 JSON 以外的内容(无需前言和总结)
|
|
91
|
+
- 如果没有发现问题,输出空数组 `[]`
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file scripts/hook-pre-compact.mjs
|
|
3
|
+
* @description PreCompact Hook 脚本
|
|
4
|
+
* 在 Claude Code 执行上下文压缩(compact)前触发:
|
|
5
|
+
* 1. 从 stdin 读取压缩前的上下文信息
|
|
6
|
+
* 2. 保存上下文检查点到状态文件(~/.ghostcode/state/compact-checkpoint.json)
|
|
7
|
+
* 3. 检查点内容:压缩时间戳 + 当前活跃子 Agent 数量 + 摘要信息
|
|
8
|
+
*
|
|
9
|
+
* 用途:
|
|
10
|
+
* - 在上下文压缩后,可通过检查点了解压缩前的状态
|
|
11
|
+
* - 供 Skill Learning 模块分析压缩频率和原因
|
|
12
|
+
*
|
|
13
|
+
* 注意:失败时 exit 0,不阻断上下文压缩操作
|
|
14
|
+
* @author Atlas.oi
|
|
15
|
+
* @date 2026-03-05
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import { readStdin } from "./lib/stdin.mjs";
|
|
22
|
+
|
|
23
|
+
// ============================================
|
|
24
|
+
// 常量配置
|
|
25
|
+
// ============================================
|
|
26
|
+
|
|
27
|
+
// GhostCode 主目录,支持环境变量覆盖(主要用于测试隔离)
|
|
28
|
+
const GHOSTCODE_HOME = process.env.GHOSTCODE_HOME || join(homedir(), ".ghostcode");
|
|
29
|
+
|
|
30
|
+
// 压缩检查点文件路径
|
|
31
|
+
const CHECKPOINT_FILE = join(GHOSTCODE_HOME, "state", "compact-checkpoint.json");
|
|
32
|
+
|
|
33
|
+
// 子 Agent 状态文件(读取活跃 Agent 数量)
|
|
34
|
+
const SUBAGENTS_FILE = join(GHOSTCODE_HOME, "state", "subagents.json");
|
|
35
|
+
|
|
36
|
+
// ============================================
|
|
37
|
+
// 工具函数
|
|
38
|
+
// ============================================
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 获取当前活跃的子 Agent 数量
|
|
42
|
+
*
|
|
43
|
+
* @returns {number} 活跃子 Agent 数量
|
|
44
|
+
*/
|
|
45
|
+
function getActiveSubagentCount() {
|
|
46
|
+
try {
|
|
47
|
+
if (existsSync(SUBAGENTS_FILE)) {
|
|
48
|
+
const state = JSON.parse(readFileSync(SUBAGENTS_FILE, "utf-8"));
|
|
49
|
+
return Object.keys(state.agents || {}).length;
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
// 读取失败返回 0
|
|
53
|
+
}
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 写入检查点文件
|
|
59
|
+
*
|
|
60
|
+
* @param {object} checkpoint - 检查点数据对象
|
|
61
|
+
*/
|
|
62
|
+
function writeCheckpoint(checkpoint) {
|
|
63
|
+
try {
|
|
64
|
+
const stateDir = join(GHOSTCODE_HOME, "state");
|
|
65
|
+
mkdirSync(stateDir, { recursive: true });
|
|
66
|
+
writeFileSync(CHECKPOINT_FILE, JSON.stringify(checkpoint, null, 2), "utf-8");
|
|
67
|
+
} catch {
|
|
68
|
+
// 写入失败静默处理
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ============================================
|
|
73
|
+
// 主逻辑
|
|
74
|
+
// ============================================
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* PreCompact Hook 主函数
|
|
78
|
+
*
|
|
79
|
+
* 业务逻辑说明:
|
|
80
|
+
* 1. 从 stdin 读取压缩前的上下文摘要信息
|
|
81
|
+
* 2. 采集当前系统状态(活跃子 Agent 数量等)
|
|
82
|
+
* 3. 生成检查点并写入状态文件
|
|
83
|
+
*/
|
|
84
|
+
async function main() {
|
|
85
|
+
// ============================================
|
|
86
|
+
// 第一步:从 stdin 读取上下文摘要
|
|
87
|
+
// Claude Code 通过 stdin 传入 PreCompact 事件的 JSON 数据
|
|
88
|
+
// ============================================
|
|
89
|
+
const raw = await readStdin();
|
|
90
|
+
let event = {};
|
|
91
|
+
try {
|
|
92
|
+
event = JSON.parse(raw);
|
|
93
|
+
} catch {
|
|
94
|
+
// JSON 解析失败,使用空事件继续
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ============================================
|
|
98
|
+
// 第二步:提取摘要信息
|
|
99
|
+
// 兼容嵌套格式:event.event.summary 或 event.summary
|
|
100
|
+
// ============================================
|
|
101
|
+
const inner = event?.event ?? event;
|
|
102
|
+
const summary = inner?.summary || inner?.context_summary || "";
|
|
103
|
+
const triggerReason = inner?.trigger_reason || inner?.triggerReason || "unknown";
|
|
104
|
+
|
|
105
|
+
// ============================================
|
|
106
|
+
// 第三步:生成并保存检查点
|
|
107
|
+
// 记录压缩时的系统状态,供后续分析使用
|
|
108
|
+
// ============================================
|
|
109
|
+
const activeSubagents = getActiveSubagentCount();
|
|
110
|
+
const checkpoint = {
|
|
111
|
+
compactedAt: new Date().toISOString(),
|
|
112
|
+
triggerReason,
|
|
113
|
+
summary: summary.slice(0, 500), // 只保留前 500 字节,避免状态文件过大
|
|
114
|
+
activeSubagents,
|
|
115
|
+
};
|
|
116
|
+
writeCheckpoint(checkpoint);
|
|
117
|
+
|
|
118
|
+
console.log(`[GhostCode] PreCompact: 检查点已保存(活跃子 Agent: ${activeSubagents})`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ============================================
|
|
122
|
+
// 入口:执行主逻辑
|
|
123
|
+
// exit 0 策略:检查点保存失败不阻断上下文压缩
|
|
124
|
+
// ============================================
|
|
125
|
+
main().catch((err) => {
|
|
126
|
+
console.error("[GhostCode] hook-pre-compact 异常:", err);
|
|
127
|
+
process.exit(0);
|
|
128
|
+
});
|