claude-pangu 2.2.21 → 2.3.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.
Files changed (65) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +2 -0
  3. package/agents/huoshen.md +220 -424
  4. package/agents/librarian.md +113 -276
  5. package/agents/lilou.md +56 -293
  6. package/agents/liubowen.md +103 -324
  7. package/agents/metis.md +178 -152
  8. package/agents/oracle.md +102 -260
  9. package/agents/wukong.md +101 -164
  10. package/agents/yugong.md +384 -231
  11. package/agents/zhuge.md +276 -200
  12. package/commands/handoff.md +178 -0
  13. package/commands/init-deep.md +160 -112
  14. package/commands/refactor.md +196 -194
  15. package/commands/start-work.md +88 -73
  16. package/commands/stop-continuation.md +57 -0
  17. package/hooks/agent-collaboration.sh +14 -1
  18. package/hooks/agent-handoff-prompt.sh +15 -4
  19. package/hooks/agent-ready-notification.sh +13 -2
  20. package/hooks/agent-usage-reminder.sh +12 -2
  21. package/hooks/anthropic-context-window-limit-recovery.sh +14 -2
  22. package/hooks/ast-grep.sh +14 -1
  23. package/hooks/atlas.sh +13 -4
  24. package/hooks/auto-update-checker.sh +20 -1
  25. package/hooks/background-compaction.sh +15 -2
  26. package/hooks/background-notification.sh +1 -1
  27. package/hooks/category-skill-reminder.sh +92 -0
  28. package/hooks/code-quality-checker.sh +14 -1
  29. package/hooks/comment-checker.sh +119 -0
  30. package/hooks/compaction-context-injector.sh +218 -0
  31. package/hooks/context-compression.sh +14 -1
  32. package/hooks/context-smart-alert.sh +15 -3
  33. package/hooks/context-window-monitor.sh +15 -3
  34. package/hooks/delegate-task-retry.sh +4 -4
  35. package/hooks/directory-agents-injector.sh +14 -1
  36. package/hooks/directory-readme-injector.sh +16 -2
  37. package/hooks/edit-error-recovery.sh +17 -3
  38. package/hooks/empty-message-sanitizer.sh +150 -0
  39. package/hooks/empty-task-response-detector.sh +14 -3
  40. package/hooks/error-friendly-display.sh +17 -7
  41. package/hooks/error-recovery.sh +14 -1
  42. package/hooks/first-use-onboarding.sh +1 -4
  43. package/hooks/hook-performance-monitor.sh +1 -1
  44. package/hooks/hooks.json +84 -1
  45. package/hooks/interactive-bash-session.sh +12 -2
  46. package/hooks/json-error-recovery.sh +176 -0
  47. package/hooks/lsp-tools.sh +14 -1
  48. package/hooks/non-interactive-env.sh +186 -0
  49. package/hooks/output-truncator.sh +14 -1
  50. package/hooks/preemptive-compaction.sh +14 -1
  51. package/hooks/rules-injector.sh +14 -1
  52. package/hooks/session-notification.sh +17 -3
  53. package/hooks/session-recovery.sh +12 -2
  54. package/hooks/stop-continuation-guard.sh +37 -0
  55. package/hooks/task-checkpointing.sh +14 -1
  56. package/hooks/think-mode.sh +14 -1
  57. package/hooks/thinking-block-validator.sh +14 -3
  58. package/hooks/tmux-agent-visualizer.sh +17 -2
  59. package/hooks/todo-continuation-enforcer.sh +105 -0
  60. package/hooks/write-existing-file-guard.sh +100 -0
  61. package/package.json +1 -1
  62. package/skills/agent-browser/SKILL.md +385 -146
  63. package/skills/dev-browser/SKILL.md +136 -0
  64. package/skills/frontend-ui-ux/SKILL.md +95 -3
  65. package/skills/git-master/SKILL.md +561 -386
@@ -1,104 +1,130 @@
1
1
  ---
2
2
  name: start-work
3
3
  description: |
4
- 开始工作流命令 - 从 GitHub Issue 或任务描述开始完整工作流程。
5
- 自动分析需求、创建 TODO、执行实现、验证结果。
4
+ 开始工作流命令 - 从 Prometheus 计划或 GitHub Issue 开始完整工作流程。
5
+ 自动分析需求、加载计划、创建 TODO、执行实现、验证结果。
6
6
  别名:/work, /begin
