feat: add sortContacts action - #1
Open
BTForIT wants to merge 17 commits into
Open
Conversation
Moves filterContacts from actions/contacts.cherri to actions_std.go to enable WFContentItemFilter predicate generation. This addresses electrikmilk#128 by adding support for filter conditions on contact properties. New syntax: filterContacts(contacts, "Job Title", "contains", "#All") filterContacts(contacts, "Job Title", "contains", "#{DeviceText}", "#All") The implementation: - Accepts filterProperty, filterOperator, and variadic filterValues - Generates WFContentPredicateTableTemplate with proper predicates - Supports inline variable references via WFTextTokenString - Uses OR logic (WFActionParameterFilterPrefix=0) for multiple values - Maps operator strings to Shortcuts operator codes: is=4, is not=5, contains=99, does not contain=999, begins with=8, ends with=9 - Includes decompilation support Fixes electrikmilk#128
Adds compiler warnings when: - An action output gets a generic name like "Text" or "Text 1" instead of a descriptive const name This catches a common issue where @variable = "string" creates unnamed gettext actions that show as broken references in the Shortcuts editor. Using const instead produces named outputs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changes unnamed text block detection from warning to compiler error. Using @variable = "string" now fails compilation with: Error: Unnamed text block 'Text'. Use 'const descriptiveName = ...' This prevents deploying shortcuts with broken/unnamed references that show as red text on iOS. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Notes was missing from the contactDetail enum, preventing getContactDetail(contact, "Notes") from compiling. This is needed for vCard-based launchers that use the NOTE field for routing targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Catches two cases: 1. Conditional with no comparison value at all (missing WFConditionalActionString) 2. Conditional with empty string "" as comparison value Both cases cause shortcuts to show broken conditions on iOS. Conditions 100/101 (has value/has no value) are exempt since they don't use comparison strings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds reference comment documenting the non-obvious WFCondition code mapping (2=greater than, NOT contains; 99=contains; 4=is, NOT 0). Also validates that comparison conditionals have non-empty values at compile time — catches blank WFConditionalActionString before it reaches the phone. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…kmilk#149) The rawAction check function set overrideIdentifier on the shared actions["rawAction"] definition. Since all rawAction calls share this definition, each call overwrote the previous one's identifier, causing every rawAction to compile with the LAST call's identifier. Fix: remove the shared mutation from check(), and instead set currentAction.overrideIdentifier per-call during the generation phase (shortcutgen.go), right after setCurrentAction copies the definition. This scopes the identifier to each individual call. Before: rawAction("A", {}); rawAction("B", {}) → both compile as "B" After: rawAction("A", {}); rawAction("B", {}) → "A" and "B" respectively Fixes electrikmilk#149 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…alidation" This reverts commit c826dca.
This reverts commit de11d92.
This reverts commit bb3a301.
This reverts commit 876f31a.
…ixes - Remove filterContacts comment in contacts.cherri - Remove explanatory comments in actions_std.go make/decomp functions - Rename filterProperty->property, filterOperator->operator, filterValues->values - Enum renamed from filterOperator to operator in action.go Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The toolkit DB (Tools-active) overrides .cherri-defined enum values when both exist. Some valid Shortcuts values (e.g. "Notes" for contactDetail) are defined in .cherri but missing from the DB. Previously, defineParamEnums would skip updating if the enum name already existed, effectively letting the DB values win. Now it merges both sources — DB values plus any additional values from the .cherri action definitions — so nothing gets silently dropped. This fixes getContactDetail(contact, "Notes") failing with "Invalid value 'Notes'" despite Notes being a valid WFContentItemPropertyName in Apple Shortcuts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…context
Two bugs in rawAction handling:
1. actions_std.go: getArgValue(args[1]).(map[string]interface{}) panics
when the dict is empty ({}). Empty dict literal is parsed as nil,
causing type assertion to fail. Now checks for nil and returns
empty map instead.
2. shortcutgen.go: When rawAction is used in an expression context
(e.g. const X = rawAction(...)), the overrideIdentifier was never
set, causing the action to emit with identifier
'is.workflow.actions.rawaction' instead of the user-provided one.
The fix replicates the override logic in the Variable branch of
makeVariableValue, matching what generateActions already does for
standalone rawAction statements.
Together these enable: const X = rawAction("com.apple.Foo", {})
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a separate `sortContacts(contacts, sortBy, orderBy)` action that compiles to filter.contacts with sort settings only (no filter templates). This works around the inability to add positional sort/orderBy params to the existing filterContacts action — its `values` parameter has infinite:true, so additional positional params would conflict. Chains naturally: sortContacts(All, "Last Name", "A to Z") → filterContacts with the sort preserved through filter operations. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why a separate action (not new params on filterContacts)?
`filterContacts` has `values` declared as `infinite: true` — additional positional params after it would be ambiguous. A separate `sortContacts` action is cleaner and allows natural chaining:
```cherri
const Sorted = sortContacts(AllContacts, "Last Name", "A to Z")
const Filtered = filterContacts(Sorted, "Job Title", "contains", "{tag}", "fallback")
```
Test plan
🤖 Generated with Claude Code