@lovenyberg/ove 0.2.1 → 0.3.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/README.md +10 -5
- package/bun.lock +63 -263
- package/config.example.json +13 -2
- package/docs/examples.md +28 -0
- package/docs/index.html +14 -9
- package/docs/plans/2026-02-22-repo-autodiscovery-design.md +98 -0
- package/docs/plans/2026-02-22-repo-autodiscovery-plan.md +826 -0
- package/package.json +2 -2
- package/src/adapters/debounce.ts +10 -0
- package/src/adapters/discord.ts +1 -11
- package/src/adapters/github.ts +12 -0
- package/src/adapters/http.ts +11 -3
- package/src/adapters/slack.ts +1 -11
- package/src/adapters/telegram.ts +37 -15
- package/src/adapters/whatsapp.ts +49 -11
- package/src/config.test.ts +70 -0
- package/src/config.ts +16 -4
- package/src/handlers.ts +512 -0
- package/src/index.ts +96 -491
- package/src/queue.ts +46 -10
- package/src/repo-registry.test.ts +130 -0
- package/src/repo-registry.ts +201 -0
- package/src/repos.ts +19 -5
- package/src/router.test.ts +125 -1
- package/src/router.ts +46 -3
- package/src/runner.ts +1 -0
- package/src/runners/claude.ts +7 -1
- package/src/runners/codex.ts +7 -1
- package/src/schedules.ts +13 -3
- package/src/sessions.ts +8 -2
- package/src/worker.ts +173 -0
package/config.example.json
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
"my-app": {
|
|
4
4
|
"url": "git@github.com:user/my-app.git",
|
|
5
5
|
"defaultBranch": "main"
|
|
6
|
+
},
|
|
7
|
+
"infra": {
|
|
8
|
+
"runner": { "name": "codex" },
|
|
9
|
+
"defaultBranch": "develop"
|
|
10
|
+
},
|
|
11
|
+
"old-legacy": {
|
|
12
|
+
"excluded": true
|
|
6
13
|
}
|
|
7
14
|
},
|
|
8
15
|
"users": {
|
|
@@ -10,9 +17,9 @@
|
|
|
10
17
|
"name": "love",
|
|
11
18
|
"repos": ["my-app"]
|
|
12
19
|
},
|
|
13
|
-
"
|
|
20
|
+
"telegram:123456789": {
|
|
14
21
|
"name": "love",
|
|
15
|
-
"repos": ["
|
|
22
|
+
"repos": ["*"]
|
|
16
23
|
}
|
|
17
24
|
},
|
|
18
25
|
"claude": {
|
|
@@ -21,6 +28,10 @@
|
|
|
21
28
|
"runner": {
|
|
22
29
|
"name": "claude"
|
|
23
30
|
},
|
|
31
|
+
"github": {
|
|
32
|
+
"syncInterval": 1800000,
|
|
33
|
+
"orgs": ["my-org"]
|
|
34
|
+
},
|
|
24
35
|
"mcpServers": {
|
|
25
36
|
"filesystem": {
|
|
26
37
|
"command": "npx",
|
package/docs/examples.md
CHANGED
|
@@ -227,6 +227,32 @@ data: {"type":"done","result":"Validation complete. No issues."}
|
|
|
227
227
|
|
|
228
228
|
**Web UI:** Open `http://localhost:3000` in a browser for a chat-style interface.
|
|
229
229
|
|
|
230
|
+
## Task Management
|
|
231
|
+
|
|
232
|
+
Tasks on different repos run in parallel (up to 5 concurrent). Same-repo tasks stay serial.
|
|
233
|
+
|
|
234
|
+
**List running and pending tasks:**
|
|
235
|
+
```
|
|
236
|
+
alice: tasks
|
|
237
|
+
ove: Running:
|
|
238
|
+
abc1234 — "fix the login bug" on auth-service (2m 30s)
|
|
239
|
+
def4567 — "review PR #42" on infra (45s)
|
|
240
|
+
Pending:
|
|
241
|
+
ghi7890 — "add tests" on auth-service (waiting — auth-service busy)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Cancel a task by short ID:**
|
|
245
|
+
```
|
|
246
|
+
alice: cancel abc1234
|
|
247
|
+
ove: Killed task abc1234 on auth-service. Gone.
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Cancel a pending task:**
|
|
251
|
+
```
|
|
252
|
+
alice: cancel ghi7890
|
|
253
|
+
ove: Cancelled pending task ghi7890 on auth-service.
|
|
254
|
+
```
|
|
255
|
+
|
|
230
256
|
## Meta Commands
|
|
231
257
|
|
|
232
258
|
```
|
|
@@ -247,6 +273,8 @@ ove: Commands:
|
|
|
247
273
|
• validate <repo>
|
|
248
274
|
• discuss <topic> — brainstorm ideas (no code changes)
|
|
249
275
|
• create project <name> [with template <type>]
|
|
276
|
+
• tasks — see running and pending tasks
|
|
277
|
+
• cancel <id> — kill a running or pending task
|
|
250
278
|
• <task> every day at <time> — schedule a recurring task
|
|
251
279
|
• list schedules — see your scheduled tasks
|
|
252
280
|
• remove schedule #N — remove a scheduled task
|
package/docs/index.html
CHANGED
|
@@ -663,9 +663,9 @@
|
|
|
663
663
|
</div>
|
|
664
664
|
<div class="feature">
|
|
665
665
|
<div class="feature-label">06 — Manage</div>
|
|
666
|
-
<h3>
|
|
667
|
-
<p>
|
|
668
|
-
<code>
|
|
666
|
+
<h3>Task Management</h3>
|
|
667
|
+
<p>See what's running, what's queued, and kill anything that's gone sideways. Different repos run in parallel, same repo stays serial.</p>
|
|
668
|
+
<code>tasks</code> <code>cancel <id></code>
|
|
669
669
|
</div>
|
|
670
670
|
</div>
|
|
671
671
|
|
|
@@ -776,6 +776,10 @@ sudo systemctl enable --now ove</pre>
|
|
|
776
776
|
<dd>See your scheduled tasks</dd>
|
|
777
777
|
<dt>remove schedule #N</dt>
|
|
778
778
|
<dd>Remove a scheduled task</dd>
|
|
779
|
+
<dt>tasks</dt>
|
|
780
|
+
<dd>List running and pending tasks</dd>
|
|
781
|
+
<dt>cancel <id></dt>
|
|
782
|
+
<dd>Kill a running or pending task</dd>
|
|
779
783
|
<dt>status</dt>
|
|
780
784
|
<dd>Queue stats</dd>
|
|
781
785
|
<dt>history</dt>
|
|
@@ -789,16 +793,17 @@ sudo systemctl enable --now ove</pre>
|
|
|
789
793
|
|
|
790
794
|
<section class="section">
|
|
791
795
|
<h2>How It Works</h2>
|
|
792
|
-
<p class="section-note">
|
|
796
|
+
<p class="section-note">Parallel where it matters. Serial where it must be. Proper.</p>
|
|
793
797
|
|
|
794
798
|
<ol class="pipeline">
|
|
795
799
|
<li><span class="step-n">1</span><span class="step-arrow">›</span> Message arrives via Slack, WhatsApp, Telegram, Discord, CLI, HTTP API, or GitHub comment</li>
|
|
796
800
|
<li><span class="step-n">2</span><span class="step-arrow">›</span> Router parses intent and extracts repo/args</li>
|
|
797
|
-
<li><span class="step-n">3</span><span class="step-arrow">›</span> Task gets queued in SQLite — one per repo at a time</li>
|
|
798
|
-
<li><span class="step-n">4</span><span class="step-arrow">›</span> Worker
|
|
799
|
-
<li><span class="step-n">5</span><span class="step-arrow">›</span>
|
|
800
|
-
<li><span class="step-n">6</span><span class="step-arrow">›</span>
|
|
801
|
-
<li><span class="step-n">7</span><span class="step-arrow">›</span>
|
|
801
|
+
<li><span class="step-n">3</span><span class="step-arrow">›</span> Task gets queued in SQLite — one per repo at a time, different repos run in parallel</li>
|
|
802
|
+
<li><span class="step-n">4</span><span class="step-arrow">›</span> Worker loop picks up tasks concurrently (up to 5 parallel)</li>
|
|
803
|
+
<li><span class="step-n">5</span><span class="step-arrow">›</span> Each task gets an isolated git worktree</li>
|
|
804
|
+
<li><span class="step-n">6</span><span class="step-arrow">›</span> Runs the configured runner (<code>claude -p</code> or <code>codex exec</code>) with streaming JSON output</li>
|
|
805
|
+
<li><span class="step-n">7</span><span class="step-arrow">›</span> Status updates stream back — chat edits, SSE, or GitHub comment</li>
|
|
806
|
+
<li><span class="step-n">8</span><span class="step-arrow">›</span> Result sent back, worktree cleaned up — use <code>tasks</code> to monitor, <code>cancel <id></code> to stop</li>
|
|
802
807
|
</ol>
|
|
803
808
|
</section>
|
|
804
809
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Auto-Discovery Repo Management Design
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Scale Ove from manually configured repos to auto-discovering 50-100+ repos via GitHub, with on-demand cloning and Claude-powered repo resolution.
|
|
6
|
+
|
|
7
|
+
## Repo Storage
|
|
8
|
+
|
|
9
|
+
Move repo registry from config.json to SQLite. New `repos` table:
|
|
10
|
+
|
|
11
|
+
```sql
|
|
12
|
+
CREATE TABLE repos (
|
|
13
|
+
name TEXT PRIMARY KEY,
|
|
14
|
+
url TEXT NOT NULL,
|
|
15
|
+
owner TEXT,
|
|
16
|
+
default_branch TEXT DEFAULT 'main',
|
|
17
|
+
source TEXT NOT NULL, -- "github-sync" | "manual" | "config"
|
|
18
|
+
excluded INTEGER DEFAULT 0,
|
|
19
|
+
last_synced_at TEXT
|
|
20
|
+
);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## GitHub Sync
|
|
24
|
+
|
|
25
|
+
On startup and every 30 min (configurable), run `gh repo list` to discover repos. New repos inserted, existing ones updated. Non-blocking — Ove starts immediately, sync runs in background.
|
|
26
|
+
|
|
27
|
+
Config adds optional `github` section:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"github": {
|
|
32
|
+
"syncInterval": 1800000,
|
|
33
|
+
"orgs": ["seenthis-ab", "jacksoncage"]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If `orgs` omitted, syncs all repos the `gh` user has access to.
|
|
39
|
+
|
|
40
|
+
## User Access
|
|
41
|
+
|
|
42
|
+
Wildcard support: `"repos": ["*"]` means access to all discovered repos. Existing per-repo lists still work.
|
|
43
|
+
|
|
44
|
+
## Repo Resolution
|
|
45
|
+
|
|
46
|
+
When user doesn't specify a repo explicitly:
|
|
47
|
+
|
|
48
|
+
1. Router regex — explicit `on <repo>` works as fast path
|
|
49
|
+
2. Claude resolves — inject user's repo list into the prompt, Claude picks the right repo or asks
|
|
50
|
+
|
|
51
|
+
Repo list injected as: `Available repos: repo-a, repo-b, ...`
|
|
52
|
+
|
|
53
|
+
## Config Changes
|
|
54
|
+
|
|
55
|
+
`config.json` repos become overrides only:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"repos": {
|
|
60
|
+
"infra-salming-ai": {
|
|
61
|
+
"runner": { "name": "codex" },
|
|
62
|
+
"defaultBranch": "develop"
|
|
63
|
+
},
|
|
64
|
+
"old-legacy-thing": {
|
|
65
|
+
"excluded": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"users": {
|
|
69
|
+
"telegram:8518556027": { "name": "love", "repos": ["*"] }
|
|
70
|
+
},
|
|
71
|
+
"claude": { "maxTurns": 10 },
|
|
72
|
+
"github": {
|
|
73
|
+
"syncInterval": 1800000,
|
|
74
|
+
"orgs": ["seenthis-ab", "jacksoncage"]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Repos no longer need `url` — auto-discovered repos have it in SQLite. Only specify overrides (custom branch, runner, exclusion). `url` still works for non-GitHub repos.
|
|
80
|
+
|
|
81
|
+
## Clone Strategy
|
|
82
|
+
|
|
83
|
+
On-demand — clone only when a task first targets a repo. Existing `cloneIfNeeded` handles this. No change needed.
|
|
84
|
+
|
|
85
|
+
## Migration
|
|
86
|
+
|
|
87
|
+
On first run, existing config.json repos get inserted into SQLite with `source: "config"`. No breaking change.
|
|
88
|
+
|
|
89
|
+
## Components
|
|
90
|
+
|
|
91
|
+
- `src/repo-registry.ts` — new SQLite-backed repo store (sync, getAll, getByName, isExcluded)
|
|
92
|
+
- `src/config.ts` — add github config, update types, wildcard auth
|
|
93
|
+
- `src/router.ts` — remove single-repo fallback
|
|
94
|
+
- `src/index.ts` — wire up registry, inject repo list into prompts, start background sync
|
|
95
|
+
|
|
96
|
+
## Unchanged
|
|
97
|
+
|
|
98
|
+
Queue, runners, adapters, worktrees, task processing — all untouched.
|