@devflow-tools/cli 0.15.0 → 0.16.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 (95) hide show
  1. package/dist/commands/benchmark-cmd.d.ts +17 -4
  2. package/dist/commands/benchmark-cmd.d.ts.map +1 -1
  3. package/dist/commands/benchmark-cmd.js +71 -14
  4. package/dist/commands/benchmark-cmd.js.map +1 -1
  5. package/dist/commands/connect.d.ts +0 -1
  6. package/dist/commands/connect.d.ts.map +1 -1
  7. package/dist/commands/connect.js +4 -10
  8. package/dist/commands/connect.js.map +1 -1
  9. package/dist/commands/context.d.ts +2 -2
  10. package/dist/commands/context.d.ts.map +1 -1
  11. package/dist/commands/context.js +5 -3
  12. package/dist/commands/context.js.map +1 -1
  13. package/dist/commands/db.d.ts +25 -0
  14. package/dist/commands/db.d.ts.map +1 -0
  15. package/dist/commands/db.js +258 -0
  16. package/dist/commands/db.js.map +1 -0
  17. package/dist/commands/docs.d.ts +20 -0
  18. package/dist/commands/docs.d.ts.map +1 -0
  19. package/dist/commands/docs.js +37 -0
  20. package/dist/commands/docs.js.map +1 -0
  21. package/dist/commands/doctor.d.ts +59 -1
  22. package/dist/commands/doctor.d.ts.map +1 -1
  23. package/dist/commands/doctor.js +3912 -50
  24. package/dist/commands/doctor.js.map +1 -1
  25. package/dist/commands/index-cmd.d.ts +1 -0
  26. package/dist/commands/index-cmd.d.ts.map +1 -1
  27. package/dist/commands/index-cmd.js +7 -0
  28. package/dist/commands/index-cmd.js.map +1 -1
  29. package/dist/commands/init.d.ts.map +1 -1
  30. package/dist/commands/init.js +3 -6
  31. package/dist/commands/init.js.map +1 -1
  32. package/dist/commands/knowledge.d.ts +2 -1
  33. package/dist/commands/knowledge.d.ts.map +1 -1
  34. package/dist/commands/knowledge.js +11 -8
  35. package/dist/commands/knowledge.js.map +1 -1
  36. package/dist/commands/memory.d.ts +17 -1
  37. package/dist/commands/memory.d.ts.map +1 -1
  38. package/dist/commands/memory.js +22 -3
  39. package/dist/commands/memory.js.map +1 -1
  40. package/dist/commands/plugin-loader.d.ts +1 -1
  41. package/dist/commands/plugin-loader.d.ts.map +1 -1
  42. package/dist/commands/plugin-loader.js +1 -1
  43. package/dist/commands/plugin-loader.js.map +1 -1
  44. package/dist/commands/plugin-memory-hints.d.ts +23 -0
  45. package/dist/commands/plugin-memory-hints.d.ts.map +1 -0
  46. package/dist/commands/plugin-memory-hints.js +58 -0
  47. package/dist/commands/plugin-memory-hints.js.map +1 -0
  48. package/dist/commands/reset.d.ts +32 -0
  49. package/dist/commands/reset.d.ts.map +1 -0
  50. package/dist/commands/reset.js +316 -0
  51. package/dist/commands/reset.js.map +1 -0
  52. package/dist/commands/session.d.ts.map +1 -1
  53. package/dist/commands/session.js +2 -1
  54. package/dist/commands/session.js.map +1 -1
  55. package/dist/commands/status.d.ts.map +1 -1
  56. package/dist/commands/status.js +33 -6
  57. package/dist/commands/status.js.map +1 -1
  58. package/dist/index.js +225 -96
  59. package/dist/index.js.map +1 -1
  60. package/dist/lib/plugin-setup.d.ts.map +1 -1
  61. package/dist/lib/plugin-setup.js +37 -2
  62. package/dist/lib/plugin-setup.js.map +1 -1
  63. package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
  64. package/dist/plugin-files/dist/command-registry.json +34 -36
  65. package/dist/plugin-files/dist/hooks/enforcer-summary.js +6 -0
  66. package/dist/plugin-files/dist/hooks/hook-client.js +6 -0
  67. package/dist/plugin-files/dist/hooks/hook-daemon.js +14 -0
  68. package/dist/plugin-files/dist/hooks/post-tool-use-failure.js +2 -0
  69. package/dist/plugin-files/dist/hooks/post-tool-use.js +3 -0
  70. package/dist/plugin-files/dist/hooks/pre-compact.js +3 -0
  71. package/dist/plugin-files/dist/hooks/pre-tool-use.js +2 -0
  72. package/dist/plugin-files/dist/hooks/server-bootstrap.js +109 -0
  73. package/dist/plugin-files/dist/hooks/session-end.js +2 -0
  74. package/dist/plugin-files/dist/hooks/stop.js +2 -0
  75. package/dist/plugin-files/dist/hooks/user-prompt-submit.js +2 -0
  76. package/dist/plugin-files/dist/skills/devflow:graphql/SKILL.md +2 -4
  77. package/dist/plugin-files/dist/skills/devflow:nest/SKILL.md +4 -4
  78. package/dist/plugin-files/dist/skills/devflow:nextjs/SKILL.md +4 -4
  79. package/dist/plugin-files/dist/skills/devflow:react/SKILL.md +6 -8
  80. package/dist/plugin-files/dist/skills/devflow:tailwind/SKILL.md +4 -2
  81. package/dist/plugin-files/dist/skills/devflow:vue/SKILL.md +2 -4
  82. package/dist/plugin-files/hooks/post-tool-use +2 -2
  83. package/dist/plugin-files/hooks/post-tool-use-failure +2 -2
  84. package/dist/plugin-files/hooks/pre-compact +2 -2
  85. package/dist/plugin-files/hooks/pre-tool-use +4 -4
  86. package/dist/plugin-files/hooks/session-end +2 -2
  87. package/dist/plugin-files/hooks/session-start +160 -77
  88. package/dist/plugin-files/hooks/stop +2 -8
  89. package/dist/plugin-files/hooks/user-prompt-submit +2 -2
  90. package/dist/plugin-files/package.json +13 -2
  91. package/package.json +27 -27
  92. package/dist/commands/dashboard.d.ts +0 -3
  93. package/dist/commands/dashboard.d.ts.map +0 -1
  94. package/dist/commands/dashboard.js +0 -10
  95. package/dist/commands/dashboard.js.map +0 -1
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
5
+ SESSION_START_INPUT="$(cat)"
6
+
4
7
  # Try to get project summary from devflow doctor
