Skip to content

Add Follow Up Boss CRM skill#15

Merged
TechNickAI merged 6 commits intomainfrom
feature/followupboss-skill
Feb 9, 2026
Merged

Add Follow Up Boss CRM skill#15
TechNickAI merged 6 commits intomainfrom
feature/followupboss-skill

Conversation

@TechNickAI
Copy link
Owner

Summary

  • New followupboss skill — standalone UV script for querying/managing Follow Up Boss real estate CRM
  • Commands: search, get, recent, notes, add-note, tasks, add-task, deals, stages, users, raw
  • Auto-detects search type (name vs email vs phone) for natural queries
  • 18 tests: 6 unit (help/defaults), 6 validation (input checking), 6 integration (live API)

Test plan

  • All 18 tests pass (uv run --with pytest pytest tests/test_followupboss.py -v)
  • Live-tested against Julianna's FUB account (6,230 contacts)
  • Deployed to Julianna's Mac Mini, verified working remotely
  • Integration tests auto-skip gracefully without FUB_API_KEY

🤖 Generated with Claude Code

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28e0b681dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 469 to 479
def cmd_tasks(args: list[str]) -> None:
"""List tasks, optionally filtered by person."""
params: dict[str, Any] = {"limit": DEFAULT_LIMIT}

if args:
# First arg could be a person ID or a limit
try:
pid = int(args[0])
params["personId"] = pid
if len(args) > 1:
params["limit"] = validate_limit(args[1])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Interpret single numeric arg as limit for tasks

The tasks command always treats the first argument as a person ID, so followupboss tasks 5 ends up filtering to personId=5 instead of returning the 5 most recent tasks. This makes it impossible to request a smaller limit without also providing a person ID, which contradicts the help text that frames the person filter as optional. In practice, users trying to list N tasks will silently get the wrong dataset when they pass a single number.

Useful? React with 👍 / 👎.

Nick Sullivan and others added 3 commits February 8, 2026 16:34
Standalone UV script for querying and managing Follow Up Boss real estate
CRM — contacts, notes, tasks, deals, and pipeline stages. Includes 18 tests
(unit + validation + integration). Tested live against Julianna's account
(6,230 contacts). Deployed to her Mac Mini.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@TechNickAI TechNickAI force-pushed the feature/followupboss-skill branch from 833c20f to f92461c Compare February 8, 2026 22:34
- Tasks command now interprets single arg ≤100 as limit, not person ID
  Fixes: 'followupboss tasks 5' now returns 5 tasks, not person #5's tasks
- cmd_raw validates GET request JSON is dict before passing to params
  Prevents AttributeError crash when user passes array/primitive

Addresses Codex P2 and Cursor Low severity feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 8, 2026

Code review

Found one issue to address:

VERSION file needs to be bumped

The VERSION file should be incremented when adding a new skill.

Per CLAUDE.md line 27:

Bump VERSION file and skill's SKILL.md version on changes

Established pattern: Previous PRs that added skills have incremented VERSION:

Suggested fix: Update VERSION from 0.8.0 to 0.9.0


Otherwise, the code looks good! The Follow Up Boss skill is well-structured, follows the UV script pattern correctly, includes comprehensive tests with proper API key handling, and has no bugs or security issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 8, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Addresses Cursor and Codex bot feedback:

1. Fix null name rendering - Use `or ""` pattern to handle API null
   values that would render as literal "None" string
2. Fix tasks command ambiguity - Remove heuristic that prevented
   querying person IDs 1-100, now matches documented signature
3. cmd_raw GET validation already present - No changes needed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

output.append(f"**Stage:** {stage}")
if source:
output.append(f"**Source:** {source}")
output.append(f"**Assigned to:** {assigned}")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Null assignedTo renders as "None" instead of default

Low Severity

When the API returns "assignedTo": null, person.get("assignedTo", "Unassigned") evaluates to None (key exists, so default isn't used), and the output displays literal "Assigned to: None" instead of "Assigned to: Unassigned". This is the same null-key-exists issue documented in the comment on line 152 — the fix used for firstName/lastName (or "") wasn't applied here. Same issue in format_person and format_tasks.

Additional Locations (1)

Fix in Cursor Fix in Web

@TechNickAI TechNickAI merged commit 7054d5f into main Feb 9, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant