@bybrawe/opencode-loop 0.5.18 → 0.5.20

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.
@@ -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
- await new Promise((resolve) => setTimeout(resolve, 0))
90
- assert.ok(prompts.some((prompt) => prompt.includes(path.resolve(directory))), "goal prompt must include the working directory")
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
- await new Promise((resolve) => setTimeout(resolve, 1_400))
126
- assert.equal(prompts.length, promptCountBeforeBackgroundTool + 1, "the due loop must resume after the active tool finishes and the session becomes idle")
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
- await new Promise((resolve) => setTimeout(resolve, 1_400))
147
- assert.equal(prompts.length, promptCountBeforeBackgroundChild + 1, "the parent loop must resume after its background child becomes idle")
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)