anvil-dev-framework 0.1.7 → 0.1.9
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/README.md +71 -22
- package/VERSION +1 -1
- package/docs/ANV-263-hook-logging-investigation.md +116 -0
- package/docs/command-reference.md +398 -17
- package/docs/session-workflow.md +62 -9
- package/docs/system-architecture.md +584 -0
- package/global/api/__pycache__/ralph_api.cpython-314.pyc +0 -0
- package/global/api/openapi.yaml +357 -0
- package/global/api/ralph_api.py +528 -0
- package/global/commands/anvil-settings.md +47 -19
- package/global/commands/audit.md +163 -0
- package/global/commands/checklist.md +180 -0
- package/global/commands/coderabbit-fix.md +282 -0
- package/global/commands/efficiency.md +356 -0
- package/global/commands/evidence.md +117 -33
- package/global/commands/hud.md +24 -0
- package/global/commands/insights.md +101 -3
- package/global/commands/orient.md +22 -21
- package/global/commands/patterns.md +115 -0
- package/global/commands/ralph.md +47 -1
- package/global/commands/token-budget.md +214 -0
- package/global/commands/weekly-review.md +21 -1
- package/global/config/notifications.yaml.template +50 -0
- package/global/hooks/ralph_stop.sh +33 -1
- package/global/hooks/statusline.sh +67 -2
- package/global/lib/__pycache__/coderabbit_metrics.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/command_tracker.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/context_optimizer.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/git_utils.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_models.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/optimization_applier.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/ralph_state.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/ralph_webhooks.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/state_manager.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/token_analyzer.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/token_metrics.cpython-314.pyc +0 -0
- package/global/lib/coderabbit_metrics.py +647 -0
- package/global/lib/command_tracker.py +147 -0
- package/global/lib/context_optimizer.py +323 -0
- package/global/lib/linear_provider.py +210 -16
- package/global/lib/log_rotation.py +287 -0
- package/global/lib/optimization_applier.py +582 -0
- package/global/lib/ralph_events.py +398 -0
- package/global/lib/ralph_notifier.py +366 -0
- package/global/lib/ralph_state.py +264 -24
- package/global/lib/ralph_webhooks.py +470 -0
- package/global/lib/state_manager.py +121 -0
- package/global/lib/token_analyzer.py +1383 -0
- package/global/lib/token_metrics.py +919 -0
- package/global/tests/__pycache__/test_command_tracker.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_context_optimizer.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_doc_coverage.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_issue_models.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_linear_filtering.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_linear_provider.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_local_provider.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_optimization_applier.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_token_analyzer.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_token_analyzer_phase6.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/__pycache__/test_token_metrics.cpython-314-pytest-9.0.2.pyc +0 -0
- package/global/tests/test_command_tracker.py +172 -0
- package/global/tests/test_context_optimizer.py +321 -0
- package/global/tests/test_linear_filtering.py +319 -0
- package/global/tests/test_linear_provider.py +40 -1
- package/global/tests/test_optimization_applier.py +508 -0
- package/global/tests/test_token_analyzer.py +735 -0
- package/global/tests/test_token_analyzer_phase6.py +537 -0
- package/global/tests/test_token_metrics.py +829 -0
- package/global/tools/README.md +153 -0
- package/global/tools/__pycache__/anvil-hud.cpython-314.pyc +0 -0
- package/global/tools/__pycache__/orient_linear.cpython-314.pyc +0 -0
- package/global/tools/__pycache__/ralph-watchcpython-314.pyc +0 -0
- package/global/tools/anvil-hud.py +86 -1
- package/global/tools/anvil-memory/src/__tests__/ccs/context-monitor.test.ts +472 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/fixtures.ts +405 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/index.ts +36 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/prompt-generator.test.ts +653 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/ralph-stop.test.ts +727 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/test-utils.ts +340 -0
- package/global/tools/anvil-memory/src/__tests__/commands.test.ts +218 -0
- package/global/tools/anvil-memory/src/commands/context.ts +322 -0
- package/global/tools/anvil-memory/src/db.ts +108 -0
- package/global/tools/anvil-memory/src/index.ts +2 -8
- package/global/tools/orient_linear.py +159 -0
- package/global/tools/ralph-watch +423 -0
- package/package.json +2 -1
- package/project/.anvil-project.yaml.template +93 -0
- package/project/CLAUDE.md.template +343 -0
- package/project/agents/README.md +119 -0
- package/project/agents/cross-layer-debugger.md +217 -0
- package/project/agents/security-code-reviewer.md +162 -0
- package/project/constitution.md.template +235 -0
- package/project/coordination.md +103 -0
- package/project/docs/background-tasks.md +258 -0
- package/project/docs/skills-frontmatter.md +243 -0
- package/project/examples/README.md +106 -0
- package/project/examples/api-route-template.ts +171 -0
- package/project/examples/component-template.tsx +110 -0
- package/project/examples/hook-template.ts +152 -0
- package/project/examples/service-template.ts +207 -0
- package/project/examples/test-template.test.tsx +249 -0
- package/project/hooks/README.md +491 -0
- package/project/hooks/__pycache__/notification.cpython-314.pyc +0 -0
- package/project/hooks/__pycache__/post_tool_use.cpython-314.pyc +0 -0
- package/project/hooks/__pycache__/pre_tool_use.cpython-314.pyc +0 -0
- package/project/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
- package/project/hooks/__pycache__/stop.cpython-314.pyc +0 -0
- package/project/hooks/notification.py +183 -0
- package/project/hooks/permission_request.py +438 -0
- package/project/hooks/post_tool_use.py +397 -0
- package/project/hooks/pre_compact.py +126 -0
- package/project/hooks/pre_tool_use.py +454 -0
- package/project/hooks/session_start.py +656 -0
- package/project/hooks/stop.py +356 -0
- package/project/hooks/subagent_start.py +223 -0
- package/project/hooks/subagent_stop.py +215 -0
- package/project/hooks/user_prompt_submit.py +110 -0
- package/project/hooks/utils/llm/anth.py +114 -0
- package/project/hooks/utils/llm/oai.py +114 -0
- package/project/hooks/utils/tts/elevenlabs_tts.py +63 -0
- package/project/hooks/utils/tts/mlx_audio_tts.py +86 -0
- package/project/hooks/utils/tts/openai_tts.py +92 -0
- package/project/hooks/utils/tts/pyttsx3_tts.py +75 -0
- package/project/linear.yaml.template +23 -0
- package/project/product.md.template +238 -0
- package/project/retros/README.md +126 -0
- package/project/rules/README.md +90 -0
- package/project/rules/debugging.md +139 -0
- package/project/rules/security-review.md +115 -0
- package/project/settings.yaml.template +185 -0
- package/project/specs/SPEC-ANV-72-hud-kanban.md +525 -0
- package/project/templates/api-python/CLAUDE.md +547 -0
- package/project/templates/generic/CLAUDE.md +260 -0
- package/project/templates/saas/CLAUDE.md +478 -0
- package/project/tests/README.md +140 -0
- package/project/tests/__pycache__/test_transcript_parser.cpython-314-pytest-9.0.2.pyc +0 -0
- package/project/tests/fixtures/sample-transcript.jsonl +21 -0
- package/project/tests/test-hooks.sh +259 -0
- package/project/tests/test-lib.sh +248 -0
- package/project/tests/test-statusline.sh +165 -0
- package/project/tests/test_transcript_parser.py +323 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env -S uv run --script
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.8"
|
|
4
|
+
# dependencies = [
|
|
5
|
+
# "openai",
|
|
6
|
+
# "openai[voice_helpers]",
|
|
7
|
+
# "python-dotenv",
|
|
8
|
+
# ]
|
|
9
|
+
# ///
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import asyncio
|
|
14
|
+
from dotenv import load_dotenv
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def main():
|
|
18
|
+
"""
|
|
19
|
+
OpenAI TTS Script
|
|
20
|
+
|
|
21
|
+
Uses OpenAI's latest TTS model for high-quality text-to-speech.
|
|
22
|
+
Accepts optional text prompt as command-line argument.
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
- ./openai_tts.py # Uses default text
|
|
26
|
+
- ./openai_tts.py "Your custom text" # Uses provided text
|
|
27
|
+
|
|
28
|
+
Features:
|
|
29
|
+
- OpenAI gpt-4o-mini-tts model (latest)
|
|
30
|
+
- Nova voice (engaging and warm)
|
|
31
|
+
- Streaming audio with instructions support
|
|
32
|
+
- Live audio playback via LocalAudioPlayer
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
# Load environment variables
|
|
36
|
+
load_dotenv()
|
|
37
|
+
|
|
38
|
+
# Get API key from environment
|
|
39
|
+
api_key = os.getenv("OPENAI_API_KEY")
|
|
40
|
+
if not api_key:
|
|
41
|
+
print("❌ Error: OPENAI_API_KEY not found in environment variables")
|
|
42
|
+
print("Please add your OpenAI API key to .env file:")
|
|
43
|
+
print("OPENAI_API_KEY=your_api_key_here")
|
|
44
|
+
sys.exit(1)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
from openai import AsyncOpenAI
|
|
48
|
+
from openai.helpers import LocalAudioPlayer
|
|
49
|
+
|
|
50
|
+
# Initialize OpenAI client
|
|
51
|
+
openai = AsyncOpenAI(api_key=api_key)
|
|
52
|
+
|
|
53
|
+
print("🎙️ OpenAI TTS")
|
|
54
|
+
print("=" * 20)
|
|
55
|
+
|
|
56
|
+
# Get text from command line argument or use default
|
|
57
|
+
if len(sys.argv) > 1:
|
|
58
|
+
text = " ".join(sys.argv[1:]) # Join all arguments as text
|
|
59
|
+
else:
|
|
60
|
+
text = "Today is a wonderful day to build something people love!"
|
|
61
|
+
|
|
62
|
+
print(f"🎯 Text: {text}")
|
|
63
|
+
print("🔊 Generating and streaming...")
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
# Generate and stream audio using OpenAI TTS
|
|
67
|
+
async with openai.audio.speech.with_streaming_response.create(
|
|
68
|
+
model="gpt-4o-mini-tts",
|
|
69
|
+
voice="nova",
|
|
70
|
+
input=text,
|
|
71
|
+
instructions="Speak in a cheerful, positive yet professional tone.",
|
|
72
|
+
response_format="mp3",
|
|
73
|
+
) as response:
|
|
74
|
+
await LocalAudioPlayer().play(response)
|
|
75
|
+
|
|
76
|
+
print("✅ Playback complete!")
|
|
77
|
+
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print(f"❌ Error: {e}")
|
|
80
|
+
|
|
81
|
+
except ImportError:
|
|
82
|
+
print("❌ Error: Required package not installed")
|
|
83
|
+
print("This script uses UV to auto-install dependencies.")
|
|
84
|
+
print("Make sure UV is installed: https://docs.astral.sh/uv/")
|
|
85
|
+
sys.exit(1)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
print(f"❌ Unexpected error: {e}")
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env -S uv run --script
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.8"
|
|
4
|
+
# dependencies = [
|
|
5
|
+
# "pyttsx3",
|
|
6
|
+
# ]
|
|
7
|
+
# ///
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import random
|
|
11
|
+
|
|
12
|
+
def main():
|
|
13
|
+
"""
|
|
14
|
+
pyttsx3 TTS Script
|
|
15
|
+
|
|
16
|
+
Uses pyttsx3 for offline text-to-speech synthesis.
|
|
17
|
+
Accepts optional text prompt as command-line argument.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
- ./pyttsx3_tts.py # Uses default text
|
|
21
|
+
- ./pyttsx3_tts.py "Your custom text" # Uses provided text
|
|
22
|
+
|
|
23
|
+
Features:
|
|
24
|
+
- Offline TTS (no API key required)
|
|
25
|
+
- Cross-platform compatibility
|
|
26
|
+
- Configurable voice settings
|
|
27
|
+
- Immediate audio playback
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
import pyttsx3
|
|
32
|
+
|
|
33
|
+
# Initialize TTS engine
|
|
34
|
+
engine = pyttsx3.init()
|
|
35
|
+
|
|
36
|
+
# Configure engine settings
|
|
37
|
+
engine.setProperty('rate', 180) # Speech rate (words per minute)
|
|
38
|
+
engine.setProperty('volume', 0.8) # Volume (0.0 to 1.0)
|
|
39
|
+
|
|
40
|
+
print("🎙️ pyttsx3 TTS")
|
|
41
|
+
print("=" * 15)
|
|
42
|
+
|
|
43
|
+
# Get text from command line argument or use default
|
|
44
|
+
if len(sys.argv) > 1:
|
|
45
|
+
text = " ".join(sys.argv[1:]) # Join all arguments as text
|
|
46
|
+
else:
|
|
47
|
+
# Default completion messages
|
|
48
|
+
completion_messages = [
|
|
49
|
+
"Work complete!",
|
|
50
|
+
"All done!",
|
|
51
|
+
"Task finished!",
|
|
52
|
+
"Job complete!",
|
|
53
|
+
"Ready for next task!"
|
|
54
|
+
]
|
|
55
|
+
text = random.choice(completion_messages)
|
|
56
|
+
|
|
57
|
+
print(f"🎯 Text: {text}")
|
|
58
|
+
print("🔊 Speaking...")
|
|
59
|
+
|
|
60
|
+
# Speak the text
|
|
61
|
+
engine.say(text)
|
|
62
|
+
engine.runAndWait()
|
|
63
|
+
|
|
64
|
+
print("✅ Playback complete!")
|
|
65
|
+
|
|
66
|
+
except ImportError:
|
|
67
|
+
print("❌ Error: pyttsx3 package not installed")
|
|
68
|
+
print("This script uses UV to auto-install dependencies.")
|
|
69
|
+
sys.exit(1)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
print(f"❌ Error: {e}")
|
|
72
|
+
sys.exit(1)
|
|
73
|
+
|
|
74
|
+
if __name__ == "__main__":
|
|
75
|
+
main()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Linear Integration Configuration
|
|
2
|
+
#
|
|
3
|
+
# This file maps your local project to a Linear team/project.
|
|
4
|
+
# Commands like /orient, /sprint, /tasks will use this to filter issues.
|
|
5
|
+
#
|
|
6
|
+
# Run `/linear-setup` to configure interactively, or edit manually.
|
|
7
|
+
|
|
8
|
+
# Required: Linear team key (e.g., "AMP", "ANV", "ENG")
|
|
9
|
+
# Find this in Linear: Settings → Teams → [Team] → Key
|
|
10
|
+
team_key: ""
|
|
11
|
+
|
|
12
|
+
# Optional: Specific Linear project within the team
|
|
13
|
+
# Leave empty to see all team issues
|
|
14
|
+
project_name: ""
|
|
15
|
+
|
|
16
|
+
# Auto-generated: Issue prefix for this team (usually same as team_key)
|
|
17
|
+
issue_prefix: ""
|
|
18
|
+
|
|
19
|
+
# Auto-generated: Team UUID (set by /linear-setup)
|
|
20
|
+
team_id: ""
|
|
21
|
+
|
|
22
|
+
# Auto-generated: Project UUID (set by /linear-setup)
|
|
23
|
+
project_id: ""
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Product Definition
|
|
2
|
+
|
|
3
|
+
> What we're building, why, and for whom.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick Start (Answer These First)
|
|
8
|
+
|
|
9
|
+
Fill in these essential questions to get started. Expand into the detailed sections below as your project matures.
|
|
10
|
+
|
|
11
|
+
### What does this project do in one sentence?
|
|
12
|
+
> [Your answer here]
|
|
13
|
+
|
|
14
|
+
### Who are the primary users and what problem do they have?
|
|
15
|
+
> [Your answer here]
|
|
16
|
+
|
|
17
|
+
### What technologies are you using and why?
|
|
18
|
+
> [Your answer here]
|
|
19
|
+
|
|
20
|
+
### What are you working on RIGHT NOW?
|
|
21
|
+
> [Your answer here]
|
|
22
|
+
|
|
23
|
+
### What comes after the current focus? What's explicitly out of scope?
|
|
24
|
+
> [Your answer here]
|
|
25
|
+
|
|
26
|
+
### How do you know if this project is successful?
|
|
27
|
+
> [Your answer here]
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Detailed Sections
|
|
32
|
+
|
|
33
|
+
*Expand into these sections as needed. Not all sections are required initially.*
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Mission
|
|
38
|
+
|
|
39
|
+
### One-Line Mission
|
|
40
|
+
[A single sentence describing what this product does and why it matters]
|
|
41
|
+
|
|
42
|
+
### Elevator Pitch
|
|
43
|
+
[Product name] is a [category] that helps [target user] to [primary benefit] by [key differentiator]. Unlike [alternatives], we [unique value].
|
|
44
|
+
|
|
45
|
+
### Why This Matters
|
|
46
|
+
[2-3 sentences on the problem being solved and why it's worth solving]
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Core Value Propositions
|
|
51
|
+
|
|
52
|
+
### 1. [Value Prop 1 Name]
|
|
53
|
+
**What**: [Brief description]
|
|
54
|
+
**Why it matters**: [Benefit to user]
|
|
55
|
+
**How we deliver**: [Key feature/approach]
|
|
56
|
+
|
|
57
|
+
### 2. [Value Prop 2 Name]
|
|
58
|
+
**What**: [Brief description]
|
|
59
|
+
**Why it matters**: [Benefit to user]
|
|
60
|
+
**How we deliver**: [Key feature/approach]
|
|
61
|
+
|
|
62
|
+
### 3. [Value Prop 3 Name]
|
|
63
|
+
**What**: [Brief description]
|
|
64
|
+
**Why it matters**: [Benefit to user]
|
|
65
|
+
**How we deliver**: [Key feature/approach]
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Target Users
|
|
70
|
+
|
|
71
|
+
### Primary Persona: [Name]
|
|
72
|
+
- **Who**: [Demographics, role]
|
|
73
|
+
- **Goals**: [What they want to achieve]
|
|
74
|
+
- **Pain Points**: [Current frustrations]
|
|
75
|
+
- **Why Us**: [Why our solution fits]
|
|
76
|
+
|
|
77
|
+
### Secondary Persona: [Name]
|
|
78
|
+
- **Who**: [Demographics, role]
|
|
79
|
+
- **Goals**: [What they want to achieve]
|
|
80
|
+
- **Pain Points**: [Current frustrations]
|
|
81
|
+
- **Why Us**: [Why our solution fits]
|
|
82
|
+
|
|
83
|
+
### Anti-Personas (Who We're NOT For)
|
|
84
|
+
- [Description of users we explicitly don't target]
|
|
85
|
+
- [Description of users we explicitly don't target]
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Product Principles
|
|
90
|
+
|
|
91
|
+
These guide all product decisions:
|
|
92
|
+
|
|
93
|
+
1. **[Principle 1]**: [Explanation]
|
|
94
|
+
2. **[Principle 2]**: [Explanation]
|
|
95
|
+
3. **[Principle 3]**: [Explanation]
|
|
96
|
+
4. **[Principle 4]**: [Explanation]
|
|
97
|
+
5. **[Principle 5]**: [Explanation]
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Tech Stack Rationale
|
|
102
|
+
|
|
103
|
+
### Why [Framework]
|
|
104
|
+
- [Reason 1]
|
|
105
|
+
- [Reason 2]
|
|
106
|
+
- [Trade-off acknowledged]
|
|
107
|
+
|
|
108
|
+
### Why [Database]
|
|
109
|
+
- [Reason 1]
|
|
110
|
+
- [Reason 2]
|
|
111
|
+
- [Trade-off acknowledged]
|
|
112
|
+
|
|
113
|
+
### Why [Hosting]
|
|
114
|
+
- [Reason 1]
|
|
115
|
+
- [Reason 2]
|
|
116
|
+
- [Trade-off acknowledged]
|
|
117
|
+
|
|
118
|
+
### What We Explicitly Avoided
|
|
119
|
+
- **[Technology]**: [Why we didn't choose it]
|
|
120
|
+
- **[Technology]**: [Why we didn't choose it]
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Current Roadmap
|
|
125
|
+
|
|
126
|
+
### Now (Current Sprint)
|
|
127
|
+
| Priority | Feature | Status |
|
|
128
|
+
|----------|---------|--------|
|
|
129
|
+
| P0 | [Feature] | In Progress |
|
|
130
|
+
| P1 | [Feature] | Todo |
|
|
131
|
+
|
|
132
|
+
### Next (Next Sprint)
|
|
133
|
+
| Priority | Feature | Dependencies |
|
|
134
|
+
|----------|---------|--------------|
|
|
135
|
+
| P1 | [Feature] | [Current feature] |
|
|
136
|
+
| P2 | [Feature] | None |
|
|
137
|
+
|
|
138
|
+
### Later (Backlog)
|
|
139
|
+
| Priority | Feature | Notes |
|
|
140
|
+
|----------|---------|-------|
|
|
141
|
+
| P2 | [Feature] | [Context] |
|
|
142
|
+
| P3 | [Feature] | [Context] |
|
|
143
|
+
|
|
144
|
+
### Not Doing (Explicitly Rejected)
|
|
145
|
+
| Feature | Reason |
|
|
146
|
+
|---------|--------|
|
|
147
|
+
| [Feature] | [Why not] |
|
|
148
|
+
| [Feature] | [Why not] |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Success Metrics
|
|
153
|
+
|
|
154
|
+
### North Star Metric
|
|
155
|
+
**[Metric Name]**: [Definition]
|
|
156
|
+
**Target**: [Specific target]
|
|
157
|
+
**Why This Metric**: [Explanation]
|
|
158
|
+
|
|
159
|
+
### Leading Indicators
|
|
160
|
+
| Metric | Target | Frequency |
|
|
161
|
+
|--------|--------|-----------|
|
|
162
|
+
| [Metric] | [Target] | Daily |
|
|
163
|
+
| [Metric] | [Target] | Weekly |
|
|
164
|
+
|
|
165
|
+
### Lagging Indicators
|
|
166
|
+
| Metric | Target | Frequency |
|
|
167
|
+
|--------|--------|-----------|
|
|
168
|
+
| [Metric] | [Target] | Monthly |
|
|
169
|
+
| [Metric] | [Target] | Quarterly |
|
|
170
|
+
|
|
171
|
+
### What We Don't Optimize For
|
|
172
|
+
- [Metric we explicitly deprioritize and why]
|
|
173
|
+
- [Metric we explicitly deprioritize and why]
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Competitive Landscape
|
|
178
|
+
|
|
179
|
+
### Direct Competitors
|
|
180
|
+
| Competitor | Strength | Weakness | Our Differentiation |
|
|
181
|
+
|------------|----------|----------|---------------------|
|
|
182
|
+
| [Name] | [Strength] | [Weakness] | [How we're different] |
|
|
183
|
+
| [Name] | [Strength] | [Weakness] | [How we're different] |
|
|
184
|
+
|
|
185
|
+
### Indirect Competitors / Alternatives
|
|
186
|
+
| Alternative | When Users Choose It | Our Response |
|
|
187
|
+
|-------------|---------------------|--------------|
|
|
188
|
+
| [Name] | [Scenario] | [Our counter] |
|
|
189
|
+
| [Name] | [Scenario] | [Our counter] |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Constraints
|
|
194
|
+
|
|
195
|
+
### Technical Constraints
|
|
196
|
+
- [Constraint and why]
|
|
197
|
+
- [Constraint and why]
|
|
198
|
+
|
|
199
|
+
### Business Constraints
|
|
200
|
+
- [Constraint and why]
|
|
201
|
+
- [Constraint and why]
|
|
202
|
+
|
|
203
|
+
### Design Constraints
|
|
204
|
+
- [Constraint and why]
|
|
205
|
+
- [Constraint and why]
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Open Questions
|
|
210
|
+
|
|
211
|
+
Questions we haven't resolved yet:
|
|
212
|
+
|
|
213
|
+
1. **[Question]**
|
|
214
|
+
- Context: [Why this matters]
|
|
215
|
+
- Options: [A, B, C]
|
|
216
|
+
- Deadline: [When we need to decide]
|
|
217
|
+
|
|
218
|
+
2. **[Question]**
|
|
219
|
+
- Context: [Why this matters]
|
|
220
|
+
- Options: [A, B, C]
|
|
221
|
+
- Deadline: [When we need to decide]
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Decision Log
|
|
226
|
+
|
|
227
|
+
Major product decisions and their rationale:
|
|
228
|
+
|
|
229
|
+
### [Date]: [Decision]
|
|
230
|
+
- **Context**: [Why this came up]
|
|
231
|
+
- **Options Considered**: [A, B, C]
|
|
232
|
+
- **Decision**: [What we chose]
|
|
233
|
+
- **Rationale**: [Why]
|
|
234
|
+
- **Trade-offs Accepted**: [What we gave up]
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
*Update this document as the product evolves. This is the single source of truth for what we're building and why.*
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Retrospectives
|
|
2
|
+
|
|
3
|
+
> Learn from what happened. Keep it simple.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
**Write retros that you'll actually write.**
|
|
10
|
+
|
|
11
|
+
Complex formats create friction → retros don't get written → learning doesn't happen.
|
|
12
|
+
|
|
13
|
+
Simple format: Narrative first, structure optional.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## When to Write Retros
|
|
18
|
+
|
|
19
|
+
- After completing a significant feature
|
|
20
|
+
- After a bug that took >1 hour to diagnose
|
|
21
|
+
- After discovering unexpected complexity
|
|
22
|
+
- After any "I wish I had known..." moment
|
|
23
|
+
- Weekly (even if brief)
|
|
24
|
+
|
|
25
|
+
## When NOT to Write Retros
|
|
26
|
+
|
|
27
|
+
- After trivial changes
|
|
28
|
+
- When there's nothing to learn
|
|
29
|
+
- When it would be pure ceremony
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Format: Narrative First
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
# [Issue ID]: [Brief descriptive title]
|
|
37
|
+
|
|
38
|
+
**Outcome:** success | partial | failed
|
|
39
|
+
**Date:** YYYY-MM-DD
|
|
40
|
+
|
|
41
|
+
## What Happened
|
|
42
|
+
[Narrative: What did you try? What worked? What didn't? Why?]
|
|
43
|
+
|
|
44
|
+
## Key Learning
|
|
45
|
+
[One concrete thing you learned]
|
|
46
|
+
|
|
47
|
+
## For Next Time
|
|
48
|
+
[One specific thing to do differently]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That's it. Three sections, narrative style.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Example Retro
|
|
56
|
+
|
|
57
|
+
```markdown
|
|
58
|
+
# ENG-42: Password Reset Token Generation
|
|
59
|
+
|
|
60
|
+
**Outcome:** success
|
|
61
|
+
**Date:** 2025-12-17
|
|
62
|
+
|
|
63
|
+
## What Happened
|
|
64
|
+
Started by copying the email verification token pattern, but password
|
|
65
|
+
reset has different requirements - tokens need to be single-use and
|
|
66
|
+
expire faster. Spent 30 minutes debugging why tokens weren't invalidating
|
|
67
|
+
before realizing the existing pattern didn't include the `used_at` column.
|
|
68
|
+
|
|
69
|
+
Ended up creating a separate table rather than retrofitting the existing one.
|
|
70
|
+
This was the right call - cleaner separation of concerns.
|
|
71
|
+
|
|
72
|
+
## Key Learning
|
|
73
|
+
Don't assume similar-sounding features can share infrastructure.
|
|
74
|
+
Check the actual requirements before copying patterns.
|
|
75
|
+
|
|
76
|
+
## For Next Time
|
|
77
|
+
When copying patterns, make a checklist of requirements for the new
|
|
78
|
+
use case FIRST, then evaluate if the existing pattern meets them.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## File Organization
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
.claude/retros/
|
|
87
|
+
├── README.md
|
|
88
|
+
├── 2025-12/
|
|
89
|
+
│ ├── ENG-42-password-reset.md
|
|
90
|
+
│ └── ENG-45-oauth-integration.md
|
|
91
|
+
└── 2025-11/
|
|
92
|
+
└── ...
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Organize by month (reduces clutter)
|
|
96
|
+
- Name files: `[ISSUE-ID]-[slug].md`
|
|
97
|
+
- Archive older months when >20 files
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## What NOT to Include
|
|
102
|
+
|
|
103
|
+
❌ **YAML frontmatter with 10+ fields** — Creates friction
|
|
104
|
+
❌ **Structured sections for everything** — Makes it feel like a form
|
|
105
|
+
❌ **Metrics and scores** — Over-engineering
|
|
106
|
+
❌ **Multi-level categorization** — Analysis paralysis
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Synthesis: /insights
|
|
111
|
+
|
|
112
|
+
Individual retros capture learnings. The `/insights` command synthesizes patterns:
|
|
113
|
+
|
|
114
|
+
- Run weekly (or when starting similar work)
|
|
115
|
+
- Identifies patterns across retros (2+ occurrences)
|
|
116
|
+
- Outputs actionable recommendations
|
|
117
|
+
|
|
118
|
+
See: `~/.claude/commands/insights.md`
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Success Metric
|
|
123
|
+
|
|
124
|
+
**Retros get written.**
|
|
125
|
+
|
|
126
|
+
If you're not writing retros, the format is too complex. Simplify until you do.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Claude Rules
|
|
2
|
+
|
|
3
|
+
> Modular rule files that Claude loads automatically alongside CLAUDE.md.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
The `.claude/rules/` directory provides a location for supplementary rules that:
|
|
10
|
+
- Apply to specific contexts (security, testing, API design)
|
|
11
|
+
- Can be injected into sub-agents via hooks
|
|
12
|
+
- Keep CLAUDE.md focused on project-level guidance
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## How It Works
|
|
17
|
+
|
|
18
|
+
1. **Automatic loading**: Claude reads markdown files in this directory
|
|
19
|
+
2. **Hook injection**: SubagentStart hook can inject specific rules based on agent type
|
|
20
|
+
3. **Modular organization**: Each file focuses on one domain
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Suggested Files
|
|
25
|
+
|
|
26
|
+
| File | Purpose |
|
|
27
|
+
|------|---------|
|
|
28
|
+
| `security.md` | Security requirements and checklists |
|
|
29
|
+
| `testing.md` | Testing standards and coverage requirements |
|
|
30
|
+
| `api-design.md` | API conventions and standards |
|
|
31
|
+
| `code-style.md` | Style guidelines beyond linter rules |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Example: security.md
|
|
36
|
+
|
|
37
|
+
```markdown
|
|
38
|
+
# Security Rules
|
|
39
|
+
|
|
40
|
+
## Input Validation
|
|
41
|
+
- All user input must be validated
|
|
42
|
+
- Use parameterized queries for SQL
|
|
43
|
+
- Encode output to prevent XSS
|
|
44
|
+
|
|
45
|
+
## Authentication
|
|
46
|
+
- Passwords must use bcrypt/argon2
|
|
47
|
+
- Session tokens must be cryptographically random
|
|
48
|
+
- Enforce token expiration
|
|
49
|
+
|
|
50
|
+
## Authorization
|
|
51
|
+
- Implement role-based access control
|
|
52
|
+
- Check permissions on every API endpoint
|
|
53
|
+
- Prevent privilege escalation
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Integration with Sub-Agents
|
|
59
|
+
|
|
60
|
+
Rules can be injected into sub-agents using the SubagentStart hook:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# In subagent_start.py
|
|
64
|
+
context_map = {
|
|
65
|
+
"security-code-reviewer": ".claude/rules/security.md",
|
|
66
|
+
"cross-layer-debugger": ".claude/rules/debugging.md",
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
See `.claude/hooks/subagent_start.py` for implementation details.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Best Practices
|
|
75
|
+
|
|
76
|
+
### Do:
|
|
77
|
+
- Keep rules focused and actionable
|
|
78
|
+
- Use checklists for review processes
|
|
79
|
+
- Reference industry standards (OWASP, CWE)
|
|
80
|
+
- Update rules as project evolves
|
|
81
|
+
|
|
82
|
+
### Don't:
|
|
83
|
+
- Duplicate content from CLAUDE.md
|
|
84
|
+
- Create rules for one-time guidance
|
|
85
|
+
- Make rules too long (keep under 200 lines)
|
|
86
|
+
- Include code examples unless necessary
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
*Introduced in Claude Code 2.0.64*
|