7
7
  ---
8
8
 
9
- # 🚀 开始工作流
9
+ # 开始工作会话
10
10
 
11
- 你正在启动 **开始工作流** 模式。这是一个完整的从需求到交付的工作流程。
11
+ 你正在启动一个 Sisyphus 工作会话。
12
12
 
13
- ## 工作流程
13
+ ## 执行步骤
14
14
 
15
- ### 阶段 1: 需求分析
15
+ ### 1. 查找可用计划
16
16
 
17
- **理解任务**:
17
+ 搜索 Prometheus 生成的计划文件:
18
18
 
19
19
  ```
20
- 1. 解析用户提供的任务描述或 GitHub Issue
21
- 2. 识别:
22
- - 核心需求是什么?
23
- - 成功标准是什么?
24
- - 有什么约束条件?
25
- - 涉及哪些文件/模块?
20
+ 查找 .sisyphus/plans/ 目录
21
+ 查找 .claude/plans/ 目录
22
+ 查找任何 *-plan.md 文件
26
23
  ```
27
24
 
28
- **如果是 GitHub Issue**:
25
+ ### 2. 检查活跃状态
29
26
 
30
- ```bash
31
- # 获取 Issue 详情
32
- gh issue view <issue_number>
27
+ 读取 `.sisyphus/boulder.json`(如果存在)。
33
28
 
34
- # 获取相关讨论
35
- gh issue view <issue_number> --comments
36
- ```
29
+ ### 3. 决策逻辑
37
30
 
38
- ### 阶段 2: 探索现有代码
31
+ - 如果 `boulder.json` 存在且计划未完成(有未勾选项):
32
+ - 继续现有计划的工作
33
+ - 如果没有活跃计划或计划已完成:
34
+ - 列出可用计划文件
35
+ - 如果只有一个计划:自动选择
36
+ - 如果有多个计划:显示列表让用户选择
37
+ - 如果没有任何计划文件:
38
+ - 解析用户提供的任务描述或 GitHub Issue
39
+ - 创建新的 TODO 列表
39
40
 
40
- **并行发起探索**:
41
+ ### 4. 创建/更新状态
41
42
 
43
+ ```json
44
+ {
45
+ "active_plan": "/absolute/path/to/plan.md",
46
+ "started_at": "ISO_TIMESTAMP",
47
+ "plan_name": "plan-name"
48
+ }
42
49
  ```
43
- # 探索相关代码
44
- background_task(agent="explore", prompt="找到与 [需求] 相关的现有代码...")
45
50
 
46
- # 探索测试模式
47
- background_task(agent="explore", prompt="找到类似功能的测试模式...")
51
+ ### 5. 读取计划并开始执行
52
+
53
+ 读取完整计划文件,按照 atlas 工作流开始执行任务。
54
+
55
+ ---
56
+
57
+ ## 输出格式
58
+
59
+ ### 列出计划时
48
60
 
49
- # 如果涉及外部库,探索文档
50
- background_task(agent="librarian", prompt="获取 [库名] 的最佳实践...")
51
61
  ```
62
+ 可用工作计划
52
63
 
53
- ### 阶段 3: 创建工作计划
64
+ 当前时间: {ISO timestamp}
54
65
 
55
- **使用 TodoWrite 创建详细计划**:
66
+ 1. [plan-name-1.md] - 修改: {date} - 进度: 3/10 任务
67
+ 2. [plan-name-2.md] - 修改: {date} - 进度: 0/5 任务
56
68
 
69
+ 选择要执行的计划?(输入编号或计划名)
57
70
  ```
58
- TodoWrite([
59
- { id: "1", content: "分析需求和现有代码", status: "pending", priority: "high" },
60
- { id: "2", content: "设计实现方案", status: "pending", priority: "high" },
61
- { id: "3", content: "实现核心功能", status: "pending", priority: "high" },
62
- { id: "4", content: "添加测试", status: "pending", priority: "medium" },
63
- { id: "5", content: "验证和文档", status: "pending", priority: "medium" }
64
- ])
71
+
72
+ ### 恢复现有工作时
73
+
65
74
  ```
75
+ 恢复工作会话
66
76
 
67
- ### 阶段 4: 执行实现
77
+ 活跃计划: {plan-name}
78
+ 进度: {completed}/{total} 任务
68
79
 
69
- **根据任务类型分派**:
80
+ 读取计划并从上次未完成的任务继续...
81
+ ```
70
82
 
