noru 0.1.0__tar.gz

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.
Files changed (59) hide show
  1. noru-0.1.0/LICENSE +21 -0
  2. noru-0.1.0/PKG-INFO +501 -0
  3. noru-0.1.0/README.md +473 -0
  4. noru-0.1.0/pyproject.toml +49 -0
  5. noru-0.1.0/setup.cfg +4 -0
  6. noru-0.1.0/src/noru/__init__.py +3 -0
  7. noru-0.1.0/src/noru/__main__.py +5 -0
  8. noru-0.1.0/src/noru/core/__init__.py +19 -0
  9. noru-0.1.0/src/noru/core/config.py +108 -0
  10. noru-0.1.0/src/noru/core/constants.py +229 -0
  11. noru-0.1.0/src/noru/core/database.py +478 -0
  12. noru-0.1.0/src/noru/core/migrations/001_initial_schema.sql +108 -0
  13. noru-0.1.0/src/noru/core/migrations/002_add_jobs_table.sql +20 -0
  14. noru-0.1.0/src/noru/core/migrations/003_add_jobs_retry_count.sql +5 -0
  15. noru-0.1.0/src/noru/core/migrations/004_add_task_numbers.sql +5 -0
  16. noru-0.1.0/src/noru/core/migrations/005_backfill_task_numbers.sql +16 -0
  17. noru-0.1.0/src/noru/core/migrations/006_add_commit_hash.sql +3 -0
  18. noru-0.1.0/src/noru/core/migrations/007_usage_history.sql +6 -0
  19. noru-0.1.0/src/noru/core/migrations/008_activity_log.sql +13 -0
  20. noru-0.1.0/src/noru/core/migrations/__init__.py +0 -0
  21. noru-0.1.0/src/noru/core/models.py +284 -0
  22. noru-0.1.0/src/noru/engine/__init__.py +13 -0
  23. noru-0.1.0/src/noru/engine/activity_logger.py +57 -0
  24. noru-0.1.0/src/noru/engine/events.py +40 -0
  25. noru-0.1.0/src/noru/engine/hook_registry.py +98 -0
  26. noru-0.1.0/src/noru/engine/queue_manager.py +40 -0
  27. noru-0.1.0/src/noru/engine/scheduler.py +63 -0
  28. noru-0.1.0/src/noru/engine/token_monitor.py +136 -0
  29. noru-0.1.0/src/noru/engine/tunnel.py +116 -0
  30. noru-0.1.0/src/noru/engine/usage_api.py +348 -0
  31. noru-0.1.0/src/noru/engine/webhook.py +46 -0
  32. noru-0.1.0/src/noru/engine/weekly_tracker.py +87 -0
  33. noru-0.1.0/src/noru/executor/__init__.py +1 -0
  34. noru-0.1.0/src/noru/executor/action_service.py +202 -0
  35. noru-0.1.0/src/noru/executor/idle_reviewer.py +355 -0
  36. noru-0.1.0/src/noru/executor/job_scanner.py +304 -0
  37. noru-0.1.0/src/noru/executor/session_manager.py +154 -0
  38. noru-0.1.0/src/noru/executor/tmux_controller.py +100 -0
  39. noru-0.1.0/src/noru/executor/tmux_worker.py +236 -0
  40. noru-0.1.0/src/noru/executor/watermark.py +18 -0
  41. noru-0.1.0/src/noru/executor/worker_pool.py +95 -0
  42. noru-0.1.0/src/noru/integrations/__init__.py +30 -0
  43. noru-0.1.0/src/noru/integrations/agency_agent.py +14 -0
  44. noru-0.1.0/src/noru/integrations/hooks/__init__.py +1 -0
  45. noru-0.1.0/src/noru/integrations/hooks/discord.py +39 -0
  46. noru-0.1.0/src/noru/integrations/hooks/slack.py +44 -0
  47. noru-0.1.0/src/noru/integrations/hooks/telegram.py +43 -0
  48. noru-0.1.0/src/noru/integrations/superpowers.py +8 -0
  49. noru-0.1.0/src/noru/interface/__init__.py +6 -0
  50. noru-0.1.0/src/noru/interface/cli.py +817 -0
  51. noru-0.1.0/src/noru/interface/orchestrator.py +434 -0
  52. noru-0.1.0/src/noru/interface/server.py +905 -0
  53. noru-0.1.0/src/noru/interface/ui/index.html +3160 -0
  54. noru-0.1.0/src/noru.egg-info/PKG-INFO +501 -0
  55. noru-0.1.0/src/noru.egg-info/SOURCES.txt +57 -0
  56. noru-0.1.0/src/noru.egg-info/dependency_links.txt +1 -0
  57. noru-0.1.0/src/noru.egg-info/entry_points.txt +2 -0
  58. noru-0.1.0/src/noru.egg-info/requires.txt +12 -0
  59. noru-0.1.0/src/noru.egg-info/top_level.txt +1 -0
