@pjmendonca/devflow 1.13.2 → 1.19.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/commands/agent.md +1 -1
- package/.claude/commands/brainstorm.md +28 -0
- package/.claude/commands/bugfix.md +21 -0
- package/.claude/commands/checkpoint.md +0 -1
- package/.claude/commands/collab.md +0 -1
- package/.claude/commands/costs.md +88 -18
- package/.claude/commands/devflow.md +26 -0
- package/.claude/commands/handoff.md +0 -1
- package/.claude/commands/init.md +383 -0
- package/.claude/commands/memory.md +0 -1
- package/.claude/commands/pair.md +0 -1
- package/.claude/commands/review.md +27 -0
- package/.claude/commands/route.md +0 -1
- package/.claude/commands/swarm.md +0 -1
- package/.claude/commands/validate.md +55 -0
- package/.claude/hooks/session-notification.sh +44 -0
- package/.claude/hooks/session-startup.sh +427 -0
- package/.claude/hooks/session-stop.sh +38 -0
- package/.claude/hooks/session_tracker.py +272 -0
- package/.claude/settings.json +38 -0
- package/.claude/skills/brainstorm/SKILL.md +531 -0
- package/.claude/skills/costs/SKILL.md +156 -0
- package/.claude/skills/validate/SKILL.md +101 -0
- package/CHANGELOG.md +284 -0
- package/README.md +207 -10
- package/bin/devflow-install.js +2 -1
- package/bin/devflow.js +4 -0
- package/lib/constants.js +0 -1
- package/lib/exec-python.js +1 -1
- package/package.json +1 -1
- package/tooling/.automation/.checkpoint_lock +1 -0
- package/tooling/.automation/agents/architect.md +19 -0
- package/tooling/.automation/agents/ba.md +19 -0
- package/tooling/.automation/agents/maintainer.md +19 -0
- package/tooling/.automation/agents/pm.md +19 -0
- package/tooling/.automation/agents/reviewer.md +1 -1
- package/tooling/.automation/agents/writer.md +19 -0
- package/tooling/.automation/benchmarks/benchmark_20251230_100119.json +314 -0
- package/tooling/.automation/benchmarks/benchmark_20251230_100216.json +314 -0
- package/tooling/.automation/costs/config.json +31 -0
- package/tooling/.automation/costs/sessions/2025-12-29_20251229_164128.json +22 -0
- package/tooling/.automation/memory/knowledge/kg_integration-test.json +738 -1
- package/tooling/.automation/memory/knowledge/kg_test-story.json +3381 -2
- package/tooling/.automation/memory/shared/shared_integration-test.json +193 -1
- package/tooling/.automation/memory/shared/shared_test-story.json +757 -1
- package/tooling/.automation/memory/shared/shared_test.json +1332 -0
- package/tooling/.automation/memory/shared/shared_validation-check.json +240 -0
- package/tooling/.automation/overrides/templates/architect/cloud-native.yaml +5 -5
- package/tooling/.automation/overrides/templates/architect/enterprise-architect.yaml +23 -5
- package/tooling/.automation/overrides/templates/architect/pragmatic-minimalist.yaml +24 -6
- package/tooling/.automation/overrides/templates/ba/agile-storyteller.yaml +4 -4
- package/tooling/.automation/overrides/templates/ba/domain-expert.yaml +4 -4
- package/tooling/.automation/overrides/templates/ba/requirements-engineer.yaml +4 -4
- package/tooling/.automation/overrides/templates/dev/performance-engineer.yaml +18 -0
- package/tooling/.automation/overrides/templates/dev/rapid-prototyper.yaml +19 -1
- package/tooling/.automation/overrides/templates/dev/security-focused.yaml +18 -0
- package/tooling/.automation/overrides/templates/dev/user-advocate.yaml +54 -0
- package/tooling/.automation/overrides/templates/maintainer/devops-maintainer.yaml +4 -4
- package/tooling/.automation/overrides/templates/maintainer/legacy-steward.yaml +4 -4
- package/tooling/.automation/overrides/templates/maintainer/oss-maintainer.yaml +4 -4
- package/tooling/.automation/overrides/templates/maintainer/reliability-engineer.yaml +55 -0
- package/tooling/.automation/overrides/templates/pm/agile-pm.yaml +4 -4
- package/tooling/.automation/overrides/templates/pm/hybrid-delivery.yaml +3 -3
- package/tooling/.automation/overrides/templates/pm/traditional-pm.yaml +4 -4
- package/tooling/.automation/overrides/templates/reviewer/quick-sanity.yaml +18 -0
- package/tooling/.automation/overrides/templates/reviewer/thorough-critic.yaml +18 -0
- package/tooling/.automation/overrides/templates/sm/agile-coach.yaml +2 -2
- package/tooling/.automation/overrides/templates/sm/startup-pm.yaml +3 -3
- package/tooling/.automation/overrides/templates/writer/api-documentarian.yaml +5 -5
- package/tooling/.automation/overrides/templates/writer/docs-as-code.yaml +4 -4
- package/tooling/.automation/overrides/templates/writer/user-guide-author.yaml +5 -5
- package/tooling/.automation/validation/history/2025-12-29_val_002a28c1.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_01273bb1.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_03369914.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_07a449ba.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_0df1f0a2.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_10ff3d34.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_110771d7.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_13f3a7f9.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_17ba9d21.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_22247089.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_227ea6a4.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_2335d5ae.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_246824bb.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_28b4b9cd.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_2abd12cc.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_2c801b2f.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_2c8cfa8e.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_2ce76eb0.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_30351948.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_30eb7229.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_34df0e77.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_376e4d6a.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_3a4e8a1a.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_3b77a628.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_3ea4e1cf.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_44aacdb4.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_457ddfa8.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_45af6238.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_4735dba1.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_486b203c.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_49dc56cd.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_4d863d6d.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_5149a808.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_52e0bb43.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_585d6319.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_5b2d859a.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_635a7081.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_64df4905.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_70634cee.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_714553f9.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_7f7bfdbf.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_7faad91d.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_81821f8f.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_8249f3c9.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_8422b50f.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_8446c134.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_879f4e26.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_8b6d5bd7.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_8c5cd787.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_91d20bc7.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_958a12b7.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_95d91108.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_980dbb74.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_9e40c79b.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_9f499b7c.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_9f7c3b57.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_a30d5bd4.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_a6eb09c7.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_a86f7b83.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_ad5347e1.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_b0a5a993.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_bcb0192e.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_bf3c9aaa.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_c461ff88.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_c4f4e258.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_c7f0fa6d.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_c911b0e6.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_cc581964.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_cdd5a33b.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_cfd42495.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_d1c7a4ee.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_d2280d0e.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_d2a6ff69.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_d8c53ab2.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_d9c1247a.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_d9d58569.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_dabb4fd9.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_dd8fe359.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_decdffc9.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_e3a95476.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_e776dfca.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_ea70969f.json +59 -0
- package/tooling/.automation/validation/history/2025-12-29_val_ef41ea95.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_f384f9b1.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_f8adc38c.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_fa40b69e.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_fc538d54.json +41 -0
- package/tooling/.automation/validation/history/2025-12-29_val_fe814665.json +32 -0
- package/tooling/.automation/validation/history/2025-12-29_val_ffea4b12.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_02d001e5.json +59 -0
- package/tooling/.automation/validation/history/2025-12-30_val_0b8966dc.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_15455fbf.json +59 -0
- package/tooling/.automation/validation/history/2025-12-30_val_157e34b9.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_28d1d933.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_3442a52c.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_37f1ce1e.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_4f1d8a93.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_56ff1de3.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_664fd4e2.json +41 -0
- package/tooling/.automation/validation/history/2025-12-30_val_66afb0a7.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_7634663c.json +41 -0
- package/tooling/.automation/validation/history/2025-12-30_val_8ea830c3.json +41 -0
- package/tooling/.automation/validation/history/2025-12-30_val_998957c2.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_a52177db.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_a5b65a63.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_ae391d0e.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_c7895339.json +41 -0
- package/tooling/.automation/validation/history/2025-12-30_val_ca416593.json +41 -0
- package/tooling/.automation/validation/history/2025-12-30_val_cee19422.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_ddd4f4e6.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_f2e1394b.json +32 -0
- package/tooling/.automation/validation/history/2025-12-30_val_f4a7fa06.json +41 -0
- package/tooling/.automation/validation/history/2025-12-30_val_ffea3369.json +32 -0
- package/tooling/.automation/validation/history/2026-01-03_val_1287a74c.json +41 -0
- package/tooling/.automation/validation/history/2026-01-03_val_3b24071f.json +32 -0
- package/tooling/.automation/validation/history/2026-01-03_val_44d77573.json +32 -0
- package/tooling/.automation/validation/history/2026-01-03_val_5b31dc51.json +32 -0
- package/tooling/.automation/validation/history/2026-01-03_val_74267244.json +32 -0
- package/tooling/.automation/validation/history/2026-01-03_val_8b2d95c7.json +59 -0
- package/tooling/.automation/validation/history/2026-01-03_val_d875b297.json +41 -0
- package/tooling/.automation/validation-config.yaml +103 -0
- package/tooling/completions/DevflowCompletion.ps1 +21 -21
- package/tooling/completions/_run-story +3 -3
- package/tooling/completions/run-story-completion.bash +8 -8
- package/tooling/docs/DOC-STANDARD.md +14 -14
- package/tooling/docs/stories/.gitkeep +0 -0
- package/tooling/docs/templates/brainstorm-guide.md +314 -0
- package/tooling/docs/templates/migration-spec.md +4 -4
- package/tooling/docs/templates/story.md +66 -0
- package/tooling/scripts/context_checkpoint.py +5 -15
- package/tooling/scripts/cost_dashboard.py +610 -13
- package/tooling/scripts/create-persona.py +1 -12
- package/tooling/scripts/create-persona.sh +44 -44
- package/tooling/scripts/lib/__init__.py +12 -1
- package/tooling/scripts/lib/agent_handoff.py +11 -2
- package/tooling/scripts/lib/agent_router.py +31 -10
- package/tooling/scripts/lib/colors.py +106 -0
- package/tooling/scripts/lib/context_monitor.py +766 -0
- package/tooling/scripts/lib/cost_config.py +229 -10
- package/tooling/scripts/lib/cost_display.py +20 -45
- package/tooling/scripts/lib/cost_tracker.py +462 -15
- package/tooling/scripts/lib/currency_converter.py +28 -5
- package/tooling/scripts/lib/pair_programming.py +102 -3
- package/tooling/scripts/lib/personality_system.py +949 -0
- package/tooling/scripts/lib/platform.py +55 -0
- package/tooling/scripts/lib/shared_memory.py +9 -3
- package/tooling/scripts/lib/swarm_orchestrator.py +514 -75
- package/tooling/scripts/lib/validation_loop.py +1014 -0
- package/tooling/scripts/memory_summarize.py +9 -2
- package/tooling/scripts/new-doc.py +2 -9
- package/tooling/scripts/personalize_agent.py +1 -12
- package/tooling/scripts/rollback-migration.sh +60 -60
- package/tooling/scripts/run-collab.ps1 +16 -16
- package/tooling/scripts/run-collab.py +88 -53
- package/tooling/scripts/run-collab.sh +4 -4
- package/tooling/scripts/run-story.py +278 -20
- package/tooling/scripts/run-story.sh +3 -3
- package/tooling/scripts/setup-checkpoint-service.py +2 -9
- package/tooling/scripts/tech-debt-tracker.py +1 -12
- package/tooling/scripts/test_adversarial_swarm.py +452 -0
- package/tooling/scripts/validate-overrides.py +1 -10
- package/tooling/scripts/validate-overrides.sh +40 -40
- package/tooling/scripts/validate_loop.py +162 -0
- package/tooling/scripts/validate_setup.py +2 -30
- package/.claude/skills/init/SKILL.md +0 -496
|
@@ -19,18 +19,7 @@ import sys
|
|
|
19
19
|
from dataclasses import dataclass, field
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
# Colors for terminal output
|
|
24
|
-
class Colors:
|
|
25
|
-
RED = "\033[0;31m"
|
|
26
|
-
GREEN = "\033[0;32m"
|
|
27
|
-
YELLOW = "\033[1;33m"
|
|
28
|
-
BLUE = "\033[0;34m"
|
|
29
|
-
CYAN = "\033[0;36m"
|
|
30
|
-
MAGENTA = "\033[0;35m"
|
|
31
|
-
BOLD = "\033[1m"
|
|
32
|
-
NC = "\033[0m"
|
|
33
|
-
|
|
22
|
+
from lib.colors import Colors
|
|
34
23
|
|
|
35
24
|
# Persona templates
|
|
36
25
|
PERSONA_TEMPLATES = {
|
|
@@ -44,15 +44,15 @@ prompt() {
|
|
|
44
44
|
local message="$1"
|
|
45
45
|
local default="$2"
|
|
46
46
|
local result
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
if [[ -n "$default" ]]; then
|
|
49
49
|
echo -n -e "${BLUE}${message}${NC} [${default}]: "
|
|
50
50
|
else
|
|
51
51
|
echo -n -e "${BLUE}${message}${NC}: "
|
|
52
52
|
fi
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
read result
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
if [[ -z "$result" && -n "$default" ]]; then
|
|
57
57
|
echo "$default"
|
|
58
58
|
else
|
|
@@ -65,15 +65,15 @@ prompt_list() {
|
|
|
65
65
|
local min_items="${2:-0}"
|
|
66
66
|
local items=()
|
|
67
67
|
local count=0
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
echo -e "${BLUE}${message}${NC}"
|
|
70
70
|
echo " (Enter items one per line, empty line to finish)"
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
while true; do
|
|
73
73
|
((count++))
|
|
74
74
|
echo -n " $count. "
|
|
75
75
|
read item
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
if [[ -z "$item" ]]; then
|
|
78
78
|
if [[ ${#items[@]} -ge $min_items ]]; then
|
|
79
79
|
break
|
|
@@ -83,10 +83,10 @@ prompt_list() {
|
|
|
83
83
|
continue
|
|
84
84
|
fi
|
|
85
85
|
fi
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
items+=("$item")
|
|
88
88
|
done
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
printf '%s\n' "${items[@]}"
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -96,7 +96,7 @@ prompt_list() {
|
|
|
96
96
|
|
|
97
97
|
get_template() {
|
|
98
98
|
local template_name="$1"
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
case "$template_name" in
|
|
101
101
|
developer|dev)
|
|
102
102
|
echo "developer|Software Developer|Writing clean, maintainable code|sonnet"
|
|
@@ -136,9 +136,9 @@ generate_agent_file() {
|
|
|
136
136
|
local model="$4"
|
|
137
137
|
shift 4
|
|
138
138
|
local responsibilities=("${@}")
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
local file="$AGENTS_DIR/${name}.md"
|
|
141
|
-
|
|
141
|
+
|
|
142
142
|
cat > "$file" << EOF
|
|
143
143
|
# ${role} Agent
|
|
144
144
|
|
|
@@ -147,13 +147,13 @@ You are a ${role}. ${focus}
|
|
|
147
147
|
## Responsibilities
|
|
148
148
|
|
|
149
149
|
EOF
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
local count=0
|
|
152
152
|
for resp in "${responsibilities[@]}"; do
|
|
153
153
|
((count++))
|
|
154
154
|
echo "$count. $resp" >> "$file"
|
|
155
155
|
done
|
|
156
|
-
|
|
156
|
+
|
|
157
157
|
cat >> "$file" << 'EOF'
|
|
158
158
|
|
|
159
159
|
## Principles
|
|
@@ -185,25 +185,25 @@ If you sense context is running low, output a warning:
|
|
|
185
185
|
```
|
|
186
186
|
|
|
187
187
|
EOF
|
|
188
|
-
|
|
188
|
+
|
|
189
189
|
echo "## Model" >> "$file"
|
|
190
190
|
echo "" >> "$file"
|
|
191
191
|
echo "Recommended model: \`${model}\`" >> "$file"
|
|
192
192
|
echo "" >> "$file"
|
|
193
|
-
|
|
193
|
+
|
|
194
194
|
echo "$file"
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
generate_override_file() {
|
|
198
198
|
local name="$1"
|
|
199
|
-
|
|
199
|
+
|
|
200
200
|
local file="$OVERRIDES_DIR/${name}.override.yaml"
|
|
201
|
-
|
|
201
|
+
|
|
202
202
|
# Don't overwrite existing
|
|
203
203
|
if [[ -f "$file" ]]; then
|
|
204
204
|
return
|
|
205
205
|
fi
|
|
206
|
-
|
|
206
|
+
|
|
207
207
|
cat > "$file" << EOF
|
|
208
208
|
# ${name^^} Agent Override
|
|
209
209
|
# Customize this agent's behavior without modifying the core agent file
|
|
@@ -228,7 +228,7 @@ critical_actions:
|
|
|
228
228
|
# max_budget_usd: 10.00
|
|
229
229
|
|
|
230
230
|
EOF
|
|
231
|
-
|
|
231
|
+
|
|
232
232
|
echo "$file"
|
|
233
233
|
}
|
|
234
234
|
|
|
@@ -239,50 +239,50 @@ EOF
|
|
|
239
239
|
list_personas() {
|
|
240
240
|
echo -e "${BOLD}Available Agent Personas:${NC}"
|
|
241
241
|
echo ""
|
|
242
|
-
|
|
242
|
+
|
|
243
243
|
if [[ ! -d "$AGENTS_DIR" ]]; then
|
|
244
244
|
echo -e " ${YELLOW}No agents directory found.${NC}"
|
|
245
245
|
return
|
|
246
246
|
fi
|
|
247
|
-
|
|
247
|
+
|
|
248
248
|
printf " %-15s │ %-25s │ Override\n" "NAME" "ROLE"
|
|
249
249
|
printf " %s\n" "$(printf '─%.0s' {1..50})"
|
|
250
|
-
|
|
250
|
+
|
|
251
251
|
for agent_file in "$AGENTS_DIR"/*.md; do
|
|
252
252
|
if [[ -f "$agent_file" ]]; then
|
|
253
253
|
local name=$(basename "$agent_file" .md)
|
|
254
254
|
local role=$(head -1 "$agent_file" | sed 's/# //' | sed 's/ Agent$//')
|
|
255
|
-
|
|
255
|
+
|
|
256
256
|
local has_override=" "
|
|
257
257
|
if [[ -f "$OVERRIDES_DIR/${name}.override.yaml" ]]; then
|
|
258
258
|
has_override="[OK]"
|
|
259
259
|
fi
|
|
260
|
-
|
|
260
|
+
|
|
261
261
|
printf " ${GREEN}%-15s${NC} │ %-25s │ %s\n" "$name" "$role" "$has_override"
|
|
262
262
|
fi
|
|
263
263
|
done
|
|
264
|
-
|
|
264
|
+
|
|
265
265
|
echo ""
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
create_from_template() {
|
|
269
269
|
local template_name="$1"
|
|
270
270
|
local persona_name="$2"
|
|
271
|
-
|
|
271
|
+
|
|
272
272
|
local template=$(get_template "$template_name")
|
|
273
|
-
|
|
273
|
+
|
|
274
274
|
if [[ -z "$template" ]]; then
|
|
275
275
|
echo -e "${RED}Unknown template: $template_name${NC}"
|
|
276
276
|
echo "Available templates: developer, reviewer, architect, tester, security, devops, documentation"
|
|
277
277
|
exit 1
|
|
278
278
|
fi
|
|
279
|
-
|
|
279
|
+
|
|
280
280
|
# Parse template
|
|
281
281
|
IFS='|' read -r tpl_name role focus model <<< "$template"
|
|
282
|
-
|
|
282
|
+
|
|
283
283
|
# Use provided name or template name
|
|
284
284
|
local name="${persona_name:-$tpl_name}"
|
|
285
|
-
|
|
285
|
+
|
|
286
286
|
# Default responsibilities
|
|
287
287
|
local responsibilities=(
|
|
288
288
|
"Complete assigned tasks efficiently"
|
|
@@ -290,12 +290,12 @@ create_from_template() {
|
|
|
290
290
|
"Document work appropriately"
|
|
291
291
|
"Communicate progress and blockers"
|
|
292
292
|
)
|
|
293
|
-
|
|
293
|
+
|
|
294
294
|
mkdir -p "$AGENTS_DIR" "$OVERRIDES_DIR"
|
|
295
|
-
|
|
295
|
+
|
|
296
296
|
local agent_file=$(generate_agent_file "$name" "$role" "$focus" "$model" "${responsibilities[@]}")
|
|
297
297
|
local override_file=$(generate_override_file "$name")
|
|
298
|
-
|
|
298
|
+
|
|
299
299
|
echo -e "${GREEN}[OK] Persona created from template!${NC}"
|
|
300
300
|
echo ""
|
|
301
301
|
echo " Agent file: $agent_file"
|
|
@@ -306,16 +306,16 @@ create_from_template() {
|
|
|
306
306
|
interactive_create() {
|
|
307
307
|
echo -e "${BOLD}Let's create your custom agent persona!${NC}"
|
|
308
308
|
echo ""
|
|
309
|
-
|
|
309
|
+
|
|
310
310
|
# Get name
|
|
311
311
|
local name=$(prompt "Persona name (e.g., 'qa', 'frontend-dev')")
|
|
312
312
|
name=$(echo "$name" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
|
|
313
|
-
|
|
313
|
+
|
|
314
314
|
if [[ -z "$name" ]]; then
|
|
315
315
|
echo -e "${RED}Name is required.${NC}"
|
|
316
316
|
exit 1
|
|
317
317
|
fi
|
|
318
|
-
|
|
318
|
+
|
|
319
319
|
# Check if exists
|
|
320
320
|
if [[ -f "$AGENTS_DIR/${name}.md" ]]; then
|
|
321
321
|
echo -e "${YELLOW}Persona '$name' already exists.${NC}"
|
|
@@ -324,25 +324,25 @@ interactive_create() {
|
|
|
324
324
|
exit 0
|
|
325
325
|
fi
|
|
326
326
|
fi
|
|
327
|
-
|
|
327
|
+
|
|
328
328
|
# Get details
|
|
329
329
|
echo ""
|
|
330
330
|
local role=$(prompt "Role (e.g., 'Senior QA Engineer')")
|
|
331
331
|
local focus=$(prompt "Focus (one-line description)")
|
|
332
|
-
|
|
332
|
+
|
|
333
333
|
echo ""
|
|
334
334
|
echo "Select model:"
|
|
335
335
|
echo " 1. sonnet (default - balanced)"
|
|
336
336
|
echo " 2. opus (complex tasks)"
|
|
337
337
|
echo " 3. haiku (quick tasks)"
|
|
338
338
|
local model_choice=$(prompt "Choice" "1")
|
|
339
|
-
|
|
339
|
+
|
|
340
340
|
local model="sonnet"
|
|
341
341
|
case "$model_choice" in
|
|
342
342
|
2|opus) model="opus" ;;
|
|
343
343
|
3|haiku) model="haiku" ;;
|
|
344
344
|
esac
|
|
345
|
-
|
|
345
|
+
|
|
346
346
|
echo ""
|
|
347
347
|
echo "Enter responsibilities (what this agent does):"
|
|
348
348
|
local responsibilities=()
|
|
@@ -361,13 +361,13 @@ interactive_create() {
|
|
|
361
361
|
fi
|
|
362
362
|
responsibilities+=("$resp")
|
|
363
363
|
done
|
|
364
|
-
|
|
364
|
+
|
|
365
365
|
# Create files
|
|
366
366
|
mkdir -p "$AGENTS_DIR" "$OVERRIDES_DIR"
|
|
367
|
-
|
|
367
|
+
|
|
368
368
|
local agent_file=$(generate_agent_file "$name" "$role" "$focus" "$model" "${responsibilities[@]}")
|
|
369
369
|
local override_file=$(generate_override_file "$name")
|
|
370
|
-
|
|
370
|
+
|
|
371
371
|
echo ""
|
|
372
372
|
echo -e "${GREEN}[OK] Persona created successfully!${NC}"
|
|
373
373
|
echo ""
|
|
@@ -405,7 +405,7 @@ print_usage() {
|
|
|
405
405
|
|
|
406
406
|
main() {
|
|
407
407
|
print_header
|
|
408
|
-
|
|
408
|
+
|
|
409
409
|
case "$1" in
|
|
410
410
|
--list|-l)
|
|
411
411
|
list_personas
|
|
@@ -2,34 +2,45 @@
|
|
|
2
2
|
Devflow Library - Core modules for the Devflow automation system.
|
|
3
3
|
|
|
4
4
|
This package provides:
|
|
5
|
+
- colors: Shared terminal color codes
|
|
6
|
+
- platform: Cross-platform detection utilities
|
|
5
7
|
- cost_tracker: Token usage and cost tracking
|
|
6
8
|
- cost_display: Terminal-based cost monitoring display
|
|
7
9
|
- cost_config: Configuration management for costs
|
|
8
10
|
- currency_converter: Multi-currency support
|
|
11
|
+
- context_monitor: Real-time context window tracking
|
|
9
12
|
- errors: Enhanced error handling
|
|
10
13
|
- agent_router: Dynamic agent selection
|
|
11
14
|
- agent_handoff: Structured agent transitions
|
|
12
15
|
- shared_memory: Cross-agent knowledge sharing
|
|
13
16
|
- swarm_orchestrator: Multi-agent collaboration
|
|
14
17
|
- pair_programming: DEV + REVIEWER collaboration
|
|
18
|
+
- validation_loop: Three-tier validation framework
|
|
15
19
|
|
|
16
20
|
Usage:
|
|
17
21
|
from lib.cost_tracker import CostTracker
|
|
22
|
+
from lib.context_monitor import ContextMonitor, StatusLine, get_status_manager
|
|
18
23
|
from lib.agent_router import AgentRouter
|
|
24
|
+
from lib.colors import Colors
|
|
25
|
+
from lib.platform import get_platform, IS_WINDOWS
|
|
19
26
|
"""
|
|
20
27
|
|
|
21
|
-
__version__ = "1.
|
|
28
|
+
__version__ = "1.19.0"
|
|
22
29
|
|
|
23
30
|
# Lazy imports to avoid circular dependencies
|
|
24
31
|
__all__ = [
|
|
32
|
+
"colors",
|
|
33
|
+
"platform",
|
|
25
34
|
"cost_tracker",
|
|
26
35
|
"cost_display",
|
|
27
36
|
"cost_config",
|
|
28
37
|
"currency_converter",
|
|
38
|
+
"context_monitor",
|
|
29
39
|
"errors",
|
|
30
40
|
"agent_router",
|
|
31
41
|
"agent_handoff",
|
|
32
42
|
"shared_memory",
|
|
33
43
|
"swarm_orchestrator",
|
|
34
44
|
"pair_programming",
|
|
45
|
+
"validation_loop",
|
|
35
46
|
]
|
|
@@ -226,7 +226,12 @@ class HandoffGenerator:
|
|
|
226
226
|
)
|
|
227
227
|
|
|
228
228
|
return changes
|
|
229
|
-
except
|
|
229
|
+
except subprocess.SubprocessError as e:
|
|
230
|
+
# Git command failed - likely not a git repo or git not installed
|
|
231
|
+
print(f"Warning: Could not get git changes: {e}")
|
|
232
|
+
return []
|
|
233
|
+
except OSError as e:
|
|
234
|
+
print(f"Warning: Error accessing git: {e}")
|
|
230
235
|
return []
|
|
231
236
|
|
|
232
237
|
def get_staged_changes(self) -> list[FileChange]:
|
|
@@ -255,7 +260,11 @@ class HandoffGenerator:
|
|
|
255
260
|
)
|
|
256
261
|
|
|
257
262
|
return changes
|
|
258
|
-
except
|
|
263
|
+
except subprocess.SubprocessError as e:
|
|
264
|
+
print(f"Warning: Could not get staged changes: {e}")
|
|
265
|
+
return []
|
|
266
|
+
except OSError as e:
|
|
267
|
+
print(f"Warning: Error accessing git for staged changes: {e}")
|
|
259
268
|
return []
|
|
260
269
|
|
|
261
270
|
def extract_decisions_from_memory(self, agent: str) -> list[str]:
|
|
@@ -29,6 +29,14 @@ from enum import Enum
|
|
|
29
29
|
from pathlib import Path
|
|
30
30
|
from typing import Optional
|
|
31
31
|
|
|
32
|
+
# Configuration constants (can be overridden via environment or config)
|
|
33
|
+
CONFIDENCE_BASE = 0.3 # Base confidence score
|
|
34
|
+
CONFIDENCE_PATTERN_WEIGHT = 0.1 # Weight per detected pattern
|
|
35
|
+
CONFIDENCE_FILE_CONTEXT_WEIGHT = 0.1 # Weight per file context match
|
|
36
|
+
COMPLEXITY_SIMPLE_THRESHOLD = 2 # Complexity <= this is "simple"
|
|
37
|
+
COST_OPT_COMPLEXITY_THRESHOLD = 3 # Max complexity for cost optimization
|
|
38
|
+
MAX_ALTERNATIVES = 3 # Maximum alternative agents to suggest
|
|
39
|
+
|
|
32
40
|
|
|
33
41
|
class TaskType(Enum):
|
|
34
42
|
"""Types of development tasks."""
|
|
@@ -242,6 +250,12 @@ TASK_PATTERNS = {
|
|
|
242
250
|
],
|
|
243
251
|
}
|
|
244
252
|
|
|
253
|
+
# Pre-compile regex patterns for performance
|
|
254
|
+
COMPILED_TASK_PATTERNS: dict[TaskType, list[re.Pattern]] = {
|
|
255
|
+
task_type: [re.compile(pattern, re.IGNORECASE) for pattern in patterns]
|
|
256
|
+
for task_type, patterns in TASK_PATTERNS.items()
|
|
257
|
+
}
|
|
258
|
+
|
|
245
259
|
# File extension to specialty mapping
|
|
246
260
|
FILE_SPECIALTIES = {
|
|
247
261
|
# Security-sensitive files
|
|
@@ -337,14 +351,14 @@ class AgentRouter:
|
|
|
337
351
|
"""
|
|
338
352
|
description_lower = description.lower()
|
|
339
353
|
|
|
340
|
-
# Detect task type from patterns
|
|
354
|
+
# Detect task type from pre-compiled patterns (faster than re.findall each time)
|
|
341
355
|
type_scores: dict[TaskType, int] = {}
|
|
342
356
|
detected_patterns: list[str] = []
|
|
343
357
|
|
|
344
|
-
for task_type,
|
|
358
|
+
for task_type, compiled_patterns in COMPILED_TASK_PATTERNS.items():
|
|
345
359
|
score = 0
|
|
346
|
-
for pattern in
|
|
347
|
-
matches =
|
|
360
|
+
for pattern in compiled_patterns:
|
|
361
|
+
matches = pattern.findall(description_lower)
|
|
348
362
|
if matches:
|
|
349
363
|
score += len(matches)
|
|
350
364
|
detected_patterns.extend(matches)
|
|
@@ -368,8 +382,13 @@ class AgentRouter:
|
|
|
368
382
|
# Estimate complexity
|
|
369
383
|
complexity = self._estimate_complexity(description, files)
|
|
370
384
|
|
|
371
|
-
# Calculate confidence
|
|
372
|
-
confidence = min(
|
|
385
|
+
# Calculate confidence using configurable weights
|
|
386
|
+
confidence = min(
|
|
387
|
+
1.0,
|
|
388
|
+
CONFIDENCE_BASE
|
|
389
|
+
+ (CONFIDENCE_PATTERN_WEIGHT * len(detected_patterns))
|
|
390
|
+
+ (CONFIDENCE_FILE_CONTEXT_WEIGHT * len(file_contexts)),
|
|
391
|
+
)
|
|
373
392
|
|
|
374
393
|
return TaskAnalysis(
|
|
375
394
|
task_type=task_type,
|
|
@@ -562,7 +581,9 @@ class AgentRouter:
|
|
|
562
581
|
}
|
|
563
582
|
|
|
564
583
|
# Determine complexity level
|
|
565
|
-
complexity_level =
|
|
584
|
+
complexity_level = (
|
|
585
|
+
"simple" if complexity.value <= COMPLEXITY_SIMPLE_THRESHOLD else "complex"
|
|
586
|
+
)
|
|
566
587
|
|
|
567
588
|
# Get routing
|
|
568
589
|
rule = routing_rules.get(task_type, {}).get(complexity_level)
|
|
@@ -572,11 +593,11 @@ class AgentRouter:
|
|
|
572
593
|
agents, workflow, reasoning = rule
|
|
573
594
|
|
|
574
595
|
# Cost optimization
|
|
575
|
-
if prefer_cost and complexity.value <=
|
|
596
|
+
if prefer_cost and complexity.value <= COST_OPT_COMPLEXITY_THRESHOLD:
|
|
576
597
|
# Replace Opus agents with Sonnet equivalents where possible
|
|
577
598
|
cost_effective_agents = []
|
|
578
599
|
for agent in agents:
|
|
579
|
-
if agent == "REVIEWER" and complexity.value <=
|
|
600
|
+
if agent == "REVIEWER" and complexity.value <= COMPLEXITY_SIMPLE_THRESHOLD:
|
|
580
601
|
cost_effective_agents.append("SM") # SM can do simple reviews
|
|
581
602
|
else:
|
|
582
603
|
cost_effective_agents.append(agent)
|
|
@@ -601,7 +622,7 @@ class AgentRouter:
|
|
|
601
622
|
if matches and agent.max_complexity >= analysis.complexity.value:
|
|
602
623
|
alternatives.append(name)
|
|
603
624
|
|
|
604
|
-
return alternatives[:
|
|
625
|
+
return alternatives[:MAX_ALTERNATIVES]
|
|
605
626
|
|
|
606
627
|
def get_workflow_for_agents(self, agents: list[str]) -> str:
|
|
607
628
|
"""Determine the best workflow for a set of agents."""
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Shared Colors Module for Devflow.
|
|
4
|
+
|
|
5
|
+
Provides consistent ANSI color codes for terminal output across all scripts.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from lib.colors import Colors
|
|
9
|
+
|
|
10
|
+
print(f"{Colors.GREEN}Success!{Colors.RESET}")
|
|
11
|
+
print(f"{Colors.BOLD_RED}Error!{Colors.RESET}")
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _supports_color() -> bool:
|
|
19
|
+
"""Check if the terminal supports color output."""
|
|
20
|
+
# Check for explicit NO_COLOR environment variable
|
|
21
|
+
if os.getenv("NO_COLOR"):
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
# Check for explicit FORCE_COLOR
|
|
25
|
+
if os.getenv("FORCE_COLOR"):
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
# Check if output is a TTY
|
|
29
|
+
if not hasattr(sys.stdout, "isatty") or not sys.stdout.isatty():
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
# Windows-specific handling
|
|
33
|
+
if sys.platform == "win32":
|
|
34
|
+
try:
|
|
35
|
+
import ctypes
|
|
36
|
+
|
|
37
|
+
kernel32 = ctypes.windll.kernel32
|
|
38
|
+
# Enable ANSI escape sequences on Windows 10+
|
|
39
|
+
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
|
40
|
+
return True
|
|
41
|
+
except Exception:
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
return True
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Colors:
|
|
48
|
+
"""ANSI color codes for terminal output."""
|
|
49
|
+
|
|
50
|
+
_USE_COLORS = _supports_color()
|
|
51
|
+
|
|
52
|
+
# Reset
|
|
53
|
+
RESET = "\033[0m" if _USE_COLORS else ""
|
|
54
|
+
END = RESET # Alias for compatibility
|
|
55
|
+
|
|
56
|
+
# Regular colors
|
|
57
|
+
BLACK = "\033[30m" if _USE_COLORS else ""
|
|
58
|
+
RED = "\033[31m" if _USE_COLORS else ""
|
|
59
|
+
GREEN = "\033[32m" if _USE_COLORS else ""
|
|
60
|
+
YELLOW = "\033[33m" if _USE_COLORS else ""
|
|
61
|
+
BLUE = "\033[34m" if _USE_COLORS else ""
|
|
62
|
+
MAGENTA = "\033[35m" if _USE_COLORS else ""
|
|
63
|
+
CYAN = "\033[36m" if _USE_COLORS else ""
|
|
64
|
+
WHITE = "\033[37m" if _USE_COLORS else ""
|
|
65
|
+
|
|
66
|
+
# Bold colors
|
|
67
|
+
BOLD = "\033[1m" if _USE_COLORS else ""
|
|
68
|
+
BOLD_RED = "\033[1;31m" if _USE_COLORS else ""
|
|
69
|
+
BOLD_GREEN = "\033[1;32m" if _USE_COLORS else ""
|
|
70
|
+
BOLD_YELLOW = "\033[1;33m" if _USE_COLORS else ""
|
|
71
|
+
BOLD_BLUE = "\033[1;34m" if _USE_COLORS else ""
|
|
72
|
+
BOLD_MAGENTA = "\033[1;35m" if _USE_COLORS else ""
|
|
73
|
+
BOLD_CYAN = "\033[1;36m" if _USE_COLORS else ""
|
|
74
|
+
BOLD_WHITE = "\033[1;37m" if _USE_COLORS else ""
|
|
75
|
+
|
|
76
|
+
# Background colors
|
|
77
|
+
BG_RED = "\033[41m" if _USE_COLORS else ""
|
|
78
|
+
BG_GREEN = "\033[42m" if _USE_COLORS else ""
|
|
79
|
+
BG_YELLOW = "\033[43m" if _USE_COLORS else ""
|
|
80
|
+
BG_BLUE = "\033[44m" if _USE_COLORS else ""
|
|
81
|
+
|
|
82
|
+
# Styles
|
|
83
|
+
DIM = "\033[2m" if _USE_COLORS else ""
|
|
84
|
+
UNDERLINE = "\033[4m" if _USE_COLORS else ""
|
|
85
|
+
|
|
86
|
+
# Common aliases used across codebase
|
|
87
|
+
HEADER = BOLD_MAGENTA
|
|
88
|
+
OKBLUE = BLUE
|
|
89
|
+
OKCYAN = CYAN
|
|
90
|
+
OKGREEN = GREEN
|
|
91
|
+
WARNING = YELLOW
|
|
92
|
+
FAIL = RED
|
|
93
|
+
ENDC = RESET
|
|
94
|
+
NC = RESET # No Color alias
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def strip(text: str) -> str:
|
|
98
|
+
"""Remove ANSI codes from text."""
|
|
99
|
+
import re
|
|
100
|
+
|
|
101
|
+
return re.sub(r"\033\[[0-9;]*m", "", text)
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def enabled(cls) -> bool:
|
|
105
|
+
"""Check if colors are enabled."""
|
|
106
|
+
return cls._USE_COLORS
|