Summary
Build a template auto-generator that produces working JXA templates directly from sdef class/property definitions. This covers ~60-70% of operations for any macOS app adapter and is the highest-ROI automation for the pipeline.
Context
During the Apple Mail adapter build, we found that most READ and UPDATE operations follow a predictable pattern derivable from the sdef:
sdef: <class name="mailbox"><property name="unread count" type="integer"/></class>
generates: account.mailboxes.byName(specifier).unreadCount()
The pattern for property reads:
{parent}.{class_plural}.byName({{specifier}}).{camelCase(property)}()
The pattern for property writes:
{parent}.{class_plural}.byName({{specifier}}).{camelCase(property)} = {{value}};
The pattern for element listings:
var items = {parent}.{class_plural}.byName({{specifier}}).{element_plural}();
// iterate with index, NOT batch
for (var i = 0; i < Math.min(items.length, limit); i++) { ... }
What to Build
Template Generator Module (src/template-generator.ts)
Input: Parsed sdef (from sdef-parser.ts) — classes, properties, elements, types
Output: templates.json with working JXA for each operation
Transformations Needed
- Property name → JXA accessor:
"unread count" → unreadCount() (camelCase, remove spaces)
- Class name → JXA plural accessor:
"account" → accounts, "mailbox" → mailboxes
- Type mapping: sdef
type="integer" → template param {"type": "integer"}
- Access chain inference: sdef class hierarchy tells us
mailbox is an element of account, so the access chain is mail.accounts.byName(x).mailboxes.byName(y)
- Read vs write: sdef
access="r" → READ template only; access="rw" → READ + UPDATE templates
Hierarchy Resolution
The sdef defines containment:
<class name="account"><element type="mailbox"/></class>
<class name="mailbox"><element type="message"/></class>
The generator must resolve the full access chain:
message.subject → mail.accounts.byName(a).mailboxes.byName(m).messages[i].subject()
mailbox.unreadCount → mail.accounts.byName(a).mailboxes.byName(m).unreadCount()
account.name → mail.accounts.byName(a).name()
Performance-Safe Patterns
CRITICAL: The generator MUST use the index iterator pattern for element listings, NOT batch reads or whose filters. From Apple Mail testing:
| Pattern |
Scales to |
Use |
items[i].property() |
Any size |
✅ Always use |
items.property() (batch) |
~500 items |
❌ Never use |
items.whose({...}) |
~500 items |
❌ Never for large collections |
CLI Extension
mcpaql-sdef-interrogate --app Mail --out /tmp/pipeline --generate-templates
The --generate-templates flag runs the template generator after sdef parsing, producing templates.json alongside the discovery bundle.
Acceptance Criteria
References
Summary
Build a template auto-generator that produces working JXA templates directly from sdef class/property definitions. This covers ~60-70% of operations for any macOS app adapter and is the highest-ROI automation for the pipeline.
Context
During the Apple Mail adapter build, we found that most READ and UPDATE operations follow a predictable pattern derivable from the sdef:
The pattern for property reads:
The pattern for property writes:
The pattern for element listings:
What to Build
Template Generator Module (
src/template-generator.ts)Input: Parsed sdef (from
sdef-parser.ts) — classes, properties, elements, typesOutput:
templates.jsonwith working JXA for each operationTransformations Needed
"unread count"→unreadCount()(camelCase, remove spaces)"account"→accounts,"mailbox"→mailboxestype="integer"→ template param{"type": "integer"}mailboxis an element ofaccount, so the access chain ismail.accounts.byName(x).mailboxes.byName(y)access="r"→ READ template only;access="rw"→ READ + UPDATE templatesHierarchy Resolution
The sdef defines containment:
The generator must resolve the full access chain:
message.subject→mail.accounts.byName(a).mailboxes.byName(m).messages[i].subject()mailbox.unreadCount→mail.accounts.byName(a).mailboxes.byName(m).unreadCount()account.name→mail.accounts.byName(a).name()Performance-Safe Patterns
CRITICAL: The generator MUST use the index iterator pattern for element listings, NOT batch reads or
whosefilters. From Apple Mail testing:items[i].property()items.property()(batch)items.whose({...})CLI Extension
The
--generate-templatesflag runs the template generator after sdef parsing, producingtemplates.jsonalongside the discovery bundle.Acceptance Criteria
TemplateOverridesDocumentfrom adapter-generator typesReferences
src/plugins/transport/apple-mail-templates.tssrc/sdef-parser.ts