projecta-rrr 1.17.0 → 1.18.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 +79 -0
- package/bin/install.js +63 -0
- package/commands/rrr/execute-plan.md +51 -0
- package/commands/rrr/plan-phase.md +41 -0
- package/docs/ohmyposh-config.md +268 -0
- package/hooks/rrr-classify-intent.sh +256 -0
- package/hooks/rrr-detect-drift.sh +145 -0
- package/hooks/rrr-hud.ohmyposh.json +159 -0
- package/hooks/rrr-intent-check.sh +83 -0
- package/hooks/rrr-sync-hud-state.sh +69 -1
- package/hooks/rrr-update-cache-stats.sh +96 -0
- package/hooks/statusline.sh +283 -18
- package/package.json +1 -1
- package/rrr/lib/decision-recall.js +152 -0
- package/rrr/lib/decision-store.js +183 -0
- package/rrr/lib/memory-store.js +75 -1
- package/rrr/lib/orphan-detector.js +108 -0
- package/rrr/lib/reuse-candidates.js +485 -0
- package/rrr/lib/reuse-gate.js +360 -0
- package/rrr/lib/scope-classifier.js +343 -0
- package/rrr/ohmyposh/rrr-env.sh +39 -3
- package/rrr/scripts/classify-request.js +120 -0
- package/rrr/scripts/drift-detect.js +201 -0
- package/rrr/scripts/episode-emit.js +210 -0
- package/rrr/scripts/query-reuse-candidates.js +193 -0
- package/rrr/scripts/recall-decisions.js +47 -0
- package/rrr/scripts/record-decision.js +103 -0
- package/rrr/scripts/save-intent.js +68 -0
- package/rrr/workflows/complete-milestone.md +22 -0
- package/rrr/workflows/execute-plan.md +92 -0
- package/scripts/jarvis.sh +217 -12
- package/scripts/rrr-hud-dynamic.js +16 -1
- package/scripts/verify-hooks.js +212 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,85 @@ 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.18.0] - 2026-01-30
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Real-time Drift Detection** - PostToolUse hooks trigger `detectDrift()` on every file modification
|
|
12
|
+
- **Intent Persistence** - Structured JSON (`current-intent.json`) maintains context across sessions
|
|
13
|
+
- **Episode Logging** - JSONL append-only log (`.planning/episodes/YYYY-MM-DD.jsonl`) enables future Graphiti integration
|
|
14
|
+
- **Scope Classification** - Heuristic classifier routes requests to correct RRR commands (PATCH/BUG/PLAN/PHASE/MILESTONE)
|
|
15
|
+
- **Orphan Detection** - Identifies files modified outside planned scope with alerts
|
|
16
|
+
- **Decision Recall** - Surfaces past decisions during planning from decision-store
|
|
17
|
+
- **Reuse Candidate Gate** - Mandatory semantic/lexical search before code generation in execute-plan workflow
|
|
18
|
+
- **Smart Drift Alerts** - UserPromptSubmit hook with intelligent skip conditions
|
|
19
|
+
|
|
20
|
+
### New Libraries
|
|
21
|
+
|
|
22
|
+
- `rrr/lib/scope-classifier.js` - Request classification
|
|
23
|
+
- `rrr/lib/orphan-detector.js` - Out-of-scope file detection
|
|
24
|
+
- `rrr/lib/decision-store.js` - Structured rationale storage
|
|
25
|
+
- `rrr/lib/decision-recall.js` - Decision query and retrieval
|
|
26
|
+
- `rrr/lib/reuse-candidates.js` - Semantic + lexical candidate search
|
|
27
|
+
- `rrr/lib/reuse-gate.js` - Workflow gate implementation
|
|
28
|
+
|
|
29
|
+
### New Scripts
|
|
30
|
+
|
|
31
|
+
- `rrr/scripts/drift-detect.js` - CLI for drift detection
|
|
32
|
+
- `rrr/scripts/episode-emit.js` - Episode logging
|
|
33
|
+
- `rrr/scripts/save-intent.js` - Intent persistence
|
|
34
|
+
- `rrr/scripts/classify-request.js` - Request classification CLI
|
|
35
|
+
- `rrr/scripts/record-decision.js` - Decision recording
|
|
36
|
+
- `rrr/scripts/recall-decisions.js` - Decision retrieval
|
|
37
|
+
- `rrr/scripts/query-reuse-candidates.js` - Reuse candidate queries
|
|
38
|
+
- `scripts/verify-hooks.js` - Hook verification debug script
|
|
39
|
+
|
|
40
|
+
### New Hooks
|
|
41
|
+
|
|
42
|
+
- `hooks/rrr-detect-drift.sh` - PostToolUse drift detection
|
|
43
|
+
- `hooks/rrr-classify-intent.sh` - UserPromptSubmit intent classification
|
|
44
|
+
- `hooks/rrr-intent-check.sh` - SessionStart drift check
|
|
45
|
+
- `hooks/rrr-update-cache-stats.sh` - Cache stats on session start
|
|
46
|
+
|
|
47
|
+
## [1.17.1] - 2026-01-30
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- Re-release of 1.17.0 with all intent drift detection features
|
|
52
|
+
|
|
53
|
+
## [1.17.0] - 2026-01-30
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **Smart Intent Drift Detection** (`hooks/rrr-classify-intent.sh`) - UserPromptSubmit hook that:
|
|
58
|
+
- Classifies user requests as PATCH/BUG/PLAN/PHASE/MILESTONE
|
|
59
|
+
- Compares with current intent/plan context
|
|
60
|
+
- Outputs drift warning when user is working off-plan
|
|
61
|
+
- Suggests appropriate RRR command to get back on track
|
|
62
|
+
- Smart filtering: skips conversational, questions, patch-level requests
|
|
63
|
+
|
|
64
|
+
- **Enhanced Statusline** (`hooks/statusline.sh`) - ASCII-compatible footer showing:
|
|
65
|
+
- Index health: `IDX:2.2k` (indexed files count)
|
|
66
|
+
- Location: `v1.18/64 (2/2)` (milestone/phase with plan progress)
|
|
67
|
+
- Drift status: `DRIFT:11 files` or `OK`
|
|
68
|
+
- Model, directory, and context usage bar
|
|
69
|
+
- No emojis/Unicode for Claude Code compatibility
|
|
70
|
+
|
|
71
|
+
- **Scope Classifier Integration** - Wired Phase 63's classifier to real-time request analysis
|
|
72
|
+
|
|
73
|
+
- **Intent Check Hook** (`hooks/rrr-intent-check.sh`) - SessionStart hook for initial drift check
|
|
74
|
+
|
|
75
|
+
- **Cache Stats Hook** (`hooks/rrr-update-cache-stats.sh`) - Updates semantic index stats on session start
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- **Install Script** - Now configures UserPromptSubmit hook for intent classification
|
|
80
|
+
- **HUD State** - Added `plans_in_phase` and `plans_completed` tracking
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- **Phase 61+63 Integration** - Properly wired scope classifier and episode emitter to Claude Code hooks
|
|
85
|
+
|
|
7
86
|
## [1.16.9] - 2026-01-28
|
|
8
87
|
|
|
9
88
|
### Fixed
|
package/bin/install.js
CHANGED
|
@@ -1361,6 +1361,69 @@ function install(isGlobal) {
|
|
|
1361
1361
|
}
|
|
1362
1362
|
}
|
|
1363
1363
|
|
|
1364
|
+
// PATCH-01: Configure PostToolUse hook for drift detection
|
|
1365
|
+
// This hook fires after every tool use to detect project drift
|
|
1366
|
+
const detectDriftCommand = isGlobal
|
|
1367
|
+
? '$HOME/.claude/hooks/rrr-detect-drift.sh'
|
|
1368
|
+
: `${localDirName}/hooks/rrr-detect-drift.sh`;
|
|
1369
|
+
|
|
1370
|
+
if (bashStatus.available && hookFileExists(claudeDir, 'rrr-detect-drift.sh')) {
|
|
1371
|
+
if (!settings.hooks) {
|
|
1372
|
+
settings.hooks = {};
|
|
1373
|
+
}
|
|
1374
|
+
if (!settings.hooks.PostToolUse) {
|
|
1375
|
+
settings.hooks.PostToolUse = [];
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// Check if drift detection hook already exists
|
|
1379
|
+
const hasDriftHook = settings.hooks.PostToolUse.some(entry =>
|
|
1380
|
+
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-detect-drift'))
|
|
1381
|
+
);
|
|
1382
|
+
|
|
1383
|
+
if (!hasDriftHook) {
|
|
1384
|
+
settings.hooks.PostToolUse.push({
|
|
1385
|
+
matcher: '*', // Required: match all tools
|
|
1386
|
+
hooks: [
|
|
1387
|
+
{
|
|
1388
|
+
type: 'command',
|
|
1389
|
+
command: detectDriftCommand
|
|
1390
|
+
}
|
|
1391
|
+
]
|
|
1392
|
+
});
|
|
1393
|
+
console.log(` ${green}✓${reset} Configured drift detection hook (PostToolUse)`);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// Configure UserPromptSubmit hook for intent classification (smart drift detection)
|
|
1398
|
+
const classifyIntentCommand = isGlobal
|
|
1399
|
+
? '$HOME/.claude/hooks/rrr-classify-intent.sh'
|
|
1400
|
+
: `${localDirName}/hooks/rrr-classify-intent.sh`;
|
|
1401
|
+
|
|
1402
|
+
if (bashStatus.available) {
|
|
1403
|
+
if (!settings.hooks) {
|
|
1404
|
+
settings.hooks = {};
|
|
1405
|
+
}
|
|
1406
|
+
if (!settings.hooks.UserPromptSubmit) {
|
|
1407
|
+
settings.hooks.UserPromptSubmit = [];
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
const hasClassifyHook = settings.hooks.UserPromptSubmit.some(entry =>
|
|
1411
|
+
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('rrr-classify-intent'))
|
|
1412
|
+
);
|
|
1413
|
+
|
|
1414
|
+
if (!hasClassifyHook) {
|
|
1415
|
+
settings.hooks.UserPromptSubmit.push({
|
|
1416
|
+
hooks: [
|
|
1417
|
+
{
|
|
1418
|
+
type: 'command',
|
|
1419
|
+
command: classifyIntentCommand
|
|
1420
|
+
}
|
|
1421
|
+
]
|
|
1422
|
+
});
|
|
1423
|
+
console.log(` ${green}✓${reset} Configured intent classification hook (UserPromptSubmit)`);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1364
1427
|
// Install Pushpa Mode and MCP setup scripts to the project directory
|
|
1365
1428
|
// For local install, use current directory; for global, also install to cwd if it has package.json
|
|
1366
1429
|
const projectDir = process.cwd();
|
|
@@ -37,6 +37,13 @@ Plan path: $ARGUMENTS
|
|
|
37
37
|
@.planning/STATE.md
|
|
38
38
|
@.planning/config.json (if exists)
|
|
39
39
|
@rrr/lib/memory-store.js
|
|
40
|
+
|
|
41
|
+
**Note:** During execution, `.planning/current-intent.json` is created with the current plan's intent, milestone, phase, and allowed paths. This file is used by drift detection hooks to validate that file changes stay within scope.
|
|
42
|
+
|
|
43
|
+
**Intent lifecycle:**
|
|
44
|
+
- Step 0.3: Save intent on plan start
|
|
45
|
+
- Step 7.55: Clear intent on plan completion
|
|
46
|
+
- Intent persists through checkpoints (not cleared until plan complete)
|
|
40
47
|
</context>
|
|
41
48
|
|
|
42
49
|
<process>
|
|
@@ -85,6 +92,38 @@ Plan path: $ARGUMENTS
|
|
|
85
92
|
" 2>/dev/null || echo "[MEMORY] Tracking skipped"
|
|
86
93
|
```
|
|
87
94
|
|
|
95
|
+
0.3. **Save structured intent (before execution)**
|
|
96
|
+
|
|
97
|
+
After tracking command in memory, save structured intent for drift detection:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Parse plan path to extract identifiers
|
|
101
|
+
PLAN_FILE="$ARGUMENTS"
|
|
102
|
+
PLAN_ID=$(basename "$PLAN_FILE" | sed 's/-PLAN\.md$//')
|
|
103
|
+
PHASE_DIR=$(dirname "$PLAN_FILE")
|
|
104
|
+
PHASE_NAME=$(basename "$PHASE_DIR")
|
|
105
|
+
PHASE_NUM=$(echo "$PHASE_NAME" | cut -d'-' -f1)
|
|
106
|
+
|
|
107
|
+
# Extract milestone from ROADMAP.md
|
|
108
|
+
MILESTONE=$(grep -E "^## Current Milestone:" .planning/ROADMAP.md 2>/dev/null | sed 's/.*Milestone: *\(v[0-9.]*\).*/\1/' || echo "")
|
|
109
|
+
|
|
110
|
+
# Extract allowed paths from plan frontmatter (files_modified)
|
|
111
|
+
ALLOWED_PATHS=$(grep -A100 "^files_modified:" "$PLAN_FILE" 2>/dev/null | grep -E "^ - " | head -20 | sed 's/^ - //' | tr -d '"' | tr '\n' ',' | sed 's/,$//')
|
|
112
|
+
|
|
113
|
+
# Extract intent from plan objective
|
|
114
|
+
INTENT=$(grep -A5 "<objective>" "$PLAN_FILE" 2>/dev/null | head -3 | tail -1 | sed 's/^ *//' || echo "Executing plan $PLAN_ID")
|
|
115
|
+
|
|
116
|
+
# Save intent using save-intent.js
|
|
117
|
+
node ~/.claude/rrr/scripts/save-intent.js \
|
|
118
|
+
--milestone="$MILESTONE" \
|
|
119
|
+
--phase="$PHASE_NUM" \
|
|
120
|
+
--plan="$PLAN_ID" \
|
|
121
|
+
--intent="$INTENT" \
|
|
122
|
+
--allowed-paths="$ALLOWED_PATHS" 2>/dev/null || echo "[INTENT] Save skipped"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This creates `.planning/current-intent.json` with full context for drift detection and HUD display.
|
|
126
|
+
|
|
88
127
|
0.5. **Scope Check (validate plan is in scope)**
|
|
89
128
|
|
|
90
129
|
Before executing, validate the plan's files against current scope:
|
|
@@ -412,6 +451,18 @@ Config: @.planning/config.json (if exists)",
|
|
|
412
451
|
- Do NOT proceed to step 8
|
|
413
452
|
- Return control to user
|
|
414
453
|
|
|
454
|
+
7.55. **Clear intent (plan complete)**
|
|
455
|
+
|
|
456
|
+
After SUMMARY.md is verified, clear the current intent:
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
node ~/.claude/rrr/scripts/save-intent.js --clear 2>/dev/null || echo "[INTENT] Clear skipped"
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
This ensures the next session starts fresh without stale "Continuing: [intent]" display.
|
|
463
|
+
|
|
464
|
+
**Note:** Intent is only cleared on plan completion (SUMMARY.md exists), not on checkpoints. This allows resuming work after session interruptions while the plan is still in progress.
|
|
465
|
+
|
|
415
466
|
7.6. **Refresh Scope Cache (after SUMMARY)**
|
|
416
467
|
```bash
|
|
417
468
|
node ~/.claude/rrr/scripts/refresh-scope-cache.js 2>/dev/null || echo "Cache refresh skipped"
|
|
@@ -420,6 +420,44 @@ echo "${PHASE}" > /tmp/rrr-todo-dismissed-${PHASE}
|
|
|
420
420
|
- Display: `Run /rrr:check-todos to review and manage your TODOs`
|
|
421
421
|
- Exit command
|
|
422
422
|
|
|
423
|
+
## 3.7. Recall Past Decisions
|
|
424
|
+
|
|
425
|
+
**Before planning, surface relevant prior decisions to prevent re-debating settled issues.**
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
# Find relevant decisions for this phase
|
|
429
|
+
node -e "
|
|
430
|
+
const dr = require('./rrr/lib/decision-recall');
|
|
431
|
+
const decisions = dr.recallRelevantDecisions({
|
|
432
|
+
phaseGoal: '${PHASE_GOAL}',
|
|
433
|
+
phaseId: '${PHASE}',
|
|
434
|
+
tags: ['${PHASE_TYPE}'],
|
|
435
|
+
limit: 5
|
|
436
|
+
});
|
|
437
|
+
if (decisions.length > 0) {
|
|
438
|
+
console.log(dr.formatDecisionContext(decisions));
|
|
439
|
+
}
|
|
440
|
+
" 2>/dev/null
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**If relevant decisions found:**
|
|
444
|
+
- Include them in planning context for the planner agent
|
|
445
|
+
- Reference them when making similar choices
|
|
446
|
+
- Note if any prior decision should influence current plan
|
|
447
|
+
|
|
448
|
+
**If no decisions found or script not available:**
|
|
449
|
+
- Continue to step 4 (first-time planning is normal)
|
|
450
|
+
|
|
451
|
+
<context_guidance>
|
|
452
|
+
## Prior Decisions
|
|
453
|
+
|
|
454
|
+
When planning, consider:
|
|
455
|
+
1. Check if similar decisions were made before
|
|
456
|
+
2. Honor prior decisions unless circumstances changed
|
|
457
|
+
3. If revisiting a decision, document why
|
|
458
|
+
4. Reference decision IDs in plan rationale
|
|
459
|
+
</context_guidance>
|
|
460
|
+
|
|
423
461
|
## 4. Ensure Phase Directory Exists (Cross-Platform)
|
|
424
462
|
|
|
425
463
|
**On macOS/Linux:**
|
|
@@ -659,6 +697,9 @@ Fill prompt and spawn:
|
|
|
659
697
|
@{phase_dir}/{phase}-VERIFICATION.md
|
|
660
698
|
@{phase_dir}/{phase}-UAT.md
|
|
661
699
|
|
|
700
|
+
**Prior Decisions (from step 3.7, if any):**
|
|
701
|
+
{prior_decisions_context}
|
|
702
|
+
|
|
662
703
|
</planning_context>
|
|
663
704
|
|
|
664
705
|
<downstream_consumer>
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# OhMyPosh Integration for RRR HUD
|
|
2
|
+
|
|
3
|
+
Display RRR context (intent, drift status, session duration) in your terminal prompt using OhMyPosh.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- [OhMyPosh](https://ohmyposh.dev/) installed
|
|
8
|
+
- RRR installed (`npx @anthropic/claude-rrr@latest`)
|
|
9
|
+
- `jq` installed for JSON parsing
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install OhMyPosh (macOS)
|
|
13
|
+
brew install jandedobbeleer/oh-my-posh/oh-my-posh
|
|
14
|
+
|
|
15
|
+
# Install jq
|
|
16
|
+
brew install jq
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Setup
|
|
20
|
+
|
|
21
|
+
### Option 1: Use RRR Statusline (Recommended)
|
|
22
|
+
|
|
23
|
+
RRR provides a statusline script that outputs all HUD information in a single line. This is the simplest setup and matches Claude Code's native statusline.
|
|
24
|
+
|
|
25
|
+
1. **Copy the segment to your OhMyPosh config:**
|
|
26
|
+
|
|
27
|
+
Add this segment to your `~/.ohmyposh.toml` or JSON config:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"style": "plain",
|
|
33
|
+
"properties": {
|
|
34
|
+
"shell": "bash",
|
|
35
|
+
"command": "cat /dev/stdin | ~/.claude/rrr-npm/hooks/statusline.sh"
|
|
36
|
+
},
|
|
37
|
+
"template": "{{ .Output }}"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. **Output format:**
|
|
42
|
+
|
|
43
|
+
With active intent and drift:
|
|
44
|
+
```
|
|
45
|
+
Continuing: [intent] | !! Drift: HIGH | 45m | Claude | project [###------- 30%]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Without intent/drift (normal state):
|
|
49
|
+
```
|
|
50
|
+
Claude | project [###------- 30%]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Option 2: Individual Segments
|
|
54
|
+
|
|
55
|
+
For more control over styling and placement, use separate segments. Copy these from the RRR config template at `hooks/rrr-hud.ohmyposh.json`.
|
|
56
|
+
|
|
57
|
+
#### Intent Segment
|
|
58
|
+
|
|
59
|
+
Shows current work context (e.g., "Continuing: Implement auth flow").
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"type": "command",
|
|
64
|
+
"style": "powerline",
|
|
65
|
+
"foreground": "#61AFEF",
|
|
66
|
+
"background": "#2D3748",
|
|
67
|
+
"properties": {
|
|
68
|
+
"shell": "bash",
|
|
69
|
+
"command": "jq -r 'if .intent.active then \"Continuing: \" + (.intent.text | .[0:27]) else \"\" end' ~/.claude/rrr/hud-state.json 2>/dev/null"
|
|
70
|
+
},
|
|
71
|
+
"template": "{{ if .Output }} {{ .Output }} {{ end }}"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Drift Segment
|
|
76
|
+
|
|
77
|
+
Shows drift severity with color-coded warning levels.
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"type": "command",
|
|
82
|
+
"style": "powerline",
|
|
83
|
+
"foreground_templates": [
|
|
84
|
+
"{{ if contains \"HIGH\" .Output }}#FF6B6B{{ end }}",
|
|
85
|
+
"{{ if contains \"MEDIUM\" .Output }}#FFE66D{{ end }}",
|
|
86
|
+
"{{ if contains \"LOW\" .Output }}#4ECDC4{{ end }}"
|
|
87
|
+
],
|
|
88
|
+
"background": "#2D3748",
|
|
89
|
+
"properties": {
|
|
90
|
+
"shell": "bash",
|
|
91
|
+
"command": "jq -r 'if .drifting then (if .severity == \"high\" then \"!! HIGH\" elif .severity == \"medium\" then \"! MED\" else \"~ LOW\" end) else \"\" end' .planning/.drift-status.json 2>/dev/null"
|
|
92
|
+
},
|
|
93
|
+
"template": "{{ if .Output }} {{ .Output }} {{ end }}"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Duration Segment
|
|
98
|
+
|
|
99
|
+
Shows time elapsed since intent started.
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"type": "command",
|
|
104
|
+
"style": "plain",
|
|
105
|
+
"foreground": "#ABB2BF",
|
|
106
|
+
"properties": {
|
|
107
|
+
"shell": "bash",
|
|
108
|
+
"command": "st=$(jq -r '.intent.start_time // \"\"' ~/.claude/rrr/hud-state.json 2>/dev/null); if [ -n \"$st\" ] && [ \"$st\" != \"null\" ]; then if [ \"$(uname)\" = \"Darwin\" ]; then se=$(date -j -f '%Y-%m-%dT%H:%M:%S' \"${st%.*}\" +%s 2>/dev/null); else se=$(date -d \"$st\" +%s 2>/dev/null); fi; if [ -n \"$se\" ]; then el=$(($(date +%s)-se)); if [ $el -lt 60 ]; then echo \"${el}s\"; elif [ $el -lt 3600 ]; then echo \"$((el/60))m\"; else echo \"$((el/3600))h$((el%3600/60))m\"; fi; fi; fi"
|
|
109
|
+
},
|
|
110
|
+
"template": "{{ if .Output }} {{ .Output }} {{ end }}"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Color Reference
|
|
115
|
+
|
|
116
|
+
| Element | Color | Hex | Meaning |
|
|
117
|
+
|---------|-------|-----|---------|
|
|
118
|
+
| Intent | Blue | `#61AFEF` | Current work focus |
|
|
119
|
+
| Drift HIGH | Red | `#FF6B6B` | Significant context switch - urgent attention |
|
|
120
|
+
| Drift MEDIUM | Yellow | `#FFE66D` | Some unrelated work - caution |
|
|
121
|
+
| Drift LOW | Teal | `#4ECDC4` | Minor drift detected - gentle notice |
|
|
122
|
+
| Duration | Gray | `#ABB2BF` | Time since intent started |
|
|
123
|
+
|
|
124
|
+
## How It Works
|
|
125
|
+
|
|
126
|
+
The RRR HUD integrates with Claude Code's hook system:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
[SessionStart] -> rrr-sync-hud-state.sh -> ~/.claude/rrr/hud-state.json
|
|
130
|
+
|
|
|
131
|
+
v
|
|
132
|
+
Load intent from
|
|
133
|
+
.planning/current-intent.json
|
|
134
|
+
|
|
135
|
+
[PostToolUse] -> rrr-detect-drift.sh -> .planning/.drift-status.json
|
|
136
|
+
|
|
|
137
|
+
v
|
|
138
|
+
Detect drift after
|
|
139
|
+
file modifications
|
|
140
|
+
|
|
141
|
+
[Statusline] -> statusline.sh -> Terminal prompt
|
|
142
|
+
|
|
|
143
|
+
v
|
|
144
|
+
Read hud-state.json
|
|
145
|
+
and drift-status.json,
|
|
146
|
+
format output
|
|
147
|
+
|
|
148
|
+
[OhMyPosh] -> Render statusline output in prompt
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Data Flow
|
|
152
|
+
|
|
153
|
+
1. **SessionStart hook** (`rrr-sync-hud-state.sh`) loads intent from `.planning/current-intent.json` into `~/.claude/rrr/hud-state.json`
|
|
154
|
+
|
|
155
|
+
2. **PostToolUse hook** (`rrr-detect-drift.sh`) runs drift detection after file changes, writes to `.planning/.drift-status.json`
|
|
156
|
+
|
|
157
|
+
3. **Statusline** (`statusline.sh`) reads both files and formats output for display
|
|
158
|
+
|
|
159
|
+
4. **OhMyPosh** renders the statusline output in your terminal prompt
|
|
160
|
+
|
|
161
|
+
### State Files
|
|
162
|
+
|
|
163
|
+
| File | Location | Updated By | Contains |
|
|
164
|
+
|------|----------|------------|----------|
|
|
165
|
+
| `hud-state.json` | `~/.claude/rrr/` | `rrr-sync-hud-state.sh` | Intent text, start time, active flag |
|
|
166
|
+
| `drift-status.json` | `.planning/` | `rrr-detect-drift.sh` | Drifting flag, severity, details |
|
|
167
|
+
| `current-intent.json` | `.planning/` | `/rrr:execute-plan` | Plan intent, allowed paths |
|
|
168
|
+
|
|
169
|
+
## Troubleshooting
|
|
170
|
+
|
|
171
|
+
### Nothing appears in prompt
|
|
172
|
+
|
|
173
|
+
1. Check if `~/.claude/rrr/hud-state.json` exists:
|
|
174
|
+
```bash
|
|
175
|
+
cat ~/.claude/rrr/hud-state.json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
2. Verify jq is installed:
|
|
179
|
+
```bash
|
|
180
|
+
which jq
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
3. Test statusline directly:
|
|
184
|
+
```bash
|
|
185
|
+
echo '{"model":{"display_name":"Claude"},"workspace":{"current_dir":"/tmp"},"session_id":"test"}' | ~/.claude/rrr-npm/hooks/statusline.sh
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
4. Check OhMyPosh is loading your config:
|
|
189
|
+
```bash
|
|
190
|
+
oh-my-posh debug
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Intent not showing
|
|
194
|
+
|
|
195
|
+
Intent is populated when you start a plan with `/rrr:execute-plan`. To see intent in the statusline:
|
|
196
|
+
|
|
197
|
+
1. Start executing an RRR plan
|
|
198
|
+
2. The SessionStart hook creates `hud-state.json` with the intent
|
|
199
|
+
3. The statusline reads and displays it
|
|
200
|
+
|
|
201
|
+
To test manually:
|
|
202
|
+
```bash
|
|
203
|
+
echo '{"intent":{"active":true,"text":"Test intent","start_time":"2026-01-30T12:00:00Z"}}' > ~/.claude/rrr/hud-state.json
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Drift not showing
|
|
207
|
+
|
|
208
|
+
Drift is only detected after file-modifying operations (Write, Edit, Bash). It reads from `.planning/.drift-status.json` in your project.
|
|
209
|
+
|
|
210
|
+
1. Check if `.planning/.drift-status.json` exists in your project
|
|
211
|
+
2. Verify the file has `"drifting": true` when drift is expected
|
|
212
|
+
3. Test manually:
|
|
213
|
+
```bash
|
|
214
|
+
echo '{"drifting":true,"severity":"high"}' > .planning/.drift-status.json
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Slow prompt
|
|
218
|
+
|
|
219
|
+
The command segments run on every prompt render. If your prompt feels slow:
|
|
220
|
+
|
|
221
|
+
1. Use the unified statusline segment (Option 1) instead of individual segments
|
|
222
|
+
2. Check that `jq` is installed and not being installed on-demand
|
|
223
|
+
3. Ensure file paths are correct (failed file reads add latency)
|
|
224
|
+
|
|
225
|
+
### Colors not appearing
|
|
226
|
+
|
|
227
|
+
OhMyPosh's `foreground_templates` require the output to contain the trigger text. Verify:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Should output "!! HIGH" for red, "! MED" for yellow, "~ LOW" for teal
|
|
231
|
+
jq -r 'if .drifting then (if .severity == "high" then "!! HIGH" elif .severity == "medium" then "! MED" else "~ LOW" end) else "" end' .planning/.drift-status.json
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Integration with Existing Theme
|
|
235
|
+
|
|
236
|
+
To add RRR segments to your existing OhMyPosh theme:
|
|
237
|
+
|
|
238
|
+
1. Open your OhMyPosh config file (e.g., `~/.ohmyposh.toml` or `~/.poshthemes/mytheme.omp.json`)
|
|
239
|
+
|
|
240
|
+
2. Add the RRR segments to your preferred block/position
|
|
241
|
+
|
|
242
|
+
3. Reference the complete example in `hooks/rrr-hud.ohmyposh.json`
|
|
243
|
+
|
|
244
|
+
Example adding to right-aligned block:
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"type": "prompt",
|
|
248
|
+
"alignment": "right",
|
|
249
|
+
"segments": [
|
|
250
|
+
// ... your existing segments ...
|
|
251
|
+
{
|
|
252
|
+
"type": "command",
|
|
253
|
+
"style": "plain",
|
|
254
|
+
"properties": {
|
|
255
|
+
"shell": "bash",
|
|
256
|
+
"command": "cat /dev/stdin | ~/.claude/rrr-npm/hooks/statusline.sh 2>/dev/null"
|
|
257
|
+
},
|
|
258
|
+
"template": "{{ .Output }}"
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## See Also
|
|
265
|
+
|
|
266
|
+
- [OHMPOSH-SETUP.md](./OHMPOSH-SETUP.md) - Full OhMyPosh theme setup with Kushal/Atomic themes
|
|
267
|
+
- `hooks/statusline.sh` - The statusline script source
|
|
268
|
+
- `hooks/rrr-hud.ohmyposh.json` - Full OhMyPosh segment configuration template
|