5
8
  SUMMARY=""
6
9
  DOCTOR_OUTPUT=""
@@ -26,7 +29,6 @@ fi
26
29
 
27
30
  # Generate session token for MCP Gateway authentication
28
31
  # Clean up stale receipt from previous session
29
- PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
30
32
  RECEIPT_DIR="${TMPDIR:-/tmp}/.devflow-receipts"
31
33
  mkdir -p "$RECEIPT_DIR" 2>/dev/null || true
32
34
  SESSION_ID=$(echo -n "$PROJECT_ROOT" | shasum -a 256 2>/dev/null | cut -c1-16 || echo "default")
@@ -34,48 +36,10 @@ RECEIPT_FILE="$RECEIPT_DIR/${SESSION_ID}.json"
34
36
  OVERRIDE_FILE="$RECEIPT_DIR/${SESSION_ID}.override"
35
37
  rm -f "$RECEIPT_FILE" "$OVERRIDE_FILE" 2>/dev/null || true
36
38
 
37
- # ── Clean up stale execution from previous session (if stop hook didn't fire) ──
38
- EXEC_FILE="${HOME}/.devflow/current-execution-id"
39
- SKILL_FILE="${HOME}/.devflow/current-skill.json"
40
- if [ -f "$EXEC_FILE" ]; then
41
- EXEC_ID=$(cat "$EXEC_FILE" 2>/dev/null || echo "")
42
- if [ -n "$EXEC_ID" ]; then
43
- NOW_MS="$(date +%s)000"
44
- python3 -c "
45
- import urllib.request, json
46
- try:
47
- payload = json.dumps({
48
- 'executionId': '${EXEC_ID}',
49
- 'finishedAt': ${NOW_MS},
50
- 'status': 'completed',
51
- 'summary': {
52
- 'totalToolCalls': 0,
53
- 'mcpToolCalls': 0,
54
- 'directToolCalls': 0,
55
- 'subagentCount': 0,
56
- 'totalTokens': 0,
57
- 'totalDuration': 0,
58
- 'mcpComplianceRate': 0
59
- }
60
- }).encode()
61
- req = urllib.request.Request(
62
- 'http://127.0.0.1:13337/api/telemetry/skill-execution/complete',
63
- data=payload,
64
- headers={'Content-Type': 'application/json', 'X-API-Key': 'dev-key-000000'},
65
- method='POST'
66
- )
67
- urllib.request.urlopen(req, timeout=5)
68
- except:
69
- pass
70
- " 2>/dev/null || true
71
- fi
72
- rm -f "$EXEC_FILE" "$SKILL_FILE" 2>/dev/null || true
73
- fi
74
-
75
39
  # Determine plugin root directory (same way as superpowers)
