Problem
lark-cli contact +search-user returns a fresh API result every time. Recipes that need to repeatedly resolve open_id ↔ display_name ↔ aliases ↔ identifiers (email/handle/employee_id) end up either:
- Re-querying
contact.users.search per call (rate-limit pressure + cost), or
- Maintaining their own JSON store on disk (every recipe reinvents schema + lookup).
The existing +chat-search for chat IDs has the same problem.
Proposed shape
A local persistent store, scoped per lark-cli config (so multi-tenant setups stay separate), with three operations:
# Add or update a contact (idempotent on open_id)
lark-cli contact +canonical-set \
--open-id ou_xxx \
--name "Full Name" \
--aliases '["FN", "Initials"]' \
--identifiers '{"email":"x@y.com","github":"handle"}'
# Look up by name, alias, or open_id (substring or exact)
lark-cli contact +canonical-lookup --query "Full" --format json
# Show one (exact open_id)
lark-cli contact +canonical-show --open-id ou_xxx --format json
Storage: SQLite or a flat JSON next to the lark-cli config dir (whichever fits the existing config conventions).
Ideally +canonical-lookup falls back to the chat-member cache when no canonical hit is found (so a recently-active chat participant resolves even before it's been canonically set).
Why now
PM/customer-success recipes need stable contact resolution across sessions. Today every recipe carries its own contacts CSV.
Problem
lark-cli contact +search-userreturns a fresh API result every time. Recipes that need to repeatedly resolveopen_id ↔ display_name ↔ aliases ↔ identifiers (email/handle/employee_id)end up either:contact.users.searchper call (rate-limit pressure + cost), orThe existing
+chat-searchfor chat IDs has the same problem.Proposed shape
A local persistent store, scoped per
lark-cliconfig (so multi-tenant setups stay separate), with three operations:Storage: SQLite or a flat JSON next to the
lark-cliconfig dir (whichever fits the existing config conventions).Ideally
+canonical-lookupfalls back to the chat-member cache when no canonical hit is found (so a recently-active chat participant resolves even before it's been canonically set).Why now
PM/customer-success recipes need stable contact resolution across sessions. Today every recipe carries its own contacts CSV.