71
- | 任务类型 | 分派给 | 行动 |
72
- |----------|--------|------|
73
- | 架构设计 | 诸葛 (oracle) | 设计方案评审 |
74
- | 代码实现 | 鲁班 (general) | 核心实现 |
75
- | UI/UX | 顾恺之 (frontend) | 界面设计实现 |
76
- | 测试 | 包拯 (test-engineer) | 测试编写 |
77
- | 文档 | 司马迁 (document-writer) | 文档更新 |
83
+ ### 自动选择单一计划时
78
84
 
79
- ### 阶段 5: 验证
85
+ ```
86
+ 启动工作会话
80
87
 
81
- **验证清单**:
88
+ 计划: {plan-name}
89
+ 开始时间: {timestamp}
82
90
 
91
+ 读取计划并开始执行...
83
92
  ```
84
- □ 代码编译/构建通过
85
- □ lsp_diagnostics 无错误
86
- □ 测试通过(如有)
87
- 满足成功标准
88
- □ 无回归问题
93
+
94
+ ---
95
+
96
+ ## 如果是 GitHub Issue
97
+
98
+ ```bash
99
+ # 获取 Issue 详情
100
+ gh issue view <issue_number>
101
+
102
+ # 获取相关讨论
103
+ gh issue view <issue_number> --comments
89
104
  ```
90
105
 
91
- ### 阶段 6: 交付
106
+ ---
92
107
 
93
- **根据需求交付**:
108
+ ## 任务分派参考
94
109
 
95
- - 如果需要 PR 创建 PR
96
- - 如果是本地任务 → 报告完成
97
- - 如果涉及 Issue 引用 Issue 编号
110
+ | 任务类型 | 分派建议 | 说明 |
111
+ |----------|----------|------|
112
+ | 架构设计 | oracle | 只读咨询,设计方案评审 |
113
+ | 前端实现 | visual-engineering | 带 frontend-ui-ux 技能 |
114
+ | 后端实现 | deep/unspecified-high | 带相关技能 |
115
+ | 测试编写 | unspecified-high | 带 tdd-workflow 技能 |
116
+ | 文档更新 | writing | 带相关技能 |
117
+ | 简单修改 | quick | 快速任务 |
98
118
 
99
- ## 输入格式
119
+ ---
120
+
121
+ ## 关键规则
122
+
123
+ - 读取完整计划文件后再委派任何任务
124
+ - 始终在开始工作前更新状态文件
125
+ - 遵循 Category+Skills 委派协议
100
126
 
101
- 支持多种输入格式:
127
+ ## 输入格式
102
128
 
103
129
  ```bash
104
130
  # GitHub Issue
@@ -110,8 +136,8 @@ TodoWrite([
110
136
  # 任务描述
111
137
  /start-work 实现用户登录功能
112
138
 
113
- # 详细需求
114
- /start-work 添加一个 REST API 端点 /api/users,支持 CRUD 操作
139
+ # 无参数(查找现有计划)
140
+ /start-work
115
141
  ```
116
142
 
117
143
  ## 用户的任务
@@ -120,15 +146,4 @@ $ARGUMENTS
120
146
 
121
147
  ---
122
148
 
