agileflow 2.94.1 → 2.95.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/CHANGELOG.md +15 -0
- package/lib/colors.generated.js +117 -0
- package/lib/colors.js +59 -109
- package/lib/generator-factory.js +333 -0
- package/lib/path-utils.js +49 -0
- package/lib/session-registry.js +25 -15
- package/lib/smart-json-file.js +40 -32
- package/lib/state-machine.js +286 -0
- package/package.json +1 -1
- package/scripts/agileflow-configure.js +7 -6
- package/scripts/archive-completed-stories.sh +86 -11
- package/scripts/babysit-context-restore.js +89 -0
- package/scripts/claude-tmux.sh +111 -5
- package/scripts/damage-control/bash-tool-damage-control.js +11 -247
- package/scripts/damage-control/edit-tool-damage-control.js +9 -249
- package/scripts/damage-control/write-tool-damage-control.js +9 -244
- package/scripts/generate-colors.js +314 -0
- package/scripts/lib/colors.generated.sh +82 -0
- package/scripts/lib/colors.sh +10 -70
- package/scripts/lib/configure-features.js +401 -0
- package/scripts/lib/context-loader.js +181 -52
- package/scripts/precompact-context.sh +54 -17
- package/scripts/session-coordinator.sh +2 -2
- package/scripts/session-manager.js +653 -10
- package/src/core/commands/audit.md +93 -0
- package/src/core/commands/auto.md +73 -0
- package/src/core/commands/babysit.md +169 -13
- package/src/core/commands/baseline.md +73 -0
- package/src/core/commands/batch.md +64 -0
- package/src/core/commands/blockers.md +60 -0
- package/src/core/commands/board.md +66 -0
- package/src/core/commands/choose.md +77 -0
- package/src/core/commands/ci.md +77 -0
- package/src/core/commands/compress.md +27 -1
- package/src/core/commands/configure.md +126 -10
- package/src/core/commands/council.md +74 -0
- package/src/core/commands/debt.md +72 -0
- package/src/core/commands/deploy.md +73 -0
- package/src/core/commands/deps.md +68 -0
- package/src/core/commands/docs.md +60 -0
- package/src/core/commands/feedback.md +68 -0
- package/src/core/commands/ideate.md +74 -0
- package/src/core/commands/impact.md +74 -0
- package/src/core/commands/install.md +529 -0
- package/src/core/commands/maintain.md +558 -0
- package/src/core/commands/metrics.md +75 -0
- package/src/core/commands/multi-expert.md +74 -0
- package/src/core/commands/packages.md +69 -0
- package/src/core/commands/readme-sync.md +64 -0
- package/src/core/commands/research/analyze.md +285 -121
- package/src/core/commands/research/import.md +281 -109
- package/src/core/commands/retro.md +76 -0
- package/src/core/commands/review.md +72 -0
- package/src/core/commands/rlm.md +83 -0
- package/src/core/commands/rpi.md +90 -0
- package/src/core/commands/session/cleanup.md +214 -12
- package/src/core/commands/session/end.md +155 -17
- package/src/core/commands/sprint.md +72 -0
- package/src/core/commands/story-validate.md +68 -0
- package/src/core/commands/template.md +69 -0
- package/src/core/commands/tests.md +83 -0
- package/src/core/commands/update.md +59 -0
- package/src/core/commands/validate-expertise.md +76 -0
- package/src/core/commands/velocity.md +74 -0
- package/src/core/commands/verify.md +91 -0
- package/src/core/commands/whats-new.md +69 -0
- package/src/core/commands/workflow.md +88 -0
- package/src/core/templates/command-documentation.md +187 -0
- package/tools/cli/commands/session.js +1171 -0
- package/tools/cli/commands/setup.js +2 -81
- package/tools/cli/installers/core/installer.js +0 -5
- package/tools/cli/installers/ide/claude-code.js +6 -0
- package/tools/cli/lib/config-manager.js +42 -5
package/scripts/lib/colors.sh
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
#
|
|
4
4
|
# Source this file: source "$(dirname "${BASH_SOURCE[0]}")/lib/colors.sh"
|
|
5
5
|
#
|
|
6
|
+
# Color definitions are sourced from colors.generated.sh which is
|
|
7
|
+
# auto-generated from config/colors.yaml (single source of truth).
|
|
8
|
+
# Run: node scripts/generate-colors.js
|
|
9
|
+
#
|
|
6
10
|
# WCAG AA Contrast Ratios (verified against #1a1a1a dark terminal background):
|
|
7
11
|
# - Green (#32CD32): 4.5:1 ✓ (meets AA for normal text)
|
|
8
12
|
# - Red (#FF6B6B): 5.0:1 ✓ (meets AA for normal text)
|
|
@@ -18,66 +22,15 @@
|
|
|
18
22
|
# echo -e "${BRAND}AgileFlow${RESET}"
|
|
19
23
|
|
|
20
24
|
# ============================================================================
|
|
21
|
-
#
|
|
22
|
-
# ============================================================================
|
|
23
|
-
RESET="\033[0m"
|
|
24
|
-
BOLD="\033[1m"
|
|
25
|
-
DIM="\033[2m"
|
|
26
|
-
ITALIC="\033[3m"
|
|
27
|
-
UNDERLINE="\033[4m"
|
|
28
|
-
|
|
29
|
-
# ============================================================================
|
|
30
|
-
# Standard ANSI Colors (8 colors)
|
|
31
|
-
# ============================================================================
|
|
32
|
-
RED="\033[31m"
|
|
33
|
-
GREEN="\033[32m"
|
|
34
|
-
YELLOW="\033[33m"
|
|
35
|
-
BLUE="\033[34m"
|
|
36
|
-
MAGENTA="\033[35m"
|
|
37
|
-
CYAN="\033[36m"
|
|
38
|
-
WHITE="\033[37m"
|
|
39
|
-
BLACK="\033[30m"
|
|
40
|
-
|
|
41
|
-
# ============================================================================
|
|
42
|
-
# Bright Variants
|
|
43
|
-
# ============================================================================
|
|
44
|
-
BRIGHT_RED="\033[91m"
|
|
45
|
-
BRIGHT_GREEN="\033[92m"
|
|
46
|
-
BRIGHT_YELLOW="\033[93m"
|
|
47
|
-
BRIGHT_BLUE="\033[94m"
|
|
48
|
-
BRIGHT_MAGENTA="\033[95m"
|
|
49
|
-
BRIGHT_CYAN="\033[96m"
|
|
50
|
-
BRIGHT_WHITE="\033[97m"
|
|
51
|
-
BRIGHT_BLACK="\033[90m"
|
|
52
|
-
|
|
53
|
-
# ============================================================================
|
|
54
|
-
# Semantic Aliases (for consistent meaning across codebase)
|
|
25
|
+
# Source generated colors from YAML
|
|
55
26
|
# ============================================================================
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
INFO="$CYAN"
|
|
60
|
-
|
|
61
|
-
# ============================================================================
|
|
62
|
-
# 256-Color Palette (vibrant, modern look)
|
|
63
|
-
# ============================================================================
|
|
64
|
-
MINT_GREEN="\033[38;5;158m" # Healthy/success states
|
|
65
|
-
PEACH="\033[38;5;215m" # Warning states
|
|
66
|
-
CORAL="\033[38;5;203m" # Critical/error states
|
|
67
|
-
LIGHT_GREEN="\033[38;5;194m" # Session healthy
|
|
68
|
-
LIGHT_YELLOW="\033[38;5;228m" # Session warning
|
|
69
|
-
LIGHT_PINK="\033[38;5;210m" # Session critical
|
|
70
|
-
SKY_BLUE="\033[38;5;117m" # Directories/paths, ready states
|
|
71
|
-
LAVENDER="\033[38;5;147m" # Model info, story IDs
|
|
72
|
-
SOFT_GOLD="\033[38;5;222m" # Cost/money
|
|
73
|
-
TEAL="\033[38;5;80m" # Pending states
|
|
74
|
-
SLATE="\033[38;5;103m" # Secondary info
|
|
75
|
-
ROSE="\033[38;5;211m" # Blocked/critical accent
|
|
76
|
-
AMBER="\033[38;5;214m" # WIP/in-progress accent
|
|
77
|
-
POWDER="\033[38;5;153m" # Labels/headers
|
|
27
|
+
_COLORS_DIR="$(dirname "${BASH_SOURCE[0]}")"
|
|
28
|
+
# shellcheck source=colors.generated.sh
|
|
29
|
+
source "${_COLORS_DIR}/colors.generated.sh"
|
|
78
30
|
|
|
79
31
|
# ============================================================================
|
|
80
32
|
# Context/Usage Colors (for status indicators)
|
|
33
|
+
# These are additional aliases not in the generated file
|
|
81
34
|
# ============================================================================
|
|
82
35
|
CTX_GREEN="$MINT_GREEN" # Healthy context
|
|
83
36
|
CTX_YELLOW="$PEACH" # Moderate usage
|
|
@@ -86,21 +39,8 @@ CTX_RED="$CORAL" # Critical
|
|
|
86
39
|
|
|
87
40
|
# ============================================================================
|
|
88
41
|
# Session Time Colors
|
|
42
|
+
# These are additional aliases not in the generated file
|
|
89
43
|
# ============================================================================
|
|
90
44
|
SESSION_GREEN="$LIGHT_GREEN" # Plenty of time
|
|
91
45
|
SESSION_YELLOW="$LIGHT_YELLOW" # Getting low
|
|
92
46
|
SESSION_RED="$LIGHT_PINK" # Critical
|
|
93
|
-
|
|
94
|
-
# ============================================================================
|
|
95
|
-
# Brand Color (#e8683a - burnt orange/terracotta)
|
|
96
|
-
# ============================================================================
|
|
97
|
-
BRAND="\033[38;2;232;104;58m"
|
|
98
|
-
ORANGE="$BRAND" # Alias for brand color
|
|
99
|
-
|
|
100
|
-
# ============================================================================
|
|
101
|
-
# Background Colors
|
|
102
|
-
# ============================================================================
|
|
103
|
-
BG_RED="\033[41m"
|
|
104
|
-
BG_GREEN="\033[42m"
|
|
105
|
-
BG_YELLOW="\033[43m"
|
|
106
|
-
BG_BLUE="\033[44m"
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
9
10
|
const {
|
|
10
11
|
c,
|
|
11
12
|
log,
|
|
@@ -39,6 +40,14 @@ const FEATURES = {
|
|
|
39
40
|
},
|
|
40
41
|
askuserquestion: { metadataOnly: true },
|
|
41
42
|
tmuxautospawn: { metadataOnly: true },
|
|
43
|
+
shellaliases: {
|
|
44
|
+
metadataOnly: false,
|
|
45
|
+
description: 'Shell aliases (af/agileflow) for tmux-wrapped Claude',
|
|
46
|
+
},
|
|
47
|
+
claudemdreinforcement: {
|
|
48
|
+
metadataOnly: false,
|
|
49
|
+
description: 'Add /babysit rules to CLAUDE.md for context preservation',
|
|
50
|
+
},
|
|
42
51
|
};
|
|
43
52
|
|
|
44
53
|
const PROFILES = {
|
|
@@ -88,6 +97,26 @@ const PROFILES = {
|
|
|
88
97
|
'tmuxautospawn',
|
|
89
98
|
],
|
|
90
99
|
},
|
|
100
|
+
experimental: {
|
|
101
|
+
description:
|
|
102
|
+
'⚠️ CONTEXT HEAVY: Full command file injection during compact (uses more tokens but may be more reliable)',
|
|
103
|
+
enable: [
|
|
104
|
+
'sessionstart',
|
|
105
|
+
'precompact',
|
|
106
|
+
'archival',
|
|
107
|
+
'statusline',
|
|
108
|
+
'ralphloop',
|
|
109
|
+
'selfimprove',
|
|
110
|
+
'askuserquestion',
|
|
111
|
+
'tmuxautospawn',
|
|
112
|
+
],
|
|
113
|
+
archivalDays: 30,
|
|
114
|
+
experimental: {
|
|
115
|
+
fullFileInjection: true,
|
|
116
|
+
description:
|
|
117
|
+
'Instead of compact summaries, injects entire command files during context compaction',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
91
120
|
};
|
|
92
121
|
|
|
93
122
|
const STATUSLINE_COMPONENTS = [
|
|
@@ -243,6 +272,68 @@ function enableFeature(feature, options = {}, version) {
|
|
|
243
272
|
return true;
|
|
244
273
|
}
|
|
245
274
|
|
|
275
|
+
// Handle shell aliases
|
|
276
|
+
if (feature === 'shellaliases') {
|
|
277
|
+
const result = enableShellAliases();
|
|
278
|
+
if (
|
|
279
|
+
result.configured.length > 0 ||
|
|
280
|
+
result.skipped.some(s => s.includes('already configured'))
|
|
281
|
+
) {
|
|
282
|
+
updateMetadata(
|
|
283
|
+
{
|
|
284
|
+
features: {
|
|
285
|
+
shellAliases: {
|
|
286
|
+
enabled: true,
|
|
287
|
+
version,
|
|
288
|
+
at: new Date().toISOString(),
|
|
289
|
+
shells: result.configured,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
version
|
|
294
|
+
);
|
|
295
|
+
if (result.configured.length > 0) {
|
|
296
|
+
success(`Shell aliases added to: ${result.configured.join(', ')}`);
|
|
297
|
+
info('Reload shell: source ~/.bashrc or source ~/.zshrc');
|
|
298
|
+
info('Then use "af" or "agileflow" to start Claude in tmux');
|
|
299
|
+
} else {
|
|
300
|
+
info('Shell aliases already configured');
|
|
301
|
+
}
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
if (result.skipped.length > 0) {
|
|
305
|
+
warn(`Shell aliases skipped: ${result.skipped.join(', ')}`);
|
|
306
|
+
}
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Handle CLAUDE.md reinforcement
|
|
311
|
+
if (feature === 'claudemdreinforcement') {
|
|
312
|
+
const result = enableClaudeMdReinforcement();
|
|
313
|
+
if (result.success) {
|
|
314
|
+
updateMetadata(
|
|
315
|
+
{
|
|
316
|
+
features: {
|
|
317
|
+
claudeMdReinforcement: {
|
|
318
|
+
enabled: true,
|
|
319
|
+
version,
|
|
320
|
+
at: new Date().toISOString(),
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
version
|
|
325
|
+
);
|
|
326
|
+
if (result.added) {
|
|
327
|
+
success('Added /babysit rules to CLAUDE.md');
|
|
328
|
+
} else {
|
|
329
|
+
info('CLAUDE.md already has /babysit rules');
|
|
330
|
+
}
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
error(`Failed to update CLAUDE.md: ${result.error}`);
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
|
|
246
337
|
// Handle damage control
|
|
247
338
|
if (feature === 'damagecontrol') {
|
|
248
339
|
return enableDamageControl(settings, options, version);
|
|
@@ -547,6 +638,53 @@ function disableFeature(feature, version) {
|
|
|
547
638
|
return true;
|
|
548
639
|
}
|
|
549
640
|
|
|
641
|
+
// Disable shell aliases
|
|
642
|
+
if (feature === 'shellaliases') {
|
|
643
|
+
const result = disableShellAliases();
|
|
644
|
+
updateMetadata(
|
|
645
|
+
{
|
|
646
|
+
features: {
|
|
647
|
+
shellAliases: {
|
|
648
|
+
enabled: false,
|
|
649
|
+
version,
|
|
650
|
+
at: new Date().toISOString(),
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
version
|
|
655
|
+
);
|
|
656
|
+
if (result.removed.length > 0) {
|
|
657
|
+
success(`Shell aliases removed from: ${result.removed.join(', ')}`);
|
|
658
|
+
info('Reload shell: source ~/.bashrc or source ~/.zshrc');
|
|
659
|
+
} else {
|
|
660
|
+
info('No shell aliases found to remove');
|
|
661
|
+
}
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// Disable CLAUDE.md reinforcement
|
|
666
|
+
if (feature === 'claudemdreinforcement') {
|
|
667
|
+
const result = disableClaudeMdReinforcement();
|
|
668
|
+
updateMetadata(
|
|
669
|
+
{
|
|
670
|
+
features: {
|
|
671
|
+
claudeMdReinforcement: {
|
|
672
|
+
enabled: false,
|
|
673
|
+
version,
|
|
674
|
+
at: new Date().toISOString(),
|
|
675
|
+
},
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
version
|
|
679
|
+
);
|
|
680
|
+
if (result.removed) {
|
|
681
|
+
success('Removed /babysit rules from CLAUDE.md');
|
|
682
|
+
} else {
|
|
683
|
+
info('CLAUDE.md did not have /babysit rules');
|
|
684
|
+
}
|
|
685
|
+
return true;
|
|
686
|
+
}
|
|
687
|
+
|
|
550
688
|
// Disable damage control
|
|
551
689
|
if (feature === 'damagecontrol') {
|
|
552
690
|
if (settings.hooks?.PreToolUse && Array.isArray(settings.hooks.PreToolUse)) {
|
|
@@ -625,6 +763,43 @@ function applyProfile(profileName, options = {}, version) {
|
|
|
625
763
|
profile.disable.forEach(f => disableFeature(f, version));
|
|
626
764
|
}
|
|
627
765
|
|
|
766
|
+
// Handle experimental profile settings
|
|
767
|
+
if (profile.experimental) {
|
|
768
|
+
updateMetadata(
|
|
769
|
+
{
|
|
770
|
+
features: {
|
|
771
|
+
experimental: {
|
|
772
|
+
enabled: true,
|
|
773
|
+
fullFileInjection: profile.experimental.fullFileInjection || false,
|
|
774
|
+
version,
|
|
775
|
+
at: new Date().toISOString(),
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
version
|
|
780
|
+
);
|
|
781
|
+
if (profile.experimental.fullFileInjection) {
|
|
782
|
+
warn('⚠️ EXPERIMENTAL: Full file injection enabled');
|
|
783
|
+
info(' PreCompact will inject entire command files instead of compact summaries');
|
|
784
|
+
info(' This uses more context tokens but may provide better instruction adherence');
|
|
785
|
+
}
|
|
786
|
+
} else {
|
|
787
|
+
// Disable experimental mode if switching to non-experimental profile
|
|
788
|
+
updateMetadata(
|
|
789
|
+
{
|
|
790
|
+
features: {
|
|
791
|
+
experimental: {
|
|
792
|
+
enabled: false,
|
|
793
|
+
fullFileInjection: false,
|
|
794
|
+
version,
|
|
795
|
+
at: new Date().toISOString(),
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
version
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
|
|
628
803
|
return true;
|
|
629
804
|
}
|
|
630
805
|
|
|
@@ -837,6 +1012,226 @@ function upgradeFeatures(status, version) {
|
|
|
837
1012
|
return upgraded > 0;
|
|
838
1013
|
}
|
|
839
1014
|
|
|
1015
|
+
// ============================================================================
|
|
1016
|
+
// SHELL ALIASES
|
|
1017
|
+
// ============================================================================
|
|
1018
|
+
|
|
1019
|
+
const SHELL_ALIAS_MARKER = '# AgileFlow tmux wrapper';
|
|
1020
|
+
const SHELL_ALIAS_BLOCK = `
|
|
1021
|
+
${SHELL_ALIAS_MARKER}
|
|
1022
|
+
# Use 'af' or 'agileflow' for tmux, 'claude' stays normal
|
|
1023
|
+
alias af="bash .agileflow/scripts/af"
|
|
1024
|
+
alias agileflow="bash .agileflow/scripts/af"
|
|
1025
|
+
`;
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Enable shell aliases by adding them to ~/.bashrc and ~/.zshrc
|
|
1029
|
+
* @returns {object} Result with configured and skipped shells
|
|
1030
|
+
*/
|
|
1031
|
+
function enableShellAliases() {
|
|
1032
|
+
const result = {
|
|
1033
|
+
configured: [],
|
|
1034
|
+
skipped: [],
|
|
1035
|
+
error: null,
|
|
1036
|
+
};
|
|
1037
|
+
|
|
1038
|
+
// Only set up aliases on Unix-like systems
|
|
1039
|
+
if (process.platform === 'win32') {
|
|
1040
|
+
result.skipped.push('Windows (not supported)');
|
|
1041
|
+
return result;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
const homeDir = os.homedir();
|
|
1045
|
+
const rcFiles = [
|
|
1046
|
+
{ name: 'bash', path: path.join(homeDir, '.bashrc') },
|
|
1047
|
+
{ name: 'zsh', path: path.join(homeDir, '.zshrc') },
|
|
1048
|
+
];
|
|
1049
|
+
|
|
1050
|
+
for (const rc of rcFiles) {
|
|
1051
|
+
try {
|
|
1052
|
+
// Check if RC file exists
|
|
1053
|
+
if (!fs.existsSync(rc.path)) {
|
|
1054
|
+
result.skipped.push(`${rc.name} (no ${path.basename(rc.path)})`);
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
const content = fs.readFileSync(rc.path, 'utf8');
|
|
1059
|
+
|
|
1060
|
+
// Check if aliases already exist
|
|
1061
|
+
if (content.includes(SHELL_ALIAS_MARKER)) {
|
|
1062
|
+
result.skipped.push(`${rc.name} (already configured)`);
|
|
1063
|
+
continue;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
// Append aliases to RC file
|
|
1067
|
+
fs.appendFileSync(rc.path, SHELL_ALIAS_BLOCK);
|
|
1068
|
+
result.configured.push(rc.name);
|
|
1069
|
+
} catch (err) {
|
|
1070
|
+
result.skipped.push(`${rc.name} (error: ${err.message})`);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
return result;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Disable shell aliases by removing them from ~/.bashrc and ~/.zshrc
|
|
1079
|
+
* @returns {object} Result with removed shells
|
|
1080
|
+
*/
|
|
1081
|
+
function disableShellAliases() {
|
|
1082
|
+
const result = {
|
|
1083
|
+
removed: [],
|
|
1084
|
+
skipped: [],
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
if (process.platform === 'win32') {
|
|
1088
|
+
return result;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
const homeDir = os.homedir();
|
|
1092
|
+
const rcFiles = [
|
|
1093
|
+
{ name: 'bash', path: path.join(homeDir, '.bashrc') },
|
|
1094
|
+
{ name: 'zsh', path: path.join(homeDir, '.zshrc') },
|
|
1095
|
+
];
|
|
1096
|
+
|
|
1097
|
+
for (const rc of rcFiles) {
|
|
1098
|
+
try {
|
|
1099
|
+
if (!fs.existsSync(rc.path)) {
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
const content = fs.readFileSync(rc.path, 'utf8');
|
|
1104
|
+
|
|
1105
|
+
if (!content.includes(SHELL_ALIAS_MARKER)) {
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
// Remove the alias block
|
|
1110
|
+
const lines = content.split('\n');
|
|
1111
|
+
const filteredLines = [];
|
|
1112
|
+
let inBlock = false;
|
|
1113
|
+
|
|
1114
|
+
for (const line of lines) {
|
|
1115
|
+
if (line.includes(SHELL_ALIAS_MARKER)) {
|
|
1116
|
+
inBlock = true;
|
|
1117
|
+
continue;
|
|
1118
|
+
}
|
|
1119
|
+
if (
|
|
1120
|
+
inBlock &&
|
|
1121
|
+
(line.startsWith('# Use ') ||
|
|
1122
|
+
line.startsWith('alias af=') ||
|
|
1123
|
+
line.startsWith('alias agileflow='))
|
|
1124
|
+
) {
|
|
1125
|
+
continue;
|
|
1126
|
+
}
|
|
1127
|
+
if (inBlock && line.trim() === '') {
|
|
1128
|
+
inBlock = false;
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
inBlock = false;
|
|
1132
|
+
filteredLines.push(line);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
fs.writeFileSync(rc.path, filteredLines.join('\n'), 'utf8');
|
|
1136
|
+
result.removed.push(rc.name);
|
|
1137
|
+
} catch (err) {
|
|
1138
|
+
result.skipped.push(`${rc.name} (error: ${err.message})`);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
return result;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// ============================================================================
|
|
1146
|
+
// CLAUDE.MD REINFORCEMENT
|
|
1147
|
+
// ============================================================================
|
|
1148
|
+
|
|
1149
|
+
const CLAUDE_MD_MARKER = '<!-- AGILEFLOW_BABYSIT_RULES -->';
|
|
1150
|
+
const CLAUDE_MD_CONTENT = `
|
|
1151
|
+
|
|
1152
|
+
${CLAUDE_MD_MARKER}
|
|
1153
|
+
## AgileFlow /babysit Context Preservation Rules
|
|
1154
|
+
|
|
1155
|
+
When \`/agileflow:babysit\` is active (check session-state.json), these rules are MANDATORY:
|
|
1156
|
+
|
|
1157
|
+
1. **ALWAYS end responses with the AskUserQuestion tool** - Not text like "What next?" but the ACTUAL TOOL CALL
|
|
1158
|
+
2. **Use Plan Mode for non-trivial tasks** - Call \`EnterPlanMode\` before complex implementations
|
|
1159
|
+
3. **Delegate complex work to domain experts** - Use \`Task\` tool with appropriate \`subagent_type\`
|
|
1160
|
+
4. **Track progress with TodoWrite** - For any task with 3+ steps
|
|
1161
|
+
|
|
1162
|
+
These rules persist across conversation compaction. Check \`docs/09-agents/session-state.json\` for active commands.
|
|
1163
|
+
${CLAUDE_MD_MARKER}
|
|
1164
|
+
`;
|
|
1165
|
+
|
|
1166
|
+
/**
|
|
1167
|
+
* Enable CLAUDE.md reinforcement by adding babysit rules
|
|
1168
|
+
* @returns {object} Result with success, added, and error
|
|
1169
|
+
*/
|
|
1170
|
+
function enableClaudeMdReinforcement() {
|
|
1171
|
+
const claudeMdPath = path.join(process.cwd(), 'CLAUDE.md');
|
|
1172
|
+
|
|
1173
|
+
try {
|
|
1174
|
+
let existingContent = '';
|
|
1175
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
1176
|
+
existingContent = fs.readFileSync(claudeMdPath, 'utf8');
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// Only append if marker doesn't exist
|
|
1180
|
+
if (existingContent.includes(CLAUDE_MD_MARKER)) {
|
|
1181
|
+
return { success: true, added: false };
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
fs.appendFileSync(claudeMdPath, CLAUDE_MD_CONTENT);
|
|
1185
|
+
return { success: true, added: true };
|
|
1186
|
+
} catch (err) {
|
|
1187
|
+
return { success: false, error: err.message };
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Disable CLAUDE.md reinforcement by removing babysit rules
|
|
1193
|
+
* @returns {object} Result with removed flag
|
|
1194
|
+
*/
|
|
1195
|
+
function disableClaudeMdReinforcement() {
|
|
1196
|
+
const claudeMdPath = path.join(process.cwd(), 'CLAUDE.md');
|
|
1197
|
+
|
|
1198
|
+
if (!fs.existsSync(claudeMdPath)) {
|
|
1199
|
+
return { removed: false };
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
try {
|
|
1203
|
+
const content = fs.readFileSync(claudeMdPath, 'utf8');
|
|
1204
|
+
|
|
1205
|
+
if (!content.includes(CLAUDE_MD_MARKER)) {
|
|
1206
|
+
return { removed: false };
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
// Remove the section between markers (inclusive)
|
|
1210
|
+
const startIdx = content.indexOf(CLAUDE_MD_MARKER);
|
|
1211
|
+
const endMarkerIdx = content.indexOf(CLAUDE_MD_MARKER, startIdx + CLAUDE_MD_MARKER.length);
|
|
1212
|
+
|
|
1213
|
+
if (startIdx === -1 || endMarkerIdx === -1) {
|
|
1214
|
+
return { removed: false };
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
// Find the start of the line containing the first marker
|
|
1218
|
+
let lineStart = content.lastIndexOf('\n', startIdx);
|
|
1219
|
+
if (lineStart === -1) lineStart = 0;
|
|
1220
|
+
|
|
1221
|
+
// Find the end of the line containing the second marker
|
|
1222
|
+
let lineEnd = content.indexOf('\n', endMarkerIdx + CLAUDE_MD_MARKER.length);
|
|
1223
|
+
if (lineEnd === -1) lineEnd = content.length;
|
|
1224
|
+
|
|
1225
|
+
const newContent = content.slice(0, lineStart) + content.slice(lineEnd);
|
|
1226
|
+
|
|
1227
|
+
// Clean up any trailing newlines
|
|
1228
|
+
fs.writeFileSync(claudeMdPath, newContent.trimEnd() + '\n', 'utf8');
|
|
1229
|
+
return { removed: true };
|
|
1230
|
+
} catch (err) {
|
|
1231
|
+
return { removed: false, error: err.message };
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
|
|
840
1235
|
module.exports = {
|
|
841
1236
|
// Constants
|
|
842
1237
|
FEATURES,
|
|
@@ -856,4 +1251,10 @@ module.exports = {
|
|
|
856
1251
|
// Helpers
|
|
857
1252
|
scriptExists,
|
|
858
1253
|
getScriptPath,
|
|
1254
|
+
// Shell aliases
|
|
1255
|
+
enableShellAliases,
|
|
1256
|
+
disableShellAliases,
|
|
1257
|
+
// CLAUDE.md reinforcement
|
|
1258
|
+
enableClaudeMdReinforcement,
|
|
1259
|
+
disableClaudeMdReinforcement,
|
|
859
1260
|
};
|