autoworkflow 3.9.0 → 3.10.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/.claude/.autoworkflow/memories/blockers.md +5 -13
- package/.claude/.autoworkflow/memories/decisions.md +5 -13
- package/.claude/.autoworkflow/memories/patterns.md +7 -16
- package/.claude/hooks/logger.sh +318 -0
- package/.claude/hooks/phase-transition.sh +117 -112
- package/.claude/hooks/post-edit.sh +12 -0
- package/.claude/hooks/pre-commit-check.sh +10 -0
- package/.claude/hooks/session-check.sh +57 -1
- package/.claude/settings.json +10 -1
- package/CLAUDE.md +62 -19
- package/bin/cli.js +67 -1
- package/package.json +1 -1
|
@@ -1,23 +1,15 @@
|
|
|
1
|
-
# Blockers
|
|
1
|
+
# Blockers
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
> Saves time by not rediscovering the same problems.
|
|
3
|
+
> Known issues and workarounds. Claude edits directly.
|
|
5
4
|
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
## Template
|
|
9
|
-
|
|
10
|
-
*Recorded: YYYY-MM-DD HH:MM:SS*
|
|
7
|
+
## Template
|
|
8
|
+
*YYYY-MM-DD*
|
|
11
9
|
|
|
12
10
|
**Issue:** What is the problem?
|
|
13
|
-
|
|
14
|
-
**Symptoms:** How does it manifest?
|
|
15
|
-
|
|
16
|
-
**Root Cause:** Why does this happen? (if known)
|
|
17
|
-
|
|
18
11
|
**Workaround:** How to work around it?
|
|
19
|
-
|
|
20
|
-
**Status:** Open / Resolved / Won't Fix
|
|
12
|
+
**Status:** Open / Resolved
|
|
21
13
|
|
|
22
14
|
---
|
|
23
15
|
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
# Decisions
|
|
1
|
+
# Decisions
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
> This helps maintain context across sessions and explains "why" for future reference.
|
|
3
|
+
> Architectural and implementation choices. Claude edits directly.
|
|
5
4
|
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
## Template
|
|
9
|
-
|
|
10
|
-
*Recorded: YYYY-MM-DD HH:MM:SS*
|
|
11
|
-
|
|
12
|
-
**Context:** What was the situation or requirement?
|
|
13
|
-
|
|
14
|
-
**Options Considered:**
|
|
15
|
-
1. Option A - pros/cons
|
|
16
|
-
2. Option B - pros/cons
|
|
7
|
+
## Template
|
|
8
|
+
*YYYY-MM-DD*
|
|
17
9
|
|
|
10
|
+
**Context:** What was the situation?
|
|
18
11
|
**Decision:** What was chosen and why?
|
|
19
|
-
|
|
20
12
|
**Implications:** What does this mean going forward?
|
|
21
13
|
|
|
22
14
|
---
|
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
# Patterns
|
|
1
|
+
# Patterns
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
> Helps maintain consistency and avoid reinventing solutions.
|
|
3
|
+
> Discovered codebase patterns. Claude edits directly.
|
|
5
4
|
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
## Template
|
|
7
|
+
## Template
|
|
8
|
+
*YYYY-MM-DD*
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
**
|
|
13
|
-
|
|
14
|
-
**Where Used:** Which files/components use this?
|
|
15
|
-
|
|
16
|
-
**How It Works:**
|
|
17
|
-
```
|
|
18
|
-
// Code example or description
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**When to Use:** What situations call for this pattern?
|
|
10
|
+
**Pattern:** What is this pattern?
|
|
11
|
+
**Where:** Which files/components use it?
|
|
12
|
+
**Usage:** When and how to use it?
|
|
22
13
|
|
|
23
14
|
---
|
|
24
15
|
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# AutoWorkflow Logger
|
|
3
|
+
# Centralized logging for all hooks, gates, and workflow events
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# source logger.sh
|
|
7
|
+
# aw_log "HOOK" "session-check.sh" "START"
|
|
8
|
+
# aw_log "GATE" "plan_approval" "PASSED"
|
|
9
|
+
# aw_log "PHASE" "PLAN" "IMPLEMENT"
|
|
10
|
+
# aw_log "VERIFY" "1/10" "checking..."
|
|
11
|
+
# aw_log "ERROR" "pre-commit" "TypeScript errors found"
|
|
12
|
+
|
|
13
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
14
|
+
# CONFIGURATION
|
|
15
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
|
|
17
|
+
# Project directory
|
|
18
|
+
LOGGER_PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
19
|
+
|
|
20
|
+
# Log directory and file
|
|
21
|
+
LOG_DIR="$LOGGER_PROJECT_DIR/.claude/.autoworkflow/logs"
|
|
22
|
+
LOG_FILE="$LOG_DIR/aw.log"
|
|
23
|
+
MAX_LOG_SIZE=1048576 # 1MB
|
|
24
|
+
MAX_LOG_FILES=5
|
|
25
|
+
|
|
26
|
+
# Debug mode (set AUTOWORKFLOW_DEBUG=1 to enable verbose output)
|
|
27
|
+
DEBUG_MODE="${AUTOWORKFLOW_DEBUG:-0}"
|
|
28
|
+
|
|
29
|
+
# Colors for terminal output (when viewing with tail -f)
|
|
30
|
+
LOG_RED='\033[0;31m'
|
|
31
|
+
LOG_GREEN='\033[0;32m'
|
|
32
|
+
LOG_YELLOW='\033[1;33m'
|
|
33
|
+
LOG_CYAN='\033[0;36m'
|
|
34
|
+
LOG_BLUE='\033[0;34m'
|
|
35
|
+
LOG_MAGENTA='\033[0;35m'
|
|
36
|
+
LOG_BOLD='\033[1m'
|
|
37
|
+
LOG_DIM='\033[2m'
|
|
38
|
+
LOG_NC='\033[0m'
|
|
39
|
+
|
|
40
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
41
|
+
# INITIALIZATION
|
|
42
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
43
|
+
|
|
44
|
+
# Ensure log directory exists
|
|
45
|
+
mkdir -p "$LOG_DIR"
|
|
46
|
+
|
|
47
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
48
|
+
# LOG ROTATION
|
|
49
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
50
|
+
|
|
51
|
+
rotate_logs() {
|
|
52
|
+
if [ -f "$LOG_FILE" ]; then
|
|
53
|
+
local size=$(stat -f%z "$LOG_FILE" 2>/dev/null || stat -c%s "$LOG_FILE" 2>/dev/null || echo "0")
|
|
54
|
+
|
|
55
|
+
if [ "$size" -gt "$MAX_LOG_SIZE" ]; then
|
|
56
|
+
# Rotate existing logs
|
|
57
|
+
for i in $(seq $((MAX_LOG_FILES - 1)) -1 1); do
|
|
58
|
+
if [ -f "$LOG_FILE.$i" ]; then
|
|
59
|
+
mv "$LOG_FILE.$i" "$LOG_FILE.$((i + 1))"
|
|
60
|
+
fi
|
|
61
|
+
done
|
|
62
|
+
|
|
63
|
+
# Move current log to .1
|
|
64
|
+
mv "$LOG_FILE" "$LOG_FILE.1"
|
|
65
|
+
|
|
66
|
+
# Create new log file with header
|
|
67
|
+
echo "# AutoWorkflow Log - Rotated $(date '+%Y-%m-%d %H:%M:%S')" > "$LOG_FILE"
|
|
68
|
+
echo "# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >> "$LOG_FILE"
|
|
69
|
+
echo "" >> "$LOG_FILE"
|
|
70
|
+
|
|
71
|
+
# Remove oldest if exceeds max
|
|
72
|
+
if [ -f "$LOG_FILE.$MAX_LOG_FILES" ]; then
|
|
73
|
+
rm -f "$LOG_FILE.$MAX_LOG_FILES"
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
80
|
+
# LOGGING FUNCTIONS
|
|
81
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
82
|
+
|
|
83
|
+
# Get color for category
|
|
84
|
+
get_category_color() {
|
|
85
|
+
local category="$1"
|
|
86
|
+
case "$category" in
|
|
87
|
+
HOOK) echo "$LOG_CYAN" ;;
|
|
88
|
+
PHASE) echo "$LOG_BLUE" ;;
|
|
89
|
+
GATE) echo "$LOG_MAGENTA" ;;
|
|
90
|
+
VERIFY) echo "$LOG_GREEN" ;;
|
|
91
|
+
MEMORY) echo "$LOG_CYAN" ;;
|
|
92
|
+
COMMIT) echo "$LOG_GREEN" ;;
|
|
93
|
+
ERROR) echo "$LOG_RED" ;;
|
|
94
|
+
WARN) echo "$LOG_YELLOW" ;;
|
|
95
|
+
DEBUG) echo "$LOG_DIM" ;;
|
|
96
|
+
*) echo "$LOG_NC" ;;
|
|
97
|
+
esac
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Get symbol for status
|
|
101
|
+
get_status_symbol() {
|
|
102
|
+
local status="$1"
|
|
103
|
+
case "$status" in
|
|
104
|
+
START|STARTED) echo "▶" ;;
|
|
105
|
+
COMPLETE|DONE) echo "✓" ;;
|
|
106
|
+
PASSED|SUCCESS) echo "✓" ;;
|
|
107
|
+
FAILED|ERROR) echo "✗" ;;
|
|
108
|
+
BLOCKED|DENIED) echo "⛔" ;;
|
|
109
|
+
WAITING|PENDING) echo "◉" ;;
|
|
110
|
+
SKIPPED) echo "○" ;;
|
|
111
|
+
*) echo "●" ;;
|
|
112
|
+
esac
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Main logging function
|
|
116
|
+
# Usage: aw_log <CATEGORY> <SOURCE> <MESSAGE> [DETAILS]
|
|
117
|
+
aw_log() {
|
|
118
|
+
local category="${1:-INFO}"
|
|
119
|
+
local source="${2:-unknown}"
|
|
120
|
+
local message="${3:-}"
|
|
121
|
+
local details="${4:-}"
|
|
122
|
+
|
|
123
|
+
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
124
|
+
local time_only=$(date '+%H:%M:%S')
|
|
125
|
+
|
|
126
|
+
# Check for log rotation
|
|
127
|
+
rotate_logs
|
|
128
|
+
|
|
129
|
+
# Get color and symbol
|
|
130
|
+
local color=$(get_category_color "$category")
|
|
131
|
+
local symbol=$(get_status_symbol "$message")
|
|
132
|
+
|
|
133
|
+
# Format the log entry
|
|
134
|
+
local log_entry="[$time_only] [$category] $source $symbol $message"
|
|
135
|
+
[ -n "$details" ] && log_entry="$log_entry - $details"
|
|
136
|
+
|
|
137
|
+
# Write to log file (plain text, no colors)
|
|
138
|
+
echo "[$timestamp] [$category] $source $symbol $message${details:+ - $details}" >> "$LOG_FILE"
|
|
139
|
+
|
|
140
|
+
# If debug mode, also output to stderr (visible in terminal)
|
|
141
|
+
if [ "$DEBUG_MODE" = "1" ]; then
|
|
142
|
+
echo -e "${color}${log_entry}${LOG_NC}" >&2
|
|
143
|
+
fi
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# Convenience functions for common log types
|
|
147
|
+
aw_log_hook() {
|
|
148
|
+
local hook_name="$1"
|
|
149
|
+
local status="$2"
|
|
150
|
+
local details="${3:-}"
|
|
151
|
+
aw_log "HOOK" "$hook_name" "$status" "$details"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
aw_log_phase() {
|
|
155
|
+
local from="$1"
|
|
156
|
+
local to="$2"
|
|
157
|
+
aw_log "PHASE" "$from → $to" "TRANSITION"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
aw_log_gate() {
|
|
161
|
+
local gate_name="$1"
|
|
162
|
+
local status="$2"
|
|
163
|
+
local details="${3:-}"
|
|
164
|
+
aw_log "GATE" "$gate_name" "$status" "$details"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
aw_log_verify() {
|
|
168
|
+
local iteration="$1"
|
|
169
|
+
local status="$2"
|
|
170
|
+
local details="${3:-}"
|
|
171
|
+
aw_log "VERIFY" "iteration $iteration" "$status" "$details"
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
aw_log_memory() {
|
|
175
|
+
local action="$1"
|
|
176
|
+
local file="$2"
|
|
177
|
+
aw_log "MEMORY" "$action" "$file"
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
aw_log_commit() {
|
|
181
|
+
local status="$1"
|
|
182
|
+
local message="${2:-}"
|
|
183
|
+
aw_log "COMMIT" "$status" "$message"
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
aw_log_error() {
|
|
187
|
+
local source="$1"
|
|
188
|
+
local message="$2"
|
|
189
|
+
aw_log "ERROR" "$source" "FAILED" "$message"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
aw_log_warn() {
|
|
193
|
+
local source="$1"
|
|
194
|
+
local message="$2"
|
|
195
|
+
aw_log "WARN" "$source" "WARNING" "$message"
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
aw_log_debug() {
|
|
199
|
+
if [ "$DEBUG_MODE" = "1" ]; then
|
|
200
|
+
local source="$1"
|
|
201
|
+
local message="$2"
|
|
202
|
+
aw_log "DEBUG" "$source" "DEBUG" "$message"
|
|
203
|
+
fi
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
207
|
+
# LOG VIEWING FUNCTIONS
|
|
208
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
209
|
+
|
|
210
|
+
# View logs in real-time (for CLI command)
|
|
211
|
+
view_logs_live() {
|
|
212
|
+
if [ -f "$LOG_FILE" ]; then
|
|
213
|
+
echo -e "${LOG_CYAN}━━━ AutoWorkflow Logs (live) ━━━${LOG_NC}"
|
|
214
|
+
echo -e "${LOG_DIM}Press Ctrl+C to stop${LOG_NC}"
|
|
215
|
+
echo ""
|
|
216
|
+
tail -f "$LOG_FILE"
|
|
217
|
+
else
|
|
218
|
+
echo "No log file found. Logs will appear after first hook execution."
|
|
219
|
+
fi
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
# View recent logs
|
|
223
|
+
view_logs_recent() {
|
|
224
|
+
local lines="${1:-50}"
|
|
225
|
+
if [ -f "$LOG_FILE" ]; then
|
|
226
|
+
echo -e "${LOG_CYAN}━━━ AutoWorkflow Logs (last $lines) ━━━${LOG_NC}"
|
|
227
|
+
echo ""
|
|
228
|
+
tail -n "$lines" "$LOG_FILE"
|
|
229
|
+
else
|
|
230
|
+
echo "No log file found."
|
|
231
|
+
fi
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
# View all logs
|
|
235
|
+
view_logs_all() {
|
|
236
|
+
if [ -f "$LOG_FILE" ]; then
|
|
237
|
+
echo -e "${LOG_CYAN}━━━ AutoWorkflow Logs (all) ━━━${LOG_NC}"
|
|
238
|
+
echo ""
|
|
239
|
+
cat "$LOG_FILE"
|
|
240
|
+
else
|
|
241
|
+
echo "No log file found."
|
|
242
|
+
fi
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# Clear logs
|
|
246
|
+
clear_logs() {
|
|
247
|
+
rm -f "$LOG_FILE" "$LOG_FILE".*
|
|
248
|
+
echo -e "${LOG_GREEN}✓${LOG_NC} Logs cleared"
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
# Show log stats
|
|
252
|
+
show_log_stats() {
|
|
253
|
+
echo -e "${LOG_CYAN}━━━ Log Statistics ━━━${LOG_NC}"
|
|
254
|
+
echo ""
|
|
255
|
+
|
|
256
|
+
if [ -f "$LOG_FILE" ]; then
|
|
257
|
+
local size=$(stat -f%z "$LOG_FILE" 2>/dev/null || stat -c%s "$LOG_FILE" 2>/dev/null || echo "0")
|
|
258
|
+
local lines=$(wc -l < "$LOG_FILE" | tr -d ' ')
|
|
259
|
+
local hooks=$(grep -c "\[HOOK\]" "$LOG_FILE" 2>/dev/null || echo "0")
|
|
260
|
+
local phases=$(grep -c "\[PHASE\]" "$LOG_FILE" 2>/dev/null || echo "0")
|
|
261
|
+
local gates=$(grep -c "\[GATE\]" "$LOG_FILE" 2>/dev/null || echo "0")
|
|
262
|
+
local errors=$(grep -c "\[ERROR\]" "$LOG_FILE" 2>/dev/null || echo "0")
|
|
263
|
+
|
|
264
|
+
echo " Log file: $LOG_FILE"
|
|
265
|
+
echo " Size: $((size / 1024)) KB"
|
|
266
|
+
echo " Lines: $lines"
|
|
267
|
+
echo ""
|
|
268
|
+
echo " Events:"
|
|
269
|
+
echo " Hooks: $hooks"
|
|
270
|
+
echo " Phases: $phases"
|
|
271
|
+
echo " Gates: $gates"
|
|
272
|
+
echo " Errors: $errors"
|
|
273
|
+
else
|
|
274
|
+
echo " No log file found."
|
|
275
|
+
fi
|
|
276
|
+
echo ""
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
280
|
+
# CLI INTERFACE (when run directly)
|
|
281
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
282
|
+
|
|
283
|
+
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
|
284
|
+
case "${1:-}" in
|
|
285
|
+
live|watch|tail|-f)
|
|
286
|
+
view_logs_live
|
|
287
|
+
;;
|
|
288
|
+
recent)
|
|
289
|
+
view_logs_recent "${2:-50}"
|
|
290
|
+
;;
|
|
291
|
+
all|--all|-a)
|
|
292
|
+
view_logs_all
|
|
293
|
+
;;
|
|
294
|
+
clear|--clear|-c)
|
|
295
|
+
clear_logs
|
|
296
|
+
;;
|
|
297
|
+
stats|--stats|-s)
|
|
298
|
+
show_log_stats
|
|
299
|
+
;;
|
|
300
|
+
*)
|
|
301
|
+
echo "AutoWorkflow Logger"
|
|
302
|
+
echo ""
|
|
303
|
+
echo "Usage: logger.sh <command>"
|
|
304
|
+
echo ""
|
|
305
|
+
echo "Commands:"
|
|
306
|
+
echo " live, watch, tail, -f View logs in real-time"
|
|
307
|
+
echo " recent [n] Show last n log entries (default: 50)"
|
|
308
|
+
echo " all, --all, -a Show all logs"
|
|
309
|
+
echo " clear, --clear, -c Clear all logs"
|
|
310
|
+
echo " stats, --stats, -s Show log statistics"
|
|
311
|
+
echo ""
|
|
312
|
+
echo "Environment:"
|
|
313
|
+
echo " AUTOWORKFLOW_DEBUG=1 Enable debug output to terminal"
|
|
314
|
+
echo ""
|
|
315
|
+
echo "Log file: $LOG_FILE"
|
|
316
|
+
;;
|
|
317
|
+
esac
|
|
318
|
+
fi
|
|
@@ -17,6 +17,10 @@ NC='\033[0m'
|
|
|
17
17
|
# Project directory (use env var if set, otherwise current directory)
|
|
18
18
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
19
19
|
|
|
20
|
+
# Source the logger
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
22
|
+
source "$SCRIPT_DIR/logger.sh" 2>/dev/null || true
|
|
23
|
+
|
|
20
24
|
# State directory
|
|
21
25
|
STATE_DIR="$PROJECT_DIR/.claude/.autoworkflow"
|
|
22
26
|
mkdir -p "$STATE_DIR"
|
|
@@ -112,11 +116,13 @@ check_analyze_gate() {
|
|
|
112
116
|
check_plan_approval_gate() {
|
|
113
117
|
echo ""
|
|
114
118
|
echo "Checking plan_approval_gate..."
|
|
119
|
+
aw_log_gate "plan_approval" "CHECKING"
|
|
115
120
|
|
|
116
121
|
if [ -f "$APPROVAL_FILE" ]; then
|
|
117
122
|
local approval=$(cat "$APPROVAL_FILE")
|
|
118
123
|
if [ "$approval" = "approved" ]; then
|
|
119
124
|
echo -e " ${GREEN}✅${NC} Plan has been approved"
|
|
125
|
+
aw_log_gate "plan_approval" "PASSED"
|
|
120
126
|
return 0
|
|
121
127
|
fi
|
|
122
128
|
fi
|
|
@@ -127,6 +133,7 @@ check_plan_approval_gate() {
|
|
|
127
133
|
echo ""
|
|
128
134
|
echo "Wait for user to say 'yes', 'proceed', 'approved', etc."
|
|
129
135
|
echo ""
|
|
136
|
+
aw_log_gate "plan_approval" "BLOCKED" "awaiting user approval"
|
|
130
137
|
return 1
|
|
131
138
|
}
|
|
132
139
|
|
|
@@ -134,11 +141,13 @@ check_plan_approval_gate() {
|
|
|
134
141
|
check_verify_gate() {
|
|
135
142
|
echo ""
|
|
136
143
|
echo "Checking verify_gate..."
|
|
144
|
+
aw_log_gate "verify" "CHECKING"
|
|
137
145
|
|
|
138
146
|
if [ -f "$STATE_DIR/verify-status" ]; then
|
|
139
147
|
local status=$(cat "$STATE_DIR/verify-status")
|
|
140
148
|
if [ "$status" = "PASSED" ]; then
|
|
141
149
|
echo -e " ${GREEN}✅${NC} Verification passed"
|
|
150
|
+
aw_log_gate "verify" "PASSED"
|
|
142
151
|
return 0
|
|
143
152
|
fi
|
|
144
153
|
fi
|
|
@@ -147,6 +156,7 @@ check_verify_gate() {
|
|
|
147
156
|
echo ""
|
|
148
157
|
echo -e "${YELLOW}BLOCKED:${NC} Run npm run verify and fix all errors first."
|
|
149
158
|
echo ""
|
|
159
|
+
aw_log_gate "verify" "BLOCKED" "verification not passed"
|
|
150
160
|
return 1
|
|
151
161
|
}
|
|
152
162
|
|
|
@@ -190,6 +200,8 @@ transition() {
|
|
|
190
200
|
local from="$1"
|
|
191
201
|
local to="$2"
|
|
192
202
|
|
|
203
|
+
aw_log_phase "$from" "$to"
|
|
204
|
+
|
|
193
205
|
echo ""
|
|
194
206
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
195
207
|
echo -e "${BOLD}AUTOWORKFLOW: PHASE TRANSITION${NC}"
|
|
@@ -244,6 +256,9 @@ transition() {
|
|
|
244
256
|
# Output reflection prompt for the new phase
|
|
245
257
|
output_reflection_prompt "$to"
|
|
246
258
|
|
|
259
|
+
# Prompt to update memories based on completed phase
|
|
260
|
+
prompt_memory_update "$from"
|
|
261
|
+
|
|
247
262
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
248
263
|
echo ""
|
|
249
264
|
|
|
@@ -287,127 +302,119 @@ reset_workflow() {
|
|
|
287
302
|
}
|
|
288
303
|
|
|
289
304
|
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
290
|
-
# MEMORY SYSTEM (Serena-inspired)
|
|
291
|
-
#
|
|
305
|
+
# MEMORY SYSTEM v2 (Serena-inspired)
|
|
306
|
+
# Claude edits files directly + hooks prompt at key moments
|
|
292
307
|
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
293
308
|
|
|
294
309
|
MEMORY_DIR="$STATE_DIR/memories"
|
|
295
310
|
mkdir -p "$MEMORY_DIR"
|
|
296
311
|
|
|
297
|
-
#
|
|
298
|
-
|
|
299
|
-
local
|
|
300
|
-
local
|
|
301
|
-
local
|
|
302
|
-
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
|
303
|
-
|
|
304
|
-
local memory_file="$MEMORY_DIR/${category}.md"
|
|
305
|
-
|
|
306
|
-
# Create file with header if it doesn't exist
|
|
307
|
-
if [ ! -f "$memory_file" ]; then
|
|
308
|
-
cat > "$memory_file" << EOF
|
|
309
|
-
# ${category^} Memory
|
|
310
|
-
|
|
311
|
-
> Auto-generated memory store. Add entries as you work.
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
EOF
|
|
316
|
-
fi
|
|
317
|
-
|
|
318
|
-
# Append new memory entry
|
|
319
|
-
cat >> "$memory_file" << EOF
|
|
320
|
-
## $key
|
|
321
|
-
*Recorded: $timestamp*
|
|
322
|
-
|
|
323
|
-
$value
|
|
324
|
-
|
|
325
|
-
---
|
|
326
|
-
|
|
327
|
-
EOF
|
|
328
|
-
|
|
329
|
-
echo -e "${GREEN}✅${NC} Memory saved: $category/$key"
|
|
330
|
-
}
|
|
312
|
+
# Prompt Claude to update memories (called at phase transitions)
|
|
313
|
+
prompt_memory_update() {
|
|
314
|
+
local phase="$1"
|
|
315
|
+
local memory_type=""
|
|
316
|
+
local prompt_text=""
|
|
331
317
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
318
|
+
case "$phase" in
|
|
319
|
+
PLAN|CONFIRM)
|
|
320
|
+
memory_type="decisions"
|
|
321
|
+
prompt_text="If you made any architectural or implementation decisions, update .claude/.autoworkflow/memories/decisions.md"
|
|
322
|
+
;;
|
|
323
|
+
IMPLEMENT|VERIFY)
|
|
324
|
+
memory_type="patterns"
|
|
325
|
+
prompt_text="If you discovered any codebase patterns, update .claude/.autoworkflow/memories/patterns.md"
|
|
326
|
+
;;
|
|
327
|
+
COMMIT)
|
|
328
|
+
memory_type="context"
|
|
329
|
+
prompt_text="Update .claude/.autoworkflow/memories/context.md with session summary for continuity"
|
|
330
|
+
;;
|
|
331
|
+
esac
|
|
336
332
|
|
|
337
|
-
if [ -
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
echo "
|
|
333
|
+
if [ -n "$memory_type" ]; then
|
|
334
|
+
echo ""
|
|
335
|
+
echo -e "${CYAN}━━━ MEMORY UPDATE ━━━${NC}"
|
|
336
|
+
echo -e "${DIM}$prompt_text${NC}"
|
|
337
|
+
echo ""
|
|
338
|
+
echo -e "${DIM}Format: Add a new ## Section with date and details${NC}"
|
|
339
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
340
|
+
echo ""
|
|
341
341
|
fi
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
#
|
|
345
|
-
|
|
344
|
+
# Prompt to record a blocker (called when errors occur)
|
|
345
|
+
prompt_blocker_update() {
|
|
346
|
+
local error_context="$1"
|
|
346
347
|
echo ""
|
|
347
|
-
echo -e "${
|
|
348
|
+
echo -e "${YELLOW}━━━ BLOCKER DETECTED ━━━${NC}"
|
|
349
|
+
echo -e "${DIM}Consider recording this in .claude/.autoworkflow/memories/blockers.md${NC}"
|
|
348
350
|
echo ""
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
for file in "$MEMORY_DIR"/*.md; do
|
|
352
|
-
if [ -f "$file" ]; then
|
|
353
|
-
local category=$(basename "$file" .md)
|
|
354
|
-
local count=$(grep -c "^## " "$file" 2>/dev/null || echo "0")
|
|
355
|
-
echo " - $category ($count entries)"
|
|
356
|
-
fi
|
|
357
|
-
done
|
|
358
|
-
else
|
|
359
|
-
echo " No memories stored yet."
|
|
360
|
-
fi
|
|
351
|
+
echo -e "${DIM}Include: Issue, Symptoms, Workaround, Status${NC}"
|
|
352
|
+
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
361
353
|
echo ""
|
|
362
354
|
}
|
|
363
355
|
|
|
364
|
-
#
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
local task_type=$(get_task_type)
|
|
369
|
-
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
|
370
|
-
|
|
371
|
-
local context_file="$MEMORY_DIR/context.md"
|
|
372
|
-
|
|
373
|
-
cat > "$context_file" << EOF
|
|
374
|
-
# Session Context
|
|
375
|
-
|
|
376
|
-
> Last updated: $timestamp
|
|
377
|
-
|
|
378
|
-
## Current State
|
|
379
|
-
- **Phase:** $current_phase
|
|
380
|
-
- **Task Type:** $task_type
|
|
381
|
-
- **Description:** $task_description
|
|
382
|
-
|
|
383
|
-
## What Was Done
|
|
384
|
-
<!-- Claude should update this section as work progresses -->
|
|
356
|
+
# Load and display memories at session start
|
|
357
|
+
load_memories_summary() {
|
|
358
|
+
echo ""
|
|
359
|
+
echo -e "${CYAN}━━━ PROJECT MEMORIES ━━━${NC}"
|
|
385
360
|
|
|
386
|
-
|
|
387
|
-
<!-- Claude should update this section -->
|
|
361
|
+
local has_memories=false
|
|
388
362
|
|
|
389
|
-
|
|
390
|
-
|
|
363
|
+
# Check decisions
|
|
364
|
+
if [ -f "$MEMORY_DIR/decisions.md" ]; then
|
|
365
|
+
local decision_count=$(grep -c "^## " "$MEMORY_DIR/decisions.md" 2>/dev/null || echo "0")
|
|
366
|
+
if [ "$decision_count" -gt 1 ]; then # More than template
|
|
367
|
+
echo -e " ${GREEN}●${NC} Decisions: $((decision_count - 1)) recorded"
|
|
368
|
+
has_memories=true
|
|
369
|
+
fi
|
|
370
|
+
fi
|
|
391
371
|
|
|
392
|
-
|
|
393
|
-
|
|
372
|
+
# Check patterns
|
|
373
|
+
if [ -f "$MEMORY_DIR/patterns.md" ]; then
|
|
374
|
+
local pattern_count=$(grep -c "^## " "$MEMORY_DIR/patterns.md" 2>/dev/null || echo "0")
|
|
375
|
+
if [ "$pattern_count" -gt 1 ]; then
|
|
376
|
+
echo -e " ${GREEN}●${NC} Patterns: $((pattern_count - 1)) recorded"
|
|
377
|
+
has_memories=true
|
|
378
|
+
fi
|
|
379
|
+
fi
|
|
394
380
|
|
|
395
|
-
|
|
381
|
+
# Check blockers
|
|
382
|
+
if [ -f "$MEMORY_DIR/blockers.md" ]; then
|
|
383
|
+
local blocker_count=$(grep -c "^## " "$MEMORY_DIR/blockers.md" 2>/dev/null || echo "0")
|
|
384
|
+
if [ "$blocker_count" -gt 1 ]; then
|
|
385
|
+
echo -e " ${YELLOW}●${NC} Blockers: $((blocker_count - 1)) recorded"
|
|
386
|
+
has_memories=true
|
|
387
|
+
fi
|
|
388
|
+
fi
|
|
396
389
|
|
|
397
|
-
|
|
398
|
-
|
|
390
|
+
if [ "$has_memories" = false ]; then
|
|
391
|
+
echo -e " ${DIM}No memories recorded yet${NC}"
|
|
392
|
+
fi
|
|
399
393
|
|
|
400
|
-
echo
|
|
394
|
+
echo ""
|
|
395
|
+
echo -e "${DIM}Read with: Read tool on .claude/.autoworkflow/memories/*.md${NC}"
|
|
396
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
397
|
+
echo ""
|
|
401
398
|
}
|
|
402
399
|
|
|
403
|
-
# Load context summary
|
|
400
|
+
# Load context summary (for session resume)
|
|
404
401
|
load_context() {
|
|
405
402
|
local context_file="$MEMORY_DIR/context.md"
|
|
406
403
|
|
|
407
404
|
if [ -f "$context_file" ]; then
|
|
408
405
|
echo ""
|
|
409
406
|
echo -e "${CYAN}━━━ PREVIOUS SESSION CONTEXT ━━━${NC}"
|
|
410
|
-
|
|
407
|
+
# Show just the key sections
|
|
408
|
+
if grep -q "## What Was Done" "$context_file"; then
|
|
409
|
+
echo -e "${BOLD}What Was Done:${NC}"
|
|
410
|
+
sed -n '/## What Was Done/,/## /p' "$context_file" | head -8 | tail -n +2
|
|
411
|
+
fi
|
|
412
|
+
if grep -q "## What Remains" "$context_file"; then
|
|
413
|
+
echo -e "${BOLD}What Remains:${NC}"
|
|
414
|
+
sed -n '/## What Remains/,/## /p' "$context_file" | head -8 | tail -n +2
|
|
415
|
+
fi
|
|
416
|
+
echo ""
|
|
417
|
+
echo -e "${DIM}Full context: .claude/.autoworkflow/memories/context.md${NC}"
|
|
411
418
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
412
419
|
echo ""
|
|
413
420
|
fi
|
|
@@ -442,22 +449,16 @@ case "$1" in
|
|
|
442
449
|
fi
|
|
443
450
|
echo ""
|
|
444
451
|
;;
|
|
445
|
-
# Memory commands (
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
;;
|
|
449
|
-
memory-read)
|
|
450
|
-
read_memories "$2"
|
|
451
|
-
;;
|
|
452
|
-
memory-list)
|
|
453
|
-
list_memories
|
|
452
|
+
# Memory commands v2 (Claude edits files directly)
|
|
453
|
+
memories)
|
|
454
|
+
load_memories_summary
|
|
454
455
|
;;
|
|
455
|
-
context
|
|
456
|
-
save_context "$2"
|
|
457
|
-
;;
|
|
458
|
-
context-load)
|
|
456
|
+
context)
|
|
459
457
|
load_context
|
|
460
458
|
;;
|
|
459
|
+
blocker)
|
|
460
|
+
prompt_blocker_update "$2"
|
|
461
|
+
;;
|
|
461
462
|
reflect)
|
|
462
463
|
output_reflection_prompt "$2"
|
|
463
464
|
;;
|
|
@@ -471,12 +472,16 @@ case "$1" in
|
|
|
471
472
|
echo " reset - Reset workflow state"
|
|
472
473
|
echo " status - Show current state"
|
|
473
474
|
echo ""
|
|
474
|
-
echo "Memory Commands (
|
|
475
|
-
echo "
|
|
476
|
-
echo "
|
|
477
|
-
echo "
|
|
478
|
-
echo "
|
|
479
|
-
echo "
|
|
480
|
-
echo "
|
|
475
|
+
echo "Memory Commands (Claude edits files directly):"
|
|
476
|
+
echo " memories - Show memory summary"
|
|
477
|
+
echo " context - Load previous session context"
|
|
478
|
+
echo " blocker - Prompt to record a blocker"
|
|
479
|
+
echo " reflect <phase> - Show reflection prompts"
|
|
480
|
+
echo ""
|
|
481
|
+
echo "Memory Files (edit directly with Claude):"
|
|
482
|
+
echo " .claude/.autoworkflow/memories/decisions.md"
|
|
483
|
+
echo " .claude/.autoworkflow/memories/patterns.md"
|
|
484
|
+
echo " .claude/.autoworkflow/memories/blockers.md"
|
|
485
|
+
echo " .claude/.autoworkflow/memories/context.md"
|
|
481
486
|
;;
|
|
482
487
|
esac
|
|
@@ -20,6 +20,10 @@ NC='\033[0m'
|
|
|
20
20
|
# Project directory (use env var if set, otherwise current directory)
|
|
21
21
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
22
22
|
|
|
23
|
+
# Source the logger
|
|
24
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
25
|
+
source "$SCRIPT_DIR/logger.sh" 2>/dev/null || true
|
|
26
|
+
|
|
23
27
|
# State directory
|
|
24
28
|
STATE_DIR="$PROJECT_DIR/.claude/.autoworkflow"
|
|
25
29
|
mkdir -p "$STATE_DIR"
|
|
@@ -311,6 +315,8 @@ run_verify() {
|
|
|
311
315
|
|
|
312
316
|
# Main execution
|
|
313
317
|
main() {
|
|
318
|
+
aw_log_hook "post-edit.sh" "START"
|
|
319
|
+
|
|
314
320
|
local current_phase=$(get_phase)
|
|
315
321
|
|
|
316
322
|
# Track that we're in VERIFY phase
|
|
@@ -318,6 +324,7 @@ main() {
|
|
|
318
324
|
|
|
319
325
|
# Get current iteration and increment
|
|
320
326
|
local iteration=$(increment_iteration)
|
|
327
|
+
aw_log_verify "$iteration/$MAX_ITERATIONS" "STARTED"
|
|
321
328
|
|
|
322
329
|
# Check if we've exceeded max iterations
|
|
323
330
|
if [ "$iteration" -gt "$MAX_ITERATIONS" ]; then
|
|
@@ -334,6 +341,7 @@ main() {
|
|
|
334
341
|
echo " 2. Reset counter: rm $VERIFY_ITERATION_FILE"
|
|
335
342
|
echo ""
|
|
336
343
|
echo "BLOCKED" > "$VERIFY_STATUS_FILE"
|
|
344
|
+
aw_log_verify "$iteration/$MAX_ITERATIONS" "BLOCKED" "max iterations reached"
|
|
337
345
|
# Don't exit with error - let Claude continue but report the issue
|
|
338
346
|
exit 0
|
|
339
347
|
fi
|
|
@@ -356,6 +364,7 @@ main() {
|
|
|
356
364
|
|
|
357
365
|
# Update status
|
|
358
366
|
echo "PASSED" > "$VERIFY_STATUS_FILE"
|
|
367
|
+
aw_log_verify "$iteration/$MAX_ITERATIONS" "PASSED" "0 errors"
|
|
359
368
|
|
|
360
369
|
# Check if this was a feature/refactor that needs audit
|
|
361
370
|
local task_type=""
|
|
@@ -386,6 +395,7 @@ main() {
|
|
|
386
395
|
# Update status
|
|
387
396
|
echo "FAILED" > "$VERIFY_STATUS_FILE"
|
|
388
397
|
echo "$iteration" > "$VERIFY_ITERATION_FILE"
|
|
398
|
+
aw_log_verify "$iteration/$MAX_ITERATIONS" "FAILED" "errors found"
|
|
389
399
|
|
|
390
400
|
echo "Fix the errors above and save the file."
|
|
391
401
|
echo "Verification will re-run automatically."
|
|
@@ -396,6 +406,8 @@ main() {
|
|
|
396
406
|
# Enter FIX phase
|
|
397
407
|
set_phase "FIX"
|
|
398
408
|
fi
|
|
409
|
+
|
|
410
|
+
aw_log_hook "post-edit.sh" "COMPLETE"
|
|
399
411
|
}
|
|
400
412
|
|
|
401
413
|
main
|
|
@@ -19,6 +19,10 @@ NC='\033[0m'
|
|
|
19
19
|
# Project directory (use env var if set, otherwise current directory)
|
|
20
20
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
21
21
|
|
|
22
|
+
# Source the logger
|
|
23
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
24
|
+
source "$SCRIPT_DIR/logger.sh" 2>/dev/null || true
|
|
25
|
+
|
|
22
26
|
# State directory
|
|
23
27
|
STATE_DIR="$PROJECT_DIR/.claude/.autoworkflow"
|
|
24
28
|
mkdir -p "$STATE_DIR"
|
|
@@ -191,6 +195,8 @@ check_commit_message() {
|
|
|
191
195
|
|
|
192
196
|
# Main execution
|
|
193
197
|
main() {
|
|
198
|
+
aw_log_gate "pre_commit" "CHECKING" "7 checks"
|
|
199
|
+
|
|
194
200
|
print_header
|
|
195
201
|
|
|
196
202
|
echo "Checking requirements..."
|
|
@@ -219,6 +225,8 @@ main() {
|
|
|
219
225
|
echo "BLOCKED" > "$STATE_DIR/gate-status"
|
|
220
226
|
echo "$ERRORS" > "$STATE_DIR/gate-errors"
|
|
221
227
|
|
|
228
|
+
aw_log_gate "pre_commit" "BLOCKED" "$ERRORS errors"
|
|
229
|
+
|
|
222
230
|
# EXIT WITH ERROR TO BLOCK THE COMMIT
|
|
223
231
|
exit 1
|
|
224
232
|
else
|
|
@@ -231,6 +239,8 @@ main() {
|
|
|
231
239
|
echo "PASSED" > "$STATE_DIR/gate-status"
|
|
232
240
|
echo "0" > "$STATE_DIR/gate-errors"
|
|
233
241
|
|
|
242
|
+
aw_log_gate "pre_commit" "PASSED" "7/7 checks"
|
|
243
|
+
|
|
234
244
|
exit 0
|
|
235
245
|
fi
|
|
236
246
|
}
|
|
@@ -21,6 +21,10 @@ NC='\033[0m'
|
|
|
21
21
|
# Project directory (use env var if set, otherwise current directory)
|
|
22
22
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
23
23
|
|
|
24
|
+
# Source the logger
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
source "$SCRIPT_DIR/logger.sh" 2>/dev/null || true
|
|
27
|
+
|
|
24
28
|
# State directory
|
|
25
29
|
STATE_DIR="$PROJECT_DIR/.claude/.autoworkflow"
|
|
26
30
|
mkdir -p "$STATE_DIR"
|
|
@@ -462,13 +466,57 @@ reset_turn_state() {
|
|
|
462
466
|
echo "0" > "$CURRENT_TURN_EDITS_FILE"
|
|
463
467
|
}
|
|
464
468
|
|
|
469
|
+
# Load and display memories summary (for context awareness)
|
|
470
|
+
show_memories_summary() {
|
|
471
|
+
local has_memories=false
|
|
472
|
+
|
|
473
|
+
# Check if any memories exist (beyond templates)
|
|
474
|
+
for file in "$MEMORY_DIR/decisions.md" "$MEMORY_DIR/patterns.md" "$MEMORY_DIR/blockers.md"; do
|
|
475
|
+
if [ -f "$file" ]; then
|
|
476
|
+
local count=$(grep -c "^## " "$file" 2>/dev/null || echo "0")
|
|
477
|
+
if [ "$count" -gt 1 ]; then
|
|
478
|
+
has_memories=true
|
|
479
|
+
break
|
|
480
|
+
fi
|
|
481
|
+
fi
|
|
482
|
+
done
|
|
483
|
+
|
|
484
|
+
if [ "$has_memories" = true ]; then
|
|
485
|
+
echo ""
|
|
486
|
+
echo -e "${CYAN}━━━ PROJECT MEMORIES ━━━${NC}"
|
|
487
|
+
|
|
488
|
+
if [ -f "$MEMORY_DIR/decisions.md" ]; then
|
|
489
|
+
local count=$(grep -c "^## " "$MEMORY_DIR/decisions.md" 2>/dev/null || echo "0")
|
|
490
|
+
[ "$count" -gt 1 ] && echo -e " ${GREEN}●${NC} Decisions: $((count - 1)) recorded"
|
|
491
|
+
fi
|
|
492
|
+
|
|
493
|
+
if [ -f "$MEMORY_DIR/patterns.md" ]; then
|
|
494
|
+
local count=$(grep -c "^## " "$MEMORY_DIR/patterns.md" 2>/dev/null || echo "0")
|
|
495
|
+
[ "$count" -gt 1 ] && echo -e " ${GREEN}●${NC} Patterns: $((count - 1)) recorded"
|
|
496
|
+
fi
|
|
497
|
+
|
|
498
|
+
if [ -f "$MEMORY_DIR/blockers.md" ]; then
|
|
499
|
+
local count=$(grep -c "^## " "$MEMORY_DIR/blockers.md" 2>/dev/null || echo "0")
|
|
500
|
+
[ "$count" -gt 1 ] && echo -e " ${YELLOW}●${NC} Blockers: $((count - 1)) recorded"
|
|
501
|
+
fi
|
|
502
|
+
|
|
503
|
+
echo ""
|
|
504
|
+
echo -e "${DIM}Read: .claude/.autoworkflow/memories/*.md${NC}"
|
|
505
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
506
|
+
echo ""
|
|
507
|
+
fi
|
|
508
|
+
}
|
|
509
|
+
|
|
465
510
|
# Main execution
|
|
466
511
|
main() {
|
|
512
|
+
aw_log_hook "session-check.sh" "START"
|
|
513
|
+
|
|
467
514
|
local is_new_session=false
|
|
468
515
|
|
|
469
516
|
# Initialize session
|
|
470
517
|
if init_session; then
|
|
471
518
|
is_new_session=true
|
|
519
|
+
aw_log "HOOK" "session-check.sh" "NEW_SESSION"
|
|
472
520
|
fi
|
|
473
521
|
|
|
474
522
|
# Reset turn state on each user message
|
|
@@ -476,6 +524,7 @@ main() {
|
|
|
476
524
|
|
|
477
525
|
# Check if init is needed (package installed but not set up)
|
|
478
526
|
if check_init_needed; then
|
|
527
|
+
aw_log "HOOK" "session-check.sh" "INIT_NEEDED"
|
|
479
528
|
exit 0
|
|
480
529
|
fi
|
|
481
530
|
|
|
@@ -485,10 +534,17 @@ main() {
|
|
|
485
534
|
fi
|
|
486
535
|
|
|
487
536
|
# Check for missing blueprint (prompts user for documentation)
|
|
488
|
-
check_blueprint
|
|
537
|
+
if ! check_blueprint; then
|
|
538
|
+
aw_log "HOOK" "session-check.sh" "DOCS_REQUIRED"
|
|
539
|
+
fi
|
|
540
|
+
|
|
541
|
+
# Show memories summary (if any exist)
|
|
542
|
+
show_memories_summary
|
|
489
543
|
|
|
490
544
|
# Show current state if not idle
|
|
491
545
|
show_state
|
|
546
|
+
|
|
547
|
+
aw_log_hook "session-check.sh" "COMPLETE"
|
|
492
548
|
}
|
|
493
549
|
|
|
494
550
|
main
|
package/.claude/settings.json
CHANGED
|
@@ -144,7 +144,16 @@
|
|
|
144
144
|
"- phase: Current phase (ANALYZE, PLAN, etc.)",
|
|
145
145
|
"- task-type: Classified task type",
|
|
146
146
|
"- verify-iteration: Current verify loop count",
|
|
147
|
-
"- gate-status: Last gate check result"
|
|
147
|
+
"- gate-status: Last gate check result",
|
|
148
|
+
"",
|
|
149
|
+
"### Memory System (Persistent Context)",
|
|
150
|
+
"Edit these files directly using the Edit tool:",
|
|
151
|
+
"- `.claude/.autoworkflow/memories/decisions.md` - After PLAN: record architectural choices",
|
|
152
|
+
"- `.claude/.autoworkflow/memories/patterns.md` - After IMPLEMENT: record discovered patterns",
|
|
153
|
+
"- `.claude/.autoworkflow/memories/blockers.md` - When errors: record issues and workarounds",
|
|
154
|
+
"- `.claude/.autoworkflow/memories/context.md` - Before COMMIT: update session summary",
|
|
155
|
+
"",
|
|
156
|
+
"Format: ## Title, *Date*, Content, ---"
|
|
148
157
|
],
|
|
149
158
|
|
|
150
159
|
"workflow": {
|
package/CLAUDE.md
CHANGED
|
@@ -124,35 +124,77 @@ All state stored in `.claude/.autoworkflow/`:
|
|
|
124
124
|
|
|
125
125
|
---
|
|
126
126
|
|
|
127
|
-
##
|
|
127
|
+
## Logging System
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
Real-time visibility into hook execution, gates, and workflow events.
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|------|---------|
|
|
133
|
-
| `decisions.md` | Document architectural/implementation choices |
|
|
134
|
-
| `patterns.md` | Record discovered codebase patterns |
|
|
135
|
-
| `blockers.md` | Track known issues and workarounds |
|
|
136
|
-
| `context.md` | Session continuity (auto-generated) |
|
|
131
|
+
**Log Location:** `.claude/.autoworkflow/logs/aw.log`
|
|
137
132
|
|
|
138
|
-
**
|
|
133
|
+
**CLI Commands:**
|
|
139
134
|
```bash
|
|
140
|
-
#
|
|
141
|
-
|
|
135
|
+
npx autoworkflow logs # Watch logs in real-time
|
|
136
|
+
npx autoworkflow logs --recent # Show last 50 entries
|
|
137
|
+
npx autoworkflow logs --all # Show all logs
|
|
138
|
+
npx autoworkflow logs --clear # Clear logs
|
|
139
|
+
npx autoworkflow logs --stats # Show statistics
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Or use tail directly:**
|
|
143
|
+
```bash
|
|
144
|
+
tail -f .claude/.autoworkflow/logs/aw.log
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Log Categories:**
|
|
148
|
+
| Category | Events |
|
|
149
|
+
|----------|--------|
|
|
150
|
+
| HOOK | Hook start/complete |
|
|
151
|
+
| PHASE | Phase transitions |
|
|
152
|
+
| GATE | Gate checks (pass/block) |
|
|
153
|
+
| VERIFY | Verification iterations |
|
|
154
|
+
| MEMORY | Memory update prompts |
|
|
155
|
+
| COMMIT | Commit events |
|
|
156
|
+
| ERROR | Errors and failures |
|
|
157
|
+
|
|
158
|
+
**Debug Mode:** Set `AUTOWORKFLOW_DEBUG=1` to see logs in terminal.
|
|
142
159
|
|
|
143
|
-
|
|
144
|
-
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Memory System (Serena-inspired)
|
|
145
163
|
|
|
146
|
-
|
|
147
|
-
.claude/hooks/phase-transition.sh memory-list
|
|
164
|
+
Persistent context that survives across sessions. **Claude edits files directly** + hooks prompt at key moments.
|
|
148
165
|
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
**Memory Files:** `.claude/.autoworkflow/memories/`
|
|
167
|
+
| File | Purpose | When to Update |
|
|
168
|
+
|------|---------|----------------|
|
|
169
|
+
| `decisions.md` | Architectural/implementation choices | After PLAN phase |
|
|
170
|
+
| `patterns.md` | Discovered codebase patterns | After IMPLEMENT |
|
|
171
|
+
| `blockers.md` | Known issues and workarounds | When hitting errors |
|
|
172
|
+
| `context.md` | Session continuity | Before COMMIT |
|
|
173
|
+
|
|
174
|
+
**How it works:**
|
|
175
|
+
1. **Session Start** → Memories summary displayed automatically
|
|
176
|
+
2. **Phase Transitions** → Hooks prompt to update relevant memory
|
|
177
|
+
3. **Claude Edits Directly** → Use Edit tool on memory files
|
|
178
|
+
4. **No Shell Commands** → Just read and edit the markdown files
|
|
151
179
|
|
|
152
|
-
|
|
153
|
-
|
|
180
|
+
**Memory Format:**
|
|
181
|
+
```markdown
|
|
182
|
+
## [Entry Title]
|
|
183
|
+
*[Date]*
|
|
184
|
+
|
|
185
|
+
[Content - decisions made, patterns found, blockers hit]
|
|
186
|
+
|
|
187
|
+
---
|
|
154
188
|
```
|
|
155
189
|
|
|
190
|
+
**Automated Prompts:**
|
|
191
|
+
| Trigger | Memory Prompt |
|
|
192
|
+
|---------|---------------|
|
|
193
|
+
| After PLAN | "Record any decisions made" |
|
|
194
|
+
| After IMPLEMENT | "Record any patterns discovered" |
|
|
195
|
+
| Before COMMIT | "Update context for next session" |
|
|
196
|
+
| Error encountered | "Consider recording this blocker" |
|
|
197
|
+
|
|
156
198
|
---
|
|
157
199
|
|
|
158
200
|
## Reflection Prompts (Serena-inspired)
|
|
@@ -239,6 +281,7 @@ npm run format # Prettier
|
|
|
239
281
|
| `phase-transition.sh` | Manual call | State management |
|
|
240
282
|
| `audit-runner.sh` | Manual call | Run UI + cycle audits |
|
|
241
283
|
| `blueprint-generator.sh` | Manual call | Enhanced project discovery (8 scans) |
|
|
284
|
+
| `logger.sh` | Sourced by hooks | Centralized logging system |
|
|
242
285
|
|
|
243
286
|
---
|
|
244
287
|
|
package/bin/cli.js
CHANGED
|
@@ -72,6 +72,12 @@ Commands:
|
|
|
72
72
|
${colors.cyan('update')} Smart update - core files only, preserve user files
|
|
73
73
|
${colors.cyan('status')} Show installed version and what would change
|
|
74
74
|
|
|
75
|
+
${colors.cyan('logs')} View AutoWorkflow logs (real-time)
|
|
76
|
+
${colors.cyan('logs --recent')} Show last 50 log entries
|
|
77
|
+
${colors.cyan('logs --all')} Show all logs
|
|
78
|
+
${colors.cyan('logs --clear')} Clear all logs
|
|
79
|
+
${colors.cyan('logs --stats')} Show log statistics
|
|
80
|
+
|
|
75
81
|
${colors.cyan('help')} Show this help message
|
|
76
82
|
|
|
77
83
|
Options:
|
|
@@ -82,7 +88,7 @@ Examples:
|
|
|
82
88
|
npx autoworkflow init # Fresh install
|
|
83
89
|
npx autoworkflow update # Update core files only
|
|
84
90
|
npx autoworkflow status # Check what would change
|
|
85
|
-
npx autoworkflow
|
|
91
|
+
npx autoworkflow logs # Watch logs in real-time
|
|
86
92
|
`);
|
|
87
93
|
}
|
|
88
94
|
|
|
@@ -453,6 +459,62 @@ function init(options = {}) {
|
|
|
453
459
|
console.log(`${colors.dim('Optional: Edit instructions/AI_RULES.md to customize coding standards')}\n`);
|
|
454
460
|
}
|
|
455
461
|
|
|
462
|
+
// Logs command
|
|
463
|
+
import { spawn } from 'child_process';
|
|
464
|
+
|
|
465
|
+
function logs() {
|
|
466
|
+
const cwd = process.cwd();
|
|
467
|
+
const loggerScript = join(cwd, '.claude', 'hooks', 'logger.sh');
|
|
468
|
+
|
|
469
|
+
// Check if logger exists
|
|
470
|
+
if (!existsSync(loggerScript)) {
|
|
471
|
+
console.log(`${colors.yellow('⚠')} AutoWorkflow not initialized in this directory.`);
|
|
472
|
+
console.log(` Run: npx autoworkflow init`);
|
|
473
|
+
process.exit(1);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Determine subcommand
|
|
477
|
+
const subCommand = args[1] || 'live';
|
|
478
|
+
|
|
479
|
+
let loggerArg;
|
|
480
|
+
switch (subCommand) {
|
|
481
|
+
case '--recent':
|
|
482
|
+
case '-r':
|
|
483
|
+
loggerArg = 'recent';
|
|
484
|
+
break;
|
|
485
|
+
case '--all':
|
|
486
|
+
case '-a':
|
|
487
|
+
loggerArg = 'all';
|
|
488
|
+
break;
|
|
489
|
+
case '--clear':
|
|
490
|
+
case '-c':
|
|
491
|
+
loggerArg = 'clear';
|
|
492
|
+
break;
|
|
493
|
+
case '--stats':
|
|
494
|
+
case '-s':
|
|
495
|
+
loggerArg = 'stats';
|
|
496
|
+
break;
|
|
497
|
+
default:
|
|
498
|
+
loggerArg = 'live';
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Run the logger script
|
|
502
|
+
const child = spawn('bash', [loggerScript, loggerArg], {
|
|
503
|
+
cwd: cwd,
|
|
504
|
+
stdio: 'inherit',
|
|
505
|
+
env: { ...process.env, CLAUDE_PROJECT_DIR: cwd }
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
child.on('error', (err) => {
|
|
509
|
+
console.error(`${colors.red('Error:')} ${err.message}`);
|
|
510
|
+
process.exit(1);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
child.on('exit', (code) => {
|
|
514
|
+
process.exit(code || 0);
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
456
518
|
// Main
|
|
457
519
|
switch (command) {
|
|
458
520
|
case 'init':
|
|
@@ -464,6 +526,10 @@ switch (command) {
|
|
|
464
526
|
case 'status':
|
|
465
527
|
status();
|
|
466
528
|
break;
|
|
529
|
+
case 'logs':
|
|
530
|
+
case 'log':
|
|
531
|
+
logs();
|
|
532
|
+
break;
|
|
467
533
|
case 'help':
|
|
468
534
|
case '--help':
|
|
469
535
|
case '-h':
|