shortcuts-playground 1.2.1

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.
Files changed (68) hide show
  1. package/README.md +54 -0
  2. package/agents/shortcut-builder.md +172 -0
  3. package/agents/shortcut-remixer.md +239 -0
  4. package/commands/build-shortcut.md +32 -0
  5. package/commands/remix-shortcut.md +34 -0
  6. package/opencode.json +30 -0
  7. package/package.json +47 -0
  8. package/plugin/validator.ts +179 -0
  9. package/skills/shortcuts-playground/ACTIONS.md +713 -0
  10. package/skills/shortcuts-playground/APPINTENTS.md +2760 -0
  11. package/skills/shortcuts-playground/AUTOMATION_TRIGGERS.md +133 -0
  12. package/skills/shortcuts-playground/BEST_PRACTICES.md +357 -0
  13. package/skills/shortcuts-playground/CHANGELOG.md +585 -0
  14. package/skills/shortcuts-playground/CONTROL_FLOW.md +777 -0
  15. package/skills/shortcuts-playground/DATE_TIME.md +75 -0
  16. package/skills/shortcuts-playground/EXAMPLES.md +738 -0
  17. package/skills/shortcuts-playground/FILTERS.md +697 -0
  18. package/skills/shortcuts-playground/HEALTHKIT.md +317 -0
  19. package/skills/shortcuts-playground/ICONS_AND_COLORS.md +89 -0
  20. package/skills/shortcuts-playground/JAVASCRIPT_WEBPAGE.md +51 -0
  21. package/skills/shortcuts-playground/PARAMETER_TYPES.md +1117 -0
  22. package/skills/shortcuts-playground/PLIST_FORMAT.md +296 -0
  23. package/skills/shortcuts-playground/README.md +77 -0
  24. package/skills/shortcuts-playground/SKILL.md +459 -0
  25. package/skills/shortcuts-playground/THIRD_PARTY_ACTIONS.md +77 -0
  26. package/skills/shortcuts-playground/TOOLKIT_SNAPSHOT.md +62 -0
  27. package/skills/shortcuts-playground/URL_SCHEMES.md +59 -0
  28. package/skills/shortcuts-playground/VARIABLES.md +569 -0
  29. package/skills/shortcuts-playground/assets/shortcuts-small.svg +14 -0
  30. package/skills/shortcuts-playground/assets/shortcuts.png +0 -0
  31. package/skills/shortcuts-playground/data/healthkit-ios26.2-reference.json +2603 -0
  32. package/skills/shortcuts-playground/data/macos27-shortpy-grounding.json +4085 -0
  33. package/skills/shortcuts-playground/data/macos27-workflow-trigger-samples.json +1 -0
  34. package/skills/shortcuts-playground/data/shortcuts-glyph-synonyms.json +5102 -0
  35. package/skills/shortcuts-playground/data/shortcuts-icon-colors.json +107 -0
  36. package/skills/shortcuts-playground/data/shortcuts-official-glyph-mapping.json +509 -0
  37. package/skills/shortcuts-playground/data/toolkit-v63-tool-ids.json +1806 -0
  38. package/skills/shortcuts-playground/data/toolkit-v78-first-party-enum-cases.json +1 -0
  39. package/skills/shortcuts-playground/data/toolkit-v78-first-party-parameter-keys.json +1 -0
  40. package/skills/shortcuts-playground/data/toolkit-v78-ios27-tool-ids.json +1222 -0
  41. package/skills/shortcuts-playground/data/toolkit-v78-tool-ids.json +2745 -0
  42. package/skills/shortcuts-playground/data/toolkit-v78-trigger-parameter-keys.json +1051 -0
  43. package/skills/shortcuts-playground/golden-shortcuts/index.jsonl +19 -0
  44. package/skills/shortcuts-playground/golden-shortcuts/xml/1be4dde95b794253bf82438e201b33e7.xml +174 -0
  45. package/skills/shortcuts-playground/golden-shortcuts/xml/2e0fb675e45948aaacee7e534f910492.xml +1016 -0
  46. package/skills/shortcuts-playground/golden-shortcuts/xml/332c12a0060043b388b22b806be7ab58.xml +1924 -0
  47. package/skills/shortcuts-playground/golden-shortcuts/xml/3dd4ee24e43f464f92adaa70a0311eaa.xml +1177 -0
  48. package/skills/shortcuts-playground/golden-shortcuts/xml/4d102301c6e646faa7a8a221f4f4ec98.xml +321 -0
  49. package/skills/shortcuts-playground/golden-shortcuts/xml/51cc4e26d1044893a0c3f2f3630cf2d2.xml +1933 -0
  50. package/skills/shortcuts-playground/golden-shortcuts/xml/623e7f1ca5f948e2bd53811fec63e544.xml +136 -0
  51. package/skills/shortcuts-playground/golden-shortcuts/xml/6a18b76843ac45c384ac3400f3740997.xml +1791 -0
  52. package/skills/shortcuts-playground/golden-shortcuts/xml/71f0cacb0f604b399b76c5dcb7286e7c.xml +2228 -0
  53. package/skills/shortcuts-playground/golden-shortcuts/xml/807525ed9f974829bc8494defac923a8.xml +259 -0
  54. package/skills/shortcuts-playground/golden-shortcuts/xml/8ab0d39826ab4249be58672763caa3ba.xml +420 -0
  55. package/skills/shortcuts-playground/golden-shortcuts/xml/91c45fd3fd3b427897d9ba485efb1227.xml +800 -0
  56. package/skills/shortcuts-playground/golden-shortcuts/xml/97be626bb25c41709d175646a7f6d8f2.xml +424 -0
  57. package/skills/shortcuts-playground/golden-shortcuts/xml/ae59e10d409348f9bd33894f03f9beb4.xml +568 -0
  58. package/skills/shortcuts-playground/golden-shortcuts/xml/afa83b6be811483b9c32189c41eb9312.xml +391 -0
  59. package/skills/shortcuts-playground/golden-shortcuts/xml/cfdb083b857e4ac189629fa386d27cdc.xml +193 -0
  60. package/skills/shortcuts-playground/golden-shortcuts/xml/e01cebe192d64b2fbca80204d03d92ab.xml +111 -0
  61. package/skills/shortcuts-playground/golden-shortcuts/xml/ef669bcf8bad489d9ef4b88bfaf5772f.xml +780 -0
  62. package/skills/shortcuts-playground/golden-shortcuts/xml/f44f5caf5e3e48d4817e73af450c4404.xml +570 -0
  63. package/skills/shortcuts-playground/scripts/generate_healthkit_reference.py +394 -0
  64. package/skills/shortcuts-playground/scripts/lookup_action_grounding.py +1164 -0
  65. package/skills/shortcuts-playground/scripts/select_shortcut_icon_color.py +597 -0
  66. package/skills/shortcuts-playground/scripts/test_random_mixed_shortcuts.py +1067 -0
  67. package/skills/shortcuts-playground/scripts/test_wiring_regressions.py +2247 -0
  68. package/skills/shortcuts-playground/scripts/validate_shortcut.py +4526 -0