76
40
  if [ -z "${CLAUDE_PLUGIN_ROOT:-}" ]; then
77
41
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
78
- PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
42
+ PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
79
43
  else
80
44
  PLUGIN_ROOT="$CLAUDE_PLUGIN_ROOT"
81
45
  fi
@@ -92,13 +56,32 @@ else
92
56
  GLOBAL_CONSTRAINT="DevFlow Constitution 文件未找到。使用 /devflow: 命令时请优先调用 MCP 工具。"
93
57
  fi
94
58
 
59
+ # Read the active rule/gate counts from the canonical global database.
60
+ GATE_COUNT=4
61
+ RULE_COUNT=""
62
+ ENFORCER_SUMMARY_JS="${PLUGIN_ROOT}/dist/hooks/enforcer-summary.js"
63
+ if [ -f "$ENFORCER_SUMMARY_JS" ] && command -v node >/dev/null 2>&1; then
64
+ ENFORCER_SUMMARY=$(node "$ENFORCER_SUMMARY_JS" 2>/dev/null || echo "")
65
+ if [ -n "$ENFORCER_SUMMARY" ] && command -v python3 >/dev/null 2>&1; then
66
+ PARSED_COUNTS=$(printf '%s' "$ENFORCER_SUMMARY" | python3 -c "import json,sys; d=json.load(sys.stdin); g=d.get('gateCount'); r=d.get('ruleCount'); print(f'{g}|{r}' if isinstance(g,int) and isinstance(r,int) else '')" 2>/dev/null || echo "")
67
+ if [[ "$PARSED_COUNTS" =~ ^[0-9]+\|[0-9]+$ ]]; then
68
+ GATE_COUNT="${PARSED_COUNTS%%|*}"
69
+ RULE_COUNT="${PARSED_COUNTS##*|}"
70
+ fi
71
+ fi
72
+ fi
73
+ GATE_DETAIL="启用规则数未知"
74
+ if [ -n "$RULE_COUNT" ]; then
75
+ GATE_DETAIL="启用规则: ${RULE_COUNT}"
76
+ fi
77
+
95
78
  # Append Gateway status to summary
96
79
  GATEWAY_STATUS="\n\n━━━━━━ DevFlow Gateway ━━━━━━\n"
97
80
  # Check if devflow MCP server is configured (token will be auto-generated by ensureSessionToken)
98
81
  if [ -f ~/.claude/.mcp.json ] && grep -q '"devflow"' ~/.claude/.mcp.json 2>/dev/null; then
99
- GATEWAY_STATUS="${GATEWAY_STATUS}Status: 🟢 DevFlow MCP 已配置\nGate 层数: 4 (宪法 → 派发 → 拦截 → 纠正)\n"
82
+ GATEWAY_STATUS="${GATEWAY_STATUS}Status: 🟢 DevFlow MCP 已配置\nGate 层数: ${GATE_COUNT} (${GATE_DETAIL})\n"
100
83
  elif [ -f .mcp.json ] && grep -q '"devflow"' .mcp.json 2>/dev/null; then
101
- GATEWAY_STATUS="${GATEWAY_STATUS}Status: 🟢 DevFlow MCP 已配置(项目级)\nGate 层数: 4 (宪法 → 派发 → 拦截 → 纠正)\n"
84
+ GATEWAY_STATUS="${GATEWAY_STATUS}Status: 🟢 DevFlow MCP 已配置(项目级)\nGate 层数: ${GATE_COUNT} (${GATE_DETAIL})\n"
102
85
  else
