Skip to content

Commit 1de53d3

Browse files
mcheemaaclaude
andcommitted
Bump to v2.0.4: fix wait_after param substitution, harden slack-send
Bug fix: wait_after conditions with {{param}} placeholders were never substituted, causing recipes to wait for literal "{{channel}}" strings. Now substituteWaitAfter resolves templates before checking conditions. slack-send recipe improvements: - Add explicit wait step for message input before clicking (fixes race condition) - Broaden message input match from "Message to" to "Message" (works for all channel types) - Increase verification timeout to 5s, mark as skip-on-failure (message already sent) - 8 steps, tested 2x with 100% success rate All 4 recipes tested end-to-end: - gmail-send: 7/7 steps, 30s - arxiv-download: 8/8 steps, 20s - slack-send: 8/8 steps, 13s - finder-create-folder: 5/5 steps, 6s Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d40cac9 commit 1de53d3

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

Sources/GhostOS/Common/Types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Foundation
88
// MARK: - Version
99

1010
public enum GhostOS {
11-
public static let version = "2.0.3"
11+
public static let version = "2.0.4"
1212
public static let name = "ghost-os"
1313
}
1414

Sources/GhostOS/Recipes/RecipeEngine.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,10 @@ public enum RecipeEngine {
128128
)
129129
}
130130

131-
// Handle wait_after condition
131+
// Handle wait_after condition (substitute {{params}} in value)
132132
if let waitAfter = step.waitAfter {
133-
let waitResult = handleWaitAfter(waitAfter, appName: recipe.app)
133+
let resolvedWaitAfter = substituteWaitAfter(waitAfter, with: params)
134+
let waitResult = handleWaitAfter(resolvedWaitAfter, appName: recipe.app)
134135
if !waitResult.success {
135136
let totalDuration = Int(Date().timeIntervalSince(startTime) * 1000)
136137

@@ -228,6 +229,23 @@ public enum RecipeEngine {
228229
return resolved
229230
}
230231

232+
/// Replace {{param}} placeholders in a wait_after condition's value.
233+
private static func substituteWaitAfter(
234+
_ waitAfter: RecipeWaitCondition,
235+
with values: [String: String]
236+
) -> RecipeWaitCondition {
237+
guard var value = waitAfter.value else { return waitAfter }
238+
for (paramName, paramValue) in values {
239+
value = value.replacingOccurrences(of: "{{\(paramName)}}", with: paramValue)
240+
}
241+
return RecipeWaitCondition(
242+
condition: waitAfter.condition,
243+
target: waitAfter.target,
244+
value: value,
245+
timeout: waitAfter.timeout
246+
)
247+
}
248+
231249
// MARK: - Step Execution
232250

233251
/// Execute a single recipe step by dispatching to the appropriate action.

recipes/slack-send.json

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,21 @@
5050
}
5151
},
5252
{
53-
"action": "click",
53+
"action": "wait",
5454
"id": 4,
55+
"note": "Wait for message input to be ready",
56+
"params": {
57+
"condition": "elementExists",
58+
"timeout": "5",
59+
"value": "Message"
60+
}
61+
},
62+
{
63+
"action": "click",
64+
"id": 5,
5565
"note": "Click message input box",
5666
"target": {
57-
"computedNameContains": "Message to",
67+
"computedNameContains": "Message",
5868
"criteria": [
5969
{
6070
"attribute": "AXRole",
@@ -65,27 +75,28 @@
6575
},
6676
{
6777
"action": "type",
68-
"id": 5,
78+
"id": 6,
6979
"note": "Type the message",
7080
"params": {
7181
"text": "{{message}}"
7282
}
7383
},
7484
{
7585
"action": "hotkey",
76-
"id": 6,
86+
"id": 7,
7787
"note": "Send message",
7888
"params": {
7989
"keys": "cmd,return"
8090
}
8191
},
8292
{
8393
"action": "wait",
84-
"id": 7,
85-
"note": "Wait for message to appear in channel",
94+
"id": 8,
95+
"note": "Verify message appeared in channel",
96+
"on_failure": "skip",
8697
"params": {
8798
"condition": "elementExists",
88-
"timeout": "3",
99+
"timeout": "5",
89100
"value": "{{message}}"
90101
}
91102
}

0 commit comments

Comments
 (0)