@@ -0,0 +1,59 @@
1
+ # Shortcuts URL Schemes and x-callback-url
2
+
3
+ Use only Apple-documented Shortcuts URL forms. Do not invent `shortcuts://` routes, import routes, or extra query parameters unless the user provides working evidence from their own shortcut library.
4
+
5
+ ## Apple-Documented Shortcuts URLs
6
+
7
+ All query parameter values must be URL-encoded.
8
+
9
+ | Purpose | URL |
10
+ | --- | --- |
11
+ | Open Shortcuts | `shortcuts://` |
12
+ | Create a new shortcut editor draft | `shortcuts://create-shortcut` |
13
+ | Open an existing shortcut | `shortcuts://open-shortcut?name=<encoded shortcut name>` |
14
+ | Run a shortcut | `shortcuts://run-shortcut?name=<encoded shortcut name>` |
15
+ | Run with text input | `shortcuts://run-shortcut?name=<encoded shortcut name>&input=text&text=<encoded text>` |
16
+ | Run with clipboard input | `shortcuts://run-shortcut?name=<encoded shortcut name>&input=clipboard` |
17
+ | Open Gallery | `shortcuts://gallery` |
18
+ | Search Gallery | `shortcuts://gallery/search?query=<encoded search terms>` |
19
+
20
+ Use the **Run Shortcut** action instead of `shortcuts://run-shortcut` when one shortcut needs to run another shortcut. Use the URL scheme only for integration from outside Shortcuts, such as another app, a website, a command line, or a task manager URL field.
21
+
22
+ ## x-callback-url
23
+
24
+ Shortcuts supports x-callback-url for running shortcuts and returning to the calling app:
25
+
26
+ ```text
27
+ shortcuts://x-callback-url/run-shortcut?name=<encoded shortcut name>&input=text&text=<encoded text>&x-success=<encoded callback URL>&x-cancel=<encoded callback URL>&x-error=<encoded callback URL>
28
+ ```
29
+
30
+ Callback parameters:
31
+
32
+ | Parameter | Behavior |
33
+ | --- | --- |
34
+ | `x-success` | Opened after successful completion. When a shortcut runs, Shortcuts appends `result=<text output>` to this callback URL. |
35
+ | `x-cancel` | Opened when the user cancels before completion. No shortcut output is provided. |
36
+ | `x-error` | Opened when Shortcuts fails to complete. Shortcuts appends `errorMessage=<description>` to this callback URL. |
37
+
38
+ Always URL-encode the callback URL itself. For example, `myapp://done` becomes `myapp%3A%2F%2Fdone` when placed in `x-success`.
39
+
40
+ ## Building These in Shortcuts
41
+
42
+ - For a normal URL launch, use **URL** (`is.workflow.actions.url`) followed by **Open URL** (`is.workflow.actions.openurl`).
43
+ - For callback workflows, prefer **Open X-Callback URL** (`is.workflow.actions.openxcallbackurl`) when the shortcut must wait for or route callbacks.
44
+ - Do not hard-code unencoded user text into a URL. Assemble text first, then URL-encode user-supplied pieces.
45
+ - Do not use `input=text` without a non-empty `text` parameter.
46
+ - Do not include `text=` with `input=clipboard`; Shortcuts ignores it.
47
+
48
+ ## Local Verification Notes
49
+
50
+ On macOS, `open -g -u <url>` verifies that LaunchServices accepts the Shortcuts URL and hands it to Shortcuts. In local testing on 2026-05-04, `shortcuts://`, `shortcuts://gallery`, `shortcuts://gallery/search?query=photos`, `shortcuts://open-shortcut?name=Shortcuts%20Playground`, and `shortcuts://create-shortcut` all returned success through `open -g -u`.
51
+
52
+ x-callback success/error routing requires a runnable shortcut and a real callback receiver. The bundled validator therefore verifies the documented URL shapes and required parameters, but it cannot prove a specific user-library shortcut exists.
53
+
54
+ ## Sources
55
+
56
+ - Apple Shortcuts User Guide: Open and create a shortcut using a URL scheme
57
+ - Apple Shortcuts User Guide: Run a shortcut from a URL
58
+ - Apple Shortcuts User Guide: Open or search the Gallery from a URL
59
+ - Apple Shortcuts User Guide: Use x-callback-url
@@ -0,0 +1,569 @@
1
+ # Variable Reference System
2
+
3
+ How to pass data between actions in Shortcuts.
4
+
5
+ ## Overview
6
+
7
+ Shortcuts uses a UUID-based system for referencing output from previous actions:
8
+
9
+ 1. **Source action** has a `UUID` parameter identifying its output
10
+ 2. **Consuming action** references that UUID via `OutputUUID` in `attachmentsByRange`
11
+ 3. The placeholder character `` (U+FFFC) marks where variables are inserted in text
12
+
13
+ ## UUID Format
14
+
15
+ UUIDs must be:
16
+ - **Uppercase** letters
17
+ - Standard UUID format: `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX`
18
+
19
+ Example: `A1B2C3D4-E5F6-7890-ABCD-EF1234567890`
20
+
21
+ Generate with any UUID generator, just ensure uppercase.
22
+
23
+ ---
24
+
25
+ ## WFSerializationType Values
26
+
27
+ The `WFSerializationType` key indicates the type of value:
28
+
29
+ | Type | Description | Usage |
30
+ |------|-------------|-------|
31
+ | `WFTextTokenString` | Text with embedded variable references | Text fields with variables mixed in; uses `` placeholders |
32
+ | `WFTextTokenAttachment` | Single variable reference (no surrounding text) | When parameter IS purely a variable/output; no text wrapper |
33
+ | `WFContentPredicateTableTemplate` | Filter/predicate definition | For filter actions |
34
+ | `WFDictionaryFieldValueItems` | Dictionary entries | For dictionary creation |
35
+ | `WFQuantityFieldValue` | Measurement with unit (duration, size, etc.) | For durations: Magnitude + Unit |
36
+
37
+ **CRITICAL DISTINCTION (from analysis of 127 real shortcuts + runtime testing):**
38
+
39
+ - **WFTextTokenAttachment = Single variable reference for data-flow parameters** — use when the parameter IS just a variable with no text around it AND the parameter is a non-display data input (e.g., `WFInput`, `WFDate`, `WFVariable`)
40
+ - **WFTextTokenString = Text containing embedded variables OR display parameters** — use when there's text that contains one or more variables inserted via `` placeholders, OR when the parameter is a display parameter (shown to the user in UI)
41
+
42
+ **Display vs Non-Display Parameter Rule (runtime-verified):**
43
+
44
+ | Parameter Type | Serialization | Example Parameters |
45
+ |----------------|--------------|-------------------|
46
+ | **Display** (user-visible text) | MUST use `WFTextTokenString` even for single variable | `WFAlertActionMessage`, `WFAlertActionTitle`, `WFNotificationActionBody`, `WFNotificationActionTitle`, `Text` (Show Result) |
47
+ | **Non-display** (data flow) | Can use `WFTextTokenAttachment` for single variable | `WFInput`, `WFDate`, `WFVariable`, `WFDictionary`, `WFFile` |
48
+
49
+ Using `WFTextTokenAttachment` for display parameters causes the field to appear as default/empty text at runtime. This was confirmed across all 46 Show Alert and 41 Notification instances in the 127-shortcut corpus — every one uses `WFTextTokenString` for message/body fields.
50
+
51
+ ---
52
+
53
+ ## attachmentsByRange Format
54
+
55
+ The `attachmentsByRange` dictionary maps character positions to variable references:
56
+
57
+ ```xml
58
+ <key>attachmentsByRange</key>
59
+ <dict>
60
+ <key>{position, length}</key>
61
+ <dict>
62
+ <key>OutputUUID</key>
63
+ <string>SOURCE-ACTION-UUID</string>
64
+ <key>OutputName</key>
65
+ <string>Display Name</string>
66
+ <key>Type</key>
67
+ <string>ActionOutput</string>
68
+ </dict>
69
+ </dict>
70
+ ```
71
+
72
+ ### Range Key Format
73
+
74
+ `{position, length}` where:
75
+ - **position**: Character index in the string (0-based)
76
+ - **length**: Always `1` (the placeholder is 1 character)
77
+
78
+ Examples:
79
+ - `{0, 1}` - Variable at start of string
80
+ - `{5, 1}` - Variable at position 5
81
+ - `{10, 1}` - Variable at position 10
82
+
83
+ ---
84
+
85
+ ## The Placeholder Character
86
+
87
+ The Object Replacement Character `` (U+FFFC, Unicode code point 65532) serves as a placeholder in the `string` value where variables are inserted.
88
+
89
+ In XML, represent it as:
90
+ - Direct character: ``
91
+ - Or escaped: `&#xFFFC;` or `&#65532;`
92
+
93
+ Example string with two variables:
94
+ ```xml
95
+ <key>string</key>
96
+ <string>Hello , the weather is </string>
97
+ ```
98
+
99
+ With attachments at positions 6 and 24.
100
+
101
+ ---
102
+
103
+ ## Position Accuracy Checklist
104
+
105
+ - Compute `attachmentsByRange` positions from the final string (0-based) by locating each `` placeholder.
106
+ - Recompute positions if the surrounding text changes (including emoji or added characters).
107
+ - For multiple placeholders, create one `attachmentsByRange` entry per `` and verify each key points to the exact position.
108
+ - If a placeholder exists but no matching range, the variable will not render.
109
+ - If a range points past the end of the string, Shortcuts can crash on import.
110
+ - For JSON strings, do not leave required fields as empty quotes (`""`); use a placeholder with an attachment or explicitly document the missing value.
111
+
112
+ ---
113
+
114
+ ## Complete Variable Reference Structure
115
+
116
+ ### WFTextTokenString (Text with Variables)
117
+
118
+ Use when the parameter is text that may contain variable references:
119
+
120
+ ```xml
121
+ <key>ParameterName</key>
122
+ <dict>
123
+ <key>Value</key>
124
+ <dict>
125
+ <key>string</key>
126
+ <string>The result is: </string>
127
+ <key>attachmentsByRange</key>
128
+ <dict>
129
+ <key>{16, 1}</key>
130
+ <dict>
131
+ <key>OutputUUID</key>
132
+ <string>11111111-1111-1111-1111-111111111111</string>
133
+ <key>OutputName</key>
134
+ <string>Result</string>
135
+ <key>Type</key>
136
+ <string>ActionOutput</string>
137
+ </dict>
138
+ </dict>
139
+ </dict>
140
+ <key>WFSerializationType</key>
141
+ <string>WFTextTokenString</string>
142
+ </dict>
143
+ ```
144
+
145
+ ### WFTextTokenAttachment (Single Variable)
146
+
147
+ Use when the parameter is just a variable reference with no surrounding text:
148
+
149
+ ```xml
150
+ <key>ParameterName</key>
151
+ <dict>
152
+ <key>Value</key>
153
+ <dict>
154
+ <key>OutputUUID</key>
155
+ <string>11111111-1111-1111-1111-111111111111</string>
156
+ <key>OutputName</key>
157
+ <string>Text</string>
158
+ <key>Type</key>
159
+ <string>ActionOutput</string>
160
+ </dict>
161
+ <key>WFSerializationType</key>
162
+ <string>WFTextTokenAttachment</string>
163
+ </dict>
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Type Values
169
+
170
+ The `Type` key in attachment dictionaries indicates the variable source.
171
+
172
+ **Complete list of Variable Types (from XML ground truth analysis of 127 real shortcuts):**
173
+
174
+ | Type | Description | Usage |
175
+ |------|-------------|-------|
176
+ | `ActionOutput` | Output from a previous action | Most common; requires OutputUUID + OutputName |
177
+ | `Variable` | Named variable (from Set Variable) | For referencing named variables by VariableName |
178
+ | `CurrentDate` | Current date/time | No additional parameters |
179
+ | `Clipboard` | System clipboard contents | No additional parameters |
180
+ | `Ask` | Ask When Run prompt response | No additional parameters |
181
+ | `ExtensionInput` | Shortcut input (share sheet) | Magic variable for shortcut input |
182
+ | `DeviceDetails` | Device information | No additional parameters |
183
+ | `CurrentApp` | Currently active application | No additional parameters |
184
+
185
+ Example with CurrentDate:
186
+ ```xml
187
+ <dict>
188
+ <key>Type</key>
189
+ <string>CurrentDate</string>
190
+ </dict>
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Set Variable and Append Variable Patterns
196
+
197
+ ### Set Variable (is.workflow.actions.setvariable)
198
+
199
+ Creates or updates a named variable:
200
+
201
+ ```xml
202
+ <dict>
203
+ <key>WFWorkflowActionIdentifier</key>
204
+ <string>is.workflow.actions.setvariable</string>
205
+ <key>WFWorkflowActionParameters</key>
206
+ <dict>
207
+ <key>UUID</key>
208
+ <string>VARIABLE-ACTION-UUID</string>
209
+ <key>WFVariableName</key>
210
+ <string>myVariableName</string>
211
+ <key>WFInput</key>
212
+ <dict>
213
+ <key>Value</key>
214
+ <dict>
215
+ <key>OutputUUID</key>
216
+ <string>SOURCE-ACTION-UUID</string>
217
+ <key>OutputName</key>
218
+ <string>Text</string>
219
+ <key>Type</key>
220
+ <string>ActionOutput</string>
221
+ </dict>
222
+ <key>WFSerializationType</key>
223
+ <string>WFTextTokenAttachment</string>
224
+ </dict>
225
+ </dict>
226
+ </dict>
227
+ ```
228
+
229
+ **Key parameters:**
230
+ - `WFVariableName`: Name of the variable being set (appears in Variable picker)
231
+ - `WFInput`: The value to store (action output, text, etc.)
232
+
233
+ ### Get Variable (WFVariable token attachment)
234
+
235
+ Reference a named variable later with:
236
+
237
+ ```xml
238
+ <key>WFVariable</key>
239
+ <dict>
240
+ <key>Value</key>
241
+ <dict>
242
+ <key>Type</key>
243
+ <string>Variable</string>
244
+ <key>VariableName</key>
245
+ <string>myVariableName</string>
246
+ </dict>
247
+ <key>WFSerializationType</key>
248
+ <string>WFTextTokenAttachment</string>
249
+ </dict>
250
+ ```
251
+
252
+ ### Append Variable (is.workflow.actions.appendvariable)
253
+
254
+ Accumulator pattern: adds items to a named variable inside loops.
255
+
256
+ ```xml
257
+ <dict>
258
+ <key>WFWorkflowActionIdentifier</key>
259
+ <string>is.workflow.actions.appendvariable</string>
260
+ <key>WFWorkflowActionParameters</key>
261
+ <dict>
262
+ <key>UUID</key>
263
+ <string>APPEND-ACTION-UUID</string>
264
+ <key>WFVariableName</key>
265
+ <string>myList</string>
266
+ <key>WFInput</key>
267
+ <dict>
268
+ <key>Value</key>
269
+ <dict>
270
+ <key>OutputUUID</key>
271
+ <string>REPEAT-ITEM-UUID</string>
272
+ <key>OutputName</key>
273
+ <string>Repeat Item</string>
274
+ <key>Type</key>
275
+ <string>ActionOutput</string>
276
+ </dict>
277
+ <key>WFSerializationType</key>
278
+ <string>WFTextTokenAttachment</string>
279
+ </dict>
280
+ </dict>
281
+ </dict>
282
+ ```
283
+
284
+ **Common pattern (accumulator inside Repeat Each loop):**
285
+ 1. Start a Repeat Each loop over a list
286
+ 2. Inside the loop, use Append Variable to add items (or properties of items) to a named variable
287
+ 3. After the loop ends, the named variable contains all accumulated items
288
+ 4. Reference it with `Type: Variable` / `VariableName: "myList"`
289
+
290
+ ---
291
+
292
+ ## Aggrandizements (Property Access)
293
+
294
+ Aggrandizements modify how a variable is accessed, like getting a property or coercing type:
295
+
296
+ ```xml
297
+ <key>Aggrandizements</key>
298
+ <array>
299
+ <dict>
300
+ <key>PropertyName</key>
301
+ <string>Name</string>
302
+ <key>Type</key>
303
+ <string>WFPropertyVariableAggrandizement</string>
304
+ </dict>
305
+ </array>
306
+ ```
307
+
308
+ ### Common Aggrandizement Types
309
+
310
+ #### Property Access
311
+ ```xml
312
+ <dict>
313
+ <key>PropertyName</key>
314
+ <string>Name</string>
315
+ <key>Type</key>
316
+ <string>WFPropertyVariableAggrandizement</string>
317
+ </dict>
318
+ ```
319
+
320
+ #### Dictionary Key Access
321
+ ```xml
322
+ <dict>
323
+ <key>DictionaryKey</key>
324
+ <string>keyName</string>
325
+ <key>Type</key>
326
+ <string>WFDictionaryValueVariableAggrandizement</string>
327
+ </dict>
328
+ ```
329
+
330
+ #### Type Coercion
331
+ ```xml
332
+ <dict>
333
+ <key>CoercionItemClass</key>
334
+ <string>WFStringContentItem</string>
335
+ <key>Type</key>
336
+ <string>WFCoercionVariableAggrandizement</string>
337
+ </dict>
338
+ ```
339
+
340
+ #### Date Format
341
+ Format a date variable inline (without a separate Format Date action):
342
+ ```xml
343
+ <dict>
344
+ <key>DateFormat</key>
345
+ <string>Short</string>
346
+ <key>Type</key>
347
+ <string>WFDateFormatVariableAggrandizement</string>
348
+ </dict>
349
+ ```
350
+
351
+ Possible `DateFormat` values: `Short`, `Medium`, `Long`, `Relative`, or a custom format string.
352
+
353
+ #### Chaining Multiple Aggrandizements
354
+
355
+ Aggrandizements can chain to perform multi-step property access in a single variable reference. For example, coercing a calendar event to a Location, then extracting its Street address:
356
+
357
+ ```xml
358
+ <key>Aggrandizements</key>
359
+ <array>
360
+ <dict>
361
+ <key>CoercionItemClass</key>
362
+ <string>WFLocationContentItem</string>
363
+ <key>Type</key>
364
+ <string>WFCoercionVariableAggrandizement</string>
365
+ </dict>
366
+ <dict>
367
+ <key>PropertyName</key>
368
+ <string>Street</string>
369
+ <key>PropertyUserInfo</key>
370
+ <string>street</string>
371
+ <key>Type</key>
372
+ <string>WFPropertyVariableAggrandizement</string>
373
+ </dict>
374
+ </array>
375
+ ```
376
+
377
+ This eliminates the need for intermediate actions — a single variable reference can coerce and extract in one step. Confirmed in the Calendar Locations golden shortcut.
378
+
379
+ #### Unit Extraction
380
+ Extract numeric value or unit string from a measurement variable:
381
+ ```xml
382
+ <dict>
383
+ <key>PropertyName</key>
384
+ <string>Value</string>
385
+ <key>Type</key>
386
+ <string>WFUnitVariableAggrandizement</string>
387
+ </dict>
388
+ ```
389
+
390
+ ---
391
+
392
+ ## WFQuantityFieldValue (Duration and Measurement)
393
+
394
+ Used for durations and measurements with units (delays, file sizes, etc.):
395
+
396
+ ```xml
397
+ <key>WFDuration</key>
398
+ <dict>
399
+ <key>Value</key>
400
+ <dict>
401
+ <key>Magnitude</key>
402
+ <real>5.0</real>
403
+ <key>Unit</key>
404
+ <string>min</string>
405
+ </dict>
406
+ <key>WFSerializationType</key>
407
+ <string>WFQuantityFieldValue</string>
408
+ </dict>
409
+ ```
410
+
411
+ **Structure:**
412
+ - `Magnitude`: The numeric value (e.g., 5.0 for 5 minutes)
413
+ - `Unit`: The unit abbreviation (e.g., "min", "hr", "days", "sec")
414
+
415
+ **Common duration units:**
416
+ - `sec` = seconds
417
+ - `min` = minutes
418
+ - `hr` = hours
419
+ - `days` = days
420
+ - `wk` = weeks
421
+ - `mon` = months
422
+ - `yr` = years
423
+
424
+ ---
425
+
426
+ ## Common Output Names
427
+
428
+ When referencing action outputs, use these common `OutputName` values:
429
+
430
+ | Action | OutputName |
431
+ |--------|------------|
432
+ | Text (gettext) | `Text` |
433
+ | Ask for Input | `Provided Input` |
434
+ | Ask LLM | `Response` |
435
+ | Get Weather | `Weather Conditions` |
436
+ | Get Current Location | `Current Location` |
437
+ | URL | `URL` |
438
+ | Get Contents of URL | `Contents of URL` |
439
+ | Number | `Number` |
440
+ | Date | `Date` |
441
+ | List | `List` |
442
+ | Dictionary | `Dictionary` |
443
+ | Repeat Each | `Repeat Item` |
444
+ | Repeat Count | `Repeat Index` |
445
+
446
+ ---
447
+
448
+ ## Example: Chaining Three Actions
449
+
450
+ ```xml
451
+ <!-- Action 1: Get Text -->
452
+ <dict>
453
+ <key>WFWorkflowActionIdentifier</key>
454
+ <string>is.workflow.actions.gettext</string>
455
+ <key>WFWorkflowActionParameters</key>
456
+ <dict>
457
+ <key>UUID</key>
458
+ <string>11111111-1111-1111-1111-111111111111</string>
459
+ <key>WFTextActionText</key>
460
+ <string>Hello World</string>
461
+ </dict>
462
+ </dict>
463
+
464
+ <!-- Action 2: Ask LLM (references Action 1) -->
465
+ <dict>
466
+ <key>WFWorkflowActionIdentifier</key>
467
+ <string>is.workflow.actions.askllm</string>
468
+ <key>WFWorkflowActionParameters</key>
469
+ <dict>
470
+ <key>UUID</key>
471
+ <string>22222222-2222-2222-2222-222222222222</string>
472
+ <key>WFLLMPrompt</key>
473
+ <dict>
474
+ <key>Value</key>
475
+ <dict>
476
+ <key>string</key>
477
+ <string>Translate this to French: </string>
478
+ <key>attachmentsByRange</key>
479
+ <dict>
480
+ <key>{26, 1}</key>
481
+ <dict>
482
+ <key>OutputUUID</key>
483
+ <string>11111111-1111-1111-1111-111111111111</string>
484
+ <key>OutputName</key>
485
+ <string>Text</string>
486
+ <key>Type</key>
487
+ <string>ActionOutput</string>
488
+ </dict>
489
+ </dict>
490
+ </dict>
491
+ <key>WFSerializationType</key>
492
+ <string>WFTextTokenString</string>
493
+ </dict>
494
+ </dict>
495
+ </dict>
496
+
497
+ <!-- Action 3: Show Result (references Action 2) -->
498
+ <dict>
499
+ <key>WFWorkflowActionIdentifier</key>
500
+ <string>is.workflow.actions.showresult</string>
501
+ <key>WFWorkflowActionParameters</key>
502
+ <dict>
503
+ <key>Text</key>
504
+ <dict>
505
+ <key>Value</key>
506
+ <dict>
507
+ <key>attachmentsByRange</key>
508
+ <dict>
509
+ <key>{0, 1}</key>
510
+ <dict>
511
+ <key>OutputUUID</key>
512
+ <string>22222222-2222-2222-2222-222222222222</string>
513
+ <key>OutputName</key>
514
+ <string>Response</string>
515
+ <key>Type</key>
516
+ <string>ActionOutput</string>
517
+ </dict>
518
+ </dict>
519
+ <key>string</key>
520
+ <string></string>
521
+ </dict>
522
+ <key>WFSerializationType</key>
523
+ <string>WFTextTokenString</string>
524
+ </dict>
525
+ </dict>
526
+ </dict>
527
+ ```
528
+
529
+ ---
530
+
531
+ ## Multiple Variables in One Parameter
532
+
533
+ When a parameter contains multiple variable references:
534
+
535
+ ```xml
536
+ <key>Text</key>
537
+ <dict>
538
+ <key>Value</key>
539
+ <dict>
540
+ <key>string</key>
541
+ <string>Name: , Age: </string>
542
+ <key>attachmentsByRange</key>
543
+ <dict>
544
+ <key>{6, 1}</key>
545
+ <dict>
546
+ <key>OutputUUID</key>
547
+ <string>UUID-FOR-NAME</string>
548
+ <key>OutputName</key>
549
+ <string>Name</string>
550
+ <key>Type</key>
551
+ <string>ActionOutput</string>
552
+ </dict>
553
+ <key>{14, 1}</key>
554
+ <dict>
555
+ <key>OutputUUID</key>
556
+ <string>UUID-FOR-AGE</string>
557
+ <key>OutputName</key>
558
+ <string>Age</string>
559
+ <key>Type</key>
560
+ <string>ActionOutput</string>
561
+ </dict>
562
+ </dict>
563
+ </dict>
564
+ <key>WFSerializationType</key>
565
+ <string>WFTextTokenString</string>
566
+ </dict>
567
+ ```
568
+
569
+ Note: Position counting includes all characters including the placeholder ``.
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" role="img" aria-label="Shortcuts-style icon in black and white">
2
+ <!-- Background (rounded app icon) -->
3
+ <rect x="0" y="0" width="200" height="200" rx="45" fill="#000"></rect>
4
+
5
+ <!-- Bottom diamond -->
6
+ <g transform="translate(100 133)">
7
+ <rect x="-44" y="-44" width="88" height="88" rx="18" fill="#d9d9d9" transform="rotate(45)"></rect>
8
+ </g>
9
+
10
+ <!-- Top diamond -->
11
+ <g transform="translate(100 74)">
12
+ <rect x="-44" y="-44" width="88" height="88" rx="18" fill="#ffffff" transform="rotate(45)"></rect>
13
+ </g>
14
+ </svg>