# Explicit improvement plan (reasonable, tested only)

**Goal:** Fix issues that hurt satisfaction without rebuilding anything. Only small, testable changes already validated in the quality assessment.

---

## 1. Never surface code errors to the user

- **Where:** Tools that catch exceptions and return strings (e.g. `create_campaign`, others in `server.py`).
- **What:** If the exception is `ImportError` / `ModuleNotFoundError` or message contains "import" / "ImportError", return a single user-facing line (e.g. "Something went wrong loading a module. Try running setup_profile again or check ~/.heylead/logs.") instead of raw exception text. Keep logging the real exception server-side.
- **Status:** Already done for `create_campaign` (lazy import + `ImportError` handling). Ensure that path is what runs in production (editable install or released package). No new code in this pass.

---

## 2. One-line “what’s next” after key actions

- **Where:** Tool response strings in `heylead/tools/` for: `create_campaign` (success), `check_replies` (no messages), and optionally `show_status` when there are no campaigns.
- **What:** Append exactly one line, e.g. "Next: say ‘send messages’ or run generate_and_send." after create_campaign success; "Next: run suggest_next_action for the best next step." when check_replies finds nothing. Reuse existing phrasing; no new UX framework.
- **Status:** Implemented for setup success: after `setup_profile` success we append **Next:** create_campaign(...) → generate_and_send → check_replies. Other tools already have clear “Ready to start? → generate_and_send” etc.; no over-engineering in this pass.

---

## 3. Clear “retry after setup” when backend has no LinkedIn account

- **Where:** Any tool that can get “No LinkedIn account connected on the backend” from `BackendClient` (e.g. `create_campaign`, profile fetch, search).
- **What:** When the backend returns 400 for missing account, show the same or slightly expanded message and add: "Re-run setup_profile to connect LinkedIn, then try again."
- **Status:** **Done.** In `linkedin/backend_client.py` we use a single constant `_NO_LINKEDIN_MSG` and raise it in all three places that previously raised "No LinkedIn account connected on the backend." No new error types; no backend contract changes.

---

## 4. No new “bicycles”

- Do **not** add: new IDs, new dashboards, new flows, or new config. Do **not** change backend contracts or add new APIs.
- Only string/response tweaks and the existing error-handling pattern (catch → log → return short user message).

---

## Verification

- After each change: run existing smoke test `tests/smoke_tools.py`.
- Optional manual flow: setup_profile (or skip if already set) → create_campaign (with icp_id or company_context) → show_status / suggest_next_action.
- If create_campaign fails with “no LinkedIn account”, the message must be the new “Re-run setup_profile to connect LinkedIn, then try again.” text.

---

## Summary of code changes (this pass)

| Item | File | Change |
|------|------|--------|
| Retry after setup | `linkedin/backend_client.py` | Constant `_NO_LINKEDIN_MSG` and use it in 3 raise sites (get_own_profile, search_people, get_llm_params). |
| Next-step hint | `tools/setup_profile.py` | Append one line after success: **Next:** create_campaign(...) → generate_and_send → check_replies. |

Export already says “Copy the table above to paste into spreadsheets or documents.” — no change. Lazy import and ImportError handling in create_campaign remain as already implemented.
