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,697 @@
1
+ # Content Item Filters Reference
2
+
3
+ Documentation for `WFContentItemFilter` used in Find/Filter actions like FindPhotos, FindFiles, FindReminders, etc.
4
+
5
+ ## Filter Structure
6
+
7
+ Filters are used in actions like `is.workflow.actions.filter.photos` to specify criteria for finding content.
8
+
9
+ ### Basic Filter Template
10
+
11
+ ```xml
12
+ <key>WFContentItemFilter</key>
13
+ <dict>
14
+ <key>Value</key>
15
+ <dict>
16
+ <key>WFActionParameterFilterPrefix</key>
17
+ <integer>1</integer>
18
+ <key>WFContentPredicateBoundedDate</key>
19
+ <false/>
20
+ <key>WFActionParameterFilterTemplates</key>
21
+ <array>
22
+ <!-- Filter conditions go here -->
23
+ </array>
24
+ </dict>
25
+ <key>WFSerializationType</key>
26
+ <string>WFContentPredicateTableTemplate</string>
27
+ </dict>
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Operator Reference
33
+
34
+ Operators define the comparison type. These were discovered from Shortcuts internal JavaScript:
35
+
36
+ | Operator | Meaning | Use Case |
37
+ |----------|---------|----------|
38
+ | 2 | `is after` | Date is after a date/token |
39
+ | 3 | `>=` | Greater than or equal |
40
+ | 4 | `is` | Exact match |
41
+ | 5 | `is not` | Not equal |
42
+ | 8 | `begins with` | String prefix |
43
+ | 9 | `ends with` | String suffix |
44
+ | 99 | `contains` | String contains |
45
+ | 100 | `has any value` | Not empty |
46
+ | 101 | `does not have any value` | Is empty |
47
+ | 999 | `does not contain` | String not contains |
48
+ | 1000 | `is in the next` | Future date range |
49
+ | 1001 | `is in the last` | Past date range |
50
+ | 1002 | `is today` | Date is today |
51
+ | 1003 | `is between` | Date range |
52
+
53
+ ---
54
+
55
+ ## Unit Reference
56
+
57
+ Units are used with date/time and enumeration filters:
58
+
59
+ ### Date Units (for operators 1000, 1001)
60
+
61
+ | Unit | Meaning |
62
+ |------|---------|
63
+ | 4 | years |
64
+ | 8 | months |
65
+ | 8192 | weeks |
66
+ | 16384 | days |
67
+
68
+ ### Boolean/Enum Unit
69
+
70
+ | Unit | Context |
71
+ |------|---------|
72
+ | 4 | Standard unit for boolean and enumeration values |
73
+
74
+ ---
75
+
76
+ ## Filter Templates by Type
77
+
78
+ ### Boolean Filter (e.g., Is a Screenshot)
79
+
80
+ ```xml
81
+ <dict>
82
+ <key>Operator</key>
83
+ <integer>4</integer>
84
+ <key>Property</key>
85
+ <string>Is a Screenshot</string>
86
+ <key>Removable</key>
87
+ <true/>
88
+ <key>Values</key>
89
+ <dict>
90
+ <key>Bool</key>
91
+ <true/>
92
+ <key>Unit</key>
93
+ <integer>4</integer>
94
+ </dict>
95
+ </dict>
96
+ ```
97
+
98
+ ### "Is Today" Date Filter
99
+
100
+ The `is today` operator (1002) does NOT require Values:
101
+
102
+ ```xml
103
+ <dict>
104
+ <key>Operator</key>
105
+ <integer>1002</integer>
106
+ <key>Property</key>
107
+ <string>Date Taken</string>
108
+ <key>Removable</key>
109
+ <true/>
110
+ </dict>
111
+ ```
112
+
113
+ ### Find Calendar Events: Next Event After Now
114
+
115
+ For **Find Calendar Events** date predicates, use the date-specific operator codes. Do not use numeric comparison codes such as `3` (`>=`) for `Start Date` or `End Date`; Shortcuts can import that as a red invalid condition. The common "next event after now" pattern is:
116
+
117
+ - `Start Date is today`: `Operator = 1002`, `Values = {}`.
118
+ - `Start Date is after Current Date`: `Operator = 2`, `Values.Date = CurrentDate` token.
119
+ - Sort by `Start Date`, `Oldest First`, limit to `1`.
120
+
121
+ ```xml
122
+ <dict>
123
+ <key>Operator</key>
124
+ <integer>1002</integer>
125
+ <key>Property</key>
126
+ <string>Start Date</string>
127
+ <key>Removable</key>
128
+ <true/>
129
+ <key>Values</key>
130
+ <dict/>
131
+ </dict>
132
+ <dict>
133
+ <key>Operator</key>
134
+ <integer>2</integer>
135
+ <key>Property</key>
136
+ <string>Start Date</string>
137
+ <key>Removable</key>
138
+ <true/>
139
+ <key>Values</key>
140
+ <dict>
141
+ <key>Date</key>
142
+ <dict>
143
+ <key>Value</key>
144
+ <dict>
145
+ <key>Type</key>
146
+ <string>CurrentDate</string>
147
+ </dict>
148
+ <key>WFSerializationType</key>
149
+ <string>WFTextTokenAttachment</string>
150
+ </dict>
151
+ </dict>
152
+ </dict>
153
+ ```
154
+
155
+ ### Find Health Samples "Start Date Is Today" Filter
156
+
157
+ Verified from a manually created iOS Shortcuts XML example and generated shortcut failures. **Find Health Samples** uses the same `WFContentPredicateTableTemplate` wrapper, but the Health sample kind is a locked `Type` predicate row backed by an enumeration state. Do not use top-level `WFHealthQuantityType`, and do not use a `Value` predicate row with `Values.String`; current iOS Shortcuts renders that as an editable text filter instead of the Health type picker.
158
+
159
+ Use observed Find Health Samples picker labels. Examples: `Steps`, `Sleep`, `Walking + Running Distance`, `Active Calories`, and `Exercise Minutes`. Do not use SDK-derived labels such as `Sleep Analysis`, `Active Energy`, `Active Energy Burned`, or `Apple Exercise Time`.
160
+
161
+ ```xml
162
+ <key>WFContentItemFilter</key>
163
+ <dict>
164
+ <key>Value</key>
165
+ <dict>
166
+ <key>WFActionParameterFilterPrefix</key>
167
+ <integer>1</integer>
168
+ <key>WFContentPredicateBoundedDate</key>
169
+ <false/>
170
+ <key>WFActionParameterFilterTemplates</key>
171
+ <array>
172
+ <dict>
173
+ <key>Bounded</key>
174
+ <true/>
175
+ <key>Operator</key>
176
+ <integer>4</integer>
177
+ <key>Property</key>
178
+ <string>Type</string>
179
+ <key>Removable</key>
180
+ <false/>
181
+ <key>Values</key>
182
+ <dict>
183
+ <key>Enumeration</key>
184
+ <dict>
185
+ <key>Value</key>
186
+ <string>Steps</string>
187
+ <key>WFSerializationType</key>
188
+ <string>WFStringSubstitutableState</string>
189
+ </dict>
190
+ </dict>
191
+ </dict>
192
+ <dict>
193
+ <key>Bounded</key>
194
+ <true/>
195
+ <key>Operator</key>
196
+ <integer>1002</integer>
197
+ <key>Property</key>
198
+ <string>Start Date</string>
199
+ <key>Removable</key>
200
+ <false/>
201
+ <key>Values</key>
202
+ <dict>
203
+ <key>Number</key>
204
+ <string>7</string>
205
+ <key>Unit</key>
206
+ <integer>16</integer>
207
+ </dict>
208
+ </dict>
209
+ </array>
210
+ </dict>
211
+ <key>WFSerializationType</key>
212
+ <string>WFContentPredicateTableTemplate</string>
213
+ </dict>
214
+ ```
215
+
216
+ ### "Is in the Last X" Date Filter
217
+
218
+ The `is in the last` operator (1001) requires Number and Unit:
219
+
220
+ ```xml
221
+ <dict>
222
+ <key>Operator</key>
223
+ <integer>1001</integer>
224
+ <key>Property</key>
225
+ <string>Date Taken</string>
226
+ <key>Removable</key>
227
+ <true/>
228
+ <key>Values</key>
229
+ <dict>
230
+ <key>Number</key>
231
+ <integer>1</integer>
232
+ <key>Unit</key>
233
+ <integer>8192</integer> <!-- weeks -->
234
+ </dict>
235
+ </dict>
236
+ ```
237
+
238
+ ### "Is Between" Date Filter (verified against an Apple-built sample)
239
+
240
+ The `is between` operator (1003), **for date properties**, uses two value keys: `Date` for the lower bound (literal ISO date) and `AnotherDate` for the upper bound (token attachment, commonly `{Type: "CurrentDate"}` or another date variable):
241
+
242
+ ```xml
243
+ <dict>
244
+ <key>Operator</key>
245
+ <integer>1003</integer>
246
+ <key>Property</key>
247
+ <string>Due Date</string>
248
+ <key>Removable</key>
249
+ <true/>
250
+ <key>Values</key>
251
+ <dict>
252
+ <key>Date</key>
253
+ <date>2026-04-13T09:54:12Z</date>
254
+ <key>AnotherDate</key>
255
+ <dict>
256
+ <key>Value</key>
257
+ <dict>
258
+ <key>Type</key>
259
+ <string>CurrentDate</string>
260
+ </dict>
261
+ <key>WFSerializationType</key>
262
+ <string>WFTextTokenAttachment</string>
263
+ </dict>
264
+ </dict>
265
+ </dict>
266
+ ```
267
+
268
+ ⚠️ **Date filter `1003` ≠ numeric If conditional `1003`.** The If conditional version uses `WFNumberValue` + `WFAnotherNumber`. Filter-table version uses `Values.Date` + `Values.AnotherDate`. Do NOT copy one structure into the other.
269
+
270
+ ### Enumeration Filter (e.g., Media Type)
271
+
272
+ **IMPORTANT**: Media Type only accepts: `Image`, `Video`, `Live Photo`
273
+ Do NOT use `Screenshot` - use the `Is a Screenshot` boolean filter instead.
274
+
275
+ ```xml
276
+ <dict>
277
+ <key>Operator</key>
278
+ <integer>4</integer>
279
+ <key>Property</key>
280
+ <string>Media Type</string>
281
+ <key>Removable</key>
282
+ <true/>
283
+ <key>Values</key>
284
+ <dict>
285
+ <key>Unit</key>
286
+ <integer>4</integer>
287
+ <key>Enumeration</key>
288
+ <dict>
289
+ <key>Value</key>
290
+ <string>Image</string>
291
+ <key>WFSerializationType</key>
292
+ <string>WFStringSubstitutableState</string>
293
+ </dict>
294
+ </dict>
295
+ </dict>
296
+ ```
297
+
298
+ ### String Filter (e.g., Album name)
299
+
300
+ ```xml
301
+ <dict>
302
+ <key>Operator</key>
303
+ <integer>4</integer>
304
+ <key>Property</key>
305
+ <string>Album</string>
306
+ <key>Removable</key>
307
+ <true/>
308
+ <key>Values</key>
309
+ <dict>
310
+ <key>String</key>
311
+ <string>Favorites</string>
312
+ <key>Unit</key>
313
+ <integer>4</integer>
314
+ </dict>
315
+ </dict>
316
+ ```
317
+
318
+ ---
319
+
320
+ ## FindPhotos Complete Example
321
+
322
+ Find screenshots taken today:
323
+
324
+ ```xml
325
+ <dict>
326
+ <key>WFWorkflowActionIdentifier</key>
327
+ <string>is.workflow.actions.filter.photos</string>
328
+ <key>WFWorkflowActionParameters</key>
329
+ <dict>
330
+ <key>UUID</key>
331
+ <string>FIND-PHOTOS-UUID</string>
332
+ <key>WFContentItemFilter</key>
333
+ <dict>
334
+ <key>Value</key>
335
+ <dict>
336
+ <key>WFActionParameterFilterPrefix</key>
337
+ <integer>1</integer>
338
+ <key>WFContentPredicateBoundedDate</key>
339
+ <false/>
340
+ <key>WFActionParameterFilterTemplates</key>
341
+ <array>
342
+ <!-- Is a Screenshot = true -->
343
+ <dict>
344
+ <key>Operator</key>
345
+ <integer>4</integer>
346
+ <key>Property</key>
347
+ <string>Is a Screenshot</string>
348
+ <key>Removable</key>
349
+ <true/>
350
+ <key>Values</key>
351
+ <dict>
352
+ <key>Bool</key>
353
+ <true/>
354
+ <key>Unit</key>
355
+ <integer>4</integer>
356
+ </dict>
357
+ </dict>
358
+ <!-- Date Taken is today -->
359
+ <dict>
360
+ <key>Operator</key>
361
+ <integer>1002</integer>
362
+ <key>Property</key>
363
+ <string>Date Taken</string>
364
+ <key>Removable</key>
365
+ <true/>
366
+ </dict>
367
+ </array>
368
+ </dict>
369
+ <key>WFSerializationType</key>
370
+ <string>WFContentPredicateTableTemplate</string>
371
+ </dict>
372
+ <key>WFContentItemSortProperty</key>
373
+ <string>Date Taken</string>
374
+ <key>WFContentItemSortOrder</key>
375
+ <string>Latest First</string>
376
+ </dict>
377
+ </dict>
378
+ ```
379
+
380
+ ---
381
+
382
+ ## DeletePhotos Action
383
+
384
+ **CRITICAL**: DeletePhotos uses `photos` as the parameter key, NOT `WFInput`:
385
+
386
+ ```xml
387
+ <dict>
388
+ <key>WFWorkflowActionIdentifier</key>
389
+ <string>is.workflow.actions.deletephotos</string>
390
+ <key>WFWorkflowActionParameters</key>
391
+ <dict>
392
+ <key>UUID</key>
393
+ <string>DELETE-UUID</string>
394
+ <key>photos</key>
395
+ <dict>
396
+ <key>Value</key>
397
+ <dict>
398
+ <key>OutputName</key>
399
+ <string>Photos</string>
400
+ <key>OutputUUID</key>
401
+ <string>FIND-PHOTOS-UUID</string>
402
+ <key>Type</key>
403
+ <string>ActionOutput</string>
404
+ </dict>
405
+ <key>WFSerializationType</key>
406
+ <string>WFTextTokenAttachment</string>
407
+ </dict>
408
+ </dict>
409
+ </dict>
410
+ ```
411
+
412
+ ---
413
+
414
+ ## Available Filter Properties by Content Type
415
+
416
+ ### Photos (WFPhotoMediaContentItem)
417
+
418
+ | Property | Type | Values |
419
+ |----------|------|--------|
420
+ | `Album` | Enumeration | Album names |
421
+ | `Media Type` | Enumeration | `Image`, `Video`, `Live Photo` |
422
+ | `Is a Screenshot` | Boolean | true/false |
423
+ | `Is Hidden` | Boolean | true/false |
424
+ | `Is Favorite` | Boolean | true/false |
425
+ | `Date Taken` | Date | Use date operators |
426
+ | `Creation Date` | Date | Use date operators |
427
+ | `Width` | Number | Pixels |
428
+ | `Height` | Number | Pixels |
429
+ | `Orientation` | Enumeration | `Up`, `Down`, `Left`, `Right` |
430
+ | `Photo Type` | Enumeration | `HDR`, `Panorama`, etc. |
431
+ | `Frame Rate` | Number | FPS (for videos) |
432
+ | `Duration` | Number | Seconds (for videos) |
433
+ | `Camera Make` | String | Camera manufacturer |
434
+ | `Camera Model` | String | Camera model |
435
+ | `File Extension` | String | e.g., `png`, `jpg` |
436
+
437
+ ### Files (WFGenericFileContentItem)
438
+
439
+ | Property | Type | Values |
440
+ |----------|------|--------|
441
+ | `Name` | String | Filename |
442
+ | `File Extension` | String | Extension without dot |
443
+ | `Creation Date` | Date | Use date operators |
444
+ | `File Size` | Number | Bytes |
445
+ | `Last Modified Date` | Date | Use date operators |
446
+
447
+ ### Notes (WFNoteContentItem)
448
+
449
+ | Property | Type | Supported Operators |
450
+ |----------|------|---------------------|
451
+ | `Name` | String | **Contains (99) only** — see critical note below |
452
+ | `Body` | String | Contains (99), Does Not Contain (999) |
453
+ | `Creation Date` | Date | Use date operators |
454
+ | `Last Modified Date` | Date | Use date operators |
455
+ | `Folder` | Enumeration | Folder names |
456
+
457
+ > **CRITICAL — Name filter operator:**
458
+ > Find Notes actions only support operator `99` (contains) for `Name` matching.
459
+ > Using operator `4` (is/exact match) produces an **empty result set at runtime** — the filter silently fails.
460
+ > Always use operator `99` when searching notes by name, even when you want an exact title match.
461
+
462
+ ```xml
463
+ <!-- CORRECT: Name contains -->
464
+ <key>WFFilterOperator</key>
465
+ <integer>99</integer>
466
+
467
+ <!-- WRONG: Name is — fails silently, returns nothing -->
468
+ <key>WFFilterOperator</key>
469
+ <integer>4</integer>
470
+ ```
471
+
472
+ ### Reminders (WFReminderContentItem)
473
+
474
+ | Property | Type | Values |
475
+ |----------|------|--------|
476
+ | `Title` | String | Reminder title |
477
+ | `Is Completed` | Boolean | `{ Bool: <true/false> }` — no `Unit` key (Reminders Boolean filters don't use it) |
478
+ | `Is Flagged` | Boolean | Same shape as Is Completed |
479
+ | `Priority` | Enumeration | `None`, `Low`, `Medium`, `High` |
480
+ | `Due Date` | Date | Use date operators (1000–1003) |
481
+ | `Creation Date` | Date | Use date operators |
482
+ | `List` | Enumeration | List names — match via operator `4` with `Values.Enumeration` |
483
+
484
+ ⚠️ **Reminders Boolean filters skip `Unit: 4`.** Photos Boolean filters (e.g. `Is a Screenshot`) do require `Values = { Bool: <true/false>, Unit: 4 }`. Reminders Boolean filters use `Values = { Bool: <true/false> }` only — no `Unit` field. Verified against an Apple-built sample.
485
+
486
+ **"Is Completed = Yes" (find completed reminders):**
487
+
488
+ ```xml
489
+ <dict>
490
+ <key>WFWorkflowActionIdentifier</key>
491
+ <string>is.workflow.actions.filter.reminders</string>
492
+ <key>WFWorkflowActionParameters</key>
493
+ <dict>
494
+ <key>UUID</key>
495
+ <string>FIND-COMPLETED-UUID</string>
496
+ <key>WFContentItemFilter</key>
497
+ <dict>
498
+ <key>Value</key>
499
+ <dict>
500
+ <key>WFActionParameterFilterPrefix</key>
501
+ <integer>1</integer>
502
+ <key>WFActionParameterFilterTemplates</key>
503
+ <array>
504
+ <dict>
505
+ <key>Operator</key>
506
+ <integer>4</integer>
507
+ <key>Property</key>
508
+ <string>Is Completed</string>
509
+ <key>Removable</key>
510
+ <true/>
511
+ <key>Values</key>
512
+ <dict>
513
+ <key>Bool</key>
514
+ <true/>
515
+ </dict>
516
+ </dict>
517
+ </array>
518
+ <key>WFContentPredicateBoundedDate</key>
519
+ <false/>
520
+ </dict>
521
+ <key>WFSerializationType</key>
522
+ <string>WFContentPredicateTableTemplate</string>
523
+ </dict>
524
+ </dict>
525
+ </dict>
526
+ ```
527
+
528
+ **"Is Completed = No" (find incomplete reminders):** same action, same structure, only `Values.Bool` flips to `<false/>`.
529
+
530
+ ### Find vs Filter: `WFContentItemInputParameter`
531
+
532
+ Shortcuts.app shows two variants in the UI:
533
+ - **"Find X where"** — queries the system's content database for the type (e.g., all reminders, all photos) matching the filter.
534
+ - **"Filter X where"** — applies the filter to the output of a preceding action, trimming down an already-collected list.
535
+
536
+ Both variants use the **same action identifier** (`is.workflow.actions.filter.<type>`). The difference is the presence of `WFContentItemInputParameter`:
537
+
538
+ - **Find** = no `WFContentItemInputParameter`. The filter operates on the system database.
539
+ - **Filter** = `WFContentItemInputParameter` set to a token attachment wrapping the previous action's `ActionOutput` (typically with `OutputName` matching the type — e.g., `"Reminders"`, `"Photos"`, `"Files"`).
540
+
541
+ **Chained "Filter Reminders where Is Completed = No" on the output of a preceding "Find Reminders where Is Completed = Yes":**
542
+
543
+ ```xml
544
+ <dict>
545
+ <key>WFWorkflowActionIdentifier</key>
546
+ <string>is.workflow.actions.filter.reminders</string>
547
+ <key>WFWorkflowActionParameters</key>
548
+ <dict>
549
+ <key>UUID</key>
550
+ <string>FILTER-INCOMPLETE-UUID</string>
551
+ <key>WFContentItemFilter</key>
552
+ <dict>
553
+ <key>Value</key>
554
+ <dict>
555
+ <key>WFActionParameterFilterPrefix</key>
556
+ <integer>1</integer>
557
+ <key>WFActionParameterFilterTemplates</key>
558
+ <array>
559
+ <dict>
560
+ <key>Operator</key>
561
+ <integer>4</integer>
562
+ <key>Property</key>
563
+ <string>Is Completed</string>
564
+ <key>Removable</key>
565
+ <true/>
566
+ <key>Values</key>
567
+ <dict>
568
+ <key>Bool</key>
569
+ <false/>
570
+ </dict>
571
+ </dict>
572
+ </array>
573
+ <key>WFContentPredicateBoundedDate</key>
574
+ <false/>
575
+ </dict>
576
+ <key>WFSerializationType</key>
577
+ <string>WFContentPredicateTableTemplate</string>
578
+ </dict>
579
+ <key>WFContentItemInputParameter</key>
580
+ <dict>
581
+ <key>Value</key>
582
+ <dict>
583
+ <key>OutputName</key>
584
+ <string>Reminders</string>
585
+ <key>OutputUUID</key>
586
+ <string>PREVIOUS-FILTER-REMINDERS-UUID</string>
587
+ <key>Type</key>
588
+ <string>ActionOutput</string>
589
+ </dict>
590
+ <key>WFSerializationType</key>
591
+ <string>WFTextTokenAttachment</string>
592
+ </dict>
593
+ </dict>
594
+ </dict>
595
+ ```
596
+
597
+ The same `WFContentItemInputParameter` chaining pattern applies to `filter.photos`, `filter.files`, `filter.notes`, `filter.calendarevents`, and every other `filter.*` action — wire it to a previous action's output via `Type=ActionOutput` and the filter becomes a "Filter X" instead of a "Find X".
598
+
599
+ **Reminders-specific filter example (verified from an Apple-built sample). Any-are-true OR of: List is "Reminders" OR Due Date is today OR Due Date is between a literal date and Current Date:**
600
+
601
+ **Reminders-specific filter example (verified from an Apple-built sample). Any-are-true OR of: List is "Reminders" OR Due Date is today OR Due Date is between a literal date and Current Date:**
602
+
603
+ ```xml
604
+ <dict>
605
+ <key>WFWorkflowActionIdentifier</key>
606
+ <string>is.workflow.actions.filter.reminders</string>
607
+ <key>WFWorkflowActionParameters</key>
608
+ <dict>
609
+ <key>UUID</key>
610
+ <string>FIND-REMINDERS-UUID</string>
611
+ <key>WFContentItemFilter</key>
612
+ <dict>
613
+ <key>Value</key>
614
+ <dict>
615
+ <key>WFActionParameterFilterPrefix</key>
616
+ <integer>0</integer>
617
+ <key>WFActionParameterFilterTemplates</key>
618
+ <array>
619
+ <dict>
620
+ <key>Operator</key>
621
+ <integer>4</integer>
622
+ <key>Property</key>
623
+ <string>List</string>
624
+ <key>Removable</key>
625
+ <true/>
626
+ <key>Values</key>
627
+ <dict>
628
+ <key>Enumeration</key>
629
+ <dict>
630
+ <key>Value</key>
631
+ <string>Reminders</string>
632
+ <key>WFSerializationType</key>
633
+ <string>WFStringSubstitutableState</string>
634
+ </dict>
635
+ </dict>
636
+ </dict>
637
+ <dict>
638
+ <key>Operator</key>
639
+ <integer>1002</integer>
640
+ <key>Property</key>
641
+ <string>Due Date</string>
642
+ <key>Removable</key>
643
+ <true/>
644
+ <key>Values</key>
645
+ <dict/>
646
+ </dict>
647
+ <dict>
648
+ <key>Operator</key>
649
+ <integer>1003</integer>
650
+ <key>Property</key>
651
+ <string>Due Date</string>
652
+ <key>Removable</key>
653
+ <true/>
654
+ <key>Values</key>
655
+ <dict>
656
+ <key>Date</key>
657
+ <date>2026-04-13T09:54:12Z</date>
658
+ <key>AnotherDate</key>
659
+ <dict>
660
+ <key>Value</key>
661
+ <dict>
662
+ <key>Type</key>
663
+ <string>CurrentDate</string>
664
+ </dict>
665
+ <key>WFSerializationType</key>
666
+ <string>WFTextTokenAttachment</string>
667
+ </dict>
668
+ </dict>
669
+ </dict>
670
+ </array>
671
+ <key>WFContentPredicateBoundedDate</key>
672
+ <false/>
673
+ </dict>
674
+ <key>WFSerializationType</key>
675
+ <string>WFContentPredicateTableTemplate</string>
676
+ </dict>
677
+ </dict>
678
+ </dict>
679
+ ```
680
+
681
+ For the editing side (`is.workflow.actions.setters.reminders`), see [PARAMETER_TYPES.md → Reminders — Filter & Setter Schemas](PARAMETER_TYPES.md#reminders--filter--setter-schemas-definitive) for the complete list of property names and their value keys.
682
+
683
+ ---
684
+
685
+ ## Common Mistakes to Avoid
686
+
687
+ 1. **Using `media_type="Screenshot"`** - This is WRONG. Use `Is a Screenshot` boolean filter instead.
688
+
689
+ 2. **Using Operator 4 for "is today"** - WRONG. Use Operator 1002.
690
+
691
+ 3. **Using `WFInput` for DeletePhotos** - WRONG. Use `photos` (lowercase).
692
+
693
+ 4. **Adding Values to "is today" filter** - WRONG. Operator 1002 doesn't need Values.
694
+
695
+ 5. **Forgetting OutputUUID reference** - When passing results between actions, you must reference the source action's UUID.
696
+
697
+ 6. **Using Operator 4 (is) for Find Notes Name filter** - WRONG. Operator 4 produces empty results at runtime. Always use Operator 99 (contains) for Note name matching.