@bybrawe/opencode-loop 0.5.18 → 0.5.19
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 +4 -0
- package/README.md +2 -2
- package/package.json +1 -1
- package/scripts/smoke-test.mjs +24 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.19
|
|
4
|
+
|
|
5
|
+
- Made the asynchronous goal prompt smoke test wait for the observable SDK call instead of assuming a single event-loop tick is always sufficient under load.
|
|
6
|
+
|
|
3
7
|
## 0.5.18
|
|
4
8
|
|
|
5
9
|
- Fixed package-based installs loading stale OpenCode cache entries after npm had installed a newer release. The installer now pins an existing package config entry to its exact installed version while preserving JSONC comments.
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ v0.5.11 includes a referenced heartbeat scheduler. This is important in OpenCode
|
|
|
16
16
|
|
|
17
17
|
## Current status
|
|
18
18
|
|
|
19
|
-
**v0.5.
|
|
19
|
+
**v0.5.19 hardens Goal Mode, package updates, and the background daemon.** Package installs are pinned to the installed version so OpenCode cannot keep loading an older cached release, scheduler-created goal messages no longer self-interrupt on delayed updates, finite daemon failures return nonzero, model/agent selection is supported, Windows scheduled tasks use a short launcher that stays below the `/TR` limit, and asynchronous release verification is reliable under load.
|
|
20
20
|
|
|
21
21
|
The known update-related symptoms from older builds are fixed:
|
|
22
22
|
|
|
@@ -32,7 +32,7 @@ The known update-related symptoms from older builds are fixed:
|
|
|
32
32
|
|
|
33
33
|
The TUI loop is still intentionally session-bound: it runs while OpenCode is open and the current session emits status/idle events. For long-running background work after closing the terminal or OpenCode, use `opencode-loopd`.
|
|
34
34
|
|
|
35
|
-
## v0.5.
|
|
35
|
+
## v0.5.19 quick behavior guide
|
|
36
36
|
|
|
37
37
|
OpenCode Loop has two triggers now:
|
|
38
38
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bybrawe/opencode-loop",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.19",
|
|
4
4
|
"description": "Claude Code/Codex style /loop and experimental goal mode for OpenCode: heartbeat scheduler, idle-safe loops, scheduled commands, compact scheduling, verification, checkpoints, and persistent coding goals.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/scripts/smoke-test.mjs
CHANGED
|
@@ -12,6 +12,15 @@ const prompts = []
|
|
|
12
12
|
const liveStatuses = new Map([[sessionID, "idle"]])
|
|
13
13
|
let hooks
|
|
14
14
|
|
|
15
|
+
async function waitFor(predicate, timeoutMs = 2_000) {
|
|
16
|
+
const deadline = Date.now() + timeoutMs
|
|
17
|
+
while (!predicate()) {
|
|
18
|
+
if (Date.now() >= deadline) return false
|
|
19
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
20
|
+
}
|
|
21
|
+
return true
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
function legacyBody(name) {
|
|
16
25
|
return async (args) => {
|
|
17
26
|
attempts[name]++
|
|
@@ -86,8 +95,11 @@ try {
|
|
|
86
95
|
assert.equal(output.parts.length, 0, "a locally handled slash command must not start a placeholder model turn")
|
|
87
96
|
|
|
88
97
|
await hooks["command.execute.before"]({ command: "loop-now", sessionID, arguments: "goal" }, { parts: [] })
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
assert.equal(
|
|
99
|
+
await waitFor(() => prompts.some((prompt) => prompt.includes(path.resolve(directory)))),
|
|
100
|
+
true,
|
|
101
|
+
"goal prompt must include the working directory",
|
|
102
|
+
)
|
|
91
103
|
assert.ok(prompts.some((prompt) => prompt.includes("never turn a relative path into a root path")))
|
|
92
104
|
|
|
93
105
|
const stateFile = path.join(directory, ".opencode", "opencode-loop", `${sessionID}.json`)
|
|
@@ -122,8 +134,11 @@ try {
|
|
|
122
134
|
|
|
123
135
|
await hooks["tool.execute.after"]({ tool: "bash", sessionID, callID: "call_background", args: {} }, { title: "done", output: "", metadata: {} })
|
|
124
136
|
await hooks.event({ event: { type: "session.idle", properties: { sessionID } } })
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
assert.equal(
|
|
138
|
+
await waitFor(() => prompts.length === promptCountBeforeBackgroundTool + 1, 5_000),
|
|
139
|
+
true,
|
|
140
|
+
"the due loop must resume after the active tool finishes and the session becomes idle",
|
|
141
|
+
)
|
|
127
142
|
|
|
128
143
|
await hooks["command.execute.before"]({ command: "loop-clear", sessionID, arguments: "" }, { parts: [] })
|
|
129
144
|
|
|
@@ -143,8 +158,11 @@ try {
|
|
|
143
158
|
liveStatuses.set(childSessionID, "idle")
|
|
144
159
|
await hooks.event({ event: { type: "session.status", properties: { sessionID: childSessionID, status: { type: "idle" } } } })
|
|
145
160
|
await hooks.event({ event: { type: "session.idle", properties: { sessionID } } })
|
|
146
|
-
|
|
147
|
-
|
|
161
|
+
assert.equal(
|
|
162
|
+
await waitFor(() => prompts.length === promptCountBeforeBackgroundChild + 1, 5_000),
|
|
163
|
+
true,
|
|
164
|
+
"the parent loop must resume after its background child becomes idle",
|
|
165
|
+
)
|
|
148
166
|
|
|
149
167
|
await hooks["command.execute.before"]({ command: "loop-clear", sessionID, arguments: "" }, { parts: [] })
|
|
150
168
|
assert.equal(attempts.log, 1)
|