olympus-ai 2.7.4 → 3.2.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/.claude/.olympus-version.json +6 -0
- package/.claude/CLAUDE.md +84 -61
- package/.claude/agents/document-writer.md +152 -0
- package/.claude/agents/explore-medium.md +25 -0
- package/.claude/agents/explore.md +86 -0
- package/.claude/agents/frontend-engineer-high.md +17 -0
- package/.claude/agents/frontend-engineer-low.md +17 -0
- package/.claude/agents/frontend-engineer.md +80 -0
- package/.claude/agents/librarian-low.md +22 -0
- package/.claude/agents/librarian.md +70 -0
- package/.claude/agents/metis.md +85 -0
- package/.claude/agents/momus.md +97 -0
- package/.claude/agents/multimodal-looker.md +39 -0
- package/.claude/agents/olympian-high.md +32 -0
- package/.claude/agents/olympian-low.md +22 -0
- package/.claude/agents/olympian.md +78 -0
- package/.claude/agents/oracle-low.md +23 -0
- package/.claude/agents/oracle-medium.md +28 -0
- package/.claude/agents/oracle.md +77 -0
- package/.claude/agents/prometheus.md +125 -0
- package/.claude/agents/qa-tester.md +220 -0
- package/.claude/commands/analyze/skill.md +14 -0
- package/.claude/commands/ascent/skill.md +152 -0
- package/.claude/commands/cancel-ascent.md +9 -0
- package/.claude/commands/complete-plan.md +101 -0
- package/.claude/commands/deepsearch/skill.md +15 -0
- package/.claude/commands/olympus/skill.md +82 -0
- package/.claude/commands/olympus-default.md +26 -0
- package/.claude/commands/plan.md +71 -0
- package/.claude/commands/prometheus/skill.md +38 -0
- package/.claude/commands/review/skill.md +34 -0
- package/.claude/commands/ultrawork/skill.md +90 -0
- package/.claude/commands/update.md +38 -0
- package/.claude-plugin/plugin.json +1 -1
- package/COPYRIGHT +22 -0
- package/LICENSE +1 -1
- package/NOTICE +24 -0
- package/README.md +376 -10
- package/dist/__tests__/installer.test.js +1 -1
- package/dist/__tests__/learning/cleanup.test.d.ts +2 -0
- package/dist/__tests__/learning/cleanup.test.d.ts.map +1 -0
- package/dist/__tests__/learning/cleanup.test.js +122 -0
- package/dist/__tests__/learning/cleanup.test.js.map +1 -0
- package/dist/__tests__/learning/storage.test.d.ts +2 -0
- package/dist/__tests__/learning/storage.test.d.ts.map +1 -0
- package/dist/__tests__/learning/storage.test.js +75 -0
- package/dist/__tests__/learning/storage.test.js.map +1 -0
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +22 -6
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/olympian.d.ts.map +1 -1
- package/dist/agents/olympian.js +23 -7
- package/dist/agents/olympian.js.map +1 -1
- package/dist/agents/orchestrator-olympus.js +1 -1
- package/dist/cli/index.js +128 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/hooks/context-window-limit-recovery/index.d.ts +2 -3
- package/dist/hooks/context-window-limit-recovery/index.d.ts.map +1 -1
- package/dist/hooks/context-window-limit-recovery/index.js +2 -3
- package/dist/hooks/context-window-limit-recovery/index.js.map +1 -1
- package/dist/hooks/olympus-orchestrator/constants.d.ts +3 -3
- package/dist/hooks/olympus-orchestrator/constants.d.ts.map +1 -1
- package/dist/hooks/olympus-orchestrator/constants.js +3 -3
- package/dist/hooks/preemptive-compaction/index.d.ts +2 -3
- package/dist/hooks/preemptive-compaction/index.d.ts.map +1 -1
- package/dist/hooks/preemptive-compaction/index.js +2 -3
- package/dist/hooks/preemptive-compaction/index.js.map +1 -1
- package/dist/installer/index.d.ts +2 -2
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +114 -30
- package/dist/installer/index.js.map +1 -1
- package/dist/learning/cleanup.d.ts +18 -0
- package/dist/learning/cleanup.d.ts.map +1 -0
- package/dist/learning/cleanup.js +160 -0
- package/dist/learning/cleanup.js.map +1 -0
- package/dist/learning/discovery.d.ts.map +1 -1
- package/dist/learning/discovery.js +3 -1
- package/dist/learning/discovery.js.map +1 -1
- package/dist/learning/pattern-extractor.d.ts +1 -1
- package/dist/learning/pattern-extractor.d.ts.map +1 -1
- package/dist/learning/pattern-extractor.js +4 -2
- package/dist/learning/pattern-extractor.js.map +1 -1
- package/dist/learning/stats.d.ts +28 -0
- package/dist/learning/stats.d.ts.map +1 -0
- package/dist/learning/stats.js +112 -0
- package/dist/learning/stats.js.map +1 -0
- package/dist/learning/storage.d.ts +4 -0
- package/dist/learning/storage.d.ts.map +1 -1
- package/dist/learning/storage.js +26 -1
- package/dist/learning/storage.js.map +1 -1
- package/package.json +9 -4
- package/{dist → scripts/dist}/hooks/olympus-hooks.cjs +70 -69
- package/scripts/esbuild.hooks.mjs +67 -0
- package/scripts/generate-logo-hybrid-v2.mjs +213 -0
- package/scripts/generate-logo-hybrid.mjs +209 -0
- package/scripts/generate-logo-infinity.mjs +239 -0
- package/scripts/generate-logo-mythology.mjs +190 -0
- package/scripts/generate-logo-orchestration.mjs +228 -0
- package/scripts/generate-logo-recraft.mjs +147 -0
- package/scripts/generate-logo-simple.mjs +154 -0
- package/scripts/generate-logo.mjs +117 -0
- package/scripts/install.sh +4 -7
- package/scripts/rebrand.mjs +206 -0
- package/.claude-plugin/nul +0 -3
package/README.md
CHANGED
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
### Multi-Agent Orchestration for Claude Code
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/olympus-ai)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
[](https://github.com/mikev10/olympus)
|
|
10
|
+
[](https://github.com/mikev10/olympus/actions)
|
|
10
11
|
|
|
11
12
|
**Summon the gods of code.**
|
|
12
13
|
|
|
13
|
-
[
|
|
14
|
+
[Why Olympus?](#why-olympus) • [Quick Start](#quick-start) • [Self-Learning](#self-learning-system) • [Use Cases](#use-cases) • [Agents](#available-agents) • [Docs](#documentation)
|
|
14
15
|
|
|
15
16
|
</div>
|
|
16
17
|
|
|
@@ -20,11 +21,86 @@
|
|
|
20
21
|
|
|
21
22
|
Olympus is a multi-agent orchestration system for [Claude Code](https://docs.anthropic.com/claude-code). It provides:
|
|
22
23
|
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
24
|
+
- 🧠 **Self-Learning System** - Learns your preferences, patterns, and codebase over time
|
|
25
|
+
- 🤖 **20+ Specialized Agents** - Oracle, Prometheus, Olympian, Librarian, and more
|
|
26
|
+
- ⚡ **Smart Model Routing** - Auto-selects Haiku/Sonnet/Opus based on task complexity
|
|
27
|
+
- 📋 **Todo Management** - Tracks progress with real-time updates
|
|
28
|
+
- 🔄 **Background Execution** - Long-running tasks run async with notifications
|
|
29
|
+
- 🎯 **Continuation Enforcement** - Never stops until all tasks are complete
|
|
30
|
+
- 💬 **13+ Slash Commands** - `/ultrawork`, `/plan`, `/ascent`, and more
|
|
31
|
+
- 🔮 **Magic Keywords** - Natural language triggers for enhanced modes
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Why Olympus?
|
|
36
|
+
|
|
37
|
+
Olympus transforms Claude Code from a single agent into a **pantheon of specialized experts** that work together seamlessly.
|
|
38
|
+
|
|
39
|
+
### 🧠 Self-Learning System
|
|
40
|
+
|
|
41
|
+
**Olympus learns from your preferences and evolves over time.**
|
|
42
|
+
|
|
43
|
+
- **Active Agent Learning** - Agents proactively record patterns, gotchas, and workarounds they discover during work
|
|
44
|
+
- **Passive Feedback Capture** - Automatically detects corrections, preferences, and patterns from your interactions
|
|
45
|
+
- **Pattern Extraction** - Identifies recurring feedback and adapts behavior accordingly
|
|
46
|
+
- **Preference Learning** - Infers your communication style (concise vs. detailed, autonomous vs. collaborative)
|
|
47
|
+
- **Agent Performance Tracking** - Monitors which agents succeed or fail for specific tasks
|
|
48
|
+
- **Discovery Storage** - Structured JSONL storage with verification tracking and confidence scoring
|
|
49
|
+
- **Context Injection** - Learned preferences and discoveries are automatically applied in new sessions
|
|
50
|
+
|
|
51
|
+
**The more you use Olympus, the better it understands your workflow.**
|
|
52
|
+
|
|
53
|
+
### ⚡ Intelligent Orchestration
|
|
54
|
+
|
|
55
|
+
- **Smart Delegation** - Routes tasks to specialized agents based on complexity
|
|
56
|
+
- **Model Routing** - Automatically selects Haiku/Sonnet/Opus to optimize cost and performance
|
|
57
|
+
- **Parallel Execution** - Runs independent tasks concurrently for maximum throughput
|
|
58
|
+
|
|
59
|
+
### 🎯 Continuous Delivery
|
|
60
|
+
|
|
61
|
+
- **Todo Management** - Tracks progress across complex multi-step tasks
|
|
62
|
+
- **Continuation Enforcement** - Never stops until all tasks are verified complete
|
|
63
|
+
- **Background Operations** - Long-running builds, tests, and installs run async with notifications
|
|
64
|
+
|
|
65
|
+
### 🔧 Developer Experience
|
|
66
|
+
|
|
67
|
+
- **Zero Configuration** - Works out-of-the-box with sensible defaults
|
|
68
|
+
- **Slash Commands** - 13+ productivity commands (`/ultrawork`, `/plan`, `/ascent`)
|
|
69
|
+
- **Magic Keywords** - Natural language triggers for enhanced modes
|
|
70
|
+
|
|
71
|
+
### 📊 Olympus vs. Manual Claude Usage
|
|
72
|
+
|
|
73
|
+
| Feature | Manual Claude | Olympus |
|
|
74
|
+
|---------|---------------|---------|
|
|
75
|
+
| **Multi-Step Tasks** | Sequential, manual tracking | Automatic todo management |
|
|
76
|
+
| **Parallel Execution** | One task at a time | 3-5x faster with concurrent agents |
|
|
77
|
+
| **Learning** | Repeats mistakes | Learns from corrections automatically |
|
|
78
|
+
| **Model Selection** | Manual switching | Smart routing (cost optimized) |
|
|
79
|
+
| **Task Persistence** | Stops when asked | Continues until verified complete |
|
|
80
|
+
| **Background Tasks** | Blocks waiting | Runs async with notifications |
|
|
81
|
+
| **Agent Specialization** | Generic responses | 20+ experts for specific domains |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Quick Start
|
|
86
|
+
|
|
87
|
+
Get started in under 60 seconds:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Install globally
|
|
91
|
+
npm install -g olympus-ai
|
|
92
|
+
|
|
93
|
+
# Initialize Olympus
|
|
94
|
+
olympus-ai install
|
|
95
|
+
|
|
96
|
+
# Start Claude Code
|
|
97
|
+
claude
|
|
98
|
+
|
|
99
|
+
# Try it out
|
|
100
|
+
/olympus implement a REST API for user management
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**That's it.** Olympus is now active and learning from your interactions.
|
|
28
104
|
|
|
29
105
|
---
|
|
30
106
|
|
|
@@ -112,6 +188,116 @@ Include these words anywhere in your prompt to activate enhanced modes:
|
|
|
112
188
|
|
|
113
189
|
---
|
|
114
190
|
|
|
191
|
+
## Use Cases
|
|
192
|
+
|
|
193
|
+
### 🏗️ Complex Refactoring
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
/ascent refactor the entire authentication module to use OAuth 2.0
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**What happens:**
|
|
200
|
+
- Creates todo list for all subtasks
|
|
201
|
+
- Delegates to specialized agents (Oracle for architecture, Olympian for execution)
|
|
202
|
+
- Runs tests in background
|
|
203
|
+
- Continues until all tasks verified complete
|
|
204
|
+
|
|
205
|
+
### 📊 Multi-Agent Research
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
/ultrawork research and document all API endpoints in the codebase
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**What happens:**
|
|
212
|
+
- Spawns multiple agents in parallel (Explore for search, Librarian for docs)
|
|
213
|
+
- Aggregates findings
|
|
214
|
+
- Generates comprehensive documentation
|
|
215
|
+
- ~3x faster than sequential execution
|
|
216
|
+
|
|
217
|
+
### 📋 Strategic Planning
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
/plan build a real-time chat application with WebSocket support
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**What happens:**
|
|
224
|
+
- Prometheus interviews you about requirements
|
|
225
|
+
- Creates detailed work plan with phases
|
|
226
|
+
- Identifies dependencies and risks
|
|
227
|
+
- Saves plan to `.olympus/plans/` for execution
|
|
228
|
+
|
|
229
|
+
### 🧠 Learning Your Workflow
|
|
230
|
+
|
|
231
|
+
**Automatic - no command needed**
|
|
232
|
+
|
|
233
|
+
You: "No, use TypeScript interfaces instead of types"
|
|
234
|
+
→ Olympus records this preference
|
|
235
|
+
|
|
236
|
+
You: "Use functional components, not class components"
|
|
237
|
+
→ Olympus learns your React style
|
|
238
|
+
|
|
239
|
+
**Next session:** Claude automatically applies these preferences without being told.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Architecture
|
|
244
|
+
|
|
245
|
+
Olympus operates as a three-tier orchestration system with a continuous learning loop:
|
|
246
|
+
|
|
247
|
+
```mermaid
|
|
248
|
+
graph TD
|
|
249
|
+
A[User Request] --> B[Orchestrator]
|
|
250
|
+
B --> C{Task Analysis}
|
|
251
|
+
C -->|Simple| D[Haiku Agent]
|
|
252
|
+
C -->|Standard| E[Sonnet Agent]
|
|
253
|
+
C -->|Complex| F[Opus Agent]
|
|
254
|
+
D --> G[Learning System]
|
|
255
|
+
E --> G
|
|
256
|
+
F --> G
|
|
257
|
+
G --> H[Feedback Storage]
|
|
258
|
+
H -.->|Next Session| B
|
|
259
|
+
B --> I[Todo Manager]
|
|
260
|
+
I --> J[Background Executor]
|
|
261
|
+
J --> K[Result]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### How It Works
|
|
265
|
+
|
|
266
|
+
**Current Session Flow:**
|
|
267
|
+
1. **User Request** → Arrives with learned context already injected at SessionStart
|
|
268
|
+
2. **Orchestrator** → Analyzes task complexity and delegates to appropriate agents
|
|
269
|
+
3. **Model Router** → Selects Haiku (simple), Sonnet (standard), or Opus (complex)
|
|
270
|
+
4. **Agents Execute** → Specialized agents complete their tasks
|
|
271
|
+
5. **Learning System** → Passively captures feedback from corrections, preferences, and patterns
|
|
272
|
+
6. **Feedback Storage** → Stores learned preferences, agent performance, and discoveries
|
|
273
|
+
7. **Result** → User sees the completed work
|
|
274
|
+
|
|
275
|
+
**Learning & Context Injection (Between Sessions):**
|
|
276
|
+
|
|
277
|
+
The learning system operates across session boundaries:
|
|
278
|
+
|
|
279
|
+
- **During Session**: Captures feedback from user corrections ("No, use async/await"), preferences ("Always use TypeScript"), and agent discoveries (gotchas, workarounds)
|
|
280
|
+
- **Storage**: Writes to `~/.claude/olympus/learning/` (global) and `.olympus/learning/` (project-specific)
|
|
281
|
+
- **Next Session Start**: SessionStart hook automatically injects learned context into the initial prompt
|
|
282
|
+
- **Context Types Injected**:
|
|
283
|
+
- User preferences (verbosity, autonomy, explicit rules)
|
|
284
|
+
- Recurring corrections (mistakes to avoid)
|
|
285
|
+
- Project conventions (tech stack, patterns)
|
|
286
|
+
- Agent performance notes (weak areas to watch)
|
|
287
|
+
- Recent discoveries (technical insights about your codebase)
|
|
288
|
+
|
|
289
|
+
**Key Insight:** Context injection happens at the **beginning** of each session (via SessionStart hook), not in the result. This means every new conversation starts with Claude already aware of your preferences and past learnings.
|
|
290
|
+
|
|
291
|
+
**Key Components:**
|
|
292
|
+
- **Orchestrator** - Delegates tasks to specialized agents based on complexity
|
|
293
|
+
- **Model Router** - Selects optimal tier (Haiku/Sonnet/Opus) to balance cost and capability
|
|
294
|
+
- **Learning System** - Captures feedback passively and builds preference models
|
|
295
|
+
- **Todo Manager** - Tracks multi-step task progress with real-time status updates
|
|
296
|
+
- **Background Executor** - Runs long-running operations (builds, tests, installs) async with notifications
|
|
297
|
+
- **Feedback Storage** - Persists learned preferences, patterns, and discoveries across sessions
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
115
301
|
## Available Agents
|
|
116
302
|
|
|
117
303
|
### Task Execution
|
|
@@ -182,16 +368,139 @@ Plans are saved to `.olympus/plans/` in your project directory.
|
|
|
182
368
|
|
|
183
369
|
---
|
|
184
370
|
|
|
371
|
+
## Self-Learning System
|
|
372
|
+
|
|
373
|
+
Olympus continuously learns from your interactions to provide increasingly personalized assistance.
|
|
374
|
+
|
|
375
|
+
### How It Works
|
|
376
|
+
|
|
377
|
+
**Phase 1: Passive Feedback Capture**
|
|
378
|
+
- Detects corrections: "No, that's wrong"
|
|
379
|
+
- Identifies rejections: "Stop", "Cancel"
|
|
380
|
+
- Recognizes clarifications: "I meant X"
|
|
381
|
+
- Captures enhancements: "Also add Y"
|
|
382
|
+
- Records praise: "Perfect", "Thanks"
|
|
383
|
+
- Extracts explicit preferences: "Always use X"
|
|
384
|
+
|
|
385
|
+
**Phase 2: Pattern Extraction**
|
|
386
|
+
- Clusters similar feedback using Jaccard similarity
|
|
387
|
+
- Identifies recurring corrections (minimum 3 occurrences)
|
|
388
|
+
- Categorizes patterns: style, behavior, tooling, communication
|
|
389
|
+
|
|
390
|
+
**Phase 3: Preference Learning**
|
|
391
|
+
- Infers verbosity level (concise vs. detailed)
|
|
392
|
+
- Determines autonomy preference (ask first vs. just do it)
|
|
393
|
+
- Tracks agent-specific performance
|
|
394
|
+
- Implements 30-day decay for outdated patterns
|
|
395
|
+
|
|
396
|
+
**Phase 4: Context Injection**
|
|
397
|
+
- Automatically applies learned preferences at session start
|
|
398
|
+
- Injects relevant discoveries about your codebase
|
|
399
|
+
- Limits injection to ~500 tokens to avoid context bloat
|
|
400
|
+
|
|
401
|
+
**Phase 5: Agent Discovery**
|
|
402
|
+
- Agents record technical insights about your project
|
|
403
|
+
- Discoveries include: gotchas, workarounds, patterns, dependencies
|
|
404
|
+
- Validated and deduplicated before storage
|
|
405
|
+
- Retrieved contextually in future sessions
|
|
406
|
+
|
|
407
|
+
### Storage Locations
|
|
408
|
+
|
|
409
|
+
**Global Learning:**
|
|
410
|
+
```
|
|
411
|
+
~/.claude/olympus/learning/
|
|
412
|
+
├── feedback-log.jsonl # All feedback entries (auto-rotates at 10k lines)
|
|
413
|
+
├── user-preferences.json # Learned preferences
|
|
414
|
+
├── agent-performance.json # Per-agent metrics
|
|
415
|
+
└── discoveries.jsonl # Global discoveries (auto-rotates at 10k lines)
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**Project-Specific Learning:**
|
|
419
|
+
```
|
|
420
|
+
.olympus/learning/
|
|
421
|
+
├── session-state.json # Current session state
|
|
422
|
+
├── patterns.json # Project patterns
|
|
423
|
+
└── discoveries.jsonl # Project discoveries (auto-rotates at 10k lines)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**Data Lifecycle:**
|
|
427
|
+
- JSONL files automatically rotate when they exceed 10,000 lines
|
|
428
|
+
- Archived files are saved with timestamps (e.g., `feedback-log.2026-01-28.old.jsonl`)
|
|
429
|
+
- Manual cleanup available via CLI (see Managing Learning Data below)
|
|
430
|
+
|
|
431
|
+
### Managing Learning Data
|
|
432
|
+
|
|
433
|
+
View learning statistics and manage stored data using the CLI:
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# View learning statistics
|
|
437
|
+
olympus-ai learn --stats
|
|
438
|
+
|
|
439
|
+
# Preview cleanup (dry run)
|
|
440
|
+
olympus-ai learn --cleanup --dry-run
|
|
441
|
+
|
|
442
|
+
# Clean up entries older than 180 days (default)
|
|
443
|
+
olympus-ai learn --cleanup
|
|
444
|
+
|
|
445
|
+
# Clean up with custom age threshold
|
|
446
|
+
olympus-ai learn --cleanup --age 90
|
|
447
|
+
|
|
448
|
+
# Remove archived files
|
|
449
|
+
olympus-ai learn --cleanup --remove-archived
|
|
450
|
+
|
|
451
|
+
# View current learnings
|
|
452
|
+
olympus-ai learn --show
|
|
453
|
+
|
|
454
|
+
# Analyze feedback and update patterns
|
|
455
|
+
olympus-ai learn --analyze
|
|
456
|
+
|
|
457
|
+
# Forget all learnings
|
|
458
|
+
olympus-ai learn --forget
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**Example output:**
|
|
462
|
+
```
|
|
463
|
+
Learning System Statistics
|
|
464
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
465
|
+
|
|
466
|
+
Feedback Entries: 1247 (1.2 MB)
|
|
467
|
+
Discoveries: 123
|
|
468
|
+
Total Storage: 1.5 MB
|
|
469
|
+
|
|
470
|
+
Top Verified Discoveries:
|
|
471
|
+
1. Prisma migrations must run before seeding (8×)
|
|
472
|
+
2. This codebase uses kebab-case for files (6×)
|
|
473
|
+
3. Environment variable DATABASE_URL required (5×)
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Example
|
|
477
|
+
|
|
478
|
+
**Session 1:** You tell Claude "No, use async/await instead of .then()"
|
|
479
|
+
→ Olympus records this as a correction
|
|
480
|
+
|
|
481
|
+
**Session 2:** Similar situation arises
|
|
482
|
+
→ You provide the same feedback
|
|
483
|
+
|
|
484
|
+
**Session 3:** Olympus detects the pattern (3+ occurrences)
|
|
485
|
+
→ Learns your preference: "Use async/await over Promise chains"
|
|
486
|
+
|
|
487
|
+
**Session 4+:** This preference is automatically injected
|
|
488
|
+
→ Claude proactively uses async/await without being told
|
|
489
|
+
|
|
490
|
+
**The learning happens silently in the background. No configuration required.**
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
185
494
|
## What Gets Installed
|
|
186
495
|
|
|
187
496
|
```
|
|
188
497
|
~/.claude/
|
|
189
|
-
├── agents/ #
|
|
498
|
+
├── agents/ # 20+ agent definitions
|
|
190
499
|
│ ├── oracle.md
|
|
191
500
|
│ ├── prometheus.md
|
|
192
501
|
│ ├── olympian.md
|
|
193
502
|
│ └── ...
|
|
194
|
-
├── commands/ # 13 slash commands
|
|
503
|
+
├── commands/ # 13+ slash commands
|
|
195
504
|
│ ├── olympus/skill.md
|
|
196
505
|
│ ├── ultrawork/skill.md
|
|
197
506
|
│ ├── plan.md
|
|
@@ -245,6 +554,62 @@ rm -rf ~/.claude/agents ~/.claude/commands ~/.claude/hooks ~/.claude/CLAUDE.md
|
|
|
245
554
|
|
|
246
555
|
---
|
|
247
556
|
|
|
557
|
+
## Contributing
|
|
558
|
+
|
|
559
|
+
We welcome contributions! Here's how to get started:
|
|
560
|
+
|
|
561
|
+
### Development Setup
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
# Clone the repository
|
|
565
|
+
git clone https://github.com/mikev10/olympus.git
|
|
566
|
+
cd olympus
|
|
567
|
+
|
|
568
|
+
# Install dependencies
|
|
569
|
+
npm install
|
|
570
|
+
|
|
571
|
+
# Build the project
|
|
572
|
+
npm run build
|
|
573
|
+
|
|
574
|
+
# Test locally
|
|
575
|
+
node dist/cli/index.js install --local
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Running Tests
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
npm test # Run tests in watch mode
|
|
582
|
+
npm run test:run # Run tests once
|
|
583
|
+
npm run test:coverage # Generate coverage report
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### Project Structure
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
olympus/
|
|
590
|
+
├── src/
|
|
591
|
+
│ ├── agents/ # Agent definitions
|
|
592
|
+
│ ├── features/ # Core features (routing, learning, etc.)
|
|
593
|
+
│ ├── hooks/ # Event handlers
|
|
594
|
+
│ ├── learning/ # Self-learning system
|
|
595
|
+
│ └── cli/ # CLI commands
|
|
596
|
+
├── agents/ # Agent markdown files (installed)
|
|
597
|
+
├── commands/ # Slash command files (installed)
|
|
598
|
+
└── scripts/ # Build and installation scripts
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## Documentation
|
|
604
|
+
|
|
605
|
+
- 📖 [Getting Started Guide](docs/Olympus.md)
|
|
606
|
+
- 🤖 [Agent Reference](docs/AGENTS.md)
|
|
607
|
+
- 🏗️ [Architecture Overview](docs/ARCHITECTURE.md)
|
|
608
|
+
- 🗺️ [Roadmap](docs/ROADMAP.md)
|
|
609
|
+
- 📋 [Changelog](CHANGELOG.md)
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
248
613
|
## License
|
|
249
614
|
|
|
250
615
|
MIT - see [LICENSE](LICENSE)
|
|
@@ -260,3 +625,4 @@ MIT - see [LICENSE](LICENSE)
|
|
|
260
625
|
**Summon the gods of code.**
|
|
261
626
|
|
|
262
627
|
</div>
|
|
628
|
+
|
|
@@ -231,7 +231,7 @@ describe('Installer Constants', () => {
|
|
|
231
231
|
});
|
|
232
232
|
it('should match package.json version', () => {
|
|
233
233
|
// This is a runtime check - VERSION should match the package.json
|
|
234
|
-
expect(VERSION).toBe('
|
|
234
|
+
expect(VERSION).toBe('3.1.0');
|
|
235
235
|
});
|
|
236
236
|
});
|
|
237
237
|
describe('File Paths', () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/cleanup.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { cleanupLearning } from '../../learning/cleanup.js';
|
|
5
|
+
const TEST_DIR = join(process.cwd(), '.test-cleanup');
|
|
6
|
+
describe('Learning Cleanup', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
if (existsSync(TEST_DIR)) {
|
|
9
|
+
rmSync(TEST_DIR, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
12
|
+
process.env.HOME = TEST_DIR;
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
if (existsSync(TEST_DIR)) {
|
|
16
|
+
rmSync(TEST_DIR, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
delete process.env.HOME;
|
|
19
|
+
});
|
|
20
|
+
it('removes old feedback entries', () => {
|
|
21
|
+
const learningDir = join(TEST_DIR, '.claude', 'olympus', 'learning');
|
|
22
|
+
mkdirSync(learningDir, { recursive: true });
|
|
23
|
+
const logPath = join(learningDir, 'feedback-log.jsonl');
|
|
24
|
+
const oldDate = new Date();
|
|
25
|
+
oldDate.setDate(oldDate.getDate() - 200); // 200 days ago
|
|
26
|
+
const entries = [
|
|
27
|
+
{
|
|
28
|
+
id: 'old-1',
|
|
29
|
+
timestamp: oldDate.toISOString(),
|
|
30
|
+
session_id: 'session-1',
|
|
31
|
+
project_path: '/test',
|
|
32
|
+
event_type: 'revision',
|
|
33
|
+
user_message: 'Old message',
|
|
34
|
+
feedback_category: 'correction',
|
|
35
|
+
confidence: 0.9,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'new-1',
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
session_id: 'session-2',
|
|
41
|
+
project_path: '/test',
|
|
42
|
+
event_type: 'revision',
|
|
43
|
+
user_message: 'New message',
|
|
44
|
+
feedback_category: 'correction',
|
|
45
|
+
confidence: 0.9,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
writeFileSync(logPath, entries.map(e => JSON.stringify(e)).join('\n') + '\n', 'utf-8');
|
|
49
|
+
const result = cleanupLearning('/test', { ageDays: 180, dryRun: false });
|
|
50
|
+
expect(result.feedback_entries_removed).toBe(1);
|
|
51
|
+
expect(result.space_freed_mb).toBeGreaterThan(0);
|
|
52
|
+
});
|
|
53
|
+
it('removes expired discoveries', () => {
|
|
54
|
+
const learningDir = join(TEST_DIR, '.claude', 'olympus', 'learning');
|
|
55
|
+
mkdirSync(learningDir, { recursive: true });
|
|
56
|
+
const discoveryPath = join(learningDir, 'discoveries.jsonl');
|
|
57
|
+
const expiredDate = new Date();
|
|
58
|
+
expiredDate.setDate(expiredDate.getDate() - 10);
|
|
59
|
+
const futureDate = new Date();
|
|
60
|
+
futureDate.setDate(futureDate.getDate() + 10);
|
|
61
|
+
const discoveries = [
|
|
62
|
+
{
|
|
63
|
+
id: 'expired-1',
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
session_id: 'session-1',
|
|
66
|
+
project_path: '/test',
|
|
67
|
+
category: 'workaround',
|
|
68
|
+
summary: 'Expired discovery',
|
|
69
|
+
details: 'This is expired',
|
|
70
|
+
agent_name: 'oracle',
|
|
71
|
+
confidence: 0.9,
|
|
72
|
+
verified: false,
|
|
73
|
+
verification_count: 0,
|
|
74
|
+
scope: 'global',
|
|
75
|
+
expires_at: expiredDate.toISOString(),
|
|
76
|
+
last_useful: new Date().toISOString(),
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'active-1',
|
|
80
|
+
timestamp: new Date().toISOString(),
|
|
81
|
+
session_id: 'session-1',
|
|
82
|
+
project_path: '/test',
|
|
83
|
+
category: 'pattern',
|
|
84
|
+
summary: 'Active discovery',
|
|
85
|
+
details: 'This is active',
|
|
86
|
+
agent_name: 'oracle',
|
|
87
|
+
confidence: 0.9,
|
|
88
|
+
verified: false,
|
|
89
|
+
verification_count: 0,
|
|
90
|
+
scope: 'global',
|
|
91
|
+
expires_at: futureDate.toISOString(),
|
|
92
|
+
last_useful: new Date().toISOString(),
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
writeFileSync(discoveryPath, discoveries.map(d => JSON.stringify(d)).join('\n') + '\n', 'utf-8');
|
|
96
|
+
const result = cleanupLearning('/test', { compactExpired: true, dryRun: false });
|
|
97
|
+
expect(result.discoveries_removed).toBe(1);
|
|
98
|
+
});
|
|
99
|
+
it('dry run does not modify files', () => {
|
|
100
|
+
const learningDir = join(TEST_DIR, '.claude', 'olympus', 'learning');
|
|
101
|
+
mkdirSync(learningDir, { recursive: true });
|
|
102
|
+
const logPath = join(learningDir, 'feedback-log.jsonl');
|
|
103
|
+
const oldDate = new Date();
|
|
104
|
+
oldDate.setDate(oldDate.getDate() - 200);
|
|
105
|
+
const entry = {
|
|
106
|
+
id: 'old-1',
|
|
107
|
+
timestamp: oldDate.toISOString(),
|
|
108
|
+
session_id: 'session-1',
|
|
109
|
+
project_path: '/test',
|
|
110
|
+
event_type: 'revision',
|
|
111
|
+
user_message: 'Old message',
|
|
112
|
+
feedback_category: 'correction',
|
|
113
|
+
confidence: 0.9,
|
|
114
|
+
};
|
|
115
|
+
writeFileSync(logPath, JSON.stringify(entry) + '\n', 'utf-8');
|
|
116
|
+
const sizeBefore = require('fs').statSync(logPath).size;
|
|
117
|
+
cleanupLearning('/test', { ageDays: 180, dryRun: true });
|
|
118
|
+
const sizeAfter = require('fs').statSync(logPath).size;
|
|
119
|
+
expect(sizeBefore).toBe(sizeAfter);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=cleanup.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/cleanup.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/storage.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { appendFeedback, readFeedbackLog } from '../../learning/storage.js';
|
|
5
|
+
const TEST_DIR = join(process.cwd(), '.test-learning');
|
|
6
|
+
describe('Storage with Rotation', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
// Override getLearningDir for testing
|
|
9
|
+
process.env.HOME = TEST_DIR;
|
|
10
|
+
if (existsSync(TEST_DIR)) {
|
|
11
|
+
rmSync(TEST_DIR, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
if (existsSync(TEST_DIR)) {
|
|
17
|
+
rmSync(TEST_DIR, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
delete process.env.HOME;
|
|
20
|
+
});
|
|
21
|
+
it('rotates JSONL file when exceeding threshold', () => {
|
|
22
|
+
const testEntry = {
|
|
23
|
+
id: 'test-1',
|
|
24
|
+
timestamp: new Date().toISOString(),
|
|
25
|
+
session_id: 'session-1',
|
|
26
|
+
project_path: '/test',
|
|
27
|
+
event_type: 'revision',
|
|
28
|
+
user_message: 'Test message',
|
|
29
|
+
feedback_category: 'correction',
|
|
30
|
+
confidence: 0.9,
|
|
31
|
+
};
|
|
32
|
+
// Create a file with many lines (simulating large file)
|
|
33
|
+
const learningDir = join(TEST_DIR, '.claude', 'olympus', 'learning');
|
|
34
|
+
mkdirSync(learningDir, { recursive: true });
|
|
35
|
+
const logPath = join(learningDir, 'feedback-log.jsonl');
|
|
36
|
+
// Write 10,001 lines to trigger rotation
|
|
37
|
+
const lines = [];
|
|
38
|
+
for (let i = 0; i < 10001; i++) {
|
|
39
|
+
lines.push(JSON.stringify({ ...testEntry, id: `test-${i}` }));
|
|
40
|
+
}
|
|
41
|
+
writeFileSync(logPath, lines.join('\n') + '\n', 'utf-8');
|
|
42
|
+
// Append new entry (should trigger rotation)
|
|
43
|
+
appendFeedback(testEntry);
|
|
44
|
+
// Check that archive file was created
|
|
45
|
+
const files = require('fs').readdirSync(learningDir);
|
|
46
|
+
const archiveFiles = files.filter((f) => f.includes('.old.jsonl'));
|
|
47
|
+
expect(archiveFiles.length).toBeGreaterThan(0);
|
|
48
|
+
// Check that new file has only 1 entry
|
|
49
|
+
const newLog = readFeedbackLog();
|
|
50
|
+
expect(newLog.length).toBe(1);
|
|
51
|
+
});
|
|
52
|
+
it('does not rotate when below threshold', () => {
|
|
53
|
+
const testEntry = {
|
|
54
|
+
id: 'test-1',
|
|
55
|
+
timestamp: new Date().toISOString(),
|
|
56
|
+
session_id: 'session-1',
|
|
57
|
+
project_path: '/test',
|
|
58
|
+
event_type: 'revision',
|
|
59
|
+
user_message: 'Test message',
|
|
60
|
+
feedback_category: 'correction',
|
|
61
|
+
confidence: 0.9,
|
|
62
|
+
};
|
|
63
|
+
// Add a few entries (below threshold)
|
|
64
|
+
for (let i = 0; i < 5; i++) {
|
|
65
|
+
appendFeedback({ ...testEntry, id: `test-${i}` });
|
|
66
|
+
}
|
|
67
|
+
const learningDir = join(TEST_DIR, '.claude', 'olympus', 'learning');
|
|
68
|
+
const files = require('fs').readdirSync(learningDir);
|
|
69
|
+
const archiveFiles = files.filter((f) => f.includes('.old.jsonl'));
|
|
70
|
+
expect(archiveFiles.length).toBe(0);
|
|
71
|
+
const log = readFeedbackLog();
|
|
72
|
+
expect(log.length).toBe(5);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=storage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/storage.test.ts"],"names":[],"mappings":"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"}
|