@mindfoldhq/trellis 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +110 -0
- package/README.md +149 -0
- package/bin/trellis.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +42 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +236 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/configurators/claude.d.ts +35 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +83 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/cursor.d.ts +8 -0
- package/dist/configurators/cursor.d.ts.map +1 -0
- package/dist/configurators/cursor.js +22 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/templates.d.ts +40 -0
- package/dist/configurators/templates.d.ts.map +1 -0
- package/dist/configurators/templates.js +67 -0
- package/dist/configurators/templates.js.map +1 -0
- package/dist/configurators/workflow.d.ts +16 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +169 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +69 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +80 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/agents/check.txt +120 -0
- package/dist/templates/agents/debug.txt +121 -0
- package/dist/templates/agents/dispatch.txt +201 -0
- package/dist/templates/agents/implement.txt +114 -0
- package/dist/templates/agents/index.d.ts +35 -0
- package/dist/templates/agents/index.d.ts.map +1 -0
- package/dist/templates/agents/index.js +71 -0
- package/dist/templates/agents/index.js.map +1 -0
- package/dist/templates/agents/research.txt +258 -0
- package/dist/templates/commands/claude/start.md.txt +127 -0
- package/dist/templates/commands/common/before-backend-dev.txt +13 -0
- package/dist/templates/commands/common/before-frontend-dev.txt +13 -0
- package/dist/templates/commands/common/break-loop.txt +107 -0
- package/dist/templates/commands/common/check-backend.txt +13 -0
- package/dist/templates/commands/common/check-cross-layer.txt +153 -0
- package/dist/templates/commands/common/check-frontend.txt +13 -0
- package/dist/templates/commands/common/create-command.txt +154 -0
- package/dist/templates/commands/common/finish-work.txt +129 -0
- package/dist/templates/commands/common/integrate-skill.txt +219 -0
- package/dist/templates/commands/common/onboard-developer.txt +355 -0
- package/dist/templates/commands/common/record-agent-flow.txt +62 -0
- package/dist/templates/commands/cursor/start.md.txt +94 -0
- package/dist/templates/commands/index.d.ts +46 -0
- package/dist/templates/commands/index.d.ts.map +1 -0
- package/dist/templates/commands/index.js +151 -0
- package/dist/templates/commands/index.js.map +1 -0
- package/dist/templates/extract.d.ts +22 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +34 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/hooks/index.d.ts +33 -0
- package/dist/templates/hooks/index.d.ts.map +1 -0
- package/dist/templates/hooks/index.js +53 -0
- package/dist/templates/hooks/index.js.map +1 -0
- package/dist/templates/hooks/inject-subagent-context.py +620 -0
- package/dist/templates/hooks/settings.json +16 -0
- package/dist/templates/markdown/agent-traces-index.md.txt +124 -0
- package/dist/templates/markdown/agents.md.txt +18 -0
- package/dist/templates/markdown/gitignore.txt +3 -0
- package/dist/templates/markdown/index.d.ts +26 -0
- package/dist/templates/markdown/index.d.ts.map +1 -0
- package/dist/templates/markdown/index.js +33 -0
- package/dist/templates/markdown/index.js.map +1 -0
- package/dist/templates/markdown/init-agent.md.txt +315 -0
- package/dist/templates/markdown/structure/backend/database-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/backend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/structure/backend/error-handling.md.txt +51 -0
- package/dist/templates/markdown/structure/backend/index.md.txt +38 -0
- package/dist/templates/markdown/structure/backend/logging-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/backend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/component-guidelines.md.txt +59 -0
- package/dist/templates/markdown/structure/frontend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/structure/frontend/hook-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/index.md.txt +39 -0
- package/dist/templates/markdown/structure/frontend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/state-management.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/type-safety.md.txt +51 -0
- package/dist/templates/markdown/structure/guides/code-reuse-thinking-guide.md.txt +92 -0
- package/dist/templates/markdown/structure/guides/cross-layer-thinking-guide.md.txt +94 -0
- package/dist/templates/markdown/structure/guides/index.md.txt +79 -0
- package/dist/templates/markdown/workflow.md.txt +335 -0
- package/dist/templates/scripts/add-session.sh.txt +384 -0
- package/dist/templates/scripts/common/developer.sh.txt +130 -0
- package/dist/templates/scripts/common/git-context.sh.txt +237 -0
- package/dist/templates/scripts/common/paths.sh.txt +201 -0
- package/dist/templates/scripts/create-bootstrap.sh.txt +298 -0
- package/dist/templates/scripts/feature.sh.txt +700 -0
- package/dist/templates/scripts/get-context.sh.txt +7 -0
- package/dist/templates/scripts/get-developer.sh.txt +15 -0
- package/dist/templates/scripts/index.d.ts +25 -0
- package/dist/templates/scripts/index.d.ts.map +1 -0
- package/dist/templates/scripts/index.js +28 -0
- package/dist/templates/scripts/index.js.map +1 -0
- package/dist/templates/scripts/init-developer.sh.txt +34 -0
- package/dist/types/ai-tools.d.ts +35 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +31 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/utils/file-writer.d.ts +23 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +140 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/project-detector.d.ts +16 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +186 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Git and Session Context utilities
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# ./.trellis/scripts/common/git-context.sh # Full context output
|
|
6
|
+
# ./.trellis/scripts/common/git-context.sh --json # JSON format
|
|
7
|
+
#
|
|
8
|
+
# Or source in other scripts:
|
|
9
|
+
# source "$(dirname "$0")/common/git-context.sh"
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
source "$COMMON_DIR/paths.sh"
|
|
15
|
+
source "$COMMON_DIR/developer.sh"
|
|
16
|
+
|
|
17
|
+
# =============================================================================
|
|
18
|
+
# JSON Output
|
|
19
|
+
# =============================================================================
|
|
20
|
+
|
|
21
|
+
output_json() {
|
|
22
|
+
local repo_root=$(get_repo_root)
|
|
23
|
+
local developer=$(get_developer "$repo_root")
|
|
24
|
+
local features_dir=$(get_features_dir "$repo_root")
|
|
25
|
+
local progress_file=$(get_active_progress_file "$repo_root")
|
|
26
|
+
local progress_lines=0
|
|
27
|
+
local progress_relative=""
|
|
28
|
+
|
|
29
|
+
if [[ -n "$progress_file" ]]; then
|
|
30
|
+
progress_lines=$(count_lines "$progress_file")
|
|
31
|
+
progress_relative="$DIR_WORKFLOW/$DIR_PROGRESS/$developer/$(basename "$progress_file")"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
local branch=$(git branch --show-current 2>/dev/null || echo "unknown")
|
|
35
|
+
local git_status=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
36
|
+
local is_clean="true"
|
|
37
|
+
[[ "$git_status" != "0" ]] && is_clean="false"
|
|
38
|
+
|
|
39
|
+
# Build commits JSON
|
|
40
|
+
local commits_json="["
|
|
41
|
+
local first=true
|
|
42
|
+
while IFS= read -r line; do
|
|
43
|
+
local hash=$(echo "$line" | cut -d' ' -f1)
|
|
44
|
+
local msg=$(echo "$line" | cut -d' ' -f2-)
|
|
45
|
+
msg=$(echo "$msg" | sed 's/"/\\"/g')
|
|
46
|
+
if [[ "$first" == "true" ]]; then
|
|
47
|
+
first=false
|
|
48
|
+
else
|
|
49
|
+
commits_json+=","
|
|
50
|
+
fi
|
|
51
|
+
commits_json+="{\"hash\":\"$hash\",\"message\":\"$msg\"}"
|
|
52
|
+
done < <(git log --oneline -5 2>/dev/null || echo "")
|
|
53
|
+
commits_json+="]"
|
|
54
|
+
|
|
55
|
+
# Build features JSON
|
|
56
|
+
local features_json="["
|
|
57
|
+
first=true
|
|
58
|
+
if [[ -d "$features_dir" ]]; then
|
|
59
|
+
for f in "$features_dir"/*.json; do
|
|
60
|
+
if [[ -f "$f" ]]; then
|
|
61
|
+
local filename=$(basename "$f")
|
|
62
|
+
local name=$(echo "$filename" | sed 's/^[0-9]*-//' | sed 's/\.json$//')
|
|
63
|
+
local status="unknown"
|
|
64
|
+
if command -v jq &> /dev/null; then
|
|
65
|
+
status=$(jq -r '.status // "unknown"' "$f")
|
|
66
|
+
fi
|
|
67
|
+
if [[ "$first" == "true" ]]; then
|
|
68
|
+
first=false
|
|
69
|
+
else
|
|
70
|
+
features_json+=","
|
|
71
|
+
fi
|
|
72
|
+
features_json+="{\"file\":\"$filename\",\"name\":\"$name\",\"status\":\"$status\"}"
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
fi
|
|
76
|
+
features_json+="]"
|
|
77
|
+
|
|
78
|
+
cat << EOF
|
|
79
|
+
{
|
|
80
|
+
"developer": "$developer",
|
|
81
|
+
"git": {
|
|
82
|
+
"branch": "$branch",
|
|
83
|
+
"isClean": $is_clean,
|
|
84
|
+
"uncommittedChanges": $git_status,
|
|
85
|
+
"recentCommits": $commits_json
|
|
86
|
+
},
|
|
87
|
+
"features": {
|
|
88
|
+
"active": $features_json,
|
|
89
|
+
"directory": "$DIR_WORKFLOW/$DIR_PROGRESS/$developer/$DIR_FEATURES"
|
|
90
|
+
},
|
|
91
|
+
"progress": {
|
|
92
|
+
"file": "$progress_relative",
|
|
93
|
+
"lines": $progress_lines,
|
|
94
|
+
"nearLimit": $([ "$progress_lines" -gt 1800 ] && echo "true" || echo "false")
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
EOF
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# =============================================================================
|
|
101
|
+
# Text Output
|
|
102
|
+
# =============================================================================
|
|
103
|
+
|
|
104
|
+
output_text() {
|
|
105
|
+
local repo_root=$(get_repo_root)
|
|
106
|
+
local developer=$(get_developer "$repo_root")
|
|
107
|
+
|
|
108
|
+
echo "========================================"
|
|
109
|
+
echo "SESSION CONTEXT"
|
|
110
|
+
echo "========================================"
|
|
111
|
+
echo ""
|
|
112
|
+
|
|
113
|
+
echo "## DEVELOPER"
|
|
114
|
+
if [[ -z "$developer" ]]; then
|
|
115
|
+
echo "ERROR: Not initialized. Run: ./$DIR_WORKFLOW/$DIR_SCRIPTS/init-developer.sh <name>"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
echo "Name: $developer"
|
|
119
|
+
echo ""
|
|
120
|
+
|
|
121
|
+
echo "## GIT STATUS"
|
|
122
|
+
echo "Branch: $(git branch --show-current 2>/dev/null || echo 'unknown')"
|
|
123
|
+
local status_count=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
124
|
+
if [[ "$status_count" == "0" ]]; then
|
|
125
|
+
echo "Working directory: Clean"
|
|
126
|
+
else
|
|
127
|
+
echo "Working directory: $status_count uncommitted change(s)"
|
|
128
|
+
echo ""
|
|
129
|
+
echo "Changes:"
|
|
130
|
+
git status --short 2>/dev/null | head -10
|
|
131
|
+
fi
|
|
132
|
+
echo ""
|
|
133
|
+
|
|
134
|
+
echo "## RECENT COMMITS"
|
|
135
|
+
git log --oneline -5 2>/dev/null || echo "(no commits)"
|
|
136
|
+
echo ""
|
|
137
|
+
|
|
138
|
+
echo "## CURRENT FEATURE"
|
|
139
|
+
local current_feature=$(get_current_feature "$repo_root")
|
|
140
|
+
if [[ -n "$current_feature" ]]; then
|
|
141
|
+
local current_feature_dir="$repo_root/$current_feature"
|
|
142
|
+
local feature_json="$current_feature_dir/feature.json"
|
|
143
|
+
echo "Path: $current_feature"
|
|
144
|
+
|
|
145
|
+
if [[ -f "$feature_json" ]]; then
|
|
146
|
+
if command -v jq &> /dev/null; then
|
|
147
|
+
local f_name=$(jq -r '.name // .id // "unknown"' "$feature_json")
|
|
148
|
+
local f_status=$(jq -r '.status // "unknown"' "$feature_json")
|
|
149
|
+
local f_created=$(jq -r '.createdAt // "unknown"' "$feature_json")
|
|
150
|
+
local f_desc=$(jq -r '.description // ""' "$feature_json")
|
|
151
|
+
echo "Name: $f_name"
|
|
152
|
+
echo "Status: $f_status"
|
|
153
|
+
echo "Created: $f_created"
|
|
154
|
+
if [[ -n "$f_desc" ]]; then
|
|
155
|
+
echo "Description: $f_desc"
|
|
156
|
+
fi
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# Check for prd.md
|
|
161
|
+
if [[ -f "$current_feature_dir/prd.md" ]]; then
|
|
162
|
+
echo ""
|
|
163
|
+
echo "[!] This feature has prd.md - read it for task details"
|
|
164
|
+
fi
|
|
165
|
+
else
|
|
166
|
+
echo "(none)"
|
|
167
|
+
fi
|
|
168
|
+
echo ""
|
|
169
|
+
|
|
170
|
+
echo "## ACTIVE FEATURES"
|
|
171
|
+
local features_dir=$(get_features_dir "$repo_root")
|
|
172
|
+
local feature_count=0
|
|
173
|
+
if [[ -d "$features_dir" ]]; then
|
|
174
|
+
for d in "$features_dir"/*/; do
|
|
175
|
+
if [[ -d "$d" ]] && [[ "$(basename "$d")" != "archive" ]]; then
|
|
176
|
+
local dir_name=$(basename "$d")
|
|
177
|
+
local f_json="$d/feature.json"
|
|
178
|
+
local status="unknown"
|
|
179
|
+
if [[ -f "$f_json" ]] && command -v jq &> /dev/null; then
|
|
180
|
+
status=$(jq -r '.status // "unknown"' "$f_json")
|
|
181
|
+
fi
|
|
182
|
+
echo "- $dir_name/ ($status)"
|
|
183
|
+
((feature_count++))
|
|
184
|
+
fi
|
|
185
|
+
done
|
|
186
|
+
fi
|
|
187
|
+
if [[ $feature_count -eq 0 ]]; then
|
|
188
|
+
echo "(no active features)"
|
|
189
|
+
fi
|
|
190
|
+
echo "Total: $feature_count active feature(s)"
|
|
191
|
+
echo ""
|
|
192
|
+
|
|
193
|
+
echo "## PROGRESS FILE"
|
|
194
|
+
local progress_file=$(get_active_progress_file "$repo_root")
|
|
195
|
+
if [[ -n "$progress_file" ]]; then
|
|
196
|
+
local lines=$(count_lines "$progress_file")
|
|
197
|
+
local relative="$DIR_WORKFLOW/$DIR_PROGRESS/$developer/$(basename "$progress_file")"
|
|
198
|
+
echo "Active file: $relative"
|
|
199
|
+
echo "Line count: $lines / 2000"
|
|
200
|
+
if [[ "$lines" -gt 1800 ]]; then
|
|
201
|
+
echo "[!] WARNING: Approaching 2000 line limit!"
|
|
202
|
+
fi
|
|
203
|
+
else
|
|
204
|
+
echo "No progress file found"
|
|
205
|
+
fi
|
|
206
|
+
echo ""
|
|
207
|
+
|
|
208
|
+
echo "## PATHS"
|
|
209
|
+
echo "Progress dir: $DIR_WORKFLOW/$DIR_PROGRESS/$developer/"
|
|
210
|
+
echo "Features dir: $DIR_WORKFLOW/$DIR_PROGRESS/$developer/$DIR_FEATURES/"
|
|
211
|
+
echo "Index file: $DIR_WORKFLOW/$DIR_PROGRESS/$developer/index.md"
|
|
212
|
+
echo ""
|
|
213
|
+
|
|
214
|
+
echo "========================================"
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# =============================================================================
|
|
218
|
+
# Main Entry
|
|
219
|
+
# =============================================================================
|
|
220
|
+
|
|
221
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
222
|
+
case "${1:-}" in
|
|
223
|
+
--json|-j)
|
|
224
|
+
output_json
|
|
225
|
+
;;
|
|
226
|
+
--help|-h)
|
|
227
|
+
echo "Get Session Context for AI Agent"
|
|
228
|
+
echo ""
|
|
229
|
+
echo "Usage:"
|
|
230
|
+
echo " $0 Output context in text format"
|
|
231
|
+
echo " $0 --json Output context in JSON format"
|
|
232
|
+
;;
|
|
233
|
+
*)
|
|
234
|
+
output_text
|
|
235
|
+
;;
|
|
236
|
+
esac
|
|
237
|
+
fi
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Common path utilities for Trellis workflow
|
|
3
|
+
#
|
|
4
|
+
# Usage: source this file in other scripts
|
|
5
|
+
# source "$(dirname "$0")/common/paths.sh"
|
|
6
|
+
#
|
|
7
|
+
# Provides:
|
|
8
|
+
# get_repo_root - Get repository root directory
|
|
9
|
+
# get_developer - Get developer name
|
|
10
|
+
# get_features_dir - Get features directory
|
|
11
|
+
# get_progress_dir - Get progress directory
|
|
12
|
+
# get_active_progress_file - Get current progress file
|
|
13
|
+
|
|
14
|
+
# =============================================================================
|
|
15
|
+
# Path Constants (change here to rename directories)
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
18
|
+
# Directory names
|
|
19
|
+
DIR_WORKFLOW=".trellis"
|
|
20
|
+
DIR_PROGRESS="agent-traces"
|
|
21
|
+
DIR_FEATURES="features"
|
|
22
|
+
DIR_ARCHIVE="archive"
|
|
23
|
+
DIR_STRUCTURE="structure"
|
|
24
|
+
DIR_SCRIPTS="scripts"
|
|
25
|
+
|
|
26
|
+
# File names
|
|
27
|
+
FILE_DEVELOPER=".developer"
|
|
28
|
+
FILE_CURRENT_FEATURE=".current-feature"
|
|
29
|
+
FILE_FEATURE_JSON="feature.json"
|
|
30
|
+
|
|
31
|
+
# =============================================================================
|
|
32
|
+
# Repository Root
|
|
33
|
+
# =============================================================================
|
|
34
|
+
|
|
35
|
+
get_repo_root() {
|
|
36
|
+
# Find the nearest directory containing .trellis/ folder
|
|
37
|
+
# This handles nested git repos correctly (e.g., test project inside another repo)
|
|
38
|
+
local current="$PWD"
|
|
39
|
+
|
|
40
|
+
while [[ "$current" != "/" ]]; do
|
|
41
|
+
if [[ -d "$current/$DIR_WORKFLOW" ]]; then
|
|
42
|
+
echo "$current"
|
|
43
|
+
return
|
|
44
|
+
fi
|
|
45
|
+
current=$(dirname "$current")
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
# Fallback to current directory if no .trellis/ found
|
|
49
|
+
echo "$PWD"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# =============================================================================
|
|
53
|
+
# Developer
|
|
54
|
+
# =============================================================================
|
|
55
|
+
|
|
56
|
+
get_developer() {
|
|
57
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
58
|
+
local dev_file="$repo_root/$DIR_WORKFLOW/$FILE_DEVELOPER"
|
|
59
|
+
|
|
60
|
+
if [[ -f "$dev_file" ]]; then
|
|
61
|
+
grep "^name=" "$dev_file" 2>/dev/null | cut -d'=' -f2
|
|
62
|
+
fi
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
check_developer() {
|
|
66
|
+
local developer=$(get_developer "$1")
|
|
67
|
+
[[ -n "$developer" ]]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# =============================================================================
|
|
71
|
+
# Features Directory
|
|
72
|
+
# =============================================================================
|
|
73
|
+
|
|
74
|
+
get_features_dir() {
|
|
75
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
76
|
+
local developer=$(get_developer "$repo_root")
|
|
77
|
+
|
|
78
|
+
if [[ -n "$developer" ]]; then
|
|
79
|
+
echo "$repo_root/$DIR_WORKFLOW/$DIR_PROGRESS/$developer/$DIR_FEATURES"
|
|
80
|
+
fi
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# =============================================================================
|
|
84
|
+
# Progress Directory
|
|
85
|
+
# =============================================================================
|
|
86
|
+
|
|
87
|
+
get_progress_dir() {
|
|
88
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
89
|
+
local developer=$(get_developer "$repo_root")
|
|
90
|
+
|
|
91
|
+
if [[ -n "$developer" ]]; then
|
|
92
|
+
echo "$repo_root/$DIR_WORKFLOW/$DIR_PROGRESS/$developer"
|
|
93
|
+
fi
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# =============================================================================
|
|
97
|
+
# Progress File
|
|
98
|
+
# =============================================================================
|
|
99
|
+
|
|
100
|
+
get_active_progress_file() {
|
|
101
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
102
|
+
local progress_dir=$(get_progress_dir "$repo_root")
|
|
103
|
+
|
|
104
|
+
if [[ -z "$progress_dir" ]] || [[ ! -d "$progress_dir" ]]; then
|
|
105
|
+
echo ""
|
|
106
|
+
return
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
local latest=""
|
|
110
|
+
local highest=0
|
|
111
|
+
for f in "$progress_dir"/progress-*.md; do
|
|
112
|
+
if [[ -f "$f" ]]; then
|
|
113
|
+
local num=$(basename "$f" | sed 's/progress-//' | sed 's/\.md//')
|
|
114
|
+
if [[ "$num" =~ ^[0-9]+$ ]] && [[ "$num" -gt "$highest" ]]; then
|
|
115
|
+
highest=$num
|
|
116
|
+
latest="$f"
|
|
117
|
+
fi
|
|
118
|
+
fi
|
|
119
|
+
done
|
|
120
|
+
|
|
121
|
+
if [[ -n "$latest" ]]; then
|
|
122
|
+
echo "$latest"
|
|
123
|
+
fi
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
count_lines() {
|
|
127
|
+
local file="$1"
|
|
128
|
+
if [[ -f "$file" ]]; then
|
|
129
|
+
wc -l < "$file" | tr -d ' '
|
|
130
|
+
else
|
|
131
|
+
echo "0"
|
|
132
|
+
fi
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# =============================================================================
|
|
136
|
+
# Current Feature Management
|
|
137
|
+
# =============================================================================
|
|
138
|
+
|
|
139
|
+
# Get .current-feature file path
|
|
140
|
+
_get_current_feature_file() {
|
|
141
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
142
|
+
echo "$repo_root/$DIR_WORKFLOW/$FILE_CURRENT_FEATURE"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# Get current feature directory path (relative to repo_root)
|
|
146
|
+
get_current_feature() {
|
|
147
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
148
|
+
local current_file=$(_get_current_feature_file "$repo_root")
|
|
149
|
+
|
|
150
|
+
if [[ -f "$current_file" ]]; then
|
|
151
|
+
cat "$current_file" 2>/dev/null
|
|
152
|
+
fi
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Get current feature directory absolute path
|
|
156
|
+
get_current_feature_abs() {
|
|
157
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
158
|
+
local relative=$(get_current_feature "$repo_root")
|
|
159
|
+
|
|
160
|
+
if [[ -n "$relative" ]]; then
|
|
161
|
+
echo "$repo_root/$relative"
|
|
162
|
+
fi
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# Set current feature
|
|
166
|
+
# Args: $1 - feature directory path (relative to repo_root)
|
|
167
|
+
set_current_feature() {
|
|
168
|
+
local feature_path="$1"
|
|
169
|
+
local repo_root="${2:-$(get_repo_root)}"
|
|
170
|
+
local current_file=$(_get_current_feature_file "$repo_root")
|
|
171
|
+
|
|
172
|
+
if [[ -z "$feature_path" ]]; then
|
|
173
|
+
echo "Error: feature path is required" >&2
|
|
174
|
+
return 1
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# Verify feature directory exists
|
|
178
|
+
local full_path="$repo_root/$feature_path"
|
|
179
|
+
if [[ ! -d "$full_path" ]]; then
|
|
180
|
+
echo "Error: feature directory not found: $feature_path" >&2
|
|
181
|
+
return 1
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
echo "$feature_path" > "$current_file"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Clear current feature
|
|
188
|
+
clear_current_feature() {
|
|
189
|
+
local repo_root="${1:-$(get_repo_root)}"
|
|
190
|
+
local current_file=$(_get_current_feature_file "$repo_root")
|
|
191
|
+
|
|
192
|
+
if [[ -f "$current_file" ]]; then
|
|
193
|
+
rm -f "$current_file"
|
|
194
|
+
fi
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# Check if has current feature
|
|
198
|
+
has_current_feature() {
|
|
199
|
+
local current=$(get_current_feature "$1")
|
|
200
|
+
[[ -n "$current" ]]
|
|
201
|
+
}
|