specweave 0.23.12 → 0.23.14
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/dist/src/core/progress/error-logger.d.ts +58 -0
- package/dist/src/core/progress/error-logger.d.ts.map +1 -0
- package/dist/src/core/progress/error-logger.js +99 -0
- package/dist/src/core/progress/error-logger.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/hooks/docs-changed.sh +9 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh +9 -1
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh +9 -1
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +9 -1
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +24 -0
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Logger - Comprehensive error logging for batch operations
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - File-based error logging
|
|
6
|
+
* - Timestamped error records
|
|
7
|
+
* - Structured error format
|
|
8
|
+
* - Automatic log directory creation
|
|
9
|
+
*
|
|
10
|
+
* @module core/progress/error-logger
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Error log entry
|
|
14
|
+
*/
|
|
15
|
+
export interface ErrorLogEntry {
|
|
16
|
+
timestamp: string;
|
|
17
|
+
projectKey: string;
|
|
18
|
+
error: string;
|
|
19
|
+
suggestion?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Error logger options
|
|
23
|
+
*/
|
|
24
|
+
export interface ErrorLoggerOptions {
|
|
25
|
+
/** Log file path (default: .specweave/logs/import-errors.log) */
|
|
26
|
+
logFile?: string;
|
|
27
|
+
/** Project root directory */
|
|
28
|
+
projectRoot?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Log error to file
|
|
32
|
+
*
|
|
33
|
+
* @param projectKey Project identifier
|
|
34
|
+
* @param error Error object or message
|
|
35
|
+
* @param options Logger options
|
|
36
|
+
*/
|
|
37
|
+
export declare function logError(projectKey: string, error: Error | string, options?: ErrorLoggerOptions): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Read error log
|
|
40
|
+
*
|
|
41
|
+
* @param options Logger options
|
|
42
|
+
* @returns Array of error log entries
|
|
43
|
+
*/
|
|
44
|
+
export declare function readErrorLog(options?: ErrorLoggerOptions): Promise<ErrorLogEntry[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Clear error log
|
|
47
|
+
*
|
|
48
|
+
* @param options Logger options
|
|
49
|
+
*/
|
|
50
|
+
export declare function clearErrorLog(options?: ErrorLoggerOptions): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Get error count from log
|
|
53
|
+
*
|
|
54
|
+
* @param options Logger options
|
|
55
|
+
* @returns Number of errors in log
|
|
56
|
+
*/
|
|
57
|
+
export declare function getErrorCount(options?: ErrorLoggerOptions): Promise<number>;
|
|
58
|
+
//# sourceMappingURL=error-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-logger.d.ts","sourceRoot":"","sources":["../../../../src/core/progress/error-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,GAAG,MAAM,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA4B7F;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOnF;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Logger - Comprehensive error logging for batch operations
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - File-based error logging
|
|
6
|
+
* - Timestamped error records
|
|
7
|
+
* - Structured error format
|
|
8
|
+
* - Automatic log directory creation
|
|
9
|
+
*
|
|
10
|
+
* @module core/progress/error-logger
|
|
11
|
+
*/
|
|
12
|
+
import { promises as fs } from 'fs';
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
import { existsSync } from 'fs';
|
|
15
|
+
import { mkdirpSync } from '../../utils/fs-native.js';
|
|
16
|
+
/**
|
|
17
|
+
* Get default error log file path
|
|
18
|
+
*/
|
|
19
|
+
function getDefaultLogPath(projectRoot) {
|
|
20
|
+
return join(projectRoot, '.specweave', 'logs', 'import-errors.log');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Log error to file
|
|
24
|
+
*
|
|
25
|
+
* @param projectKey Project identifier
|
|
26
|
+
* @param error Error object or message
|
|
27
|
+
* @param options Logger options
|
|
28
|
+
*/
|
|
29
|
+
export async function logError(projectKey, error, options = {}) {
|
|
30
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
31
|
+
const logFile = options.logFile ?? getDefaultLogPath(projectRoot);
|
|
32
|
+
const logDir = join(projectRoot, '.specweave', 'logs');
|
|
33
|
+
// Ensure log directory exists
|
|
34
|
+
mkdirpSync(logDir);
|
|
35
|
+
// Create error entry
|
|
36
|
+
const entry = {
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
projectKey,
|
|
39
|
+
error: error instanceof Error ? error.message : error
|
|
40
|
+
};
|
|
41
|
+
// Format log line
|
|
42
|
+
const logLine = `[${entry.timestamp}] ${entry.projectKey}: ${entry.error}\n`;
|
|
43
|
+
// Append to log file
|
|
44
|
+
await fs.appendFile(logFile, logLine, 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Read error log
|
|
48
|
+
*
|
|
49
|
+
* @param options Logger options
|
|
50
|
+
* @returns Array of error log entries
|
|
51
|
+
*/
|
|
52
|
+
export async function readErrorLog(options = {}) {
|
|
53
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
54
|
+
const logFile = options.logFile ?? getDefaultLogPath(projectRoot);
|
|
55
|
+
if (!existsSync(logFile)) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const content = await fs.readFile(logFile, 'utf-8');
|
|
59
|
+
const lines = content.split('\n').filter(line => line.trim());
|
|
60
|
+
return lines.map(line => {
|
|
61
|
+
// Parse log line: [timestamp] projectKey: error
|
|
62
|
+
const match = line.match(/^\[([^\]]+)\]\s+([^:]+):\s+(.+)$/);
|
|
63
|
+
if (!match) {
|
|
64
|
+
return {
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
projectKey: 'UNKNOWN',
|
|
67
|
+
error: line
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
timestamp: match[1],
|
|
72
|
+
projectKey: match[2].trim(),
|
|
73
|
+
error: match[3].trim()
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Clear error log
|
|
79
|
+
*
|
|
80
|
+
* @param options Logger options
|
|
81
|
+
*/
|
|
82
|
+
export async function clearErrorLog(options = {}) {
|
|
83
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
84
|
+
const logFile = options.logFile ?? getDefaultLogPath(projectRoot);
|
|
85
|
+
if (existsSync(logFile)) {
|
|
86
|
+
await fs.unlink(logFile);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get error count from log
|
|
91
|
+
*
|
|
92
|
+
* @param options Logger options
|
|
93
|
+
* @returns Number of errors in log
|
|
94
|
+
*/
|
|
95
|
+
export async function getErrorCount(options = {}) {
|
|
96
|
+
const entries = await readErrorLog(options);
|
|
97
|
+
return entries.length;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=error-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-logger.js","sourceRoot":"","sources":["../../../../src/core/progress/error-logger.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.14",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
# Detects if documentation was changed during implementation
|
|
6
6
|
# Triggers review workflow if needed
|
|
7
7
|
|
|
8
|
-
set
|
|
8
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
9
|
+
|
|
10
|
+
# EMERGENCY KILL SWITCH
|
|
11
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
9
14
|
|
|
10
15
|
# Find project root by searching upward for .specweave/ directory
|
|
11
16
|
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
@@ -77,3 +82,6 @@ if [ -n "$DOC_CHANGES" ]; then
|
|
|
77
82
|
mkdir -p "$LOGS_DIR"
|
|
78
83
|
echo "[$(date)] Documentation changed: $DOC_CHANGES" >> "$LOGS_DIR/hooks.log"
|
|
79
84
|
fi
|
|
85
|
+
|
|
86
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
87
|
+
exit 0
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Docs-Changed Hook
|
|
4
|
+
# Runs after file changes are detected
|
|
5
|
+
# Detects if documentation was changed during implementation
|
|
6
|
+
# Triggers review workflow if needed
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
# Find project root by searching upward for .specweave/ directory
|
|
11
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
12
|
+
find_project_root() {
|
|
13
|
+
local dir="$1"
|
|
14
|
+
while [ "$dir" != "/" ]; do
|
|
15
|
+
if [ -d "$dir/.specweave" ]; then
|
|
16
|
+
echo "$dir"
|
|
17
|
+
return 0
|
|
18
|
+
fi
|
|
19
|
+
dir="$(dirname "$dir")"
|
|
20
|
+
done
|
|
21
|
+
# Fallback: try current directory
|
|
22
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
23
|
+
pwd
|
|
24
|
+
else
|
|
25
|
+
echo "$(pwd)"
|
|
26
|
+
fi
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
30
|
+
cd "$PROJECT_ROOT"
|
|
31
|
+
|
|
32
|
+
# Colors
|
|
33
|
+
RED='\033[0;31m'
|
|
34
|
+
YELLOW='\033[1;33m'
|
|
35
|
+
NC='\033[0m'
|
|
36
|
+
|
|
37
|
+
# Get changed files (git)
|
|
38
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
39
|
+
# Not a git repository, skip
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
CHANGED_FILES=$(git diff --name-only HEAD 2>/dev/null || echo "")
|
|
44
|
+
|
|
45
|
+
if [ -z "$CHANGED_FILES" ]; then
|
|
46
|
+
# No changes
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Check if any documentation files changed
|
|
51
|
+
DOC_CHANGES=$(echo "$CHANGED_FILES" | grep -E '\.specweave/(docs|increments/.*/.*\.md)' || true)
|
|
52
|
+
|
|
53
|
+
if [ -n "$DOC_CHANGES" ]; then
|
|
54
|
+
echo -e "${RED}⚠️ Documentation changed during implementation${NC}"
|
|
55
|
+
echo ""
|
|
56
|
+
echo "📋 Files changed:"
|
|
57
|
+
echo "$DOC_CHANGES" | sed 's/^/ /'
|
|
58
|
+
echo ""
|
|
59
|
+
echo -e "${YELLOW}🔔 Recommended actions:${NC}"
|
|
60
|
+
echo " 1. Review documentation changes"
|
|
61
|
+
echo " 2. Update tasks.md if architecture changed"
|
|
62
|
+
echo " 3. Type /review-docs to see full impact"
|
|
63
|
+
echo ""
|
|
64
|
+
|
|
65
|
+
# Play notification sound
|
|
66
|
+
case "$(uname -s)" in
|
|
67
|
+
Darwin)
|
|
68
|
+
afplay /System/Library/Sounds/Ping.aiff 2>/dev/null &
|
|
69
|
+
;;
|
|
70
|
+
Linux)
|
|
71
|
+
paplay /usr/share/sounds/freedesktop/stereo/dialog-warning.oga 2>/dev/null || true
|
|
72
|
+
;;
|
|
73
|
+
esac
|
|
74
|
+
|
|
75
|
+
# Log to hooks log
|
|
76
|
+
LOGS_DIR=".specweave/logs"
|
|
77
|
+
mkdir -p "$LOGS_DIR"
|
|
78
|
+
echo "[$(date)] Documentation changed: $DOC_CHANGES" >> "$LOGS_DIR/hooks.log"
|
|
79
|
+
fi
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
# 2. Log the question/requirement
|
|
9
9
|
# 3. Record in current increment's work log (if applicable)
|
|
10
10
|
|
|
11
|
-
set
|
|
11
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
12
|
+
|
|
13
|
+
# EMERGENCY KILL SWITCH
|
|
14
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
12
17
|
|
|
13
18
|
# Find project root by searching upward for .specweave/ directory
|
|
14
19
|
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
@@ -73,3 +78,6 @@ if [ -n "$CURRENT_WORK" ] && [ -d "$CURRENT_WORK" ]; then
|
|
|
73
78
|
fi
|
|
74
79
|
|
|
75
80
|
echo "✅ Hook complete"
|
|
81
|
+
|
|
82
|
+
# ALWAYS exit 0 - NEVER let hook errors crash Claude Code
|
|
83
|
+
exit 0
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Human-Input-Required Hook
|
|
4
|
+
# Runs when Claude needs clarification or approval
|
|
5
|
+
#
|
|
6
|
+
# Actions:
|
|
7
|
+
# 1. Play notification sound (Ping.aiff)
|
|
8
|
+
# 2. Log the question/requirement
|
|
9
|
+
# 3. Record in current increment's work log (if applicable)
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
# Find project root by searching upward for .specweave/ directory
|
|
14
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
15
|
+
find_project_root() {
|
|
16
|
+
local dir="$1"
|
|
17
|
+
while [ "$dir" != "/" ]; do
|
|
18
|
+
if [ -d "$dir/.specweave" ]; then
|
|
19
|
+
echo "$dir"
|
|
20
|
+
return 0
|
|
21
|
+
fi
|
|
22
|
+
dir="$(dirname "$dir")"
|
|
23
|
+
done
|
|
24
|
+
# Fallback: try current directory
|
|
25
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
26
|
+
pwd
|
|
27
|
+
else
|
|
28
|
+
echo "$(pwd)"
|
|
29
|
+
fi
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
33
|
+
cd "$PROJECT_ROOT"
|
|
34
|
+
|
|
35
|
+
# Get question/requirement (passed as argument or default)
|
|
36
|
+
QUESTION="${1:-User input required}"
|
|
37
|
+
|
|
38
|
+
echo "❓ Human input required"
|
|
39
|
+
|
|
40
|
+
# 1. Play notification sound (cross-platform)
|
|
41
|
+
play_sound() {
|
|
42
|
+
case "$(uname -s)" in
|
|
43
|
+
Darwin)
|
|
44
|
+
afplay /System/Library/Sounds/Ping.aiff 2>/dev/null &
|
|
45
|
+
;;
|
|
46
|
+
Linux)
|
|
47
|
+
paplay /usr/share/sounds/freedesktop/stereo/dialog-question.oga 2>/dev/null || \
|
|
48
|
+
aplay /usr/share/sounds/alsa/Side_Left.wav 2>/dev/null || true
|
|
49
|
+
;;
|
|
50
|
+
MINGW*|MSYS*|CYGWIN*)
|
|
51
|
+
powershell -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\notify.wav').PlaySync();" 2>/dev/null || true
|
|
52
|
+
;;
|
|
53
|
+
esac
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
play_sound &
|
|
57
|
+
|
|
58
|
+
# 2. Log to main hooks log
|
|
59
|
+
LOGS_DIR=".specweave/logs"
|
|
60
|
+
mkdir -p "$LOGS_DIR"
|
|
61
|
+
echo "[$(date)] Human input required: $QUESTION" >> "$LOGS_DIR/hooks.log"
|
|
62
|
+
|
|
63
|
+
# 3. Log to current work context (if exists)
|
|
64
|
+
CURRENT_WORK=$(find .specweave/work -maxdepth 1 -type d -name "current-*" | head -1 || true)
|
|
65
|
+
|
|
66
|
+
if [ -n "$CURRENT_WORK" ] && [ -d "$CURRENT_WORK" ]; then
|
|
67
|
+
echo "" >> "$CURRENT_WORK/notes.md"
|
|
68
|
+
echo "## Input Required ($(date +%Y-%m-%d\ %H:%M))" >> "$CURRENT_WORK/notes.md"
|
|
69
|
+
echo "" >> "$CURRENT_WORK/notes.md"
|
|
70
|
+
echo "$QUESTION" >> "$CURRENT_WORK/notes.md"
|
|
71
|
+
echo "" >> "$CURRENT_WORK/notes.md"
|
|
72
|
+
echo "📝 Logged to $CURRENT_WORK/notes.md"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo "✅ Hook complete"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SpecWeave Post-First-Increment Hook
|
|
3
|
+
#
|
|
4
|
+
# Triggers after the first increment is completed
|
|
5
|
+
# Congratulates the user on completing their first increment
|
|
6
|
+
#
|
|
7
|
+
# NON-INTERACTIVE: Just shows a message (hooks run in background)
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# Get project root (where .specweave/ lives)
|
|
12
|
+
PROJECT_ROOT="$(pwd)"
|
|
13
|
+
|
|
14
|
+
# Check if .specweave directory exists
|
|
15
|
+
if [ ! -d ".specweave" ]; then
|
|
16
|
+
# Not in SpecWeave project, skip
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Check if this is the first increment completion
|
|
21
|
+
# Count completed increments in .specweave/increments/
|
|
22
|
+
COMPLETED_COUNT=0
|
|
23
|
+
if [ -d ".specweave/increments" ]; then
|
|
24
|
+
# Count directories that have COMPLETION-REPORT.md or completion metadata
|
|
25
|
+
for inc_dir in .specweave/increments/[0-9][0-9][0-9][0-9]-*/; do
|
|
26
|
+
if [ -d "$inc_dir" ]; then
|
|
27
|
+
if [ -f "${inc_dir}reports/COMPLETION-REPORT.md" ] || \
|
|
28
|
+
[ -f "${inc_dir}COMPLETION-SUMMARY.md" ] || \
|
|
29
|
+
([ -f "${inc_dir}metadata.json" ] && grep -q '"status".*"completed"' "${inc_dir}metadata.json" 2>/dev/null); then
|
|
30
|
+
COMPLETED_COUNT=$((COMPLETED_COUNT + 1))
|
|
31
|
+
fi
|
|
32
|
+
fi
|
|
33
|
+
done
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Only trigger on first completion
|
|
37
|
+
if [ "$COMPLETED_COUNT" -ne 1 ]; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Show congratulations message (non-interactive)
|
|
42
|
+
echo ""
|
|
43
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
44
|
+
echo "🎉 Congratulations! You completed your first increment!"
|
|
45
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
46
|
+
echo ""
|
|
47
|
+
echo "✅ Your increment has been documented in:"
|
|
48
|
+
echo " .specweave/increments/[increment-id]/"
|
|
49
|
+
echo ""
|
|
50
|
+
echo "📚 View your documentation:"
|
|
51
|
+
echo " - Specs: .specweave/docs/internal/specs/"
|
|
52
|
+
echo " - Architecture: .specweave/docs/internal/architecture/"
|
|
53
|
+
echo ""
|
|
54
|
+
echo "🚀 Next steps:"
|
|
55
|
+
echo " - Review your increment: /specweave:status"
|
|
56
|
+
echo " - Start next increment: /specweave:increment \"feature name\""
|
|
57
|
+
echo ""
|
|
58
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
59
|
+
echo ""
|
|
60
|
+
|
|
61
|
+
exit 0
|
|
@@ -17,7 +17,12 @@
|
|
|
17
17
|
# Example:
|
|
18
18
|
# ./post-increment-change.sh 0015-hierarchical-sync spec.md
|
|
19
19
|
|
|
20
|
-
set
|
|
20
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
21
|
+
|
|
22
|
+
# EMERGENCY KILL SWITCH
|
|
23
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
21
26
|
|
|
22
27
|
# Find project root
|
|
23
28
|
find_project_root() {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Post-Increment-Change Hook
|
|
4
|
+
# Runs automatically after increment files (spec.md, plan.md, tasks.md) are modified
|
|
5
|
+
#
|
|
6
|
+
# Trigger: File watcher or git hook (pre-commit/post-commit)
|
|
7
|
+
# Purpose: Sync increment file changes to GitHub issues
|
|
8
|
+
#
|
|
9
|
+
# What it does:
|
|
10
|
+
# 1. Detects which file changed (spec.md, plan.md, tasks.md)
|
|
11
|
+
# 2. Invokes GitHub sync for increment changes
|
|
12
|
+
# 3. Updates GitHub issue with scope/plan/task changes
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# ./post-increment-change.sh <incrementId> <changedFile>
|
|
16
|
+
#
|
|
17
|
+
# Example:
|
|
18
|
+
# ./post-increment-change.sh 0015-hierarchical-sync spec.md
|
|
19
|
+
|
|
20
|
+
set -e
|
|
21
|
+
|
|
22
|
+
# Find project root
|
|
23
|
+
find_project_root() {
|
|
24
|
+
local dir="$1"
|
|
25
|
+
while [ "$dir" != "/" ]; do
|
|
26
|
+
if [ -d "$dir/.specweave" ]; then
|
|
27
|
+
echo "$dir"
|
|
28
|
+
return 0
|
|
29
|
+
fi
|
|
30
|
+
dir="$(dirname "$dir")"
|
|
31
|
+
done
|
|
32
|
+
pwd
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
36
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
37
|
+
|
|
38
|
+
# Configuration
|
|
39
|
+
LOGS_DIR=".specweave/logs"
|
|
40
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
41
|
+
|
|
42
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
43
|
+
|
|
44
|
+
# Arguments
|
|
45
|
+
INCREMENT_ID="$1"
|
|
46
|
+
CHANGED_FILE="$2"
|
|
47
|
+
|
|
48
|
+
if [ -z "$INCREMENT_ID" ] || [ -z "$CHANGED_FILE" ]; then
|
|
49
|
+
echo "Usage: $0 <incrementId> <changedFile>" >&2
|
|
50
|
+
echo "Example: $0 0015-hierarchical-sync spec.md" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
echo "[$(date)] 📝 Increment file changed: $CHANGED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
55
|
+
|
|
56
|
+
# Validate changed file
|
|
57
|
+
case "$CHANGED_FILE" in
|
|
58
|
+
spec.md|plan.md|tasks.md)
|
|
59
|
+
;;
|
|
60
|
+
*)
|
|
61
|
+
echo "[$(date)] ⚠️ Unknown file type: $CHANGED_FILE (skipping sync)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
62
|
+
exit 0
|
|
63
|
+
;;
|
|
64
|
+
esac
|
|
65
|
+
|
|
66
|
+
# Check if Node.js available
|
|
67
|
+
if ! command -v node &> /dev/null; then
|
|
68
|
+
echo "[$(date)] ⚠️ Node.js not found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
69
|
+
exit 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Check if GitHub CLI available
|
|
73
|
+
if ! command -v gh &> /dev/null; then
|
|
74
|
+
echo "[$(date)] ℹ️ GitHub CLI not found, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Check if authenticated
|
|
79
|
+
if ! gh auth status &> /dev/null; then
|
|
80
|
+
echo "[$(date)] ℹ️ GitHub CLI not authenticated, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
81
|
+
exit 0
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Sync to GitHub
|
|
85
|
+
echo "[$(date)] 🔄 Syncing $CHANGED_FILE changes to GitHub..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
86
|
+
|
|
87
|
+
node dist/plugins/specweave-github/lib/github-sync-increment-changes.js "$INCREMENT_ID" "$CHANGED_FILE" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
88
|
+
echo "[$(date)] ⚠️ Failed to sync increment changes (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
echo "[$(date)] ✅ Post-increment-change hook complete" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
92
|
+
|
|
93
|
+
# Update status line cache (increment changed)
|
|
94
|
+
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
95
|
+
bash "$HOOK_DIR/lib/update-status-line.sh" 2>/dev/null || true
|
|
96
|
+
|
|
97
|
+
# Return success (non-blocking)
|
|
98
|
+
exit 0
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
#
|
|
6
6
|
# This hook closes GitHub issues automatically when increments complete
|
|
7
7
|
|
|
8
|
-
set
|
|
8
|
+
set +e # EMERGENCY FIX: Prevents Claude Code crashes
|
|
9
|
+
|
|
10
|
+
# EMERGENCY KILL SWITCH
|
|
11
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
9
14
|
|
|
10
15
|
HOOK_NAME="post-increment-completion"
|
|
11
16
|
INCREMENT_ID="${1:-}"
|