agileflow 2.71.0 → 2.73.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/package.json +1 -1
- package/scripts/agileflow-configure.js +119 -85
- package/src/core/agents/configuration/archival.md +10 -10
- package/src/core/commands/configure.md +68 -32
- package/tools/cli/installers/core/installer.js +3 -11
- package/src/core/templates/agileflow-configure.js +0 -1033
- package/src/core/templates/agileflow-statusline.sh +0 -355
- package/src/core/templates/agileflow-welcome.js +0 -731
- package/src/core/templates/clear-active-command.js +0 -42
- package/src/core/templates/precompact-context.sh +0 -123
- /package/{src/core/templates → scripts}/init.sh +0 -0
- /package/{src/core/templates → scripts}/resume-session.sh +0 -0
- /package/{src/core/templates → scripts}/validate-tokens.sh +0 -0
- /package/{src/core/templates → scripts}/worktree-create.sh +0 -0
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - RECONFIGURE: Change settings (archival days, etc.)
|
|
12
12
|
*
|
|
13
13
|
* Usage:
|
|
14
|
-
* node scripts/agileflow-configure.js [options]
|
|
14
|
+
* node .agileflow/scripts/agileflow-configure.js [options]
|
|
15
15
|
*
|
|
16
16
|
* Options:
|
|
17
17
|
* --profile=full|basic|minimal|none Apply a preset
|
|
@@ -93,19 +93,19 @@ const PROFILES = {
|
|
|
93
93
|
full: {
|
|
94
94
|
description: 'All features enabled',
|
|
95
95
|
enable: ['sessionstart', 'precompact', 'archival', 'statusline'],
|
|
96
|
-
archivalDays:
|
|
96
|
+
archivalDays: 30,
|
|
97
97
|
},
|
|
98
98
|
basic: {
|
|
99
99
|
description: 'Essential hooks + archival (SessionStart + PreCompact + Archival)',
|
|
100
100
|
enable: ['sessionstart', 'precompact', 'archival'],
|
|
101
101
|
disable: ['statusline'],
|
|
102
|
-
archivalDays:
|
|
102
|
+
archivalDays: 30,
|
|
103
103
|
},
|
|
104
104
|
minimal: {
|
|
105
105
|
description: 'SessionStart + archival only',
|
|
106
106
|
enable: ['sessionstart', 'archival'],
|
|
107
107
|
disable: ['precompact', 'statusline'],
|
|
108
|
-
archivalDays:
|
|
108
|
+
archivalDays: 30,
|
|
109
109
|
},
|
|
110
110
|
none: {
|
|
111
111
|
description: 'Disable all AgileFlow features',
|
|
@@ -155,22 +155,16 @@ const writeJSON = (filePath, data) => {
|
|
|
155
155
|
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n');
|
|
156
156
|
};
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
fs.chmodSync(destPath, '755');
|
|
169
|
-
} catch {}
|
|
170
|
-
return true;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return false;
|
|
158
|
+
// Scripts are located in .agileflow/scripts/ (installed by AgileFlow)
|
|
159
|
+
const SCRIPTS_DIR = path.join(process.cwd(), '.agileflow', 'scripts');
|
|
160
|
+
|
|
161
|
+
const scriptExists = scriptName => {
|
|
162
|
+
const scriptPath = path.join(SCRIPTS_DIR, scriptName);
|
|
163
|
+
return fs.existsSync(scriptPath);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const getScriptPath = scriptName => {
|
|
167
|
+
return `.agileflow/scripts/${scriptName}`;
|
|
174
168
|
};
|
|
175
169
|
|
|
176
170
|
// ============================================================================
|
|
@@ -184,12 +178,14 @@ function detectConfig() {
|
|
|
184
178
|
settingsValid: true,
|
|
185
179
|
settingsIssues: [],
|
|
186
180
|
features: {
|
|
187
|
-
sessionstart: { enabled: false, valid: true, issues: [] },
|
|
188
|
-
precompact: { enabled: false, valid: true, issues: [] },
|
|
189
|
-
archival: { enabled: false, threshold: null },
|
|
190
|
-
statusline: { enabled: false, valid: true, issues: [] },
|
|
181
|
+
sessionstart: { enabled: false, valid: true, issues: [], version: null, outdated: false },
|
|
182
|
+
precompact: { enabled: false, valid: true, issues: [], version: null, outdated: false },
|
|
183
|
+
archival: { enabled: false, threshold: null, version: null, outdated: false },
|
|
184
|
+
statusline: { enabled: false, valid: true, issues: [], version: null, outdated: false },
|
|
191
185
|
},
|
|
192
186
|
metadata: { exists: false, version: null },
|
|
187
|
+
currentVersion: VERSION,
|
|
188
|
+
hasOutdated: false,
|
|
193
189
|
};
|
|
194
190
|
|
|
195
191
|
// Git
|
|
@@ -280,6 +276,20 @@ function detectConfig() {
|
|
|
280
276
|
status.features.archival.enabled = true;
|
|
281
277
|
status.features.archival.threshold = meta.archival.threshold_days;
|
|
282
278
|
}
|
|
279
|
+
|
|
280
|
+
// Read feature versions from metadata and check if outdated
|
|
281
|
+
if (meta.features) {
|
|
282
|
+
Object.entries(meta.features).forEach(([feature, data]) => {
|
|
283
|
+
if (status.features[feature] && data.version) {
|
|
284
|
+
status.features[feature].version = data.version;
|
|
285
|
+
// Check if feature version differs from current VERSION
|
|
286
|
+
if (data.version !== VERSION && status.features[feature].enabled) {
|
|
287
|
+
status.features[feature].outdated = true;
|
|
288
|
+
status.hasOutdated = true;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
283
293
|
}
|
|
284
294
|
}
|
|
285
295
|
|
|
@@ -317,6 +327,10 @@ function printStatus(status) {
|
|
|
317
327
|
statusIcon = '⚠️';
|
|
318
328
|
statusText = 'INVALID FORMAT';
|
|
319
329
|
color = c.yellow;
|
|
330
|
+
} else if (f.enabled && f.outdated) {
|
|
331
|
+
statusIcon = '🔄';
|
|
332
|
+
statusText = `outdated (v${f.version} → v${status.currentVersion})`;
|
|
333
|
+
color = c.yellow;
|
|
320
334
|
}
|
|
321
335
|
|
|
322
336
|
log(` ${statusIcon} ${label}: ${statusText}`, color);
|
|
@@ -348,7 +362,11 @@ function printStatus(status) {
|
|
|
348
362
|
log('\n⚠️ Format issues detected! Run with --migrate to fix.', c.yellow);
|
|
349
363
|
}
|
|
350
364
|
|
|
351
|
-
|
|
365
|
+
if (status.hasOutdated) {
|
|
366
|
+
log('\n🔄 Outdated scripts detected! Run with --upgrade to update.', c.yellow);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return { hasIssues, hasOutdated: status.hasOutdated };
|
|
352
370
|
}
|
|
353
371
|
|
|
354
372
|
// ============================================================================
|
|
@@ -454,6 +472,34 @@ function migrateSettings() {
|
|
|
454
472
|
return migrated;
|
|
455
473
|
}
|
|
456
474
|
|
|
475
|
+
// ============================================================================
|
|
476
|
+
// UPGRADE FEATURES
|
|
477
|
+
// ============================================================================
|
|
478
|
+
|
|
479
|
+
function upgradeFeatures(status) {
|
|
480
|
+
header('🔄 Upgrading Outdated Features...');
|
|
481
|
+
|
|
482
|
+
let upgraded = 0;
|
|
483
|
+
|
|
484
|
+
Object.entries(status.features).forEach(([feature, data]) => {
|
|
485
|
+
if (data.enabled && data.outdated) {
|
|
486
|
+
log(`\nUpgrading ${feature}...`, c.cyan);
|
|
487
|
+
// Re-enable the feature to deploy latest scripts
|
|
488
|
+
if (enableFeature(feature, { archivalDays: data.threshold || 30, isUpgrade: true })) {
|
|
489
|
+
upgraded++;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
if (upgraded === 0) {
|
|
495
|
+
info('No features needed upgrading');
|
|
496
|
+
} else {
|
|
497
|
+
success(`Upgraded ${upgraded} feature(s) to v${VERSION}`);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return upgraded > 0;
|
|
501
|
+
}
|
|
502
|
+
|
|
457
503
|
// ============================================================================
|
|
458
504
|
// ENABLE/DISABLE FEATURES
|
|
459
505
|
// ============================================================================
|
|
@@ -466,7 +512,6 @@ function enableFeature(feature, options = {}) {
|
|
|
466
512
|
}
|
|
467
513
|
|
|
468
514
|
ensureDir('.claude');
|
|
469
|
-
ensureDir('scripts');
|
|
470
515
|
|
|
471
516
|
const settings = readJSON('.claude/settings.json') || {};
|
|
472
517
|
settings.hooks = settings.hooks || {};
|
|
@@ -474,25 +519,13 @@ function enableFeature(feature, options = {}) {
|
|
|
474
519
|
|
|
475
520
|
// Handle hook-based features
|
|
476
521
|
if (config.hook) {
|
|
477
|
-
const scriptPath =
|
|
478
|
-
|
|
479
|
-
//
|
|
480
|
-
if (!
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
scriptPath,
|
|
485
|
-
`#!/usr/bin/env node\nconsole.log('AgileFlow v${VERSION} loaded');\n`
|
|
486
|
-
);
|
|
487
|
-
} else if (feature === 'precompact') {
|
|
488
|
-
fs.writeFileSync(scriptPath, '#!/bin/bash\necho "PreCompact: preserving context"\n');
|
|
489
|
-
}
|
|
490
|
-
try {
|
|
491
|
-
fs.chmodSync(scriptPath, '755');
|
|
492
|
-
} catch {}
|
|
493
|
-
warn(`Created minimal ${config.script}`);
|
|
494
|
-
} else {
|
|
495
|
-
success(`Deployed ${config.script}`);
|
|
522
|
+
const scriptPath = getScriptPath(config.script);
|
|
523
|
+
|
|
524
|
+
// Verify script exists
|
|
525
|
+
if (!scriptExists(config.script)) {
|
|
526
|
+
error(`Script not found: ${scriptPath}`);
|
|
527
|
+
info('Run "npx agileflow update" to reinstall scripts');
|
|
528
|
+
return false;
|
|
496
529
|
}
|
|
497
530
|
|
|
498
531
|
// Configure hook
|
|
@@ -504,18 +537,18 @@ function enableFeature(feature, options = {}) {
|
|
|
504
537
|
hooks: [{ type: 'command', command }],
|
|
505
538
|
},
|
|
506
539
|
];
|
|
507
|
-
success(`${config.hook} hook enabled`);
|
|
540
|
+
success(`${config.hook} hook enabled (${config.script})`);
|
|
508
541
|
}
|
|
509
542
|
|
|
510
543
|
// Handle archival
|
|
511
544
|
if (feature === 'archival') {
|
|
512
|
-
const days = options.archivalDays ||
|
|
513
|
-
const scriptPath = '
|
|
545
|
+
const days = options.archivalDays || 30;
|
|
546
|
+
const scriptPath = getScriptPath('archive-completed-stories.sh');
|
|
514
547
|
|
|
515
|
-
if (!
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
548
|
+
if (!scriptExists('archive-completed-stories.sh')) {
|
|
549
|
+
error(`Script not found: ${scriptPath}`);
|
|
550
|
+
info('Run "npx agileflow update" to reinstall scripts');
|
|
551
|
+
return false;
|
|
519
552
|
}
|
|
520
553
|
|
|
521
554
|
// Add to SessionStart hook
|
|
@@ -526,7 +559,7 @@ function enableFeature(feature, options = {}) {
|
|
|
526
559
|
if (!hasArchival) {
|
|
527
560
|
settings.hooks.SessionStart[0].hooks.push({
|
|
528
561
|
type: 'command',
|
|
529
|
-
command:
|
|
562
|
+
command: `bash ${scriptPath} --quiet`,
|
|
530
563
|
});
|
|
531
564
|
}
|
|
532
565
|
}
|
|
@@ -538,28 +571,17 @@ function enableFeature(feature, options = {}) {
|
|
|
538
571
|
|
|
539
572
|
// Handle statusLine
|
|
540
573
|
if (feature === 'statusline') {
|
|
541
|
-
const scriptPath = '
|
|
542
|
-
|
|
543
|
-
if (!
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
input=$(cat)
|
|
548
|
-
MODEL=$(echo "$input" | jq -r '.model.display_name // "Claude"')
|
|
549
|
-
echo "[$MODEL] AgileFlow"
|
|
550
|
-
`
|
|
551
|
-
);
|
|
552
|
-
try {
|
|
553
|
-
fs.chmodSync(scriptPath, '755');
|
|
554
|
-
} catch {}
|
|
555
|
-
warn('Created minimal statusline script');
|
|
556
|
-
} else {
|
|
557
|
-
success('Deployed agileflow-statusline.sh');
|
|
574
|
+
const scriptPath = getScriptPath('agileflow-statusline.sh');
|
|
575
|
+
|
|
576
|
+
if (!scriptExists('agileflow-statusline.sh')) {
|
|
577
|
+
error(`Script not found: ${scriptPath}`);
|
|
578
|
+
info('Run "npx agileflow update" to reinstall scripts');
|
|
579
|
+
return false;
|
|
558
580
|
}
|
|
559
581
|
|
|
560
582
|
settings.statusLine = {
|
|
561
583
|
type: 'command',
|
|
562
|
-
command:
|
|
584
|
+
command: `bash ${scriptPath}`,
|
|
563
585
|
padding: 0,
|
|
564
586
|
};
|
|
565
587
|
success('Status line enabled');
|
|
@@ -855,7 +877,7 @@ function printHelp() {
|
|
|
855
877
|
${c.bold}AgileFlow Configure${c.reset} - Manage AgileFlow features
|
|
856
878
|
|
|
857
879
|
${c.cyan}Usage:${c.reset}
|
|
858
|
-
node scripts/agileflow-configure.js [options]
|
|
880
|
+
node .agileflow/scripts/agileflow-configure.js [options]
|
|
859
881
|
|
|
860
882
|
${c.cyan}Profiles:${c.reset}
|
|
861
883
|
--profile=full All features (hooks, archival, statusline)
|
|
@@ -877,37 +899,41 @@ ${c.cyan}Statusline Components:${c.reset}
|
|
|
877
899
|
Components: agileflow, model, story, epic, wip, context, cost, git
|
|
878
900
|
|
|
879
901
|
${c.cyan}Settings:${c.reset}
|
|
880
|
-
--archival-days=N Set archival threshold (default:
|
|
902
|
+
--archival-days=N Set archival threshold (default: 30)
|
|
881
903
|
|
|
882
904
|
${c.cyan}Maintenance:${c.reset}
|
|
883
905
|
--migrate Fix old/invalid formats
|
|
906
|
+
--upgrade Re-deploy all enabled features with latest scripts
|
|
884
907
|
--validate Check for issues (same as --detect)
|
|
885
908
|
--detect Show current configuration
|
|
886
909
|
|
|
887
910
|
${c.cyan}Examples:${c.reset}
|
|
888
911
|
# Quick setup with all features
|
|
889
|
-
node scripts/agileflow-configure.js --profile=full
|
|
912
|
+
node .agileflow/scripts/agileflow-configure.js --profile=full
|
|
890
913
|
|
|
891
914
|
# Enable specific features
|
|
892
|
-
node scripts/agileflow-configure.js --enable=sessionstart,precompact,archival
|
|
915
|
+
node .agileflow/scripts/agileflow-configure.js --enable=sessionstart,precompact,archival
|
|
893
916
|
|
|
894
917
|
# Disable a feature
|
|
895
|
-
node scripts/agileflow-configure.js --disable=statusline
|
|
918
|
+
node .agileflow/scripts/agileflow-configure.js --disable=statusline
|
|
896
919
|
|
|
897
920
|
# Show only agileflow branding and context in statusline
|
|
898
|
-
node scripts/agileflow-configure.js --hide=model,story,epic,wip,cost,git
|
|
921
|
+
node .agileflow/scripts/agileflow-configure.js --hide=model,story,epic,wip,cost,git
|
|
899
922
|
|
|
900
923
|
# Re-enable git branch in statusline
|
|
901
|
-
node scripts/agileflow-configure.js --show=git
|
|
924
|
+
node .agileflow/scripts/agileflow-configure.js --show=git
|
|
902
925
|
|
|
903
926
|
# List component status
|
|
904
|
-
node scripts/agileflow-configure.js --components
|
|
927
|
+
node .agileflow/scripts/agileflow-configure.js --components
|
|
905
928
|
|
|
906
929
|
# Fix format issues
|
|
907
|
-
node scripts/agileflow-configure.js --migrate
|
|
930
|
+
node .agileflow/scripts/agileflow-configure.js --migrate
|
|
908
931
|
|
|
909
932
|
# Check current status
|
|
910
|
-
node scripts/agileflow-configure.js --detect
|
|
933
|
+
node .agileflow/scripts/agileflow-configure.js --detect
|
|
934
|
+
|
|
935
|
+
# Upgrade outdated scripts to latest version
|
|
936
|
+
node .agileflow/scripts/agileflow-configure.js --upgrade
|
|
911
937
|
`);
|
|
912
938
|
}
|
|
913
939
|
|
|
@@ -924,9 +950,10 @@ function main() {
|
|
|
924
950
|
let disable = [];
|
|
925
951
|
let show = [];
|
|
926
952
|
let hide = [];
|
|
927
|
-
let archivalDays =
|
|
953
|
+
let archivalDays = 30;
|
|
928
954
|
let migrate = false;
|
|
929
955
|
let detect = false;
|
|
956
|
+
let upgrade = false;
|
|
930
957
|
let components = false;
|
|
931
958
|
let help = false;
|
|
932
959
|
|
|
@@ -952,9 +979,10 @@ function main() {
|
|
|
952
979
|
.split('=')[1]
|
|
953
980
|
.split(',')
|
|
954
981
|
.map(s => s.trim().toLowerCase());
|
|
955
|
-
else if (arg.startsWith('--archival-days=')) archivalDays = parseInt(arg.split('=')[1]) ||
|
|
982
|
+
else if (arg.startsWith('--archival-days=')) archivalDays = parseInt(arg.split('=')[1]) || 30;
|
|
956
983
|
else if (arg === '--migrate') migrate = true;
|
|
957
984
|
else if (arg === '--detect' || arg === '--validate') detect = true;
|
|
985
|
+
else if (arg === '--upgrade') upgrade = true;
|
|
958
986
|
else if (arg === '--components') components = true;
|
|
959
987
|
else if (arg === '--help' || arg === '-h') help = true;
|
|
960
988
|
});
|
|
@@ -979,10 +1007,16 @@ function main() {
|
|
|
979
1007
|
|
|
980
1008
|
// Always detect first
|
|
981
1009
|
const status = detectConfig();
|
|
982
|
-
const hasIssues = printStatus(status);
|
|
1010
|
+
const { hasIssues, hasOutdated } = printStatus(status);
|
|
983
1011
|
|
|
984
1012
|
// Detect only mode
|
|
985
|
-
if (detect && !migrate && !profile && enable.length === 0 && disable.length === 0) {
|
|
1013
|
+
if (detect && !migrate && !upgrade && !profile && enable.length === 0 && disable.length === 0) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
// Upgrade mode
|
|
1018
|
+
if (upgrade) {
|
|
1019
|
+
upgradeFeatures(status);
|
|
986
1020
|
return;
|
|
987
1021
|
}
|
|
988
1022
|
|
|
@@ -36,9 +36,9 @@ ROLE: Auto-Archival Configurator
|
|
|
36
36
|
"header": "Threshold",
|
|
37
37
|
"multiSelect": false,
|
|
38
38
|
"options": [
|
|
39
|
-
{"label": "
|
|
39
|
+
{"label": "30 days (Recommended)", "description": "Archive after 1 month"},
|
|
40
40
|
{"label": "14 days", "description": "Archive after 2 weeks"},
|
|
41
|
-
{"label": "
|
|
41
|
+
{"label": "7 days", "description": "Archive after 1 week"}
|
|
42
42
|
]
|
|
43
43
|
}]</parameter>
|
|
44
44
|
</invoke>
|
|
@@ -71,20 +71,20 @@ Use AskUserQuestion tool to get user preference:
|
|
|
71
71
|
"multiSelect": false,
|
|
72
72
|
"options": [
|
|
73
73
|
{
|
|
74
|
-
"label": "
|
|
75
|
-
"description": "
|
|
74
|
+
"label": "30 days (Recommended)",
|
|
75
|
+
"description": "Monthly archival - default, keeps recent context visible"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
|
-
"label": "
|
|
79
|
-
"description": "
|
|
78
|
+
"label": "14 days",
|
|
79
|
+
"description": "Bi-weekly archival - good balance for fast-moving projects"
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
|
-
"label": "
|
|
83
|
-
"description": "
|
|
82
|
+
"label": "7 days",
|
|
83
|
+
"description": "Weekly archival - for large teams with many stories"
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
|
-
"label": "
|
|
87
|
-
"description": "
|
|
86
|
+
"label": "3 days",
|
|
87
|
+
"description": "Very aggressive - keeps status.json very small"
|
|
88
88
|
}
|
|
89
89
|
]
|
|
90
90
|
}]</parameter>
|
|
@@ -1,38 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Configure advanced AgileFlow features (git, hooks, archival, CI, status line)
|
|
3
|
-
argument-hint: [--profile=full|basic|minimal|none] [--enable/--disable=features] [--migrate]
|
|
3
|
+
argument-hint: [--profile=full|basic|minimal|none] [--enable/--disable=features] [--migrate] [--upgrade]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!-- COMPACT_SUMMARY_START -->
|
|
7
7
|
|
|
8
8
|
## Compact Summary
|
|
9
9
|
|
|
10
|
-
Configuration management with **profiles**, **enable/disable**, and **
|
|
10
|
+
Configuration management with **profiles**, **enable/disable**, **format migration**, and **upgrade detection**.
|
|
11
11
|
|
|
12
12
|
### Workflow (MUST FOLLOW)
|
|
13
13
|
|
|
14
14
|
1. **Run detection**: `node .agileflow/scripts/agileflow-configure.js --detect`
|
|
15
15
|
2. **If ⚠️ INVALID FORMAT shown**: Ask user to fix with `--migrate` BEFORE anything else
|
|
16
|
-
3. **
|
|
16
|
+
3. **If 🔄 OUTDATED shown**: Ask user to upgrade with `--upgrade`
|
|
17
|
+
4. **Present options**: Profiles, enable/disable, or check status
|
|
17
18
|
|
|
18
19
|
### Quick Commands
|
|
19
20
|
|
|
20
21
|
```bash
|
|
21
|
-
node .agileflow/scripts/agileflow-configure.js --detect
|
|
22
|
-
node .agileflow/scripts/agileflow-configure.js --migrate
|
|
23
|
-
node .agileflow/scripts/agileflow-configure.js --
|
|
24
|
-
node .agileflow/scripts/agileflow-configure.js --profile=
|
|
25
|
-
node .agileflow/scripts/agileflow-configure.js --
|
|
26
|
-
node .agileflow/scripts/agileflow-configure.js --
|
|
22
|
+
node .agileflow/scripts/agileflow-configure.js --detect # Check status
|
|
23
|
+
node .agileflow/scripts/agileflow-configure.js --migrate # Fix format issues
|
|
24
|
+
node .agileflow/scripts/agileflow-configure.js --upgrade # Update outdated scripts
|
|
25
|
+
node .agileflow/scripts/agileflow-configure.js --profile=full # Enable all
|
|
26
|
+
node .agileflow/scripts/agileflow-configure.js --profile=none # Disable all
|
|
27
|
+
node .agileflow/scripts/agileflow-configure.js --enable=sessionstart # Enable specific
|
|
28
|
+
node .agileflow/scripts/agileflow-configure.js --disable=archival # Disable specific
|
|
27
29
|
```
|
|
28
30
|
|
|
31
|
+
**Note:** All scripts are located in `.agileflow/scripts/` - no files in project root `scripts/`.
|
|
32
|
+
|
|
29
33
|
### Features
|
|
30
34
|
|
|
31
|
-
`sessionstart`, `precompact`, `
|
|
35
|
+
`sessionstart`, `precompact`, `archival`, `statusline`, `autoupdate`
|
|
32
36
|
|
|
33
37
|
### Critical Rules
|
|
34
38
|
|
|
35
39
|
- **Check for format issues FIRST** - offer to fix before other options
|
|
40
|
+
- **Check for outdated scripts** - offer to upgrade if versions differ
|
|
36
41
|
- **Backup created** on migrate: `.claude/settings.json.backup`
|
|
37
42
|
- **Restart required** - always show red banner after changes
|
|
38
43
|
|
|
@@ -54,10 +59,9 @@ node .agileflow/scripts/agileflow-configure.js --detect
|
|
|
54
59
|
|
|
55
60
|
**CRITICAL**: Check the output for format issues (⚠️ INVALID FORMAT).
|
|
56
61
|
|
|
57
|
-
## STEP 2:
|
|
58
|
-
|
|
59
|
-
If you see `⚠️ INVALID FORMAT` in the detection output, **immediately ask user about fixing**:
|
|
62
|
+
## STEP 2: Handle Issues (Migration or Upgrade)
|
|
60
63
|
|
|
64
|
+
### If ⚠️ INVALID FORMAT detected → Offer Migration
|
|
61
65
|
```xml
|
|
62
66
|
<invoke name="AskUserQuestion">
|
|
63
67
|
<parameter name="questions">[{
|
|
@@ -77,6 +81,26 @@ If user says yes:
|
|
|
77
81
|
node .agileflow/scripts/agileflow-configure.js --migrate
|
|
78
82
|
```
|
|
79
83
|
|
|
84
|
+
### If 🔄 OUTDATED detected → Offer Upgrade
|
|
85
|
+
```xml
|
|
86
|
+
<invoke name="AskUserQuestion">
|
|
87
|
+
<parameter name="questions">[{
|
|
88
|
+
"question": "Outdated scripts detected! Your features were configured with an older AgileFlow version. Update them?",
|
|
89
|
+
"header": "Upgrade",
|
|
90
|
+
"multiSelect": false,
|
|
91
|
+
"options": [
|
|
92
|
+
{"label": "Yes, upgrade scripts (Recommended)", "description": "Re-deploy all enabled features with latest scripts."},
|
|
93
|
+
{"label": "No, keep current versions", "description": "Continue with older scripts (may miss bug fixes)."}
|
|
94
|
+
]
|
|
95
|
+
}]</parameter>
|
|
96
|
+
</invoke>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If user says yes:
|
|
100
|
+
```bash
|
|
101
|
+
node .agileflow/scripts/agileflow-configure.js --upgrade
|
|
102
|
+
```
|
|
103
|
+
|
|
80
104
|
## STEP 3: Configuration Options
|
|
81
105
|
|
|
82
106
|
After fixing issues (or if no issues), present main options:
|
|
@@ -120,13 +144,13 @@ node .agileflow/scripts/agileflow-configure.js --profile=none
|
|
|
120
144
|
|
|
121
145
|
```bash
|
|
122
146
|
# Enable features
|
|
123
|
-
node .agileflow/scripts/agileflow-configure.js --enable=sessionstart,precompact
|
|
147
|
+
node .agileflow/scripts/agileflow-configure.js --enable=sessionstart,precompact
|
|
124
148
|
|
|
125
149
|
# Disable features
|
|
126
150
|
node .agileflow/scripts/agileflow-configure.js --disable=statusline
|
|
127
151
|
|
|
128
152
|
# Both at once
|
|
129
|
-
node .agileflow/scripts/agileflow-configure.js --enable=
|
|
153
|
+
node .agileflow/scripts/agileflow-configure.js --enable=statusline --disable=archival
|
|
130
154
|
|
|
131
155
|
# With custom archival days
|
|
132
156
|
node .agileflow/scripts/agileflow-configure.js --enable=archival --archival-days=14
|
|
@@ -134,12 +158,12 @@ node .agileflow/scripts/agileflow-configure.js --enable=archival --archival-days
|
|
|
134
158
|
|
|
135
159
|
## Profile Details
|
|
136
160
|
|
|
137
|
-
| Profile | SessionStart | PreCompact |
|
|
138
|
-
|
|
139
|
-
| `full` | ✅ | ✅ | ✅
|
|
140
|
-
| `basic` | ✅ | ✅ |
|
|
141
|
-
| `minimal` | ✅ | ❌ |
|
|
142
|
-
| `none` | ❌ | ❌ | ❌ | ❌ |
|
|
161
|
+
| Profile | SessionStart | PreCompact | Archival | StatusLine |
|
|
162
|
+
|---------|-------------|------------|----------|------------|
|
|
163
|
+
| `full` | ✅ | ✅ | ✅ 30 days | ✅ |
|
|
164
|
+
| `basic` | ✅ | ✅ | ✅ 30 days | ❌ |
|
|
165
|
+
| `minimal` | ✅ | ❌ | ✅ 30 days | ❌ |
|
|
166
|
+
| `none` | ❌ | ❌ | ❌ | ❌ |
|
|
143
167
|
|
|
144
168
|
## Interactive Mode (via /configure command)
|
|
145
169
|
|
|
@@ -176,7 +200,6 @@ Based on selection, run appropriate command.
|
|
|
176
200
|
"options": [
|
|
177
201
|
{"label": "SessionStart Hook", "description": "Welcome display with project status"},
|
|
178
202
|
{"label": "PreCompact Hook", "description": "Context preservation on compact"},
|
|
179
|
-
{"label": "Stop Hook", "description": "Warns about uncommitted git changes"},
|
|
180
203
|
{"label": "Archival", "description": "Auto-archive old completed stories"},
|
|
181
204
|
{"label": "Status Line", "description": "Custom status bar"},
|
|
182
205
|
{"label": "Auto-Update", "description": "Automatically update AgileFlow on session start"}
|
|
@@ -188,7 +211,6 @@ Based on selection, run appropriate command.
|
|
|
188
211
|
Map selections:
|
|
189
212
|
- "SessionStart Hook" → `sessionstart`
|
|
190
213
|
- "PreCompact Hook" → `precompact`
|
|
191
|
-
- "Stop Hook" → `stop`
|
|
192
214
|
- "Archival" → `archival`
|
|
193
215
|
- "Status Line" → `statusline`
|
|
194
216
|
- "Auto-Update" → `autoupdate`
|
|
@@ -243,18 +265,17 @@ The script updates `docs/00-meta/agileflow-metadata.json`:
|
|
|
243
265
|
|
|
244
266
|
```json
|
|
245
267
|
{
|
|
246
|
-
"version": "2.
|
|
247
|
-
"updated": "2025-12-
|
|
268
|
+
"version": "2.71.0",
|
|
269
|
+
"updated": "2025-12-29T...",
|
|
248
270
|
"archival": {
|
|
249
271
|
"enabled": true,
|
|
250
272
|
"threshold_days": 7
|
|
251
273
|
},
|
|
252
274
|
"features": {
|
|
253
|
-
"sessionstart": {"enabled": true, "version": "2.
|
|
254
|
-
"precompact": {"enabled": true, "version": "2.
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
"statusline": {"enabled": true, "version": "2.41.0", "at": "..."}
|
|
275
|
+
"sessionstart": {"enabled": true, "version": "2.71.0", "at": "..."},
|
|
276
|
+
"precompact": {"enabled": true, "version": "2.71.0", "at": "..."},
|
|
277
|
+
"archival": {"enabled": true, "version": "2.71.0", "at": "..."},
|
|
278
|
+
"statusline": {"enabled": true, "version": "2.71.0", "at": "..."}
|
|
258
279
|
}
|
|
259
280
|
}
|
|
260
281
|
```
|
|
@@ -296,10 +317,9 @@ After configuration:
|
|
|
296
317
|
Enabled:
|
|
297
318
|
✅ sessionstart
|
|
298
319
|
✅ precompact
|
|
299
|
-
✅
|
|
320
|
+
✅ archival
|
|
300
321
|
|
|
301
322
|
Disabled:
|
|
302
|
-
❌ archival
|
|
303
323
|
❌ statusline
|
|
304
324
|
|
|
305
325
|
═══════════════════════════════════════════════════════
|
|
@@ -307,3 +327,19 @@ Disabled:
|
|
|
307
327
|
Quit completely, wait 5 seconds, restart
|
|
308
328
|
═══════════════════════════════════════════════════════
|
|
309
329
|
```
|
|
330
|
+
|
|
331
|
+
After upgrade:
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
🔄 Upgrading Outdated Features...
|
|
335
|
+
|
|
336
|
+
Upgrading sessionstart...
|
|
337
|
+
✅ Deployed agileflow-welcome.js
|
|
338
|
+
✅ SessionStart hook enabled
|
|
339
|
+
|
|
340
|
+
Upgrading precompact...
|
|
341
|
+
✅ Deployed precompact-context.sh
|
|
342
|
+
✅ PreCompact hook enabled
|
|
343
|
+
|
|
344
|
+
✅ Upgraded 2 feature(s) to v2.71.0
|
|
345
|
+
```
|
|
@@ -46,11 +46,11 @@ class Installer {
|
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Clean up existing content directories before installing.
|
|
49
|
-
* Removes agents/, commands/, skills/, templates/ but preserves _cfg/ and config.yaml.
|
|
49
|
+
* Removes agents/, commands/, skills/, scripts/, templates/ but preserves _cfg/ and config.yaml.
|
|
50
50
|
* @param {string} agileflowDir - AgileFlow installation directory
|
|
51
51
|
*/
|
|
52
52
|
async cleanup(agileflowDir) {
|
|
53
|
-
const dirsToRemove = ['agents', 'commands', 'skills', 'templates'];
|
|
53
|
+
const dirsToRemove = ['agents', 'commands', 'skills', 'scripts', 'templates'];
|
|
54
54
|
|
|
55
55
|
for (const dir of dirsToRemove) {
|
|
56
56
|
const dirPath = path.join(agileflowDir, dir);
|
|
@@ -243,14 +243,6 @@ class Installer {
|
|
|
243
243
|
await fs.ensureDir(skillsDest);
|
|
244
244
|
await this.copyContent(skillsSource, skillsDest, agileflowFolder, policy);
|
|
245
245
|
}
|
|
246
|
-
|
|
247
|
-
// Copy templates
|
|
248
|
-
const templatesSource = path.join(packageRoot, 'templates');
|
|
249
|
-
const templatesDest = path.join(agileflowDir, 'templates');
|
|
250
|
-
if (await fs.pathExists(templatesSource)) {
|
|
251
|
-
await fs.ensureDir(templatesDest);
|
|
252
|
-
await this.copyContent(templatesSource, templatesDest, agileflowFolder, policy);
|
|
253
|
-
}
|
|
254
246
|
}
|
|
255
247
|
|
|
256
248
|
/**
|
|
@@ -430,7 +422,7 @@ class Installer {
|
|
|
430
422
|
const backupRoot = path.join(cfgDir, 'backups', timestamp);
|
|
431
423
|
await fs.ensureDir(backupRoot);
|
|
432
424
|
|
|
433
|
-
const candidates = ['agents', 'commands', 'skills', 'templates', 'config.yaml'];
|
|
425
|
+
const candidates = ['agents', 'commands', 'skills', 'scripts', 'templates', 'config.yaml'];
|
|
434
426
|
for (const name of candidates) {
|
|
435
427
|
const srcPath = path.join(agileflowDir, name);
|
|
436
428
|
if (await fs.pathExists(srcPath)) {
|