noru-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Louis Pham
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
noru-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,501 @@
1
+ Metadata-Version: 2.4
2
+ Name: noru
3
+ Version: 0.1.0
4
+ Summary: Autonomous orchestrator for Claude Code — runs your task queue 24/7
5
+ Author: Louis
6
+ Keywords: claude,orchestrator,automation,ai
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Topic :: Software Development :: Build Tools
13
+ Requires-Python: >=3.11
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: click>=8.0
17
+ Requires-Dist: fastapi>=0.100
18
+ Requires-Dist: uvicorn[standard]
19
+ Requires-Dist: pyyaml>=6.0
20
+ Requires-Dist: pydantic>=2.0
21
+ Requires-Dist: httpx>=0.27
22
+ Requires-Dist: qrcode>=7.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8.0; extra == "dev"
25
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
26
+ Requires-Dist: httpx>=0.27; extra == "dev"
27
+ Dynamic: license-file
28
+
29
+ <p align="center">
30
+ <h1 align="center">🤖 Noru</h1>
31
+ <p align="center">
32
+ <strong>Ship while you sleep — autonomous Claude Code orchestration</strong>
33
+ </p>
34
+ <p align="center">
35
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11+-blue.svg" alt="Python 3.11+"></a>
36
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT"></a>
37
+ <a href="https://github.com/anthropics/claude-code"><img src="https://img.shields.io/badge/Claude-Code-blueviolet.svg" alt="Claude Code"></a>
38
+ <a href="#-contributing"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"></a>
39
+ </p>
40
+ </p>
41
+
42
+ > **Your AI developer that never sleeps.** Noru is a Python CLI + web dashboard that runs Claude Code tasks autonomously 24/7 — managing priorities, token budgets, and idle code reviews so your codebase improves around the clock.
43
+
44
+ <p align="center">
45
+ <a href="https://youtu.be/JR6D9MSrjLs">
46
+ <img src="https://img.youtube.com/vi/JR6D9MSrjLs/maxresdefault.jpg" alt="Noru Demo" width="720">
47
+ </a>
48
+ <br>
49
+ <em>▶️ Watch the demo (2 min)</em>
50
+ </p>
51
+
52
+ ---
53
+
54
+ ## 📑 Table of Contents
55
+
56
+ - [📑 Table of Contents](#-table-of-contents)
57
+ - [✨ Features](#-features)
58
+ - [🚀 Quick Start](#-quick-start)
59
+ - [1. Install](#1-install)
60
+ - [2. Initialize a project](#2-initialize-a-project)
61
+ - [3. Start the orchestrator](#3-start-the-orchestrator)
62
+ - [Adding tasks manually](#adding-tasks-manually)
63
+ - [📊 Dashboard](#-dashboard)
64
+ - [Tabs](#tabs)
65
+ - [⚙️ Configuration](#️-configuration)
66
+ - [🛡️ Guardrails](#️-guardrails)
67
+ - [🔍 Idle Review Jobs (16 built-in)](#-idle-review-jobs-16-built-in)
68
+ - [🔧 CLI Reference](#-cli-reference)
69
+ - [Lifecycle](#lifecycle)
70
+ - [Task Management](#task-management)
71
+ - [Project Management](#project-management)
72
+ - [Configuration](#configuration)
73
+ - [Idle Reviews](#idle-reviews)
74
+ - [Direct Execution](#direct-execution)
75
+ - [🔔 Integrations](#-integrations)
76
+ - [Telegram](#telegram)
77
+ - [Slack](#slack)
78
+ - [Discord](#discord)
79
+ - [🌐 Tunnel (Remote Access)](#-tunnel-remote-access)
80
+ - [📡 API Reference](#-api-reference)
81
+ - [🏗️ Architecture](#️-architecture)
82
+ - [Project Structure](#project-structure)
83
+ - [Tech Stack](#tech-stack)
84
+ - [🤝 Contributing](#-contributing)
85
+ - [📄 License](#-license)
86
+
87
+ ---
88
+
89
+ ## ✨ Features
90
+
91
+ | Feature | Description |
92
+ |---------|-------------|
93
+ | 🎯 **Autonomous Task Queue** | Priority-based scheduling with weight classes (light/medium/heavy) |
94
+ | 📊 **Real-Time Dashboard** | Kanban board, stats, charts — desktop + mobile responsive |
95
+ | 📊 **Token Budget Management** | 5-hour session windows + weekly limits with auto-pause |
96
+ | 🔍 **Idle Code Reviews** | 16 built-in review types run via watermark refill when ready tasks drop below threshold |
97
+ | ⏸️ **Pause / Resume** | Pause the agent from the CLI or API — server stays up, dispatch stops |
98
+ | 🌍 **Language Config** | Claude responds in your language — 13 supported languages |
99
+ | 📜 **Activity Log** | Persistent event timeline for every dispatch, pause, and state change |
100
+ | 🛡️ **Guardrails** | User-defined rules injected into all prompts to prevent noru from overstepping |
101
+ | 🔌 **Plugin Notifications** | Telegram, Slack, Discord — know when tasks complete |
102
+ | 🌐 **Remote Access** | Built-in tunnel support (cloudflared/ngrok) with QR code |
103
+ | 🔧 **Full REST API** | Everything the dashboard can do, your scripts can too |
104
+ | 📋 **Event Hooks** | Custom notifications on task start, complete, fail |
105
+ | ⚡ **Zero Build Step** | No npm, no webpack, no framework overhead — just Python |
106
+ | 🛡️ **SQLite + WAL** | Fast, reliable, zero-config database |
107
+
108
+ ---
109
+
110
+ ## 🚀 Quick Start
111
+
112
+ Get Noru running in under 2 minutes:
113
+
114
+ ### 1. Install
115
+
116
+ ```bash
117
+ pip install noru
118
+ ```
119
+
120
+ ### 2. Initialize a project
121
+
122
+ ```bash
123
+ cd ~/your-project
124
+ noru init
125
+ ```
126
+
127
+ > 💡 **Tip:** `noru init` scans your project and suggests initial tasks based on TODOs, open issues, and code quality signals.
128
+
129
+ ### 3. Start the orchestrator
130
+
131
+ ```bash
132
+ noru start
133
+ ```
134
+
135
+ That's it. Noru is now running tasks and serving the dashboard at **http://localhost:7777**.
136
+
137
+ ```bash
138
+ # Open the dashboard in your browser
139
+ noru dashboard
140
+
141
+ # Check what's happening
142
+ noru status
143
+ ```
144
+
145
+ ### Adding tasks manually
146
+
147
+ ```bash
148
+ # Add a task
149
+ noru task add --project my-app --title "Fix authentication bug" --priority 1
150
+
151
+ # Promote it to the queue
152
+ noru task ready 1
153
+
154
+ # Watch it get picked up automatically
155
+ noru status
156
+ ```
157
+
158
+ ---
159
+
160
+ ## 📊 Dashboard
161
+
162
+ Noru ships with a single-file HTML dashboard — no build step, no node_modules. Just open **http://localhost:7777**.
163
+
164
+ ### Tabs
165
+
166
+ | Tab | What it shows |
167
+ |-----|---------------|
168
+ | 📈 **Overview** | Metric cards, token window bar, weekly budget bar, agent controls, recent activity |
169
+ | 📋 **Kanban** | 4-column board (Todo → Doing → Review → Done) with project filters |
170
+ | 📁 **Projects** | Project cards with status and task counts |
171
+ | 📝 **Tasks** | Searchable, filterable table with all tasks |
172
+ | 📊 **Stats** | Token usage charts, completion rates, cost tracking |
173
+
174
+ > 📱 **Mobile friendly.** The dashboard is fully responsive — check on your tasks from your phone while you're out.
175
+
176
+ ---
177
+
178
+ ## ⚙️ Configuration
179
+
180
+ > **Full reference:** [docs/configuration.md](docs/configuration.md)
181
+
182
+ Config lives at `~/.noru/config.yaml`. Created automatically on first run, or customize it:
183
+
184
+ ```yaml
185
+ # Core settings
186
+ loop_interval_seconds: 60
187
+ port: 7777
188
+ claude_cli: claude
189
+
190
+ # Token budget — 5-hour rolling window
191
+ max20_window_tokens: 220000
192
+ window_duration_hours: 5
193
+
194
+ # Weekly budget
195
+ weekly:
196
+ seed_limit: 1500000
197
+ developer_reserve_pct: 0.35 # 35% reserved for your interactive sessions
198
+ reset_day: monday
199
+
200
+ # Guardrails — injected into all prompts
201
+ guardrails:
202
+ - "NEVER change database schema or migrations"
203
+ - "NEVER re-architect the project layout"
204
+
205
+ # Watermark refill — trigger idle scans when ready tasks drop below threshold
206
+ watermark:
207
+ low_watermark: 2
208
+ scan_cooldown_seconds: 60
209
+
210
+ # Idle review jobs (run when ready tasks < watermark)
211
+ idle_jobs:
212
+ max_tasks_per_run: 3
213
+ jobs:
214
+ - id: security-scan
215
+ enabled: true
216
+ - id: bug-detection
217
+ enabled: true
218
+ - id: test-coverage
219
+ enabled: true
220
+ # ... see full list below
221
+ ```
222
+
223
+ > 💡 **Tip:** You can also edit configuration from the dashboard's admin panel.
224
+
225
+ ### 🛡️ Guardrails
226
+
227
+ User-defined rules injected into every prompt noru sends to Claude Code. Use them to set hard boundaries on what noru is allowed to do:
228
+
229
+ ```yaml
230
+ guardrails:
231
+ - "NEVER change database schema or migrations"
232
+ - "NEVER re-architect the project layout"
233
+ - "NEVER modify CI/CD pipelines"
234
+ ```
235
+
236
+ ### 🔍 Idle Review Jobs (16 built-in)
237
+
238
+ When ready tasks drop below the watermark threshold, noru triggers a scan that creates review tasks automatically. This is stateless — no phases, no state machine. Just: `ready_tasks < low_watermark` triggers a scan, then cooldown.
239
+
240
+ | Job | Default | Focus |
241
+ |-----|---------|-------|
242
+ | `security-scan` | ✅ ON | XSS, injection, secrets, OWASP Top 10 |
243
+ | `bug-detection` | ✅ ON | Test failures, type errors, edge cases |
244
+ | `logic-review` | ✅ ON | Business logic, missing validations |
245
+ | `test-coverage` | ✅ ON | Untested functions, generate tests |
246
+ | `code-quality` | ✅ ON | Dead code, unused imports, TODOs |
247
+ | `refactor` | ⬜ OFF | Extract functions, reduce duplication |
248
+ | `ui-bug-scan` | ⬜ OFF | Visual regressions, broken layouts |
249
+ | `ux-review` | ⬜ OFF | Accessibility, navigation, UX patterns |
250
+ | `ui-polish` | ⬜ OFF | Spacing, alignment, consistency |
251
+ | `perf-audit` | ⬜ OFF | N+1 queries, memory leaks |
252
+ | `docs-update` | ⬜ OFF | Missing docstrings, README gaps |
253
+ | `dependency-check` | ⬜ OFF | Outdated packages, CVEs |
254
+ | `api-review` | ⬜ OFF | Endpoint consistency, validation |
255
+ | `type-safety` | ⬜ OFF | Missing type hints |
256
+ | `error-handling` | ⬜ OFF | Missing try/catch, error propagation |
257
+ | `pr-review` | ⬜ OFF | Review open PRs on GitHub |
258
+
259
+ ```bash
260
+ # Enable/disable review jobs
261
+ noru idle enable perf-audit
262
+ noru idle disable docs-update
263
+ noru idle list
264
+ ```
265
+
266
+ ---
267
+
268
+ ## 🔧 CLI Reference
269
+
270
+ ### Lifecycle
271
+
272
+ | Command | Description |
273
+ |---------|-------------|
274
+ | `noru start` | Start orchestrator + dashboard server |
275
+ | `noru stop` | Graceful stop (finishes current task) |
276
+ | `noru stop --force` | Immediate stop |
277
+ | `noru restart` | Stop then start |
278
+ | `noru pause` | Pause dispatch — server stays up, no tasks run |
279
+ | `noru status` | Current state, queue depth, active task |
280
+ | `noru status --json` | Machine-readable status output |
281
+ | `noru dashboard` | Open dashboard in browser |
282
+ | `noru logs` | Tail orchestrator logs |
283
+
284
+ ### Task Management
285
+
286
+ | Command | Description |
287
+ |---------|-------------|
288
+ | `noru task add --project ID --title "..." --priority N` | Add a task |
289
+ | `noru task ready ID` | Promote task to the active queue |
290
+ | `noru task list` | List all tasks |
291
+ | `noru task list --status todo --project my-app` | Filter tasks |
292
+ | `noru task done ID` | Mark task done manually |
293
+ | `noru task skip ID` | Skip task (lower priority) |
294
+
295
+ ### Project Management
296
+
297
+ | Command | Description |
298
+ |---------|-------------|
299
+ | `noru project add --id my-app --name "My App" --repo-path ~/dev/my-app` | Register a project |
300
+ | `noru project list` | List all projects |
301
+ | `noru project pause ID` | Pause a project (skip its tasks) |
302
+ | `noru project resume ID` | Resume a paused project |
303
+ | `noru init` | Scan current directory and propose tasks |
304
+
305
+ ### Configuration
306
+
307
+ | Command | Description |
308
+ |---------|-------------|
309
+ | `noru config show` | View current configuration |
310
+ | `noru config set KEY VALUE` | Set a config value (dot notation) |
311
+ | `noru config reset` | Reset config to defaults |
312
+
313
+ ### Idle Reviews
314
+
315
+ | Command | Description |
316
+ |---------|-------------|
317
+ | `noru idle list` | Show all review jobs with on/off status |
318
+ | `noru idle enable JOB` | Enable a review job |
319
+ | `noru idle disable JOB` | Disable a review job |
320
+
321
+ ### Direct Execution
322
+
323
+ | Command | Description |
324
+ |---------|-------------|
325
+ | `noru run` | Run one task now (bypasses scheduler) |
326
+ | `noru run --task ID` | Run a specific task |
327
+ | `noru run --dry-run` | Show the prompt without executing |
328
+
329
+ ---
330
+
331
+ ## 🔔 Integrations
332
+
333
+ > **Full reference:** [docs/integrations.md](docs/integrations.md)
334
+
335
+ Noru supports event hooks for notifications when tasks complete, fail, or when the queue empties.
336
+
337
+ ### Telegram
338
+
339
+ ```yaml
340
+ # ~/.noru/config.yaml
341
+ hooks:
342
+ telegram:
343
+ enabled: true
344
+ bot_token: "your-bot-token"
345
+ chat_id: "your-chat-id"
346
+ events: [task_completed, task_failed, queue_empty]
347
+ ```
348
+
349
+ ### Slack
350
+
351
+ ```yaml
352
+ hooks:
353
+ slack:
354
+ enabled: true
355
+ webhook_url: "https://hooks.slack.com/services/..."
356
+ events: [task_completed, task_failed]
357
+ ```
358
+
359
+ ### Discord
360
+
361
+ ```yaml
362
+ hooks:
363
+ discord:
364
+ enabled: true
365
+ webhook_url: "https://discord.com/api/webhooks/..."
366
+ events: [task_completed, task_failed]
367
+ ```
368
+
369
+ > 💡 **Tip:** You can combine multiple integrations. All hooks fire independently.
370
+
371
+ ---
372
+
373
+ ## 🌐 Tunnel (Remote Access)
374
+
375
+ > **Full reference:** [docs/tunnel.md](docs/tunnel.md)
376
+
377
+ Access your dashboard from anywhere — no port forwarding required.
378
+
379
+ ```bash
380
+ # Start a tunnel (auto-detects cloudflared or ngrok)
381
+ noru tunnel start
382
+
383
+ # Displays a public URL + QR code for mobile access
384
+ # Example: https://abc123.trycloudflare.com
385
+ ```
386
+
387
+ | Provider | Setup |
388
+ |----------|-------|
389
+ | **cloudflared** (recommended) | `brew install cloudflared` — no account needed |
390
+ | **ngrok** | `brew install ngrok` — free account required |
391
+
392
+ > ⚠️ **Warning:** The tunnel exposes your dashboard to the internet. Use it on trusted networks or add authentication.
393
+
394
+ ---
395
+
396
+ ## 📡 API Reference
397
+
398
+ > **Full reference:** [docs/api.md](docs/api.md)
399
+
400
+ Noru exposes a full REST API at `http://localhost:7777/api`. Everything the dashboard does, your scripts can do too.
401
+
402
+ **Key endpoints:**
403
+
404
+ | Method | Endpoint | Description |
405
+ |--------|----------|-------------|
406
+ | `GET` | `/api/status` | Orchestrator state and queue info |
407
+ | `GET` | `/api/tasks` | List all tasks (supports filters) |
408
+ | `POST` | `/api/tasks` | Create a new task |
409
+ | `PATCH` | `/api/tasks/:id` | Update task status or priority |
410
+ | `GET` | `/api/projects` | List all projects |
411
+ | `GET` | `/api/budget` | Token budget status |
412
+ | `GET` | `/api/stats` | Usage statistics and charts data |
413
+ | `POST` | `/api/agent/start` | Start the orchestrator |
414
+ | `POST` | `/api/agent/stop` | Stop the orchestrator |
415
+
416
+ ```bash
417
+ # Example: list tasks via curl
418
+ curl http://localhost:7777/api/tasks | python3 -m json.tool
419
+
420
+ # Example: add a task via API
421
+ curl -X POST http://localhost:7777/api/tasks \
422
+ -H "Content-Type: application/json" \
423
+ -d '{"project_id": "my-app", "title": "Fix login bug", "priority": 1}'
424
+ ```
425
+
426
+ ---
427
+
428
+ ## 🏗️ Architecture
429
+
430
+ ```
431
+ noru start
432
+ └── Python process (single PID)
433
+ ├── Main thread: uvicorn (FastAPI on :7777)
434
+ └── Daemon thread: OrchestratorLoop
435
+ ├── Fetches usage via tmux /usage command (HTTP API fallback)
436
+ ├── Picks highest-priority eligible task
437
+ ├── Dispatches to Claude Code via tmux sessions (session-id continuity)
438
+ ├── Detects 429 rate-limit errors and backs off reactively
439
+ └── Records results to SQLite (WAL mode)
440
+ ```
441
+
442
+ **Every loop cycle** (default 60s) — scheduler picks one of 4 actions:
443
+
444
+ 1. **dispatch** — evaluate token budgets, pick highest-priority task, send to Claude Code
445
+ 2. **sleep** — budget exhausted, wait for token window to refill
446
+ 3. **idle** — queue empty + ready tasks below watermark, trigger scan to create review tasks
447
+ 4. **create_only** — budget too low for execution, only create/plan tasks
448
+
449
+ ### Project Structure
450
+
451
+ ```
452
+ src/noru/
453
+ ├── core/ # Models, database, config, constants (zero external deps)
454
+ ├── engine/ # Token monitor, weekly tracker, queue, scheduler
455
+ ├── executor/ # WorkerBackend protocol, Claude CLI, dispatcher, idle reviewer
456
+ ├── interface/ # Orchestrator loop, Click CLI, FastAPI server, dashboard
457
+ └── integrations/ # Hooks (Telegram, Slack, Discord), superpowers, agency-agent
458
+ ```
459
+
460
+ ### Tech Stack
461
+
462
+ - **Python 3.11+** — threaded orchestrator, zero JS build step
463
+ - **SQLite (WAL mode)** — fast concurrent reads, zero config
464
+ - **FastAPI** — REST API + dashboard serving
465
+ - **Click** — CLI framework
466
+ - **Alpine.js + Chart.js** — dashboard UI (single HTML file)
467
+
468
+ The `WorkerBackend` protocol abstracts CLI execution. The default `TmuxWorker` manages persistent Claude Code tmux sessions with session-id continuity per project. You can implement your own backend for other LLM CLIs.
469
+
470
+ ---
471
+
472
+ ## 🤝 Contributing
473
+
474
+ Contributions are welcome! Noru is built with a test-first approach.
475
+
476
+ ```bash
477
+ # Clone and install
478
+ git clone https://github.com/pxson2903/noru.git
479
+ cd noru
480
+ pip install -e ".[dev]"
481
+
482
+ # Run tests
483
+ pytest
484
+
485
+ # Run a specific test file
486
+ pytest tests/core/test_database.py -v
487
+ ```
488
+
489
+ **Guidelines:**
490
+
491
+ - Write tests first, then implement (TDD)
492
+ - Use frozen dataclasses for models
493
+ - All DB queries go in `core/database.py` as named methods
494
+ - Follow the `WorkerBackend` protocol for execution backends
495
+ - Keep `core/` free of external dependencies
496
+
497
+ ---
498
+
499
+ ## 📄 License
500
+
501
+ MIT — use it, fork it, ship with it.