agileflow 2.94.1 → 2.95.1
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 +20 -0
- package/README.md +3 -3
- 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
|
@@ -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
|
};
|