123
- ## 开始执行
124
-
125
- 现在我将:
126
-
127
- 1. **分析需求** - 理解你想要什么
128
- 2. **探索代码** - 了解现有实现
129
- 3. **创建计划** - 使用 TodoWrite 分解任务
130
- 4. **执行实现** - 逐步完成子任务
131
- 5. **验证结果** - 确保质量和正确性
132
- 6. **交付成果** - 完成 PR 或报告
133
-
134
149
  **工作流启动...**
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: stop-continuation
3
+ description: |
4
+ 停止所有续航机制 - 停止 todo-continuation、Ralph Loop 和循环状态。
5
+ 使用此命令暂停自动续航,切换为手动控制。
6
+ 别名:/stop-loop, /cancel-continuation
7
+ ---
8
+
9
+ # 停止续航机制
10
+
11
+ 停止当前会话的所有续航机制。
12
+
13
+ 此命令将:
14
+ 1. 停止 todo-continuation-enforcer 的自动任务续航
15
+ 2. 取消任何活跃的 Ralph Loop
16
+ 3. 清除当前项目的循环状态
17
+
18
+ 执行后:
19
+ - 会话空闲时不会自动继续
20
+ - 你可以在准备好时手动继续工作
21
+ - 停止状态为每会话级别,会话结束时自动清除
22
+
23
+ **当你需要暂停自动续航并切换为手动控制时使用此命令。**
24
+
25
+ ---
26
+
27
+ ## 执行步骤
28
+
29
+ **立即执行以下操作:**
30
+
31
+ ```bash
32
+ # 1. 创建停止标记文件
33
+ mkdir -p "$HOME/.oh-my-claude/state"
34
+ echo "stopped" > "$HOME/.oh-my-claude/state/continuation-stopped"
35
+
36
+ # 2. 清除 Ralph Loop 状态(如果存在)
37
+ rm -f .claude/ralph-loop.local.md
38
+
39
+ # 3. 清除愚公移山循环状态(如果存在)
40
+ rm -f .claude/yishan-loop.local.md
41
+ ```
42
+
43
+ 完成后确认:
44
+
45
+ ```
46
+ ✅ 续航机制已停止
47
+
48
+ 已执行:
49
+ - [x] 创建停止标记
50
+ - [x] 清除 Ralph Loop 状态
51
+ - [x] 清除愚公移山循环状态
52
+
53
+ 当前会话不会再自动继续未完成的任务。
54
+ 如需恢复自动续航,开始新会话或手动删除标记文件。
55
+ ```
56
+
57
+ $ARGUMENTS
@@ -161,5 +161,18 @@ main() {
161
161
  fi
162
162
  }
163
163
 
164
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
165
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
166
+ if [ -z "$_STDIN_INPUT" ]; then
167
+ exit 0
168
+ fi
169
+
170
+ # 解析 stdin JSON 的 prompt 字段
171
+ if command -v jq > /dev/null 2>&1; then
172
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | jq -r '.prompt // empty' 2>/dev/null) || _STDIN_PROMPT=""
173
+ else
174
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || _STDIN_PROMPT=""
175
+ fi
176
+
164
177
  # 执行主函数
165
- main "$@"
178
+ main "$_STDIN_PROMPT"
@@ -10,10 +10,21 @@
10
10
  # 错误捕获:任何错误都静默退出,不影响用户体验
11
11
  trap 'exit 0' ERR EXIT
12
12
 