103
86
  GATEWAY_STATUS="${GATEWAY_STATUS}Status: 🔴 未配置 DevFlow MCP Server\n请将 devflow MCP 配置加入 .mcp.json\n"
104
87
  fi
@@ -112,13 +95,13 @@ MCP_PROTOCOL="
112
95
  当用户使用 /devflow: 开头的技能时(如 /devflow:react、/devflow:vue、/devflow:context 等),你必须按以下流程操作:
113
96
 
114
97
  ### Step 1: 获取上下文(必须先执行)
115
- 调用 mcp__devflow__get_project_context,参数格式:{\"query\": \"用户的问题描述\"}
98
+ 调用 mcp__devflow__get_project_context,参数格式:{\"query\": \"用户的问题描述\", \"projectRoot\": \"\${CLAUDE_PROJECT_DIR}\"}
116
99
  这个工具返回项目中的相关文件、符号、风险提示和下一步建议。
117
100
  不要跳过这一步。不要用 Explore、Agent、Grep 或 Bash 代替。
118
101
 
119
102
  ### Step 2: 按需调用领域工具
120
103
  根据技能类型调用对应的 MCP 工具:
121
- - React 性能问题 → mcp__devflow__react_audit_performance(无需参数)
104
+ - React 性能问题 → mcp__devflow__react_audit_performance(参数:{\"projectRoot\": \"\${CLAUDE_PROJECT_DIR}\"})
122
105
  - React Bug → mcp__devflow__react_diagnose_bug
123
106
  - React Hooks 审查 → mcp__devflow__react_review_hooks
124
107
  - Vue 问题 → mcp__devflow__vue_diagnose_bug
@@ -131,46 +114,146 @@ MCP_PROTOCOL="
131
114
 
132
115
  ### 铁律
133
116
  - 永远不要用 Explore、Agent、Grep 或 Glob 替代 MCP 工具的第一步上下文获取
134
- - 所有 mcp__devflow__ 工具的 projectRoot 参数都是可选的,无需传
117
+ - Every mcp__devflow__ tool MUST pass projectRoot = \${CLAUDE_PROJECT_DIR}; missing projectRoot is rejected; no cwd fallback.
135
118
  - 如果 MCP 工具返回错误,重试一次;再失败则回退到直接读文件"
136
119
 
137
- SUMMARY="${SUMMARY}${MCP_PROTOCOL}${GLOBAL_CONSTRAINT}${GATEWAY_STATUS}"
120
+ MEMORY_DISTILL="
138
121
 
139
- # Escape for JSON
140
- ESCAPED=$(echo "$SUMMARY" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")
122
+ Next session instruction: call mcp__devflow__memory_request_distill once at session start; it safely reports when no memory events are pending."
141
123
 
142
- # Output context injection in Claude Code format (always output, even without CLAUDE_PLUGIN_ROOT)
143
- printf '{\n "hookSpecificOutput": {\n "hookEventName": "SessionStart",\n "additionalContext": %s\n }\n}\n' "$ESCAPED"
124
+ DEVFLOW_DAEMON_REACHABLE=0
125
+ run_lifecycle() {
126
+ local PROJECT_HASH=""
127
+ local state_dir=""
128
+ local log_dir="${HOME}/.devflow/logs"
129
+ local fallback_dir="${TMPDIR:-/tmp}"
130
+
131
+ if command -v shasum >/dev/null 2>&1; then
132
+ PROJECT_HASH=$(printf '%s' "$PROJECT_ROOT" | shasum -a 256 2>/dev/null | cut -c1-16) || PROJECT_HASH=""
133
+ fi
134
+ [[ "$PROJECT_HASH" =~ ^[0-9a-f]{16}$ ]] || PROJECT_HASH=""
135
+
136
+ if [ -n "${DEVFLOW_STATE_DIR:-}" ]; then
137
+ state_dir="$DEVFLOW_STATE_DIR"
138
+ elif [ -n "$PROJECT_HASH" ]; then
139
+ state_dir="${HOME}/.devflow/state/${PROJECT_HASH}"
140
+ fi
141
+ if [ -n "$state_dir" ]; then
142
+ rm -f "${state_dir}/current-execution-id" "${state_dir}/current-skill.json" 2>/dev/null || true
143
+ fi
144
+
145
+ if mkdir -p "$log_dir" 2>/dev/null; then
146
+ DAEMON_LOG="${log_dir}/hook-daemon-${PROJECT_HASH:-fallback}.log"
147
+ SERVER_LOG="${HOME}/.devflow/logs/server.log"
148
+ elif [ -d "$fallback_dir" ]; then
149
+ DAEMON_LOG="${fallback_dir}/devflow-hook-daemon-${PROJECT_HASH:-fallback}.log"
150
+ SERVER_LOG="${fallback_dir}/devflow-server.log"
151
+ else
152
+ DAEMON_LOG="/dev/null"
153
+ SERVER_LOG="/dev/null"
154
+ fi
155
+
156
+ DAEMON_JS="${PLUGIN_ROOT}/dist/hooks/hook-daemon.js"
157
+ CLIENT_JS="${PLUGIN_ROOT}/dist/hooks/hook-client.js"
144
158
 
145
- # ── Start hook daemon (background, Unix socket) ──
146
- DAEMON_JS="${PLUGIN_ROOT}/dist/hooks/hook-daemon.js"
147
- if [ -f "$DAEMON_JS" ]; then
148
- # Kill any stale daemon from previous session
149
- STALE_PID=$(pgrep -f "hook-daemon.js" 2>/dev/null || true)
150
- if [ -n "$STALE_PID" ]; then
151
- kill "$STALE_PID" 2>/dev/null || true
152
- sleep 0.5
159
+ register_session() {
160
+ local suppress_fallback="${1:-1}"
161
+ [ -n "$SESSION_START_INPUT" ] || return 0
162
+ [ -f "$CLIENT_JS" ] || return 1
163
+ if DEVFLOW_HOOK_CLIENT_TIMEOUT_MS=250 \
164
+ DEVFLOW_HOOK_CLIENT_RETRY_DELAY_MS=50 \
165
+ DEVFLOW_HOOK_CLIENT_SUPPRESS_FALLBACK_LOG="$suppress_fallback" \
166
+ node "$CLIENT_JS" session-start "$SESSION_START_INPUT" >/dev/null 2>> "$DAEMON_LOG"; then
167
+ DEVFLOW_DAEMON_REACHABLE=1
168
+ return 0
169
+ fi
170
+ return 1
171
+ }
172
+
173
+ if [ -n "$SESSION_START_INPUT" ] && register_session 1; then
174
+ :
175
+ elif [ -f "$DAEMON_JS" ] && command -v nohup >/dev/null 2>&1 && command -v node >/dev/null 2>&1; then
176
+ if [ -n "$SESSION_START_INPUT" ]; then
177
+ nohup node "$DAEMON_JS" "$PROJECT_ROOT" "$SESSION_START_INPUT" </dev/null >> "$DAEMON_LOG" 2>&1 &
178
+ else
179
+ nohup node "$DAEMON_JS" "$PROJECT_ROOT" </dev/null >> "$DAEMON_LOG" 2>&1 &
180
+ fi
181
+ DAEMON_PID=$!
182
+ echo "[devflow] Hook daemon started for ${PROJECT_ROOT} (PID ${DAEMON_PID})" >&2 || true
183
+
184
+ if [ -n "$SESSION_START_INPUT" ]; then
185
+ for _ in 1 2 3 4 5 6 7 8; do
186
+ register_session 1 && break
187
+ sleep 0.05
188
+ done
189
+ fi
190
+ fi
191
+
192
+ if [ -n "$SESSION_START_INPUT" ] && [ "$DEVFLOW_DAEMON_REACHABLE" != "1" ]; then
193
+ register_session 0 || true
194
+ fi
195
+
196
+ SERVER_BOOTSTRAP_JS="${PLUGIN_ROOT}/dist/hooks/server-bootstrap.js"
197
+ if [ -f "$SERVER_BOOTSTRAP_JS" ] && command -v nohup >/dev/null 2>&1 && command -v node >/dev/null 2>&1; then
198
+ nohup node "$SERVER_BOOTSTRAP_JS" </dev/null >> "$SERVER_LOG" 2>&1 &
153
199
  fi
154
- node "$DAEMON_JS" "${CLAUDE_PROJECT_DIR:-$(pwd)}" &
155
- echo "[devflow] Hook daemon started (PID $!)" >&2
200
+ }
201
+
202
+ run_lifecycle || true
203
+
204
+ DEGRADED_CONTEXT=""
205
+ if [ "$DEVFLOW_DAEMON_REACHABLE" != "1" ]; then
206
+ DEGRADED_CONTEXT="
207
+
208
+ WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement is unavailable, memory prefetch cache is unavailable, and daemon-shared Hook state is unavailable. Run devflow doctor for details."
156
209
  fi
157
210
 
158
- # ── Trigger memory extraction for previous session events (best-effort, async) ──
159
- (python3 -c "
160
- import urllib.request, json, sys
161
- try:
162
- req = urllib.request.Request(
163
- 'http://127.0.0.1:13337/api/memory/process?rootPath=${CLAUDE_PROJECT_DIR:-$(pwd)}',
164
- data=b'{}',
165
- headers={'Content-Type': 'application/json', 'X-API-Key': 'dev-key-000000'},
166
- method='POST',
167
- )
168
- resp = urllib.request.urlopen(req, timeout=30)
169
- result = json.loads(resp.read())
170
- print('DevFlow memory: {} extracted, {} approved, {} pending'.format(
171
- result.get('extracted', 0), result.get('approved', 0), result.get('pending', 0)), file=sys.stderr)
172
- except Exception as e:
173
- print('DevFlow memory extraction skipped: {}'.format(e), file=sys.stderr)
174
- " 2>/dev/null || true) &
211
+ MEMORY_SNAPSHOT="## Project memory\n本项目暂无记忆"
212
+ CONFIG_FILE="${PROJECT_ROOT}/.devflow/config.json"
213
+ MEMORY_RESPONSE=""
214
+ if [ -f "${CLIENT_JS:-}" ] && command -v node >/dev/null 2>&1; then
215
+ MEMORY_RESPONSE=$(DEVFLOW_HOOK_CLIENT_TIMEOUT_MS=1000 node "$CLIENT_JS" memory-snapshot </dev/null 2>/dev/null || echo "")
216
+ fi
217
+ if command -v python3 >/dev/null 2>&1; then
218
+ MEMORY_SNAPSHOT=$(DEVFLOW_MEMORY_RESPONSE="$MEMORY_RESPONSE" python3 - "$CONFIG_FILE" 2>/dev/null <<'PY'
219
+ import json,os,sys
220
+ try: cfg=json.load(open(sys.argv[1])).get('sessionStart',{}).get('injectMemories',True)
221
+ except Exception: cfg=True
222
+ if cfg is False: print(''); raise SystemExit
223
+ try: response=json.loads(os.environ.get('DEVFLOW_MEMORY_RESPONSE',''))
224
+ except Exception: response={}
225
+ print(response.get('markdown') or '## Project memory\n本项目暂无记忆')
226
+ PY
227
+ ) || MEMORY_SNAPSHOT="## Project memory\n本项目暂无记忆"
228
+ fi
229
+
230
+ ONBOARDING_SNAPSHOT=""
231
+ ONBOARDING_FILE="${PROJECT_ROOT}/.devflow/onboarding-pack.json"
232
+ if [ -f "$ONBOARDING_FILE" ] && command -v python3 >/dev/null 2>&1; then
233
+ ONBOARDING_SNAPSHOT=$(python3 - "$ONBOARDING_FILE" 2>/dev/null <<'PY'
234
+ import json,sys
235
+ def clean(value): return ' '.join(str(value).split())[:120]
236
+ try: data=json.load(open(sys.argv[1]))
237
+ except Exception: raise SystemExit
238
+ modules=[clean(item.get('name','')) for item in data.get('keyModules',[])[:6] if item.get('name')]
239
+ layers=[f"{clean(item.get('name',''))} ({int(item.get('files',0))} files)" for item in data.get('architectureLayers',[])[:6] if item.get('name')]
240
+ if modules or layers:
241
+ print('## Project map (auto-injected)')
242
+ if modules: print('Key modules: ' + ', '.join(modules))
243
+ if layers: print('Architecture: ' + ', '.join(layers))
244
+ PY
245
+ ) || ONBOARDING_SNAPSHOT=""
246
+ fi
247
+
248
+ SUMMARY="${SUMMARY}${DEGRADED_CONTEXT}${MEMORY_DISTILL}\n\n${ONBOARDING_SNAPSHOT}\n\n${MEMORY_SNAPSHOT}${MCP_PROTOCOL}${GLOBAL_CONSTRAINT}${GATEWAY_STATUS}"
249
+
250
+ if command -v python3 >/dev/null 2>&1 \
251
+ && ESCAPED=$(printf '%s\n' "$SUMMARY" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))" 2>/dev/null); then
252
+ :
253
+ else
254
+ ESCAPED='"Next session instruction: call mcp__devflow__memory_request_distill once at session start; it safely reports when no memory events are pending."'
255
+ fi
256
+
257
+ printf '{\n "hookSpecificOutput": {\n "hookEventName": "SessionStart",\n "additionalContext": %s\n }\n}\n' "$ESCAPED"
175
258
 
176
259
  exit 0
@@ -11,19 +11,13 @@ if [ -f "$CLIENT_JS" ]; then
11
11
  node "$CLIENT_JS" stop </dev/null 2>/dev/null || true
12
12
  fi
13
13
 
14
- # 2. Fallback: kill any remaining daemon process
15
- DAEMON_PID=$(pgrep -f "hook-daemon.js" 2>/dev/null || true)
16
- if [ -n "$DAEMON_PID" ]; then
17
- kill "$DAEMON_PID" 2>/dev/null || true
18
- fi
19
-
20
- # 3. Run existing stop.js cleanup (session close, memory extraction)
14
+ # 2. Run existing stop.js cleanup (session close, memory extraction)
21
15
  STOP_JS="$PLUGIN_ROOT/dist/hooks/stop.js"
22
16
  if [ -f "$STOP_JS" ]; then
23
17
  node "$STOP_JS" 2>/dev/null || true
24
18
  fi
25
19
 
26
- # 4. Clean up stale receipt files for this project
20
+ # 3. Clean up stale receipt files for this project
27
21
  PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
28
22
  SESSION_ID=$(echo -n "$PROJECT_ROOT" | shasum -a 256 2>/dev/null | cut -c1-16 || echo "")
29
23
  RECEIPT_FILE="${TMPDIR:-/tmp}/.devflow-receipts/${SESSION_ID}.json"
@@ -10,10 +10,10 @@ INPUT="$(cat)"
10
10
 
11
11
  if [ -f "$CLIENT_JS" ]; then
12
12
  node "$CLIENT_JS" user-prompt-submit "$INPUT" 2>/dev/null || {
13
- echo "$INPUT" | node "$FALLBACK_JS" 2>/dev/null || true
13
+ echo "$INPUT" | DEVFLOW_HOOK_DEGRADED=1 node "$FALLBACK_JS" 2>/dev/null || true
14
14
  }
15
15
  elif [ -f "$FALLBACK_JS" ]; then
16
- echo "$INPUT" | node "$FALLBACK_JS" 2>/dev/null || true
16
+ echo "$INPUT" | DEVFLOW_HOOK_DEGRADED=1 node "$FALLBACK_JS" 2>/dev/null || true
17
17
  fi
18
18
 
19
19
  exit 0
@@ -1,14 +1,25 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "DevFlow — Developer Intelligence Platform for Claude Code",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "npx tsx scripts/inject-gates.ts",
8
8
  "deploy": "npx tsx scripts/inject-gates.ts --deploy"
9
9
  },
10
+ "dependencies": {
11
+ "@devflow-tools/database": "0.16.0",
12
+ "@devflow-tools/memory-engine": "0.16.0",
13
+ "@devflow-tools/sdk": "0.16.0",
14
+ "@devflow-tools/telemetry": "0.16.0",
15
+ "@devflow-tools/workflow-engine": "0.16.0"
16
+ },
17
+ "allowScripts": {
18
+ "better-sqlite3@12.11.1": true,
19
+ "sharp@0.32.6": true
20
+ },
10
21
  "devDependencies": {
11
- "@devflow-tools/mcp-server": "0.15.0"
22
+ "@devflow-tools/mcp-server": "0.16.0"
12
23
  },
13
24
  "keywords": [
14
25
  "pi-package",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/cli",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -12,31 +12,31 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@colbymchenry/codegraph": "^1.1.1",
15
- "@devflow-tools/adapters": "0.15.0",
16
- "@devflow-tools/benchmark": "0.15.0",
17
- "@devflow-tools/context-engine": "0.15.0",
18
- "@devflow-tools/database": "0.15.0",
19
- "@devflow-tools/knowledge-engine": "0.15.0",
20
- "@devflow-tools/mcp-server": "0.15.0",
21
- "@devflow-tools/memory-engine": "0.15.0",
22
- "@devflow-tools/plugin-animation": "0.15.0",
23
- "@devflow-tools/plugin-css": "0.15.0",
24
- "@devflow-tools/plugin-docker": "0.15.0",
25
- "@devflow-tools/plugin-electron": "0.15.0",
26
- "@devflow-tools/plugin-git": "0.15.0",
27
- "@devflow-tools/plugin-graphql": "0.15.0",
28
- "@devflow-tools/plugin-nest": "0.15.0",
29
- "@devflow-tools/plugin-nextjs": "0.15.0",
30
- "@devflow-tools/plugin-performance": "0.15.0",
31
- "@devflow-tools/plugin-react": "0.15.0",
32
- "@devflow-tools/plugin-tailwind": "0.15.0",
33
- "@devflow-tools/plugin-taro": "0.15.0",
34
- "@devflow-tools/plugin-ui-layout": "0.15.0",
35
- "@devflow-tools/plugin-vue": "0.15.0",
36
- "@devflow-tools/sdk": "0.15.0",
37
- "@devflow-tools/server": "0.15.0",
38
- "@devflow-tools/telemetry": "0.15.0",
39
- "@devflow-tools/workflow-engine": "0.15.0",
15
+ "@devflow-tools/adapters": "0.16.0",
16
+ "@devflow-tools/benchmark": "0.16.0",
17
+ "@devflow-tools/context-engine": "0.16.0",
18
+ "@devflow-tools/database": "0.16.0",
19
+ "@devflow-tools/knowledge-engine": "0.16.0",
20
+ "@devflow-tools/mcp-server": "0.16.0",
21
+ "@devflow-tools/memory-engine": "0.16.0",
22
+ "@devflow-tools/plugin-animation": "0.16.0",
23
+ "@devflow-tools/plugin-css": "0.16.0",
24
+ "@devflow-tools/plugin-docker": "0.16.0",
25
+ "@devflow-tools/plugin-electron": "0.16.0",
26
+ "@devflow-tools/plugin-git": "0.16.0",
27
+ "@devflow-tools/plugin-graphql": "0.16.0",
28
+ "@devflow-tools/plugin-nest": "0.16.0",
29
+ "@devflow-tools/plugin-nextjs": "0.16.0",
30
+ "@devflow-tools/plugin-performance": "0.16.0",
31
+ "@devflow-tools/plugin-react": "0.16.0",
32
+ "@devflow-tools/plugin-tailwind": "0.16.0",
33
+ "@devflow-tools/plugin-taro": "0.16.0",
34
+ "@devflow-tools/plugin-ui-layout": "0.16.0",
35
+ "@devflow-tools/plugin-vue": "0.16.0",
36
+ "@devflow-tools/sdk": "0.16.0",
37
+ "@devflow-tools/server": "0.16.0",
38
+ "@devflow-tools/telemetry": "0.16.0",
39
+ "@devflow-tools/workflow-engine": "0.16.0",
40
40
  "@inquirer/prompts": "^7.10.1",
41
41
  "chalk": "^5.3.0",
42
42
  "commander": "^12.0.0"
@@ -49,5 +49,5 @@
49
49
  "dist",
50
50
  "bin"
51
51
  ],
52
- "gitHead": "716b2355d8bea1138f4b7551758044c3663fad0e"
52
+ "gitHead": "2f52776bda72517354d44453756cccb9e8de9afa"
53
53
  }
@@ -1,3 +0,0 @@
1
- import { Command } from "commander";
2
- export declare const dashboardCommand: Command;
3
- //# sourceMappingURL=dashboard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,gBAAgB,SAMzB,CAAC"}
@@ -1,10 +0,0 @@
1
- import { Command } from "commander";
2
- import chalk from "chalk";
3
- export const dashboardCommand = new Command("dashboard")
4
- .description("Open DevFlow Dashboard")
5
- .action(async () => {
6
- console.log(chalk.blue("The Dashboard is served by the DevFlow server."));
7
- console.log(chalk.dim("Run: devflow start"));
8
- console.log(chalk.dim(`Then open: http://localhost:13337`));
9
- });
10
- //# sourceMappingURL=dashboard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC;KACrD,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC"}