@bojackduy/opencode-loopd 1.0.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/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +138 -0
- package/commands/goal.md +20 -0
- package/dist/server.js +2402 -0
- package/dist/tui.js +1480 -0
- package/package.json +82 -0
- package/scripts/build-tui.ts +20 -0
- package/scripts/install-node.mjs +151 -0
- package/skills/loopd/SKILL.md +206 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0 (2026-08-21)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Goal lifecycle**: create, active, pause, resume, retry, clear, complete, blocked
|
|
8
|
+
- **Engine-driven loop**: idle detection → continuation steering → automatic re-prompt
|
|
9
|
+
- **Continuation steering**: accumulated context (progress history, transcript tail, inbox messages)
|
|
10
|
+
- **Worker tools**: get_goal, report_goal_progress, complete_goal, block_goal (clarification via OpenCode's native `question` tool)
|
|
11
|
+
- **Owner tools**: list_background_goals, inspect_background_goal, read_goal_transcript, send_goal_input, pause_goal, resume_goal, clear_goal
|
|
12
|
+
- **Inbox system**: bidirectional user↔child messaging
|
|
13
|
+
- **Dashboard**: goal list, detail view, question banner, mode switch (NORMAL/INSERT), keyboard shortcuts
|
|
14
|
+
- **Safety defaults**: maxTurns=50, maxFailures=3
|
|
15
|
+
- **Server/TUI debug logging**: /tmp/loopd-server.log, /tmp/loopd-tui.log
|
|
16
|
+
- **Skill file**: agent guidance for goal lifecycle at ~/.config/opencode/skills/loopd/SKILL.md
|
|
17
|
+
|
|
18
|
+
### Architecture
|
|
19
|
+
|
|
20
|
+
- Engine-driven loop (same as Codex): idle event → continuation steering → child continues
|
|
21
|
+
- Parent visibility layer: owner tools read child transcript, progress, and state
|
|
22
|
+
- Bidirectional messaging: inbox system for user→child instructions
|
|
23
|
+
- Awaiting_user status: child can pause and ask questions
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## 1.0.1 (2026-08-21)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Removed redundant `ask_user` tool and `awaiting_user` status. Workers now use OpenCode's native `question` tool for clarification — questions appear in the TUI footer as blocker tabs, no goal status change needed.
|
|
31
|
+
- Removed `:answer` dashboard command (native question answers flow through OpenCode).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 Duy Trinh
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Affero General Public License as published
|
|
8
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
This project also bundles installer and runtime dependencies with their
|
|
21
|
+
own licenses. See package.json for details.
|
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# opencode-loopd
|
|
2
|
+
|
|
3
|
+
**Background goal engine for OpenCode** — run long-running tasks as autonomous child sessions while the main chat stays interactive.
|
|
4
|
+
|
|
5
|
+
## What it is
|
|
6
|
+
|
|
7
|
+
opencode-loopd is an OpenCode plugin that creates background goals with dedicated worker sessions. The parent chat stays interactive while work happens behind the scenes. You can observe, steer, pause, or stop goals at any time.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
### Manual
|
|
12
|
+
|
|
13
|
+
Add to `~/.config/opencode/opencode.jsonc`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"plugin": [
|
|
18
|
+
"/Users/you/Code/opencode-loopd"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### npx (recommended)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx -y @bojackduy/opencode-loopd@latest
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Run the same command again to update. Then restart OpenCode.
|
|
30
|
+
|
|
31
|
+
### npm global
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g @bojackduy/opencode-loopd@latest
|
|
35
|
+
opencode-loopd
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then restart OpenCode.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
### Create a goal
|
|
43
|
+
|
|
44
|
+
From any session, tell the agent:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Create a background goal to fetch the latest AI news and save 10 items to ai-news.md
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The agent will use `loopd_create_goal` to start the goal.
|
|
51
|
+
|
|
52
|
+
### Monitor with dashboard
|
|
53
|
+
|
|
54
|
+
Press `Ctrl+L` or open the command palette → "Loop Dashboard".
|
|
55
|
+
|
|
56
|
+
Dashboard shortcuts:
|
|
57
|
+
- `j/k` — move selection
|
|
58
|
+
- `g/G` — jump to top/bottom
|
|
59
|
+
- `o` — open child session (full transcript)
|
|
60
|
+
- `p/r/R/x` — pause / resume / retry / clear selected goal
|
|
61
|
+
- `?` — toggle help
|
|
62
|
+
- `:` — enter insert mode (send message, control commands)
|
|
63
|
+
- `Ctrl+N` — return to normal mode
|
|
64
|
+
- `q` — close
|
|
65
|
+
|
|
66
|
+
### Inspect from main agent
|
|
67
|
+
|
|
68
|
+
The main agent can use these tools:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
list_background_goals() — status snapshot
|
|
72
|
+
inspect_background_goal() — full detail
|
|
73
|
+
read_goal_transcript() — child session transcript
|
|
74
|
+
send_goal_input(goalID, msg) — send instruction to child
|
|
75
|
+
pause_goal(goalID) — pause
|
|
76
|
+
resume_goal(goalID) — resume
|
|
77
|
+
clear_goal(goalID) — stop and remove
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Worker tools (child session)
|
|
81
|
+
|
|
82
|
+
The child worker has these tools:
|
|
83
|
+
|
|
84
|
+
- `get_goal` — read objective, state, criteria
|
|
85
|
+
- `report_goal_progress` — report what was done
|
|
86
|
+
- `complete_goal` — mark done (must pass checks)
|
|
87
|
+
- `block_goal` — mark blocked (needs user)
|
|
88
|
+
- `question` (OpenCode builtin) — ask the user; appears in the TUI footer
|
|
89
|
+
|
|
90
|
+
## Architecture
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Main session (parent)
|
|
94
|
+
↕ owner tools: inspect, steer, pause
|
|
95
|
+
Loopd engine
|
|
96
|
+
↕ continuation steering + accumulated context
|
|
97
|
+
Child worker session
|
|
98
|
+
↕ goal tools: progress, complete, block, ask
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- **Engine-driven loop**: child works → idle detected → engine re-prompts with accumulated context
|
|
102
|
+
- **Parent visibility**: owner tools read child transcript, progress history, and current state
|
|
103
|
+
- **Bidirectional messaging**: inbox system for user↔child instructions
|
|
104
|
+
- **Safety defaults**: maxTurns=50, maxFailures=3
|
|
105
|
+
|
|
106
|
+
## Example
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
# Create a goal
|
|
110
|
+
goal: "Find all .ts files in src/, count lines, write summary to line-counts.md"
|
|
111
|
+
|
|
112
|
+
# Engine loops automatically
|
|
113
|
+
Turn 1: child counts files → reports progress
|
|
114
|
+
Turn 2: child sees "batch 1 done" → continues
|
|
115
|
+
Turn 3: child finishes → calls complete_goal
|
|
116
|
+
|
|
117
|
+
# Parent inspects at any time
|
|
118
|
+
inspect_background_goal() → shows turn count, progress, status
|
|
119
|
+
read_goal_transcript() → shows child's work
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Configuration
|
|
123
|
+
|
|
124
|
+
Goals accept these config options:
|
|
125
|
+
|
|
126
|
+
| Option | Default | Description |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| `maxTurns` | 50 | Max continuation turns |
|
|
129
|
+
| `maxFailures` | 3 | Max consecutive failures before block |
|
|
130
|
+
| `maxNoProgress` | 3 | Turns without progress before block |
|
|
131
|
+
| `timeoutMs` | 300000 | Per-turn timeout (5 min) |
|
|
132
|
+
| `compactEvery` | — | Compact child session every N turns |
|
|
133
|
+
| `checks` | [] | Shell commands that must pass for completion |
|
|
134
|
+
| `progressFile` | — | Markdown file for transaction state |
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
AGPL-3.0-only — see [LICENSE](./LICENSE).
|
package/commands/goal.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new background loop goal. Asks clarifying questions, then spawns an autonomous worker session via loopd.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Create a new background loop goal using the `loopd_create_goal` tool.
|
|
6
|
+
|
|
7
|
+
First, gather what you need to craft a good goal:
|
|
8
|
+
- If the user gave a vague objective, ask 1–3 short clarifying questions (what to accomplish, where, and how they'll verify it).
|
|
9
|
+
- If the user was specific, skip straight to creating it.
|
|
10
|
+
|
|
11
|
+
When you have enough to write a concrete objective:
|
|
12
|
+
1. Call `loopd_create_goal` with:
|
|
13
|
+
- `name` — a short slug (e.g. "pdf-notes")
|
|
14
|
+
- `objective` — a precise, self-contained statement including verification criteria
|
|
15
|
+
- `checks` — optional shell commands that must pass before the goal can be marked complete (e.g. `["npm test"]`)
|
|
16
|
+
- `progressFile` — optional path to a markdown progress file
|
|
17
|
+
- limits — optional `maxTurns`, `maxNoProgress`, `maxFailures`, `compactEvery`, `timeoutMs`
|
|
18
|
+
2. After it returns, tell the user the goal is running in the background and they can monitor it with `/loop` (or Ctrl+L).
|
|
19
|
+
|
|
20
|
+
Important: the worker session runs autonomously — do not try to do the goal's work in this chat. This chat only creates the goal.
|