projecta-rrr 1.18.8 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -0
- package/bin/install.js +201 -1
- package/commands/rrr/complete-milestone.md +43 -2
- package/commands/rrr/discuss-phase.md +33 -0
- package/commands/rrr/execute-phase.md +145 -9
- package/commands/rrr/execute-plan.md +44 -0
- package/commands/rrr/mvp.md +52 -2
- package/commands/rrr/optimize-cpu.md +238 -0
- package/commands/rrr/overnight.md +69 -1
- package/commands/rrr/think.md +94 -0
- package/commands/rrr/update.md +39 -0
- package/docs/OPTIMIZATION_SUMMARY.md +211 -0
- package/docs/SEMANTIC_SEARCH_OPTIMIZATION.md +1207 -0
- package/hooks/rrr-observation-logger.sh +69 -0
- package/hooks/rrr-session-start.sh +60 -0
- package/package.json +2 -1
- package/rrr/hooks/observation-logger.js +264 -0
- package/rrr/hooks/session-start.js +308 -0
- package/rrr/lib/mcp/session-search-tool.js +151 -9
- package/rrr/lib/memory-store.js +186 -2
- package/rrr/lib/scope-classifier.js +148 -0
- package/rrr/lib/search/query-cache.js +3 -2
- package/rrr/lib/search/storage.js +52 -0
- package/rrr/lib/team-coord.js +685 -0
- package/rrr/lib/team-executor.js +307 -0
- package/rrr/lib/team-ready.md +380 -0
- package/rrr/mcp-server/index.js +38 -2
- package/rrr/mcp-server/tools/session-search.js +10 -2
- package/rrr/scripts/state-compact.js +253 -0
- package/rrr/templates/config.json +8 -0
- package/rrr/templates/thinking-models/first-principles.md +103 -0
- package/rrr/templates/thinking-models/five-whys.md +110 -0
- package/rrr/templates/thinking-models/inversion.md +98 -0
- package/rrr/templates/thinking-models/pareto.md +103 -0
- package/rrr/workflows/resume-project.md +18 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,81 @@ All notable changes to RRR will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
6
|
|
|
7
|
+
## [1.19.0] - 2026-02-05
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Auto-Capture Observation Logger** - PostToolUse hook that automatically captures file creates/deletes, test results, git commits, and decision signals to `.planning/observations-YYYY-MM-DD.jsonl` with daily rotation and 1MB limit
|
|
12
|
+
- **Progressive STATE.md Disclosure** - Compact ~30 token state index loaded on session start; full STATE.md only on explicit resume (saves context budget)
|
|
13
|
+
- **SessionStart Auto-Resume Hook** - Handles Claude Code's `source` field (startup/resume/compact/clear) for automatic context restoration
|
|
14
|
+
- **Native Context Window Metrics** - 4-level fallback (HUD state > env var > cached file > estimation) with pressure levels integrated into drift detection
|
|
15
|
+
- **Timeline-Aware Session Queries** - `since`/`until` filters for session search with ISO dates, relative words ("yesterday"), and durations ("3d", "2w")
|
|
16
|
+
- **Complexity-Adaptive Routing** - `/rrr:mvp` auto-detects task complexity (SMALL/MEDIUM/LARGE) and routes to appropriate workflow depth
|
|
17
|
+
- **Configurable Git Branching** - `git_branching` strategy (none/phase/milestone) in config.json with squash-on-complete option
|
|
18
|
+
- **`/rrr:think` Command** - 4 structured thinking models: first-principles, inversion (pre-mortem), pareto (80/20), five-whys (root cause)
|
|
19
|
+
- **TeammateTool / Hidden Swarm Embedding** - File-based team coordination mirroring Claude Code's hidden TeammateTool API with spawnTeam/write/broadcast/cleanup primitives, team-aware executor for wave parallelization, and GA migration path with transport swap
|
|
20
|
+
- **Session Forking Guidance** - Documented session forking as preferred overnight method with fallback to traditional Jarvis
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- `/rrr:mvp` now includes complexity detection preamble before routing
|
|
25
|
+
- `/rrr:execute-phase` supports team coordination for multi-plan waves
|
|
26
|
+
- `/rrr:execute-plan` creates git branches when `git_branching` is configured
|
|
27
|
+
- `/rrr:complete-milestone` handles branch merge and optional squash cleanup
|
|
28
|
+
- `/rrr:discuss-phase` offers optional thinking model integration
|
|
29
|
+
- `/rrr:overnight` uses session forking with 10-min hook timeout
|
|
30
|
+
- Resume workflow uses compact-first progressive disclosure approach
|
|
31
|
+
- Memory store includes context pressure signals in drift detection
|
|
32
|
+
|
|
33
|
+
## [1.18.10] - 2026-02-03
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- **Ferrari-Fast Performance Patch** - Comprehensive optimization implementing all Top 5 research recommendations
|
|
38
|
+
- GrepAI hybrid search configuration (27.5% cost savings, 97% token reduction)
|
|
39
|
+
- MCP process management with V8 heap limits (512MB max) and graceful shutdown
|
|
40
|
+
- LanceDB scalar quantization (4x memory reduction, <1% accuracy loss)
|
|
41
|
+
- Enhanced query caching (1000 queries, 15-minute TTL)
|
|
42
|
+
- Auto-optimization already integrated in v1.18.9 (runs on install for v1.18.9-v1.19.4)
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Query cache size increased: 500 → 1000 embeddings for higher hit rate
|
|
47
|
+
- Query cache TTL optimized: 30min → 15min for faster refresh cycles
|
|
48
|
+
- MCP server now enforces memory limits to prevent zombie processes
|
|
49
|
+
|
|
50
|
+
### Performance
|
|
51
|
+
|
|
52
|
+
- Memory usage: ~800MB → ~200MB (4x reduction with quantization)
|
|
53
|
+
- Query cache capacity: 2x increase for better hit rates
|
|
54
|
+
- Token usage: -27.5% through GrepAI compact output
|
|
55
|
+
- MCP process leaks: Prevented via V8 limits and graceful shutdown
|
|
56
|
+
|
|
57
|
+
### Documentation
|
|
58
|
+
|
|
59
|
+
- Created `.planning/milestones/v1.18/PATCHES.md` with full implementation details
|
|
60
|
+
- Research basis: `docs/SEMANTIC_SEARCH_OPTIMIZATION.md` and `docs/OPTIMIZATION_SUMMARY.md`
|
|
61
|
+
|
|
62
|
+
## [1.18.9] - 2026-02-03
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **`/rrr:optimize-cpu`** - Keep RRR blazing fast with one command
|
|
67
|
+
- Clean search indexes and caches (regenerable)
|
|
68
|
+
- Kill zombie VS Code processes
|
|
69
|
+
- Kill runaway MCP servers
|
|
70
|
+
- Optimize git repository
|
|
71
|
+
- Show before/after performance metrics
|
|
72
|
+
- Modes: default (safe), --aggressive (deep clean), --check-only (stats only)
|
|
73
|
+
- Run weekly to maintain peak performance
|
|
74
|
+
|
|
75
|
+
- **Auto-optimization on install** - New users automatically get "Ferrari-fast" performance
|
|
76
|
+
- Runs automatically during `npx projecta-rrr` for next 5-6 updates (v1.18.9 - v1.19.4)
|
|
77
|
+
- Cleans search indexes, GrepAI cache, and optimizes git on first install
|
|
78
|
+
- Ensures new users see speed improvements immediately
|
|
79
|
+
- Add `--skip-optimization` flag to skip if needed
|
|
80
|
+
- Part of our commitment to deliver speed improvements to all users
|
|
81
|
+
|
|
7
82
|
## [1.18.8] - 2026-02-03
|
|
8
83
|
|
|
9
84
|
### Fixed
|
package/bin/install.js
CHANGED
|
@@ -207,6 +207,7 @@ const forceStatusline = args.includes('--force-statusline');
|
|
|
207
207
|
const forceNotify = args.includes('--force-notify');
|
|
208
208
|
const noNotify = args.includes('--no-notify');
|
|
209
209
|
const hudOnly = args.includes('--hud-only');
|
|
210
|
+
const skipOptimization = args.includes('--skip-optimization');
|
|
210
211
|
|
|
211
212
|
console.log(banner);
|
|
212
213
|
|
|
@@ -222,6 +223,7 @@ if (hasHelp) {
|
|
|
222
223
|
${cyan}--force-statusline${reset} Replace existing statusline config
|
|
223
224
|
${cyan}--force-notify${reset} Replace existing notification hook
|
|
224
225
|
${cyan}--no-notify${reset} Skip notification hook installation
|
|
226
|
+
${cyan}--skip-optimization${reset} Skip automatic performance optimization
|
|
225
227
|
${cyan}--hud-only${reset} Install only HUD components (themes + stop hook)
|
|
226
228
|
|
|
227
229
|
${yellow}Examples:${reset}
|
|
@@ -1410,6 +1412,27 @@ function install(isGlobal) {
|
|
|
1410
1412
|
});
|
|
1411
1413
|
console.log(` ${green}✓${reset} Configured cache stats hook`);
|
|
1412
1414
|
}
|
|
1415
|
+
|
|
1416
|
+
// Configure SessionStart hook for auto-resume context
|
|
1417
|
+
const sessionStartCommand = isGlobal
|
|
1418
|
+
? '$HOME/.claude/hooks/rrr-session-start.sh'
|
|
1419
|
+
: `${localDirName}/hooks/rrr-session-start.sh`;
|
|
1420
|
+
|
|
1421
|
+
const hasSessionStartHook = settings.hooks.SessionStart.some(entry =>
|
|
1422
|
+
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-session-start'))
|
|
1423
|
+
);
|
|
1424
|
+
|
|
1425
|
+
if (!hasSessionStartHook && hookFileExists(claudeDir, 'rrr-session-start.sh')) {
|
|
1426
|
+
settings.hooks.SessionStart.push({
|
|
1427
|
+
hooks: [
|
|
1428
|
+
{
|
|
1429
|
+
type: 'command',
|
|
1430
|
+
command: sessionStartCommand
|
|
1431
|
+
}
|
|
1432
|
+
]
|
|
1433
|
+
});
|
|
1434
|
+
console.log(` ${green}✓${reset} Configured auto-resume hook (SessionStart)`);
|
|
1435
|
+
}
|
|
1413
1436
|
}
|
|
1414
1437
|
|
|
1415
1438
|
// PATCH-01: Configure PostToolUse hook for drift detection
|
|
@@ -1445,6 +1468,37 @@ function install(isGlobal) {
|
|
|
1445
1468
|
}
|
|
1446
1469
|
}
|
|
1447
1470
|
|
|
1471
|
+
// Configure PostToolUse hook for observation logger (auto-capture key events)
|
|
1472
|
+
const observationLoggerCommand = isGlobal
|
|
1473
|
+
? '$HOME/.claude/hooks/rrr-observation-logger.sh'
|
|
1474
|
+
: `${localDirName}/hooks/rrr-observation-logger.sh`;
|
|
1475
|
+
|
|
1476
|
+
if (bashStatus.available && hookFileExists(claudeDir, 'rrr-observation-logger.sh')) {
|
|
1477
|
+
if (!settings.hooks) {
|
|
1478
|
+
settings.hooks = {};
|
|
1479
|
+
}
|
|
1480
|
+
if (!settings.hooks.PostToolUse) {
|
|
1481
|
+
settings.hooks.PostToolUse = [];
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
const hasObservationHook = settings.hooks.PostToolUse.some(entry =>
|
|
1485
|
+
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-observation-logger'))
|
|
1486
|
+
);
|
|
1487
|
+
|
|
1488
|
+
if (!hasObservationHook) {
|
|
1489
|
+
settings.hooks.PostToolUse.push({
|
|
1490
|
+
matcher: '*',
|
|
1491
|
+
hooks: [
|
|
1492
|
+
{
|
|
1493
|
+
type: 'command',
|
|
1494
|
+
command: observationLoggerCommand
|
|
1495
|
+
}
|
|
1496
|
+
]
|
|
1497
|
+
});
|
|
1498
|
+
console.log(` ${green}✓${reset} Configured observation logger hook (PostToolUse)`);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1448
1502
|
// Configure UserPromptSubmit hook for intent classification (smart drift detection)
|
|
1449
1503
|
const classifyIntentCommand = isGlobal
|
|
1450
1504
|
? '$HOME/.claude/hooks/rrr-classify-intent.sh'
|
|
@@ -1654,6 +1708,13 @@ function install(isGlobal) {
|
|
|
1654
1708
|
// Silent fail - context building is optional
|
|
1655
1709
|
}
|
|
1656
1710
|
}
|
|
1711
|
+
|
|
1712
|
+
// Run optimization for new users (v1.18.9 - v1.19.4)
|
|
1713
|
+
// This keeps RRR "Ferrari-fast" by cleaning caches and optimizing git
|
|
1714
|
+
// Only runs if: (1) version is in range, (2) --skip-optimization not passed, (3) has package.json
|
|
1715
|
+
if (!skipOptimization && shouldAutoOptimize() && hasProjectPkg) {
|
|
1716
|
+
runOptimization(projectDir);
|
|
1717
|
+
}
|
|
1657
1718
|
}
|
|
1658
1719
|
|
|
1659
1720
|
return { settingsPath, settings, statuslineCommand, notifyCommand, claudeDir, localDirName, isGlobal, bashAvailable: bashStatus.available };
|
|
@@ -1800,6 +1861,136 @@ function printDoctorSummary(claudeDir, settings, localDirName, isGlobal) {
|
|
|
1800
1861
|
}
|
|
1801
1862
|
}
|
|
1802
1863
|
|
|
1864
|
+
/**
|
|
1865
|
+
* Check if current version should run auto-optimization
|
|
1866
|
+
* Runs for v1.18.9 through v1.19.4 (next 5-6 updates)
|
|
1867
|
+
*/
|
|
1868
|
+
function shouldAutoOptimize() {
|
|
1869
|
+
const currentVersion = pkg.version;
|
|
1870
|
+
|
|
1871
|
+
// Parse version parts
|
|
1872
|
+
const match = currentVersion.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
1873
|
+
if (!match) return false;
|
|
1874
|
+
|
|
1875
|
+
const [_, major, minor, patch] = match.map(Number);
|
|
1876
|
+
|
|
1877
|
+
// Enable for v1.18.9 through v1.19.4
|
|
1878
|
+
if (major !== 1) return false;
|
|
1879
|
+
if (minor === 18 && patch >= 9) return true;
|
|
1880
|
+
if (minor === 19 && patch <= 4) return true;
|
|
1881
|
+
|
|
1882
|
+
return false;
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
/**
|
|
1886
|
+
* Run performance optimization on the installed RRR directory
|
|
1887
|
+
* Cleans search indexes, GrepAI cache, and optimizes git
|
|
1888
|
+
*/
|
|
1889
|
+
function runOptimization(projectDir) {
|
|
1890
|
+
console.log(`\n ${cyan}Optimizing RRR Performance${reset}\n`);
|
|
1891
|
+
|
|
1892
|
+
try {
|
|
1893
|
+
// Get initial metrics
|
|
1894
|
+
const initialStats = {
|
|
1895
|
+
repoSize: execSync('du -sh . 2>/dev/null || echo "unknown"', {
|
|
1896
|
+
cwd: projectDir,
|
|
1897
|
+
encoding: 'utf8',
|
|
1898
|
+
timeout: 10000
|
|
1899
|
+
}).split('\t')[0].trim()
|
|
1900
|
+
};
|
|
1901
|
+
|
|
1902
|
+
console.log(` ${dim}Current repo size: ${initialStats.repoSize}${reset}`);
|
|
1903
|
+
|
|
1904
|
+
let freedSpace = 0;
|
|
1905
|
+
|
|
1906
|
+
// Clean search indexes (regenerable)
|
|
1907
|
+
const searchIndexDir = path.join(projectDir, '.rrr', 'search');
|
|
1908
|
+
if (fs.existsSync(searchIndexDir)) {
|
|
1909
|
+
try {
|
|
1910
|
+
const beforeSize = execSync(`du -sk "${searchIndexDir}" 2>/dev/null || echo "0"`, {
|
|
1911
|
+
encoding: 'utf8',
|
|
1912
|
+
timeout: 5000
|
|
1913
|
+
}).split('\t')[0];
|
|
1914
|
+
|
|
1915
|
+
fs.rmSync(searchIndexDir, { recursive: true, force: true });
|
|
1916
|
+
console.log(` ${green}✓${reset} Removed search indexes (~${Math.round(parseInt(beforeSize) / 1024)}MB)`);
|
|
1917
|
+
freedSpace += parseInt(beforeSize);
|
|
1918
|
+
} catch (e) {
|
|
1919
|
+
// Silent fail - not critical
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
// Clean GrepAI cache (regenerable)
|
|
1924
|
+
const grepaiDir = path.join(projectDir, '.grepai');
|
|
1925
|
+
if (fs.existsSync(grepaiDir)) {
|
|
1926
|
+
try {
|
|
1927
|
+
const beforeSize = execSync(`du -sk "${grepaiDir}" 2>/dev/null || echo "0"`, {
|
|
1928
|
+
encoding: 'utf8',
|
|
1929
|
+
timeout: 5000
|
|
1930
|
+
}).split('\t')[0];
|
|
1931
|
+
|
|
1932
|
+
fs.rmSync(grepaiDir, { recursive: true, force: true });
|
|
1933
|
+
console.log(` ${green}✓${reset} Removed GrepAI cache (~${Math.round(parseInt(beforeSize) / 1024)}MB)`);
|
|
1934
|
+
freedSpace += parseInt(beforeSize);
|
|
1935
|
+
} catch (e) {
|
|
1936
|
+
// Silent fail - not critical
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
// Clean .claude-local duplicates (if not in source repo)
|
|
1941
|
+
const claudeLocalDir = path.join(projectDir, '.claude-local');
|
|
1942
|
+
if (fs.existsSync(claudeLocalDir) && !isRrrSourceRepo()) {
|
|
1943
|
+
try {
|
|
1944
|
+
const beforeSize = execSync(`du -sk "${claudeLocalDir}" 2>/dev/null || echo "0"`, {
|
|
1945
|
+
encoding: 'utf8',
|
|
1946
|
+
timeout: 5000
|
|
1947
|
+
}).split('\t')[0];
|
|
1948
|
+
|
|
1949
|
+
fs.rmSync(claudeLocalDir, { recursive: true, force: true });
|
|
1950
|
+
console.log(` ${green}✓${reset} Removed .claude-local duplicates (~${Math.round(parseInt(beforeSize) / 1024)}MB)`);
|
|
1951
|
+
freedSpace += parseInt(beforeSize);
|
|
1952
|
+
} catch (e) {
|
|
1953
|
+
// Silent fail - not critical
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
// Optimize git repository
|
|
1958
|
+
try {
|
|
1959
|
+
console.log(` ${dim}Optimizing git repository...${reset}`);
|
|
1960
|
+
execSync('git gc --auto 2>&1', {
|
|
1961
|
+
cwd: projectDir,
|
|
1962
|
+
encoding: 'utf8',
|
|
1963
|
+
stdio: 'pipe',
|
|
1964
|
+
timeout: 30000
|
|
1965
|
+
});
|
|
1966
|
+
console.log(` ${green}✓${reset} Git optimized`);
|
|
1967
|
+
} catch (e) {
|
|
1968
|
+
// Silent fail - git gc is optional
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// Get final metrics
|
|
1972
|
+
const finalStats = {
|
|
1973
|
+
repoSize: execSync('du -sh . 2>/dev/null || echo "unknown"', {
|
|
1974
|
+
cwd: projectDir,
|
|
1975
|
+
encoding: 'utf8',
|
|
1976
|
+
timeout: 10000
|
|
1977
|
+
}).split('\t')[0].trim()
|
|
1978
|
+
};
|
|
1979
|
+
|
|
1980
|
+
const freedMB = Math.round(freedSpace / 1024);
|
|
1981
|
+
console.log(`\n ${green}Optimization complete!${reset}`);
|
|
1982
|
+
console.log(` ${dim}Final repo size: ${finalStats.repoSize}${reset}`);
|
|
1983
|
+
if (freedMB > 0) {
|
|
1984
|
+
console.log(` ${dim}Freed ~${freedMB}MB of disk space${reset}`);
|
|
1985
|
+
}
|
|
1986
|
+
console.log(` ${dim}Search indexes will rebuild as needed${reset}\n`);
|
|
1987
|
+
|
|
1988
|
+
} catch (e) {
|
|
1989
|
+
// Don't fail install if optimization fails
|
|
1990
|
+
console.log(` ${yellow}⚠${reset} Optimization skipped: ${e.message}\n`);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1803
1994
|
/**
|
|
1804
1995
|
* Apply statusline and notification config, then print completion message
|
|
1805
1996
|
*/
|
|
@@ -1878,9 +2069,18 @@ function finishInstall(settingsPath, settings, statuslineCommand, notifyCommand,
|
|
|
1878
2069
|
setupScheduledIndexing();
|
|
1879
2070
|
}
|
|
1880
2071
|
|
|
2072
|
+
// Show optimization note if it ran
|
|
2073
|
+
let optimizationNote = '';
|
|
2074
|
+
if (!skipOptimization && shouldAutoOptimize()) {
|
|
2075
|
+
optimizationNote = `
|
|
2076
|
+
${green}Performance optimized!${reset} RRR is ready to run at "Ferrari speed".
|
|
2077
|
+
${dim}(Run ${cyan}/rrr:optimize-cpu${reset} anytime to clean caches and free resources)${reset}
|
|
2078
|
+
`;
|
|
2079
|
+
}
|
|
2080
|
+
|
|
1881
2081
|
console.log(`
|
|
1882
2082
|
${green}Done!${reset}
|
|
1883
|
-
|
|
2083
|
+
${optimizationNote}
|
|
1884
2084
|
${yellow}If you installed from inside Claude Code:${reset}
|
|
1885
2085
|
Type ${cyan}exit${reset} and restart ${cyan}claude${reset} so it reloads commands.
|
|
1886
2086
|
|
|
@@ -100,14 +100,55 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
|
|
|
100
100
|
- Add "Next Milestone Goals" section
|
|
101
101
|
- Archive previous content in `<details>` (if v1.1+)
|
|
102
102
|
|
|
103
|
-
7. **
|
|
103
|
+
7. **Merge branches (if git branching was used):**
|
|
104
|
+
|
|
105
|
+
Check config.json for `git_branching` setting:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
GIT_BRANCHING=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.git_branching || 'none'); } catch(e) { console.log('none'); }" 2>/dev/null)
|
|
109
|
+
SQUASH=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.squash_on_complete ? 'true' : 'false'); } catch(e) { console.log('false'); }" 2>/dev/null)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**If `git_branching` is `phase` or `milestone`:**
|
|
113
|
+
|
|
114
|
+
a. List all RRR branches:
|
|
115
|
+
```bash
|
|
116
|
+
git branch --list 'rrr/*'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
b. For each RRR branch:
|
|
120
|
+
- Ensure we are on the main/default branch
|
|
121
|
+
- Merge or squash-merge based on `squash_on_complete`:
|
|
122
|
+
```bash
|
|
123
|
+
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
|
|
124
|
+
git checkout "$DEFAULT_BRANCH"
|
|
125
|
+
|
|
126
|
+
if [ "$SQUASH" = "true" ]; then
|
|
127
|
+
git merge --squash "$BRANCH_NAME"
|
|
128
|
+
git commit -m "feat: merge ${BRANCH_NAME} (squashed)"
|
|
129
|
+
else
|
|
130
|
+
git merge "$BRANCH_NAME" --no-edit
|
|
131
|
+
fi
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
c. Clean up merged branches:
|
|
135
|
+
```bash
|
|
136
|
+
git branch -d "$BRANCH_NAME"
|
|
137
|
+
echo "[RRR] Merged and deleted branch: $BRANCH_NAME"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
d. Present summary of merged branches to user for confirmation.
|
|
141
|
+
|
|
142
|
+
**If `none`:** Skip this step entirely.
|
|
143
|
+
|
|
144
|
+
8. **Commit and tag:**
|
|
104
145
|
|
|
105
146
|
- Stage: MILESTONES.md, PROJECT.md, ROADMAP.md, STATE.md, archive files
|
|
106
147
|
- Commit: `chore: archive v{{version}} milestone`
|
|
107
148
|
- Tag: `git tag -a v{{version}} -m "[milestone summary]"`
|
|
108
149
|
- Ask about pushing tag
|
|
109
150
|
|
|
110
|
-
|
|
151
|
+
9. **Offer next steps:**
|
|
111
152
|
- `/rrr:discuss-milestone` — thinking partner, creates context file
|
|
112
153
|
- Then `/rrr:new-milestone` — update PROJECT.md with new goals
|
|
113
154
|
|
|
@@ -62,6 +62,39 @@ Phase number: $ARGUMENTS (required)
|
|
|
62
62
|
- Scope expansion (roadmap defines scope)
|
|
63
63
|
</process>
|
|
64
64
|
|
|
65
|
+
<thinking_models>
|
|
66
|
+
**Optional: Apply thinking model during discussion**
|
|
67
|
+
|
|
68
|
+
After step 5 (deep-dive areas) and before step 6 (write CONTEXT.md), offer structured analysis if the discussion revealed complex architectural decisions:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
Noticed some meaty decisions in this discussion. Want to apply a thinking model?
|
|
74
|
+
|
|
75
|
+
| Model | Good For |
|
|
76
|
+
|-------|----------|
|
|
77
|
+
| `/rrr:think first-principles` | Strip assumptions, rebuild approach |
|
|
78
|
+
| `/rrr:think inversion` | Pre-mortem: what could go wrong? |
|
|
79
|
+
| `/rrr:think pareto` | Cut scope to the essential 20% |
|
|
80
|
+
| `/rrr:think five-whys` | Dig into root cause of a design question |
|
|
81
|
+
|
|
82
|
+
Or skip and proceed to CONTEXT.md.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**When to offer:**
|
|
88
|
+
- At least one gray area involved architecture or technology choice
|
|
89
|
+
- Discussion surfaced significant trade-offs
|
|
90
|
+
- User expressed uncertainty about approach
|
|
91
|
+
|
|
92
|
+
**When to skip (just proceed):**
|
|
93
|
+
- All gray areas were UI/UX/content (not architectural)
|
|
94
|
+
- Discussion was quick and clear
|
|
95
|
+
- User has strong opinions already
|
|
96
|
+
</thinking_models>
|
|
97
|
+
|
|
65
98
|
<success_criteria>
|
|
66
99
|
- Gray areas identified through intelligent analysis
|
|
67
100
|
- User chose which areas to discuss
|
|
@@ -100,6 +100,50 @@ Phase: $ARGUMENTS
|
|
|
100
100
|
**If script not found:**
|
|
101
101
|
- Log warning, continue without preflight
|
|
102
102
|
|
|
103
|
+
1.7. **Git branching (if configured)**
|
|
104
|
+
|
|
105
|
+
Check config.json for `git_branching` setting:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
GIT_BRANCHING=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.git_branching || 'none'); } catch(e) { console.log('none'); }" 2>/dev/null)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**If `git_branching` is `phase`:**
|
|
112
|
+
- Create and checkout branch for this phase:
|
|
113
|
+
```bash
|
|
114
|
+
PHASE_NUM=$ARGUMENTS
|
|
115
|
+
PHASE_SLUG=$(basename "$PHASE_DIR" | sed "s/^${PHASE_NUM}-//")
|
|
116
|
+
BRANCH_NAME="rrr/phase-${PHASE_NUM}-${PHASE_SLUG}"
|
|
117
|
+
|
|
118
|
+
if ! git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
|
|
119
|
+
git checkout -b "$BRANCH_NAME"
|
|
120
|
+
echo "[RRR] Created branch: $BRANCH_NAME"
|
|
121
|
+
else
|
|
122
|
+
git checkout "$BRANCH_NAME" 2>/dev/null || echo "[RRR] Already on branch: $BRANCH_NAME"
|
|
123
|
+
fi
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**If `git_branching` is `milestone`:**
|
|
127
|
+
- Branch is created at milestone level (by execute-plan or new-milestone)
|
|
128
|
+
- Ensure we are on the milestone branch if it exists
|
|
129
|
+
|
|
130
|
+
**If `none` (default):** No branching, continue on current branch.
|
|
131
|
+
|
|
132
|
+
1.8. **Team coordination (if configured)**
|
|
133
|
+
|
|
134
|
+
Check config.json for `team_coordination` setting:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
TEAM_COORD=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.team_coordination !== false ? 'true' : 'false'); } catch(e) { console.log('true'); }" 2>/dev/null)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**If `true` (default):** Team coordination enabled for multi-plan waves.
|
|
141
|
+
- Load team libraries: `rrr/lib/team-coord.js` and `rrr/lib/team-executor.js`
|
|
142
|
+
- Team coordination only activates for waves with 2+ plans
|
|
143
|
+
- Single-plan waves always skip team coordination (zero overhead)
|
|
144
|
+
|
|
145
|
+
**If `false`:** Team coordination disabled. Execute with original hub-and-spoke pattern.
|
|
146
|
+
|
|
103
147
|
2. **Discover plans**
|
|
104
148
|
- List all *-PLAN.md files in phase directory
|
|
105
149
|
- Check which have *-SUMMARY.md (already complete)
|
|
@@ -133,11 +177,69 @@ Phase: $ARGUMENTS
|
|
|
133
177
|
- If user chooses to skip: Mark plan as skipped, continue to next
|
|
134
178
|
- If user chooses to continue: Proceed with execution
|
|
135
179
|
|
|
136
|
-
**5b.
|
|
180
|
+
**5b. Team setup (if multi-plan wave and team_coordination enabled):**
|
|
181
|
+
|
|
182
|
+
For waves with 2+ plans when `TEAM_COORD=true`:
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
// Using rrr/lib/team-executor.js
|
|
186
|
+
const team = prepareWaveTeam(phaseNum, waveNum, planIds, planPaths, projectRoot);
|
|
187
|
+
// team is null for single-plan waves (zero overhead)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
This creates `.planning/teams/phase-{N}-wave-{W}/` with:
|
|
191
|
+
- `config.json` — team members, status
|
|
192
|
+
- `messages/{agent-id}/` — per-agent inbox dirs
|
|
193
|
+
- `messages/broadcast/` — group messages
|
|
194
|
+
- `state.json` — team lifecycle state
|
|
195
|
+
|
|
196
|
+
Shared file detection: parse each plan's `## Files Modified` section,
|
|
197
|
+
find files appearing in 2+ plans. These require coordination.
|
|
198
|
+
|
|
199
|
+
**5c. Execute plans:**
|
|
137
200
|
- For each plan, inject `<skills>` block into executor prompt
|
|
201
|
+
- If team exists (multi-plan wave): inject `<team_context>` block with team name, agent ID, peer IDs, shared files
|
|
138
202
|
- Spawn `rrr-executor` for each plan in wave (parallel Task calls)
|
|
139
203
|
- Wait for completion (Task blocks)
|
|
140
|
-
|
|
204
|
+
|
|
205
|
+
**5d. Post-wave team analysis (if team exists):**
|
|
206
|
+
|
|
207
|
+
After all executors in wave complete:
|
|
208
|
+
|
|
209
|
+
1. **Read team messages** (for logging/debugging):
|
|
210
|
+
```javascript
|
|
211
|
+
const { messages } = collectTeamMessages(team);
|
|
212
|
+
// Log: "[RRR] Wave {W}: {N} team messages exchanged"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
2. **Detect file conflicts** (same file modified by 2+ agents):
|
|
216
|
+
```javascript
|
|
217
|
+
const conflicts = detectFileConflicts(team, summaryPaths);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
3. **If conflicts detected:** Present conflict resolution UI:
|
|
221
|
+
```
|
|
222
|
+
── FILE CONFLICT DETECTED ──────────────────────────
|
|
223
|
+
|
|
224
|
+
File: {file_path}
|
|
225
|
+
Modified by: {agent-1}, {agent-2}
|
|
226
|
+
|
|
227
|
+
{agent-1} changes: {summary from team messages}
|
|
228
|
+
{agent-2} changes: {summary from team messages}
|
|
229
|
+
|
|
230
|
+
────────────────────────────────────────────────────
|
|
231
|
+
> Select: merge-both / keep-{agent-1} / keep-{agent-2} / manual
|
|
232
|
+
────────────────────────────────────────────────────
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Use AskUserQuestion for conflict resolution if any non-expected conflicts exist.
|
|
236
|
+
|
|
237
|
+
4. **Cleanup team:**
|
|
238
|
+
```javascript
|
|
239
|
+
cleanupWaveTeam(team); // Archives to .planning/teams/archived/
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
5. **Verify SUMMARYs created**
|
|
141
243
|
- Proceed to next wave
|
|
142
244
|
|
|
143
245
|
6. **Aggregate results**
|
|
@@ -374,22 +476,56 @@ After user runs `/rrr:plan-phase {Z} --gaps`:
|
|
|
374
476
|
</offer_next>
|
|
375
477
|
|
|
376
478
|
<wave_execution>
|
|
377
|
-
**Parallel spawning:**
|
|
479
|
+
**Parallel spawning with team coordination:**
|
|
480
|
+
|
|
481
|
+
**Step 1: Prepare team (multi-plan waves only)**
|
|
482
|
+
|
|
483
|
+
For waves with 2+ plans when `team_coordination` is enabled:
|
|
484
|
+
|
|
485
|
+
```javascript
|
|
486
|
+
// From rrr/lib/team-executor.js
|
|
487
|
+
const team = prepareWaveTeam(phaseNum, waveNum, planIds, planPaths, projectRoot);
|
|
488
|
+
// Returns null for single-plan waves (zero overhead)
|
|
489
|
+
|
|
490
|
+
// Build team context for each executor
|
|
491
|
+
const teamBlock = buildTeamPromptBlock(team, planId);
|
|
492
|
+
// Returns '' for null teams
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Step 2: Spawn executors**
|
|
378
496
|
|
|
379
497
|
Spawn all plans in a wave with a single message containing multiple Task calls.
|
|
380
|
-
Include the `<skills>` block loaded in step 4 for each plan:
|
|
498
|
+
Include the `<skills>` block loaded in step 4 and `<team_context>` block for each plan:
|
|
381
499
|
|
|
382
500
|
```
|
|
383
|
-
Task(prompt="Execute plan at {plan_01_path}\n\n{skills_01_block}\n\nPlan: @{plan_01_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
|
|
384
|
-
Task(prompt="Execute plan at {plan_02_path}\n\n{skills_02_block}\n\nPlan: @{plan_02_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
|
|
385
|
-
Task(prompt="Execute plan at {plan_03_path}\n\n{skills_03_block}\n\nPlan: @{plan_03_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
|
|
501
|
+
Task(prompt="Execute plan at {plan_01_path}\n\n{skills_01_block}\n\n{team_context_01}\n\nPlan: @{plan_01_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
|
|
502
|
+
Task(prompt="Execute plan at {plan_02_path}\n\n{skills_02_block}\n\n{team_context_02}\n\nPlan: @{plan_02_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
|
|
503
|
+
Task(prompt="Execute plan at {plan_03_path}\n\n{skills_03_block}\n\n{team_context_03}\n\nPlan: @{plan_03_path}\nProject state: @.planning/STATE.md", subagent_type="rrr-executor")
|
|
386
504
|
```
|
|
387
505
|
|
|
388
|
-
Where
|
|
506
|
+
Where:
|
|
507
|
+
- `{skills_XX_block}` is the `<skills>` content containing skill SKILL.md files specific to that plan
|
|
508
|
+
- `{team_context_XX}` is the `<team_context>` block from `buildTeamPromptBlock()` (empty for single-plan waves)
|
|
509
|
+
|
|
510
|
+
All executors run in parallel. Task tool blocks until all complete.
|
|
511
|
+
|
|
512
|
+
**Step 3: Post-wave analysis (multi-plan waves only)**
|
|
389
513
|
|
|
390
|
-
|
|
514
|
+
```javascript
|
|
515
|
+
// Collect team messages for logging
|
|
516
|
+
const { messages } = collectTeamMessages(team);
|
|
517
|
+
// Log: "[RRR] Wave {W}: {N} team messages exchanged"
|
|
518
|
+
|
|
519
|
+
// Check for file conflicts
|
|
520
|
+
const conflicts = detectFileConflicts(team, summaryPaths);
|
|
521
|
+
// If conflicts: present resolution UI via AskUserQuestion
|
|
522
|
+
|
|
523
|
+
// Archive team
|
|
524
|
+
cleanupWaveTeam(team);
|
|
525
|
+
```
|
|
391
526
|
|
|
392
527
|
**No polling.** No background agents. No TaskOutput loops.
|
|
528
|
+
**Single-plan waves:** Skip all team logic. Zero overhead. Same as before.
|
|
393
529
|
</wave_execution>
|
|
394
530
|
|
|
395
531
|
<checkpoint_handling>
|
|
@@ -168,6 +168,50 @@ Plan path: $ARGUMENTS
|
|
|
168
168
|
- "Review plan first" → display plan summary, ask again
|
|
169
169
|
- "Cancel" → exit without executing
|
|
170
170
|
|
|
171
|
+
0.7. **Git branching (if configured)**
|
|
172
|
+
|
|
173
|
+
Check config.json for `git_branching` setting:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
GIT_BRANCHING=$(node -e "try { const c = require('./.planning/config.json'); console.log(c.git_branching || 'none'); } catch(e) { console.log('none'); }" 2>/dev/null)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**If `git_branching` is `phase`:**
|
|
180
|
+
- Extract phase number and slug from plan path
|
|
181
|
+
- Check if branch `rrr/phase-{N}-{slug}` already exists
|
|
182
|
+
- If not: create and checkout the branch
|
|
183
|
+
```bash
|
|
184
|
+
PHASE_NUM=$(basename "$(dirname "$ARGUMENTS")" | cut -d'-' -f1)
|
|
185
|
+
PHASE_SLUG=$(basename "$(dirname "$ARGUMENTS")" | sed "s/^${PHASE_NUM}-//")
|
|
186
|
+
BRANCH_NAME="rrr/phase-${PHASE_NUM}-${PHASE_SLUG}"
|
|
187
|
+
|
|
188
|
+
if ! git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
|
|
189
|
+
git checkout -b "$BRANCH_NAME"
|
|
190
|
+
echo "[RRR] Created branch: $BRANCH_NAME"
|
|
191
|
+
else
|
|
192
|
+
git checkout "$BRANCH_NAME" 2>/dev/null || echo "[RRR] Already on branch: $BRANCH_NAME"
|
|
193
|
+
fi
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**If `git_branching` is `milestone`:**
|
|
197
|
+
- Extract milestone version from ROADMAP.md
|
|
198
|
+
- Check if branch `rrr/{version}-{slug}` already exists
|
|
199
|
+
- If not: create and checkout the branch
|
|
200
|
+
```bash
|
|
201
|
+
MILESTONE_VER=$(grep -E "^## Current Milestone:" .planning/ROADMAP.md 2>/dev/null | sed 's/.*: *\(v[0-9.]*\).*/\1/' || echo "vX.X")
|
|
202
|
+
PHASE_SLUG=$(basename "$(dirname "$ARGUMENTS")" | sed 's/^[0-9]*-//')
|
|
203
|
+
BRANCH_NAME="rrr/${MILESTONE_VER}-${PHASE_SLUG}"
|
|
204
|
+
|
|
205
|
+
if ! git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
|
|
206
|
+
git checkout -b "$BRANCH_NAME"
|
|
207
|
+
echo "[RRR] Created branch: $BRANCH_NAME"
|
|
208
|
+
else
|
|
209
|
+
git checkout "$BRANCH_NAME" 2>/dev/null || echo "[RRR] Already on branch: $BRANCH_NAME"
|
|
210
|
+
fi
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**If `none` (default):** No branching, continue on current branch.
|
|
214
|
+
|
|
171
215
|
1. **Validate plan exists**
|
|
172
216
|
- Confirm file at $ARGUMENTS exists
|
|
173
217
|
- Error if not found: "Plan not found: {path}"
|