claude-symphony 0.0.5 → 0.0.6
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/bin/create.js +120 -3
- package/package.json +3 -2
- package/template/.claude/settings.json +0 -2
- package/template/.claude/skills/context-compression/README.md +39 -0
- package/template/CLAUDE.md +64 -1
- package/template/config/ai_fallbacks.yaml +130 -0
- package/template/config/implementation.yaml.template +72 -72
- package/template/config/pipeline.yaml +50 -0
- package/template/config/ui-ux.yaml +31 -0
- package/template/scripts/config-manager.sh +350 -0
- package/template/scripts/context-manager.sh +55 -4
- package/template/scripts/goto-stage.sh +264 -0
- package/template/scripts/next-stage.sh +132 -0
- package/template/stages/01-brainstorm/HANDOFF.md.template +42 -42
- package/template/stages/02-research/HANDOFF.md.template +42 -42
- package/template/stages/03-planning/HANDOFF.md.template +39 -39
- package/template/stages/04-ui-ux/CLAUDE.md +40 -0
- package/template/stages/04-ui-ux/HANDOFF.md.template +38 -38
- package/template/stages/04-ui-ux/inputs/moodboard/brand-assets/.gitkeep +3 -0
- package/template/stages/04-ui-ux/inputs/moodboard/sketches/.gitkeep +3 -0
- package/template/stages/04-ui-ux/inputs/moodboard/ui-references/.gitkeep +3 -0
- package/template/stages/05-task-management/HANDOFF.md.template +38 -38
- package/template/stages/06-implementation/CLAUDE.md +39 -0
- package/template/stages/06-implementation/HANDOFF.md.template +76 -76
- package/template/stages/06-implementation/config.yaml +16 -0
- package/template/stages/07-refactoring/HANDOFF.md.template +42 -42
- package/template/stages/08-qa/HANDOFF.md.template +45 -45
- package/template/stages/09-testing/HANDOFF.md.template +46 -46
- package/template/stages/10-deployment/HANDOFF.md.template +60 -60
- package/template/state/progress.json.template +26 -0
- package/template/state/templates/handoff_base.md.template +57 -57
- package/template/state/templates/phase_state.md.template +35 -35
|
@@ -1,180 +1,180 @@
|
|
|
1
1
|
# Implementation Rules Template
|
|
2
|
-
# claude-symphony
|
|
2
|
+
# claude-symphony project-specific implementation rules definition (Issue #10 resolution)
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
# Implementation
|
|
4
|
+
# This file is created during the Planning stage (03) to match project requirements
|
|
5
|
+
# and referenced during the Implementation stage (06).
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
# 1.
|
|
9
|
-
# 2.
|
|
10
|
-
# 3.
|
|
7
|
+
# Usage:
|
|
8
|
+
# 1. Copy this template to the project root as implementation.yaml
|
|
9
|
+
# 2. Modify according to project requirements
|
|
10
|
+
# 3. Follow these rules during implementation
|
|
11
11
|
|
|
12
12
|
project:
|
|
13
13
|
name: "{{PROJECT_NAME}}"
|
|
14
14
|
created_at: "{{TIMESTAMP}}"
|
|
15
15
|
|
|
16
|
-
#
|
|
16
|
+
# Component Rules
|
|
17
17
|
components:
|
|
18
|
-
#
|
|
18
|
+
# Component type
|
|
19
19
|
type: "functional" # functional | class | both
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# Export method
|
|
22
22
|
export: "named" # named | default | both
|
|
23
23
|
|
|
24
|
-
#
|
|
24
|
+
# Components per file
|
|
25
25
|
single_component_per_file: true
|
|
26
26
|
|
|
27
|
-
# Props
|
|
27
|
+
# Props definition method
|
|
28
28
|
props_definition: "interface" # interface | type | inline
|
|
29
29
|
|
|
30
|
-
#
|
|
30
|
+
# Default structure
|
|
31
31
|
structure: |
|
|
32
32
|
// imports
|
|
33
33
|
// types/interfaces
|
|
34
34
|
// component
|
|
35
35
|
// exports
|
|
36
36
|
|
|
37
|
-
#
|
|
37
|
+
# Styling Rules
|
|
38
38
|
styling:
|
|
39
|
-
#
|
|
39
|
+
# Approach
|
|
40
40
|
approach: "css-modules" # css-modules | styled-components | tailwind | emotion | vanilla
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# File location
|
|
43
43
|
location: "colocated" # colocated | separate | global
|
|
44
44
|
|
|
45
|
-
#
|
|
45
|
+
# Naming convention
|
|
46
46
|
naming: "BEM" # BEM | camelCase | kebab-case
|
|
47
47
|
|
|
48
|
-
# CSS
|
|
48
|
+
# CSS variables usage
|
|
49
49
|
css_variables: true
|
|
50
50
|
|
|
51
|
-
#
|
|
51
|
+
# State Management Rules
|
|
52
52
|
state_management:
|
|
53
|
-
#
|
|
53
|
+
# Global state
|
|
54
54
|
global: "context" # context | redux | zustand | recoil | jotai
|
|
55
55
|
|
|
56
|
-
#
|
|
56
|
+
# Server state
|
|
57
57
|
server: "tanstack-query" # tanstack-query | swr | rtk-query
|
|
58
58
|
|
|
59
|
-
#
|
|
59
|
+
# Local state
|
|
60
60
|
local: "useState" # useState | useReducer
|
|
61
61
|
|
|
62
|
-
#
|
|
62
|
+
# File/Folder Naming
|
|
63
63
|
file_naming:
|
|
64
|
-
#
|
|
64
|
+
# Component files
|
|
65
65
|
components: "PascalCase" # PascalCase | kebab-case | camelCase
|
|
66
66
|
|
|
67
|
-
#
|
|
68
|
-
hooks: "camelCase" # useXxx
|
|
67
|
+
# Hook files
|
|
68
|
+
hooks: "camelCase" # useXxx pattern
|
|
69
69
|
|
|
70
|
-
#
|
|
70
|
+
# Utility files
|
|
71
71
|
utilities: "camelCase"
|
|
72
72
|
|
|
73
|
-
#
|
|
73
|
+
# Constant files
|
|
74
74
|
constants: "SCREAMING_SNAKE_CASE"
|
|
75
75
|
|
|
76
|
-
#
|
|
76
|
+
# Test files
|
|
77
77
|
tests: "{name}.test.{ext}" # {name}.test.{ext} | {name}.spec.{ext}
|
|
78
78
|
|
|
79
|
-
#
|
|
79
|
+
# Folder Structure
|
|
80
80
|
folder_structure:
|
|
81
|
-
#
|
|
81
|
+
# Structure type
|
|
82
82
|
type: "feature-based" # feature-based | type-based | atomic
|
|
83
83
|
|
|
84
|
-
#
|
|
84
|
+
# Default structure
|
|
85
85
|
structure: |
|
|
86
86
|
src/
|
|
87
|
-
├── components/ #
|
|
88
|
-
├── features/ #
|
|
87
|
+
├── components/ # Shared components
|
|
88
|
+
├── features/ # Feature modules
|
|
89
89
|
│ └── [feature]/
|
|
90
90
|
│ ├── components/
|
|
91
91
|
│ ├── hooks/
|
|
92
92
|
│ ├── utils/
|
|
93
93
|
│ └── index.ts
|
|
94
|
-
├── hooks/ #
|
|
95
|
-
├── utils/ #
|
|
96
|
-
├── types/ #
|
|
97
|
-
├── constants/ #
|
|
98
|
-
└── styles/ #
|
|
94
|
+
├── hooks/ # Shared hooks
|
|
95
|
+
├── utils/ # Shared utilities
|
|
96
|
+
├── types/ # Type definitions
|
|
97
|
+
├── constants/ # Constants
|
|
98
|
+
└── styles/ # Global styles
|
|
99
99
|
|
|
100
|
-
# API
|
|
100
|
+
# API Integration Rules
|
|
101
101
|
api:
|
|
102
|
-
# HTTP
|
|
102
|
+
# HTTP client
|
|
103
103
|
client: "axios" # axios | fetch | ky
|
|
104
104
|
|
|
105
|
-
# API
|
|
105
|
+
# API call location
|
|
106
106
|
location: "services" # services | features | hooks
|
|
107
107
|
|
|
108
|
-
#
|
|
108
|
+
# Error handling
|
|
109
109
|
error_handling: "centralized" # centralized | per-request
|
|
110
110
|
|
|
111
|
-
#
|
|
111
|
+
# Interceptors usage
|
|
112
112
|
interceptors: true
|
|
113
113
|
|
|
114
|
-
#
|
|
114
|
+
# Error Handling Rules
|
|
115
115
|
error_handling:
|
|
116
|
-
# Error Boundary
|
|
116
|
+
# Error Boundary usage
|
|
117
117
|
error_boundary: true
|
|
118
118
|
|
|
119
|
-
#
|
|
119
|
+
# Logging
|
|
120
120
|
logging: "console" # console | service | both
|
|
121
121
|
|
|
122
|
-
#
|
|
122
|
+
# User notification
|
|
123
123
|
user_notification: "toast" # toast | modal | inline
|
|
124
124
|
|
|
125
|
-
#
|
|
125
|
+
# Testing Rules
|
|
126
126
|
testing:
|
|
127
|
-
#
|
|
127
|
+
# Test framework
|
|
128
128
|
framework: "vitest" # vitest | jest
|
|
129
129
|
|
|
130
|
-
# E2E
|
|
130
|
+
# E2E framework
|
|
131
131
|
e2e: "playwright" # playwright | cypress
|
|
132
132
|
|
|
133
|
-
#
|
|
133
|
+
# Coverage target
|
|
134
134
|
coverage_target: 80
|
|
135
135
|
|
|
136
|
-
#
|
|
136
|
+
# Required tests
|
|
137
137
|
required:
|
|
138
138
|
- "unit"
|
|
139
139
|
- "integration"
|
|
140
140
|
|
|
141
|
-
#
|
|
141
|
+
# Code Quality Rules
|
|
142
142
|
code_quality:
|
|
143
|
-
#
|
|
143
|
+
# Linter
|
|
144
144
|
linter: "eslint"
|
|
145
145
|
|
|
146
|
-
#
|
|
146
|
+
# Formatter
|
|
147
147
|
formatter: "prettier"
|
|
148
148
|
|
|
149
|
-
#
|
|
149
|
+
# Type check
|
|
150
150
|
type_check: "strict" # strict | loose
|
|
151
151
|
|
|
152
|
-
#
|
|
152
|
+
# Commit hooks
|
|
153
153
|
commit_hooks: true
|
|
154
154
|
|
|
155
|
-
#
|
|
155
|
+
# Documentation Rules
|
|
156
156
|
documentation:
|
|
157
|
-
# JSDoc
|
|
157
|
+
# JSDoc usage
|
|
158
158
|
jsdoc: true
|
|
159
159
|
|
|
160
|
-
# README
|
|
160
|
+
# README per feature
|
|
161
161
|
readme_per_feature: false
|
|
162
162
|
|
|
163
|
-
#
|
|
163
|
+
# Component documentation
|
|
164
164
|
component_docs: "storybook" # storybook | docz | none
|
|
165
165
|
|
|
166
|
-
#
|
|
166
|
+
# Prohibited Practices
|
|
167
167
|
prohibited:
|
|
168
|
-
- "any
|
|
169
|
-
- "console.log (
|
|
170
|
-
- "
|
|
171
|
-
- "
|
|
172
|
-
- "
|
|
173
|
-
- "var
|
|
174
|
-
|
|
175
|
-
#
|
|
168
|
+
- "Using 'any' type (except explicit escape)"
|
|
169
|
+
- "console.log (except during development)"
|
|
170
|
+
- "Inline styles (except dynamic styles)"
|
|
171
|
+
- "Magic numbers/strings"
|
|
172
|
+
- "Nested ternary operators"
|
|
173
|
+
- "var keyword"
|
|
174
|
+
|
|
175
|
+
# Recommended Practices
|
|
176
176
|
recommended:
|
|
177
|
-
- "Early return
|
|
177
|
+
- "Early return pattern"
|
|
178
178
|
- "Descriptive naming"
|
|
179
179
|
- "Small functions (< 30 lines)"
|
|
180
180
|
- "Composition over inheritance"
|
|
@@ -355,3 +355,53 @@ forking:
|
|
|
355
355
|
compare: "/fork compare"
|
|
356
356
|
merge: "/fork merge"
|
|
357
357
|
delete: "/fork delete"
|
|
358
|
+
|
|
359
|
+
# ============================================
|
|
360
|
+
# Sprint Mode Configuration
|
|
361
|
+
# ============================================
|
|
362
|
+
sprint_mode:
|
|
363
|
+
enabled: true
|
|
364
|
+
type: "sprint_based" # single_pass | sprint_based | spiral
|
|
365
|
+
|
|
366
|
+
sprint_config:
|
|
367
|
+
enabled: true
|
|
368
|
+
source: "stages/05-task-management/outputs/sprint_plan.md"
|
|
369
|
+
default_sprints: 3
|
|
370
|
+
auto_detect: true
|
|
371
|
+
|
|
372
|
+
completion_criteria:
|
|
373
|
+
require_all_must_tasks: true
|
|
374
|
+
require_tests_pass: true
|
|
375
|
+
allow_force_complete: true
|
|
376
|
+
|
|
377
|
+
stage_iterations:
|
|
378
|
+
"06-implementation":
|
|
379
|
+
iterative: true
|
|
380
|
+
iteration_unit: "sprint"
|
|
381
|
+
completion_check: "all_sprints_complete"
|
|
382
|
+
|
|
383
|
+
loop_back:
|
|
384
|
+
enabled: true
|
|
385
|
+
max_stages_back: 3
|
|
386
|
+
|
|
387
|
+
triggers:
|
|
388
|
+
- name: "bug_found"
|
|
389
|
+
from_stages: ["08-qa", "09-testing"]
|
|
390
|
+
to_stage: "06-implementation"
|
|
391
|
+
auto_suggest: true
|
|
392
|
+
|
|
393
|
+
- name: "requirements_change"
|
|
394
|
+
from_stages: ["*"]
|
|
395
|
+
to_stage: "03-planning"
|
|
396
|
+
require_confirmation: true
|
|
397
|
+
|
|
398
|
+
- name: "feature_addition"
|
|
399
|
+
from_stages: ["07-refactoring"]
|
|
400
|
+
to_stage: "06-implementation"
|
|
401
|
+
auto_suggest: true
|
|
402
|
+
|
|
403
|
+
on_loop_back:
|
|
404
|
+
- create_checkpoint
|
|
405
|
+
- record_reason
|
|
406
|
+
- update_handoff
|
|
407
|
+
- notify_user
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# UI/UX Configuration
|
|
2
|
+
# Settings for the 04-ui-ux stage
|
|
3
|
+
|
|
4
|
+
moodboard:
|
|
5
|
+
enabled: true
|
|
6
|
+
supported_formats: [png, jpg, webp, svg]
|
|
7
|
+
max_images: 10
|
|
8
|
+
|
|
9
|
+
directories:
|
|
10
|
+
ui_references: "stages/04-ui-ux/inputs/moodboard/ui-references"
|
|
11
|
+
brand_assets: "stages/04-ui-ux/inputs/moodboard/brand-assets"
|
|
12
|
+
sketches: "stages/04-ui-ux/inputs/moodboard/sketches"
|
|
13
|
+
|
|
14
|
+
analysis:
|
|
15
|
+
# AI will analyze images using vision capabilities
|
|
16
|
+
extract_colors: true
|
|
17
|
+
identify_layouts: true
|
|
18
|
+
suggest_components: true
|
|
19
|
+
|
|
20
|
+
design_system:
|
|
21
|
+
# Design system generation settings
|
|
22
|
+
auto_generate: true
|
|
23
|
+
include_spacing: true
|
|
24
|
+
include_typography: true
|
|
25
|
+
include_colors: true
|
|
26
|
+
|
|
27
|
+
wireframes:
|
|
28
|
+
# Wireframe output format
|
|
29
|
+
format: "ascii" # ascii | mermaid | both
|
|
30
|
+
responsive: true
|
|
31
|
+
breakpoints: [mobile, tablet, desktop]
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# config-manager.sh - Pipeline configuration manager
|
|
3
|
+
# claude-symphony workflow pipeline
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
8
|
+
CONFIG_FILE="$PROJECT_ROOT/config/pipeline.yaml"
|
|
9
|
+
TASK_CONFIG_FILE="$PROJECT_ROOT/stages/05-task-management/config.yaml"
|
|
10
|
+
PROGRESS_FILE="$PROJECT_ROOT/state/progress.json"
|
|
11
|
+
CONFIG_HISTORY="$PROJECT_ROOT/state/config_history.json"
|
|
12
|
+
|
|
13
|
+
# Color definitions
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
GREEN='\033[0;32m'
|
|
16
|
+
YELLOW='\033[1;33m'
|
|
17
|
+
BLUE='\033[0;34m'
|
|
18
|
+
CYAN='\033[0;36m'
|
|
19
|
+
WHITE='\033[1;37m'
|
|
20
|
+
NC='\033[0m' # No Color
|
|
21
|
+
|
|
22
|
+
# Check for yq (YAML parser)
|
|
23
|
+
check_yq() {
|
|
24
|
+
if ! command -v yq &> /dev/null; then
|
|
25
|
+
echo -e "${RED}Error:${NC} yq is required for configuration management."
|
|
26
|
+
echo " Install: brew install yq (macOS) or apt install yq (Linux)"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Check for jq
|
|
32
|
+
check_jq() {
|
|
33
|
+
if ! command -v jq &> /dev/null; then
|
|
34
|
+
echo -e "${RED}Error:${NC} jq is required."
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Initialize config history if not exists
|
|
40
|
+
init_config_history() {
|
|
41
|
+
if [ ! -f "$CONFIG_HISTORY" ]; then
|
|
42
|
+
mkdir -p "$(dirname "$CONFIG_HISTORY")"
|
|
43
|
+
echo '{"changes": []}' > "$CONFIG_HISTORY"
|
|
44
|
+
fi
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Record config change
|
|
48
|
+
record_change() {
|
|
49
|
+
local CATEGORY=$1
|
|
50
|
+
local ACTION=$2
|
|
51
|
+
local VALUE=$3
|
|
52
|
+
|
|
53
|
+
init_config_history
|
|
54
|
+
|
|
55
|
+
local ENTRY=$(cat << EOF
|
|
56
|
+
{
|
|
57
|
+
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
|
58
|
+
"category": "$CATEGORY",
|
|
59
|
+
"action": "$ACTION",
|
|
60
|
+
"value": "$VALUE"
|
|
61
|
+
}
|
|
62
|
+
EOF
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
jq ".changes += [$ENTRY]" "$CONFIG_HISTORY" > "${CONFIG_HISTORY}.tmp" \
|
|
66
|
+
&& mv "${CONFIG_HISTORY}.tmp" "$CONFIG_HISTORY"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Sprint configuration
|
|
70
|
+
config_sprint() {
|
|
71
|
+
local ACTION=$1
|
|
72
|
+
local VALUE=$2
|
|
73
|
+
|
|
74
|
+
check_yq
|
|
75
|
+
check_jq
|
|
76
|
+
|
|
77
|
+
case $ACTION in
|
|
78
|
+
enable)
|
|
79
|
+
yq -i '.sprint_mode.enabled = true' "$CONFIG_FILE"
|
|
80
|
+
record_change "sprint" "enable" "true"
|
|
81
|
+
echo -e "${GREEN}✅${NC} Sprint mode enabled"
|
|
82
|
+
;;
|
|
83
|
+
|
|
84
|
+
disable)
|
|
85
|
+
yq -i '.sprint_mode.enabled = false' "$CONFIG_FILE"
|
|
86
|
+
record_change "sprint" "disable" "false"
|
|
87
|
+
echo -e "${GREEN}✅${NC} Sprint mode disabled (single-pass mode)"
|
|
88
|
+
;;
|
|
89
|
+
|
|
90
|
+
count)
|
|
91
|
+
if [[ "$VALUE" =~ ^[0-9]+$ ]] && [ "$VALUE" -ge 1 ] && [ "$VALUE" -le 100 ]; then
|
|
92
|
+
yq -i ".sprint_mode.sprint_config.default_sprints = $VALUE" "$CONFIG_FILE"
|
|
93
|
+
|
|
94
|
+
# Also update progress.json
|
|
95
|
+
if [ -f "$PROGRESS_FILE" ]; then
|
|
96
|
+
# Update total_sprints
|
|
97
|
+
jq ".current_iteration.total_sprints = $VALUE" "$PROGRESS_FILE" > "${PROGRESS_FILE}.tmp" \
|
|
98
|
+
&& mv "${PROGRESS_FILE}.tmp" "$PROGRESS_FILE"
|
|
99
|
+
|
|
100
|
+
# Regenerate sprints object
|
|
101
|
+
local SPRINTS_JSON="{}"
|
|
102
|
+
for ((i=1; i<=VALUE; i++)); do
|
|
103
|
+
SPRINTS_JSON=$(echo "$SPRINTS_JSON" | jq ". + {\"Sprint $i\": {\"status\": \"pending\", \"tasks_total\": 0, \"tasks_completed\": 0, \"checkpoint_id\": null}}")
|
|
104
|
+
done
|
|
105
|
+
jq ".sprints = $SPRINTS_JSON" "$PROGRESS_FILE" > "${PROGRESS_FILE}.tmp" \
|
|
106
|
+
&& mv "${PROGRESS_FILE}.tmp" "$PROGRESS_FILE"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
record_change "sprint" "count" "$VALUE"
|
|
110
|
+
echo -e "${GREEN}✅${NC} Default sprint count: $VALUE"
|
|
111
|
+
else
|
|
112
|
+
echo -e "${RED}Error:${NC} Sprint count must be between 1 and 100"
|
|
113
|
+
exit 1
|
|
114
|
+
fi
|
|
115
|
+
;;
|
|
116
|
+
|
|
117
|
+
status)
|
|
118
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
119
|
+
echo -e "⚙️ ${WHITE}Sprint Configuration${NC}"
|
|
120
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
121
|
+
|
|
122
|
+
local ENABLED=$(yq '.sprint_mode.enabled // false' "$CONFIG_FILE")
|
|
123
|
+
local COUNT=$(yq '.sprint_mode.sprint_config.default_sprints // 3' "$CONFIG_FILE")
|
|
124
|
+
local TYPE=$(yq '.sprint_mode.type // "sprint_based"' "$CONFIG_FILE")
|
|
125
|
+
|
|
126
|
+
echo -e "Sprint mode: ${CYAN}$ENABLED${NC}"
|
|
127
|
+
echo -e "Type: ${CYAN}$TYPE${NC}"
|
|
128
|
+
echo -e "Default count: ${CYAN}$COUNT${NC}"
|
|
129
|
+
|
|
130
|
+
if [ -f "$PROGRESS_FILE" ]; then
|
|
131
|
+
echo ""
|
|
132
|
+
echo "Current session:"
|
|
133
|
+
local CURRENT=$(jq -r '.current_iteration.current_sprint // 1' "$PROGRESS_FILE")
|
|
134
|
+
local TOTAL=$(jq -r '.current_iteration.total_sprints // 3' "$PROGRESS_FILE")
|
|
135
|
+
echo -e " Sprint: ${CYAN}$CURRENT / $TOTAL${NC}"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
139
|
+
;;
|
|
140
|
+
|
|
141
|
+
*)
|
|
142
|
+
echo -e "${RED}Error:${NC} Unknown sprint action: $ACTION"
|
|
143
|
+
echo " Available: enable, disable, count <n>, status"
|
|
144
|
+
exit 1
|
|
145
|
+
;;
|
|
146
|
+
esac
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Notion configuration
|
|
150
|
+
config_notion() {
|
|
151
|
+
local ACTION=$1
|
|
152
|
+
|
|
153
|
+
check_yq
|
|
154
|
+
|
|
155
|
+
case $ACTION in
|
|
156
|
+
enable)
|
|
157
|
+
if [ -f "$TASK_CONFIG_FILE" ]; then
|
|
158
|
+
yq -i '.notion_integration.enabled = true' "$TASK_CONFIG_FILE"
|
|
159
|
+
fi
|
|
160
|
+
record_change "notion" "enable" "true"
|
|
161
|
+
echo -e "${GREEN}✅${NC} Notion integration enabled"
|
|
162
|
+
;;
|
|
163
|
+
|
|
164
|
+
disable)
|
|
165
|
+
if [ -f "$TASK_CONFIG_FILE" ]; then
|
|
166
|
+
yq -i '.notion_integration.enabled = false' "$TASK_CONFIG_FILE"
|
|
167
|
+
fi
|
|
168
|
+
record_change "notion" "disable" "false"
|
|
169
|
+
echo -e "${GREEN}✅${NC} Notion integration disabled"
|
|
170
|
+
;;
|
|
171
|
+
|
|
172
|
+
status)
|
|
173
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
174
|
+
echo -e "📋 ${WHITE}Notion Configuration${NC}"
|
|
175
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
176
|
+
|
|
177
|
+
if [ -f "$TASK_CONFIG_FILE" ]; then
|
|
178
|
+
local ENABLED=$(yq '.notion_integration.enabled // false' "$TASK_CONFIG_FILE")
|
|
179
|
+
echo -e "Notion integration: ${CYAN}$ENABLED${NC}"
|
|
180
|
+
else
|
|
181
|
+
echo -e "Notion integration: ${YELLOW}config not found${NC}"
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
185
|
+
;;
|
|
186
|
+
|
|
187
|
+
*)
|
|
188
|
+
echo -e "${RED}Error:${NC} Unknown notion action: $ACTION"
|
|
189
|
+
echo " Available: enable, disable, status"
|
|
190
|
+
exit 1
|
|
191
|
+
;;
|
|
192
|
+
esac
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Loop-back configuration
|
|
196
|
+
config_loopback() {
|
|
197
|
+
local ACTION=$1
|
|
198
|
+
local VALUE=$2
|
|
199
|
+
|
|
200
|
+
check_yq
|
|
201
|
+
|
|
202
|
+
case $ACTION in
|
|
203
|
+
enable)
|
|
204
|
+
yq -i '.sprint_mode.loop_back.enabled = true' "$CONFIG_FILE"
|
|
205
|
+
record_change "loopback" "enable" "true"
|
|
206
|
+
echo -e "${GREEN}✅${NC} Loop-back enabled"
|
|
207
|
+
;;
|
|
208
|
+
|
|
209
|
+
disable)
|
|
210
|
+
yq -i '.sprint_mode.loop_back.enabled = false' "$CONFIG_FILE"
|
|
211
|
+
record_change "loopback" "disable" "false"
|
|
212
|
+
echo -e "${GREEN}✅${NC} Loop-back disabled"
|
|
213
|
+
;;
|
|
214
|
+
|
|
215
|
+
max)
|
|
216
|
+
if [[ "$VALUE" =~ ^[0-9]+$ ]] && [ "$VALUE" -ge 1 ] && [ "$VALUE" -le 10 ]; then
|
|
217
|
+
yq -i ".sprint_mode.loop_back.max_stages_back = $VALUE" "$CONFIG_FILE"
|
|
218
|
+
record_change "loopback" "max" "$VALUE"
|
|
219
|
+
echo -e "${GREEN}✅${NC} Max loop-back stages: $VALUE"
|
|
220
|
+
else
|
|
221
|
+
echo -e "${RED}Error:${NC} Max stages must be between 1 and 10"
|
|
222
|
+
exit 1
|
|
223
|
+
fi
|
|
224
|
+
;;
|
|
225
|
+
|
|
226
|
+
status)
|
|
227
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
228
|
+
echo -e "🔙 ${WHITE}Loop-back Configuration${NC}"
|
|
229
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
230
|
+
|
|
231
|
+
local ENABLED=$(yq '.sprint_mode.loop_back.enabled // true' "$CONFIG_FILE")
|
|
232
|
+
local MAX=$(yq '.sprint_mode.loop_back.max_stages_back // 3' "$CONFIG_FILE")
|
|
233
|
+
|
|
234
|
+
echo -e "Loop-back enabled: ${CYAN}$ENABLED${NC}"
|
|
235
|
+
echo -e "Max stages back: ${CYAN}$MAX${NC}"
|
|
236
|
+
|
|
237
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
238
|
+
;;
|
|
239
|
+
|
|
240
|
+
*)
|
|
241
|
+
echo -e "${RED}Error:${NC} Unknown loopback action: $ACTION"
|
|
242
|
+
echo " Available: enable, disable, max <n>, status"
|
|
243
|
+
exit 1
|
|
244
|
+
;;
|
|
245
|
+
esac
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
# Show all configurations
|
|
249
|
+
show_all() {
|
|
250
|
+
config_sprint status
|
|
251
|
+
echo ""
|
|
252
|
+
config_notion status
|
|
253
|
+
echo ""
|
|
254
|
+
config_loopback status
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
# Show config history
|
|
258
|
+
show_history() {
|
|
259
|
+
check_jq
|
|
260
|
+
init_config_history
|
|
261
|
+
|
|
262
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
263
|
+
echo -e "📜 ${WHITE}Configuration History${NC}"
|
|
264
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
265
|
+
|
|
266
|
+
local COUNT=$(jq '.changes | length' "$CONFIG_HISTORY")
|
|
267
|
+
|
|
268
|
+
if [ "$COUNT" == "0" ]; then
|
|
269
|
+
echo "No configuration changes recorded."
|
|
270
|
+
else
|
|
271
|
+
jq -r '.changes | reverse | .[0:10] | .[] | "[\(.timestamp)] \(.category)/\(.action): \(.value)"' "$CONFIG_HISTORY"
|
|
272
|
+
|
|
273
|
+
if [ "$COUNT" -gt 10 ]; then
|
|
274
|
+
echo ""
|
|
275
|
+
echo -e "${GRAY}(Showing last 10 of $COUNT changes)${NC}"
|
|
276
|
+
fi
|
|
277
|
+
fi
|
|
278
|
+
|
|
279
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# Print usage
|
|
283
|
+
print_usage() {
|
|
284
|
+
echo "Usage: config-manager.sh <category> <action> [value]"
|
|
285
|
+
echo ""
|
|
286
|
+
echo "Categories:"
|
|
287
|
+
echo " sprint Sprint mode configuration"
|
|
288
|
+
echo " notion Notion integration configuration"
|
|
289
|
+
echo " loopback Loop-back configuration"
|
|
290
|
+
echo " all Show all configurations"
|
|
291
|
+
echo " history Show configuration change history"
|
|
292
|
+
echo ""
|
|
293
|
+
echo "Sprint actions:"
|
|
294
|
+
echo " enable Enable sprint mode"
|
|
295
|
+
echo " disable Disable sprint mode (single-pass)"
|
|
296
|
+
echo " count <n> Set default sprint count"
|
|
297
|
+
echo " status Show current sprint configuration"
|
|
298
|
+
echo ""
|
|
299
|
+
echo "Notion actions:"
|
|
300
|
+
echo " enable Enable Notion integration"
|
|
301
|
+
echo " disable Disable Notion integration"
|
|
302
|
+
echo " status Show current Notion configuration"
|
|
303
|
+
echo ""
|
|
304
|
+
echo "Loopback actions:"
|
|
305
|
+
echo " enable Enable loop-back"
|
|
306
|
+
echo " disable Disable loop-back"
|
|
307
|
+
echo " max <n> Set max stages for loop-back"
|
|
308
|
+
echo " status Show current loop-back configuration"
|
|
309
|
+
echo ""
|
|
310
|
+
echo "Examples:"
|
|
311
|
+
echo " ./config-manager.sh sprint enable"
|
|
312
|
+
echo " ./config-manager.sh sprint count 5"
|
|
313
|
+
echo " ./config-manager.sh notion disable"
|
|
314
|
+
echo " ./config-manager.sh all"
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
# Main
|
|
318
|
+
CATEGORY=$1
|
|
319
|
+
ACTION=$2
|
|
320
|
+
VALUE=$3
|
|
321
|
+
|
|
322
|
+
case $CATEGORY in
|
|
323
|
+
sprint)
|
|
324
|
+
config_sprint "$ACTION" "$VALUE"
|
|
325
|
+
;;
|
|
326
|
+
notion)
|
|
327
|
+
config_notion "$ACTION"
|
|
328
|
+
;;
|
|
329
|
+
loopback)
|
|
330
|
+
config_loopback "$ACTION" "$VALUE"
|
|
331
|
+
;;
|
|
332
|
+
all)
|
|
333
|
+
show_all
|
|
334
|
+
;;
|
|
335
|
+
history)
|
|
336
|
+
show_history
|
|
337
|
+
;;
|
|
338
|
+
--help|-h)
|
|
339
|
+
print_usage
|
|
340
|
+
;;
|
|
341
|
+
*)
|
|
342
|
+
if [ -z "$CATEGORY" ]; then
|
|
343
|
+
print_usage
|
|
344
|
+
else
|
|
345
|
+
echo -e "${RED}Error:${NC} Unknown category: $CATEGORY"
|
|
346
|
+
print_usage
|
|
347
|
+
exit 1
|
|
348
|
+
fi
|
|
349
|
+
;;
|
|
350
|
+
esac
|