AI agents for automating Cut+Dry distributor onboarding tasks.
Smith automates the entire app store submission screenshot pipeline for Cut+Dry white-label apps. Given a distributor URL, it logs into the app, captures screenshots across three device sizes, composites them into on-brand marketing images with device frames and marketing titles, finds or creates a Jira ticket under the epic you provide, attaches all assets to that ticket, and posts progress to Slack.
Time saved: 2-3 hours → ~15 minutes per distributor.
- Reads prior learnings from
~/.claude/agents/learnings/smith-learnings.mdand applies known workarounds - Captures 18 screenshots — 6 pages (home, order guide, catalog, order history, chat, order check-in) at 3 device sizes (iPhone 6.5", iPad 12.9", Android)
- Generates composites — device-framed marketing images sized for App Store and Play Store, with brand color background, marketing titles, and automatic dark/light color handling
- Finds or creates the Jira ticket — first searches the epic for an existing "Submit mobile apps live" task and reuses it; only creates a new one if none exists
- Attaches composites to the ticket via the Jira REST API
- Pings Slack at each checkpoint (start, capture complete, composites ready, done, or on failure)
- Appends a new learnings entry so the next run inherits any fixes or quirks discovered
onboarding-agents/
├── README.md (this file)
└── smith/
├── smith.md Agent definition (uses SMITH_PATH placeholder)
├── smith-learnings.md Seed learnings from ~15 prior runs
├── package.json npm entry, playwright dep, postinstall hook
├── install.sh Manual install script (postinstall runs the same steps)
├── bin/smith.js smith CLI entrypoint
├── screenshot-templates/
│ ├── capture.mjs Playwright login + page capture
│ ├── generate.mjs Composite generator (device frames + titles)
│ ├── compose.html HTML template for phone/tablet composites
│ ├── feature-graphic.html HTML template for Play Store feature graphic
│ ├── frames/ iphone.png, android.png, ipad.png device frames
│ ├── verify-training.mjs Utility: verify screenshots for training set
│ ├── wl-refactor.mjs Utility: white-label refactor helper
│ ├── find-order.mjs Utility: dynamic order-id resolver
│ └── android-template.html Alt Android composite template
└── outputs/ (gitignored) progress log + generated screenshots
Screenshots and composites for each distributor land at smith/{DistributorName}/{android,ios,ipad,Iphone 6.5,Ipad 12.9,Android}/ inside the clone. These directories are gitignored per distributor.
- Node.js v18 or higher
- Claude Code (CLI, desktop, or IDE extension)
- Atlassian MCP connected in Claude Code (for Jira create/search)
- Slack MCP connected in Claude Code (for progress notifications; optional but recommended)
git clone https://github.com/eshandeane/onboarding-agents.git
cd onboarding-agents/smith
npm installnpm install runs a postinstall hook that automatically:
- Installs Node dependencies (
playwright) - Downloads Chromium to
~/Library/Caches/ms-playwright/ - Substitutes
SMITH_PATHinsmith.mdwith the absolute clone path - Copies the substituted agent definition to
~/.claude/agents/smith.md - Symlinks
bin/smith.jsinto$(npm config get prefix)/bin/smithsosmithis on PATH
Scripts, device frames, and generated screenshots stay in the cloned repo directory. Only the substituted agent definition is placed into ~/.claude/agents/.
If postinstall fails (e.g., permissions on the npm prefix), run ./install.sh from smith/ to re-run the same steps manually.
Atlassian (required for Jira ticket create/search):
claude mcp add --transport http atlassian https://mcp.atlassian.com/v1/mcpAuthenticate when prompted in Claude Code.
Slack (required for progress pings — the agent hardcodes channel DL88SS3EU, which is Eshan's DM; change this in smith.md before running as a new engineer):
Add the Slack MCP per the Claude Code MCP docs and authenticate.
Jira REST attachments: Step 7 in smith.md shells out to curl to attach PNGs to the ticket. Export JIRA_EMAIL and JIRA_TOKEN in your shell environment, or the agent will attempt to read them from ~/.claude/.mcp.json.
From anywhere in your terminal:
smithThe CLI prompts for the app URL and then launches Claude Code with the smith agent. You can also pass the URL directly:
smith https://hillcrest.cutanddry.comInside Claude Code, Smith will ask (via AskUserQuestion) for:
- Login email + password for the app
- Jira epic key (e.g.
DOT-12345) - App name (e.g. "Hillcrest Foodservice")
- Brand color hex (e.g.
#E87722)
Then walk away. Progress streams to Slack and smith/outputs/screensmith-progress.log.
Composites are saved to smith/{DistributorName}/{android,ios,ipad}/ and attached to the Jira ticket.
| Asset | Size |
|---|---|
| iPhone 6.5" | 1284 × 2778 |
| iPad 12.9" | 2048 × 2732 |
| Android | 1080 × 1920 |
| Feature Graphic | 1024 × 500 |
Smith posts five message types to the channel configured in smith.md:
- Started (immediately after inputs collected)
- Capture complete (with per-page WARNING list if any)
- Composites ready (with per-device counts)
- Done (with Jira URL + folder path)
- Failed (with error message + failed step)
generate.mjs picks a background/text pairing based on relative luminance:
- Dark colors (luminance < 0.35, e.g.,
#000000,#25232a): white background, brand-colored title text - Light colors (luminance > 0.85, e.g., cream, off-white like
#fff7e1): brand background, dark title text (#1a1a1a) - Everything else: brand background, white title text
Smith is designed to get better with every run.
On start (Phase 0): Smith reads ~/.claude/agents/learnings/smith-learnings.md and applies any prior fixes (login workarounds, timing issues, MCP quirks, per-app credential notes).
On finish: Smith appends a new entry to the same file with capture issues, app-specific quirks, process improvements, and Jira integration notes.
The seed file smith/smith-learnings.md ships with ~15 real prior runs (MGP, Bizzup, South Asian Food, Valley Gold, Spokane Produce, Williams, Sierra Meat, Downeast Coffee, Marin-Sonoma, Midwest Global Imports, AFBS, Pacific Produce). Copy it to the shared location on first install:
cp smith/smith-learnings.md ~/.claude/agents/learnings/smith-learnings.mdhttp://in the app URL breaks login — the HTTP→HTTPS redirect leaves agent-browser onabout:blank. Always normalize tohttps://before settingbaseUrl.- Order check-in requires an order in the account — the script auto-expands the order history filter from 30 → 90 days if empty. If the account has zero orders in the last 90 days, the page is skipped.
- Occasional blank single-viewport captures (~4KB PNG) — has been seen on Android chat and iPhone chat/order-check-in. Transient; usually resolved by re-running just the affected page. Check file sizes before uploading to app stores.
- Atlassian MCP intermittently unavailable — falls back to Finder + manual drag-and-drop. See per-run learnings for JQL that finds the existing ticket in that case.
- Marketing test credentials in the Jira ticket sometimes differ from working test credentials — see the Marin-Sonoma learnings entry. Prefer the credentials the previous run used successfully.
- Prior owner: Eshan (eshan@cutanddry.com). Handing over as of 2026-08-18.
- Current state: Working end-to-end. ~15 successful runs recorded in
smith-learnings.md. Composites accepted into iOS and Google Play submissions for all distributors listed above. - First things a new owner should do:
- Change the Slack channel in
smith.md(search forDL88SS3EU) to your own DM or the#smithchannelC0B4EB10NJJ. - Copy
smith/smith-learnings.mdto~/.claude/agents/learnings/smith-learnings.mdso Phase 0 has priors. - Confirm Atlassian + Slack MCPs are connected in your Claude Code install.
- Do a test run against a distributor with a known-working Jira epic (see any recent entry in
smith-learnings.mdfor a JQL + epic pair).
- Change the Slack channel in
- Not portable outside Cut+Dry: The agent hardcodes Cut+Dry-specific URLs (
/white-label-home,/place-order,/chat-v2,/orders-revised/view-one/), Jira project (DOTatgetcodify.atlassian.net), and marketing copy. Any repurposing requires editingsmith.md.
git pull
cd smith && npm install