Kelly inquiry
Personal App-in-Skill inbound-inquiry reception desk for cross-border/foreign-trade sellers, aggregating WhatsApp, Instagram, Messenger, and email inquiries into a local pipeline with a product knowledge base, quote worksheet, approval queue, and follow-up reminders. Use when the user invokes $kelly-inquiry or /kelly-inquiry, mentions 询盘, inquiry desk, WhatsApp leads, quote management, 报价, foreign trade sales, follow-up reminders, or a lead pipeline, wants inquiries triaged into new/replied/quoted/negotiating/won/lost stages, agent-drafted replies and quotes reviewed before sending, or stale deals surfaced.From its SKILL.md
npx -y skills add mr-kelly/skills --skill kelly-inquiryAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
15.7 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it
Kelly Inquiry
Overview
Use this skill as Kelly's inbound-inquiry reception desk for foreign-trade sales. Inquiries arrive via WhatsApp, Instagram, Messenger, and email; sales reply late and leads leak. The skill aggregates them into one file-backed App-in-Skill pipeline (new → replied → quoted → negotiating → won/lost), maintains a product knowledge base + FAQ so the agent can draft accurate replies and quotes, enforces approval before anything is sent, and surfaces stale deals past the follow-up SLA.
Default interaction mode: App UI. Unless the user explicitly asks for chat-only handling, check onboarding/config, refresh or load the local inquiry snapshot, start/reuse the local app with app/start.sh, and give the actual local URL. Use chat-only mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar.
App UI Screenshots
<table> <tr> <td width="50%"><img src="assets/screenshots/overview.webp" alt="Kelly Inquiry overview"></td> <td width="50%"><img src="assets/screenshots/approvals.webp" alt="Kelly Inquiry approvals"></td> </tr> <tr> <td><strong>Overview</strong><br>Inquiry command desk with reply SLA counters, weekly channel mix, pipeline funnel, and stale-deal alerts.</td> <td><strong>Approvals</strong><br>Approval-gated outbox for replies and quotes — nothing is sent until reviewed.</td> </tr> <tr> <td width="50%"><img src="assets/screenshots/inquiries.webp" alt="Kelly Inquiry pipeline"></td> <td width="50%"><img src="assets/screenshots/quotes.webp" alt="Kelly Inquiry quotes"></td> </tr> <tr> <td><strong>Pipeline</strong><br>Inquiries across WhatsApp, Instagram, and email with country, stage, value estimate, and next follow-up.</td> <td><strong>Quotes</strong><br>Quote worksheets with line items sourced from the product KB, validity, and min-price guards.</td> </tr> </table>Boundary
- The app reads and writes local files only and never touches any network beyond
127.0.0.1. It cannot send anything: the composer queues drafts, the approvals view records verdicts. - Every outbound reply AND quote is approval-required. The skill executes only items whose approvals status is
approved, viascripts/send_approved.ts(dry-run by default), and never bypasses the dry-run →--sendsequence. - Own accounts only: read and send exclusively through accounts the user owns and has configured. Respect each platform's terms of service and rate limits; prefer official APIs; keep collection read-only.
- Never store passwords, QR-login payloads, or session tokens. For
browser_agentcollection the agent drives the user's own already-authenticated web session and stores only inquiry text needed for review. - Product and pricing data stays local. Treat customer contacts, conversation excerpts, price floors, and quotes as sensitive: do not commit
config.local.json, env files,app/.data/, exports, tokens, or customer PII.
First Run And Onboarding
On invocation, check app/.data/onboarding.json and private config readiness. If onboarding is absent/incomplete, guide setup before collecting real inquiries.
Private config priority:
KELLY_INQUIRY_CONFIG=/absolute/path/to/config.jsonskills/kelly-inquiry/config.local.json~/.config/kelly-inquiry/config.jsonskills/kelly-inquiry/config.example.jsonas template only
Env priority:
- Existing environment variables
KELLY_INQUIRY_ENV_FILE=/absolute/path/to/.env- Repository root
.env skills/kelly-inquiry/.env.local~/.config/kelly-inquiry/.env
Onboarding asks, turn by turn:
- Which channels receive inquiries (WhatsApp / Instagram / Messenger / email) and which connector method per account (see Collection Workflow). Ask for non-secret details only: channel, display name, handle, and which env var names hold the tokens. Never ask the user to paste secret values into chat; secrets belong only in local env files.
- Product KB import: a JSON or CSV file of products (SKU, MOQ, price range incl.
price_minfloors, lead time, specs, FAQ), imported viascripts/sync_products.ts. - Quote defaults: currency, validity days, incoterm/payment terms, and whether the min-price guard is enabled.
- Follow-up SLA days per stage (defaults: new 1, replied 2, quoted 3, negotiating 5).
- Reply style: tone, language policy, signature, and "do not say" guardrails.
When setup is complete and the user confirms, write app/.data/onboarding.json:
{
"completed": true,
"completed_at": "ISO timestamp",
"config_version": "1"
}
Local App
Start the app with:
skills/kelly-inquiry/app/start.sh
The app uses local HTTP on 127.0.0.1, preferring ports 3000 through 4000, or KELLY_INQUIRY_UI_PORT when set. /api/state identifies the app as kelly-inquiry.
Required app views (hash routes):
#/overview: inquiry command desk. Human-attention panel (replies/quotes awaiting approval, unanswered new inquiries, stale deals past the follow-up SLA), KPI cards (inquiries this week with channel badges, reply median time, quotes sent, win rate), a pipeline funnel summary (inline SVG bars: new→replied→quoted→negotiating→won), and an oldest-unanswered indicator.#/inquiriesand#/inquiries/<id>: the pipeline table — customer, country flag/code, channel badge, product interest, stage, value estimate, last message age, next follow-up date, owner. Detail: conversation excerpt (bubbles), customer profile (company, country, source), linked products, quote history, an agent-drafted reply with editable text plusQueue reply(goes to Approvals), and a follow-up scheduling field.#/quotesand#/quotes/<id>: quote worksheet — quote no, customer, line items, currency, validity, status (draft/sent/accepted/expired/declined). Detail: editable line items sourced from the product KB (draft quotes only), terms, and agent pricing notes with the min-price guard result from the KB floors.#/approvals: the review queue with workflow statesneeds_review/changes_requested/approved/done/blockedover outgoing replies AND quotes. Each item shows target channel + customer, the draft, reason/context, editable text, decision buttons (approve / request changes / save edit / block), and stable refs (Reply #1/Quote #2).donemeans sent, with the execution result from the execution report.#/productsand#/products/<id>: the product KB — cards with name, SKU, MOQ, price range, lead time, FAQ count; detail with specs and the FAQ entries the agent uses for drafting.#/settings: sanitized config — channels/accounts with connector method + env readiness booleans, product KB source, quote defaults (currency, validity days, min-price guard), follow-up SLA, data provider, onboarding state, sync log, and last execution report. Never secrets.
Demo mode:
?demo=overview,?demo=inquiries,?demo=quotes,?demo=approvals, and?demo=detail(opens the featured hot WhatsApp inquirywa-mueller-led-panelswith a drafted reply and a draft quote) select named deterministic mock scenes.lang=enorlang=zhforces UI chrome language for screenshots. Withlang=zhthe chrome AND agent-generated content (reasons, notes, product names, pricing notes) are localized; drafted replies and conversation quotes stay in the buyer's language. Deep links such as/?demo=detail&lang=zh#/inquiries/wa-mueller-led-panelswork.- Demo mode never reads or writes
app/.data/. Composer, approvals, follow-up, and quote-edit buttons still work but act on in-memory state only and show a demo notice.
UI language: English and Chinese chrome with Auto default following the browser language; explicit selector persisted locally. Keep customer names, message content, and drafted outbound text in their original language.
File Contract
Read references/inquiry-schema.md before editing the app, scripts, or any generated JSON.
app/.data/inquiry_snapshot.json: accounts, inquiries (with conversation excerpts), quotes, products (KB), approvals (batch items), metrics, sync log. Written only by the scripts and the app server's queue/decision/follow-up/quote endpoints.app/.data/decisions.json: user decisions and notes keyed by approval item id.app/.data/agent_tasks.json: queued agent work —revise_reply/revise_quotetasks fromrequest_changesdecisions, plusfollow_uptasks for stale deals.app/.data/execution_report.json: latest send run results.app/.data/onboarding.json: onboarding completion marker.app/.data/agent.lock: temporary lock while the skill ingests, syncs, or sends. While it exists the app rejects writes (423) and renders the composer, approvals, follow-up field, and quote editor read-only.
Validate with node scripts/validate_ui_schema.ts before relying on a snapshot in the UI.
Collection Workflow
- Detect mode. Default to App UI.
- Load private config. If only
config.example.jsonexists, enter onboarding. - Collection reuses the connector reality documented in kelly-messenger. Per account, declare a
connector:whatsapp_cloud— WhatsApp Business Cloud API (access_token_env+phone_number_id_env). Inbound messages arrive via webhook only, so history is collected via ingest payloads; sends use the Cloud API.instagram_graph/messenger_graph— Meta Graph API for professional-account DMs and Page messages (access_token_env+ig_user_id_env/page_id_env).email_agent— hand off to the kelly-email skill: it collects inquiry emails, the agent normalizes them into an ingest payload; sends go back through kelly-email drafts.browser_agent— the agent drives the user's own already-authenticated web session (e.g. WhatsApp Web, Instagram web) with the browser skill, then writes a payload. No passwords or QR secrets are ever stored.manual— the user or agent prepares an ingest payload by hand.
- All collected data enters through one write path:
node scripts/ingest_inquiries.ts payload.json. It validates the payload, dedupes by stable inquiry/message ids, merges into the snapshot, applies the stage heuristic (an outgoing reply promotesnew→replied), updates the account card and sync log, honors the agent lock, and recomputes metrics. - While drafting, the agent may attach a
suggested_replyper inquiry (prefilled in the composer) and queue reply/quote drafts intosnapshot.approvals[]withsuggested_by: "agent"and a clearreason— always grounded in the product KB and reply style, never belowprice_min. - Start/reuse the UI and report the URL. Surface connector problems as snapshot warnings, not silent failures.
Quoting Workflow
- Ground every quote in the product KB: SKU, MOQ, tier pricing inside
price_min–price_max, lead time, and FAQ facts (certificates, OEM options, dimming, packaging). Import/refresh the KB withnode scripts/sync_products.ts products.json|products.csv(zero-dependency CSV parser with quoted-field support). - Min-price guard: config
quote_defaults.min_price_guardplus per-productprice_minfloors. Any line priced below its floor raises apricing_alertsentry; withblock_below_price_minthe agent must not queue such a quote for sending — block it and ask the user instead. - Build the quote as a
draftinsnapshot.quotes[](quote no, line items, currency, validity fromvalidity_days, terms from quote defaults, pricing notes explaining the tier used and the guard result) and queue a matchingkind: "quote"approval item referencing it. - The user edits draft line items in
#/quotes/<id>(the server recomputes totals and re-runs the guard) and gives the verdict in#/approvals. - After a quote is sent, set its status to
sent; trackaccepted/expired/declinedfrom the conversation, and move the inquiry stage accordingly (quoted,negotiating,won,lost).
Approval And Send Workflow
scripts/send_approved.ts is the executor — there is no separate execute_decisions.ts.
- Queue: the user writes or edits a reply in the composer (optionally starting from the agent's
suggested_reply) and clicksQueue reply; the app appends it tosnapshot.approvals[]asneeds_review. The agent queues its own reply/quote drafts the same way. - Review: in
#/approvalsthe user approves, edits (Save edit), requests changes, or blocks each item. Decisions are mirrored intodecisions.json;request_changesenqueues arevise_reply/revise_quotetask inagent_tasks.json. - Agent revision loop: poll
agent_tasks.json, redraft the text honoring the comment, the configreply_style, and the KB (re-check the min-price guard for quotes), set the item back toneeds_review, and mark the task done. - Send: only after the user asks to send, run
node scripts/send_approved.ts(dry-run) and show the plan — planned sends, targets, and missing-token blockers. With explicit approval, runnode scripts/send_approved.ts --send: it re-checks the lock and each item's approval immediately before sending, sends API-connector items via the official APIs (WhatsApp Cloud, Instagram/Messenger Graph), marksemail_agent/browser_agent/manualitems ashandoff_to_agentfor the agent to deliver (kelly-email drafts, or the user's own web session), sets sent items todone, and writesexecution_report.json. - Report per-item results back to the user with the stable
Reply #N/Quote #Nrefs.
Follow-Up Reminders
Stale deals are how leads leak; the agent owns catching them.
- On every invocation (and after every ingest), compare each active inquiry (
new/replied/quoted/negotiating) againstfollow_up.sla_daysfor its stage and itsnext_follow_update. - For each overdue deal, append a
follow_uptask toagent_tasks.json(inquiry id, quote id if one expired, and a comment explaining which SLA was exceeded) so the queue survives interruption. - Draft the follow-up reply into the approvals batch (
suggested_by: "agent", reason citing the SLA breach and deal value), then mark the task done — the human still approves before anything is sent. - The UI surfaces the same signal: the sidebar stale-deal counter, the overview "Stale deals past follow-up SLA" panel, and red overdue dates in the pipeline table. The user can reschedule with the follow-up field in the inquiry detail (
/api/inquiries/followup). - When the user asks "what should I chase today", answer from
agent_tasks.json+ the stale list, withReply #Nrefs for anything already drafted.
Safety Defaults
- Never send without an
approvedstatus recorded in the approvals batch, and never bypass the dry-run →--sendsequence. - Never quote below a product's
price_minwithout an explicit human decision recorded on the item. - Prefer read-scoped tokens where the platform offers them; keep collection strictly read-only.
- Redact tokens and token-like strings from logs, reports, and UI state; expose only env-var readiness booleans.
- Keep sends idempotent: stable item ids, execution results stored on the item, and re-reading approvals before each send.
- If a send target is missing (
provider_conversation_id), block that item and ask for configuration instead of guessing. - Honor platform rate limits; on 429s back off rather than retrying aggressively.
What ships with it: 62 files
308.1 KB alongside SKILL.md, 29 of them executable
agents/
- openai.yaml229 B
app/
- accent-theme.css7.5 KB
- accent-theme.jsruns7.3 KB
- app.jsruns28.7 KB
- demo-visuals.css1.4 KB
- demo-visuals.jsruns4.4 KB
- i18n/messages.jsruns11.0 KB
- index.html4.6 KB
- js/commerce-views.jsruns25.6 KB
- server/demo.tsruns44.3 KB
- server/demo-visuals.tsruns12.1 KB
- server/hono.tsruns4.3 KB
- server/index.tsruns616 B
- server/launcher.tsruns2.7 KB
- server/paths.tsruns272 B
- server/setup.tsruns6.3 KB
- server/store.tsruns641 B
- server/types.tsruns215 B
- setup-gate.css4.5 KB
- setup-gate.jsruns8.8 KB
- start.shruns467 B
- styles/layers.css24 B
- styles/shell.css9.0 KB
- styles/workflow.css16.6 KB
assets/
- screenshots/approvals.webp131 B
- screenshots/approvals-zh-CN.webp131 B
- screenshots/inquiries.webp131 B
- screenshots/inquiries-zh-CN.webp131 B
- screenshots/overview.webp130 B
- screenshots/overview-zh-CN.webp130 B
- screenshots/products.webp130 B
- screenshots/products-zh-CN.webp130 B
- screenshots/quotes.webp130 B
- screenshots/quotes-zh-CN.webp130 B
- screenshots/thumbs/approvals.webp130 B
- screenshots/thumbs/approvals-zh-CN.webp130 B
- screenshots/thumbs/inquiries.webp130 B
- screenshots/thumbs/inquiries-zh-CN.webp130 B
- screenshots/thumbs/overview.webp130 B
- screenshots/thumbs/overview-zh-CN.webp130 B
22 more files not listed here. See all 62 in the repository.