rubyn-code 0.1.0 → 0.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.
- checksums.yaml +4 -4
- data/README.md +269 -467
- data/db/migrations/009_create_teams.sql +6 -6
- data/db/migrations/011_fix_mailbox_messages_columns.rb +35 -0
- data/db/migrations/012_expand_mailbox_message_types.rb +37 -0
- data/exe/rubyn-code +1 -1
- data/lib/rubyn_code/agent/RUBYN.md +17 -0
- data/lib/rubyn_code/agent/conversation.rb +68 -19
- data/lib/rubyn_code/agent/loop.rb +312 -54
- data/lib/rubyn_code/agent/loop_detector.rb +6 -6
- data/lib/rubyn_code/auth/RUBYN.md +19 -0
- data/lib/rubyn_code/auth/oauth.rb +40 -35
- data/lib/rubyn_code/auth/server.rb +16 -12
- data/lib/rubyn_code/auth/token_store.rb +22 -22
- data/lib/rubyn_code/autonomous/RUBYN.md +14 -0
- data/lib/rubyn_code/autonomous/daemon.rb +115 -79
- data/lib/rubyn_code/autonomous/idle_poller.rb +4 -8
- data/lib/rubyn_code/autonomous/task_claimer.rb +11 -11
- data/lib/rubyn_code/background/RUBYN.md +13 -0
- data/lib/rubyn_code/background/notifier.rb +0 -2
- data/lib/rubyn_code/background/worker.rb +60 -15
- data/lib/rubyn_code/cli/RUBYN.md +30 -0
- data/lib/rubyn_code/cli/app.rb +85 -9
- data/lib/rubyn_code/cli/commands/RUBYN.md +133 -0
- data/lib/rubyn_code/cli/commands/base.rb +53 -0
- data/lib/rubyn_code/cli/commands/budget.rb +24 -0
- data/lib/rubyn_code/cli/commands/clear.rb +16 -0
- data/lib/rubyn_code/cli/commands/compact.rb +21 -0
- data/lib/rubyn_code/cli/commands/context.rb +44 -0
- data/lib/rubyn_code/cli/commands/context_info.rb +56 -0
- data/lib/rubyn_code/cli/commands/cost.rb +23 -0
- data/lib/rubyn_code/cli/commands/diff.rb +30 -0
- data/lib/rubyn_code/cli/commands/doctor.rb +112 -0
- data/lib/rubyn_code/cli/commands/help.rb +41 -0
- data/lib/rubyn_code/cli/commands/model.rb +37 -0
- data/lib/rubyn_code/cli/commands/plan.rb +22 -0
- data/lib/rubyn_code/cli/commands/quit.rb +17 -0
- data/lib/rubyn_code/cli/commands/registry.rb +64 -0
- data/lib/rubyn_code/cli/commands/resume.rb +51 -0
- data/lib/rubyn_code/cli/commands/review.rb +26 -0
- data/lib/rubyn_code/cli/commands/skill.rb +32 -0
- data/lib/rubyn_code/cli/commands/spawn.rb +24 -0
- data/lib/rubyn_code/cli/commands/tasks.rb +32 -0
- data/lib/rubyn_code/cli/commands/tokens.rb +76 -0
- data/lib/rubyn_code/cli/commands/undo.rb +17 -0
- data/lib/rubyn_code/cli/commands/version.rb +16 -0
- data/lib/rubyn_code/cli/daemon_runner.rb +129 -0
- data/lib/rubyn_code/cli/input_handler.rb +20 -23
- data/lib/rubyn_code/cli/renderer.rb +25 -27
- data/lib/rubyn_code/cli/repl.rb +161 -194
- data/lib/rubyn_code/cli/setup.rb +117 -0
- data/lib/rubyn_code/cli/spinner.rb +40 -40
- data/lib/rubyn_code/cli/stream_formatter.rb +29 -28
- data/lib/rubyn_code/cli/version_check.rb +94 -0
- data/lib/rubyn_code/config/RUBYN.md +14 -0
- data/lib/rubyn_code/config/defaults.rb +28 -19
- data/lib/rubyn_code/config/project_config.rb +7 -9
- data/lib/rubyn_code/config/settings.rb +3 -3
- data/lib/rubyn_code/context/RUBYN.md +20 -0
- data/lib/rubyn_code/context/auto_compact.rb +7 -7
- data/lib/rubyn_code/context/compactor.rb +2 -2
- data/lib/rubyn_code/context/context_collapse.rb +45 -0
- data/lib/rubyn_code/context/manager.rb +20 -3
- data/lib/rubyn_code/context/manual_compact.rb +7 -7
- data/lib/rubyn_code/context/micro_compact.rb +12 -12
- data/lib/rubyn_code/db/RUBYN.md +40 -0
- data/lib/rubyn_code/db/connection.rb +13 -13
- data/lib/rubyn_code/db/migrator.rb +67 -27
- data/lib/rubyn_code/db/schema.rb +6 -6
- data/lib/rubyn_code/debug.rb +74 -0
- data/lib/rubyn_code/hooks/RUBYN.md +17 -0
- data/lib/rubyn_code/hooks/built_in.rb +9 -9
- data/lib/rubyn_code/hooks/registry.rb +5 -5
- data/lib/rubyn_code/hooks/runner.rb +1 -1
- data/lib/rubyn_code/hooks/user_hooks.rb +16 -16
- data/lib/rubyn_code/learning/RUBYN.md +16 -0
- data/lib/rubyn_code/learning/extractor.rb +22 -22
- data/lib/rubyn_code/learning/injector.rb +17 -18
- data/lib/rubyn_code/learning/instinct.rb +18 -14
- data/lib/rubyn_code/llm/RUBYN.md +15 -0
- data/lib/rubyn_code/llm/client.rb +121 -55
- data/lib/rubyn_code/llm/message_builder.rb +19 -15
- data/lib/rubyn_code/llm/streaming.rb +80 -50
- data/lib/rubyn_code/mcp/RUBYN.md +21 -0
- data/lib/rubyn_code/mcp/client.rb +25 -24
- data/lib/rubyn_code/mcp/config.rb +7 -7
- data/lib/rubyn_code/mcp/sse_transport.rb +27 -26
- data/lib/rubyn_code/mcp/stdio_transport.rb +22 -19
- data/lib/rubyn_code/mcp/tool_bridge.rb +32 -32
- data/lib/rubyn_code/memory/RUBYN.md +17 -0
- data/lib/rubyn_code/memory/models.rb +3 -3
- data/lib/rubyn_code/memory/search.rb +17 -17
- data/lib/rubyn_code/memory/session_persistence.rb +49 -34
- data/lib/rubyn_code/memory/store.rb +17 -17
- data/lib/rubyn_code/observability/RUBYN.md +19 -0
- data/lib/rubyn_code/observability/budget_enforcer.rb +16 -15
- data/lib/rubyn_code/observability/cost_calculator.rb +3 -3
- data/lib/rubyn_code/observability/token_counter.rb +1 -1
- data/lib/rubyn_code/observability/usage_reporter.rb +35 -35
- data/lib/rubyn_code/output/RUBYN.md +11 -0
- data/lib/rubyn_code/output/diff_renderer.rb +6 -6
- data/lib/rubyn_code/output/formatter.rb +4 -4
- data/lib/rubyn_code/permissions/RUBYN.md +17 -0
- data/lib/rubyn_code/permissions/prompter.rb +8 -8
- data/lib/rubyn_code/protocols/RUBYN.md +14 -0
- data/lib/rubyn_code/protocols/interrupt_handler.rb +1 -1
- data/lib/rubyn_code/protocols/plan_approval.rb +9 -9
- data/lib/rubyn_code/protocols/shutdown_handshake.rb +9 -11
- data/lib/rubyn_code/skills/RUBYN.md +19 -0
- data/lib/rubyn_code/skills/catalog.rb +7 -7
- data/lib/rubyn_code/skills/document.rb +15 -15
- data/lib/rubyn_code/skills/loader.rb +6 -8
- data/lib/rubyn_code/sub_agents/RUBYN.md +12 -0
- data/lib/rubyn_code/sub_agents/runner.rb +15 -15
- data/lib/rubyn_code/sub_agents/summarizer.rb +1 -1
- data/lib/rubyn_code/tasks/RUBYN.md +13 -0
- data/lib/rubyn_code/tasks/dag.rb +12 -16
- data/lib/rubyn_code/tasks/manager.rb +24 -24
- data/lib/rubyn_code/tasks/models.rb +4 -4
- data/lib/rubyn_code/teams/RUBYN.md +14 -0
- data/lib/rubyn_code/teams/mailbox.rb +38 -18
- data/lib/rubyn_code/teams/manager.rb +19 -19
- data/lib/rubyn_code/teams/teammate.rb +3 -4
- data/lib/rubyn_code/tools/RUBYN.md +38 -0
- data/lib/rubyn_code/tools/background_run.rb +9 -11
- data/lib/rubyn_code/tools/base.rb +54 -3
- data/lib/rubyn_code/tools/bash.rb +16 -34
- data/lib/rubyn_code/tools/bundle_add.rb +10 -12
- data/lib/rubyn_code/tools/bundle_install.rb +9 -11
- data/lib/rubyn_code/tools/compact.rb +10 -9
- data/lib/rubyn_code/tools/db_migrate.rb +17 -15
- data/lib/rubyn_code/tools/edit_file.rb +12 -12
- data/lib/rubyn_code/tools/executor.rb +9 -4
- data/lib/rubyn_code/tools/git_commit.rb +29 -34
- data/lib/rubyn_code/tools/git_diff.rb +17 -18
- data/lib/rubyn_code/tools/git_log.rb +17 -19
- data/lib/rubyn_code/tools/git_status.rb +18 -20
- data/lib/rubyn_code/tools/glob.rb +7 -9
- data/lib/rubyn_code/tools/grep.rb +11 -9
- data/lib/rubyn_code/tools/load_skill.rb +7 -7
- data/lib/rubyn_code/tools/memory_search.rb +13 -12
- data/lib/rubyn_code/tools/memory_write.rb +14 -12
- data/lib/rubyn_code/tools/rails_generate.rb +16 -16
- data/lib/rubyn_code/tools/read_file.rb +8 -7
- data/lib/rubyn_code/tools/read_inbox.rb +5 -5
- data/lib/rubyn_code/tools/registry.rb +2 -2
- data/lib/rubyn_code/tools/review_pr.rb +55 -55
- data/lib/rubyn_code/tools/run_specs.rb +20 -19
- data/lib/rubyn_code/tools/schema.rb +9 -11
- data/lib/rubyn_code/tools/send_message.rb +10 -10
- data/lib/rubyn_code/tools/spawn_agent.rb +51 -23
- data/lib/rubyn_code/tools/spawn_teammate.rb +21 -21
- data/lib/rubyn_code/tools/task.rb +28 -28
- data/lib/rubyn_code/tools/web_fetch.rb +46 -31
- data/lib/rubyn_code/tools/web_search.rb +64 -66
- data/lib/rubyn_code/tools/write_file.rb +7 -6
- data/lib/rubyn_code/version.rb +1 -1
- data/lib/rubyn_code.rb +136 -105
- metadata +94 -21
data/README.md
CHANGED
|
@@ -1,620 +1,422 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/RubynLogo.png" alt="Rubyn Code" width="200">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">Rubyn Code</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>AI Code Assistant for Ruby & Rails — Open Source</strong>
|
|
9
|
+
</p>
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://rubygems.org/gems/rubyn-code"><img src="https://badge.fury.io/rb/rubyn-code.svg" alt="Gem Version"></a>
|
|
13
|
+
<a href="https://github.com/rubocop/rubocop"><img src="https://img.shields.io/badge/code_style-rubocop-brightgreen.svg" alt="Ruby Style Guide"></a>
|
|
14
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
15
|
+
<a href="https://github.com/MatthewSuttles/rubyn-code/actions/workflows/ci.yml"><img src="https://github.com/MatthewSuttles/rubyn-code/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
16
|
+
</p>
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
rubyn-code
|
|
18
|
+
Refactor controllers, generate idiomatic RSpec, catch N+1 queries, review code for anti-patterns, and build entire features — all context-aware with your schema, routes, and specs. Powered by Claude Opus 4.6, running on your existing Claude subscription.
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
rubyn-code --yolo
|
|
20
|
+
<img width="1230" height="280" alt="image" src="https://github.com/user-attachments/assets/14e07ce8-def0-4a8f-ac89-46661361a4eb" />
|
|
16
21
|
|
|
17
|
-
# Run a single prompt and exit
|
|
18
|
-
rubyn-code -p "Add authentication to the users controller"
|
|
19
|
-
```
|
|
20
22
|
|
|
21
|
-
**
|
|
23
|
+
> **Rubyn is going open source.** The original [Rubyn gem](https://github.com/Rubyn-AI/rubyn) provided AI-assisted refactoring, spec generation, and code review through the Rubyn API. **Rubyn Code** is the next evolution — a complete agentic coding assistant that runs locally, thinks for itself, and learns from every session. No API keys. No separate billing. Just `gem install rubyn-code` and go.
|
|
22
24
|
|
|
23
|
-
##
|
|
25
|
+
## Why Rubyn?
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
- **Rails-native** — understands service object extraction, RSpec conventions, ActiveRecord patterns, and Hotwire
|
|
28
|
+
- **Context-aware** — automatically incorporates schema, routes, specs, factories, and models
|
|
29
|
+
- **Best practices built in** — ships with 112 curated Ruby and Rails guidelines that load on demand
|
|
30
|
+
- **Agentic** — doesn't just answer questions. Reads files, writes code, runs specs, commits, reviews PRs, spawns sub-agents, and remembers what it learns
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
- `RUBYN.md` — Rubyn Code native
|
|
29
|
-
- `CLAUDE.md` — Claude Code compatible (works out of the box)
|
|
30
|
-
- `AGENT.md` — Generic agent convention
|
|
32
|
+
## Install
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Requires **Ruby 4.0+**. Install with your latest Ruby, then pin it so it works in every project:
|
|
33
35
|
|
|
34
36
|
```bash
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
# My Project
|
|
37
|
+
# Install the gem
|
|
38
|
+
gem install rubyn-code
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
- Follow the service object pattern for business logic
|
|
42
|
-
- API endpoints use Grape, not Rails controllers
|
|
43
|
-
- Run rubocop before committing
|
|
44
|
-
EOF
|
|
40
|
+
# Pin to this Ruby — bypasses rbenv/rvm version switching
|
|
41
|
+
rubyn-code --setup
|
|
45
42
|
```
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Rubyn Code loads `RUBYN.md` from multiple locations, all merged together:
|
|
50
|
-
|
|
51
|
-
| Location | Scope | Loaded |
|
|
52
|
-
|----------|-------|--------|
|
|
53
|
-
| `~/.rubyn-code/RUBYN.md` | Global | Always — applies to all projects |
|
|
54
|
-
| Parent directories above project root | Monorepo | Auto — walks up to find shared instructions |
|
|
55
|
-
| `./RUBYN.md` / `./CLAUDE.md` / `./AGENT.md` | Project | Auto — main project instructions |
|
|
56
|
-
| `./.rubyn-code/RUBYN.md` | Project | Auto — alternative location |
|
|
57
|
-
| `./subdir/RUBYN.md` (or CLAUDE.md, AGENT.md) | Subfolder | Auto — one level deep at startup |
|
|
58
|
-
| Any directory Rubyn navigates to | Dynamic | On demand — Rubyn checks when entering new dirs |
|
|
44
|
+
That's it. `rubyn-code` now works in any project regardless of `.ruby-version`.
|
|
59
45
|
|
|
60
|
-
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Using rbenv?</summary>
|
|
61
48
|
|
|
62
|
-
|
|
49
|
+
If you manage multiple Rubies with rbenv, install on your latest:
|
|
63
50
|
|
|
51
|
+
```bash
|
|
52
|
+
RBENV_VERSION=4.0.2 gem install rubyn-code
|
|
53
|
+
RBENV_VERSION=4.0.2 rubyn-code --setup
|
|
64
54
|
```
|
|
65
|
-
my-monorepo/
|
|
66
|
-
├── RUBYN.md # Shared conventions (loaded for all services)
|
|
67
|
-
├── api/
|
|
68
|
-
│ ├── RUBYN.md # API-specific: "Use Grape, JSON:API format"
|
|
69
|
-
│ └── ...
|
|
70
|
-
├── web/
|
|
71
|
-
│ ├── RUBYN.md # Web-specific: "Use Hotwire, ViewComponents"
|
|
72
|
-
│ └── ...
|
|
73
|
-
└── workers/
|
|
74
|
-
├── RUBYN.md # Worker-specific: "Use Sidekiq, idempotent jobs"
|
|
75
|
-
└── ...
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Skills — 112 Ruby/Rails Best Practice Documents
|
|
79
|
-
|
|
80
|
-
Rubyn Code ships with 112 best practice documents organized by topic. Skills load **on-demand** — only their names appear in memory until Rubyn needs the full content.
|
|
81
|
-
|
|
82
|
-
### Built-in skill categories
|
|
83
55
|
|
|
84
|
-
|
|
85
|
-
|----------|--------|
|
|
86
|
-
| **Ruby** | Collections, error handling, metaprogramming, concurrency |
|
|
87
|
-
| **Rails** | Controllers, models, views, migrations, ActiveRecord |
|
|
88
|
-
| **RSpec** | Matchers, factories, request specs, performance |
|
|
89
|
-
| **Minitest** | Assertions, system tests, fixtures |
|
|
90
|
-
| **Design Patterns** | Observer, strategy, decorator, builder, and more |
|
|
91
|
-
| **SOLID** | All five principles with Ruby examples |
|
|
92
|
-
| **Refactoring** | Extract method, replace conditional, code smells |
|
|
93
|
-
| **Code Quality** | Naming, YAGNI, value objects, null object |
|
|
94
|
-
| **Gems** | Development, versioning, publishing |
|
|
95
|
-
| **Sinatra** | Application structure, middleware, testing |
|
|
56
|
+
The `--setup` command creates a launcher in `~/.local/bin` that calls the gem wrapper directly, skipping rbenv's shim. As long as `~/.local/bin` is in your PATH before `~/.rbenv/shims`, you're good.
|
|
96
57
|
|
|
97
|
-
|
|
58
|
+
</details>
|
|
98
59
|
|
|
99
|
-
|
|
60
|
+
<details>
|
|
61
|
+
<summary>Using rvm?</summary>
|
|
100
62
|
|
|
101
63
|
```bash
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# Our API Conventions
|
|
106
|
-
|
|
107
|
-
- All endpoints return JSON:API format
|
|
108
|
-
- Use Grape for API controllers
|
|
109
|
-
- Version APIs with /v1/ prefix
|
|
110
|
-
- Always paginate collections with Kaminari
|
|
111
|
-
EOF
|
|
112
|
-
|
|
113
|
-
# Global skills (apply to all projects)
|
|
114
|
-
mkdir -p ~/.rubyn-code/skills
|
|
115
|
-
cat > ~/.rubyn-code/skills/my_preferences.md << 'EOF'
|
|
116
|
-
# My Coding Preferences
|
|
117
|
-
|
|
118
|
-
- Use double quotes for strings
|
|
119
|
-
- Prefer guard clauses over nested conditionals
|
|
120
|
-
- Always add frozen_string_literal comment
|
|
121
|
-
EOF
|
|
64
|
+
rvm use 4.0.2
|
|
65
|
+
gem install rubyn-code
|
|
66
|
+
rubyn-code --setup
|
|
122
67
|
```
|
|
123
68
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
## PR Review — Best Practice Code Review
|
|
69
|
+
</details>
|
|
127
70
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
### Quick usage
|
|
71
|
+
<details>
|
|
72
|
+
<summary>From source</summary>
|
|
131
73
|
|
|
132
74
|
```bash
|
|
133
|
-
|
|
134
|
-
rubyn
|
|
135
|
-
|
|
75
|
+
git clone https://github.com/MatthewSuttles/rubyn-code.git
|
|
76
|
+
cd rubyn-code
|
|
77
|
+
bundle install
|
|
78
|
+
bundle exec ruby -Ilib exe/rubyn-code
|
|
136
79
|
```
|
|
137
80
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
| Focus | What it checks |
|
|
141
|
-
|-------|---------------|
|
|
142
|
-
| `all` *(default)* | Everything — code quality, security, performance, testing, conventions |
|
|
143
|
-
| `security` | SQL injection, XSS, CSRF, mass assignment, auth gaps, sensitive data exposure |
|
|
144
|
-
| `performance` | N+1 queries, missing indexes, eager loading, caching, pagination |
|
|
145
|
-
| `style` | Ruby idioms, naming, method length, DRY violations, dead code |
|
|
146
|
-
| `testing` | Missing coverage, test quality, factory usage, edge cases, flaky test risks |
|
|
81
|
+
</details>
|
|
147
82
|
|
|
148
|
-
|
|
83
|
+
**Authentication:** Rubyn Code reads your Claude Code OAuth token from the macOS Keychain automatically. Just make sure you've logged into Claude Code once (`claude` in your terminal). Also supports `ANTHROPIC_API_KEY` env var.
|
|
149
84
|
|
|
150
|
-
|
|
151
|
-
2. Categorizes changed files (Ruby, templates, specs, migrations, config)
|
|
152
|
-
3. Loads relevant best practice skills automatically
|
|
153
|
-
4. Reviews every change with actionable suggestions
|
|
154
|
-
5. Rates each issue by severity:
|
|
85
|
+
## Quick Start
|
|
155
86
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
| **[warning]** | Should fix — performance issue, missing test, or convention violation |
|
|
160
|
-
| **[suggestion]** | Nice to have — cleaner approach, better naming, or Ruby idiom |
|
|
161
|
-
| **[nitpick]** | Optional — style preference or minor readability improvement |
|
|
87
|
+
```bash
|
|
88
|
+
# Interactive REPL
|
|
89
|
+
rubyn-code
|
|
162
90
|
|
|
163
|
-
|
|
91
|
+
# YOLO mode — no tool approval prompts
|
|
92
|
+
rubyn-code --yolo
|
|
164
93
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
User.where(active: true).each { |u| u.posts.count }
|
|
168
|
-
↳ N+1 query — `posts.count` fires a separate query per user.
|
|
169
|
-
Fix: User.where(active: true).includes(:posts).each { ... }
|
|
170
|
-
Or use counter_cache: true on the association.
|
|
171
|
-
|
|
172
|
-
[critical] app/controllers/admin_controller.rb:8
|
|
173
|
-
params[:user_id] used directly in SQL
|
|
174
|
-
↳ SQL injection risk. Use parameterized queries.
|
|
175
|
-
Fix: User.where(id: params[:user_id])
|
|
176
|
-
|
|
177
|
-
[suggestion] app/services/create_order.rb:22
|
|
178
|
-
Method `process` is 45 lines long
|
|
179
|
-
↳ Extract into smaller private methods for readability.
|
|
180
|
-
Consider: extract_line_items, calculate_totals, apply_discounts
|
|
94
|
+
# Single prompt
|
|
95
|
+
rubyn-code -p "Refactor app/controllers/orders_controller.rb into service objects"
|
|
181
96
|
```
|
|
182
97
|
|
|
183
|
-
|
|
98
|
+
## What Can Rubyn Do?
|
|
184
99
|
|
|
185
|
-
|
|
186
|
-
rubyn > Review my PR against best practices
|
|
187
|
-
rubyn > Check this branch for security issues
|
|
188
|
-
rubyn > Are there any N+1 queries in my changes?
|
|
100
|
+
### Refactor code
|
|
189
101
|
```
|
|
102
|
+
rubyn > This orders controller is 300 lines. Break it up.
|
|
103
|
+
> read_file: path=app/controllers/orders_controller.rb
|
|
104
|
+
> read_file: path=app/models/order.rb
|
|
105
|
+
> read_file: path=config/routes.rb
|
|
106
|
+
> write_file: path=app/services/orders/create_service.rb
|
|
107
|
+
> write_file: path=app/services/orders/cancel_service.rb
|
|
108
|
+
> edit_file: path=app/controllers/orders_controller.rb
|
|
190
109
|
|
|
191
|
-
|
|
110
|
+
Done. Extracted CreateService and CancelService. Controller is down to 45 lines.
|
|
111
|
+
```
|
|
192
112
|
|
|
193
|
-
|
|
113
|
+
### Generate specs
|
|
114
|
+
```
|
|
115
|
+
rubyn > Write specs for the new service objects
|
|
116
|
+
> read_file: path=app/services/orders/create_service.rb
|
|
117
|
+
> read_file: path=spec/factories/orders.rb
|
|
118
|
+
> write_file: path=spec/services/orders/create_service_spec.rb
|
|
119
|
+
> run_specs: path=spec/services/orders/
|
|
194
120
|
|
|
121
|
+
4 examples, 0 failures. All green. ✓
|
|
195
122
|
```
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
│ Layer 15: MCP (external tool servers via protocol) │
|
|
199
|
-
│ Layer 14: Hooks & Events (pre/post tool interception) │
|
|
200
|
-
│ Layer 13: Observability (cost tracking, token counting) │
|
|
201
|
-
│ Layer 12: Memory (persistent knowledge across sessions) │
|
|
202
|
-
│ Layer 11: Autonomous Operation (idle polling, KAIROS) │
|
|
203
|
-
│ Layer 10: Protocols (shutdown handshake, plan approval) │
|
|
204
|
-
│ Layer 9: Teams (persistent teammates, mailbox messaging) │
|
|
205
|
-
│ Layer 8: Background Execution (async tasks, notifications) │
|
|
206
|
-
│ Layer 7: Task System (persistent DAG, dependencies) │
|
|
207
|
-
│ Layer 6: Sub-Agents (isolated context, summary return) │
|
|
208
|
-
│ Layer 5: Skills (112 Ruby/Rails best practice docs) │
|
|
209
|
-
│ Layer 4: Context Management (compression pipeline) │
|
|
210
|
-
│ Layer 3: Permissions (tiered access, deny lists) │
|
|
211
|
-
│ Layer 2: Tool System (28 tools, dispatch map) │
|
|
212
|
-
│ Layer 1: THE AGENT LOOP (while tool_use → execute → repeat) │
|
|
213
|
-
└──────────────────────────────────────────────────────────────┘
|
|
123
|
+
|
|
124
|
+
### Review code
|
|
214
125
|
```
|
|
126
|
+
rubyn > /review
|
|
127
|
+
> review_pr: base_branch=main
|
|
215
128
|
|
|
216
|
-
|
|
129
|
+
[warning] app/models/user.rb:15 — N+1 query detected
|
|
130
|
+
[critical] app/controllers/admin_controller.rb:8 — SQL injection risk
|
|
131
|
+
[suggestion] app/services/create_order.rb:22 — Method too long, extract private methods
|
|
132
|
+
```
|
|
217
133
|
|
|
218
|
-
|
|
219
|
-
while response.tool_use?
|
|
220
|
-
results = execute_tools(response)
|
|
221
|
-
conversation.add_tool_results(results)
|
|
222
|
-
response = llm.chat(conversation.messages)
|
|
223
|
-
end
|
|
134
|
+
### Explore codebases
|
|
224
135
|
```
|
|
136
|
+
rubyn > I'm new to this project. Give me the lay of the land.
|
|
225
137
|
|
|
226
|
-
|
|
138
|
+
Spawning explore agent...
|
|
139
|
+
[⠹] Agent exploring the codebase... (23 tools)
|
|
140
|
+
Agent finished (23 tool calls).
|
|
227
141
|
|
|
228
|
-
|
|
142
|
+
This is a Rails 7.1 e-commerce app with...
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 28 Built-in Tools
|
|
229
146
|
|
|
230
147
|
| Category | Tools |
|
|
231
148
|
|----------|-------|
|
|
232
149
|
| **File I/O** | `read_file`, `write_file`, `edit_file` |
|
|
233
150
|
| **Search** | `glob`, `grep` |
|
|
234
151
|
| **Execution** | `bash` (sandboxed, dangerous commands blocked) |
|
|
235
|
-
| **Web** | `web_search
|
|
152
|
+
| **Web** | `web_search`, `web_fetch` |
|
|
236
153
|
| **Git** | `git_status`, `git_diff`, `git_log`, `git_commit` |
|
|
237
154
|
| **Rails** | `rails_generate`, `db_migrate`, `run_specs`, `bundle_install`, `bundle_add` |
|
|
238
155
|
| **Review** | `review_pr` (diff-based best practice code review) |
|
|
239
|
-
| **Agents** | `spawn_agent
|
|
240
|
-
| **
|
|
156
|
+
| **Agents** | `spawn_agent`, `spawn_teammate`, `background_run` |
|
|
157
|
+
| **Context** | `compact`, `load_skill`, `task` |
|
|
241
158
|
| **Memory** | `memory_search`, `memory_write` |
|
|
242
159
|
| **Teams** | `send_message`, `read_inbox` |
|
|
243
160
|
|
|
244
|
-
##
|
|
161
|
+
## 112 Best Practice Skills
|
|
245
162
|
|
|
246
|
-
|
|
163
|
+
Rubyn ships with curated best practice documents that load on demand. Only skill names are in memory — full content loads when Rubyn needs it.
|
|
164
|
+
|
|
165
|
+
| Category | Topics |
|
|
166
|
+
|----------|--------|
|
|
167
|
+
| **Ruby** | Collections, error handling, metaprogramming, concurrency, pattern matching |
|
|
168
|
+
| **Rails** | Controllers, models, views, migrations, ActiveRecord, Hotwire, caching, security |
|
|
169
|
+
| **RSpec** | Matchers, factories, request specs, shared examples, performance |
|
|
170
|
+
| **Minitest** | Assertions, system tests, fixtures, mocking |
|
|
171
|
+
| **Design Patterns** | Observer, strategy, decorator, builder, factory, adapter, and more |
|
|
172
|
+
| **SOLID** | All five principles with Ruby examples |
|
|
173
|
+
| **Refactoring** | Extract method/class, replace conditional, code smells, command-query separation |
|
|
174
|
+
| **Code Quality** | Naming, YAGNI, value objects, null object, technical debt |
|
|
175
|
+
| **Gems** | Sidekiq, Devise, FactoryBot, Pundit, Faraday, Stripe, RuboCop, dry-rb |
|
|
176
|
+
| **Sinatra** | Application structure, middleware, testing |
|
|
177
|
+
|
|
178
|
+
### Custom skills
|
|
179
|
+
|
|
180
|
+
Override or extend with your own:
|
|
247
181
|
|
|
248
182
|
```bash
|
|
249
|
-
|
|
250
|
-
rubyn-code
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
rubyn-code
|
|
255
|
-
|
|
183
|
+
# Project-specific
|
|
184
|
+
mkdir -p .rubyn-code/skills
|
|
185
|
+
echo "# Always use Grape for APIs" > .rubyn-code/skills/api_conventions.md
|
|
186
|
+
|
|
187
|
+
# Global
|
|
188
|
+
mkdir -p ~/.rubyn-code/skills
|
|
189
|
+
echo "# Use double quotes for strings" > ~/.rubyn-code/skills/my_style.md
|
|
256
190
|
```
|
|
257
191
|
|
|
258
|
-
|
|
192
|
+
## Context Architecture
|
|
259
193
|
|
|
260
|
-
|
|
194
|
+
Rubyn automatically loads relevant context based on what you're working on:
|
|
261
195
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
/spawn name role Spawn a persistent teammate agent
|
|
267
|
-
/compact Compress conversation context
|
|
268
|
-
/cost Show token usage and costs
|
|
269
|
-
/clear Clear the terminal
|
|
270
|
-
/undo Remove last exchange
|
|
271
|
-
/tasks List all tasks
|
|
272
|
-
/budget [amt] Show or set session budget
|
|
273
|
-
/skill [name] Load or list available skills
|
|
274
|
-
/resume [id] Resume or list sessions
|
|
275
|
-
/version Show version
|
|
276
|
-
```
|
|
196
|
+
- **Controllers** → includes models, routes, request specs, services
|
|
197
|
+
- **Models** → includes schema, associations, specs, factories
|
|
198
|
+
- **Service objects** → includes referenced models and their specs
|
|
199
|
+
- **Any file** → checks for `RUBYN.md`, `CLAUDE.md`, or `AGENT.md` instructions
|
|
277
200
|
|
|
278
|
-
|
|
201
|
+
## RUBYN.md — Project Instructions
|
|
279
202
|
|
|
280
|
-
|
|
281
|
-
- End a line with `\` for multiline input
|
|
282
|
-
- Ctrl-C once to interrupt, twice to exit
|
|
283
|
-
- `/` + Tab autocompletes slash commands
|
|
203
|
+
Drop a `RUBYN.md` in your project root and Rubyn follows your conventions:
|
|
284
204
|
|
|
285
|
-
|
|
205
|
+
```markdown
|
|
206
|
+
# My Project
|
|
286
207
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
208
|
+
- Always use RSpec, never Minitest
|
|
209
|
+
- Use FactoryBot for test data
|
|
210
|
+
- Service objects go in app/services/ with a .call interface
|
|
211
|
+
- API endpoints use Grape, not Rails controllers
|
|
212
|
+
- Run rubocop before committing
|
|
213
|
+
```
|
|
291
214
|
|
|
292
|
-
|
|
215
|
+
Also reads `CLAUDE.md` and `AGENT.md` — no migration needed from other tools.
|
|
216
|
+
|
|
217
|
+
| Location | Scope |
|
|
218
|
+
|----------|-------|
|
|
219
|
+
| `~/.rubyn-code/RUBYN.md` | Global — all projects |
|
|
220
|
+
| Parent directories | Monorepo — shared conventions |
|
|
221
|
+
| `./RUBYN.md` | Project root |
|
|
222
|
+
| `./subdir/RUBYN.md` | Subfolder-specific |
|
|
293
223
|
|
|
294
|
-
|
|
224
|
+
## PR Review
|
|
295
225
|
|
|
296
|
-
|
|
226
|
+
Review your branch against best practices before opening a PR:
|
|
297
227
|
|
|
298
228
|
```
|
|
299
|
-
rubyn >
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
> edit_file: path=app/controllers/users_controller.rb, old_text=User.all, new_text=User.includes(:posts).all
|
|
303
|
-
Edited app/controllers/users_controller.rb
|
|
304
|
-
> run_specs: path=spec/controllers/users_controller_spec.rb
|
|
305
|
-
3 examples, 0 failures
|
|
306
|
-
|
|
307
|
-
Fixed the N+1 by adding `.includes(:posts)` to the query. Specs pass. ✓
|
|
229
|
+
rubyn > /review # vs main
|
|
230
|
+
rubyn > /review develop # vs develop
|
|
231
|
+
rubyn > /review main security # security focus only
|
|
308
232
|
```
|
|
309
233
|
|
|
310
|
-
|
|
234
|
+
Focus areas: `all`, `security`, `performance`, `style`, `testing`
|
|
311
235
|
|
|
312
|
-
|
|
236
|
+
Severity ratings: **[critical]** **[warning]** **[suggestion]** **[nitpick]**
|
|
313
237
|
|
|
314
|
-
|
|
238
|
+
## Sub-Agents & Teams
|
|
315
239
|
|
|
316
|
-
|
|
317
|
-
|
|
240
|
+
### Sub-Agents (disposable)
|
|
241
|
+
```
|
|
242
|
+
rubyn > Explore the app/services directory and summarize the patterns
|
|
318
243
|
|
|
319
244
|
Spawning explore agent...
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
> sub-agent > read_file: path=app/services/process_payment.rb
|
|
323
|
-
Agent finished.
|
|
324
|
-
|
|
325
|
-
## Sub-Agent Result (explore)
|
|
326
|
-
The services directory uses a consistent .call pattern...
|
|
245
|
+
[⠹] Dispatching the intern... (18 tools)
|
|
246
|
+
Agent finished (18 tool calls).
|
|
327
247
|
```
|
|
328
248
|
|
|
329
|
-
Two types:
|
|
330
|
-
- **Explore** (`agent_type: "explore"`) — read-only tools, for research
|
|
331
|
-
- **Worker** (`agent_type: "worker"`) — full write access, for doing work
|
|
249
|
+
Two types: **explore** (read-only) and **worker** (full write access).
|
|
332
250
|
|
|
333
251
|
### Teams (persistent)
|
|
334
|
-
|
|
335
|
-
Spawn named teammates that persist, have their own inbox, and communicate via messages:
|
|
336
|
-
|
|
337
|
-
```bash
|
|
252
|
+
```
|
|
338
253
|
rubyn > /spawn alice tester
|
|
339
254
|
Spawned teammate alice as tester
|
|
340
255
|
|
|
341
256
|
rubyn > Send alice a message to write specs for the User model
|
|
342
|
-
> send_message: to=alice, content=Write specs for the User model...
|
|
343
257
|
```
|
|
344
258
|
|
|
345
|
-
Teammates run in background threads with their own agent loop
|
|
259
|
+
Teammates run in background threads with their own agent loop and mailbox.
|
|
260
|
+
|
|
261
|
+
## Continuous Learning
|
|
262
|
+
|
|
263
|
+
Rubyn gets smarter with every session:
|
|
264
|
+
|
|
265
|
+
1. **During conversation** — saves preferences and patterns to memory
|
|
266
|
+
2. **On session end** — extracts reusable "instincts" with confidence scores
|
|
267
|
+
3. **On next startup** — injects top instincts into the system prompt
|
|
268
|
+
4. **Over time** — reinforced instincts strengthen, unused ones decay and get pruned
|
|
269
|
+
|
|
270
|
+
## Streaming Output
|
|
271
|
+
|
|
272
|
+
Real-time streaming with live syntax highlighting via Rouge/Monokai. Code blocks are buffered and highlighted when complete. No waiting for full responses.
|
|
273
|
+
|
|
274
|
+
## Search Providers
|
|
275
|
+
|
|
276
|
+
Auto-detects the best available provider:
|
|
277
|
+
|
|
278
|
+
| Provider | Env Variable | Free Tier |
|
|
279
|
+
|----------|-------------|-----------|
|
|
280
|
+
| **DuckDuckGo** | *(none)* | Unlimited |
|
|
281
|
+
| **Tavily** | `TAVILY_API_KEY` | 1,000/mo |
|
|
282
|
+
| **Brave** | `BRAVE_API_KEY` | 2,000/mo |
|
|
283
|
+
| **SerpAPI** | `SERPAPI_API_KEY` | 100/mo |
|
|
284
|
+
| **Google** | `GOOGLE_SEARCH_API_KEY` + `GOOGLE_SEARCH_CX` | 100/day |
|
|
346
285
|
|
|
347
286
|
## User Hooks
|
|
348
287
|
|
|
349
|
-
Customize
|
|
288
|
+
Customize behavior via `.rubyn-code/hooks.yml`:
|
|
350
289
|
|
|
351
290
|
```yaml
|
|
352
|
-
# Block dangerous operations
|
|
353
291
|
pre_tool_use:
|
|
354
292
|
- tool: bash
|
|
355
293
|
match: "rm -rf"
|
|
356
294
|
action: deny
|
|
357
|
-
reason: "Destructive
|
|
358
|
-
|
|
295
|
+
reason: "Destructive delete blocked"
|
|
359
296
|
- tool: write_file
|
|
360
297
|
path: "db/migrate/**"
|
|
361
298
|
action: deny
|
|
362
|
-
reason: "Use rails generate migration
|
|
363
|
-
|
|
364
|
-
- tool: bash
|
|
365
|
-
match: "git push --force"
|
|
366
|
-
action: deny
|
|
367
|
-
reason: "Force push blocked — use regular push"
|
|
299
|
+
reason: "Use rails generate migration"
|
|
368
300
|
|
|
369
|
-
# Audit trail for file writes
|
|
370
301
|
post_tool_use:
|
|
371
302
|
- tool: write_file
|
|
372
303
|
action: log
|
|
373
|
-
- tool: edit_file
|
|
374
|
-
action: log
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Hook actions:
|
|
378
|
-
- **`deny`** — block the tool call with a reason (shown to the model)
|
|
379
|
-
- **`log`** — append to `.rubyn-code/audit.log`
|
|
380
|
-
|
|
381
|
-
Matching:
|
|
382
|
-
- **`tool`** — exact tool name match
|
|
383
|
-
- **`match`** — string match anywhere in the parameters
|
|
384
|
-
- **`path`** — glob pattern match on the `path` parameter
|
|
385
|
-
|
|
386
|
-
## Continuous Learning
|
|
387
|
-
|
|
388
|
-
Rubyn learns from every session and gets smarter over time.
|
|
389
|
-
|
|
390
|
-
### How it works
|
|
391
|
-
|
|
392
|
-
1. **During conversation** — Rubyn saves preferences and patterns via `memory_write`
|
|
393
|
-
2. **On session end** — extracts reusable patterns ("instincts") with confidence scores
|
|
394
|
-
3. **On next startup** — injects top instincts and recent memories into the system prompt
|
|
395
|
-
4. **Over time** — unused instincts decay, reinforced ones strengthen
|
|
396
|
-
|
|
397
|
-
### Instinct lifecycle
|
|
398
|
-
|
|
399
304
|
```
|
|
400
|
-
Session 1: You correct Rubyn → instinct saved (confidence: 0.5)
|
|
401
|
-
Session 2: Same pattern confirmed → confidence: 0.7
|
|
402
|
-
Session 3: Not used → confidence: 0.65 (decay)
|
|
403
|
-
Session 4: Reinforced again → confidence: 0.8
|
|
404
|
-
Session 10: Never used again → deleted (below 0.05)
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Feedback reinforcement
|
|
408
|
-
|
|
409
|
-
Rubyn detects your feedback and adjusts:
|
|
410
|
-
- **"yes that fixed it"** / **"perfect"** → reinforces recent instincts
|
|
411
|
-
- **"no, use X instead"** / **"that's wrong"** → penalizes and learns the correction
|
|
412
305
|
|
|
413
|
-
##
|
|
414
|
-
|
|
415
|
-
Rubyn can search the web and fetch documentation:
|
|
306
|
+
## CLI Reference
|
|
416
307
|
|
|
417
308
|
```bash
|
|
418
|
-
rubyn
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
rubyn
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
Rubyn auto-detects the best available search provider based on your environment variables. No configuration needed — just set the key and it switches automatically.
|
|
428
|
-
|
|
429
|
-
| Provider | Env Variable | Free Tier | Notes |
|
|
430
|
-
|----------|-------------|-----------|-------|
|
|
431
|
-
| **DuckDuckGo** | *(none needed)* | Unlimited | Default. No API key required |
|
|
432
|
-
| **Tavily** | `TAVILY_API_KEY` | 1,000/mo | Built for AI agents. Includes AI-generated answer |
|
|
433
|
-
| **Brave** | `BRAVE_API_KEY` | 2,000/mo | Fast, good quality results |
|
|
434
|
-
| **SerpAPI** | `SERPAPI_API_KEY` | 100/mo | Google results via API |
|
|
435
|
-
| **Google** | `GOOGLE_SEARCH_API_KEY` + `GOOGLE_SEARCH_CX` | 100/day | Official Google Custom Search |
|
|
436
|
-
|
|
437
|
-
**Priority order:** Tavily > Brave > SerpAPI > Google > DuckDuckGo
|
|
438
|
-
|
|
439
|
-
To switch providers, just export the key:
|
|
440
|
-
|
|
441
|
-
```bash
|
|
442
|
-
export TAVILY_API_KEY=tvly-xxxxxxxxxxxxx
|
|
443
|
-
rubyn-code # Now uses Tavily automatically
|
|
309
|
+
rubyn-code # Interactive REPL
|
|
310
|
+
rubyn-code --yolo # Auto-approve all tools
|
|
311
|
+
rubyn-code -p "prompt" # Single prompt, exit when done
|
|
312
|
+
rubyn-code --resume [ID] # Resume previous session
|
|
313
|
+
rubyn-code --setup # Pin to this Ruby (run once after install)
|
|
314
|
+
rubyn-code --debug # Enable debug output
|
|
315
|
+
rubyn-code --auth # Authenticate with Claude
|
|
316
|
+
rubyn-code --version # Show version
|
|
317
|
+
rubyn-code --help # Show help
|
|
444
318
|
```
|
|
445
319
|
|
|
446
|
-
|
|
320
|
+
### Slash Commands
|
|
447
321
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
rubyn > Review my branch before I open a PR
|
|
461
|
-
> /review
|
|
462
|
-
```
|
|
322
|
+
| Command | Purpose |
|
|
323
|
+
|---------|---------|
|
|
324
|
+
| `/help` | Show help |
|
|
325
|
+
| `/quit` | Exit (saves session + extracts learnings) |
|
|
326
|
+
| `/review [base]` | PR review against best practices |
|
|
327
|
+
| `/spawn name role` | Spawn a persistent teammate |
|
|
328
|
+
| `/compact` | Compress conversation context |
|
|
329
|
+
| `/cost` | Show token usage and costs |
|
|
330
|
+
| `/tasks` | List all tasks |
|
|
331
|
+
| `/budget [amt]` | Show or set session budget |
|
|
332
|
+
| `/skill [name]` | Load or list available skills |
|
|
333
|
+
| `/resume [id]` | Resume or list sessions |
|
|
463
334
|
|
|
464
335
|
## Authentication
|
|
465
336
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
2. Rubyn Code reads the OAuth token from your macOS Keychain
|
|
472
|
-
3. It authenticates directly with the Anthropic API using your subscription
|
|
473
|
-
|
|
474
|
-
### Fallback chain
|
|
475
|
-
|
|
476
|
-
| Priority | Source | How |
|
|
477
|
-
|----------|--------|-----|
|
|
478
|
-
| 1 | macOS Keychain | Reads Claude Code's OAuth token automatically |
|
|
479
|
-
| 2 | `~/.rubyn-code/tokens.yml` | Manual token file |
|
|
480
|
-
| 3 | `ANTHROPIC_API_KEY` env var | Standard API key (pay-per-use) |
|
|
481
|
-
|
|
482
|
-
### Supported plans
|
|
483
|
-
|
|
484
|
-
Works with Claude Pro, Max, Team, and Enterprise subscriptions. Default model: **Claude Opus 4.6**.
|
|
485
|
-
|
|
486
|
-
## Context Compression
|
|
487
|
-
|
|
488
|
-
Three-layer pipeline for infinite sessions:
|
|
337
|
+
| Priority | Source | Setup |
|
|
338
|
+
|----------|--------|-------|
|
|
339
|
+
| 1 | macOS Keychain | Log into Claude Code once: `claude` |
|
|
340
|
+
| 2 | Token file | `~/.rubyn-code/tokens.yml` |
|
|
341
|
+
| 3 | Environment | `export ANTHROPIC_API_KEY=sk-ant-...` |
|
|
489
342
|
|
|
490
|
-
|
|
491
|
-
2. **Auto Compact** — triggers at 50K tokens, saves transcript to disk, LLM-summarizes
|
|
492
|
-
3. **Manual Compact** — `/compact` at strategic moments (between phases of work)
|
|
343
|
+
Works with Claude Pro, Max, Team, and Enterprise. Default model: **Claude Opus 4.6**.
|
|
493
344
|
|
|
494
|
-
##
|
|
345
|
+
## Architecture
|
|
495
346
|
|
|
496
|
-
|
|
347
|
+
16-layer agentic architecture:
|
|
497
348
|
|
|
498
349
|
```
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
// .rubyn-code/mcp.json
|
|
518
|
-
{
|
|
519
|
-
"servers": {
|
|
520
|
-
"github": {
|
|
521
|
-
"command": "npx",
|
|
522
|
-
"args": ["-y", "@anthropic/github-mcp-server"]
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
350
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
351
|
+
│ Layer 16: Continuous Learning (pattern extraction + decay) │
|
|
352
|
+
│ Layer 15: MCP (external tool servers via protocol) │
|
|
353
|
+
│ Layer 14: Hooks & Events (user-configurable pre/post hooks) │
|
|
354
|
+
│ Layer 13: Observability (cost tracking, budget enforcement) │
|
|
355
|
+
│ Layer 12: Memory (persistent knowledge across sessions) │
|
|
356
|
+
│ Layer 11: Autonomous Operation (GOLEM daemon, task claiming) │
|
|
357
|
+
│ Layer 10: Protocols (shutdown handshake, plan approval) │
|
|
358
|
+
│ Layer 9: Teams (persistent teammates, mailbox messaging) │
|
|
359
|
+
│ Layer 8: Background Execution (async tasks, notifications) │
|
|
360
|
+
│ Layer 7: Task System (persistent DAG with dependencies) │
|
|
361
|
+
│ Layer 6: Sub-Agents (explore + worker, isolated contexts) │
|
|
362
|
+
│ Layer 5: Skills (112 best practice docs, on-demand loading) │
|
|
363
|
+
│ Layer 4: Context Management (3-layer compression pipeline) │
|
|
364
|
+
│ Layer 3: Permissions (tiered access + deny lists + hooks) │
|
|
365
|
+
│ Layer 2: Tool System (28 tools, dispatch map registry) │
|
|
366
|
+
│ Layer 1: THE AGENT LOOP (while tool_use → execute → repeat) │
|
|
367
|
+
└──────────────────────────────────────────────────────────────┘
|
|
526
368
|
```
|
|
527
369
|
|
|
528
370
|
## Configuration
|
|
529
371
|
|
|
530
|
-
### Global config
|
|
531
|
-
|
|
532
|
-
`~/.rubyn-code/config.yml`:
|
|
533
|
-
|
|
534
372
|
```yaml
|
|
373
|
+
# ~/.rubyn-code/config.yml (global)
|
|
535
374
|
model: claude-opus-4-6
|
|
536
375
|
permission_mode: allow_read
|
|
537
376
|
session_budget: 5.00
|
|
538
377
|
daily_budget: 10.00
|
|
539
|
-
max_iterations: 200
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### Project config
|
|
543
378
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
```yaml
|
|
379
|
+
# .rubyn-code/config.yml (project — overrides global)
|
|
547
380
|
model: claude-sonnet-4-6
|
|
548
381
|
permission_mode: autonomous
|
|
549
382
|
```
|
|
550
383
|
|
|
551
|
-
## Data Storage
|
|
552
|
-
|
|
553
|
-
All data stored locally in SQLite:
|
|
554
|
-
|
|
555
|
-
| Location | Purpose |
|
|
556
|
-
|----------|---------|
|
|
557
|
-
| `~/.rubyn-code/config.yml` | Global settings |
|
|
558
|
-
| `~/.rubyn-code/tokens.yml` | Auth tokens (0600 permissions) |
|
|
559
|
-
| `~/.rubyn-code/rubyn_code.db` | Sessions, tasks, memories, costs |
|
|
560
|
-
| `~/.rubyn-code/RUBYN.md` | Global project instructions |
|
|
561
|
-
| `~/.rubyn-code/skills/*.md` | Global custom skills |
|
|
562
|
-
| `.rubyn-code/config.yml` | Project settings |
|
|
563
|
-
| `.rubyn-code/skills/*.md` | Project custom skills |
|
|
564
|
-
| `RUBYN.md` | Project instructions |
|
|
565
|
-
|
|
566
384
|
## Development
|
|
567
385
|
|
|
386
|
+
Requires Ruby 4.0+.
|
|
387
|
+
|
|
568
388
|
```bash
|
|
569
|
-
|
|
389
|
+
git clone https://github.com/MatthewSuttles/rubyn-code.git
|
|
390
|
+
cd rubyn-code
|
|
391
|
+
bundle install
|
|
570
392
|
bundle exec rspec
|
|
393
|
+
```
|
|
571
394
|
|
|
572
|
-
|
|
573
|
-
bundle exec rspec spec/rubyn_code/agent/loop_spec.rb
|
|
395
|
+
## From Rubyn to Rubyn Code
|
|
574
396
|
|
|
575
|
-
|
|
576
|
-
ruby -Ilib bin/console
|
|
577
|
-
```
|
|
397
|
+
If you used the original [Rubyn gem](https://github.com/Rubyn-AI/rubyn), here's what changed:
|
|
578
398
|
|
|
579
|
-
|
|
399
|
+
| Rubyn (original) | Rubyn Code (open source) |
|
|
400
|
+
|-------------------|--------------------------|
|
|
401
|
+
| Rubyn API required | Runs locally, no external API |
|
|
402
|
+
| API key billing | Uses your Claude subscription |
|
|
403
|
+
| Refactor, spec, review commands | Full agentic assistant — reads, writes, thinks, learns |
|
|
404
|
+
| Static best practices | 112 on-demand skills + custom overrides |
|
|
405
|
+
| Single-turn commands | Multi-turn sessions with memory and context |
|
|
406
|
+
| Closed source | **MIT open source** |
|
|
580
407
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
│ ├── tasks/ # Layer 7: Task DAG
|
|
592
|
-
│ ├── background/ # Layer 8: Async execution
|
|
593
|
-
│ ├── teams/ # Layer 9: Agent teams
|
|
594
|
-
│ ├── protocols/ # Layer 10: Coordination
|
|
595
|
-
│ ├── autonomous/ # Layer 11: KAIROS daemon
|
|
596
|
-
│ ├── memory/ # Layer 12: Persistence
|
|
597
|
-
│ ├── observability/ # Layer 13: Cost tracking
|
|
598
|
-
│ ├── hooks/ # Layer 14: Event system
|
|
599
|
-
│ ├── mcp/ # Layer 15: MCP client
|
|
600
|
-
│ ├── learning/ # Layer 16: Continuous learning
|
|
601
|
-
│ ├── llm/ # Claude API client (OAuth + API key)
|
|
602
|
-
│ ├── auth/ # Token management (Keychain + file + env)
|
|
603
|
-
│ ├── db/ # SQLite connection & migrations
|
|
604
|
-
│ ├── cli/ # REPL, input handling, rendering
|
|
605
|
-
│ └── config/ # Settings management
|
|
606
|
-
├── skills/ # 112 Ruby/Rails best practice docs
|
|
607
|
-
│ ├── ruby/ # Ruby language patterns
|
|
608
|
-
│ ├── rails/ # Rails framework conventions
|
|
609
|
-
│ ├── rspec/ # RSpec testing patterns
|
|
610
|
-
│ ├── design_patterns/ # GoF and Ruby patterns
|
|
611
|
-
│ ├── solid/ # SOLID principles
|
|
612
|
-
│ ├── refactoring/ # Refactoring techniques
|
|
613
|
-
│ └── ... # + code_quality, gems, minitest, sinatra
|
|
614
|
-
├── db/migrations/ # 11 SQL migration files
|
|
615
|
-
└── spec/ # 48 RSpec test files (314 examples)
|
|
408
|
+
## Contributing
|
|
409
|
+
|
|
410
|
+
PRs welcome. If your team has conventions that should be a skill document, contribute it. If you need a tool we don't have, the tool system is a base class and a registry — add yours.
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
# Add a new tool
|
|
414
|
+
lib/rubyn_code/tools/your_tool.rb # extend Base, register with Registry
|
|
415
|
+
|
|
416
|
+
# Add a new skill
|
|
417
|
+
skills/your_category/your_skill.md # markdown with optional YAML frontmatter
|
|
616
418
|
```
|
|
617
419
|
|
|
618
420
|
## License
|
|
619
421
|
|
|
620
|
-
MIT
|
|
422
|
+
MIT License — see [LICENSE](LICENSE) for details.
|