13
- # 获取工具输出(带默认值保护)
14
- TOOL_OUTPUT="${CLAUDE_TOOL_OUTPUT:-}"
15
- TOOL_NAME="${CLAUDE_TOOL_NAME:-}"
16
- LAST_AGENT="${CLAUDE_LAST_AGENT:-}"
13
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
14
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
15
+ if [ -z "$_STDIN_INPUT" ]; then
16
+ exit 0
17
+ fi
18
+
19
+ # 解析 stdin JSON 字段
20
+ if command -v jq > /dev/null 2>&1; then
21
+ TOOL_NAME=$(echo "$_STDIN_INPUT" | jq -r '.tool_name // empty' 2>/dev/null) || TOOL_NAME=""
22
+ TOOL_OUTPUT=$(echo "$_STDIN_INPUT" | jq -r '(.tool_output // empty) | if type == "object" then tostring else . end' 2>/dev/null) || TOOL_OUTPUT=""
23
+ else
24
+ TOOL_NAME=$(echo "$_STDIN_INPUT" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_name"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || TOOL_NAME=""
25
+ TOOL_OUTPUT=$(echo "$_STDIN_INPUT" | grep -o '"tool_output"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_output"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || TOOL_OUTPUT=""
26
+ fi
27
+ LAST_AGENT=""
17
28
 
18
29
  # 安全检查:如果没有工具输出,静默退出
19
30
  if [ -z "$TOOL_OUTPUT" ]; then
@@ -6,8 +6,19 @@
6
6
 
7
7
  # 环境变量
8
8
  HOOK_NAME="agent-ready-notification"
9
- STOP_REASON="${CLAUDE_STOP_REASON:-}"
10
- SESSION_ID="${CLAUDE_SESSION_ID:-}"
9
+
10
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
11
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
12
+
13
+ # 解析 stdin JSON 字段(Stop 事件提供 session_id, transcript_path, cwd)
14
+ if command -v jq > /dev/null 2>&1; then
15
+ SESSION_ID=$(echo "$_STDIN_INPUT" | jq -r '.session_id // empty' 2>/dev/null) || SESSION_ID=""
16
+ else
17
+ SESSION_ID=$(echo "$_STDIN_INPUT" | grep -o '"session_id"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"session_id"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || SESSION_ID=""
18
+ fi
19
+
20
+ # Stop 事件没有 stop_reason 字段
21
+ STOP_REASON=""
11
22
 
12
23
  # 配置 - 可通过环境变量自定义
13
24
  NOTIFICATION_ENABLED="${OH_MY_CLAUDE_NOTIFICATIONS:-true}"
@@ -20,8 +20,18 @@ STATE_DIR=".claude"
20
20
  REMINDER_STATE_FILE="$STATE_DIR/agent-reminder-state.json"
21
21
  COOLDOWN_SECONDS=600 # 10 分钟冷却期(增加,避免打扰)
22
22
 
23
- # 获取用户输入
24
- user_input="${CLAUDE_USER_PROMPT:-}"
23
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
24
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
25
+ if [ -z "$_STDIN_INPUT" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ # 解析 stdin JSON 字段
30
+ if command -v jq > /dev/null 2>&1; then
31
+ user_input=$(echo "$_STDIN_INPUT" | jq -r '.prompt // empty' 2>/dev/null) || user_input=""
32
+ else
33
+ user_input=$(echo "$_STDIN_INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || user_input=""
34
+ fi
25
35
 
26
36
  # 如果输入为空,直接退出
27
37
  if [ -z "$user_input" ]; then
@@ -5,8 +5,20 @@
5
5
 
6
6
  # 环境变量
7
7
  HOOK_NAME="anthropic-context-window-limit-recovery"
8
- TOOL_OUTPUT="${CLAUDE_TOOL_OUTPUT:-}"
9
- ERROR_MESSAGE="${CLAUDE_ERROR:-}"
8
+
9
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
10
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
11
+ if [ -z "$_STDIN_INPUT" ]; then
12
+ exit 0
13
+ fi
14
+
15
+ # 解析 stdin JSON 字段
16
+ if command -v jq > /dev/null 2>&1; then
17
+ TOOL_OUTPUT=$(echo "$_STDIN_INPUT" | jq -r '(.tool_output // empty) | if type == "object" then tostring else . end' 2>/dev/null) || TOOL_OUTPUT=""
18
+ else
19
+ TOOL_OUTPUT=$(echo "$_STDIN_INPUT" | grep -o '"tool_output"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_output"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || TOOL_OUTPUT=""
20
+ fi
21
+ ERROR_MESSAGE=""
10
22
 
11
23
  # 配置
12
24
  RECOVERY_STATE_FILE="${HOME}/.oh-my-claude/context-recovery.state"
package/hooks/ast-grep.sh CHANGED
@@ -516,5 +516,18 @@ main() {
516
516
  exit 0
517
517
  }
518
518
 
519
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
520
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
521
+ if [ -z "$_STDIN_INPUT" ]; then
522
+ exit 0
523
+ fi
524
+
525
+ # 解析 stdin JSON 的 prompt 字段
526
+ if command -v jq > /dev/null 2>&1; then
527
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | jq -r '.prompt // empty' 2>/dev/null) || _STDIN_PROMPT=""
528
+ else
529
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || _STDIN_PROMPT=""
530
+ fi
531
+
519
532
  # 执行主函数
520
- main "$@"
533
+ main "$_STDIN_PROMPT"
package/hooks/atlas.sh CHANGED
@@ -5,10 +5,19 @@
5
5
 
6
6
  # 环境变量
7
7
  HOOK_NAME="atlas"
8
- PROMPT="${CLAUDE_PROMPT:-}"
9
- TOOL_NAME="${CLAUDE_TOOL_NAME:-}"
10
- TOOL_INPUT="${CLAUDE_TOOL_INPUT:-}"
11
- TOOL_OUTPUT="${CLAUDE_TOOL_OUTPUT:-}"
8
+
9
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
10
+ INPUT=$(cat 2>/dev/null) || INPUT=""
11
+ if [ -z "$INPUT" ]; then
12
+ exit 0
13
+ fi
14
+
15
+ # 解析 stdin JSON 字段
16
+ if command -v jq > /dev/null 2>&1; then
17
+ PROMPT=$(echo "$INPUT" | jq -r '.prompt // empty' 2>/dev/null) || PROMPT=""
18
+ else
19
+ PROMPT=$(echo "$INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || PROMPT=""
20
+ fi
12
21
 
13
22
  # 配置
14
23
  CONFIG_DIR="${HOME}/.oh-my-claude"
@@ -664,5 +664,24 @@ main() {
664
664
  exit 0
665
665
  }
666
666
 
667
+ # 检查是否通过命令行参数调用(如 SessionStart 的 --session-start)
668
+ if [ $# -gt 0 ]; then
669
+ main "$@"
670
+ exit $?
671
+ fi
672
+
673
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
674
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
675
+ if [ -z "$_STDIN_INPUT" ]; then
676
+ exit 0
677
+ fi
678
+
679
+ # 解析 stdin JSON 的 prompt 字段(UserPromptSubmit 事件)
680
+ if command -v jq > /dev/null 2>&1; then
681
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | jq -r '.prompt // empty' 2>/dev/null) || _STDIN_PROMPT=""
682
+ else
683
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || _STDIN_PROMPT=""
684
+ fi
685
+
667
686
  # 执行主函数
668
- main "$@"
687
+ main "$_STDIN_PROMPT"
@@ -5,8 +5,21 @@
5
5
 
6
6
  # 环境变量
7
7
  HOOK_NAME="background-compaction"
8
- TOOL_NAME="${CLAUDE_TOOL_NAME:-}"
9
- TOOL_OUTPUT="${CLAUDE_TOOL_OUTPUT:-}"
8
+
9
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
10
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
11
+ if [ -z "$_STDIN_INPUT" ]; then
12
+ exit 0
13
+ fi
14
+
15
+ # 解析 stdin JSON 字段
16
+ if command -v jq > /dev/null 2>&1; then
17
+ TOOL_NAME=$(echo "$_STDIN_INPUT" | jq -r '.tool_name // empty' 2>/dev/null) || TOOL_NAME=""
18
+ TOOL_OUTPUT=$(echo "$_STDIN_INPUT" | jq -r '(.tool_output // empty) | if type == "object" then tostring else . end' 2>/dev/null) || TOOL_OUTPUT=""
19
+ else
20
+ TOOL_NAME=$(echo "$_STDIN_INPUT" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_name"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || TOOL_NAME=""
21
+ TOOL_OUTPUT=$(echo "$_STDIN_INPUT" | grep -o '"tool_output"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_output"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || TOOL_OUTPUT=""
22
+ fi
10
23
 
11
24
  # 配置
12
25
  COMPACTION_THRESHOLD=5 # 触发压缩建议的后台任务数量阈值
@@ -25,7 +25,7 @@ failed_count=0
25
25
  completed_tasks=""
26
26
 
27
27
  # 遍历状态文件
28
- for state_file in "$BACKGROUND_STATE_DIR"/*.state 2>/dev/null; do
28
+ for state_file in "$BACKGROUND_STATE_DIR"/*.state; do
29
29
  [ -f "$state_file" ] || continue
30
30
 
31
31
  task_id=$(basename "$state_file" .state)
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================================
3
+ # Category+Skill Reminder Hook
4
+ # ============================================================================
5
+ # 对标 oh-my-opencode 的 category-skill-reminder hook
6
+ # 当编排 Agent 直接执行工作(而非委派)时,提醒使用 Category+Skills 系统
7
+ #
8
+ # Hook 类型: PostToolUse
9
+ # 触发条件: 工具调用为 Write/Edit/Bash 时(表示直接实现而非委派)
10
+ # 行为:
11
+ # 1. 跟踪每个会话中直接实现的工具调用次数
12
+ # 2. 累计超过 3 次后,注入 Category+Skills 提醒
13
+ # 3. 使用 $HOME/.oh-my-claude/state/ 下的文件跟踪会话计数
14
+ # ============================================================================
15
+
16
+ HOOK_NAME="category-skill-reminder"
17
+ STATE_DIR="$HOME/.oh-my-claude/state"
18
+ COUNTER_FILE="$STATE_DIR/skill-reminder-counter"
19
+
20
+ # 确保状态目录存在
21
+ mkdir -p "$STATE_DIR" 2>/dev/null
22
+
23
+ # 从 stdin 读取 JSON 数据
24
+ INPUT=$(cat 2>/dev/null) || INPUT=""
25
+ if [ -z "$INPUT" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ # 解析 stdin JSON 字段
30
+ if command -v jq > /dev/null 2>&1; then
31
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null) || TOOL_NAME=""
32
+ TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // empty' 2>/dev/null) || TOOL_INPUT=""
33
+ else
34
+ TOOL_NAME=$(echo "$INPUT" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_name"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || TOOL_NAME=""
35
+ TOOL_INPUT=""
36
+ fi
37
+
38
+ # 只关注直接实现类工具(非探索/读取类)
39
+ case "$TOOL_NAME" in
40
+ Write|write|Edit|edit|Bash|bash)
41
+ # 这些是"动手做"类工具,编排者应该委派
42
+ ;;
43
+ *)
44
+ # Read/Grep/Glob/Task/TodoWrite 等不算直接实现
45
+ exit 0
46
+ ;;
47
+ esac
48
+
49
+ # 排除: 如果是对 hooks/ 或 .claude/ 内部文件的操作,不算
50
+ if [ -n "$TOOL_INPUT" ]; then
51
+ if echo "$TOOL_INPUT" | grep -qE '(hooks/|\.claude/|oh-my-claude/)'; then
52
+ exit 0
53
+ fi
54
+ fi
55
+
56
+ # 递增计数器
57
+ CURRENT=0
58
+ if [ -f "$COUNTER_FILE" ]; then
59
+ CURRENT=$(cat "$COUNTER_FILE" 2>/dev/null | tr -d '[:space:]')
60
+ # 验证是数字
61
+ case "$CURRENT" in
62
+ ''|*[!0-9]*) CURRENT=0 ;;
63
+ esac
64
+ fi
65
+
66
+ CURRENT=$((CURRENT + 1))
67
+ echo "$CURRENT" > "$COUNTER_FILE"
68
+
69
+ # 阈值: 累计 3 次直接实现后提醒
70
+ if [ "$CURRENT" -lt 3 ]; then
71
+ exit 0
72
+ fi
73
+
74
+ # 重置计数器(提醒后重新开始计数)
75
+ echo "0" > "$COUNTER_FILE"
76
+
77
+ # 输出提醒
78
+ cat << 'EOF'
79
+
80
+ [Category+Skill Reminder]
81
+
82
+ **Built-in**: dev-browser
83
+ **⚡ YOUR SKILLS (PRIORITY)**: playwright, frontend-ui-ux, git-master, agent-browser, agent-handoff, agent-wizard, autopilot, bilingual (+60 more)
84
+
85
+ > User-installed skills OVERRIDE built-in defaults. ALWAYS prefer YOUR SKILLS when domain matches.
86
+
87
+ ```typescript
88
+ task(category="visual-engineering", load_skills=["playwright"], run_in_background=true)
89
+ ```
90
+ EOF
91
+
92
+ exit 0
@@ -424,5 +424,18 @@ main() {
424
424
  exit 0
425
425
  }
426
426
 
427
+ # 从 stdin 读取 JSON 数据(Claude Code Hook API 通过 stdin 传递事件数据)
428
+ _STDIN_INPUT=$(cat 2>/dev/null) || _STDIN_INPUT=""
429
+ if [ -z "$_STDIN_INPUT" ]; then
430
+ exit 0
431
+ fi
432
+
433
+ # 解析 stdin JSON 的 prompt 字段
434
+ if command -v jq > /dev/null 2>&1; then
435
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | jq -r '.prompt // empty' 2>/dev/null) || _STDIN_PROMPT=""
436
+ else
437
+ _STDIN_PROMPT=$(echo "$_STDIN_INPUT" | grep -o '"prompt"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)"/\1/' 2>/dev/null) || _STDIN_PROMPT=""
438
+ fi
439
+
427
440
  # 执行主函数
428
- main "$@"
441
+ main "$_STDIN_PROMPT"